Compare commits

..

13 Commits

Author SHA1 Message Date
E Spause a3f21cc9ea Additional fixups. 2017-03-16 13:27:58 -04:00
E Spause 3c9e6d913a Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-16 13:23:56 -04:00
E Spause 9c08d6f25b Fix additional logic cases for merc disbanding. 2017-03-15 07:09:14 -04:00
E Spause f8d000d660 Don't allow disbanding mercs that have their owner in combat if the rule is set. 2017-03-15 06:52:16 -04:00
E Spause b2c6bb4df5 Set default, no-skill value for bash to 1. This is consistent with what demonstar was seeing on live with no skill and slam.
GetBaseDamage is now used for Bash/Slam additionally.
2017-03-15 06:39:57 -04:00
E Spause 542d0795c4 Add rule instead of define for IDLE_WHEN_EMPTY 2017-03-15 06:37:03 -04:00
E Spause c3b7f6d0bf Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-15 06:15:04 -04:00
E Spause 21e53a3cd0 Fix up slam some more 2017-03-15 06:15:01 -04:00
E Spause 3ce99d9f00 Stupid sexy floats 2017-03-14 22:42:14 -04:00
E Spause 598196329d Bash min skill fix 2017-03-14 22:15:22 -04:00
E Spause bbfacd902c Woops 2017-03-13 15:08:20 -04:00
E Spause 5cfb3111a6 SoF-era con system. New rule, UseOldConSystem to disable this functionality. 2017-03-13 15:07:56 -04:00
E Spause 5b674f23bd Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-13 15:05:26 -04:00
1226 changed files with 144115 additions and 158884 deletions
-23
View File
@@ -1,23 +0,0 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
[*.cpp]
indent_style = tab
[*.h]
indent_style = tab
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
+10 -11
View File
@@ -23,16 +23,15 @@ CMakeFiles
Makefile
cmake_install.cmake
install_manifest.txt
[Bb]uild*/
Build/
build/
Build32/
build32/
Build64/
build64/
Build_32/
build_32/
Build_64/
build_64/
log/
logs/
vcpkg/
perl/
.idea/*
*cbp
submodules/*
cmake-build-debug/
.nfs.*
-18
View File
@@ -1,18 +0,0 @@
[submodule "submodules/glm"]
path = submodules/glm
url = https://github.com/g-truc/glm.git
[submodule "submodules/fmt"]
path = submodules/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "submodules/libuv"]
path = submodules/libuv
url = https://github.com/libuv/libuv.git
[submodule "submodules/cereal"]
path = submodules/cereal
url = https://github.com/USCiLab/cereal.git
[submodule "submodules/websocketpp"]
path = submodules/websocketpp
url = https://github.com/zaphoyd/websocketpp.git
[submodule "submodules/recastnavigation"]
path = submodules/recastnavigation
url = https://github.com/EQEmu/recastnavigation.git
+20 -23
View File
@@ -1,27 +1,24 @@
language: cpp
compiler: gcc
dist: trusty
before_install:
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get update -qq
- mkdir $HOME/usr
- export PATH="$HOME/usr/bin:$PATH"
- wget https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.sh
- chmod +x cmake-3.11.2-Linux-x86_64.sh
- ./cmake-3.11.2-Linux-x86_64.sh --prefix=$HOME/usr --exclude-subdir --skip-license
install:
- sudo apt-get install -qq g++-7
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90
- sudo apt-get install libmysqlclient-dev
- sudo apt-get install libperl-dev
- sudo apt-get install libboost-dev
- sudo apt-get install liblua5.1-0-dev
- sudo apt-get install zlib1g-dev
- sudo apt-get install uuid-dev
- sudo apt-get install libssl-dev
sudo: false
addons:
apt:
packages:
- libmysqlclient-dev
- libperl-dev
- libboost-dev
- liblua5.1-0-dev
- zlib1g-dev
script:
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
- make -j2
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON
- make -j8
- ./bin/tests
branches:
only:
- master
- stable
notifications:
email: false
irc:
channels: "irc.eqemulator.net#eqemucoders"
os: linux
-64
View File
@@ -1,64 +0,0 @@
# Guide To Building From Source Without Installer
This guide is far from exhaustive, you should expect to have some experience with building C++ code before considering compiling the code from scratch. You should instead consider using the installer scripts if you don't want to hack on the code directly.
### CMake
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source.
### Dependencies
The following libraries are required to build from source:
- [boost](https://www.boost.org/ "boost")
- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead)
- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb")
The following libraries are not strictly required but in many cased recommended.
- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client)
- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver)
- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting)
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
##### Windows
For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies.
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake.
##### Linux
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev
### Running CMake
##### Windows
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg.
mkdir build
cd build
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
##### Linux
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
mkdir build
cd build
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
### Building
##### Windows
Inside the build directory a file EQEmu.sln should be produced by a successful run of the CMake command. You can either open this with Visual Studio or build it directly with MSBuild via the command line.
msbuild EQEmu.sln /p:Configuration=Release
##### Linux
From the build directory you can simply call make to build.
For example.
make -j4
+277 -299
View File
@@ -1,28 +1,125 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
#EQEmu CMake
#Variables used:
#EQEMU_DISABLE_CRT_SECURE_WARNINGS
#EQEMU_FAST_FLOATINGPOINT
#EQEMU_ENABLE_CRASH_LOGGING
#EQEMU_DISABLE_SAFESEH
#EQEMU_BUILD_MSVC_MP
#EQEMU_DEBUG_LEVEL
#EQEMU_LOG_LEVEL_STATUS
#EQEMU_LOG_LEVEL_NORMAL
#EQEMU_LOG_LEVEL_ERROR
#EQEMU_LOG_LEVEL_DEBUG
#EQEMU_LOG_LEVEL_QUEST
#EQEMU_LOG_LEVEL_COMMANDS
#EQEMU_LOG_LEVEL_CRASH
#EQEMU_STREAM_SEND_RATE
#EQEMU_STREAM_DECAY_RATE
#EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL
#EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX
#EQEMU_STREAM_AVERAGE_DELTA_MAX
#EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS
#EQEMU_DEPOP_INVALIDATES_CACHE
#EQEMU_ENABLE_BOTS
#EQEMU_DISABLE_LOGSYS
#EQEMU_COMMANDS_LOGGING
#EQEMU_BUILD_SERVER
#EQEMU_BUILD_LOGIN
#EQEMU_BUILD_TESTS
#EQEMU_BUILD_PERL
#EQEMU_BUILD_LUA
#EQEMU_SANITIZE_LUA_LIBS
#EQEMU_BUILD_CLIENT_FILES
#EQEMU_USE_MAP_MMFS
#EQEMU_MAP_DIR
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
#Can change this if you really want but you should upgrade!
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#FindMySQL is located here so lets make it so CMake can find it
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
IF(POLICY CMP0074)
CMAKE_POLICY(SET CMP0074 NEW)
ENDIF()
#Our project name is EQEmu
PROJECT(EQEmu)
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
#Add our various windows definitions
IF(MSVC OR MINGW)
ADD_DEFINITIONS(-D_WINDOWS)
IF(CMAKE_CL_64)
ADD_DEFINITIONS(-DWIN64)
ELSE(CMAKE_CL_64)
ADD_DEFINITIONS(-DWIN32)
ENDIF(CMAKE_CL_64)
ENDIF(MSVC OR MINGW)
IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
#Set our default locations for zlib/mysql based on x86/x64
IF(CMAKE_CL_64)
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x64")
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x64")
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x64")
ELSE(CMAKE_CL_64)
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x86")
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x86")
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x86")
ENDIF(CMAKE_CL_64)
#disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere
OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON)
IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ENDIF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
#fast FP if you'd like it
OPTION(EQEMU_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
IF(EQEMU_FAST_FLOATINGPOINT)
ADD_DEFINITIONS(/fp:fast)
ENDIF(EQEMU_FAST_FLOATINGPOINT)
#crash logging currently only works on windows x86/x64
OPTION(EQEMU_ENABLE_CRASH_LOGGING "Enable crash logging" ON)
IF(EQEMU_ENABLE_CRASH_LOGGING)
ADD_DEFINITIONS(-DCRASH_LOGGING)
ENDIF(EQEMU_ENABLE_CRASH_LOGGING)
#Disable safe SEH or not?
OPTION(EQEMU_DISABLE_SAFESEH "Disable Safe SEH (Needed for Strawberry Perl)" OFF)
IF(EQEMU_DISABLE_SAFESEH)
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO")
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /SAFESEH:NO")
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /SAFESEH:NO")
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
SET(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO")
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /SAFESEH:NO")
SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
ENDIF(EQEMU_DISABLE_SAFESEH)
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON)
IF(EQEMU_BUILD_MSVC_MP)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ENDIF(EQEMU_BUILD_MSVC_MP)
#We want to compile /MT not /MD so we change that
FOREACH(flag_var CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
IF(${flag_var} MATCHES "/MD")
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
ENDIF(${flag_var} MATCHES "/MD")
ENDFOREACH(flag_var)
ADD_DEFINITIONS(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ELSE(MSVC)
#Normally set by perl but we don't use the perl flags anymore so we set it.
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC)
@@ -39,324 +136,210 @@ IF(UNIX)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF(UNIX)
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
#debug level, 5 is default. Most people wont ever change this but it's there if you want to
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
0 - Quiet mode Errors to file Status and Normal ignored
1 - Status and Normal to console, Errors to logfile
2 - Status, Normal, and Error to console and logfile
3 - Light debug release errors and status
4 - Moderate debug release errors and status
5 - Maximum debug release errors and status
10 - More errors than you ever wanted to see"
)
#MSVC can fetch dependencies automatically.
IF(MSVC)
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
ENDIF()
SET(EQEMU_LOG_LEVEL_STATUS 2 CACHE STRING "EQEmu logging level for [Status]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
#Find everything we need
FIND_PACKAGE(Boost REQUIRED)
FIND_PACKAGE(MySQL)
FIND_PACKAGE(MariaDB)
FIND_PACKAGE(ZLIB)
FIND_PACKAGE(OpenSSL)
FIND_PACKAGE(Lua51)
FIND_PACKAGE(PerlLibs)
FIND_PACKAGE(Sodium)
FIND_PACKAGE(mbedTLS)
SET(EQEMU_LOG_LEVEL_NORMAL 3 CACHE STRING "EQEmu logging level for [Normal]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Detection *")
MESSAGE(STATUS "**************************************************")
SET(EQEMU_LOG_LEVEL_ERROR 2 CACHE STRING "EQEmu logging level for [Error]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
IF(MYSQL_FOUND)
MESSAGE(STATUS "* MySQL: FOUND *")
ELSE()
MESSAGE(STATUS "* MySQL: MISSING *")
ENDIF()
SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
IF(MARIADB_FOUND)
MESSAGE(STATUS "* MariaDB: FOUND *")
ELSE()
MESSAGE(STATUS "* MariaDB: MISSING *")
ENDIF()
SET(EQEMU_LOG_LEVEL_QUEST 2 CACHE STRING "EQEmu logging level for [Quest]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
IF(ZLIB_FOUND)
MESSAGE(STATUS "* ZLIB: FOUND *")
ELSE()
MESSAGE(STATUS "* ZLIB: MISSING *")
ENDIF()
SET(EQEMU_LOG_LEVEL_COMMANDS 1 CACHE STRING "EQEmu logging level for [Commands]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
IF(Lua51_FOUND)
MESSAGE(STATUS "* Lua: FOUND *")
ELSE()
MESSAGE(STATUS "* Lua: MISSING *")
ENDIF()
SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]:
0 - Disabled
1 - Ouput to File Enabled
2 - Output to stdout Enabled
3 - Output to File and stdout Enabled
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
IF(PerlLibs_FOUND)
MESSAGE(STATUS "* Perl: FOUND *")
ELSE()
MESSAGE(STATUS "* Perl: MISSING *")
ENDIF()
MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_STATUS EQEMU_LOG_LEVEL_NORMAL EQEMU_LOG_LEVEL_ERROR EQEMU_LOG_LEVEL_DEBUG EQEMU_LOG_LEVEL_QUEST EQEMU_LOG_LEVEL_COMMANDS EQEMU_LOG_LEVEL_CRASH)
IF(SODIUM_FOUND)
MESSAGE(STATUS "* libsodium: FOUND *")
ELSE()
MESSAGE(STATUS "* libsodium: MISSING *")
ENDIF()
SET(EQEMU_STREAM_SEND_RATE 1048576 CACHE STRING "Advanced: Base amount of data stream can send before throttle.")
SET(EQEMU_STREAM_DECAY_RATE 78642 CACHE STRING "Advanced: Base amount of data stream recovers per tic.")
SET(EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL 3.0 CACHE STRING "Advanced: Multiplier on retransmit timeout.")
SET(EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX 5000 CACHE STRING "Advanced: Max in ms for retransmit timeout timer.")
SET(EQEMU_STREAM_AVERAGE_DELTA_MAX 2500 CACHE STRING "Advanced: The maximum average delta in ms allowed.")
SET(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS TRUE CACHE BOOL "Advanced: Whether or not acked packets can be retransmitted")
MARK_AS_ADVANCED(EQEMU_STREAM_SEND_RATE EQEMU_STREAM_DECAY_RATE EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX EQEMU_STREAM_AVERAGE_DELTA_MAX EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
IF(OpenSSL_FOUND)
MESSAGE(STATUS "* OpenSSL: FOUND *")
ELSE()
MESSAGE(STATUS "* OpenSSL: MISSING *")
ENDIF()
IF(MBEDTLS_FOUND)
MESSAGE(STATUS "* mbedTLS: FOUND *")
ELSE()
MESSAGE(STATUS "* mbedTLS: MISSING *")
ENDIF()
MESSAGE(STATUS "**************************************************")
#options
#NPC Types Cache Behavior
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
#Bots are a compile time option so on/off
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
#Disable entire _mlog system (excludes trade/command logs)
OPTION(EQEMU_DISABLE_LOGSYS "Disable Logging INI System" ON)
#Enable GM Command log system
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
IF(EQEMU_COMMANDS_LOGGING)
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
ENDIF(EQEMU_COMMANDS_LOGGING)
IF(EQEMU_DISABLE_LOGSYS)
ADD_DEFINITIONS(-DDISABLE_LOGSYS)
ENDIF(EQEMU_DISABLE_LOGSYS)
IF(EQEMU_ENABLE_BOTS)
ADD_DEFINITIONS(-DBOTS)
ENDIF(EQEMU_ENABLE_BOTS)
#database
IF(MySQL_FOUND AND MariaDB_FOUND)
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use:
MySQL
MariaDB"
)
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB")
SET(DATABASE_LIBRARY_TYPE "MariaDB")
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
ELSE()
MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB")
#What to build
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
#C++11 stuff
IF(NOT MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
ENDIF()
ELSEIF(MariaDB_FOUND)
SET(DATABASE_LIBRARY_TYPE "MariaDB")
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
ELSEIF(MySQL_FOUND)
SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
ELSE()
MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.")
ENDIF()
ENDIF(NOT MSVC)
#security
#prefer openssl to mbedtls (arbitrary)
IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
OpenSSL
mbedTLS"
)
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
SET(TLS_LIBRARY_TYPE " OpenSSL")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
SET(TLS_LIBRARY_TYPE " mbedTLS")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
ELSE()
MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS")
ENDIF()
ELSEIF(OpenSSL_FOUND)
SET(TLS_LIBRARY_TYPE " OpenSSL")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
ELSEIF(MBEDTLS_FOUND)
SET(TLS_LIBRARY_TYPE " mbedTLS")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
ELSE()
SET(TLS_LIBRARY_TYPE "Disabled")
SET(TLS_LIBRARY_ENABLED OFF)
ENDIF()
#Various definitions
IF(EQEMU_BUILD_PERL)
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ENDIF(EQEMU_BUILD_PERL)
IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
ENDIF(EQEMU_BUILD_LUA)
IF(SODIUM_FOUND)
SET(SODIUM_LIBRARY_TYPE "Libsodium")
SET(SODIUM_LIBRARY_ENABLED ON)
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
ADD_DEFINITIONS(-DENABLE_SECURITY)
ELSE()
SET(SODIUM_LIBRARY_TYPE " Disabled")
SET(SODIUM_LIBRARY_ENABLED OFF)
ENDIF()
OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
IF(EQEMU_USE_MAP_MMFS)
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
ENDIF(EQEMU_USE_MAP_MMFS)
IF(Lua51_FOUND)
SET(LUA_LIBRARY_TYPE " Lua 5.1")
SET(LUA_LIBRARY_ENABLED ON)
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
ELSE()
SET(LUA_LIBRARY_TYPE "Disabled")
SET(LUA_LIBRARY_ENABLED OFF)
ENDIF()
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
IF(PerlLibs_FOUND)
SET(PERL_LIBRARY_TYPE " Perl")
SET(PERL_LIBRARY_ENABLED ON)
SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY})
SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH})
ELSE()
SET(PERL_LIBRARY_TYPE "Disabled")
SET(PERL_LIBRARY_ENABLED OFF)
ENDIF()
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
ADD_DEFINITIONS(-DINVERSEXY)
ADD_DEFINITIONS(-DFIELD_ITEMS)
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
ADD_DEFINITIONS(-DRATEBASE=${EQEMU_STREAM_SEND_RATE})
ADD_DEFINITIONS(-DDECAYBASE=${EQEMU_STREAM_DECAY_RATE})
ADD_DEFINITIONS(-DRETRANSMIT_TIMEOUT_MULT=${EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL})
ADD_DEFINITIONS(-DRETRANSMIT_TIMEOUT_MAX=${EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX})
ADD_DEFINITIONS(-DAVERAGE_DELTA_MAX=${EQEMU_STREAM_AVERAGE_DELTA_MAX})
ADD_DEFINITIONS(-DLOG_LEVEL_STATUS=${EQEMU_LOG_LEVEL_STATUS})
ADD_DEFINITIONS(-DLOG_LEVEL_NORMAL=${EQEMU_LOG_LEVEL_NORMAL})
ADD_DEFINITIONS(-DLOG_LEVEL_ERROR=${EQEMU_LOG_LEVEL_ERROR})
ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
#use zlib if exists
IF(ZLIB_FOUND)
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON)
IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ELSE()
SET(ZLIB_LIBRARY_TYPE " zlib")
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
ENDIF()
ELSE()
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ENDIF()
IF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=true)
ELSE(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=false)
ENDIF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
MESSAGE(STATUS "")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Usage *")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *")
MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *")
MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *")
MESSAGE(STATUS "**************************************************")
#Find everything we need
FIND_PACKAGE(ZLIB REQUIRED)
FIND_PACKAGE(MySQL REQUIRED)
IF(EQEMU_BUILD_PERL)
FIND_PACKAGE(PerlLibs REQUIRED)
INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}")
ENDIF(EQEMU_BUILD_PERL)
#setup server libs and headers
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
IF(EQEMU_BUILD_LUA)
FIND_PACKAGE(EQLua51 REQUIRED)
SET(Boost_USE_STATIC_LIBS OFF)
SET(Boost_USE_MULTITHREADED ON)
SET(Boost_USE_STATIC_RUNTIME OFF)
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
FIND_PACKAGE(Boost REQUIRED)
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}" "luabind")
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
IF(EQEMU_BUILD_LOGGING)
ADD_DEFINITIONS(-DBUILD_LOGGING)
ENDIF()
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
ENDIF(EQEMU_BUILD_LUA)
IF(TLS_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
ENDIF()
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
IF(SODIUM_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
ENDIF()
IF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(luabind)
ENDIF(EQEMU_BUILD_LUA)
IF(LUA_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
ENDIF()
ENDIF()
ENDIF()
IF(PERL_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
IF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ENDIF()
ENDIF()
IF(WIN32)
SET(SERVER_LIBS ${SERVER_LIBS} "ws2_32" "psapi" "iphlpapi" "userenv")
ENDIF()
IF(UNIX)
SET(SERVER_LIBS ${SERVER_LIBS} ${CMAKE_DL_LIBS} "z" "m" "pthread")
IF(NOT DARWIN)
SET(SERVER_LIBS ${SERVER_LIBS} "rt")
ENDIF()
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
ENDIF()
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
ENDIF()
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
ENDIF()
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(libs)
ADD_SUBDIRECTORY(submodules/fmt)
ADD_SUBDIRECTORY(submodules/libuv)
IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
ADD_SUBDIRECTORY(libs/zlibng)
ENDIF()
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
ADD_SUBDIRECTORY(submodules/recastnavigation)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory)
ADD_SUBDIRECTORY(world)
@@ -365,15 +348,10 @@ IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(queryserv)
ADD_SUBDIRECTORY(eqlaunch)
ENDIF(EQEMU_BUILD_SERVER)
IF(EQEMU_BUILD_LOGIN)
ADD_SUBDIRECTORY(loginserver)
ENDIF(EQEMU_BUILD_LOGIN)
IF(EQEMU_BUILD_HC)
ADD_SUBDIRECTORY(hc)
ENDIF(EQEMU_BUILD_HC)
IF(EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(tests)
ENDIF(EQEMU_BUILD_TESTS)
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
-674
View File
@@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
+12
View File
@@ -0,0 +1,12 @@
The server code and utilities are released under GPLv3.
We also include some small libraries for convienence that may be under different licensing:
SocketLib - GPL
LibXML - ZLib License
StackWalker - New BSD License
ZLib - ZLib License
MySQL - GPL
Perl - GPL / ActiveState (under the assumption that this is a free project).
CPPUnit - GLP
StringUtilities - Apache
+15 -34
View File
@@ -1,30 +1,33 @@
# EQEmulator Core Server
|Travis CI (Linux)|Appveyor w/ Bots (Windows) |Appveyor w/o Bots (Windows) |
|:---:|:---:|:---:|
|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Build status](https://ci.appveyor.com/api/projects/status/scr25kmntx36c1ub/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[![Build status](https://ci.appveyor.com/api/projects/status/mdwbr4o9l6mxqofj/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server-w0pq2/branch/master) |
|Travis CI (Linux)|Appveyor (Windows) |
|:---:|:---:|
|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) |
***
**EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++**
* MySQL/MariaDB is used as the database engine (over 200+ tables)
* Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events
* Open source database (Project EQ) has content up to expansion OoW (included in server installs)
* Open source database (Project EQ) has content up to expansion GoD (included in server installs)
* Game server environments and databases can be heavily customized to create all new experiences
* Hundreds of Quests/events created and maintained by Project EQ
## Server Installs
| |Windows|Linux|
||Windows|Linux|
|:---:|:---:|:---:|
|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)|
### > Windows
* [Install](https://github.com/EQEmu/Server/wiki/Windows-Server)
* [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows)
* [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide)
### > Debian/Ubuntu/CentOS/Fedora
* You can use curl or wget to kick off the installer (whichever your OS has)
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
### > Debian/Ubuntu
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
### > CentOS/Fedora
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
## Supported Clients
|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear|
@@ -50,29 +53,7 @@ forum, although pull requests will be much quicker and easier on all parties.
- **User Discord Channel**: `#general`
- **Developer Discord Channel**: `#eqemucoders`
## Resources
Resources
---
- [EQEmulator Forums](http://www.eqemulator.org/forums)
- [EQEmulator Wiki](https://github.com/EQEmu/Server/wiki)
## Related Repositories
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
* [Maps](https://github.com/Akkadius/EQEmuMaps)
* [Installer Resources](https://github.com/Akkadius/EQEmuInstall)
* [Zone Utilities](https://github.com/EQEmu/zone-utilities) - Various utilities and libraries for parsing, rendering and manipulating EQ Zone files.
## Other License Info
* The server code and utilities are released under **GPLv3**
* We also include some small libraries for convienence that may be under different licensing
* SocketLib - GPL LibXML
* zlib - zlib license
* MariaDB/MySQL - GPL
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
* CPPUnit - GLP StringUtilities - Apache
* LUA - MIT
## Contributors
<a href="https://github.com/EQEmu/server/graphs/contributors">
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
</a>
- [EQEmulator Wiki](http://wiki.eqemulator.org/i?M=Wiki)
-3
View File
@@ -1,3 +0,0 @@
# Security Policy - Reporting Vulnerabilities
When reporting active hacks, exploits and other vulnerabilities, please describe how to reproduce said report and if you can provide context into a possible solution
-21
View File
@@ -1,21 +0,0 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
configuration: RelWithDebInfo
clone_folder: c:\projects\eqemu
init:
- ps: git config --global core.autocrlf input
cache: c:\tools\vcpkg\installed\
before_build:
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
build:
project: C:\projects\eqemu\build\EQEmu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: >-
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb
appveyor PushArtifact build_x64-bots.zip
-21
View File
@@ -1,21 +0,0 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
configuration: RelWithDebInfo
clone_folder: c:\projects\eqemu
init:
- ps: git config --global core.autocrlf input
cache: c:\tools\vcpkg\installed\
before_build:
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=OFF -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
build:
project: C:\projects\eqemu\build\EQEmu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: >-
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb
appveyor PushArtifact build_x64-no-bots.zip
+480 -1184
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
add_subdirectory(import)
add_subdirectory(export)
+23 -3
View File
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(export_sources
main.cpp
@@ -9,8 +9,28 @@ SET(export_headers
ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(export_client_files ${SERVER_LIBS})
TARGET_LINK_LIBRARIES(export_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(export_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(export_client_files "Ws2_32.lib")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(export_client_files "WS2_32")
ENDIF(MINGW)
IF(UNIX)
TARGET_LINK_LIBRARIES(export_client_files "${CMAKE_DL_LIBS}")
TARGET_LINK_LIBRARIES(export_client_files "z")
TARGET_LINK_LIBRARIES(export_client_files "m")
IF(NOT DARWIN)
TARGET_LINK_LIBRARIES(export_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(export_client_files "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+18 -40
View File
@@ -27,7 +27,7 @@
#include "../../common/rulesys.h"
#include "../../common/string_util.h"
EQEmuLogSys LogSys;
EQEmuLogSys Log;
void ExportSpells(SharedDatabase *db);
void ExportSkillCaps(SharedDatabase *db);
@@ -36,68 +36,46 @@ void ExportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientExport);
LogSys.LoadLogSettingsDefaults();
Log.LoadLogSettingsDefaults();
set_exception_handler();
LogInfo("Client Files Export Utility");
Log.Out(Logs::General, Logs::Status, "Client Files Export Utility");
if(!EQEmuConfig::LoadConfig()) {
LogError("Unable to load configuration file");
Log.Out(Logs::General, Logs::Error, "Unable to load configuration file.");
return 1;
}
auto Config = EQEmuConfig::get();
SharedDatabase database;
LogInfo("Connecting to database");
Log.Out(Logs::General, Logs::Status, "Connecting to database...");
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
LogError("Unable to connect to the database, cannot continue without a database connection");
Log.Out(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
"database connection");
return 1;
}
/* Register Log System and Settings */
database.LoadLogSettings(LogSys.log_settings);
LogSys.StartFileLogs();
std::string arg_1;
if (argv[1]) {
arg_1 = argv[1];
}
if (arg_1 == "spells") {
ExportSpells(&database);
return 0;
}
if (arg_1 == "skills") {
ExportSkillCaps(&database);
return 0;
}
if (arg_1 == "basedata") {
ExportBaseData(&database);
return 0;
}
if (arg_1 == "dbstring") {
ExportDBStrings(&database);
return 0;
}
database.LoadLogSettings(Log.log_settings);
Log.StartFileLogs();
ExportSpells(&database);
ExportSkillCaps(&database);
ExportBaseData(&database);
ExportDBStrings(&database);
LogSys.CloseFileLogs();
Log.CloseFileLogs();
return 0;
}
void ExportSpells(SharedDatabase *db) {
LogInfo("Exporting Spells");
Log.Out(Logs::General, Logs::Status, "Exporting Spells...");
FILE *f = fopen("export/spells_us.txt", "w");
if(!f) {
LogError("Unable to open export/spells_us.txt to write, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping.");
return;
}
@@ -164,11 +142,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
}
void ExportSkillCaps(SharedDatabase *db) {
LogInfo("Exporting Skill Caps");
Log.Out(Logs::General, Logs::Status, "Exporting Skill Caps...");
FILE *f = fopen("export/SkillCaps.txt", "w");
if(!f) {
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping.");
return;
}
@@ -193,11 +171,11 @@ void ExportSkillCaps(SharedDatabase *db) {
}
void ExportBaseData(SharedDatabase *db) {
LogInfo("Exporting Base Data");
Log.Out(Logs::General, Logs::Status, "Exporting Base Data...");
FILE *f = fopen("export/BaseData.txt", "w");
if(!f) {
LogError("Unable to open export/BaseData.txt to write, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping.");
return;
}
@@ -224,11 +202,11 @@ void ExportBaseData(SharedDatabase *db) {
}
void ExportDBStrings(SharedDatabase *db) {
LogInfo("Exporting DB Strings");
Log.Out(Logs::General, Logs::Status, "Exporting DB Strings...");
FILE *f = fopen("export/dbstr_us.txt", "w");
if(!f) {
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
return;
}
+23 -3
View File
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(import_sources
main.cpp
@@ -9,8 +9,28 @@ SET(import_headers
ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(import_client_files ${SERVER_LIBS})
TARGET_LINK_LIBRARIES(import_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(import_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(import_client_files "Ws2_32.lib")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(import_client_files "WS2_32")
ENDIF(MINGW)
IF(UNIX)
TARGET_LINK_LIBRARIES(import_client_files "${CMAKE_DL_LIBS}")
TARGET_LINK_LIBRARIES(import_client_files "z")
TARGET_LINK_LIBRARIES(import_client_files "m")
IF(NOT DARWIN)
TARGET_LINK_LIBRARIES(import_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(import_client_files "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+19 -19
View File
@@ -25,7 +25,7 @@
#include "../../common/rulesys.h"
#include "../../common/string_util.h"
EQEmuLogSys LogSys;
EQEmuLogSys Log;
void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db);
@@ -34,35 +34,35 @@ void ImportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientImport);
LogSys.LoadLogSettingsDefaults();
Log.LoadLogSettingsDefaults();
set_exception_handler();
LogInfo("Client Files Import Utility");
Log.Out(Logs::General, Logs::Status, "Client Files Import Utility");
if(!EQEmuConfig::LoadConfig()) {
LogError("Unable to load configuration file.");
Log.Out(Logs::General, Logs::Error, "Unable to load configuration file.");
return 1;
}
auto Config = EQEmuConfig::get();
SharedDatabase database;
LogInfo("Connecting to database");
Log.Out(Logs::General, Logs::Status, "Connecting to database...");
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
LogError("Unable to connect to the database, cannot continue without a "
Log.Out(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
"database connection");
return 1;
}
database.LoadLogSettings(LogSys.log_settings);
LogSys.StartFileLogs();
database.LoadLogSettings(Log.log_settings);
Log.StartFileLogs();
ImportSpells(&database);
ImportSkillCaps(&database);
ImportBaseData(&database);
ImportDBStrings(&database);
LogSys.CloseFileLogs();
Log.CloseFileLogs();
return 0;
}
@@ -97,10 +97,10 @@ bool IsStringField(int i) {
}
void ImportSpells(SharedDatabase *db) {
LogInfo("Importing Spells");
Log.Out(Logs::General, Logs::Status, "Importing Spells...");
FILE *f = fopen("import/spells_us.txt", "r");
if(!f) {
LogError("Unable to open import/spells_us.txt to read, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping.");
return;
}
@@ -173,23 +173,23 @@ void ImportSpells(SharedDatabase *db) {
spells_imported++;
if(spells_imported % 1000 == 0) {
LogInfo("[{}] spells imported", spells_imported);
Log.Out(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
}
}
if(spells_imported % 1000 != 0) {
LogInfo("[{}] spells imported", spells_imported);
Log.Out(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
}
fclose(f);
}
void ImportSkillCaps(SharedDatabase *db) {
LogInfo("Importing Skill Caps");
Log.Out(Logs::General, Logs::Status, "Importing Skill Caps...");
FILE *f = fopen("import/SkillCaps.txt", "r");
if(!f) {
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping.");
return;
}
@@ -220,11 +220,11 @@ void ImportSkillCaps(SharedDatabase *db) {
}
void ImportBaseData(SharedDatabase *db) {
LogInfo("Importing Base Data");
Log.Out(Logs::General, Logs::Status, "Importing Base Data...");
FILE *f = fopen("import/BaseData.txt", "r");
if(!f) {
LogError("Unable to open import/BaseData.txt to read, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping.");
return;
}
@@ -265,11 +265,11 @@ void ImportBaseData(SharedDatabase *db) {
}
void ImportDBStrings(SharedDatabase *db) {
LogInfo("Importing DB Strings");
Log.Out(Logs::General, Logs::Status, "Importing DB Strings...");
FILE *f = fopen("import/dbstr_us.txt", "r");
if(!f) {
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
Log.Out(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
return;
}
-94
View File
@@ -1,94 +0,0 @@
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON)
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON)
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-x86")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-x64")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86")
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64")
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64})
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64})
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP})
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR})
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP})
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR})
ELSE()
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86})
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86})
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP})
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR})
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP})
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR})
ENDIF()
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
MESSAGE(STATUS "Resolving vcpkg dependencies...")
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
SHOW_PROGRESS
STATUS DOWNLOAD_STATUS)
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
IF(NOT STATUS_CODE EQUAL 0)
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
ENDIF()
MESSAGE(STATUS "Extracting files...")
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
)
ENDIF()
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
ENDIF()
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
#Try to find perl first, (so you can use your active install first)
FIND_PACKAGE(PerlLibs)
IF(NOT PerlLibs_FOUND)
MESSAGE(STATUS "Resolving perl dependencies...")
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
MESSAGE(STATUS "Downloading portable perl...")
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
SHOW_PROGRESS
STATUS DOWNLOAD_STATUS)
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
IF(NOT STATUS_CODE EQUAL 0)
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
ENDIF()
MESSAGE(STATUS "Extracting files...")
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
)
ENDIF()
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
ENDIF()
ENDIF()
+124
View File
@@ -0,0 +1,124 @@
#CMake - Cross Platform Makefile Generator
#Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions
#are met:
#
#* Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
#* Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This module defines
# LUA51_FOUND, if false, do not try to link to Lua
# LUA_LIBRARIES
# LUA_INCLUDE_DIR, where to find lua.h
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
IF(LUA_ROOT)
FIND_PATH(LUA_INCLUDE_DIR
NAMES lua.h
HINTS
ENV LUA_DIR
PATHS
${LUA_ROOT}
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include src
)
FIND_LIBRARY(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua
HINTS
ENV LUA_DIR
PATHS
${LUA_ROOT}
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES lib bin
)
ELSE(LUA_ROOT)
FIND_PATH(LUA_INCLUDE_DIR
NAMES lua.h
HINTS
ENV LUA_DIR
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
)
FIND_LIBRARY(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua
HINTS
ENV LUA_DIR
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
PATH_SUFFIXES lib bin
)
ENDIF(LUA_ROOT)
IF(LUA_LIBRARY)
# include the math library for Unix
IF(UNIX AND NOT APPLE)
FIND_LIBRARY(LUA_MATH_LIBRARY m)
SET(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
ELSE()
SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
ENDIF()
ENDIF()
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
UNSET(lua_version_str)
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
-91
View File
@@ -1,91 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# Modified from the FindLua51 that comes with CMake
#[=======================================================================[.rst:
FindLua51
---------
Locate Lua51 library This module defines
::
LUA51_FOUND, if false, do not try to link to Lua
LUA_LIBRARIES
LUA_INCLUDE_DIR, where to find lua.h
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
Note that the expected include convention is
::
#include "lua.h"
and not
::
#include <lua/lua.h>
This is because, the lua location is not standardized and may exist in
locations other than lua/
#]=======================================================================]
find_path(LUA_INCLUDE_DIR lua.h
HINTS
ENV LUA_DIR
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include/luajit include
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
find_library(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua luajit
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
if(LUA_LIBRARY)
# include the math library for Unix
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
find_library(LUA_MATH_LIBRARY m)
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
else()
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
endif()
endif()
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
unset(lua_version_str)
endif()
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
-87
View File
@@ -1,87 +0,0 @@
# - Find mariadbclient
#
# -*- cmake -*-
#
# Find the native MariaDB includes and library
#
# MariaDB_INCLUDE_DIR - where to find mysql.h, etc.
# MariaDB_LIBRARIES - List of libraries when using MariaDB.
# MariaDB_FOUND - True if MariaDB found.
# The following can be used as a hint as to where to search:
# MARIADB_ROOT
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
# Already in cache, be silent
SET(MariaDB_FIND_QUIETLY TRUE)
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
# Include dir
IF(MARIADB_ROOT)
FIND_PATH(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATHS ${MARIADB_ROOT}/include
PATH_SUFFIXES mysql mariadb
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
FIND_PATH(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATH_SUFFIXES mysql mariadb
)
ELSE(MARIADB_ROOT)
FIND_PATH(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATH_SUFFIXES mysql mariadb
)
ENDIF(MARIADB_ROOT)
# Library
SET(MariaDB_NAMES libmariadb)
IF(MARIADB_ROOT)
FIND_LIBRARY(MariaDB_LIBRARY
NAMES ${MariaDB_NAMES}
PATHS ${MARIADB_ROOT}/lib
PATH_SUFFIXES mysql mariadb
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
FIND_LIBRARY(MariaDB_LIBRARY
NAMES ${MariaDB_NAMES}
PATH_SUFFIXES mysql mariadb
)
ELSE(MARIADB_ROOT)
FIND_LIBRARY(MariaDB_LIBRARY
NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
PATH_SUFFIXES mysql mariadb
)
ENDIF(MARIADB_ROOT)
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
SET(MariaDB_FOUND TRUE)
SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY})
ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
SET(MariaDB_FOUND FALSE)
SET(MariaDB_LIBRARIES)
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR)
IF(MariaDB_FOUND)
SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} )
SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} )
SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} )
ELSE(MariaDB_FOUND)
SET( MariaDB_LIBRARIES )
ENDIF(MariaDB_FOUND)
MARK_AS_ADVANCED(
MariaDB_LIBRARY_DEBUG
MariaDB_LIBRARY_RELEASE
MariaDB_INCLUDE_DIR
)
-30
View File
@@ -1,30 +0,0 @@
if (NOT MSVC)
include(FindPkgConfig)
pkg_check_modules(PC_SODIUM "libsodium")
if (NOT PC_SODIUM_FOUND)
pkg_check_modules(PC_SODIUM "sodium")
endif (NOT PC_SODIUM_FOUND)
if (PC_SODIUM_FOUND)
set(SODIUM_INCLUDE_HINTS ${PC_SODIUM_INCLUDE_DIRS} ${PC_SODIUM_INCLUDE_DIRS}/*)
set(SODIUM_LIBRARY_HINTS ${PC_SODIUM_LIBRARY_DIRS} ${PC_SODIUM_LIBRARY_DIRS}/*)
endif()
endif (NOT MSVC)
# some libraries install the headers is a subdirectory of the include dir
# returned by pkg-config, so use a wildcard match to improve chances of finding
# headers and libraries.
find_path(
SODIUM_INCLUDE_DIRS
NAMES sodium.h
HINTS ${SODIUM_INCLUDE_HINTS}
)
find_library(
SODIUM_LIBRARIES
NAMES libsodium sodium
HINTS ${SODIUM_LIBRARY_HINTS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SODIUM DEFAULT_MSG SODIUM_LIBRARIES SODIUM_INCLUDE_DIRS)
mark_as_advanced(SODIUM_FOUND SODIUM_LIBRARIES SODIUM_INCLUDE_DIRS)
-93
View File
@@ -1,93 +0,0 @@
# - Try to find mbedTLS
# Once done this will define
#
# Read-Only variables
# MBEDTLS_FOUND - system has mbedTLS
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
# MBEDTLS_LIBRARY - path to mbedTLS library
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
#
# Hint
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.
SET(_MBEDTLS_ROOT_HINTS
${MBEDTLS_ROOT_DIR}
ENV MBEDTLS_ROOT_DIR
)
SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
HINTS ${_MBEDTLS_ROOT_HINTS}
PATHS ${_MBEDTLS_ROOT_PATHS}
)
FIND_PATH(MBEDTLS_INCLUDE_DIR
NAMES mbedtls/version.h
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES include
)
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
# Already in cache, be silent
SET(MBEDTLS_FIND_QUIETLY TRUE)
ENDIF()
FIND_LIBRARY(MBEDTLS_LIBRARY
NAMES mbedtls libmbedtls
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
FIND_LIBRARY(MBEDX509_LIBRARY
NAMES mbedx509 libmbedx509
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
NAMES mbedcrypto libmbedcrypto
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
PATH_SUFFIXES library
)
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
SET(MBEDTLS_FOUND TRUE)
ENDIF()
IF(MBEDTLS_FOUND)
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
IF(NOT MBEDTLS_FIND_QUIETLY)
MESSAGE(STATUS "Found mbedTLS:")
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
IF (MBEDTLSMATCH)
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
ENDIF(MBEDTLSMATCH)
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
ELSE(MBEDTLS_FOUND)
IF(MBEDTLS_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
ENDIF(MBEDTLS_FIND_REQUIRED)
ENDIF(MBEDTLS_FOUND)
MARK_AS_ADVANCED(
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARY_DIR
MBEDTLS_LIBRARIES
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY
)
+88 -121
View File
@@ -1,10 +1,8 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(common_sources
base_packet.cpp
classes.cpp
cli/eqemu_command_handler.cpp
compression.cpp
condition.cpp
crash.cpp
crc16.cpp
@@ -15,8 +13,11 @@ SET(common_sources
dbcore.cpp
deity.cpp
emu_constants.cpp
emu_legacy.cpp
emu_limits.cpp
emu_opcodes.cpp
emu_tcp_connection.cpp
emu_tcp_server.cpp
emu_versions.cpp
eqdb.cpp
eqdb_res.cpp
@@ -25,10 +26,11 @@ SET(common_sources
eqemu_logsys.cpp
eq_limits.cpp
eq_packet.cpp
eq_stream.cpp
eq_stream_factory.cpp
eq_stream_ident.cpp
eq_stream_proxy.cpp
eqtime.cpp
event_sub.cpp
extprofile.cpp
faction.cpp
guild_base.cpp
@@ -36,15 +38,12 @@ SET(common_sources
inventory_profile.cpp
inventory_slot.cpp
ipc_mutex.cpp
ip_util.cpp
item_data.cpp
item_instance.cpp
json_config.cpp
light_source.cpp
md5.cpp
memory_buffer.cpp
memory_mapped_file.cpp
metric_manager.cpp
misc.cpp
misc_functions.cpp
mutex.cpp
@@ -58,38 +57,26 @@ SET(common_sources
perl_eqdb.cpp
perl_eqdb_res.cpp
proc_launcher.cpp
profanity_manager.cpp
ptimer.cpp
races.cpp
rdtsc.cpp
rulesys.cpp
say_link.cpp
serialize_buffer.cpp
serverinfo.cpp
shareddb.cpp
skills.cpp
spdat.cpp
string_util.cpp
struct_strategy.cpp
tcp_connection.cpp
tcp_server.cpp
textures.cpp
timeoutmgr.cpp
timer.cpp
unix.cpp
worldconn.cpp
xml_parser.cpp
platform.cpp
json/jsoncpp.cpp
net/console_server.cpp
net/console_server_connection.cpp
net/crc32.cpp
net/daybreak_connection.cpp
net/eqstream.cpp
net/packet.cpp
net/servertalk_client_connection.cpp
net/servertalk_legacy_client_connection.cpp
net/servertalk_server.cpp
net/servertalk_server_connection.cpp
net/tcp_connection.cpp
net/tcp_server.cpp
net/websocket_server.cpp
net/websocket_server_connection.cpp
patches/patches.cpp
patches/sod.cpp
patches/sod_limits.cpp
@@ -103,9 +90,23 @@ SET(common_sources
patches/titanium_limits.cpp
patches/uf.cpp
patches/uf_limits.cpp
SocketLib/Base64.cpp
SocketLib/File.cpp
SocketLib/HttpdCookies.cpp
SocketLib/HttpdForm.cpp
SocketLib/HttpdSocket.cpp
SocketLib/HTTPSocket.cpp
SocketLib/MemFile.cpp
SocketLib/Mime.cpp
SocketLib/Parse.cpp
SocketLib/socket_include.cpp
SocketLib/Utility.cpp
StackWalker/StackWalker.cpp
util/directory.cpp
util/uuid.cpp)
tinyxml/tinystr.cpp
tinyxml/tinyxml.cpp
tinyxml/tinyxmlerror.cpp
tinyxml/tinyxmlparser.cpp
)
SET(common_headers
any.h
@@ -113,23 +114,21 @@ SET(common_headers
base_data.h
bodytypes.h
classes.h
compression.h
condition.h
crash.h
crc16.h
crc32.h
cli/argh.h
cli/eqemu_command_handler.h
cli/terminal_color.hpp
data_verification.h
database.h
database_schema.h
dbcore.h
deity.h
emu_constants.h
emu_legacy.h
emu_limits.h
emu_opcodes.h
emu_oplist.h
emu_tcp_connection.h
emu_tcp_server.h
emu_versions.h
eq_constants.h
eq_packet_structs.h
@@ -139,16 +138,17 @@ SET(common_headers
eqemu_config.h
eqemu_config_elements.h
eqemu_logsys.h
eqemu_logsys_log_aliases.h
eq_limits.h
eq_packet.h
eq_stream.h
eq_stream_factory.h
eq_stream_ident.h
eq_stream_intf.h
eq_stream_locator.h
eq_stream_proxy.h
eq_stream_type.h
eqtime.h
errmsg.h
event_sub.h
extprofile.h
faction.h
features.h
@@ -157,15 +157,12 @@ SET(common_headers
global_define.h
guild_base.h
guilds.h
http/httplib.h
inventory_profile.h
inventory_slot.h
ipc_mutex.h
ip_util.h
item_data.h
item_fieldlist.h
item_instance.h
json_config.h
languages.h
light_source.h
linked_list.h
@@ -174,8 +171,6 @@ SET(common_headers
md5.h
memory_buffer.h
memory_mapped_file.h
metric_event.h
metric_manager.h
misc.h
misc_functions.h
mutex.h
@@ -189,7 +184,6 @@ SET(common_headers
packet_functions.h
platform.h
proc_launcher.h
profanity_manager.h
profiler.h
ptimer.h
queue.h
@@ -200,7 +194,6 @@ SET(common_headers
ruletypes.h
say_link.h
seperator.h
serialize_buffer.h
serverinfo.h
servertalk.h
shareddb.h
@@ -208,36 +201,19 @@ SET(common_headers
spdat.h
string_util.h
struct_strategy.h
tcp_basic_server.h
tcp_connection.h
tcp_server.h
textures.h
timeoutmgr.h
timer.h
types.h
unix.h
useperl.h
version.h
worldconn.h
xml_parser.h
zone_numbers.h
event/event_loop.h
event/task.h
event/timer.h
json/json.h
json/json-forwards.h
net/console_server.h
net/console_server_connection.h
net/crc32.h
net/daybreak_connection.h
net/daybreak_structs.h
net/dns.h
net/endian.h
net/eqstream.h
net/packet.h
net/servertalk_client_connection.h
net/servertalk_legacy_client_connection.h
net/servertalk_common.h
net/servertalk_server.h
net/servertalk_server_connection.h
net/tcp_connection.h
net/tcp_server.h
net/websocket_server.h
net/websocket_server_connection.h
patches/patches.h
patches/sod.h
patches/sod_limits.h
@@ -266,58 +242,21 @@ SET(common_headers
patches/uf_limits.h
patches/uf_ops.h
patches/uf_structs.h
SocketLib/Base64.h
SocketLib/File.h
SocketLib/HttpdCookies.h
SocketLib/HttpdForm.h
SocketLib/HttpdSocket.h
SocketLib/HTTPSocket.h
SocketLib/IFile.h
SocketLib/MemFile.h
SocketLib/Mime.h
SocketLib/Parse.h
SocketLib/socket_include.h
SocketLib/Utility.h
StackWalker/StackWalker.h
util/memory_stream.h
util/directory.h
util/uuid.h)
SOURCE_GROUP(Event FILES
event/event_loop.h
event/timer.h
event/task.h
)
SOURCE_GROUP(Json FILES
json/json.h
json/jsoncpp.cpp
json/json-forwards.h
)
SOURCE_GROUP(Net FILES
net/console_server.cpp
net/console_server.h
net/console_server_connection.cpp
net/console_server_connection.h
net/crc32.cpp
net/crc32.h
net/daybreak_connection.cpp
net/daybreak_connection.h
net/daybreak_structs.h
net/dns.h
net/endian.h
net/eqmq.cpp
net/eqmq.h
net/eqstream.cpp
net/eqstream.h
net/packet.cpp
net/packet.h
net/servertalk_client_connection.cpp
net/servertalk_client_connection.h
net/servertalk_legacy_client_connection.cpp
net/servertalk_legacy_client_connection.h
net/servertalk_common.h
net/servertalk_server.cpp
net/servertalk_server.h
net/servertalk_server_connection.cpp
net/servertalk_server_connection.h
net/tcp_connection.cpp
net/tcp_connection.h
net/tcp_server.cpp
net/tcp_server.h
net/websocket_server.cpp
net/websocket_server.h
net/websocket_server_connection.cpp
net/websocket_server_connection.h
tinyxml/tinystr.h
tinyxml/tinyxml.h
)
SOURCE_GROUP(Patches FILES
@@ -364,24 +303,52 @@ SOURCE_GROUP(Patches FILES
patches/uf_limits.cpp
)
SOURCE_GROUP(SocketLib FILES
SocketLib/Base64.h
SocketLib/File.h
SocketLib/HttpdCookies.h
SocketLib/HttpdForm.h
SocketLib/HttpdSocket.h
SocketLib/HTTPSocket.h
SocketLib/IFile.h
SocketLib/MemFile.h
SocketLib/Mime.h
SocketLib/Parse.h
SocketLib/socket_include.h
SocketLib/Utility.h
SocketLib/Base64.cpp
SocketLib/File.cpp
SocketLib/HttpdCookies.cpp
SocketLib/HttpdForm.cpp
SocketLib/HttpdSocket.cpp
SocketLib/HTTPSocket.cpp
SocketLib/MemFile.cpp
SocketLib/Mime.cpp
SocketLib/Parse.cpp
SocketLib/socket_include.cpp
SocketLib/Utility.cpp
)
SOURCE_GROUP(StackWalker FILES
StackWalker/StackWalker.h
StackWalker/StackWalker.cpp
)
SOURCE_GROUP(Util FILES
util/memory_stream.h
util/directory.cpp
util/directory.h
util/uuid.cpp
util/uuid.h
SOURCE_GROUP(TinyXML FILES
tinyxml/tinystr.h
tinyxml/tinyxml.h
tinyxml/tinystr.cpp
tinyxml/tinyxml.cpp
tinyxml/tinyxmlerror.cpp
tinyxml/tinyxmlparser.cpp
)
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML)
ADD_LIBRARY(common ${common_sources} ${common_headers})
IF(UNIX)
ADD_DEFINITIONS(-fPIC)
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
ENDIF(UNIX)
+2 -2
View File
@@ -24,8 +24,8 @@ struct BaseDataStruct
double base_hp;
double base_mana;
double base_end;
double hp_regen;
double end_regen;
double unk1;
double unk2;
double hp_factor;
double mana_factor;
double endurance_factor;
-12
View File
@@ -39,18 +39,6 @@ BasePacket::BasePacket(const unsigned char *buf, uint32 len)
}
}
BasePacket::BasePacket(SerializeBuffer &buf)
{
pBuffer = buf.m_buffer;
buf.m_buffer = nullptr;
size = buf.m_pos;
buf.m_pos = 0;
buf.m_capacity = 0;
_wpos = 0;
_rpos = 0;
timestamp.tv_sec = 0;
}
BasePacket::~BasePacket()
{
if (pBuffer)
-5
View File
@@ -19,7 +19,6 @@
#define BASEPACKET_H_
#include "types.h"
#include "serialize_buffer.h"
#include <stdio.h>
#include <string.h>
@@ -64,8 +63,6 @@ public:
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); }
void WriteString(const char * str) { uint32 len = static_cast<uint32>(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; }
// this is used in task system a lot, it is NOT null-termed
void WriteLengthString(uint32 len, const char *str) { *(uint32 *)(pBuffer + _wpos) = len; _wpos += sizeof(uint32); memcpy(pBuffer + _wpos, str, len); _wpos += len; }
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; }
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
@@ -75,7 +72,6 @@ public:
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; }
void ReadString(char *str) { uint32 len = static_cast<uint32>(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; }
void ReadString(std::string &str) { str = reinterpret_cast<char *>(pBuffer + _rpos); _rpos += str.length() + 1; }
void ReadString(char *str, uint32 Offset, uint32 MaxLength) const;
uint32 GetWritePosition() { return _wpos; }
@@ -87,7 +83,6 @@ protected:
virtual ~BasePacket();
BasePacket() { pBuffer=nullptr; size=0; _wpos = 0; _rpos = 0; }
BasePacket(const unsigned char *buf, const uint32 len);
BasePacket(SerializeBuffer &buf);
};
extern void DumpPacketHex(const BasePacket* app);
-1
View File
@@ -35,7 +35,6 @@ typedef enum {
BT_Greater_Akheva = 14,
BT_Khati_Sha = 15,
BT_Seru = 16, //not confirmed....
BT_Draz_Nurakk = 18,
BT_Zek = 19,
BT_Luggald = 20,
BT_Animal = 21,
+471 -587
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -135,7 +135,6 @@ uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
bool IsFighterClass(uint8 class_id);
bool IsSpellFighterClass(uint8 class_id);
bool IsNonSpellFighterClass(uint8 class_id);
bool IsHybridClass(uint8 class_id);
bool IsCasterClass(uint8 class_id);
bool IsINTCasterClass(uint8 class_id);
bool IsWISCasterClass(uint8 class_id);
-434
View File
@@ -1,434 +0,0 @@
#pragma once
#include <algorithm>
#include <sstream>
#include <limits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cassert>
namespace argh
{
// Terminology:
// A command line is composed of 2 types of args:
// 1. Positional args, i.e. free standing values
// 2. Options: args beginning with '-'. We identify two kinds:
// 2.1: Flags: boolean options => (exist ? true : false)
// 2.2: Parameters: a name followed by a non-option value
#if !defined(__GNUC__) || (__GNUC__ >= 5)
using string_stream = std::istringstream;
#else
// Until GCC 5, istringstream did not have a move constructor.
// stringstream_proxy is used instead, as a workaround.
class stringstream_proxy
{
public:
stringstream_proxy() = default;
// Construct with a value.
stringstream_proxy(std::string const& value) :
stream_(value)
{}
// Copy constructor.
stringstream_proxy(const stringstream_proxy& other) :
stream_(other.stream_.str())
{
stream_.setstate(other.stream_.rdstate());
}
void setstate(std::ios_base::iostate state) { stream_.setstate(state); }
// Stream out the value of the parameter.
// If the conversion was not possible, the stream will enter the fail state,
// and operator bool will return false.
template<typename T>
stringstream_proxy& operator >> (T& thing)
{
stream_ >> thing;
return *this;
}
// Get the string value.
std::string str() const { return stream_.str(); }
std::stringbuf* rdbuf() const { return stream_.rdbuf(); }
// Check the state of the stream.
// False when the most recent stream operation failed
operator bool() const { return !!stream_; }
~stringstream_proxy() = default;
private:
std::istringstream stream_;
};
using string_stream = stringstream_proxy;
#endif
class parser
{
public:
enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0,
PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1,
NO_SPLIT_ON_EQUALSIGN = 1 << 2,
SINGLE_DASH_IS_MULTIFLAG = 1 << 3,
};
parser() = default;
parser(std::initializer_list<char const* const> pre_reg_names)
{ add_params(pre_reg_names); }
parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
{ parse(argv, mode); }
parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
{ parse(argc, argv, mode); }
void add_param(std::string const& name);
void add_params(std::initializer_list<char const* const> init_list);
void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
std::multiset<std::string> const& flags() const { return flags_; }
std::map<std::string, std::string> const& params() const { return params_; }
std::vector<std::string> const& pos_args() const { return pos_args_; }
// begin() and end() for using range-for over positional args.
std::vector<std::string>::const_iterator begin() const { return pos_args_.cbegin(); }
std::vector<std::string>::const_iterator end() const { return pos_args_.cend(); }
size_t size() const { return pos_args_.size(); }
//////////////////////////////////////////////////////////////////////////
// Accessors
// flag (boolean) accessors: return true if the flag appeared, otherwise false.
bool operator[](std::string const& name) const;
// multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false.
bool operator[](std::initializer_list<char const* const> init_list) const;
// returns positional arg string by order. Like argv[] but without the options
std::string const& operator[](size_t ind) const;
// returns a std::istream that can be used to convert a positional arg to a typed value.
string_stream operator()(size_t ind) const;
// same as above, but with a default value in case the arg is missing (index out of range).
template<typename T>
string_stream operator()(size_t ind, T&& def_val) const;
// parameter accessors, give a name get an std::istream that can be used to convert to a typed value.
// call .str() on result to get as string
string_stream operator()(std::string const& name) const;
// accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value.
// call .str() on result to get as string
// returns the first value in the list to be found.
string_stream operator()(std::initializer_list<char const* const> init_list) const;
// same as above, but with a default value in case the param was missing.
// Non-string def_val types must have an operator<<() (output stream operator)
// If T only has an input stream operator, pass the string version of the type as in "3" instead of 3.
template<typename T>
string_stream operator()(std::string const& name, T&& def_val) const;
// same as above but for a list of names. returns the first value to be found.
template<typename T>
string_stream operator()(std::initializer_list<char const* const> init_list, T&& def_val) const;
private:
string_stream bad_stream() const;
std::string trim_leading_dashes(std::string const& name) const;
bool is_number(std::string const& arg) const;
bool is_option(std::string const& arg) const;
bool got_flag(std::string const& name) const;
bool is_param(std::string const& name) const;
private:
std::vector<std::string> args_;
std::map<std::string, std::string> params_;
std::vector<std::string> pos_args_;
std::multiset<std::string> flags_;
std::set<std::string> registeredParams_;
std::string empty_;
};
//////////////////////////////////////////////////////////////////////////
inline void parser::parse(const char * const argv[], int mode)
{
int argc = 0;
for (auto argvp = argv; *argvp; ++argc, ++argvp);
parse(argc, argv, mode);
}
//////////////////////////////////////////////////////////////////////////
inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/)
{
// convert to strings
args_.resize(argc);
std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; });
// parse line
for (auto i = 0u; i < args_.size(); ++i)
{
if (!is_option(args_[i]))
{
pos_args_.emplace_back(args_[i]);
continue;
}
auto name = trim_leading_dashes(args_[i]);
if (!(mode & NO_SPLIT_ON_EQUALSIGN))
{
auto equalPos = name.find('=');
if (equalPos != std::string::npos)
{
params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) });
continue;
}
}
// if the option is unregistered and should be a multi-flag
if (1 == (args_[i].size() - name.size()) && // single dash
argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode
!is_param(name)) // unregistered
{
std::string keep_param;
if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param
{
keep_param += name.back();
name.resize(name.size() - 1);
}
for (auto const& c : name)
{
flags_.emplace(std::string{ c });
}
if (!keep_param.empty())
{
name = keep_param;
}
else
{
continue; // do not consider other options for this arg
}
}
// any potential option will get as its value the next arg, unless that arg is an option too
// in that case it will be determined a flag.
if (i == args_.size() - 1 || is_option(args_[i + 1]))
{
flags_.emplace(name);
continue;
}
// if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped
// otherwise we have 2 modes:
// PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag.
// The following value (the next arg) will be a free parameter.
//
// PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg
// will be the value of that option.
assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION)
|| !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION));
bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION;
if (is_param(name) || preferParam)
{
params_.insert({ name, args_[i + 1] });
++i; // skip next value, it is not a free parameter
continue;
}
else
{
flags_.emplace(name);
}
};
}
//////////////////////////////////////////////////////////////////////////
inline string_stream parser::bad_stream() const
{
string_stream bad;
bad.setstate(std::ios_base::failbit);
return bad;
}
//////////////////////////////////////////////////////////////////////////
inline bool parser::is_number(std::string const& arg) const
{
// inefficient but simple way to determine if a string is a number (which can start with a '-')
std::istringstream istr(arg);
double number;
istr >> number;
return !(istr.fail() || istr.bad());
}
//////////////////////////////////////////////////////////////////////////
inline bool parser::is_option(std::string const& arg) const
{
assert(0 != arg.size());
if (is_number(arg))
return false;
return '-' == arg[0];
}
//////////////////////////////////////////////////////////////////////////
inline std::string parser::trim_leading_dashes(std::string const& name) const
{
auto pos = name.find_first_not_of('-');
return std::string::npos != pos ? name.substr(pos) : name;
}
//////////////////////////////////////////////////////////////////////////
inline bool argh::parser::got_flag(std::string const& name) const
{
return flags_.end() != flags_.find(trim_leading_dashes(name));
}
//////////////////////////////////////////////////////////////////////////
inline bool argh::parser::is_param(std::string const& name) const
{
return registeredParams_.count(name);
}
//////////////////////////////////////////////////////////////////////////
inline bool parser::operator[](std::string const& name) const
{
return got_flag(name);
}
//////////////////////////////////////////////////////////////////////////
inline bool parser::operator[](std::initializer_list<char const* const> init_list) const
{
return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); });
}
//////////////////////////////////////////////////////////////////////////
inline std::string const& parser::operator[](size_t ind) const
{
if (ind < pos_args_.size())
return pos_args_[ind];
return empty_;
}
//////////////////////////////////////////////////////////////////////////
inline string_stream parser::operator()(std::string const& name) const
{
auto optIt = params_.find(trim_leading_dashes(name));
if (params_.end() != optIt)
return string_stream(optIt->second);
return bad_stream();
}
//////////////////////////////////////////////////////////////////////////
inline string_stream parser::operator()(std::initializer_list<char const* const> init_list) const
{
for (auto& name : init_list)
{
auto optIt = params_.find(trim_leading_dashes(name));
if (params_.end() != optIt)
return string_stream(optIt->second);
}
return bad_stream();
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
string_stream parser::operator()(std::string const& name, T&& def_val) const
{
auto optIt = params_.find(trim_leading_dashes(name));
if (params_.end() != optIt)
return string_stream(optIt->second);
std::ostringstream ostr;
ostr.precision(std::numeric_limits<long double>::max_digits10);
ostr << def_val;
return string_stream(ostr.str()); // use default
}
//////////////////////////////////////////////////////////////////////////
// same as above but for a list of names. returns the first value to be found.
template<typename T>
string_stream parser::operator()(std::initializer_list<char const* const> init_list, T&& def_val) const
{
for (auto& name : init_list)
{
auto optIt = params_.find(trim_leading_dashes(name));
if (params_.end() != optIt)
return string_stream(optIt->second);
}
std::ostringstream ostr;
ostr.precision(std::numeric_limits<long double>::max_digits10);
ostr << def_val;
return string_stream(ostr.str()); // use default
}
//////////////////////////////////////////////////////////////////////////
inline string_stream parser::operator()(size_t ind) const
{
if (pos_args_.size() <= ind)
return bad_stream();
return string_stream(pos_args_[ind]);
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
string_stream parser::operator()(size_t ind, T&& def_val) const
{
if (pos_args_.size() <= ind)
{
std::ostringstream ostr;
ostr.precision(std::numeric_limits<long double>::max_digits10);
ostr << def_val;
return string_stream(ostr.str());
}
return string_stream(pos_args_[ind]);
}
//////////////////////////////////////////////////////////////////////////
inline void parser::add_param(std::string const& name)
{
registeredParams_.insert(trim_leading_dashes(name));
}
//////////////////////////////////////////////////////////////////////////
inline void parser::add_params(std::initializer_list<char const* const> init_list)
{
for (auto& name : init_list)
registeredParams_.insert(trim_leading_dashes(name));
}
}
-194
View File
@@ -1,194 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <fmt/format.h>
#include "eqemu_command_handler.h"
#include "terminal_color.hpp"
#include "../platform.h"
namespace EQEmuCommand {
std::map<std::string, void (*)(
int argc,
char **argv,
argh::parser &cmd,
std::string &description
)> function_map;
/**
* @param cmd
*/
void DisplayDebug(argh::parser &cmd)
{
if (cmd[{"-d", "--debug"}]) {
std::cout << "Positional args:\n";
for (auto &pos_arg : cmd.pos_args())
std::cout << '\t' << pos_arg << std::endl;
std::cout << "\nFlags:\n";
for (auto &flag : cmd.flags())
std::cout << '\t' << flag << std::endl;
std::cout << "\nParameters:\n";
for (auto &param : cmd.params())
std::cout << '\t' << param.first << " : " << param.second << std::endl;
}
}
/**
* @param arguments
* @param options
* @param cmd
* @param argc
* @param argv
*/
void ValidateCmdInput(
std::vector<std::string> &arguments,
std::vector<std::string> &options,
argh::parser &cmd,
int argc,
char **argv
)
{
bool arguments_filled = true;
int index = 2;
for (auto &arg : arguments) {
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
arguments_filled = false;
}
index++;
}
if (!arguments_filled || argc == 2) {
std::string arguments_string;
for (auto &arg : arguments) {
arguments_string += " " + arg;
}
std::string options_string;
for (auto &opt : options) {
options_string += " " + opt + "\n";
}
std::stringstream command_string;
command_string <<
termcolor::colorize <<
termcolor::yellow <<
"\nCommand" <<
termcolor::reset << "\n\n" <<
termcolor::green << argv[1] << arguments_string << termcolor::reset << "\n" <<
termcolor::yellow << (!options_string.empty() ? "\nOptions\n" : "") <<
termcolor::reset << termcolor::cyan << options_string << termcolor::reset;
std::cout << command_string.str() << std::endl;
exit(1);
}
}
/**
* @param in_function_map
* @param cmd
* @param argc
* @param argv
*/
void HandleMenu(
std::map<std::string, void (*)(
int argc,
char **argv,
argh::parser &cmd,
std::string &description
)> &in_function_map,
argh::parser &cmd,
int argc,
char **argv
)
{
std::string description;
bool ran_command = false;
for (auto &it: in_function_map) {
if (it.first == argv[1]) {
(it.second)(argc, argv, cmd, description);
ran_command = true;
}
}
if (cmd[{"-h", "--help"}]) {
std::cout << std::endl;
std::cout <<
"> " <<
termcolor::yellow <<
"EQEmulator [" + GetPlatformName() + "] CLI Menu" <<
termcolor::reset
<< std::endl
<< std::endl;
/**
* Get max command length for padding length
*/
int max_command_length = 0;
for (auto &it: in_function_map) {
std::stringstream command;
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
if (command.str().length() > max_command_length) {
max_command_length = command.str().length() + 1;
}
}
/**
* Display command menu
*/
std::string command_section;
for (auto &it: in_function_map) {
description = "";
(it.second)(argc, argv, cmd, description);
/**
* Print section header
*/
std::string command_prefix = it.first.substr(0, it.first.find(":"));
if (command_section != command_prefix) {
command_section = command_prefix;
std::cout << termcolor::reset << command_prefix << std::endl;
}
/**
* Print commands
*/
std::stringstream command;
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
}
std::cout << std::endl;
std::exit(1);
}
if (ran_command) {
std::exit(1);
}
}
}
-75
View File
@@ -1,75 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef EQEMU_EQEMU_COMMAND_HANDLER_H
#define EQEMU_EQEMU_COMMAND_HANDLER_H
#include "argh.h"
namespace EQEmuCommand {
extern std::map<std::string, void (*)(
int argc,
char **argv,
argh::parser &cmd,
std::string &description
)> function_map;
/**
* @param arguments
* @param options
* @param cmd
* @param argc
* @param argv
*/
void ValidateCmdInput(
std::vector<std::string> &arguments,
std::vector<std::string> &options,
argh::parser &cmd,
int argc,
char **argv
);
/**
* @param cmd
*/
void DisplayDebug(argh::parser &cmd);
/**
* @param in_function_map
* @param cmd
* @param argc
* @param argv
*/
void HandleMenu(
std::map<std::string, void (*)(
int argc,
char **argv,
argh::parser &cmd,
std::string &description
)> &in_function_map,
argh::parser &cmd,
int argc,
char **argv
);
};
#endif //EQEMU_EQEMU_COMMAND_HANDLER_H
-557
View File
@@ -1,557 +0,0 @@
//!
//! termcolor
//! ~~~~~~~~~
//!
//! termcolor is a header-only c++ library for printing colored messages
//! to the terminal. Written just for fun with a help of the Force.
//!
//! :copyright: (c) 2013 by Ihor Kalnytskyi
//! :license: BSD, see LICENSE for details
//!
#ifndef TERMCOLOR_HPP_
#define TERMCOLOR_HPP_
// the following snippet of code detects the current OS and
// defines the appropriate macro that is used to wrap some
// platform specific things
#if defined(_WIN32) || defined(_WIN64)
# define TERMCOLOR_OS_WINDOWS
#elif defined(__APPLE__)
# define TERMCOLOR_OS_MACOS
#elif defined(__unix__) || defined(__unix)
# define TERMCOLOR_OS_LINUX
#else
# error unsupported platform
#endif
// This headers provides the `isatty()`/`fileno()` functions,
// which are used for testing whether a standart stream refers
// to the terminal. As for Windows, we also need WinApi funcs
// for changing colors attributes of the terminal.
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
# include <unistd.h>
#elif defined(TERMCOLOR_OS_WINDOWS)
# include <io.h>
# include <windows.h>
#endif
#include <iostream>
#include <cstdio>
namespace termcolor
{
// Forward declaration of the `_internal` namespace.
// All comments are below.
namespace _internal
{
// An index to be used to access a private storage of I/O streams. See
// colorize / nocolorize I/O manipulators for details.
static int colorize_index = std::ios_base::xalloc();
inline FILE* get_standard_stream(const std::ostream& stream);
inline bool is_colorized(std::ostream& stream);
inline bool is_atty(const std::ostream& stream);
#if defined(TERMCOLOR_OS_WINDOWS)
inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
#endif
}
inline
std::ostream& colorize(std::ostream& stream)
{
stream.iword(_internal::colorize_index) = 1L;
return stream;
}
inline
std::ostream& nocolorize(std::ostream& stream)
{
stream.iword(_internal::colorize_index) = 0L;
return stream;
}
inline
std::ostream& reset(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;00m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1, -1);
#endif
}
return stream;
}
inline
std::ostream& bold(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;1m";
#elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline
std::ostream& dark(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;2m";
#elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline
std::ostream& underline(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;4m";
#elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline
std::ostream& blink(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;5m";
#elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline
std::ostream& reverse(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;7m";
#elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline
std::ostream& concealed(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;8m";
#elif defined(TERMCOLOR_OS_WINDOWS)
#endif
}
return stream;
}
inline
std::ostream& grey(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;30m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
0 // grey (black)
);
#endif
}
return stream;
}
inline
std::ostream& red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;31m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& green(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;32m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN
);
#endif
}
return stream;
}
inline
std::ostream& yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;33m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& blue(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;34m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE
);
#endif
}
return stream;
}
inline
std::ostream& magenta(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;35m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& cyan(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;36m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN
);
#endif
}
return stream;
}
inline
std::ostream& white(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;37m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_grey(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;40m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
0 // grey (black)
);
#endif
}
return stream;
}
inline
std::ostream& on_red(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;41m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_green(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;42m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN
);
#endif
}
return stream;
}
inline
std::ostream& on_yellow(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;43m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_blue(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;44m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE
);
#endif
}
return stream;
}
inline
std::ostream& on_magenta(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;45m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
inline
std::ostream& on_cyan(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;46m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE
);
#endif
}
return stream;
}
inline
std::ostream& on_white(std::ostream& stream)
{
if (_internal::is_colorized(stream))
{
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
stream << "\e[1;47m";
#elif defined(TERMCOLOR_OS_WINDOWS)
_internal::win_change_attributes(stream, -1,
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
);
#endif
}
return stream;
}
//! Since C++ hasn't a way to hide something in the header from
//! the outer access, I have to introduce this namespace which
//! is used for internal purpose and should't be access from
//! the user code.
namespace _internal
{
//! Since C++ hasn't a true way to extract stream handler
//! from the a given `std::ostream` object, I have to write
//! this kind of hack.
inline
FILE* get_standard_stream(const std::ostream& stream)
{
if (&stream == &std::cout)
return stdout;
else if ((&stream == &std::cerr) || (&stream == &std::clog))
return stderr;
return 0;
}
// Say whether a given stream should be colorized or not. It's always
// true for ATTY streams and may be true for streams marked with
// colorize flag.
inline
bool is_colorized(std::ostream& stream)
{
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index));
}
//! Test whether a given `std::ostream` object refers to
//! a terminal.
inline
bool is_atty(const std::ostream& stream)
{
FILE* std_stream = get_standard_stream(stream);
// Unfortunately, fileno() ends with segmentation fault
// if invalid file descriptor is passed. So we need to
// handle this case gracefully and assume it's not a tty
// if standard stream is not detected, and 0 is returned.
if (!std_stream)
return false;
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
return ::isatty(fileno(std_stream));
#elif defined(TERMCOLOR_OS_WINDOWS)
return ::_isatty(_fileno(std_stream));
#endif
}
#if defined(TERMCOLOR_OS_WINDOWS)
//! Change Windows Terminal colors attribute. If some
//! parameter is `-1` then attribute won't changed.
inline void win_change_attributes(std::ostream& stream, int foreground, int background)
{
// yeah, i know.. it's ugly, it's windows.
static WORD defaultAttributes = 0;
// Windows doesn't have ANSI escape sequences and so we use special
// API to change Terminal output color. That means we can't
// manipulate colors by means of "std::stringstream" and hence
// should do nothing in this case.
if (!_internal::is_atty(stream))
return;
// get terminal handle
HANDLE hTerminal = INVALID_HANDLE_VALUE;
if (&stream == &std::cout)
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
else if (&stream == &std::cerr)
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
// save default terminal attributes if it unsaved
if (!defaultAttributes)
{
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
return;
defaultAttributes = info.wAttributes;
}
// restore all default settings
if (foreground == -1 && background == -1)
{
SetConsoleTextAttribute(hTerminal, defaultAttributes);
return;
}
// get current settings
CONSOLE_SCREEN_BUFFER_INFO info;
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
return;
if (foreground != -1)
{
info.wAttributes &= ~(info.wAttributes & 0x0F);
info.wAttributes |= static_cast<WORD>(foreground);
}
if (background != -1)
{
info.wAttributes &= ~(info.wAttributes & 0xF0);
info.wAttributes |= static_cast<WORD>(background);
}
SetConsoleTextAttribute(hTerminal, info.wAttributes);
}
#endif // TERMCOLOR_OS_WINDOWS
} // namespace _internal
} // namespace termcolor
#undef TERMCOLOR_OS_WINDOWS
#undef TERMCOLOR_OS_MACOS
#undef TERMCOLOR_OS_LINUX
#endif // TERMCOLOR_HPP_
-82
View File
@@ -1,82 +0,0 @@
#include "global_define.h"
#include "types.h"
#include <string.h>
#include <zlib.h>
namespace EQEmu
{
uint32 EstimateDeflateBuffer(uint32 len) {
z_stream zstream;
memset(&zstream, 0, sizeof(zstream));
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
if (deflateInit(&zstream, Z_FINISH) != Z_OK)
return 0;
return deflateBound(&zstream, len);
}
uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max) {
z_stream zstream;
memset(&zstream, 0, sizeof(zstream));
int zerror;
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
zstream.avail_in = len;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
deflateInit(&zstream, Z_FINISH);
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);
zstream.avail_out = out_len_max;
zerror = deflate(&zstream, Z_FINISH);
if (zerror == Z_STREAM_END)
{
deflateEnd(&zstream);
return (uint32)zstream.total_out;
}
else
{
zerror = deflateEnd(&zstream);
return 0;
}
}
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) {
z_stream zstream;
int zerror = 0;
int i;
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
zstream.avail_in = len;
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);;
zstream.avail_out = out_len_max;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
i = inflateInit2(&zstream, 15);
if (i != Z_OK) {
return 0;
}
zerror = inflate(&zstream, Z_FINISH);
if (zerror == Z_STREAM_END) {
inflateEnd(&zstream);
return zstream.total_out;
}
else {
if (zerror == -4 && zstream.msg == 0)
{
return 0;
}
zerror = inflateEnd(&zstream);
return 0;
}
}
}
-8
View File
@@ -1,8 +0,0 @@
#pragma once
namespace EQEmu
{
uint32 EstimateDeflateBuffer(uint32 len);
uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max);
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max);
}
+23 -76
View File
@@ -25,7 +25,7 @@ public:
}
}
Log(Logs::General, Logs::Crash, buffer);
Log.Out(Logs::General, Logs::Crash, buffer);
StackWalker::OnOutput(szText);
}
};
@@ -35,67 +35,67 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
switch(ExceptionInfo->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
Log(Logs::General, Logs::Crash, "EXCEPTION_ACCESS_VIOLATION");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ACCESS_VIOLATION");
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
Log(Logs::General, Logs::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
break;
case EXCEPTION_BREAKPOINT:
Log(Logs::General, Logs::Crash, "EXCEPTION_BREAKPOINT");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_BREAKPOINT");
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
Log(Logs::General, Logs::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT");
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND");
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO");
break;
case EXCEPTION_FLT_INEXACT_RESULT:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_INEXACT_RESULT");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_INEXACT_RESULT");
break;
case EXCEPTION_FLT_INVALID_OPERATION:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_INVALID_OPERATION");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_INVALID_OPERATION");
break;
case EXCEPTION_FLT_OVERFLOW:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_OVERFLOW");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_OVERFLOW");
break;
case EXCEPTION_FLT_STACK_CHECK:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_STACK_CHECK");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_STACK_CHECK");
break;
case EXCEPTION_FLT_UNDERFLOW:
Log(Logs::General, Logs::Crash, "EXCEPTION_FLT_UNDERFLOW");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_UNDERFLOW");
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
Log(Logs::General, Logs::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION");
break;
case EXCEPTION_IN_PAGE_ERROR:
Log(Logs::General, Logs::Crash, "EXCEPTION_IN_PAGE_ERROR");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_IN_PAGE_ERROR");
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
Log(Logs::General, Logs::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO");
break;
case EXCEPTION_INT_OVERFLOW:
Log(Logs::General, Logs::Crash, "EXCEPTION_INT_OVERFLOW");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INT_OVERFLOW");
break;
case EXCEPTION_INVALID_DISPOSITION:
Log(Logs::General, Logs::Crash, "EXCEPTION_INVALID_DISPOSITION");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INVALID_DISPOSITION");
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
Log(Logs::General, Logs::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION");
break;
case EXCEPTION_PRIV_INSTRUCTION:
Log(Logs::General, Logs::Crash, "EXCEPTION_PRIV_INSTRUCTION");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_PRIV_INSTRUCTION");
break;
case EXCEPTION_SINGLE_STEP:
Log(Logs::General, Logs::Crash, "EXCEPTION_SINGLE_STEP");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_SINGLE_STEP");
break;
case EXCEPTION_STACK_OVERFLOW:
Log(Logs::General, Logs::Crash, "EXCEPTION_STACK_OVERFLOW");
Log.Out(Logs::General, Logs::Crash, "EXCEPTION_STACK_OVERFLOW");
break;
default:
Log(Logs::General, Logs::Crash, "Unknown Exception");
Log.Out(Logs::General, Logs::Crash, "Unknown Exception");
break;
}
@@ -111,60 +111,7 @@ void set_exception_handler() {
SetUnhandledExceptionFilter(windows_exception_handler);
}
#else
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/fcntl.h>
void print_trace()
{
auto uid = geteuid();
std::string temp_output_file = "/tmp/dump-output";
char pid_buf[30];
sprintf(pid_buf, "%d", getpid());
char name_buf[512];
name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
int child_pid = fork();
if (!child_pid) {
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
dup2(fd, 1); // redirect output to stderr
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
if (uid == 0) {
execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
}
else {
execlp("sudo", "gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
}
close(fd);
abort(); /* If gdb failed to start */
}
else {
waitpid(child_pid, NULL, 0);
}
std::ifstream input(temp_output_file);
for (std::string line; getline(input, line);) {
LogCrash("{}", line);
}
std::remove(temp_output_file.c_str());
exit(1);
}
// crash is off or an unhandled platform
void set_exception_handler()
{
signal(SIGABRT, reinterpret_cast<void (*)(int)>(print_trace));
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
signal(SIGSEGV, reinterpret_cast<void (*)(int)>(print_trace));
void set_exception_handler() {
}
#endif
+36 -38
View File
@@ -1,57 +1,55 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* EQEMu: Everquest Server Emulator
#pragma once
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_DATA_VERIFICATION_H
#define COMMON_DATA_VERIFICATION_H
#include <algorithm>
#include <cmath>
namespace EQEmu {
template<typename T>
T Clamp(const T &value, const T &lower, const T &upper)
{
namespace EQEmu
{
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper) {
return std::max(lower, std::min(value, upper));
}
template<typename T>
T ClampLower(const T &value, const T &lower)
{
template <typename T>
T ClampLower(const T& value, const T& lower) {
return std::max(lower, value);
}
template<typename T>
T ClampUpper(const T &value, const T &upper)
{
template <typename T>
T ClampUpper(const T& value, const T& upper) {
return std::min(value, upper);
}
template<typename T>
bool ValueWithin(const T &value, const T &lower, const T &upper)
{
template <typename T>
bool ValueWithin(const T& value, const T& lower, const T& upper) {
return value >= lower && value <= upper;
}
template<typename T1, typename T2, typename T3>
bool ValueWithin(const T1 &value, const T2 &lower, const T3 &upper)
{
return value >= (T1) lower && value <= (T1) upper;
template <typename T1, typename T2, typename T3>
bool ValueWithin(const T1& value, const T2& lower, const T3& upper) {
return value >= (T1)lower && value <= (T1)upper;
}
} /*EQEmu*/
#endif /*COMMON_DATA_VERIFICATION_H*/
+241 -419
View File
File diff suppressed because it is too large Load Diff
+10 -15
View File
@@ -94,8 +94,6 @@ class PTimerList;
# define _ISNAN_(a) std::isnan(a)
#endif
#define SQL(...) #__VA_ARGS__
class Database : public DBcore {
public:
Database();
@@ -107,7 +105,7 @@ public:
bool AddToNameFilter(const char* name);
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
bool DeleteCharacter(char* character_name);
bool DeleteCharacter(char* name);
bool MoveCharacterToZone(const char* charname, const char* zonename);
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
@@ -120,7 +118,7 @@ public:
/* General Information Queries */
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the Banned_IPs table.
bool AddGMIP(char* ip_address, char* name);
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
bool CheckGMIPs(const char* loginIP, uint32 account_id);
@@ -129,7 +127,7 @@ public:
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const char *name);
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
uint32 GetGuildIDByCharID(uint32 char_id);
@@ -176,18 +174,18 @@ public:
/* Account Related */
bool DeleteAccount(const char *name, const char* loginserver);
bool DeleteAccount(const char* name);
bool GetLiveChar(uint32 account_id, char* cname);
bool SetAccountStatus(const char* name, int16 status);
bool SetAccountStatus(const std::string& account_name, int16 status);
bool SetLocalPassword(uint32 accid, const char* password);
bool UpdateLiveChar(char* charname, uint32 account_id);
bool UpdateLiveChar(char* charname, uint32 lsaccount_id);
int16 CheckStatus(uint32 account_id);
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0);
uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0);
uint32 GetMiniLoginAccount(char* ip);
uint8 GetAgreementFlag(uint32 acctid);
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
@@ -223,8 +221,6 @@ public:
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
void PurgeAllDeletedDataBuckets();
/* Database Conversions 'database_conversions.cpp' */
bool CheckDatabaseConversions();
@@ -266,8 +262,7 @@ public:
void SetLFP(uint32 CharID, bool LFP);
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
int CountInvSnapshots();
void ClearInvSnapshots(bool from_now = false);
void ClearInvSnapshots(bool use_rule = true);
/* EQEmuLogSys */
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
+18 -11
View File
@@ -41,9 +41,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#pragma pack(1)
// all const/macro reference values should really be converted to a magic number for this
// process to ensure that the struct sizes and offsets match up to the corresponding blob
/* Conversion Structs */
namespace Convert {
@@ -217,7 +214,7 @@ namespace Convert {
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[9]; //in ms
/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
@@ -256,9 +253,9 @@ namespace Convert {
/*2505*/ uint8 unknown2541[47]; // ?
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[480];
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[9];
/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
@@ -333,7 +330,7 @@ namespace Convert {
/*7212*/ uint32 tribute_points;
/*7216*/ uint32 unknown7252;
/*7220*/ uint32 tribute_active; //1=active
/*7224*/ Convert::Tribute_Struct tributes[5];
/*7224*/ Convert::Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE];
/*7264*/ Convert::Disciplines_Struct disciplines;
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
/*7744*/ char unknown7780[160];
@@ -475,8 +472,18 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertPPDeblob();
CheckDatabaseConvertCorpseDeblob();
/* Fetch EQEmu Server script */
if (!std::ifstream("eqemu_server.pl")){
std::cout << "Pulling down automatic database upgrade script..." << std::endl;
#ifdef _WIN32
system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"");
#else
system("wget --no-check-certificate -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl");
#endif
}
/* Run EQEmu Server script (Checks for database updates) */
if(system("perl eqemu_server.pl ran_from_world"));
system("perl eqemu_server.pl ran_from_world");
return true;
}
@@ -1360,7 +1367,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Spell Convert */
first_entry = 0; rquery = "";
for (i = 0; i < 480; i++){
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){
if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]);
@@ -1372,7 +1379,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Max Memmed Spell Convert */
first_entry = 0; rquery = "";
for (i = 0; i < 9; i++){
for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){
if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]);
@@ -1408,7 +1415,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Tribute Convert */
first_entry = 0; rquery = "";
for (i = 0; i < 5; i++){
for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++){
if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
+3 -10
View File
@@ -38,23 +38,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <sys/time.h>
#endif
/**
* @param instance_id
* @param char_id
* @return
*/
bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id)
{
std::string query = StringFormat(
"REPLACE INTO `instance_list_player` (id, charid) "
"VALUES "
"(%lu, %lu)",
(unsigned long) instance_id,
(unsigned long) char_id
);
(unsigned long)instance_id,
(unsigned long)char_id
);
auto results = QueryDatabase(query);
return results.Success();
}
-295
View File
@@ -1,295 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef EQEMU_DATABASE_SCHEMA_H
#define EQEMU_DATABASE_SCHEMA_H
#include <vector>
namespace DatabaseSchema {
/**
* Gets player tables
*
* @return
*/
static std::vector<std::string> GetPlayerTables()
{
std::vector<std::string> tables = {
"account",
"account_ip",
"account_flags",
"account_rewards",
"adventure_details",
"adventure_stats",
"buyer",
"char_recipe_list",
"character_activities",
"character_alt_currency",
"character_alternate_abilities",
"character_auras",
"character_bandolier",
"character_bind",
"character_buffs",
"character_corpse_items",
"character_corpses",
"character_currency",
"character_data",
"character_disciplines",
"character_enabledtasks",
"character_inspect_messages",
"character_item_recast",
"character_languages",
"character_leadership_abilities",
"character_material",
"character_memmed_spells",
"character_pet_buffs",
"character_pet_info",
"character_pet_inventory",
"character_potionbelt",
"character_skills",
"character_spells",
"character_tasks",
"character_tribute",
"completed_tasks",
"data_buckets",
"faction_values",
"friends",
"guild_bank",
"guild_members",
"guild_ranks",
"guild_relations",
"guilds",
"instance_list_player",
"inventory",
"inventory_snapshots",
"keyring",
"mail",
"player_titlesets",
"quest_globals",
"sharedbank",
"timers",
"titles",
"trader",
"trader_audit",
"zone_flags"
};
return tables;
}
/**
* Gets content tables
*
* @return
*/
static std::vector<std::string> GetContentTables()
{
std::vector<std::string> tables = {
"aa_ability",
"aa_actions",
"aa_effects",
"aa_rank_effects",
"aa_rank_prereqs",
"aa_ranks",
"aa_required_level_cost",
"adventure_template",
"adventure_template_entry",
"adventure_template_entry_flavor",
"altadv_vars",
"alternate_currency",
"auras",
"base_data",
"blocked_spells",
"books",
"char_create_combinations",
"char_create_point_allocations",
"class_skill",
"damageshieldtypes",
"doors",
"faction_base_data",
"faction_list",
"faction_list_mod",
"fear_hints",
"fishing",
"forage",
"global_loot",
"goallists",
"graveyard",
"grid",
"grid_entries",
"ground_spawns",
"horses",
"instance_list",
"items",
"ldon_trap_entries",
"ldon_trap_templates",
"lootdrop",
"lootdrop_entries",
"loottable",
"loottable_entries",
"merchantlist",
"npc_emotes",
"npc_faction",
"npc_faction_entries",
"npc_scale_global_base",
"npc_spells",
"npc_spells_effects",
"npc_spells_effects_entries",
"npc_spells_entries",
"npc_types",
"npc_types_metadata",
"npc_types_tint",
"object",
"pets",
"pets_equipmentset",
"pets_equipmentset_entries",
"proximities",
"races",
"skill_caps",
"spawn2",
"spawn_condition_values",
"spawn_conditions",
"spawn_events",
"spawnentry",
"spawngroup",
"spells_new",
"start_zones",
"starting_items",
"task_activities",
"tasks",
"tasksets",
"titles",
"tradeskill_recipe",
"tradeskill_recipe_entries",
"traps",
"tribute_levels",
"tributes",
"veteran_reward_templates",
"zone",
"zone_points",
"zone_server",
"zoneserver_auth",
};
return tables;
}
/**
* Gets server tables
*
* @return
*/
static std::vector<std::string> GetServerTables()
{
std::vector<std::string> tables = {
"banned_ips",
"bugs",
"bug_reports",
"command_settings",
"db_str",
"discovered_items",
"eqtime",
"eventlog",
"gm_ips",
"hackers",
"ip_exemptions",
"launcher",
"launcher_zones",
"level_exp_mods",
"logsys_categories",
"name_filter",
"perl_event_export_settings",
"petitions",
"profanity_list",
"reports",
"rule_sets",
"rule_values",
"saylink",
"variables",
};
return tables;
}
/**
* Gets state tables
* Tables that keep track of server state
*
* @return
*/
static std::vector<std::string> GetStateTables()
{
std::vector<std::string> tables = {
"adventure_members",
"chatchannels",
"group_id",
"group_leaders",
"item_tick",
"lfguild",
"merchantlist_temp",
"object_contents",
"raid_details",
"raid_leaders",
"raid_members",
"respawn_times",
"spell_buckets",
"spell_globals",
};
return tables;
}
/**
* Gets login tables
*
* @return
*/
static std::vector<std::string> GetLoginTables()
{
std::vector<std::string> tables = {
"login_accounts",
"login_api_tokens",
"login_server_admins",
"login_server_list_types",
"login_world_servers",
};
return tables;
}
/**
* Gets login tables
*
* @return
*/
static std::vector<std::string> GetVersionTables()
{
std::vector<std::string> tables = {
"db_version",
"inventory_versions",
};
return tables;
}
}
#endif //EQEMU_DATABASE_SCHEMA_H
+65 -119
View File
@@ -2,9 +2,8 @@
#include <winsock2.h>
#endif
#include "misc_functions.h"
#include "eqemu_logsys.h"
#include "timer.h"
#include "../common/misc_functions.h"
#include "../common/eqemu_logsys.h"
#include "dbcore.h"
@@ -15,37 +14,33 @@
#include <string.h>
#ifdef _WINDOWS
#define snprintf _snprintf
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#include <process.h>
#define snprintf _snprintf
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#include <process.h>
#else
#include "unix.h"
#include <pthread.h>
#include "unix.h"
#include <pthread.h>
#endif
#ifdef _EQDEBUG
#define DEBUG_MYSQL_QUERIES 0
#define DEBUG_MYSQL_QUERIES 0
#else
#define DEBUG_MYSQL_QUERIES 0
#define DEBUG_MYSQL_QUERIES 0
#endif
DBcore::DBcore()
{
DBcore::DBcore() {
mysql_init(&mysql);
pHost = 0;
pUser = 0;
pHost = 0;
pUser = 0;
pPassword = 0;
pDatabase = 0;
pCompress = false;
pSSL = false;
pStatus = Closed;
pSSL = false;
pStatus = Closed;
}
DBcore::~DBcore()
{
DBcore::~DBcore() {
mysql_close(&mysql);
safe_delete_array(pHost);
safe_delete_array(pUser);
@@ -54,8 +49,7 @@ DBcore::~DBcore()
}
// Sends the MySQL server a keepalive
void DBcore::ping()
{
void DBcore::ping() {
if (!MDatabase.trylock()) {
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
return;
@@ -69,35 +63,34 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
}
MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce)
MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce)
{
BenchTimer timer;
timer.reset();
LockMutex lock(&MDatabase);
// Reconnect if we are not connected before hand.
if (pStatus != Connected) {
if (pStatus != Connected)
Open();
}
// request query. != 0 indicates some kind of error.
if (mysql_real_query(&mysql, query, querylen) != 0) {
if (mysql_real_query(&mysql, query, querylen) != 0)
{
unsigned int errorNumber = mysql_errno(&mysql);
if (errorNumber == CR_SERVER_GONE_ERROR) {
if (errorNumber == CR_SERVER_GONE_ERROR)
pStatus = Error;
}
// error appears to be a disconnect error, may need to try again.
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) {
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR)
{
if (retryOnFailureOnce) {
LogInfo("Database Error: Lost connection, attempting to recover");
if (retryOnFailureOnce)
{
std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl;
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
if (requestResult.Success()) {
LogInfo("Reconnection to database successful");
if (requestResult.Success())
{
std::cout << "Reconnection to database successful." << std::endl;
return requestResult;
}
@@ -109,154 +102,107 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer);
}
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
/* Implement Logging at the Root */
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)
Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query);
if (mysql_errno(&mysql) > 0 && strlen(query) > 0){
if (Log.log_settings[Logs::MySQLError].is_category_enabled == 1)
Log.Out(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query);
}
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer);
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer);
}
// successful query. get results.
MYSQL_RES *res = mysql_store_result(&mysql);
uint32 rowCount = 0;
MYSQL_RES* res = mysql_store_result(&mysql);
uint32 rowCount = 0;
if (res != nullptr) {
rowCount = (uint32) mysql_num_rows(res);
}
if (res != nullptr)
rowCount = (uint32)mysql_num_rows(res);
MySQLRequestResult requestResult(
res,
(uint32) mysql_affected_rows(&mysql),
rowCount,
(uint32) mysql_field_count(&mysql),
(uint32) mysql_insert_id(&mysql)
);
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if ((strncasecmp(query, "select", 6) == 0)) {
LogF(
Logs::General,
Logs::MySQLQuery,
"{0} ({1} row{2} returned) ({3}s)",
query,
requestResult.RowCount(),
requestResult.RowCount() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
}
else {
LogF(
Logs::General,
Logs::MySQLQuery,
"{0} ({1} row{2} affected) ({3}s)",
query,
requestResult.RowsAffected(),
requestResult.RowsAffected() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
}
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
if (Log.log_settings[Logs::MySQLQuery].is_category_enabled == 1)
{
if ((strncasecmp(query, "select", 6) == 0))
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s");
else
Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s");
}
return requestResult;
}
void DBcore::TransactionBegin()
{
void DBcore::TransactionBegin() {
QueryDatabase("START TRANSACTION");
}
void DBcore::TransactionCommit()
{
void DBcore::TransactionCommit() {
QueryDatabase("COMMIT");
}
void DBcore::TransactionRollback()
{
void DBcore::TransactionRollback() {
QueryDatabase("ROLLBACK");
}
uint32 DBcore::DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen)
{
uint32 DBcore::DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen) {
// No good reason to lock the DB, we only need it in the first place to check char encoding.
// LockMutex lock(&MDatabase);
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
}
bool DBcore::Open(
const char *iHost,
const char *iUser,
const char *iPassword,
const char *iDatabase,
uint32 iPort,
uint32 *errnum,
char *errbuf,
bool iCompress,
bool iSSL
)
{
bool DBcore::Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase,uint32 iPort, uint32* errnum, char* errbuf, bool iCompress, bool iSSL) {
LockMutex lock(&MDatabase);
safe_delete(pHost);
safe_delete(pUser);
safe_delete(pPassword);
safe_delete(pDatabase);
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase);
pCompress = iCompress;
pPort = iPort;
pSSL = iSSL;
pPort = iPort;
pSSL = iSSL;
return Open(errnum, errbuf);
}
bool DBcore::Open(uint32 *errnum, char *errbuf)
{
if (errbuf) {
bool DBcore::Open(uint32* errnum, char* errbuf) {
if (errbuf)
errbuf[0] = 0;
}
LockMutex lock(&MDatabase);
if (GetStatus() == Connected) {
if (GetStatus() == Connected)
return true;
}
if (GetStatus() == Error) {
mysql_close(&mysql);
mysql_init(&mysql); // Initialize structure again
mysql_init(&mysql); // Initialize structure again
}
if (!pHost) {
if (!pHost)
return false;
}
/*
Added CLIENT_FOUND_ROWS flag to the connect
otherwise DB update calls would say 0 rows affected when the value already equalled
what the function was tring to set it to, therefore the function would think it failed
*/
uint32 flags = CLIENT_FOUND_ROWS;
if (pCompress) {
if (pCompress)
flags |= CLIENT_COMPRESS;
}
if (pSSL) {
if (pSSL)
flags |= CLIENT_SSL;
}
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
pStatus = Connected;
return true;
}
else {
if (errnum) {
if (errnum)
*errnum = mysql_errno(&mysql);
}
if (errbuf) {
if (errbuf)
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
}
pStatus = Error;
return false;
}
+2 -3
View File
@@ -49,7 +49,7 @@ namespace EQEmu
};
enum DeityTypeBit : uint32 {
bit_DeityNone = 0x00000000,
bit_DeityAll = 0x00000000,
bit_DeityAgnostic = 0x00000001,
bit_DeityBertoxxulous = 0x00000002,
bit_DeityBrellSirilis = 0x00000004,
@@ -66,8 +66,7 @@ namespace EQEmu
bit_DeitySolusekRo = 0x00002000,
bit_DeityTheTribunal = 0x00004000,
bit_DeityTunare = 0x00008000,
bit_DeityVeeshan = 0x00010000,
bit_DeityAll = 0xFFFFFFFF
bit_DeityVeeshan = 0x00010000
};
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
-134
View File
@@ -18,137 +18,3 @@
*/
#include "emu_constants.h"
int16 EQEmu::invtype::GetInvTypeSize(int16 inv_type) {
static const int16 local_array[] = {
POSSESSIONS_SIZE,
BANK_SIZE,
SHARED_BANK_SIZE,
TRADE_SIZE,
WORLD_SIZE,
LIMBO_SIZE,
TRIBUTE_SIZE,
TROPHY_TRIBUTE_SIZE,
GUILD_TRIBUTE_SIZE,
MERCHANT_SIZE,
DELETED_SIZE,
CORPSE_SIZE,
BAZAAR_SIZE,
INSPECT_SIZE,
REAL_ESTATE_SIZE,
VIEW_MOD_PC_SIZE,
VIEW_MOD_BANK_SIZE,
VIEW_MOD_SHARED_BANK_SIZE,
VIEW_MOD_LIMBO_SIZE,
ALT_STORAGE_SIZE,
ARCHIVED_SIZE,
MAIL_SIZE,
GUILD_TROPHY_TRIBUTE_SIZE,
KRONO_SIZE,
OTHER_SIZE,
};
if (inv_type < TYPE_BEGIN || inv_type > TYPE_END)
return INULL;
return local_array[inv_type];
}
const char* EQEmu::bug::CategoryIDToCategoryName(CategoryID category_id) {
switch (category_id) {
case catVideo:
return "Video";
case catAudio:
return "Audio";
case catPathing:
return "Pathing";
case catQuest:
return "Quest";
case catTradeskills:
return "Tradeskills";
case catSpellStacking:
return "Spell stacking";
case catDoorsPortals:
return "Doors/Portals";
case catItems:
return "Items";
case catNPC:
return "NPC";
case catDialogs:
return "Dialogs";
case catLoNTCG:
return "LoN - TCG";
case catMercenaries:
return "Mercenaries";
case catOther:
default:
return "Other";
}
}
EQEmu::bug::CategoryID EQEmu::bug::CategoryNameToCategoryID(const char* category_name) {
if (!category_name)
return catOther;
if (!strcmp(category_name, "Video"))
return catVideo;
if (!strcmp(category_name, "Audio"))
return catAudio;
if (!strcmp(category_name, "Pathing"))
return catPathing;
if (!strcmp(category_name, "Quest"))
return catQuest;
if (!strcmp(category_name, "Tradeskills"))
return catTradeskills;
if (!strcmp(category_name, "Spell stacking"))
return catSpellStacking;
if (!strcmp(category_name, "Doors/Portals"))
return catDoorsPortals;
if (!strcmp(category_name, "Items"))
return catItems;
if (!strcmp(category_name, "NPC"))
return catNPC;
if (!strcmp(category_name, "Dialogs"))
return catDialogs;
if (!strcmp(category_name, "LoN - TCG"))
return catLoNTCG;
if (!strcmp(category_name, "Mercenaries"))
return catMercenaries;
return catOther;
}
const char *EQEmu::constants::GetStanceName(StanceType stance_type) {
switch (stance_type) {
case stanceUnknown:
return "Unknown";
case stancePassive:
return "Passive";
case stanceBalanced:
return "Balanced";
case stanceEfficient:
return "Efficient";
case stanceReactive:
return "Reactive";
case stanceAggressive:
return "Aggressive";
case stanceAssist:
return "Assist";
case stanceBurn:
return "Burn";
case stanceEfficient2:
return "Efficient2";
case stanceBurnAE:
return "BurnAE";
default:
return "Invalid";
}
}
int EQEmu::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
if (stance_type >= EQEmu::constants::stancePassive && stance_type <= EQEmu::constants::stanceBurnAE)
return (stance_type - EQEmu::constants::stancePassive);
return 0;
}
+109 -279
View File
@@ -21,300 +21,130 @@
#define COMMON_EMU_CONSTANTS_H
#include "eq_limits.h"
#include "emu_legacy.h"
#include "emu_versions.h"
#include <string.h>
#include <string>
// local definitions are the result of using hybrid-client or server-only values and methods
namespace EQEmu
{
using RoF2::IINVALID;
using RoF2::INULL;
namespace inventory {
} /*inventory*/
//using namespace RoF2::invtype;
//using namespace RoF2::invslot;
//using namespace RoF2::invbag;
//using namespace RoF2::invaug;
namespace invtype {
using namespace RoF2::invtype::enum_;
enum : int16 { typeInvalid = -1, slotInvalid = -1, containerInvalid = -1, socketInvalid = -1 }; // temporary
enum : int16 { typeBegin = 0, slotBegin = 0, containerBegin = 0, socketBegin = 0 }; // temporary
using RoF2::invtype::POSSESSIONS_SIZE;
using RoF2::invtype::BANK_SIZE;
using RoF2::invtype::SHARED_BANK_SIZE;
using RoF2::invtype::TRADE_SIZE;
using RoF2::invtype::WORLD_SIZE;
using RoF2::invtype::LIMBO_SIZE;
using RoF2::invtype::TRIBUTE_SIZE;
using RoF2::invtype::TROPHY_TRIBUTE_SIZE;
using RoF2::invtype::GUILD_TRIBUTE_SIZE;
using RoF2::invtype::MERCHANT_SIZE;
using RoF2::invtype::DELETED_SIZE;
using RoF2::invtype::CORPSE_SIZE;
using RoF2::invtype::BAZAAR_SIZE;
using RoF2::invtype::INSPECT_SIZE;
using RoF2::invtype::REAL_ESTATE_SIZE;
using RoF2::invtype::VIEW_MOD_PC_SIZE;
using RoF2::invtype::VIEW_MOD_BANK_SIZE;
using RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE;
using RoF2::invtype::VIEW_MOD_LIMBO_SIZE;
using RoF2::invtype::ALT_STORAGE_SIZE;
using RoF2::invtype::ARCHIVED_SIZE;
using RoF2::invtype::MAIL_SIZE;
using RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE;
using RoF2::invtype::KRONO_SIZE;
using RoF2::invtype::OTHER_SIZE;
using Titanium::invtype::TRADE_NPC_SIZE;
using RoF2::invtype::TYPE_INVALID;
using RoF2::invtype::TYPE_BEGIN;
using RoF2::invtype::TYPE_END;
using RoF2::invtype::TYPE_COUNT;
int16 GetInvTypeSize(int16 inv_type);
using RoF2::invtype::GetInvTypeName;
} // namespace invtype
namespace DevTools {
const int32 GM_ACCOUNT_STATUS_LEVEL = 150;
}
namespace popupresponse {
const int32 SERVER_INTERNAL_USE_BASE = 2000000000;
const int32 MOB_INFO_DISMISS = 2000000001;
}
namespace invslot {
using namespace RoF2::invslot::enum_;
using RoF2::invslot::SLOT_INVALID;
using RoF2::invslot::SLOT_BEGIN;
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
using RoF2::invslot::POSSESSIONS_BEGIN;
using RoF2::invslot::POSSESSIONS_END;
using RoF2::invslot::POSSESSIONS_COUNT;
using RoF2::invslot::EQUIPMENT_BEGIN;
using RoF2::invslot::EQUIPMENT_END;
using RoF2::invslot::EQUIPMENT_COUNT;
using RoF2::invslot::GENERAL_BEGIN;
using RoF2::invslot::GENERAL_END;
using RoF2::invslot::GENERAL_COUNT;
using RoF2::invslot::BONUS_BEGIN;
using RoF2::invslot::BONUS_STAT_END;
using RoF2::invslot::BONUS_SKILL_END;
using Titanium::invslot::BANK_BEGIN;
using SoF::invslot::BANK_END;
using Titanium::invslot::SHARED_BANK_BEGIN;
using Titanium::invslot::SHARED_BANK_END;
using Titanium::invslot::TRADE_BEGIN;
using Titanium::invslot::TRADE_END;
using Titanium::invslot::TRADE_NPC_END;
using Titanium::invslot::WORLD_BEGIN;
using Titanium::invslot::WORLD_END;
using Titanium::invslot::TRIBUTE_BEGIN;
using Titanium::invslot::TRIBUTE_END;
using Titanium::invslot::GUILD_TRIBUTE_BEGIN;
using Titanium::invslot::GUILD_TRIBUTE_END;
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
using RoF2::invslot::EQUIPMENT_BITMASK;
using RoF2::invslot::GENERAL_BITMASK;
using RoF2::invslot::CURSOR_BITMASK;
using RoF2::invslot::POSSESSIONS_BITMASK;
using RoF2::invslot::CORPSE_BITMASK;
using RoF2::invslot::GetInvPossessionsSlotName;
using RoF2::invslot::GetInvSlotName;
} // namespace invslot
namespace invbag {
using Titanium::invbag::SLOT_INVALID;
using Titanium::invbag::SLOT_BEGIN;
using Titanium::invbag::SLOT_END;
using Titanium::invbag::SLOT_COUNT;
using Titanium::invbag::GENERAL_BAGS_BEGIN;
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
const int16 CURSOR_BAG_BEGIN = 351;
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
using Titanium::invbag::BANK_BAGS_BEGIN;
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
using Titanium::invbag::SHARED_BANK_BAGS_BEGIN;
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
using Titanium::invbag::TRADE_BAGS_BEGIN;
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
using Titanium::invbag::GetInvBagIndexName;
} // namespace invbag
namespace invaug {
using RoF2::invaug::SOCKET_INVALID;
using RoF2::invaug::SOCKET_BEGIN;
using RoF2::invaug::SOCKET_END;
using RoF2::invaug::SOCKET_COUNT;
using RoF2::invaug::GetInvAugIndexName;
} // namespace invaug
namespace constants {
const EQEmu::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQEmu::versions::ClientVersion::Titanium;
using RoF2::constants::EXPANSION;
using RoF2::constants::EXPANSION_BIT;
using RoF2::constants::EXPANSIONS_MASK;
using RoF2::constants::CHARACTER_CREATION_LIMIT;
const size_t SAY_LINK_OPENER_SIZE = 1;
using RoF2::constants::SAY_LINK_BODY_SIZE;
const size_t SAY_LINK_TEXT_SIZE = 256; // this may be varied until it breaks something (tested:374) - the others are constant
const size_t SAY_LINK_CLOSER_SIZE = 1;
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
enum StanceType : int {
stanceUnknown = 0,
stancePassive,
stanceBalanced,
stanceEfficient,
stanceReactive,
stanceAggressive,
stanceAssist,
stanceBurn,
stanceEfficient2,
stanceBurnAE
enum PossessionsSlots : int16 { // temporary
slotCharm = 0,
slotEar1,
slotHead,
slotFace,
slotEar2,
slotNeck, // 5
slotShoulders,
slotArms,
slotBack,
slotWrist1,
slotWrist2, // 10
slotRange,
slotHands,
slotPrimary,
slotSecondary,
slotFinger1, // 15
slotFinger2,
slotChest,
slotLegs,
slotFeet,
slotWaist, // 20
slotPowerSource = 9999,
slotAmmo = 21,
slotGeneral1,
slotGeneral2,
slotGeneral3,
slotGeneral4, // 25
slotGeneral5,
slotGeneral6,
slotGeneral7,
slotGeneral8,
slotCursor, // 30
slotCount
};
const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type);
enum InventoryTypes : int16 { // temporary
typePossessions = 0,
typeBank,
typeSharedBank,
typeTrade,
typeWorld,
typeLimbo, // 5
typeTribute,
typeTrophyTribute,
typeGuildTribute,
typeMerchant,
typeDeleted, // 10
typeCorpse,
typeBazaar,
typeInspect,
typeRealEstate,
typeViewMODPC, // 15
typeViewMODBank,
typeViewMODSharedBank,
typeViewMODLimbo,
typeAltStorage,
typeArchived, // 20
typeMail,
typeGuildTrophyTribute,
typeKrono,
typeOther,
typeCount
};
const int STANCE_TYPE_FIRST = stancePassive;
const int STANCE_TYPE_LAST = stanceBurnAE;
const int STANCE_TYPE_COUNT = stanceBurnAE;
static int16 SlotCount(int16 type_index) { return 0; } // temporary
const int16 ContainerCount = 10; // temporary
const int16 SocketCount = 6; // temporary
} /*inventory*/
namespace constants {
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
const int LongBuffs = RoF2::constants::LongBuffs;
const int ShortBuffs = RoF2::constants::ShortBuffs;
const int DiscBuffs = RoF2::constants::DiscBuffs;
const int TotalBuffs = RoF2::constants::TotalBuffs;
const int NPCBuffs = RoF2::constants::NPCBuffs;
const int PetBuffs = RoF2::constants::PetBuffs;
const int MercBuffs = RoF2::constants::MercBuffs;
} /*constants*/
namespace profile {
using RoF2::profile::BANDOLIERS_SIZE;
using RoF2::profile::BANDOLIER_ITEM_COUNT;
using RoF2::profile::POTION_BELT_SIZE;
using RoF2::profile::SKILL_ARRAY_SIZE;
} // namespace profile
namespace behavior {
using RoF2::behavior::CoinHasWeight;
} // namespace behavior
namespace spells {
enum class CastingSlot : uint32 { // hybrid declaration
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 12,
Ability = 20, // HT/LoH for Tit
PotionBelt = 21, // Tit uses a different slot for PB
Item = 22,
Discipline = 23,
AltAbility = 0xFF
};
using RoF2::spells::SPELL_ID_MAX;
using RoF2::spells::SPELLBOOK_SIZE;
using UF::spells::SPELL_GEM_COUNT; // RoF+ clients define more than UF client..but, they are not valid beyond UF
using RoF2::spells::LONG_BUFFS;
using RoF2::spells::SHORT_BUFFS;
using RoF2::spells::DISC_BUFFS;
using RoF2::spells::TOTAL_BUFFS;
using RoF2::spells::NPC_BUFFS;
using RoF2::spells::PET_BUFFS;
using RoF2::spells::MERC_BUFFS;
} // namespace spells
namespace bug {
enum CategoryID : uint32 {
catOther = 0,
catVideo,
catAudio,
catPathing,
catQuest,
catTradeskills,
catSpellStacking,
catDoorsPortals,
catItems,
catNPC,
catDialogs,
catLoNTCG,
catMercenaries
};
enum OptionalInfoFlag : uint32 {
infoNoOptionalInfo = 0x0,
infoCanDuplicate = 0x1,
infoCrashBug = 0x2,
infoTargetInfo = 0x4,
infoCharacterFlags = 0x8,
infoUnknownValue = 0xFFFFFFF0
};
const char* CategoryIDToCategoryName(CategoryID category_id);
CategoryID CategoryNameToCategoryID(const char* category_name);
} // namespace bug
enum WaypointStatus : int {
RoamBoxPauseInProgress = -3,
QuestControlNoGrid = -2,
QuestControlGrid = -1
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 12,
Ability = 20, // HT/LoH for Tit
PotionBelt = 21, // Tit uses a different slot for PB
Item = 22,
Discipline = 23,
AltAbility = 0xFF
};
} /*EQEmu*/
+20
View File
@@ -0,0 +1,20 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "emu_legacy.h"
+182
View File
@@ -0,0 +1,182 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_EMU_LEGACY_H
#define COMMON_EMU_LEGACY_H
#include "types.h"
#include <stdlib.h>
namespace EQEmu
{
// this is for perl and other legacy systems
namespace legacy {
enum InventorySlot {
SLOT_CHARM = 0,
SLOT_EAR01 = 1,
SLOT_HEAD = 2,
SLOT_FACE = 3,
SLOT_EAR02 = 4,
SLOT_NECK = 5,
SLOT_SHOULDER = 6,
SLOT_ARMS = 7,
SLOT_BACK = 8,
SLOT_BRACER01 = 9,
SLOT_BRACER02 = 10,
SLOT_RANGE = 11,
SLOT_HANDS = 12,
SLOT_PRIMARY = 13,
SLOT_SECONDARY = 14,
SLOT_RING01 = 15,
SLOT_RING02 = 16,
SLOT_CHEST = 17,
SLOT_LEGS = 18,
SLOT_FEET = 19,
SLOT_WAIST = 20,
SLOT_POWER_SOURCE = 9999,
SLOT_AMMO = 21,
SLOT_GENERAL_1 = 22,
SLOT_GENERAL_2 = 23,
SLOT_GENERAL_3 = 24,
SLOT_GENERAL_4 = 25,
SLOT_GENERAL_5 = 26,
SLOT_GENERAL_6 = 27,
SLOT_GENERAL_7 = 28,
SLOT_GENERAL_8 = 29,
SLOT_CURSOR = 30,
SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this...
SLOT_TRADESKILL = 1000,
SLOT_AUGMENT = 1001,
SLOT_INVALID = (int16)0xFFFF,
SLOT_POSSESSIONS_BEGIN = 0,
SLOT_POSSESSIONS_END = 30,
SLOT_EQUIPMENT_BEGIN = 0,
SLOT_EQUIPMENT_END = 21,
SLOT_PERSONAL_BEGIN = 22,
SLOT_PERSONAL_END = 29,
SLOT_PERSONAL_BAGS_BEGIN = 251,
SLOT_PERSONAL_BAGS_END = 330,
SLOT_CURSOR_BAG_BEGIN = 331,
SLOT_CURSOR_BAG_END = 340,
SLOT_TRIBUTE_BEGIN = 400,
SLOT_TRIBUTE_END = 404,
SLOT_BANK_BEGIN = 2000,
SLOT_BANK_END = 2023,
SLOT_BANK_BAGS_BEGIN = 2031,
SLOT_BANK_BAGS_END = 2270,
SLOT_SHARED_BANK_BEGIN = 2500,
SLOT_SHARED_BANK_END = 2501,
SLOT_SHARED_BANK_BAGS_BEGIN = 2531,
SLOT_SHARED_BANK_BAGS_END = 2550,
SLOT_TRADE_BEGIN = 3000,
SLOT_TRADE_END = 3007,
SLOT_TRADE_BAGS_BEGIN = 3031,
SLOT_TRADE_BAGS_END = 3110,
SLOT_WORLD_BEGIN = 4000,
SLOT_WORLD_END = 4009
};
// these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready
static const uint16 TYPE_POSSESSIONS_SIZE = 31;
static const uint16 TYPE_BANK_SIZE = 24;
static const uint16 TYPE_SHARED_BANK_SIZE = 2;
static const uint16 TYPE_TRADE_SIZE = 8;
static const uint16 TYPE_WORLD_SIZE = 10;
static const uint16 TYPE_LIMBO_SIZE = 36;
static const uint16 TYPE_TRIBUTE_SIZE = 5; // (need client values)
static const uint16 TYPE_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 TYPE_GUILD_TRIBUTE_SIZE = 0;
static const uint16 TYPE_MERCHANT_SIZE = 0;
static const uint16 TYPE_DELETED_SIZE = 0;
static const uint16 TYPE_CORPSE_SIZE = 31; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
static const uint16 TYPE_BAZAAR_SIZE = 80;
static const uint16 TYPE_INSPECT_SIZE = 22;
static const uint16 TYPE_REAL_ESTATE_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_PC_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_BANK_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_SHARED_BANK_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_LIMBO_SIZE = 0;
static const uint16 TYPE_ALT_STORAGE_SIZE = 0;
static const uint16 TYPE_ARCHIVED_SIZE = 0;
static const uint16 TYPE_MAIL_SIZE = 0;
static const uint16 TYPE_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 TYPE_KRONO_SIZE = 0;
static const uint16 TYPE_OTHER_SIZE = 0;
// most of these definitions will go away with the structure-based system..this maintains compatibility for now
// (these are mainly to assign specific values to constants used in conversions and to identify per-client ranges/offsets)
static const int16 EQUIPMENT_BEGIN = 0;
static const int16 EQUIPMENT_END = 21;
static const uint16 EQUIPMENT_SIZE = 22; // does not account for 'Power Source' - used mainly for npc equipment arrays
static const int16 GENERAL_BEGIN = 22;
static const int16 GENERAL_END = 29;
static const uint16 GENERAL_SIZE = 8;
static const int16 GENERAL_BAGS_BEGIN = 251;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR_BAG_BEGIN = 331;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2023;
static const int16 BANK_BAGS_BEGIN = 2031;
static const int16 BANK_BAGS_END_OFFSET = 239;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2531;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_NPC_END = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031;
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 WORLD_SIZE = TYPE_WORLD_SIZE;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 TRIBUTE_SIZE = TYPE_TRIBUTE_SIZE;
static const int16 CORPSE_BEGIN = 22;
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
}
}
#endif /* COMMON_EMU_LEGACY_H */
+24 -48
View File
@@ -28,98 +28,74 @@
namespace EntityLimits
{
namespace NPC {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*NPC*/
namespace NPCMerchant {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*NPCMerchant*/
namespace Merc {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*Merc*/
namespace Bot {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 8;
enum : bool { False = false, True = true };
} // namespace invtype
namespace invslot {
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x0000000000000000;
const uint64 CURSOR_BITMASK = 0x0000000000000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
} // namespace invslot
const size_t InvTypeTradeSize = 8;
} /*Bot*/
namespace ClientPet {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*Pet*/
namespace NPCPet {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*Pet*/
namespace MercPet {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*Pet*/
namespace BotPet {
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace invtype {
const int16 TRADE_SIZE = 4;
enum : bool { False = false, True = true };
} // namespace invtype
const size_t InvTypeTradeSize = 4;
} /*Pet*/
-6
View File
@@ -9,7 +9,6 @@ N(OP_AcceptNewTask),
N(OP_AckPacket),
N(OP_Action),
N(OP_Action2),
N(OP_AddNimbusEffect),
N(OP_AdventureData),
N(OP_AdventureDetails),
N(OP_AdventureFinish),
@@ -340,7 +339,6 @@ N(OP_MOTD),
N(OP_MoveCoin),
N(OP_MoveDoor),
N(OP_MoveItem),
N(OP_MoveMultipleItems),
N(OP_MoveLogDisregard),
N(OP_MoveLogRequest),
N(OP_MultiLineMsg),
@@ -357,7 +355,6 @@ N(OP_OpenTributeMaster),
N(OP_PDeletePetition),
N(OP_PetBuffWindow),
N(OP_PetCommands),
N(OP_PetCommandState),
N(OP_PetHoTT),
N(OP_Petition),
N(OP_PetitionBug),
@@ -393,7 +390,6 @@ N(OP_PVPLeaderBoardReply),
N(OP_PVPLeaderBoardRequest),
N(OP_PVPStats),
N(OP_QueryResponseThing),
N(OP_QueryUCSServerStatus),
N(OP_RaidInvite),
N(OP_RaidJoin),
N(OP_RaidUpdate),
@@ -411,7 +407,6 @@ N(OP_ReloadUI),
N(OP_RemoveAllDoors),
N(OP_RemoveBlockedBuffs),
N(OP_RemoveNimbusEffect),
N(OP_RemoveTrap),
N(OP_Report),
N(OP_ReqClientSpawn),
N(OP_ReqNewZone),
@@ -527,7 +522,6 @@ N(OP_TributeToggle),
N(OP_TributeUpdate),
N(OP_Untargetable),
N(OP_UpdateAA),
N(OP_UpdateAura),
N(OP_UpdateLeadershipAA),
N(OP_VetClaimReply),
N(OP_VetClaimRequest),
+818
View File
@@ -0,0 +1,818 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
There are really two or three different objects shoe-hored into this
connection object. Sombody really needs to factor out the relay link
crap into its own subclass of this object, it will clean things up
tremendously.
*/
#include "../common/global_define.h"
#include <iostream>
#include <string.h>
#include "emu_tcp_connection.h"
#include "emu_tcp_server.h"
#include "../common/servertalk.h"
#ifdef FREEBSD //Timothy Whitman - January 7, 2003
#define MSG_NOSIGNAL 0
#endif
#define TCPN_DEBUG 0
#define TCPN_DEBUG_Console 0
#define TCPN_DEBUG_Memory 0
#define TCPN_LOG_PACKETS 0
#define TCPN_LOG_RAW_DATA_OUT 0
#define TCPN_LOG_RAW_DATA_IN 0
//server side case
EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, SOCKET in_socket, uint32 irIP, uint16 irPort, bool iOldFormat)
: TCPConnection(ID, in_socket, irIP, irPort),
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
id = 0;
Server = nullptr;
pOldFormat = iOldFormat;
#ifdef MINILOGIN
TCPMode = modePacket;
PacketMode = packetModeLogin;
#else
if (pOldFormat)
TCPMode = modePacket;
else
TCPMode = modeConsole;
PacketMode = packetModeZone;
#endif
RelayLink = 0;
RelayServer = false;
RelayCount = 0;
RemoteID = 0;
}
//client outgoing connection case (and client side relay)
EmuTCPConnection::EmuTCPConnection(bool iOldFormat, EmuTCPServer* iRelayServer, eTCPMode iMode)
: TCPConnection(),
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
Server = iRelayServer;
if (Server)
RelayServer = true;
else
RelayServer = false;
RelayLink = 0;
RelayCount = 0;
RemoteID = 0;
pOldFormat = iOldFormat;
TCPMode = iMode;
PacketMode = packetModeZone;
#if TCPN_DEBUG_Memory >= 7
std::cout << "Constructor #1 on outgoing TCP# " << GetID() << std::endl;
#endif
}
//server side relay case
EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, EmuTCPConnection* iRelayLink, uint32 iRemoteID, uint32 irIP, uint16 irPort)
: TCPConnection(ID, 0, irIP, irPort),
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
Server = iServer;
RelayLink = iRelayLink;
RelayServer = true;
RelayCount = 0;
RemoteID = iRemoteID;
pOldFormat = false;
ConnectionType = Incoming;
TCPMode = modePacket;
PacketMode = packetModeZone;
#if TCPN_DEBUG_Memory >= 7
std::cout << "Constructor #3 on outgoing TCP# " << GetID() << std::endl;
#endif
}
EmuTCPConnection::~EmuTCPConnection() {
//the queues free their content right now I believe.
}
EmuTCPNetPacket_Struct* EmuTCPConnection::MakePacket(ServerPacket* pack, uint32 iDestination) {
int32 size = sizeof(EmuTCPNetPacket_Struct) + pack->size;
if (pack->compressed) {
size += 4;
}
if (iDestination) {
size += 4;
}
EmuTCPNetPacket_Struct* tnps = (EmuTCPNetPacket_Struct*) new uchar[size];
tnps->size = size;
tnps->opcode = pack->opcode;
*((uint8*) &tnps->flags) = 0;
uchar* buffer = tnps->buffer;
if (pack->compressed) {
tnps->flags.compressed = 1;
*((int32*) buffer) = pack->InflatedSize;
buffer += 4;
}
if (iDestination) {
tnps->flags.destination = 1;
*((int32*) buffer) = iDestination;
buffer += 4;
}
memcpy(buffer, pack->pBuffer, pack->size);
return tnps;
}
SPackSendQueue* EmuTCPConnection::MakeOldPacket(ServerPacket* pack) {
SPackSendQueue* spsq = (SPackSendQueue*) new uchar[sizeof(SPackSendQueue) + pack->size + 4];
if (pack->pBuffer != 0 && pack->size != 0)
memcpy((char *) &spsq->buffer[4], (char *) pack->pBuffer, pack->size);
memcpy((char *) &spsq->buffer[0], (char *) &pack->opcode, 2);
spsq->size = pack->size+4;
memcpy((char *) &spsq->buffer[2], (char *) &spsq->size, 2);
return spsq;
}
bool EmuTCPConnection::SendPacket(ServerPacket* pack, uint32 iDestination) {
if (!Connected())
return false;
eTCPMode tmp = GetMode();
if (tmp != modePacket && tmp != modeTransition)
return false;
LockMutex lock(&MState);
if (RemoteID)
return RelayLink->SendPacket(pack, RemoteID);
else if (pOldFormat) {
#if TCPN_LOG_PACKETS >= 1
if (pack && pack->opcode != 0) {
struct in_addr in;
in.s_addr = GetrIP();
CoutTimestamp(true);
std::cout << ": Logging outgoing TCP OldPacket. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
#if TCPN_LOG_PACKETS == 2
if (pack->size >= 32)
DumpPacket(pack->pBuffer, 32);
else
DumpPacket(pack);
#endif
#if TCPN_LOG_PACKETS >= 3
DumpPacket(pack);
#endif
}
#endif
SPackSendQueue* spsq = MakeOldPacket(pack);
ServerSendQueuePushEnd(spsq->buffer, spsq->size);
safe_delete_array(spsq);
}
else {
EmuTCPNetPacket_Struct* tnps = MakePacket(pack, iDestination);
if (tmp == modeTransition) {
InModeQueuePush(tnps);
}
else {
#if TCPN_LOG_PACKETS >= 1
if (pack && pack->opcode != 0) {
struct in_addr in;
in.s_addr = GetrIP();
CoutTimestamp(true);
std::cout << ": Logging outgoing TCP packet. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
#if TCPN_LOG_PACKETS == 2
if (pack->size >= 32)
DumpPacket(pack->pBuffer, 32);
else
DumpPacket(pack);
#endif
#if TCPN_LOG_PACKETS >= 3
DumpPacket(pack);
#endif
}
#endif
ServerSendQueuePushEnd((uchar**) &tnps, tnps->size);
}
}
return true;
}
bool EmuTCPConnection::SendPacket(EmuTCPNetPacket_Struct* tnps) {
if (RemoteID)
return false;
if (!Connected())
return false;
if (GetMode() != modePacket)
return false;
LockMutex lock(&MState);
eTCPMode tmp = GetMode();
if (tmp == modeTransition) {
EmuTCPNetPacket_Struct* tnps2 = (EmuTCPNetPacket_Struct*) new uchar[tnps->size];
memcpy(tnps2, tnps, tnps->size);
InModeQueuePush(tnps2);
return true;
}
#if TCPN_LOG_PACKETS >= 1
if (tnps && tnps->opcode != 0) {
struct in_addr in;
in.s_addr = GetrIP();
CoutTimestamp(true);
std::cout << ": Logging outgoing TCP NetPacket. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << tnps->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << tnps->size << " " << inet_ntoa(in) << ":" << GetrPort();
if (pOldFormat)
std::cout << " (OldFormat)";
std::cout << std::endl;
#if TCPN_LOG_PACKETS == 2
if (tnps->size >= 32)
DumpPacket((uchar*) tnps, 32);
else
DumpPacket((uchar*) tnps, tnps->size);
#endif
#if TCPN_LOG_PACKETS >= 3
DumpPacket((uchar*) tnps, tnps->size);
#endif
}
#endif
ServerSendQueuePushEnd((const uchar*) tnps, tnps->size);
return true;
}
ServerPacket* EmuTCPConnection::PopPacket() {
ServerPacket* ret;
if (!MOutQueueLock.trylock())
return nullptr;
ret = OutQueue.pop();
MOutQueueLock.unlock();
return ret;
}
void EmuTCPConnection::InModeQueuePush(EmuTCPNetPacket_Struct* tnps) {
MSendQueue.lock();
InModeQueue.push(tnps);
MSendQueue.unlock();
}
void EmuTCPConnection::OutQueuePush(ServerPacket* pack) {
MOutQueueLock.lock();
OutQueue.push(pack);
MOutQueueLock.unlock();
}
bool EmuTCPConnection::LineOutQueuePush(char* line) {
#if defined(GOTFRAGS) && 0
if (strcmp(line, "**CRASHME**") == 0) {
int i = 0;
std::cout << (5 / i) << std::endl;
}
#endif
if(line[0] == '*') {
if (strcmp(line, "**PACKETMODE**") == 0) {
MSendQueue.lock();
safe_delete_array(sendbuf);
if (TCPMode == modeConsole)
Send((const uchar*) "\0**PACKETMODE**\r", 16);
TCPMode = modePacket;
PacketMode = packetModeLogin;
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop())) {
SendPacket(tnps);
safe_delete_array(tnps);
}
MSendQueue.unlock();
safe_delete_array(line);
return(true);
}
if (strcmp(line, "**PACKETMODEZONE**") == 0) {
MSendQueue.lock();
safe_delete_array(sendbuf);
if (TCPMode == modeConsole)
Send((const uchar*) "\0**PACKETMODEZONE**\r", 20);
TCPMode = modePacket;
PacketMode = packetModeZone;
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop())) {
SendPacket(tnps);
safe_delete_array(tnps);
}
MSendQueue.unlock();
safe_delete_array(line);
return(true);
}
if (strcmp(line, "**PACKETMODELAUNCHER**") == 0) {
MSendQueue.lock();
safe_delete_array(sendbuf);
if (TCPMode == modeConsole)
Send((const uchar*) "\0**PACKETMODELAUNCHER**\r", 24);
TCPMode = modePacket;
PacketMode = packetModeLauncher;
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop())) {
SendPacket(tnps);
safe_delete_array(tnps);
}
MSendQueue.unlock();
safe_delete_array(line);
return(true);
}
if (strcmp(line, "**PACKETMODEUCS**") == 0) {
MSendQueue.lock();
safe_delete_array(sendbuf);
if (TCPMode == modeConsole)
Send((const uchar*) "\0**PACKETMODEUCS**\r", 19);
TCPMode = modePacket;
PacketMode = packetModeUCS;
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop())) {
SendPacket(tnps);
safe_delete_array(tnps);
}
MSendQueue.unlock();
safe_delete_array(line);
return(true);
}
if (strcmp(line, "**PACKETMODEQS**") == 0) {
MSendQueue.lock();
safe_delete_array(sendbuf);
if (TCPMode == modeConsole)
Send((const uchar*) "\0**PACKETMODEQS**\r", 18);
TCPMode = modePacket;
PacketMode = packetModeQueryServ;
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop())) {
SendPacket(tnps);
safe_delete_array(tnps);
}
MSendQueue.unlock();
safe_delete_array(line);
return(true);
}
}
return(TCPConnection::LineOutQueuePush(line));
}
void EmuTCPConnection::Disconnect(bool iSendRelayDisconnect) {
TCPConnection::Disconnect();
if (RelayLink) {
RelayLink->RemoveRelay(this, iSendRelayDisconnect);
RelayLink = 0;
}
}
bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
if(!TCPConnection::ConnectIP(irIP, irPort, errbuf))
return(false);
MSendQueue.lock();
#ifdef MINILOGIN
TCPMode = modePacket;
#else
if (pOldFormat) {
TCPMode = modePacket;
}
else if (TCPMode == modePacket || TCPMode == modeTransition) {
TCPMode = modeTransition;
if(PacketMode == packetModeLauncher) {
safe_delete_array(sendbuf);
sendbuf_size = 24;
sendbuf_used = sendbuf_size;
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODELAUNCHER**\r", sendbuf_size);
} else if(PacketMode == packetModeLogin) {
safe_delete_array(sendbuf);
sendbuf_size = 16;
sendbuf_used = sendbuf_size;
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODE**\r", sendbuf_size);
} else if(PacketMode == packetModeUCS) {
safe_delete_array(sendbuf);
sendbuf_size = 19;
sendbuf_used = sendbuf_size;
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODEUCS**\r", sendbuf_size);
}
else if(PacketMode == packetModeQueryServ) {
safe_delete_array(sendbuf);
sendbuf_size = 18;
sendbuf_used = sendbuf_size;
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODEQS**\r", sendbuf_size);
}
else {
//default: packetModeZone
safe_delete_array(sendbuf);
sendbuf_size = 20;
sendbuf_used = sendbuf_size;
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODEZONE**\r", sendbuf_size);
}
}
#endif
MSendQueue.unlock();
return(true);
}
void EmuTCPConnection::ClearBuffers() {
TCPConnection::ClearBuffers();
LockMutex lock2(&MOutQueueLock);
ServerPacket* pack = 0;
while ((pack = OutQueue.pop()))
safe_delete(pack);
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop()))
safe_delete(tnps);
keepalive_timer.Start();
timeout_timer.Start();
}
void EmuTCPConnection::SendNetErrorPacket(const char* reason) {
#if TCPC_DEBUG >= 1
struct in_addr in;
in.s_addr = GetrIP();
std::cout "NetError: '";
if (reason)
std::cout << reason;
std::cout << "': " << inet_ntoa(in) << ":" << GetPort() << std::endl;
#endif
auto pack = new ServerPacket(0);
pack->size = 1;
if (reason)
pack->size += strlen(reason) + 1;
pack->pBuffer = new uchar[pack->size];
memset(pack->pBuffer, 0, pack->size);
pack->pBuffer[0] = 255;
strcpy((char *)&pack->pBuffer[1], reason);
SendPacket(pack);
safe_delete(pack);
}
void EmuTCPConnection::RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisconnect) {
if (iSendRelayDisconnect) {
auto pack = new ServerPacket(0, 5);
pack->pBuffer[0] = 3;
*((uint32*) &pack->pBuffer[1]) = relay->GetRemoteID();
SendPacket(pack);
safe_delete(pack);
}
RelayCount--;
}
bool EmuTCPConnection::ProcessReceivedData(char* errbuf) {
if (errbuf)
errbuf[0] = 0;
timeout_timer.Start();
if (!recvbuf)
return true;
if (TCPMode == modePacket) {
if (pOldFormat)
return ProcessReceivedDataAsOldPackets(errbuf);
else
return ProcessReceivedDataAsPackets(errbuf);
}
//else, use the base class's text processing.
bool ret = TCPConnection::ProcessReceivedData(errbuf);
//see if we made the transition to packet mode...
if(ret && TCPMode == modePacket) {
return ProcessReceivedDataAsPackets(errbuf);
}
return(ret);
}
bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
if (errbuf)
errbuf[0] = 0;
int32 base = 0;
int32 size = 7;
uchar* buffer;
ServerPacket* pack = 0;
while ((recvbuf_used - base) >= size) {
EmuTCPNetPacket_Struct* tnps = (EmuTCPNetPacket_Struct*) &recvbuf[base];
buffer = tnps->buffer;
size = tnps->size;
if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
DumpPacket(&recvbuf[base], 16);
#endif
if (errbuf)
snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
return false;
}
if ((recvbuf_used - base) >= size) {
// ok, we got enough data to make this packet!
pack = new ServerPacket;
pack->size = size - sizeof(EmuTCPNetPacket_Struct);
// read headers
pack->opcode = tnps->opcode;
if (tnps->flags.compressed) {
pack->compressed = true;
pack->InflatedSize = *((int32*)buffer);
pack->size -= 4;
buffer += 4;
}
if (tnps->flags.destination) {
pack->destination = *((int32*)buffer);
pack->size -= 4;
buffer += 4;
}
// end read headers
if (pack->size > 0) {
if (tnps->flags.compressed) {
// Lets decompress the packet here
pack->compressed = false;
pack->pBuffer = new uchar[pack->InflatedSize];
pack->size = InflatePacket(buffer, pack->size, pack->pBuffer, pack->InflatedSize);
}
else {
pack->pBuffer = new uchar[pack->size];
memcpy(pack->pBuffer, buffer, pack->size);
}
}
if (pack->opcode == 0) {
if (pack->size) {
#if TCPN_DEBUG >= 2
std::cout << "Received TCP Network layer packet" << std::endl;
#endif
ProcessNetworkLayerPacket(pack);
}
#if TCPN_DEBUG >= 5
else {
std::cout << "Received TCP keepalive packet. (opcode=0)" << std::endl;
}
#endif
// keepalive, no need to process
safe_delete(pack);
}
else {
#if TCPN_LOG_PACKETS >= 1
if (pack && pack->opcode != 0) {
struct in_addr in;
in.s_addr = GetrIP();
CoutTimestamp(true);
std::cout << ": Logging incoming TCP packet. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
#if TCPN_LOG_PACKETS == 2
if (pack->size >= 32)
DumpPacket(pack->pBuffer, 32);
else
DumpPacket(pack);
#endif
#if TCPN_LOG_PACKETS >= 3
DumpPacket(pack);
#endif
}
#endif
if (RelayServer && Server && pack->destination) {
EmuTCPConnection* con = Server->FindConnection(pack->destination);
if (!con) {
#if TCPN_DEBUG >= 1
std::cout << "Error relaying packet: con = 0" << std::endl;
#endif
safe_delete(pack);
}
else
con->OutQueuePush(pack);
}
else
OutQueuePush(pack);
}
base += size;
size = 7;
}
}
if (base != 0) {
if (base >= recvbuf_used) {
safe_delete_array(recvbuf);
} else {
auto tmpbuf = new uchar[recvbuf_size - base];
memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
safe_delete_array(recvbuf);
recvbuf = tmpbuf;
recvbuf_used -= base;
recvbuf_size -= base;
}
}
return true;
}
bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
int32 base = 0;
int32 size = 4;
uchar* buffer;
ServerPacket* pack = 0;
while ((recvbuf_used - base) >= size) {
buffer = &recvbuf[base];
memcpy(&size, &buffer[2], 2);
if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
#endif
if (errbuf)
snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
return false;
}
if ((recvbuf_used - base) >= size) {
// ok, we got enough data to make this packet!
pack = new ServerPacket;
memcpy(&pack->opcode, &buffer[0], 2);
pack->size = size - 4;
/* if () { // TODO: Checksum or size check or something similar
// Datastream corruption, get the hell outta here!
delete pack;
return false;
}*/
if (pack->size > 0) {
pack->pBuffer = new uchar[pack->size];
memcpy(pack->pBuffer, &buffer[4], pack->size);
}
if (pack->opcode == 0) {
// keepalive, no need to process
safe_delete(pack);
}
else {
#if TCPN_LOG_PACKETS >= 1
if (pack && pack->opcode != 0) {
struct in_addr in;
in.s_addr = GetrIP();
CoutTimestamp(true);
std::cout << ": Logging incoming TCP OldPacket. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
#if TCPN_LOG_PACKETS == 2
if (pack->size >= 32)
DumpPacket(pack->pBuffer, 32);
else
DumpPacket(pack);
#endif
#if TCPN_LOG_PACKETS >= 3
DumpPacket(pack);
#endif
}
#endif
OutQueuePush(pack);
}
base += size;
size = 4;
}
}
if (base != 0) {
if (base >= recvbuf_used) {
safe_delete_array(recvbuf);
}
else {
auto tmpbuf = new uchar[recvbuf_size - base];
memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
safe_delete_array(recvbuf);
recvbuf = tmpbuf;
recvbuf_used -= base;
recvbuf_size -= base;
}
}
return true;
}
void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) {
uint8 opcode = pack->pBuffer[0];
uint8* data = &pack->pBuffer[1];
switch (opcode) {
case 0: {
break;
}
case 1: { // Switch to RelayServer mode
if (pack->size != 1) {
SendNetErrorPacket("New RelayClient: wrong size, expected 1");
break;
}
if (RelayServer) {
SendNetErrorPacket("Switch to RelayServer mode when already in RelayServer mode");
break;
}
if (RemoteID) {
SendNetErrorPacket("Switch to RelayServer mode by a Relay Client");
break;
}
if (ConnectionType != Incoming) {
SendNetErrorPacket("Switch to RelayServer mode on outgoing connection");
break;
}
#if TCPC_DEBUG >= 3
struct in_addr in;
in.s_addr = GetrIP();
std::cout << "Switching to RelayServer mode: " << inet_ntoa(in) << ":" << GetPort() << std::endl;
#endif
RelayServer = true;
break;
}
case 2: { // New Relay Client
if (!RelayServer) {
SendNetErrorPacket("New RelayClient when not in RelayServer mode");
break;
}
if (pack->size != 11) {
SendNetErrorPacket("New RelayClient: wrong size, expected 11");
break;
}
if (ConnectionType != Incoming) {
SendNetErrorPacket("New RelayClient: illegal on outgoing connection");
break;
}
auto con = new EmuTCPConnection(Server->GetNextID(), Server, this, *((uint32 *)data),
*((uint32 *)&data[4]), *((uint16 *)&data[8]));
Server->AddConnection(con);
RelayCount++;
break;
}
case 3: { // Delete Relay Client
if (!RelayServer) {
SendNetErrorPacket("Delete RelayClient when not in RelayServer mode");
break;
}
if (pack->size != 5) {
SendNetErrorPacket("Delete RelayClient: wrong size, expected 5");
break;
}
EmuTCPConnection* con = Server->FindConnection(*((uint32*)data));
if (con) {
if (ConnectionType == Incoming) {
if (con->GetRelayLink() != this) {
SendNetErrorPacket("Delete RelayClient: RelayLink != this");
break;
}
}
con->Disconnect(false);
}
break;
}
case 255: {
#if TCPC_DEBUG >= 1
struct in_addr in;
in.s_addr = GetrIP();
std::cout "Received NetError: '";
if (pack->size > 1)
std::cout << (char*) data;
std::cout << "': " << inet_ntoa(in) << ":" << GetPort() << std::endl;
#endif
break;
}
}
}
bool EmuTCPConnection::SendData(bool &sent_something, char* errbuf) {
sent_something = false;
if(!TCPConnection::SendData(sent_something, errbuf))
return(false);
if(sent_something)
keepalive_timer.Start();
else if (TCPMode == modePacket && keepalive_timer.Check()) {
auto pack = new ServerPacket(0, 0);
SendPacket(pack);
safe_delete(pack);
#if TCPN_DEBUG >= 5
std::cout << "Sending TCP keepalive packet. (timeout=" << timeout_timer.GetRemainingTime() << " remaining)" << std::endl;
#endif
}
return(true);
}
bool EmuTCPConnection::RecvData(char* errbuf) {
if(!TCPConnection::RecvData(errbuf)) {
if (OutQueue.count())
return(true);
else
return(false);
}
if ((TCPMode == modePacket || TCPMode == modeTransition) && timeout_timer.Check()) {
if (errbuf)
snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Connection timeout");
return false;
}
return(true);
}
+104
View File
@@ -0,0 +1,104 @@
#ifndef EmuTCPCONNECTION_H_
#define EmuTCPCONNECTION_H_
#include "tcp_connection.h"
#include "timer.h"
//moved out of TCPConnection:: to be more exportable
#pragma pack(1)
struct EmuTCPNetPacket_Struct {
uint32 size;
struct {
uint8
compressed : 1,
destination : 1,
flag3 : 1,
flag4 : 1,
flag5 : 1,
flag6 : 1,
flag7 : 1,
flag8 : 1;
} flags;
uint16 opcode;
uchar buffer[0];
};
#pragma pack()
struct SPackSendQueue;
class EmuTCPServer;
class ServerPacket;
class EmuTCPConnection : public TCPConnection {
public:
enum eTCPMode { modeConsole, modeTransition, modePacket };
enum ePacketMode { packetModeZone, packetModeLauncher, packetModeLogin, packetModeUCS, packetModeQueryServ };
EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, SOCKET iSock, uint32 irIP, uint16 irPort, bool iOldFormat = false);
EmuTCPConnection(bool iOldFormat = false, EmuTCPServer* iRelayServer = 0, eTCPMode iMode = modePacket); // for outgoing connections
EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, EmuTCPConnection* iRelayLink, uint32 iRemoteID, uint32 irIP, uint16 irPort); // for relay connections
virtual ~EmuTCPConnection();
virtual bool ConnectIP(uint32 irIP, uint16 irPort, char* errbuf = 0);
virtual void Disconnect(bool iSendRelayDisconnect = true);
static EmuTCPNetPacket_Struct* MakePacket(ServerPacket* pack, uint32 iDestination = 0);
static SPackSendQueue* MakeOldPacket(ServerPacket* pack);
virtual bool SendPacket(ServerPacket* pack, uint32 iDestination = 0);
virtual bool SendPacket(EmuTCPNetPacket_Struct* tnps);
ServerPacket* PopPacket(); // OutQueuePop()
void SetPacketMode(ePacketMode mode) { PacketMode = mode; }
eTCPMode GetMode() const { return TCPMode; }
ePacketMode GetPacketMode() const { return(PacketMode); }
//relay crap:
inline bool IsRelayServer() const { return RelayServer; }
inline TCPConnection* GetRelayLink() const { return RelayLink; }
inline uint32 GetRemoteID() const { return RemoteID; }
protected:
void OutQueuePush(ServerPacket* pack);
void RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisconnect);
void SendNetErrorPacket(const char* reason = 0);
virtual bool SendData(bool &sent_something, char* errbuf = 0);
virtual bool RecvData(char* errbuf = 0);
virtual bool ProcessReceivedData(char* errbuf = 0);
bool ProcessReceivedDataAsPackets(char* errbuf = 0);
bool ProcessReceivedDataAsOldPackets(char* errbuf = 0);
void ProcessNetworkLayerPacket(ServerPacket* pack);
virtual bool LineOutQueuePush(char* line);
virtual void ClearBuffers();
EmuTCPServer* Server;
eTCPMode TCPMode;
ePacketMode PacketMode;
bool pOldFormat;
Timer keepalive_timer;
Timer timeout_timer;
//relay crap:
EmuTCPConnection* RelayLink;
int32 RelayCount;
bool RelayServer;
uint32 RemoteID;
//input queue...
void InModeQueuePush(EmuTCPNetPacket_Struct* tnps);
MyQueue<EmuTCPNetPacket_Struct> InModeQueue;
//output queue...
MyQueue<ServerPacket> OutQueue;
Mutex MOutQueueLock;
};
#endif /*EmuTCPCONNECTION_H_*/
+81
View File
@@ -0,0 +1,81 @@
#include "global_define.h"
#include "emu_tcp_server.h"
#include "emu_tcp_connection.h"
EmuTCPServer::EmuTCPServer(uint16 iPort, bool iOldFormat)
: TCPServer<EmuTCPConnection>(iPort),
pOldFormat(iOldFormat)
{
}
EmuTCPServer::~EmuTCPServer() {
MInQueue.lock();
while(!m_InQueue.empty()) {
delete m_InQueue.front();
m_InQueue.pop();
}
MInQueue.unlock();
}
void EmuTCPServer::Process() {
CheckInQueue();
TCPServer<EmuTCPConnection>::Process();
}
void EmuTCPServer::CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort)
{
auto conn = new EmuTCPConnection(ID, this, in_socket, irIP, irPort, pOldFormat);
AddConnection(conn);
}
void EmuTCPServer::SendPacket(ServerPacket* pack) {
EmuTCPNetPacket_Struct* tnps = EmuTCPConnection::MakePacket(pack);
SendPacket(&tnps);
}
void EmuTCPServer::SendPacket(EmuTCPNetPacket_Struct** tnps) {
MInQueue.lock();
m_InQueue.push(*tnps);
MInQueue.unlock();
tnps = nullptr;
}
void EmuTCPServer::CheckInQueue() {
EmuTCPNetPacket_Struct* tnps = 0;
while (( tnps = InQueuePop() )) {
vitr cur, end;
cur = m_list.begin();
end = m_list.end();
for(; cur != end; cur++) {
if ((*cur)->GetMode() != EmuTCPConnection::modeConsole && (*cur)->GetRemoteID() == 0)
(*cur)->SendPacket(tnps);
}
safe_delete(tnps);
}
}
EmuTCPNetPacket_Struct* EmuTCPServer::InQueuePop() {
EmuTCPNetPacket_Struct* ret = nullptr;
MInQueue.lock();
if(!m_InQueue.empty()) {
ret = m_InQueue.front();
m_InQueue.pop();
}
MInQueue.unlock();
return ret;
}
EmuTCPConnection *EmuTCPServer::FindConnection(uint32 iID) {
vitr cur, end;
cur = m_list.begin();
end = m_list.end();
for(; cur != end; cur++) {
if ((*cur)->GetID() == iID)
return *cur;
}
return(nullptr);
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef EmuTCPSERVER_H_
#define EmuTCPSERVER_H_
#include "tcp_server.h"
class EmuTCPConnection;
struct EmuTCPNetPacket_Struct;
class ServerPacket;
class EmuTCPServer : public TCPServer<EmuTCPConnection> {
public:
EmuTCPServer(uint16 iPort = 0, bool iOldFormat = false);
virtual ~EmuTCPServer();
//packet broadcast routines.
void SendPacket(ServerPacket* pack);
void SendPacket(EmuTCPNetPacket_Struct** tnps);
//special crap for relay management
EmuTCPConnection *FindConnection(uint32 iID);
//exposed for some crap we pull. Do not call from outside this object.
using TCPServer<EmuTCPConnection>::AddConnection;
protected:
virtual void Process();
virtual void CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort);
bool pOldFormat;
//broadcast packet queue..
void CheckInQueue();
Mutex MInQueue;
EmuTCPNetPacket_Struct* InQueuePop(); //returns ownership
std::queue<EmuTCPNetPacket_Struct *> m_InQueue;
};
#endif /*EmuTCPSERVER_H_*/
+34 -222
View File
@@ -18,7 +18,6 @@
*/
#include "emu_versions.h"
#include "emu_constants.h"
bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version)
@@ -64,26 +63,32 @@ const char* EQEmu::versions::ClientVersionName(ClientVersion client_version)
uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return bit_Unknown;
case ClientVersion::Titanium:
return bitTitanium;
return bit_Titanium;
case ClientVersion::SoF:
return bitSoF;
return bit_SoF;
case ClientVersion::SoD:
return bitSoD;
return bit_SoD;
case ClientVersion::UF:
return bitUF;
return bit_UF;
case ClientVersion::RoF:
return bitRoF;
return bit_RoF;
case ClientVersion::RoF2:
return bitRoF2;
return bit_RoF2;
default:
return bitUnknown;
return bit_Unknown;
}
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
{
switch (client_version_bit) {
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown) :
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)) :
return ClientVersion::Unknown;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
return ClientVersion::Titanium;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)) :
@@ -101,6 +106,27 @@ EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientV
}
}
uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
case ClientVersion::Titanium:
return 0x000007FFU;
case ClientVersion::SoF:
return 0x00007FFFU;
case ClientVersion::SoD:
return 0x0000FFFFU;
case ClientVersion::UF:
return 0x0001FFFFU;
case ClientVersion::RoF:
case ClientVersion::RoF2:
return 0x000FFFFFU;
default:
return 0;
}
}
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
{
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
@@ -342,217 +368,3 @@ EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobV
return MobVersion::Unknown;
}
}
const char* EQEmu::expansions::ExpansionName(Expansion expansion)
{
switch (expansion) {
case Expansion::EverQuest:
return "EverQuest";
case Expansion::RoK:
return "The Ruins of Kunark";
case Expansion::SoV:
return "The Scars of Velious";
case Expansion::SoL:
return "The Shadows of Luclin";
case Expansion::PoP:
return "The Planes of Power";
case Expansion::LoY:
return "The Legacy of Ykesha";
case Expansion::LDoN:
return "Lost Dungeons of Norrath";
case Expansion::GoD:
return "Gates of Discord";
case Expansion::OoW:
return "Omens of War";
case Expansion::DoN:
return "Dragons of Norrath";
case Expansion::DoD:
return "Depths of Darkhollow";
case Expansion::PoR:
return "Prophecy of Ro";
case Expansion::TSS:
return "The Serpent's Spine";
case Expansion::TBS:
return "The Buried Sea";
case Expansion::SoF:
return "Secrets of Faydwer";
case Expansion::SoD:
return "Seeds of Destruction";
case Expansion::UF:
return "Underfoot";
case Expansion::HoT:
return "House of Thule";
case Expansion::VoA:
return "Veil of Alaris";
case Expansion::RoF:
return "Rain of Fear";
case Expansion::CotF:
return "Call of the Forsaken";
default:
return "Invalid Expansion";
}
}
const char* EQEmu::expansions::ExpansionName(uint32 expansion_bit)
{
return ExpansionName(ConvertExpansionBitToExpansion(expansion_bit));
}
uint32 EQEmu::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
{
switch (expansion) {
case Expansion::RoK:
return bitRoK;
case Expansion::SoV:
return bitSoV;
case Expansion::SoL:
return bitSoL;
case Expansion::PoP:
return bitPoP;
case Expansion::LoY:
return bitLoY;
case Expansion::LDoN:
return bitLDoN;
case Expansion::GoD:
return bitGoD;
case Expansion::OoW:
return bitOoW;
case Expansion::DoN:
return bitDoN;
case Expansion::DoD:
return bitDoD;
case Expansion::PoR:
return bitPoR;
case Expansion::TSS:
return bitTSS;
case Expansion::TBS:
return bitTBS;
case Expansion::SoF:
return bitSoF;
case Expansion::SoD:
return bitSoD;
case Expansion::UF:
return bitUF;
case Expansion::HoT:
return bitHoT;
case Expansion::VoA:
return bitVoA;
case Expansion::RoF:
return bitRoF;
case Expansion::CotF:
return bitCotF;
default:
return bitEverQuest;
}
}
EQEmu::expansions::Expansion EQEmu::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
{
switch (expansion_bit) {
case bitRoK:
return Expansion::RoK;
case bitSoV:
return Expansion::SoV;
case bitSoL:
return Expansion::SoL;
case bitPoP:
return Expansion::PoP;
case bitLoY:
return Expansion::LoY;
case bitLDoN:
return Expansion::LDoN;
case bitGoD:
return Expansion::GoD;
case bitOoW:
return Expansion::OoW;
case bitDoN:
return Expansion::DoN;
case bitDoD:
return Expansion::DoD;
case bitPoR:
return Expansion::PoR;
case bitTSS:
return Expansion::TSS;
case bitTBS:
return Expansion::TBS;
case bitSoF:
return Expansion::SoF;
case bitSoD:
return Expansion::SoD;
case bitUF:
return Expansion::UF;
case bitHoT:
return Expansion::HoT;
case bitVoA:
return Expansion::VoA;
case bitRoF:
return Expansion::RoF;
case bitCotF:
return Expansion::CotF;
default:
return Expansion::EverQuest;
}
}
uint32 EQEmu::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
{
switch (expansion) {
case Expansion::RoK:
return maskRoK;
case Expansion::SoV:
return maskSoV;
case Expansion::SoL:
return maskSoL;
case Expansion::PoP:
return maskPoP;
case Expansion::LoY:
return maskLoY;
case Expansion::LDoN:
return maskLDoN;
case Expansion::GoD:
return maskGoD;
case Expansion::OoW:
return maskOoW;
case Expansion::DoN:
return maskDoN;
case Expansion::DoD:
return maskDoD;
case Expansion::PoR:
return maskPoR;
case Expansion::TSS:
return maskTSS;
case Expansion::TBS:
return maskTBS;
case Expansion::SoF:
return maskSoF;
case Expansion::SoD:
return maskSoD;
case Expansion::UF:
return maskUF;
case Expansion::HoT:
return maskHoT;
case Expansion::VoA:
return maskVoA;
case Expansion::RoF:
return maskRoF;
case Expansion::CotF:
return maskCotF;
default:
return maskEverQuest;
}
}
EQEmu::expansions::Expansion EQEmu::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
{
return EQEmu::constants::StaticLookup(client_version)->Expansion;
}
uint32 EQEmu::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
{
return EQEmu::constants::StaticLookup(client_version)->ExpansionBit;
}
uint32 EQEmu::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
{
return EQEmu::constants::StaticLookup(client_version)->ExpansionsMask;
}
+25 -119
View File
@@ -28,7 +28,7 @@
namespace EQEmu
{
namespace versions {
enum class ClientVersion : uint32 {
enum class ClientVersion {
Unknown = 0,
Client62, // Build: 'Aug 4 2005 15:40:59'
Titanium, // Build: 'Oct 31 2005 10:33:37'
@@ -39,27 +39,26 @@ namespace EQEmu
RoF2 // Build: 'May 10 2013 23:30:08'
};
enum ClientVersionBitmask : uint32 {
bitUnknown = 0x00000000,
bitClient62 = 0x00000001, // unsupported (placeholder for scripts)
bitTitanium = 0x00000002,
bitSoF = 0x00000004,
bitSoD = 0x00000008,
bitUF = 0x00000010,
bitRoF = 0x00000020,
bitRoF2 = 0x00000040,
maskUnknown = 0x00000000,
maskTitaniumAndEarlier = 0x00000003,
maskSoFAndEarlier = 0x00000007,
maskSoDAndEarlier = 0x0000000F,
maskUFAndEarlier = 0x0000001F,
maskRoFAndEarlier = 0x0000003F,
maskSoFAndLater = 0xFFFFFFFC,
maskSoDAndLater = 0xFFFFFFF8,
maskUFAndLater = 0xFFFFFFF0,
maskRoFAndLater = 0xFFFFFFE0,
maskRoF2AndLater = 0xFFFFFFC0,
maskAllClients = 0xFFFFFFFF
enum ClientVersionBit : uint32 {
bit_Unknown = 0,
bit_Client62 = 0x00000001, // unsupported (placeholder for scripts)
bit_Titanium = 0x00000002,
bit_SoF = 0x00000004,
bit_SoD = 0x00000008,
bit_UF = 0x00000010,
bit_RoF = 0x00000020,
bit_RoF2 = 0x00000040,
bit_TitaniumAndEarlier = 0x00000003,
bit_SoFAndEarlier = 0x00000007,
bit_SoDAndEarlier = 0x0000000F,
bit_UFAndEarlier = 0x0000001F,
bit_RoFAndEarlier = 0x0000003F,
bit_SoFAndLater = 0xFFFFFFFC,
bit_SoDAndLater = 0xFFFFFFF8,
bit_UFAndLater = 0xFFFFFFF0,
bit_RoFAndLater = 0xFFFFFFE0,
bit_RoF2AndLater = 0xFFFFFFC0,
bit_AllClients = 0xFFFFFFFF
};
const ClientVersion LastClientVersion = ClientVersion::RoF2;
@@ -70,8 +69,10 @@ namespace EQEmu
const char* ClientVersionName(ClientVersion client_version);
uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
enum class MobVersion : uint32 {
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
enum class MobVersion {
Unknown = 0,
Client62,
Titanium,
@@ -120,103 +121,8 @@ namespace EQEmu
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version);
MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version);
enum UCSVersion : char {
ucsUnknown = '\0',
ucsClient62Chat = 'A',
ucsClient62Mail = 'a',
ucsTitaniumChat = 'B',
ucsTitaniumMail = 'b',
ucsSoFCombined = 'C',
ucsSoDCombined = 'D',
ucsUFCombined = 'E',
ucsRoFCombined = 'F',
ucsRoF2Combined = 'G'
};
} /*versions*/
namespace expansions {
enum class Expansion : uint32 {
EverQuest = 0,
RoK,
SoV,
SoL,
PoP,
LoY,
LDoN,
GoD,
OoW,
DoN,
DoD,
PoR,
TSS,
TBS,
SoF,
SoD,
UF,
HoT,
VoA,
RoF,
CotF
};
enum ExpansionBitmask : uint32 {
bitEverQuest = 0x00000000,
bitRoK = 0x00000001,
bitSoV = 0x00000002,
bitSoL = 0x00000004,
bitPoP = 0x00000008,
bitLoY = 0x00000010,
bitLDoN = 0x00000020,
bitGoD = 0x00000040,
bitOoW = 0x00000080,
bitDoN = 0x00000100,
bitDoD = 0x00000200,
bitPoR = 0x00000400,
bitTSS = 0x00000800,
bitTBS = 0x00001000,
bitSoF = 0x00002000,
bitSoD = 0x00004000,
bitUF = 0x00008000,
bitHoT = 0x00010000,
bitVoA = 0x00020000,
bitRoF = 0x00040000,
bitCotF = 0x00080000,
maskEverQuest = 0x00000000,
maskRoK = 0x00000001,
maskSoV = 0x00000003,
maskSoL = 0x00000007,
maskPoP = 0x0000000F,
maskLoY = 0x0000001F,
maskLDoN = 0x0000003F,
maskGoD = 0x0000007F,
maskOoW = 0x000000FF,
maskDoN = 0x000001FF,
maskDoD = 0x000003FF,
maskPoR = 0x000007FF,
maskTSS = 0x00000FFF,
maskTBS = 0x00001FFF,
maskSoF = 0x00003FFF,
maskSoD = 0x00007FFF,
maskUF = 0x0000FFFF,
maskHoT = 0x0001FFFF,
maskVoA = 0x0003FFFF,
maskRoF = 0x0007FFFF,
maskCotF = 0x000FFFFF
};
const char* ExpansionName(Expansion expansion);
const char* ExpansionName(uint32 expansion_bit);
uint32 ConvertExpansionToExpansionBit(Expansion expansion);
Expansion ConvertExpansionBitToExpansion(uint32 expansion_bit);
uint32 ConvertExpansionToExpansionsMask(Expansion expansion);
Expansion ConvertClientVersionToExpansion(versions::ClientVersion client_version);
uint32 ConvertClientVersionToExpansionBit(versions::ClientVersion client_version);
uint32 ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version);
} /*expansions*/
} /*EQEmu*/
#endif /*COMMON_EMU_VERSIONS_H*/
+211 -156
View File
@@ -27,7 +27,7 @@
//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2)
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
#define AT_WhoLevel 1 // the level that shows up on /who
#define AT_HPMax 2 // idk
//#define AT_2 2 // unknown
#define AT_Invis 3 // 0 = visible, 1 = invisible
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
@@ -36,42 +36,38 @@
#define AT_SpawnID 16 // server to client, sets player spawn id
#define AT_HP 17 // Client->Server, my HP has changed (like regen tic)
#define AT_Linkdead 18 // 0 = normal, 1 = linkdead
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate max 5, see GravityBehavior enum
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate
#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM
#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay
#define AT_GuildID 22
#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader
#define AT_AFK 24 // 0 = normal, 1 = afk
#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks
#define AT_Summoned 27 // Unsure
//#define AT_27 27 // unknown
#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only)
#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2)
#define AT_SetType 30 // 0 = PC, 1 = NPC, 2 <= = corpse
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name, Trader on RoF2?
#define AT_AARank 32 // AA Rank Title ID thingy, does is this the title in /who?
#define AT_CancelSneakHide 33 // Turns off Hide and Sneak
//#define AT_30 30 // unknown
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name
//#define AT_32 32 // unknown
//#define AT_33 33 // unknown
//#define AT_34 34 // unknown (present: SoF, absent: RoF2)
#define AT_AreaHPRegen 35 // guild hall regen pool sets to value * 0.001
#define AT_AreaManaRegen 36 // guild hall regen pool sets to value * 0.001
#define AT_AreaEndRegen 37 // guild hall regen pool sets to value * 0.001
#define AT_FreezeBuffs 38 // Freezes beneficial buff timers
#define AT_NpcTintIndex 39 // not 100% sure
#define AT_GroupConsent 40 // auto consent group
#define AT_RaidConsent 41 // auto consent raid
#define AT_GuildConsent 42 // auto consent guild
//#define AT_35 35 // unknown
//#define AT_36 36 // unknown
//#define AT_37 37 // unknown
//#define AT_38 38 // unknown
//#define AT_39 39 // unknown
#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic
#define AT_DamageState 44 // The damage state of a destructible object (0 through 10) plays soundids most only have 2 or 4 states though
#define AT_EQPlayers 45 // /eqplayersupdate
#define AT_FindBits 46 // set FindBits, whatever those are!
#define AT_TextureType 48 // TextureType
#define AT_FacePick 49 // Turns off face pick window? maybe ...
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
#define AT_Offline 53 // Offline mode
#define AT_DamageState 44 // The damage state of a destructible object (0 through 4)
//#define AT_46 46 // unknown
//#define AT_48 48 // unknown
//#define AT_49 49 // unknown
//#define AT_52 52 // (absent: SoF, present: RoF2) (not a replacement for RoF absent 29 or 34)
//#define AT_53 53 // (absent: SoF, present: RoF2) (not a replacement for RoF absent 29 or 34)
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
// animations for AT_Anim
#define ANIM_FREEZE 102
#define ANIM_FREEZE 102
#define ANIM_STAND 0x64
#define ANIM_SIT 0x6e
#define ANIM_CROUCH 0x6f
@@ -87,114 +83,199 @@ typedef enum {
_eaMaxAppearance
} EmuAppearance;
namespace Chat {
const uint16 White = 0;
const uint16 DimGray = 1;
const uint16 Default = 1;
const uint16 Green = 2;
const uint16 BrightBlue = 3;
const uint16 LightBlue = 4;
const uint16 Magenta = 5;
const uint16 Gray = 6;
const uint16 LightGray = 7;
const uint16 NPCQuestSay = 10;
const uint16 DarkGray = 12;
const uint16 Red = 13;
const uint16 Lime = 14;
const uint16 Yellow = 15;
const uint16 Blue = 16;
const uint16 LightNavy = 17;
const uint16 Cyan = 18;
const uint16 Black = 20;
// msg_type's for custom usercolors
#define MT_Say 256
#define MT_Tell 257
#define MT_Group 258
#define MT_Guild 259
#define MT_OOC 260
#define MT_Auction 261
#define MT_Shout 262
#define MT_Emote 263
#define MT_Spells 264
#define MT_YouHitOther 265
#define MT_OtherHitsYou 266
#define MT_YouMissOther 267
#define MT_OtherMissesYou 268
#define MT_Broadcasts 269
#define MT_Skills 270
#define MT_Disciplines 271
#define MT_Unused1 272
#define MT_DefaultText 273
#define MT_Unused2 274
#define MT_MerchantOffer 275
#define MT_MerchantBuySell 276
#define MT_YourDeath 277
#define MT_OtherDeath 278
#define MT_OtherHits 279
#define MT_OtherMisses 280
#define MT_Who 281
#define MT_YellForHelp 282
#define MT_NonMelee 283
#define MT_WornOff 284
#define MT_MoneySplit 285
#define MT_LootMessages 286
#define MT_DiceRoll 287
#define MT_OtherSpells 288
#define MT_SpellFailure 289
#define MT_Chat 290
#define MT_Channel1 291
#define MT_Channel2 292
#define MT_Channel3 293
#define MT_Channel4 294
#define MT_Channel5 295
#define MT_Channel6 296
#define MT_Channel7 297
#define MT_Channel8 298
#define MT_Channel9 299
#define MT_Channel10 300
#define MT_CritMelee 301
#define MT_SpellCrits 302
#define MT_TooFarAway 303
#define MT_NPCRampage 304
#define MT_NPCFlurry 305
#define MT_NPCEnrage 306
#define MT_SayEcho 307
#define MT_TellEcho 308
#define MT_GroupEcho 309
#define MT_GuildEcho 310
#define MT_OOCEcho 311
#define MT_AuctionEcho 312
#define MT_ShoutECho 313
#define MT_EmoteEcho 314
#define MT_Chat1Echo 315
#define MT_Chat2Echo 316
#define MT_Chat3Echo 317
#define MT_Chat4Echo 318
#define MT_Chat5Echo 319
#define MT_Chat6Echo 320
#define MT_Chat7Echo 321
#define MT_Chat8Echo 322
#define MT_Chat9Echo 323
#define MT_Chat10Echo 324
#define MT_DoTDamage 325
#define MT_ItemLink 326
#define MT_RaidSay 327
#define MT_MyPet 328
#define MT_DS 329
#define MT_Leadership 330
#define MT_PetFlurry 331
#define MT_PetCrit 332
#define MT_FocusEffect 333
#define MT_Experience 334
#define MT_System 335
#define MT_PetSpell 336
#define MT_PetResponse 337
#define MT_ItemSpeech 338
#define MT_StrikeThrough 339
#define MT_Stun 340
/**
* User colors
*/
const uint16 Say = 256;
const uint16 Tell = 257;
const uint16 Group = 258;
const uint16 Guild = 259;
const uint16 OOC = 260;
const uint16 Auction = 261;
const uint16 Shout = 262;
const uint16 Emote = 263;
const uint16 Spells = 264;
const uint16 YouHitOther = 265;
const uint16 OtherHitYou = 266;
const uint16 YouMissOther = 267;
const uint16 OtherMissYou = 268;
const uint16 Broadcasts = 269;
const uint16 Skills = 270;
const uint16 Disciplines = 271;
const uint16 Unused1 = 272;
const uint16 DefaultText = 273;
const uint16 Unused2 = 274;
const uint16 MerchantOffer = 275;
const uint16 MerchantExchange = 276;
const uint16 YourDeath = 277;
const uint16 OtherDeath = 278;
const uint16 OtherHitOther = 279;
const uint16 OtherMissOther = 280;
const uint16 Who = 281;
const uint16 YellForHelp = 282;
const uint16 NonMelee = 283;
const uint16 SpellWornOff = 284;
const uint16 MoneySplit = 285;
const uint16 Loot = 286;
const uint16 DiceRoll = 287;
const uint16 OtherSpells = 288;
const uint16 SpellFailure = 289;
const uint16 ChatChannel = 290;
const uint16 Chat1 = 291;
const uint16 Chat2 = 292;
const uint16 Chat3 = 293;
const uint16 Chat4 = 294;
const uint16 Chat5 = 295;
const uint16 Chat6 = 296;
const uint16 Chat7 = 297;
const uint16 Chat8 = 298;
const uint16 Chat9 = 299;
const uint16 Chat10 = 300;
const uint16 MeleeCrit = 301;
const uint16 SpellCrit = 302;
const uint16 TooFarAway = 303;
const uint16 NPCRampage = 304;
const uint16 NPCFlurry = 305;
const uint16 NPCEnrage = 306;
const uint16 EchoSay = 307;
const uint16 EchoTell = 308;
const uint16 EchoGroup = 309;
const uint16 EchoGuild = 310;
const uint16 EchoOOC = 311;
const uint16 EchoAuction = 312;
const uint16 EchoShout = 313;
const uint16 EchoEmote = 314;
const uint16 EchoChat1 = 315;
const uint16 EchoChat2 = 316;
const uint16 EchoChat3 = 317;
const uint16 EchoChat4 = 318;
const uint16 EchoChat5 = 319;
const uint16 EchoChat6 = 320;
const uint16 EchoChat7 = 321;
const uint16 EchoChat8 = 322;
const uint16 EchoChat9 = 323;
const uint16 EchoChat10 = 324;
const uint16 DotDamage = 325;
const uint16 ItemLink = 326;
const uint16 RaidSay = 327;
const uint16 MyPet = 328;
const uint16 DamageShield = 329;
const uint16 LeaderShip = 330;
const uint16 PetFlurry = 331;
const uint16 PetCritical = 332;
const uint16 FocusEffect = 333;
const uint16 Experience = 334;
const uint16 System = 335;
const uint16 PetSpell = 336;
const uint16 PetResponse = 337;
const uint16 ItemSpeech = 338;
const uint16 StrikeThrough = 339;
const uint16 Stun = 340;
// TODO: Really should combine above and below into one
//from showeq
enum ChatColor
{
/*
CC_Default = 0,
CC_DarkGrey = 1,
CC_DarkGreen = 2,
CC_DarkBlue = 3,
CC_Purple = 5,
CC_LightGrey = 6,
*/
CC_WhiteSmoke = 0, // FF|F0F0F0
CC_Green = 2, // FF|008000
CC_BrightBlue = 3, // FF|0040FF
CC_Magenta = 5, // FF|F000F0
CC_Gray = 6, // FF|808080
CC_LightGray = 7, // FF|E0E0E0
//CC_WhiteSmoke2 = 10, // FF|F0F0F0
CC_DarkGray = 12, // FF|A0A0A0
CC_Red = 13, // FF|F00000
CC_Lime = 14, // FF|00F000
CC_Yellow = 15, // FF|F0F000
CC_Blue = 16, // FF|0000F0
CC_LightNavy = 17, // FF|0000AF
CC_Cyan = 18, // FF|00F0F0
CC_Black = 20, // FF|000000
// any index <= 255 that is not defined above
CC_DimGray = 1, // FF|606060
CC_Default = 1,
CC_User_Say = 256,
CC_User_Tell = 257,
CC_User_Group = 258,
CC_User_Guild = 259,
CC_User_OOC = 260,
CC_User_Auction = 261,
CC_User_Shout = 262,
CC_User_Emote = 263,
CC_User_Spells = 264,
CC_User_YouHitOther = 265,
CC_User_OtherHitYou = 266,
CC_User_YouMissOther = 267,
CC_User_OtherMissYou = 268,
CC_User_Duels = 269,
CC_User_Skills = 270,
CC_User_Disciplines = 271,
CC_User_Default = 273,
CC_User_MerchantOffer = 275,
CC_User_MerchantExchange = 276,
CC_User_YourDeath = 277,
CC_User_OtherDeath = 278,
CC_User_OtherHitOther = 279,
CC_User_OtherMissOther = 280,
CC_User_Who = 281,
CC_User_Yell = 282,
CC_User_NonMelee = 283,
CC_User_SpellWornOff = 284,
CC_User_MoneySplit = 285,
CC_User_Loot = 286,
CC_User_Random = 287,
CC_User_OtherSpells = 288,
CC_User_SpellFailure = 289,
CC_User_ChatChannel = 290,
CC_User_Chat1 = 291,
CC_User_Chat2 = 292,
CC_User_Chat3 = 293,
CC_User_Chat4 = 294,
CC_User_Chat5 = 295,
CC_User_Chat6 = 296,
CC_User_Chat7 = 297,
CC_User_Chat8 = 298,
CC_User_Chat9 = 299,
CC_User_Chat10 = 300,
CC_User_MeleeCrit = 301,
CC_User_SpellCrit = 302,
CC_User_TooFarAway = 303,
CC_User_NPCRampage = 304,
CC_User_NPCFurry = 305,
CC_User_NPCEnrage = 306,
CC_User_EchoSay = 307,
CC_User_EchoTell = 308,
CC_User_EchoGroup = 309,
CC_User_EchoGuild = 310,
CC_User_EchoOOC = 311,
CC_User_EchoAuction = 312,
CC_User_EchoShout = 313,
CC_User_EchoEmote = 314,
CC_User_EchoChat1 = 315,
CC_User_EchoChat2 = 316,
CC_User_EchoChat3 = 317,
CC_User_EchoChat4 = 318,
CC_User_EchoChat5 = 319,
CC_User_EchoChat6 = 320,
CC_User_EchoChat7 = 321,
CC_User_EchoChat8 = 322,
CC_User_EchoChat9 = 323,
CC_User_EchoChat10 = 324,
CC_User_UnusedAtThisTime = 325,
CC_User_ItemTags = 326,
CC_User_RaidSay = 327,
CC_User_MyPet = 328,
CC_User_DamageShield = 329,
};
//ZoneChange_Struct->success values
@@ -438,30 +519,4 @@ static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // chang
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
enum ChatChannelNames : uint16
{
ChatChannel_Guild = 0,
ChatChannel_Group = 2,
ChatChannel_Shout = 3,
ChatChannel_Auction = 4,
ChatChannel_OOC = 5,
ChatChannel_Broadcast = 6,
ChatChannel_Tell = 7,
ChatChannel_Say = 8,
ChatChannel_Petition = 10,
ChatChannel_GMSAY = 11,
ChatChannel_TellEcho = 14,
ChatChannel_Raid = 15,
ChatChannel_UNKNOWN_Guild = 17,
ChatChannel_UNKNOWN_GMSAY = 18,
ChatChannel_UCSRelay = 20,
ChatChannel_Emotes = 22
};
namespace ZoneBlockedSpellTypes {
const uint8 ZoneWide = 1;
const uint8 Region = 2;
};
#endif /*COMMON_EQ_CONSTANTS_H*/
+882 -1148
View File
File diff suppressed because it is too large Load Diff
+40 -208
View File
@@ -20,6 +20,7 @@
#ifndef COMMON_EQ_LIMITS_H
#define COMMON_EQ_LIMITS_H
#include "emu_legacy.h"
#include "types.h"
#include "eq_constants.h"
#include "emu_versions.h"
@@ -33,166 +34,10 @@
namespace EQEmu
{
void InitializeDynamicLookups();
namespace constants {
struct LookupEntry {
EQEmu::expansions::Expansion Expansion;
uint32 ExpansionBit;
uint32 ExpansionsMask;
int16 CharacterCreationLimit;
size_t SayLinkBodySize;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
EQEmu::expansions::Expansion Expansion,
uint32 ExpansionBit,
uint32 ExpansionsMask,
int16 CharacterCreationLimit,
size_t SayLinkBodySize
) :
Expansion(Expansion),
ExpansionBit(ExpansionBit),
ExpansionsMask(ExpansionsMask),
CharacterCreationLimit(CharacterCreationLimit),
SayLinkBodySize(SayLinkBodySize)
{ }
};
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::ClientVersion client_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::ClientVersion client_version);
const LookupEntry* DynamicGMLookup(versions::ClientVersion client_version);
const LookupEntry* StaticLookup(versions::ClientVersion client_version);
} /*constants*/
namespace inventory {
struct LookupEntry {
// note: 'PossessionsBitmask' needs to be attuned to the client version with the highest number
// of possessions slots and 'InventoryTypeSize[typePossessions]' should reflect the same count
// with translators adjusting for valid slot indices. Server-side validations will be performed
// against 'PossessionsBitmask' (note: the same applies to CorpseBitmask..size is not dependent)
struct InventoryTypeSize_Struct { // should reflect count and naming conventions referenced in emu_constants.h
int16 Possessions, Bank, SharedBank;
int16 Trade, World, Limbo;
int16 Tribute, TrophyTribute, GuildTribute;
int16 Merchant, Deleted, Corpse;
int16 Bazaar, Inspect, RealEstate;
int16 ViewMODPC, ViewMODBank, ViewMODSharedBank;
int16 ViewMODLimbo, AltStorage, Archived;
int16 Mail, GuildTrophyTribute, Krono;
int16 Other;
InventoryTypeSize_Struct(
int16 Possessions, int16 Bank, int16 SharedBank,
int16 Trade, int16 World, int16 Limbo,
int16 Tribute, int16 TrophyTribute, int16 GuildTribute,
int16 Merchant, int16 Deleted, int16 Corpse,
int16 Bazaar, int16 Inspect, int16 RealEstate,
int16 ViewMODPC, int16 ViewMODBank, int16 ViewMODSharedBank,
int16 ViewMODLimbo, int16 AltStorage, int16 Archived,
int16 Mail, int16 GuildTrophyTribute, int16 Krono,
int16 Other
) :
Possessions(Possessions), Bank(Bank), SharedBank(SharedBank),
Trade(Trade), World(World), Limbo(Limbo),
Tribute(Tribute), TrophyTribute(TrophyTribute), GuildTribute(GuildTribute),
Merchant(Merchant), Deleted(Deleted), Corpse(Corpse),
Bazaar(Bazaar), Inspect(Inspect), RealEstate(RealEstate),
ViewMODPC(ViewMODPC), ViewMODBank(ViewMODBank), ViewMODSharedBank(ViewMODSharedBank),
ViewMODLimbo(ViewMODLimbo), AltStorage(AltStorage), Archived(Archived),
Mail(Mail), GuildTrophyTribute(GuildTrophyTribute), Krono(Krono),
Other(Other)
{ }
};
union {
InventoryTypeSize_Struct InventoryTypeSize;
int16 InventoryTypeSizeArray[25]; // should reflect EQEmu::invtype::TYPE_COUNT referenced in emu_constants.h
};
uint64 EquipmentBitmask;
uint64 GeneralBitmask;
uint64 CursorBitmask;
uint64 PossessionsBitmask;
uint64 CorpseBitmask;
int16 BagSlotCount;
int16 AugSocketCount;
bool AllowEmptyBagInBag;
bool AllowClickCastFromBag;
bool ConcatenateInvTypeLimbo;
bool AllowOverLevelEquipment;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
InventoryTypeSize_Struct InventoryTypeSize,
uint64 EquipmentBitmask,
uint64 GeneralBitmask,
uint64 CursorBitmask,
uint64 PossessionsBitmask,
uint64 CorpseBitmask,
int16 BagSlotCount,
int16 AugSocketCount,
bool AllowEmptyBagInBag,
bool AllowClickCastFromBag,
bool ConcatenateInvTypeLimbo,
bool AllowOverLevelEquipment
) :
InventoryTypeSize(InventoryTypeSize),
EquipmentBitmask(EquipmentBitmask),
GeneralBitmask(GeneralBitmask),
CursorBitmask(CursorBitmask),
PossessionsBitmask(PossessionsBitmask),
CorpseBitmask(CorpseBitmask),
BagSlotCount(BagSlotCount),
AugSocketCount(AugSocketCount),
AllowEmptyBagInBag(AllowEmptyBagInBag),
AllowClickCastFromBag(AllowClickCastFromBag),
ConcatenateInvTypeLimbo(ConcatenateInvTypeLimbo),
AllowOverLevelEquipment(AllowOverLevelEquipment)
{ }
};
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::MobVersion mob_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::MobVersion mob_version);
const LookupEntry* DynamicGMLookup(versions::MobVersion mob_version);
const LookupEntry* StaticLookup(versions::MobVersion mob_version);
} /*inventory*/
namespace behavior {
struct LookupEntry {
bool CoinHasWeight;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
bool CoinHasWeight
) :
CoinHasWeight(CoinHasWeight)
{ }
};
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::MobVersion mob_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::MobVersion mob_version);
const LookupEntry* DynamicGMLookup(versions::MobVersion mob_version);
const LookupEntry* StaticLookup(versions::MobVersion mob_version);
} /*behavior*/
namespace spells {
struct LookupEntry {
int SpellIdMax;
int SpellbookSize;
int SpellGemCount;
class LookupEntry {
public:
size_t CharacterCreationLimit;
int LongBuffs;
int ShortBuffs;
int DiscBuffs;
@@ -200,69 +45,56 @@ namespace EQEmu
int NPCBuffs;
int PetBuffs;
int MercBuffs;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
int SpellIdMax,
int SpellbookSize,
int SpellGemCount,
int LongBuffs,
int ShortBuffs,
int DiscBuffs,
int TotalBuffs,
int NPCBuffs,
int PetBuffs,
int MercBuffs
) :
SpellIdMax(SpellIdMax),
SpellbookSize(SpellbookSize),
SpellGemCount(SpellGemCount),
LongBuffs(LongBuffs),
ShortBuffs(ShortBuffs),
DiscBuffs(DiscBuffs),
TotalBuffs(TotalBuffs),
NPCBuffs(NPCBuffs),
PetBuffs(PetBuffs),
MercBuffs(MercBuffs)
{ }
};
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::ClientVersion client_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::ClientVersion client_version);
const LookupEntry* DynamicGMLookup(versions::ClientVersion client_version);
const LookupEntry* StaticLookup(versions::ClientVersion client_version);
} /*spells*/
const LookupEntry* Lookup(versions::ClientVersion client_version);
} /*constants*/
namespace inventory {
class LookupEntry {
public:
size_t InventoryTypeSize[25]; // should reflect EQEmu::inventory::typeCount referenced in emu_constants.h
uint64 PossessionsBitmask;
size_t ItemBagSize;
size_t ItemAugSize;
bool AllowEmptyBagInBag;
bool AllowClickCastFromBag;
bool ConcatenateInvTypeLimbo;
bool AllowOverLevelEquipment;
};
const LookupEntry* Lookup(versions::MobVersion mob_version);
} /*inventory*/
namespace behavior {
class LookupEntry {
public:
bool CoinHasWeight;
};
const LookupEntry* Lookup(versions::MobVersion mob_version);
} /*behavior*/
} /*EQEmu*/
namespace ClientUnknown
{
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace constants {
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::EverQuest;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitEverQuest;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskEverQuest;
} // namespace constants
enum : bool { False = false, True = true };
} /*ClientUnknown*/
namespace Client62
{
const int16 IINVALID = -1;
const int16 INULL = 0;
enum : int { Invalid = -1, Null, Safety };
namespace constants {
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::EverQuest;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitEverQuest;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskEverQuest;
} // namespace constants
enum : bool { False = false, True = true };
} /*Client62*/
+1 -1
View File
@@ -132,7 +132,7 @@ void EQApplicationPacket::build_header_dump(char *buffer) const
#ifdef STATIC_OPCODE
sprintf(buffer, "[OpCode 0x%04x Size=%u]\n", emu_opcode,size);
#else
sprintf(buffer, "[OpCode %s(0x%04x) Size=%u]",OpcodeManager::EmuToName(emu_opcode), GetProtocolOpcode(), size);
sprintf(buffer, "[OpCode %s Size=%u]",OpcodeManager::EmuToName(emu_opcode),size);
#endif
}
+1 -7
View File
@@ -51,7 +51,6 @@ protected:
EmuOpcode emu_opcode;
EQPacket(EmuOpcode opcode, const unsigned char *buf, const uint32 len);
EQPacket(EmuOpcode opcode, SerializeBuffer &buf) : BasePacket(buf), emu_opcode(opcode) { };
// EQPacket(const EQPacket &p) { }
EQPacket() { emu_opcode=OP_Unknown; pBuffer=nullptr; size=0; }
@@ -105,8 +104,6 @@ public:
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
EQApplicationPacket(const EmuOpcode op, SerializeBuffer &buf) : EQPacket(op, buf), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
bool combine(const EQApplicationPacket *rhs);
uint32 serialize (uint16 opcode, unsigned char *dest) const;
uint32 Size() const { return size+app_opcode_size; }
@@ -118,14 +115,11 @@ public:
virtual void DumpRawHeader(uint16 seq=0xffff, FILE *to = stdout) const;
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
uint16 GetOpcodeBypass() const { return opcode_bypass; }
uint16 GetOpcodeBypass() { return opcode_bypass; }
void SetOpcodeBypass(uint16 v) { opcode_bypass = v; }
uint16 GetProtocolOpcode() const { return protocol_opcode; }
void SetProtocolOpcode(uint16 v) { protocol_opcode = v; }
protected:
uint16 protocol_opcode;
uint8 app_opcode_size;
uint16 opcode_bypass;
private:
+119 -216
View File
@@ -280,7 +280,7 @@ union
// horse: 0=brown, 1=white, 2=black, 3=tan
};
/*0340*/ uint32 spawnId; // Spawn Id
/*0344*/ float bounding_radius; // used in melee, overrides calc
/*0344*/ uint8 unknown0344[3];
/*0347*/ uint8 IsMercenary;
/*0348*/ EQEmu::TintProfile equipment_tint;
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
@@ -305,7 +305,7 @@ union
uint8 DestructibleUnk8;
uint32 DestructibleUnk9;
bool targetable_with_hotkey;
bool show_name;
};
struct PlayerState_Struct {
@@ -375,11 +375,7 @@ struct NewZone_Struct {
/*0692*/ uint8 unknown692[8];
/*0700*/ float fog_density;
/*0704*/ uint32 SuspendBuffs;
/*0708*/ uint32 FastRegenHP;
/*0712*/ uint32 FastRegenMana;
/*0716*/ uint32 FastRegenEndurance;
/*0720*/ uint32 NPCAggroMaxDist;
/*0724*/
/*0704*/
};
/*
@@ -554,7 +550,6 @@ struct BlockedBuffs_Struct
/*86*/ uint16 Flags;
};
// same for adding
struct RemoveNimbusEffect_Struct
{
/*00*/ uint32 spawnid; // Spawn ID
@@ -734,7 +729,7 @@ struct BandolierItem_Struct
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[EQEmu::profile::BANDOLIER_ITEM_COUNT];
BandolierItem_Struct Items[EQEmu::legacy::BANDOLIER_ITEM_COUNT];
};
//len = 72
@@ -748,7 +743,7 @@ struct PotionBeltItem_Struct
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[EQEmu::profile::POTION_BELT_SIZE];
PotionBeltItem_Struct Items[EQEmu::legacy::POTION_BELT_ITEM_COUNT];
};
struct MovePotionToBelt_Struct
@@ -852,9 +847,12 @@ struct SuspendedMinion_Struct
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions
static const uint32 MAX_PP_MEMSPELL = static_cast<uint32>(EQEmu::CastingSlot::MaxGems); // Set to latest client so functions can work right -- 12
static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 240;
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -909,7 +907,7 @@ sed -e 's/_t//g' -e 's/MAX_AA/MAX_PP_AA_ARRAY/g' \
struct PlayerProfile_Struct
{
// /*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum
/*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum
/*0004*/ char name[64]; // Name of player sizes not right
/*0068*/ char last_name[32]; // Last name of player sizes not right
/*0100*/ uint32 gender; // Player Gender - 0 Male, 1 Female
@@ -931,7 +929,7 @@ struct PlayerProfile_Struct
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[EQEmu::spells::SPELL_GEM_COUNT]; //in ms
/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
@@ -970,9 +968,9 @@ struct PlayerProfile_Struct
/*2505*/ uint8 unknown2541[47]; // ?
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[EQEmu::spells::SPELLBOOK_SIZE];
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[EQEmu::spells::SPELL_GEM_COUNT];
/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
@@ -994,8 +992,7 @@ struct PlayerProfile_Struct
/*4768*/ int32 platinum_shared; // Platinum shared between characters
/*4772*/ uint8 unknown4808[24];
/*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*5196*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*5296*/ uint8 unknown5132[84];
/*5196*/ uint8 unknown5132[184];
/*5380*/ uint32 pvp2; //
/*5384*/ uint32 unknown5420; //
/*5388*/ uint32 pvptype; //
@@ -1048,7 +1045,7 @@ struct PlayerProfile_Struct
/*7212*/ uint32 tribute_points;
/*7216*/ uint32 unknown7252;
/*7220*/ uint32 tribute_active; //1=active
/*7224*/ Tribute_Struct tributes[EQEmu::invtype::TRIBUTE_SIZE];
/*7224*/ Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE];
/*7264*/ Disciplines_Struct disciplines;
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
/*7744*/ char unknown7780[160];
@@ -1075,7 +1072,7 @@ struct PlayerProfile_Struct
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Bandolier_Struct bandoliers[EQEmu::profile::BANDOLIERS_SIZE];
/*12844*/ Bandolier_Struct bandoliers[EQEmu::legacy::BANDOLIERS_SIZE];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
@@ -1091,18 +1088,6 @@ struct PlayerProfile_Struct
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
/*19564*/ uint32 RestTimer;
/*19568*/
// All player profile packets are translated and this overhead is ignored in out-bound packets
PlayerProfile_Struct() : m_player_profile_version(EQEmu::versions::MobVersion::Unknown) { }
EQEmu::versions::MobVersion PlayerProfileVersion() { return m_player_profile_version; }
void SetPlayerProfileVersion(EQEmu::versions::MobVersion mob_version) { m_player_profile_version = EQEmu::versions::ValidateMobVersion(mob_version); }
void SetPlayerProfileVersion(EQEmu::versions::ClientVersion client_version) { SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(client_version)); }
private:
// No need for gm flag since pp already has one
// No need for lookup pointer since this struct is not tied to any one system
EQEmu::versions::MobVersion m_player_profile_version;
};
@@ -1131,11 +1116,6 @@ struct PetCommand_Struct {
/*004*/ uint32 target;
};
struct PetCommandState_Struct {
/*00*/ uint32 button_id;
/*04*/ uint32 state;
};
/*
** Delete Spawn
** Length: 4 Bytes
@@ -1188,33 +1168,19 @@ struct SpecialMesg_Struct
/*24*/ char message[1]; // What is being said?
};
struct SpecialMesgHeader_Struct
{
/*00*/ char SpeakMode; // 2 shouts, 4 %1 %2, 3 %2, 5 tells group, 0 copy, default says
/*01*/ char JournalMode; // 1 and 2 go to journal
/*02*/ char language;
/*03*/ uint32 msg_type; // Color of text (see MT_*** below)
/*07*/ uint32 target_spawn_id; // Who is it being said to?
/*11*/ // speaker's name
/*xx*/ // unknown, location, client doesn't care
/*xx*/ // unknown
/*xx*/ // unknown
/*xx*/ // message
};
/*
** When somebody changes what they're wearing or give a pet a weapon (model changes)
** Length: 19 Bytes
*/
struct WearChange_Struct {
/*000*/ uint16 spawn_id;
/*002*/ uint32 material;
/*006*/ uint32 unknown06;
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ uint32 hero_forge_model; // New to VoA
/*018*/ uint32 unknown18; // New to RoF
struct WearChange_Struct{
/*000*/ uint16 spawn_id;
/*002*/ uint32 material;
/*006*/ uint32 unknown06;
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ uint32 hero_forge_model; // New to VoA
/*018*/ uint32 unknown18; // New to RoF
/*022*/ EQEmu::textures::Tint_Struct color;
/*026*/ uint8 wear_slot_id;
/*026*/ uint8 wear_slot_id;
/*027*/
};
@@ -1278,22 +1244,21 @@ struct Action_Struct
{
/* 00 */ uint16 target; // id of target
/* 02 */ uint16 source; // id of caster
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/* 10 */ float force;
/* 14 */ float hit_heading;
/* 18 */ float hit_pitch;
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
/* 23 */ uint16 unknown23; // OSX says min_damage
/* 25 */ uint16 unknown25; // OSX says tohit
/* 04 */ uint16 level; // level of caster
/* 06 */ uint16 instrument_mod;
/* 08 */ uint32 bard_focus_id;
/* 12 */ uint16 unknown16;
// some kind of sequence that's the same in both actions
// as well as the combat damage, to tie em together?
/* 14 */ uint32 sequence;
/* 18 */ uint32 unknown18;
/* 22 */ uint8 type; // 231 (0xE7) for spells
/* 23 */ uint32 unknown23;
/* 27 */ uint16 spell; // spell id being cast
/* 29 */ uint8 spell_level;
/* 29 */ uint8 unknown29;
// this field seems to be some sort of success flag, if it's 4
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
// newer clients have some data for setting LaunchSpellData when effect_flag & 4
// /* 31 */ uint8 spell_gem;
// /* 32 */ uint32 inventory_slot;
// /* 36 */ uint32 item_cast_type;
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
/* 31 */
};
// this is what prints the You have been struck. and the regular
@@ -1303,12 +1268,12 @@ struct CombatDamage_Struct
{
/* 00 */ uint16 target;
/* 02 */ uint16 source;
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells, skill
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ uint32 damage;
/* 11 */ float force;
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
};
@@ -1358,24 +1323,21 @@ struct BecomeCorpse_Struct {
*/
struct PlayerPositionUpdateServer_Struct
{
/*0000*/ uint16 spawn_id;
/*0002*/ uint16 vehicle_id;
/*0004*/ signed padding0004 : 12;
signed y_pos : 19; // y coord
unsigned padding : 1;
/*0008*/ signed delta_z : 13; // change in z
signed delta_x : 13; // change in x
signed padding0008 : 6;
/*0012*/ signed x_pos : 19; // x coord
unsigned heading : 12; // heading
signed padding0016 : 1;
/*0016*/ signed delta_heading : 10; // change in heading
signed z_pos : 19; // z coord
signed padding0020 : 3;
/*0020*/ signed animation : 10; // animation
signed delta_y : 13; // change in y
signed padding0024 : 9;
/*0024*/
/*0000*/ uint16 spawn_id;
/*0002*/ int32 delta_heading:10, // change in heading
x_pos:19, // x coord
padding0002:3; // ***Placeholder
/*0006*/ int32 y_pos:19, // y coord
animation:10, // animation
padding0006:3; // ***Placeholder
/*0010*/ int32 z_pos:19, // z coord
delta_y:13; // change in y
/*0014*/ int32 delta_x:13, // change in x
heading:12, // heading
padding0014:7; // ***Placeholder
/*0018*/ int32 delta_z:13, // change in z
padding0018:19; // ***Placeholder
/*0022*/
};
/*
@@ -1386,23 +1348,21 @@ struct PlayerPositionUpdateServer_Struct
*/
struct PlayerPositionUpdateClient_Struct
{
/*0000*/ uint16 sequence; // increments one each packet - Verified
/*0002*/ uint16 spawn_id; // Player's spawn id
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
/*0010*/ float delta_x; // Change in x
/*0014*/ unsigned heading : 12; // Directional heading
unsigned padding0040 : 20; // ***Placeholder
/*0018*/ float x_pos; // x coord (2nd loc value)
/*0022*/ float delta_z; // Change in z
/*0026*/ float z_pos; // z coord (3rd loc value)
/*0030*/ float y_pos; // y coord (1st loc value)
/*0034*/ unsigned animation : 10; // ***Placeholder
unsigned padding0024 : 22; // animation
/*0038*/ float delta_y; // Change in y
/*0042*/ signed delta_heading : 10; // change in heading
unsigned padding0041 : 22; // ***Placeholder
/*0046*/
/*0000*/ uint16 spawn_id;
/*0002*/ uint16 sequence; //increments one each packet
/*0004*/ float y_pos; // y coord
/*0008*/ float delta_z; // Change in z
/*0012*/ float delta_x; // Change in x
/*0016*/ float delta_y; // Change in y
/*0020*/ int32 animation:10, // animation
delta_heading:10, // change in heading
padding0020:12; // ***Placeholder (mostly 1)
/*0024*/ float x_pos; // x coord
/*0028*/ float z_pos; // z coord
/*0032*/ uint16 heading:12, // Directional heading
padding0004:4; // ***Placeholder
/*0034*/ uint8 unknown0006[2]; // ***Placeholder
/*0036*/
};
struct SpawnPositionUpdate_Struct
@@ -1730,7 +1690,6 @@ struct OnLevelMessage_Struct
uint32 Duration;
uint32 PopupID;
uint32 NegativeID;
uint32 SoundControls;
char ButtonName0[25];
char ButtonName1[25];
};
@@ -1813,15 +1772,6 @@ struct CombatAbility_Struct {
uint32 m_skill;
};
// Disarm Struct incoming from Client [Size: 16]
struct Disarm_Struct
{
uint32 source;
uint32 target;
uint32 skill;
uint32 unknown;
};
//Instill Doubt
struct Instill_Doubt_Struct {
uint8 i_id;
@@ -3363,32 +3313,23 @@ struct GuildMakeLeader{
char target[64];
};
struct BugReport_Struct {
/*0000*/ uint32 category_id;
/*0004*/ char category_name[64];
/*0068*/ char reporter_name[64];
/*0132*/ char unused_0132[32];
/*0164*/ char ui_path[128];
/*0292*/ float pos_x;
/*0296*/ float pos_y;
/*0300*/ float pos_z;
/*0304*/ uint32 heading;
/*0308*/ uint32 unused_0308;
/*0312*/ uint32 time_played;
/*0316*/ char padding_0316[8];
/*0324*/ uint32 target_id;
/*0328*/ char padding_0328[140];
/*0468*/ uint32 unknown_0468; // seems to always be '0'
/*0472*/ char target_name[64];
/*0536*/ uint32 optional_info_mask;
// this looks like a butchered 8k buffer with 2 trailing dword fields
/*0540*/ char unused_0540[2052];
/*2592*/ char bug_report[2050];
/*4642*/ char system_info[4098];
/*8740*/
struct BugStruct{
/*0000*/ char chartype[64];
/*0064*/ char name[96];
/*0160*/ char ui[128];
/*0288*/ float x;
/*0292*/ float y;
/*0296*/ float z;
/*0300*/ float heading;
/*0304*/ uint32 unknown304;
/*0308*/ char unknown308[160];
/*0468*/ char target_name[64];
/*0532*/ uint32 type;
/*0536*/ char unknown536[2052];
/*2584*/ char bug[2048];
/*4632*/ char unknown4632[6];
/*4638*/ char system_info[4094];
};
struct Make_Pet_Struct { //Simple struct for getting pet info
uint8 level;
uint8 class_;
@@ -3415,21 +3356,20 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
struct ApproveZone_Struct {
char name[64];
@@ -3488,8 +3428,8 @@ struct SelectTributeReply_Struct {
struct TributeInfo_Struct {
uint32 active; //0 == inactive, 1 == active
uint32 tributes[EQEmu::invtype::TRIBUTE_SIZE]; //-1 == NONE
uint32 tiers[EQEmu::invtype::TRIBUTE_SIZE]; //all 00's
uint32 tributes[EQEmu::legacy::TRIBUTE_SIZE]; //-1 == NONE
uint32 tiers[EQEmu::legacy::TRIBUTE_SIZE]; //all 00's
uint32 tribute_master_id;
};
@@ -3821,7 +3761,7 @@ struct AcceptNewTask_Struct {
//was all 0's from client, server replied with same op, all 0's
struct CancelTask_Struct {
uint32 SequenceNumber;
uint32 type; // Only seen 0x00000002
uint32 unknown4; // Only seen 0x00000002
};
#if 0
@@ -3875,28 +3815,28 @@ struct AvailableTaskTrailer_Struct {
struct TaskDescriptionHeader_Struct {
uint32 SequenceNumber; // The order the tasks appear in the journal. 0 for first task, 1 for second, etc.
uint32 TaskID;
uint8 open_window;
uint32 task_type;
uint32 reward_type; // if this != 4 says Ebon Crystals else Radiant Crystals
uint32 unknown2;
uint32 unknown3;
uint8 unknown4;
};
struct TaskDescriptionData1_Struct {
uint32 Duration;
uint32 dur_code; // if Duration == 0
uint32 unknown2;
uint32 StartTime;
};
struct TaskDescriptionData2_Struct {
uint8 has_rewards;
uint32 coin_reward;
uint32 xp_reward;
uint32 faction_reward;
uint32 RewardCount; // ??
uint32 unknown1;
uint32 unknown2;
uint16 unknown3;
//uint8 unknown4;
};
struct TaskDescriptionTrailer_Struct {
//uint16 unknown1; // 0x0012
uint32 Points;
uint8 has_reward_selection; // uses newer reward selection window, not in all clients
};
struct TaskActivityHeader_Struct {
@@ -3936,11 +3876,11 @@ struct TaskActivityShort_Struct {
struct TaskActivityComplete_Struct {
uint32 TaskIndex;
uint32 TaskType; // task, shared task, quest
uint32 TaskID; // must match
uint32 unknown2; // 0x00000002
uint32 unknown3;
uint32 ActivityID;
uint32 task_completed; // Broadcasts "Task '%1' Completed" it not 0 and "Task '%1' Failed." if 0
uint32 stage_complete; // Broadcasts "Task Stage Completed"
uint32 unknown4; // 0x00000001
uint32 unknown5; // 0x00000001
};
#if 0
@@ -4400,7 +4340,7 @@ struct AnnoyingZoneUnknown_Struct {
};
struct LoadSpellSet_Struct {
uint32 spell[EQEmu::spells::SPELL_GEM_COUNT]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 spell[MAX_PP_MEMSPELL]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 unknown; //there seems to be an extra field in this packet...
};
@@ -4817,7 +4757,6 @@ struct BuffIconEntry_Struct
uint32 spell_id;
int32 tics_remaining;
uint32 num_hits;
char caster[64];
};
struct BuffIcon_Struct
@@ -4827,7 +4766,6 @@ struct BuffIcon_Struct
uint16 count;
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
int32 tic_timer;
int32 name_lengths; // so ahh we kind of do these packets hacky, this is the total length of all the names to make creating the real packets in the translators easier
BuffIconEntry_Struct entries[0];
};
@@ -5341,7 +5279,7 @@ struct MercenaryMerchantResponse_Struct {
struct ServerLootItem_Struct {
uint32 item_id; // uint32 item_id;
int16 equip_slot; // int16 equip_slot;
uint16 charges; // uint8 charges;
uint16 charges; // uint8 charges;
uint16 lootslot; // uint16 lootslot;
uint32 aug_1; // uint32 aug_1;
uint32 aug_2; // uint32 aug_2;
@@ -5369,7 +5307,7 @@ struct ClientMarqueeMessage_Struct {
uint32 fade_out_time; //The fade out time, in ms
uint32 duration; //in ms
char msg[1]; //message plus null terminator
};
typedef std::list<ServerLootItem_Struct*> ItemList;
@@ -5388,41 +5326,6 @@ struct fling_struct {
/* 28 */
};
// used when action == 0
struct AuraCreate_Struct {
/* 00 */ uint32 action; // 0 = add, 1 = delete, 2 = reset
/* 04 */ uint32 type; // unsure -- normal auras show 1 clicky (ex. Circle of Power) show 0
/* 08 */ char aura_name[64];
/* 72 */ uint32 entity_id;
/* 76 */ uint32 icon;
/* 80 */
};
// used when action == 1
struct AuraDestory_Struct {
/* 00 */ uint32 action; // 0 = add, 1 = delete, 2 = reset
/* 04 */ uint32 entity_id;
/* 08 */
};
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char Augment6[5];
/*036*/ char IsEvolving[1];
/*037*/ char EvolveGroup[4];
/*041*/ char EvolveLevel[2];
/*043*/ char OrnamentIcon[5];
/*048*/ char Hash[8];
/*056*/
};
// Restore structure packing to default
#pragma pack()
+119 -119
View File
@@ -84,14 +84,14 @@ void EQStream::init(bool resetSession) {
OpMgr = nullptr;
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "init Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
}
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
{
EQRawApplicationPacket *ap=nullptr;
LogNetcode(_L "Creating new application packet, length [{}]" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size);
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
ap = p->MakeAppPacket();
return ap;
@@ -100,7 +100,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
{
EQRawApplicationPacket *ap=nullptr;
LogNetcode(_L "Creating new application packet, length [{}]" __L, len);
Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len);
ap = new EQRawApplicationPacket(buf, len);
return ap;
}
@@ -130,7 +130,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) {
LogNetcode(_L "Session not initialized, packet ignored" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L);
// _raw(NET__DEBUG, 0xFFFF, p);
return;
}
@@ -141,7 +141,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
while(processed < p->size) {
subpacket_length=*(p->pBuffer+processed);
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length);
LogNetcode(_L "Extracting combined packet of length [{}]" __L, subpacket_length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length);
// _raw(NET__NET_CREATE_HEX, 0xFFFF, subp);
subp->copyInfo(p);
ProcessPacket(subp);
@@ -156,12 +156,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
while(processed<p->size) {
EQRawApplicationPacket *ap=nullptr;
if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) {
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length);
processed+=subpacket_length+1;
} else {
subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1));
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length);
processed+=subpacket_length+3;
}
@@ -176,29 +176,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_Packet: {
if(!p->pBuffer || (p->Size() < 4))
{
LogNetcode(_L "Received OP_Packet that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L);
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
SeqOrder check=CompareSequence(NextInSeq,seq);
if (check == SeqFuture) {
LogNetcode(_L "Future OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p);
PacketQueue[seq]=p->Copy();
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
//SendOutOfOrderAck(seq);
} else if (check == SeqPast) {
LogNetcode(_L "Duplicate OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p);
SendOutOfOrderAck(seq); //we already got this packet but it was out of order
} else {
// In case we did queue one before as well.
EQProtocolPacket *qp=RemoveQueue(seq);
if (qp) {
LogNetcode("[NET_TRACE] OP_Packet: Removing older queued packet with sequence [{}]", seq);
Log.Out(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq);
delete qp;
}
@@ -207,7 +207,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
// Check for an embedded OP_AppCombinded (protocol level 0x19)
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2);
LogNetcode(_L "seq [{}], Extracting combined packet of length [{}]" __L, seq, subp->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size);
// _raw(NET__NET_CREATE_HEX, seq, subp);
subp->copyInfo(p);
ProcessPacket(subp);
@@ -226,29 +226,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_Fragment: {
if(!p->pBuffer || (p->Size() < 4))
{
LogNetcode(_L "Received OP_Fragment that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L);
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
SeqOrder check=CompareSequence(NextInSeq,seq);
if (check == SeqFuture) {
LogNetcode(_L "Future OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p);
PacketQueue[seq]=p->Copy();
LogNetcode(_L "OP_Fragment Queue size=[{}]" __L, PacketQueue.size());
Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size());
//SendOutOfOrderAck(seq);
} else if (check == SeqPast) {
LogNetcode(_L "Duplicate OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p);
SendOutOfOrderAck(seq);
} else {
// In case we did queue one before as well.
EQProtocolPacket *qp=RemoveQueue(seq);
if (qp) {
LogNetcode("[NET_TRACE] OP_Fragment: Removing older queued packet with sequence [{}]", seq);
Log.Out(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq);
delete qp;
}
SetNextAckToSend(seq);
@@ -256,18 +256,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
if (oversize_buffer) {
memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2);
oversize_offset+=p->size-2;
LogNetcode(_L "Fragment of oversized of length [{}], seq [{}]: now at [{}]/[{}]" __L, p->size-2, seq, oversize_offset, oversize_length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length);
if (oversize_offset==oversize_length) {
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset);
LogNetcode(_L "seq [{}], Extracting combined oversize packet of length [{}]" __L, seq, subp->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size);
//// _raw(NET__NET_CREATE_HEX, subp);
subp->copyInfo(p);
ProcessPacket(subp);
delete subp;
} else {
EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset);
LogNetcode(_L "seq [{}], completed combined oversize packet of length [{}]" __L, seq, ap->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size);
if (ap) {
ap->copyInfo(p);
InboundQueuePush(ap);
@@ -282,20 +282,20 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
oversize_buffer=new unsigned char[oversize_length];
memcpy(oversize_buffer,p->pBuffer+6,p->size-6);
oversize_offset=p->size-6;
LogNetcode(_L "First fragment of oversized of seq [{}]: now at [{}]/[{}]" __L, seq, oversize_offset, oversize_length);
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length);
}
}
}
break;
case OP_KeepAlive: {
NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size));
LogNetcode(_L "Received and queued reply to keep alive" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L);
}
break;
case OP_Ack: {
if(!p->pBuffer || (p->Size() < 4))
{
LogNetcode(_L "Received OP_Ack that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L);
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
@@ -309,11 +309,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_SessionRequest: {
if(p->Size() < sizeof(SessionRequest))
{
LogNetcode(_L "Received OP_SessionRequest that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L);
break;
}
if (GetState()==ESTABLISHED) {
LogNetcode(_L "Received OP_SessionRequest in ESTABLISHED state ([{}]) streamactive ([{}]) attempt ([{}])" __L, GetState(),streamactive,sessionAttempts);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts);
// client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case
// streamactive means we identified the opcode for the stream, we cannot re-establish this connection
@@ -331,7 +331,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
SessionRequest *Request=(SessionRequest *)p->pBuffer;
Session=ntohl(Request->Session);
SetMaxLen(ntohl(Request->MaxLength));
LogNetcode(_L "Received OP_SessionRequest: session [{}], maxlen [{}]" __L, (unsigned long)Session, MaxLen);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen);
SetState(ESTABLISHED);
Key=0x11223344;
SendSessionResponse();
@@ -340,7 +340,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_SessionResponse: {
if(p->Size() < sizeof(SessionResponse))
{
LogNetcode(_L "Received OP_SessionResponse that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L);
break;
}
@@ -356,7 +356,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
compressed=(Response->Format&FLAG_COMPRESSED);
encoded=(Response->Format&FLAG_ENCODED);
LogNetcode(_L "Received OP_SessionResponse: session [{}], maxlen [{}], key [{}], compressed? [{}], encoded? [{}]" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
// Kinda kludgy, but trie for now
if (StreamType==UnknownStream) {
@@ -379,17 +379,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
EQStreamState state = GetState();
if(state == ESTABLISHED) {
//client initiated disconnect?
LogNetcode(_L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L);
_SendDisconnect();
SetState(CLOSED);
} else if(state == CLOSING) {
//we were waiting for this anyways, ignore pending messages, send the reply and be closed.
LogNetcode(_L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L);
_SendDisconnect();
SetState(CLOSED);
} else {
//we are expecting this (or have already gotten it, but dont care either way)
LogNetcode(_L "Received expected OP_SessionDisconnect. Moving to closed state" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L);
SetState(CLOSED);
}
}
@@ -397,24 +397,24 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_OutOfOrderAck: {
if(!p->pBuffer || (p->Size() < 4))
{
LogNetcode(_L "Received OP_OutOfOrderAck that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L);
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
MOutboundQueue.lock();
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L,
seq, SequencedBase, SequencedBase+SequencedQueue.size());
uint16 sqsize = SequencedQueue.size();
uint16 index = seq - SequencedBase;
LogNetcode(_L "OP_OutOfOrderAck marking packet acked in queue (queue index = [{}], queue size = [{}])" __L, index, sqsize);
Log.Out(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize);
if (index < sqsize) {
SequencedQueue[index]->acked = true;
// flag packets for a resend
@@ -423,7 +423,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) {
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) {
(*sitr)->sent_time = 0;
LogNetcode(_L "OP_OutOfOrderAck Flagging packet [{}] for retransmission" __L, SequencedBase + count);
Log.Out(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck Flagging packet %d for retransmission" __L, SequencedBase + count);
}
}
}
@@ -432,11 +432,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
retransmittimer = Timer::GetCurrentTime();
}
} else {
LogNetcode(_L "Received OP_OutOfOrderAck for out-of-window [{}]. Window ([{}]->[{}])" __L, seq, SequencedBase, NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq);
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "Post-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
MOutboundQueue.unlock();
@@ -445,11 +445,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_SessionStatRequest: {
if(p->Size() < sizeof(ClientSessionStats))
{
LogNetcode(_L "Received OP_SessionStatRequest that was of malformed size" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
break;
}
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
Log(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L,
(unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta),
(unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta),
(unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta));
@@ -468,7 +468,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
retransmittimeout += 300;
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
LogNetcode(_L "Retransmit timeout recalculated to [{}]ms" __L, retransmittimeout);
Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
}
}
@@ -485,11 +485,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_SessionStatResponse: {
LogNetcode(_L "Received OP_SessionStatResponse. Ignoring" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L);
}
break;
case OP_OutOfSession: {
LogNetcode(_L "Received OP_OutOfSession. Ignoring" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L);
}
break;
default:
@@ -520,7 +520,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
return;
if(OpMgr == nullptr || *OpMgr == nullptr) {
LogNetcode(_L "Packet enqueued into a stream with no opcode manager, dropping" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L);
delete pack;
return;
}
@@ -529,7 +529,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
if(pack->GetOpcodeBypass() != 0) {
opcode = pack->GetOpcodeBypass();
} else {
opcode = (*OpMgr)->EmuToEQ(pack->GetOpcode());
opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
}
if (!ack_req) {
@@ -545,32 +545,32 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
uint32 chunksize, used;
uint32 length;
if (LogSys.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){
if (Log.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){
if (p->GetOpcode() != OP_SpecialMesg){
Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
Log.Out(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
}
}
if (LogSys.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){
if (Log.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){
if (p->GetOpcode() != OP_SpecialMesg){
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
Log.Out(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
}
}
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
LogNetcode(_L "Making oversized packet, len [{}]" __L, p->Size());
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
auto tmpbuff = new unsigned char[p->size + 3];
length=p->serialize(opcode, tmpbuff);
if (length != p->Size())
LogNetcode(_L "Packet adjustment, len [{}] to [{}]" __L, p->Size(), length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4);
*(uint32 *)(out->pBuffer+2)=htonl(length);
used=MaxLen-10;
memcpy(out->pBuffer+6,tmpbuff,used);
LogNetcode(_L "First fragment: used [{}]/[{}]. Payload size [{}] in the packet" __L, used, length, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
SequencedPush(out);
@@ -581,7 +581,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
out->size=chunksize+2;
SequencedPush(out);
used+=chunksize;
LogNetcode(_L "Subsequent fragment: len [{}], used [{}]/[{}]" __L, chunksize, used, length);
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
}
delete p;
delete[] tmpbuff;
@@ -602,18 +602,18 @@ void EQStream::SequencedPush(EQProtocolPacket *p)
{
MOutboundQueue.lock();
if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L,
SequencedBase, SequencedQueue.size(), NextOutSeq);
}
Log(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L,
NextOutSeq, p->size, SequencedBase);
*(uint16 *)(p->pBuffer) = htons(NextOutSeq);
SequencedQueue.push_back(p);
NextOutSeq++;
if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L,
SequencedBase, SequencedQueue.size(), NextOutSeq);
}
@@ -623,7 +623,7 @@ void EQStream::SequencedPush(EQProtocolPacket *p)
void EQStream::NonSequencedPush(EQProtocolPacket *p)
{
MOutboundQueue.lock();
LogNetcode(_L "Pushing non-sequenced packet of length [{}]" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size);
NonSequencedQueue.push(p);
MOutboundQueue.unlock();
}
@@ -631,14 +631,14 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
void EQStream::SendAck(uint16 seq)
{
uint16 Seq=htons(seq);
LogNetcode(_L "Sending ack with sequence [{}]" __L, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq);
SetLastAckSent(seq);
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
}
void EQStream::SendOutOfOrderAck(uint16 seq)
{
LogNetcode(_L "Sending out of order ack with sequence [{}]" __L, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq);
uint16 Seq=htons(seq);
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
}
@@ -688,24 +688,24 @@ void EQStream::Write(int eq_fd)
// If we don't have a packet to try to combine into, use this one as the base
// And remove it form the queue
p = NonSequencedQueue.front();
LogNetcode(_L "Starting combined packet with non-seq packet of len [{}]" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size);
NonSequencedQueue.pop();
} else if (!p->combine(NonSequencedQueue.front())) {
// Trying to combine this packet with the base didn't work (too big maybe)
// So just send the base packet (we'll try this packet again later)
LogNetcode(_L "Combined packet full at len [{}], next non-seq packet is len [{}]" __L, p->size, (NonSequencedQueue.front())->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size);
ReadyToSend.push(p);
BytesWritten+=p->size;
p=nullptr;
if (BytesWritten > threshold) {
// Sent enough this round, lets stop to be fair
LogNetcode(_L "Exceeded write threshold in nonseq ([{}] > [{}])" __L, BytesWritten, threshold);
Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold);
break;
}
} else {
// Combine worked, so just remove this packet and it's spot in the queue
LogNetcode(_L "Combined non-seq packet of len [{}], yeilding [{}] combined" __L, (NonSequencedQueue.front())->size, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size);
delete NonSequencedQueue.front();
NonSequencedQueue.pop();
}
@@ -718,7 +718,7 @@ void EQStream::Write(int eq_fd)
uint16 seq_send = SequencedBase + count; //just for logging...
if(SequencedQueue.empty()) {
LogNetcode(_L "Tried to write a packet with an empty queue ([{}] is past next out [{}])" __L, seq_send, NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq);
SeqEmpty=true;
continue;
}
@@ -728,35 +728,35 @@ void EQStream::Write(int eq_fd)
++sitr;
++count;
if (p) {
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
ReadyToSend.push(p);
BytesWritten += p->size;
p = nullptr;
}
LogNetcode(_L "Not retransmitting seq packet [{}] because already marked as acked" __L, seq_send);
Log.Out(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send);
} else if (!p) {
// If we don't have a packet to try to combine into, use this one as the base
// Copy it first as it will still live until it is acked
p=(*sitr)->Copy();
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
(*sitr)->sent_time = Timer::GetCurrentTime();
++sitr;
++count;
} else if (!p->combine(*sitr)) {
// Trying to combine this packet with the base didn't work (too big maybe)
// So just send the base packet (we'll try this packet again later)
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send + 1, (*sitr)->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send + 1, (*sitr)->size);
ReadyToSend.push(p);
BytesWritten+=p->size;
p=nullptr;
if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) {
// Sent enough this round, lets stop to be fair
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
break;
}
} else {
// Combine worked
LogNetcode(_L "Combined seq packet [{}] of len [{}], yeilding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size);
(*sitr)->sent_time = Timer::GetCurrentTime();
++sitr;
++count;
@@ -766,7 +766,7 @@ void EQStream::Write(int eq_fd)
++sitr;
++count;
if (p) {
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
ReadyToSend.push(p);
BytesWritten += p->size;
p = nullptr;
@@ -776,25 +776,25 @@ void EQStream::Write(int eq_fd)
// Copy it first as it will still live until it is acked
p=(*sitr)->Copy();
(*sitr)->sent_time = Timer::GetCurrentTime();
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
++sitr;
++count;
} else if (!p->combine(*sitr)) {
// Trying to combine this packet with the base didn't work (too big maybe)
// So just send the base packet (we'll try this packet again later)
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send, (*sitr)->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size);
ReadyToSend.push(p);
BytesWritten+=p->size;
p=nullptr;
if (BytesWritten > threshold) {
// Sent enough this round, lets stop to be fair
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
break;
}
} else {
// Combine worked
LogNetcode(_L "Combined seq packet [{}] of len [{}], yielding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yielding %d combined." __L, seq_send, (*sitr)->size, p->size);
(*sitr)->sent_time = Timer::GetCurrentTime();
++sitr;
++count;
@@ -802,7 +802,7 @@ void EQStream::Write(int eq_fd)
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "Post send Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
} else {
// No more sequenced packets
@@ -814,7 +814,7 @@ void EQStream::Write(int eq_fd)
// We have a packet still, must have run out of both seq and non-seq, so send it
if (p) {
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
ReadyToSend.push(p);
BytesWritten+=p->size;
}
@@ -831,7 +831,7 @@ void EQStream::Write(int eq_fd)
if(SeqEmpty && NonSeqEmpty) {
//no more data to send
if(CheckState(CLOSING)) {
LogNetcode(_L "All outgoing data flushed, closing stream" __L );
Log.Out(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L );
//we are waiting for the queues to empty, now we can do our disconnect.
//this packet will not actually go out until the next call to Write().
_SendDisconnect();
@@ -896,7 +896,7 @@ void EQStream::SendSessionResponse()
out->size=sizeof(SessionResponse);
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionResponse: session %lu, maxlen=%d, key=0x%x, compressed? %s, encoded? %s" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionResponse: session %lu, maxlen=%d, key=0x%x, compressed? %s, encoded? %s" __L,
(unsigned long)Session, MaxLen, Key, compressed?"yes":"no", encoded?"yes":"no");
NonSequencedPush(out);
@@ -910,7 +910,7 @@ void EQStream::SendSessionRequest()
Request->Session=htonl(time(nullptr));
Request->MaxLength=htonl(512);
LogNetcode(_L "Sending OP_SessionRequest: session [{}], maxlen=[{}]" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
NonSequencedPush(out);
}
@@ -924,7 +924,7 @@ void EQStream::_SendDisconnect()
*(uint32 *)out->pBuffer=htonl(Session);
NonSequencedPush(out);
LogNetcode(_L "Sending OP_SessionDisconnect: session [{}]" __L, (unsigned long)Session);
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session);
}
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
@@ -950,7 +950,7 @@ EQRawApplicationPacket *p=nullptr;
if (OpMgr != nullptr && *OpMgr != nullptr) {
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
if (emu_op == OP_Unknown) {
// Log(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str());
// Log.Out(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str());
}
p->SetOpcode(emu_op);
}
@@ -976,7 +976,7 @@ EQRawApplicationPacket *p=nullptr;
if(OpMgr != nullptr && *OpMgr != nullptr) {
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
if(emu_op == OP_Unknown) {
LogNetcode("Unable to convert EQ opcode {:#04x} to an Application opcode", p->opcode);
Log.Out(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode);
}
p->SetOpcode(emu_op);
@@ -1004,7 +1004,7 @@ void EQStream::InboundQueueClear()
{
EQApplicationPacket *p=nullptr;
LogNetcode(_L "Clearing inbound queue" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L);
MInboundQueue.lock();
if (!InboundQueue.empty()) {
@@ -1047,7 +1047,7 @@ void EQStream::OutboundQueueClear()
{
EQProtocolPacket *p=nullptr;
LogNetcode(_L "Clearing outbound queue" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L);
MOutboundQueue.lock();
while(!NonSequencedQueue.empty()) {
@@ -1069,7 +1069,7 @@ void EQStream::PacketQueueClear()
{
EQProtocolPacket *p=nullptr;
LogNetcode(_L "Clearing future packet queue" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L);
if(!PacketQueue.empty()) {
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
@@ -1101,7 +1101,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
delete p;
ProcessQueue();
} else {
LogNetcode(_L "Incoming packet failed checksum" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L);
}
}
@@ -1132,23 +1132,23 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
SeqOrder ord = CompareSequence(SequencedBase, seq);
if(ord == SeqInOrder) {
//they are not acking anything new...
LogNetcode(_L "Received an ack with no window advancement (seq [{}])" __L, seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq);
} else if(ord == SeqPast) {
//they are nacking blocks going back before our buffer, wtf?
LogNetcode(_L "Received an ack with backward window advancement (they gave [{}], our window starts at [{}]). This is bad" __L, seq, SequencedBase);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase);
} else {
LogNetcode(_L "Received an ack up through sequence [{}]. Our base is [{}]" __L, seq, SequencedBase);
Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase);
//this is a good ack, we get to ack some blocks.
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
while(SequencedBase != seq) {
if(SequencedQueue.empty()) {
LogNetcode(_L "OUT OF PACKETS acked packet with sequence [{}]. Next send is [{}] before this" __L, (unsigned long)SequencedBase, SequencedQueue.size());
Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, SequencedQueue.size());
SequencedBase = NextOutSeq;
break;
}
LogNetcode(_L "Removing acked packet with sequence [{}]" __L, (unsigned long)SequencedBase);
Log.Out(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu." __L, (unsigned long)SequencedBase);
//clean out the acked packet
delete SequencedQueue.front();
SequencedQueue.pop_front();
@@ -1156,7 +1156,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
SequencedBase++;
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "Post-Ack on [{}] Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
}
@@ -1166,7 +1166,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
void EQStream::SetNextAckToSend(uint32 seq)
{
MAcks.lock();
LogNetcode(_L "Set Next Ack To Send to [{}]" __L, (unsigned long)seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq);
NextAckToSend=seq;
MAcks.unlock();
}
@@ -1174,7 +1174,7 @@ void EQStream::SetNextAckToSend(uint32 seq)
void EQStream::SetLastAckSent(uint32 seq)
{
MAcks.lock();
LogNetcode(_L "Set Last Ack Sent to [{}]" __L, (unsigned long)seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq);
LastAckSent=seq;
MAcks.unlock();
}
@@ -1187,10 +1187,10 @@ void EQStream::ProcessQueue()
EQProtocolPacket *qp=nullptr;
while((qp=RemoveQueue(NextInSeq))!=nullptr) {
LogNetcode(_L "Processing Queued Packet: Seq=[{}]" __L, NextInSeq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq);
ProcessPacket(qp);
delete qp;
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
}
}
@@ -1201,21 +1201,21 @@ EQProtocolPacket *qp=nullptr;
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
qp=itr->second;
PacketQueue.erase(itr);
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
}
return qp;
}
void EQStream::SetStreamType(EQStreamType type)
{
LogNetcode(_L "Changing stream type from [{}] to [{}]" __L, StreamTypeString(StreamType), StreamTypeString(type));
Log.Out(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type));
StreamType=type;
switch (StreamType) {
case LoginStream:
app_opcode_size=1;
compressed=false;
encoded=false;
LogNetcode(_L "Login stream has app opcode size [{}], is not compressed or encoded" __L, app_opcode_size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size);
break;
case ChatOrMailStream:
case ChatStream:
@@ -1223,7 +1223,7 @@ void EQStream::SetStreamType(EQStreamType type)
app_opcode_size=1;
compressed=false;
encoded=true;
LogNetcode(_L "Chat/Mail stream has app opcode size [{}], is not compressed, and is encoded" __L, app_opcode_size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size);
break;
case ZoneStream:
case WorldStream:
@@ -1231,7 +1231,7 @@ void EQStream::SetStreamType(EQStreamType type)
app_opcode_size=2;
compressed=true;
encoded=false;
LogNetcode(_L "World/Zone stream has app opcode size [{}], is compressed, and is not encoded" __L, app_opcode_size);
Log.Out(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size);
break;
}
}
@@ -1281,7 +1281,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
void EQStream::SetState(EQStreamState state) {
MState.lock();
LogNetcode(_L "Changing state from [{}] to [{}]" __L, State, state);
Log.Out(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state);
State=state;
MState.unlock();
}
@@ -1293,29 +1293,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
EQStreamState orig_state = GetState();
if (orig_state == CLOSING && !outgoing_data) {
LogNetcode(_L "Out of data in closing state, disconnecting" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L);
_SendDisconnect();
SetState(DISCONNECTING);
} else if (LastPacket && (now-LastPacket) > timeout) {
switch(orig_state) {
case CLOSING:
//if we time out in the closing state, they are not acking us, just give up
LogNetcode(_L "Timeout expired in closing state. Moving to closed state" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L);
_SendDisconnect();
SetState(CLOSED);
break;
case DISCONNECTING:
//we timed out waiting for them to send us the disconnect reply, just give up.
LogNetcode(_L "Timeout expired in disconnecting state. Moving to closed state" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L);
SetState(CLOSED);
break;
case CLOSED:
LogNetcode(_L "Timeout expired in closed state??" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L);
break;
case ESTABLISHED:
//we timed out during normal operation. Try to be nice about it.
//we will almost certainly time out again waiting for the disconnect reply, but oh well.
LogNetcode(_L "Timeout expired in established state. Closing connection" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L);
_SendDisconnect();
SetState(DISCONNECTING);
break;
@@ -1342,7 +1342,7 @@ void EQStream::Decay()
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) {
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) {
(*sitr)->sent_time = 0;
LogNetcode(_L "Timeout exceeded for seq [{}]. Flagging packet for retransmission" __L, SequencedBase + count);
Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout exceeded for seq %d. Flagging packet for retransmission" __L, SequencedBase + count);
}
}
MOutboundQueue.unlock();
@@ -1359,11 +1359,11 @@ void EQStream::AdjustRates(uint32 average_delta)
DecayRate=DECAYBASE/average_delta;
if (BytesWritten > RateThreshold)
BytesWritten = RateThreshold + DecayRate;
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
RateThreshold, DecayRate, average_delta);
MRate.unlock();
} else {
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
average_delta, AVERAGE_DELTA_MAX);
AverageDelta = AVERAGE_DELTA_MAX;
}
@@ -1374,7 +1374,7 @@ void EQStream::AdjustRates(uint32 average_delta)
BytesWritten = 0;
RateThreshold=RATEBASE/average_delta;
DecayRate=DECAYBASE/average_delta;
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
Log.Out(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
RateThreshold, DecayRate, average_delta);
MRate.unlock();
}
@@ -1384,12 +1384,12 @@ void EQStream::AdjustRates(uint32 average_delta)
void EQStream::Close() {
if(HasOutgoingData()) {
//there is pending data, wait for it to go out.
LogNetcode(_L "Stream requested to Close(), but there is pending data, waiting for it" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
SetState(CLOSING);
} else {
//otherwise, we are done, we can drop immediately.
_SendDisconnect();
LogNetcode(_L "Stream closing immediate due to Close()" __L);
Log.Out(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L);
SetState(DISCONNECTING);
}
}
@@ -1417,19 +1417,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
} else if(p->opcode == sig->first_eq_opcode) {
//opcode matches, check length..
if(p->size == sig->first_length) {
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length matched [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
res = MatchSuccessful;
} else if(sig->first_length == 0) {
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length ([{}]) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
res = MatchSuccessful;
} else {
//opcode matched but length did not.
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x}, but length [{}] did not match expected [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
res = MatchFailed;
}
} else {
//first opcode did not match..
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode {:#04x} did not match expected {:#04x}", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
res = MatchFailed;
}
}
+16 -4
View File
@@ -241,7 +241,7 @@ class EQStream : public EQStreamInterface {
virtual bool CheckState(EQStreamState state) { return GetState() == state; }
virtual std::string Describe() const { return("Direct EQStream"); }
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
void CheckTimeout(uint32 now, uint32 timeout=30);
bool HasOutgoingData();
@@ -250,13 +250,13 @@ class EQStream : public EQStreamInterface {
void Write(int eq_fd);
// whether or not the stream has been assigned (we passed our stream match)
virtual void SetActive(bool val) { streamactive = val; }
void SetActive(bool val) { streamactive = val; }
//
inline bool IsInUse() { bool flag; MInUse.lock(); flag=(active_users>0); MInUse.unlock(); return flag; }
inline void PutInUse() { MInUse.lock(); active_users++; MInUse.unlock(); }
virtual EQStreamState GetState() { EQStreamState s; MState.lock(); s=State; MState.unlock(); return s; }
inline EQStreamState GetState() { EQStreamState s; MState.lock(); s=State; MState.unlock(); return s; }
static SeqOrder CompareSequence(uint16 expected_seq , uint16 seq);
@@ -306,7 +306,19 @@ class EQStream : public EQStreamInterface {
const uint64 GetPacketsReceived() { return received_packet_count; }
//used for dynamic stream identification
virtual MatchState CheckSignature(const Signature *sig);
class Signature {
public:
//this object could get more complicated if needed...
uint16 ignore_eq_opcode; //0=dont ignore
uint16 first_eq_opcode;
uint32 first_length; //0=dont check length
};
typedef enum {
MatchNotReady,
MatchSuccessful,
MatchFailed
} MatchState;
MatchState CheckSignature(const Signature *sig);
};
+17 -1
View File
@@ -23,10 +23,18 @@
ThreadReturnType EQStreamFactoryReaderLoop(void *eqfs)
{
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryReaderLoop with thread ID %d", pthread_self());
#endif
fs->ReaderLoop();
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Ending EQStreamFactoryReaderLoop with thread ID %d", pthread_self());
#endif
THREAD_RETURN(nullptr);
}
@@ -34,8 +42,16 @@ ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
{
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
#endif
fs->WriterLoop();
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Ending EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
#endif
THREAD_RETURN(nullptr);
}
+21 -21
View File
@@ -4,7 +4,7 @@
#include "eqemu_logsys.h"
#include "eq_stream_ident.h"
#include "eq_stream_proxy.h"
#include "misc.h"
EQStreamIdentifier::~EQStreamIdentifier() {
while(!m_identified.empty()) {
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
}
}
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
void EQStreamIdentifier::RegisterPatch(const EQStream::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
auto p = new Patch;
p->signature = sig;
p->name = name;
@@ -46,9 +46,9 @@ void EQStreamIdentifier::Process() {
//first see if this stream has expired
if(r.expire.Check(false)) {
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before timeout", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
r.stream->Close();
//this stream has failed to match any pattern in our timeframe.
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
r.stream->ReleaseFromUse();
cur = m_streams.erase(cur);
continue;
}
@@ -62,23 +62,23 @@ void EQStreamIdentifier::Process() {
}
if(r.stream->GetState() != ESTABLISHED) {
//the stream closed before it was identified.
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before it closed", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
switch(r.stream->GetState())
{
case ESTABLISHED:
LogNetcode("[StreamIdentify] Stream state was Established");
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established");
break;
case CLOSING:
LogNetcode("[StreamIdentify] Stream state was Closing");
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing");
break;
case DISCONNECTING:
LogNetcode("[StreamIdentify] Stream state was Disconnecting");
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting");
break;
case CLOSED:
LogNetcode("[StreamIdentify] Stream state was Closed");
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed");
break;
default:
LogNetcode("[StreamIdentify] Stream state was Unestablished or unknown");
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown");
break;
}
r.stream->ReleaseFromUse();
@@ -98,17 +98,17 @@ void EQStreamIdentifier::Process() {
Patch *p = *curp;
//ask the stream to see if it matches the supplied signature
EQStreamInterface::MatchState res = r.stream->CheckSignature(&p->signature);
EQStream::MatchState res = r.stream->CheckSignature(&p->signature);
switch(res) {
case EQStreamInterface::MatchNotReady:
case EQStream::MatchNotReady:
//the stream has not received enough packets to compare with this signature
// Log.LogDebugType(Logs::General, Logs::Netcode, "[StreamIdentify] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
all_ready = false;
break;
case EQStreamInterface::MatchSuccessful: {
case EQStream::MatchSuccessful: {
//yay, a match.
LogNetcode("[StreamIdentify] Identified stream [{}:{}] with signature [{}]", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
// before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further
r.stream->SetActive(true);
@@ -120,9 +120,9 @@ void EQStreamIdentifier::Process() {
found_one = true;
break;
}
case EQStreamInterface::MatchFailed:
case EQStream::MatchFailed:
//do nothing...
LogNetcode("[StreamIdentify] [{}:{}] Tried patch [{}] and it did not match", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
break;
}
}
@@ -130,7 +130,7 @@ void EQStreamIdentifier::Process() {
//if we checked all patches and did not find a match.
if(all_ready && !found_one) {
//the stream cannot be identified.
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}], no match found", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
r.stream->ReleaseFromUse();
}
@@ -144,7 +144,7 @@ void EQStreamIdentifier::Process() {
} //end foreach stream
}
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStream> &eqs) {
m_streams.push_back(Record(eqs));
eqs = nullptr;
}
@@ -157,7 +157,7 @@ EQStreamInterface *EQStreamIdentifier::PopIdentified() {
return(res);
}
EQStreamIdentifier::Record::Record(std::shared_ptr<EQStreamInterface> s)
EQStreamIdentifier::Record::Record(std::shared_ptr<EQStream> s)
: stream(std::move(s)),
expire(STREAM_IDENT_WAIT_MS)
{
+7 -7
View File
@@ -1,13 +1,13 @@
#ifndef EQSTREAMIDENT_H_
#define EQSTREAMIDENT_H_
#include "eq_stream_intf.h"
#include "eq_stream.h"
#include "timer.h"
#include <vector>
#include <queue>
#include <memory>
#define STREAM_IDENT_WAIT_MS 30000
#define STREAM_IDENT_WAIT_MS 10000
class OpcodeManager;
class StructStrategy;
@@ -18,11 +18,11 @@ public:
~EQStreamIdentifier();
//registration interface.
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
void RegisterPatch(const EQStream::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
//main processing interface
void Process();
void AddStream(std::shared_ptr<EQStreamInterface> eqs);
void AddStream(std::shared_ptr<EQStream> &eqs);
EQStreamInterface *PopIdentified();
protected:
@@ -31,7 +31,7 @@ protected:
class Patch {
public:
std::string name;
EQStreamInterface::Signature signature;
EQStream::Signature signature;
OpcodeManager ** opcodes;
const StructStrategy *structs;
};
@@ -40,8 +40,8 @@ protected:
//pending streams..
class Record {
public:
Record(std::shared_ptr<EQStreamInterface> s);
std::shared_ptr<EQStreamInterface> stream; //we own this
Record(std::shared_ptr<EQStream> s);
std::shared_ptr<EQStream> stream; //we own this
Timer expire;
};
std::vector<Record> m_streams; //we own these objects, and the streams contained in them.
+5 -73
View File
@@ -5,8 +5,6 @@
#include <string>
#include "emu_versions.h"
#include "eq_packet.h"
#include "net/daybreak_connection.h"
typedef enum {
ESTABLISHED,
@@ -17,93 +15,27 @@ typedef enum {
} EQStreamState;
class EQApplicationPacket;
class OpcodeManager;
struct EQStreamManagerInterfaceOptions
{
EQStreamManagerInterfaceOptions() {
opcode_size = 2;
}
EQStreamManagerInterfaceOptions(int port, bool encoded, bool compressed) {
opcode_size = 2;
//World seems to support both compression and xor zone supports one or the others.
//Enforce one or the other in the convienence construct
//Login I had trouble getting to recognize compression at all
//but that might be because it was still a bit buggy when i was testing that.
if (compressed) {
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
}
else if (encoded) {
daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
}
daybreak_options.port = port;
}
int opcode_size;
bool track_opcode_stats;
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
};
class EQStreamManagerInterface
{
public:
EQStreamManagerInterface(const EQStreamManagerInterfaceOptions &options) { m_options = options; }
virtual ~EQStreamManagerInterface() { };
EQStreamManagerInterfaceOptions GetOptions() { return m_options; }
const EQStreamManagerInterfaceOptions& GetOptions() const { return m_options; }
virtual void SetOptions(const EQStreamManagerInterfaceOptions& options) = 0;
protected:
EQStreamManagerInterfaceOptions m_options;
};
class EQStreamInterface {
public:
virtual ~EQStreamInterface() {}
class Signature {
public:
//this object could get more complicated if needed...
uint16 ignore_eq_opcode; //0=dont ignore
uint16 first_eq_opcode;
uint32 first_length; //0=dont check length
};
typedef enum {
MatchNotReady,
MatchSuccessful,
MatchFailed
} MatchState;
struct Stats
{
EQ::Net::DaybreakConnectionStats DaybreakStats;
int RecvCount[_maxEmuOpcode];
int SentCount[_maxEmuOpcode];
};
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req=true) = 0;
virtual void FastQueuePacket(EQApplicationPacket **p, bool ack_req=true) = 0;
virtual EQApplicationPacket *PopPacket() = 0;
virtual void Close() = 0;
virtual void ReleaseFromUse() = 0;
virtual void RemoveData() = 0;
virtual std::string GetRemoteAddr() const = 0;
virtual uint32 GetRemoteIP() const = 0;
virtual uint16 GetRemotePort() const = 0;
virtual bool CheckState(EQStreamState state) = 0;
virtual std::string Describe() const = 0;
virtual void SetActive(bool val) { }
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
virtual EQStreamState GetState() = 0;
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
virtual const uint32 GetBytesSent() const { return 0; }
virtual const uint32 GetBytesRecieved() const { return 0; }
virtual const uint32 GetBytesSentPerSecond() const { return 0; }
virtual const uint32 GetBytesRecvPerSecond() const { return 0; }
virtual const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; }
virtual Stats GetStats() const = 0;
virtual void ResetStats() = 0;
virtual EQStreamManagerInterface* GetManager() const = 0;
};
#endif /*EQSTREAMINTF_H_*/
+22 -37
View File
@@ -1,12 +1,11 @@
#include "global_define.h"
#include "eq_stream_proxy.h"
#include "eq_stream.h"
#include "struct_strategy.h"
#include "eqemu_logsys.h"
#include "opcodemgr.h"
EQStreamProxy::EQStreamProxy(std::shared_ptr<EQStreamInterface> &stream, const StructStrategy *structs, OpcodeManager **opcodes)
EQStreamProxy::EQStreamProxy(std::shared_ptr<EQStream> &stream, const StructStrategy *structs, OpcodeManager **opcodes)
: m_stream(stream),
m_structs(structs),
m_opcodes(opcodes)
@@ -27,25 +26,10 @@ const EQEmu::versions::ClientVersion EQStreamProxy::ClientVersion() const
return m_structs->ClientVersion();
}
EQStreamState EQStreamProxy::GetState()
{
return m_stream->GetState();
}
void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
{
return m_stream->SetOpcodeManager(opm);
}
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
if(p == nullptr)
return;
if (p->GetOpcode() != OP_SpecialMesg) {
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
}
EQApplicationPacket *newp = p->Copy();
FastQueuePacket(&newp, ack_req);
}
@@ -70,10 +54,6 @@ void EQStreamProxy::Close() {
m_stream->Close();
}
std::string EQStreamProxy::GetRemoteAddr() const {
return(m_stream->GetRemoteAddr());
}
uint32 EQStreamProxy::GetRemoteIP() const {
return(m_stream->GetRemoteIP());
}
@@ -82,6 +62,26 @@ uint16 EQStreamProxy::GetRemotePort() const {
return(m_stream->GetRemotePort());
}
const uint32 EQStreamProxy::GetBytesSent() const
{
return(m_stream->GetBytesSent());
}
const uint32 EQStreamProxy::GetBytesRecieved() const
{
return(m_stream->GetBytesRecieved());
}
const uint32 EQStreamProxy::GetBytesSentPerSecond() const
{
return(m_stream->GetBytesSentPerSecond());
}
const uint32 EQStreamProxy::GetBytesRecvPerSecond() const
{
return(m_stream->GetBytesRecvPerSecond());
}
void EQStreamProxy::ReleaseFromUse() {
m_stream->ReleaseFromUse();
}
@@ -90,21 +90,6 @@ void EQStreamProxy::RemoveData() {
m_stream->RemoveData();
}
EQStreamInterface::Stats EQStreamProxy::GetStats() const
{
return m_stream->GetStats();
}
void EQStreamProxy::ResetStats()
{
m_stream->ResetStats();
}
EQStreamManagerInterface *EQStreamProxy::GetManager() const
{
return m_stream->GetManager();
}
bool EQStreamProxy::CheckState(EQStreamState state) {
if(m_stream)
return(m_stream->CheckState(state));
+9 -9
View File
@@ -4,6 +4,7 @@
#include "types.h"
#include "eq_stream_intf.h"
#include "eq_stream.h"
#include <memory>
class StructStrategy;
@@ -13,7 +14,7 @@ class EQApplicationPacket;
class EQStreamProxy : public EQStreamInterface {
public:
//takes ownership of the stream.
EQStreamProxy(std::shared_ptr<EQStreamInterface> &stream, const StructStrategy *structs, OpcodeManager **opcodes);
EQStreamProxy(std::shared_ptr<EQStream> &stream, const StructStrategy *structs, OpcodeManager **opcodes);
virtual ~EQStreamProxy();
//EQStreamInterface:
@@ -21,7 +22,6 @@ public:
virtual void FastQueuePacket(EQApplicationPacket **p, bool ack_req=true);
virtual EQApplicationPacket *PopPacket();
virtual void Close();
virtual std::string GetRemoteAddr() const;
virtual uint32 GetRemoteIP() const;
virtual uint16 GetRemotePort() const;
virtual void ReleaseFromUse();
@@ -29,15 +29,15 @@ public:
virtual bool CheckState(EQStreamState state);
virtual std::string Describe() const;
virtual const EQEmu::versions::ClientVersion ClientVersion() const;
virtual EQStreamState GetState();
virtual void SetOpcodeManager(OpcodeManager **opm);
virtual Stats GetStats() const;
virtual void ResetStats();
virtual EQStreamManagerInterface* GetManager() const;
virtual const uint32 GetBytesSent() const;
virtual const uint32 GetBytesRecieved() const;
virtual const uint32 GetBytesSentPerSecond() const;
virtual const uint32 GetBytesRecvPerSecond() const;
protected:
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
const StructStrategy *const m_structs; //we do not own this object.
std::shared_ptr<EQStream> const m_stream; //we own this stream object.
const StructStrategy *const m_structs; //we do not own this object.
//this is a pointer to a pointer to make it less likely that a packet will
//reference an invalid opcode manager when they are being reloaded.
OpcodeManager **const m_opcodes; //we do not own this object.
+316 -143
View File
@@ -23,142 +23,330 @@
#include <iostream>
#include <sstream>
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
std::string EQEmuConfig::ConfigFile = "eqemu_config.xml";
EQEmuConfig *EQEmuConfig::_config = nullptr;
void EQEmuConfig::parse_config()
void EQEmuConfig::do_world(TiXmlElement *ele)
{
ShortName = _root["server"]["world"].get("shortname", "").asString();
LongName = _root["server"]["world"].get("longname", "").asString();
WorldAddress = _root["server"]["world"].get("address", "").asString();
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
SharedKey = _root["server"]["world"].get("key", "").asString();
LoginCount = 0;
if (_root["server"]["world"]["loginserver"].isObject()) {
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
LoginLegacy = false;
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
const char *text;
TiXmlElement * sub_ele;;
text = ParseTextBlock(ele, "shortname");
if (text) {
ShortName = text;
}
else {
char str[32];
loginlist.Clear();
text = ParseTextBlock(ele, "longname");
if (text) {
LongName = text;
}
text = ParseTextBlock(ele, "address", true);
if (text) {
WorldAddress = text;
}
text = ParseTextBlock(ele, "localaddress", true);
if (text) {
LocalAddress = text;
}
text = ParseTextBlock(ele, "maxclients", true);
if (text) {
MaxClients = atoi(text);
}
// Get the <key> element
text = ParseTextBlock(ele, "key", true);
if (text) {
SharedKey = text;
}
// Get the <loginserver> element
sub_ele = ele->FirstChildElement("loginserver");
if (sub_ele) {
text = ParseTextBlock(sub_ele, "host", true);
if (text) {
LoginHost = text;
}
text = ParseTextBlock(sub_ele, "port", true);
if (text) {
LoginPort = atoi(text);
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
LoginAccount = text;
}
text = ParseTextBlock(sub_ele, "password", true);
if (text) {
LoginPassword = text;
}
} else {
char str[32];
do {
sprintf(str, "loginserver%i", ++LoginCount);
if (!_root["server"]["world"][str].isObject()) {
break;
sub_ele = ele->FirstChildElement(str);
if (sub_ele) {
auto loginconfig = new LoginConfig;
text = ParseTextBlock(sub_ele, "host", true);
if (text) {
loginconfig->LoginHost = text;
}
text = ParseTextBlock(sub_ele, "port", true);
if (text) {
loginconfig->LoginPort = atoi(text);
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
loginconfig->LoginAccount = text;
}
text = ParseTextBlock(sub_ele, "password", true);
if (text) {
loginconfig->LoginPassword = text;
}
loginlist.Insert(loginconfig);
}
auto loginconfig = new LoginConfig;
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
loginconfig->LoginLegacy = false;
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
loginlist.Insert(loginconfig);
} while (LoginCount < 100);
} while (sub_ele);
}
//<locked> from xml converts to json as locked: "", so i default to "false".
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
TelnetEnabled = false;
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
WorldHTTPEnabled = false;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
WorldHTTPEnabled = true;
// Check for locked
sub_ele = ele->FirstChildElement("locked");
if (sub_ele != nullptr) {
Locked = true;
}
// Get the <tcp> element
sub_ele = ele->FirstChildElement("tcp");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("ip");
if (text) {
WorldIP = text;
}
text = sub_ele->Attribute("port");
if (text) {
WorldTCPPort = atoi(text);
}
text = sub_ele->Attribute("telnet");
if (text && !strcasecmp(text, "enabled")) {
TelnetEnabled = true;
}
}
// Get the <http> element
sub_ele = ele->FirstChildElement("http");
if (sub_ele != nullptr) {
// text = sub_ele->Attribute("ip");
// if (text)
// WorldIP=text;
text = sub_ele->Attribute("mimefile");
if (text) {
WorldHTTPMimeFile = text;
}
text = sub_ele->Attribute("port");
if (text) {
WorldHTTPPort = atoi(text);
}
text = sub_ele->Attribute("enabled");
if (text && !strcasecmp(text, "true")) {
WorldHTTPEnabled = true;
}
}
/**
* UCS
*/
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
/**
* Database
*/
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
/**
* QS
*/
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
/**
* Zones
*/
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
/**
* Files
*/
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
MailOpCodesFile = _root["server"]["files"].get("mail_opcodes", "mail_opcodes.conf").asString();
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
/**
* Directories
*/
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
/**
* Logs
*/
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
/**
* Launcher
*/
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
#ifdef WIN32
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
#else
ZoneExe = _root["server"]["launcher"].get("exe", "./zone").asString();
#endif
}
void EQEmuConfig::do_chatserver(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
ChatHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
ChatPort = atoi(text);
}
}
void EQEmuConfig::do_mailserver(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
MailHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
MailPort = atoi(text);
}
}
void EQEmuConfig::do_database(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
DatabaseHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
DatabasePort = atoi(text);
}
text = ParseTextBlock(ele, "username", true);
if (text) {
DatabaseUsername = text;
}
text = ParseTextBlock(ele, "password", true);
if (text) {
DatabasePassword = text;
}
text = ParseTextBlock(ele, "db", true);
if (text) {
DatabaseDB = text;
}
}
void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
QSDatabaseHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
QSDatabasePort = atoi(text);
}
text = ParseTextBlock(ele, "username", true);
if (text) {
QSDatabaseUsername = text;
}
text = ParseTextBlock(ele, "password", true);
if (text) {
QSDatabasePassword = text;
}
text = ParseTextBlock(ele, "db", true);
if (text) {
QSDatabaseDB = text;
}
}
void EQEmuConfig::do_zones(TiXmlElement *ele)
{
const char *text;
TiXmlElement *sub_ele;
// TiXmlNode *node,*sub_node;
text = ParseTextBlock(ele, "defaultstatus", true);
if (text) {
DefaultStatus = atoi(text);
}
// Get the <ports> element
sub_ele = ele->FirstChildElement("ports");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("low");
if (text) {
ZonePortLow = atoi(text);
};
text = sub_ele->Attribute("high");
if (text) {
ZonePortHigh = atoi(text);
}
}
}
void EQEmuConfig::do_files(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "spells", true);
if (text) {
SpellsFile = text;
}
text = ParseTextBlock(ele, "opcodes", true);
if (text) {
OpCodesFile = text;
}
text = ParseTextBlock(ele, "plugin.pl", true);
if (text) {
PluginPlFile = text;
}
}
void EQEmuConfig::do_directories(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "maps", true);
if (text) {
MapDir = text;
if ( MapDir.back() != '/' )
MapDir += '/';
}
text = ParseTextBlock(ele, "quests", true);
if (text) {
QuestDir = text;
if ( QuestDir.back() != '/' )
QuestDir += '/';
}
text = ParseTextBlock(ele, "plugins", true);
if (text) {
PluginDir = text;
if ( PluginDir.back() != '/' )
PluginDir += '/';
}
text = ParseTextBlock(ele, "lua_modules", true);
if (text) {
LuaModuleDir = text;
if ( LuaModuleDir.back() != '/' )
LuaModuleDir += '/';
}
text = ParseTextBlock(ele, "patches", true);
if (text) {
PatchDir = text;
if ( PatchDir.back() != '/' )
PatchDir += '/';
}
text = ParseTextBlock(ele, "shared_memory", true);
if (text) {
SharedMemDir = text;
if ( SharedMemDir.back() != '/' )
SharedMemDir += '/';
}
//Not Fully Implemented yet LogDir
text = ParseTextBlock(ele, "logs", true);
if (text) {
LogDir = text;
if ( LogDir.back() != '/' )
LogDir += '/';
}
}
void EQEmuConfig::do_launcher(TiXmlElement *ele)
{
const char *text;
TiXmlElement *sub_ele;
text = ParseTextBlock(ele, "logprefix", true);
if (text) {
LogPrefix = text;
}
text = ParseTextBlock(ele, "logsuffix", true);
if (text) {
LogSuffix = text;
}
// Get the <exe> element
text = ParseTextBlock(ele, "exe", true);
if (text) {
ZoneExe = text;
}
// Get the <timers> element
sub_ele = ele->FirstChildElement("timers");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("restart");
if (text) {
RestartWait = atoi(text);
}
text = sub_ele->Attribute("reterminate");
if (text) {
TerminateWait = atoi(text);
}
text = sub_ele->Attribute("initial");
if (text) {
InitialBootWait = atoi(text);
}
text = sub_ele->Attribute("interval");
if (text) {
ZoneBootInterval = atoi(text);
}
}
}
std::string EQEmuConfig::GetByName(const std::string &var_name) const
{
if (var_name == "ShortName") {
@@ -182,9 +370,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "LoginPort") {
return (itoa(LoginPort));
}
if (var_name == "LoginLegacy") {
return (itoa(LoginLegacy ? 1 : 0));
}
if (var_name == "Locked") {
return (Locked ? "true" : "false");
}
@@ -194,12 +379,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "WorldIP") {
return (WorldIP);
}
if (var_name == "TelnetTCPPort") {
return (itoa(TelnetTCPPort));
}
if (var_name == "TelnetIP") {
return (TelnetIP);
}
if (var_name == "TelnetEnabled") {
return (TelnetEnabled ? "true" : "false");
}
@@ -260,9 +439,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "OpCodesFile") {
return (OpCodesFile);
}
if (var_name == "MailOpCodesFile") {
return (MailOpCodesFile);
}
if (var_name == "PluginPlFile") {
return (PluginPlFile);
}
@@ -319,12 +495,9 @@ void EQEmuConfig::Dump() const
std::cout << "LoginAccount = " << LoginAccount << std::endl;
std::cout << "LoginPassword = " << LoginPassword << std::endl;
std::cout << "LoginPort = " << LoginPort << std::endl;
std::cout << "LoginLegacy = " << LoginLegacy << std::endl;
std::cout << "Locked = " << Locked << std::endl;
std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl;
std::cout << "WorldIP = " << WorldIP << std::endl;
std::cout << "TelnetTCPPort = " << TelnetTCPPort << std::endl;
std::cout << "TelnetIP = " << TelnetIP << std::endl;
std::cout << "TelnetEnabled = " << TelnetEnabled << std::endl;
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
@@ -345,7 +518,6 @@ void EQEmuConfig::Dump() const
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
std::cout << "SpellsFile = " << SpellsFile << std::endl;
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
std::cout << "MailOpcodesFile = " << MailOpCodesFile << std::endl;
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
std::cout << "MapDir = " << MapDir << std::endl;
std::cout << "QuestDir = " << QuestDir << std::endl;
@@ -356,6 +528,7 @@ void EQEmuConfig::Dump() const
std::cout << "LogDir = " << LogDir << std::endl;
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
}
+81 -32
View File
@@ -18,19 +18,17 @@
#ifndef __EQEmuConfig_H
#define __EQEmuConfig_H
#include "json/json.h"
#include "xml_parser.h"
#include "linked_list.h"
#include <fstream>
struct LoginConfig {
std::string LoginHost;
std::string LoginAccount;
std::string LoginPassword;
uint16 LoginPort;
bool LoginLegacy;
};
class EQEmuConfig
class EQEmuConfig : public XMLParser
{
public:
virtual std::string GetByName(const std::string &var_name) const;
@@ -44,14 +42,11 @@ class EQEmuConfig
std::string LoginAccount;
std::string LoginPassword;
uint16 LoginPort;
bool LoginLegacy;
uint32 LoginCount;
LinkedList<LoginConfig*> loginlist;
bool Locked;
uint16 WorldTCPPort;
std::string WorldIP;
uint16 TelnetTCPPort;
std::string TelnetIP;
bool TelnetEnabled;
int32 MaxClients;
bool WorldHTTPEnabled;
@@ -84,7 +79,6 @@ class EQEmuConfig
// From <files/>
std::string SpellsFile;
std::string OpCodesFile;
std::string MailOpCodesFile;
std::string PluginPlFile;
// From <directories/>
@@ -117,14 +111,85 @@ class EQEmuConfig
protected:
static EQEmuConfig *_config;
Json::Value _root;
static std::string ConfigFile;
void parse_config();
#define ELEMENT(name) \
void do_##name(TiXmlElement *ele);
#include "eqemu_config_elements.h"
EQEmuConfig()
{
{
// import the needed handler prototypes
#define ELEMENT(name) \
Handlers[#name]=(ElementHandler)&EQEmuConfig::do_##name;
#include "eqemu_config_elements.h"
// Set sane defaults
// Login server
LoginHost = "eqemulator.net";
LoginPort = 5998;
// World
Locked = false;
WorldTCPPort = 9000;
TelnetEnabled = false;
WorldHTTPEnabled = false;
WorldHTTPPort = 9080;
WorldHTTPMimeFile = "mime.types";
SharedKey = ""; //blank disables authentication
// Mail
ChatHost = "eqchat.eqemulator.net";
ChatPort = 7778;
// Mail
MailHost = "eqmail.eqemulator.net";
MailPort = 7779;
// Mysql
DatabaseHost = "localhost";
DatabasePort = 3306;
DatabaseUsername = "eq";
DatabasePassword = "eq";
DatabaseDB = "eq";
// QueryServ Database
QSDatabaseHost = "localhost";
QSDatabasePort = 3306;
QSDatabaseUsername = "eq";
QSDatabasePassword = "eq";
QSDatabaseDB = "eq";
// Files
SpellsFile = "spells_us.txt";
OpCodesFile = "opcodes.conf";
PluginPlFile = "plugin.pl";
// Dirs
MapDir = "Maps/";
QuestDir = "quests/";
PluginDir = "plugins/";
LuaModuleDir = "lua_modules/";
PatchDir = "./";
SharedMemDir = "shared/";
LogDir = "logs/";
// Launcher
LogPrefix = "logs/zone-";
LogSuffix = ".log";
RestartWait = 10000; //milliseconds
TerminateWait = 10000; //milliseconds
InitialBootWait = 20000; //milliseconds
ZoneBootInterval = 2000; //milliseconds
#ifdef WIN32
ZoneExe = "zone.exe";
#else
ZoneExe = "./zone";
#endif
// Zones
ZonePortLow = 7000;
ZonePortHigh = 7999;
DefaultStatus = 0;
// For where zones need to connect to.
WorldIP = "127.0.0.1";
// Dynamics to start
//DynamicCount=5;
MaxClients = -1;
LoginCount = 0;
}
virtual ~EQEmuConfig() {}
@@ -133,7 +198,9 @@ class EQEmuConfig
// Produce a const singleton
static const EQEmuConfig *get()
{
LoadConfig();
if (_config == nullptr) {
LoadConfig();
}
return (_config);
}
@@ -147,28 +214,10 @@ class EQEmuConfig
static bool LoadConfig()
{
if (_config != nullptr) {
return true;
delete _config;
}
_config = new EQEmuConfig;
return parseFile();
}
// Load config file and parse data
static bool parseFile() {
if (_config == nullptr) {
return LoadConfig();
}
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
try {
fconfig >> _config->_root;
_config->parse_config();
}
catch (std::exception &) {
return false;
}
return true;
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(), "server");
}
void Dump() const;
+138 -397
View File
@@ -1,25 +1,23 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "eqemu_logsys.h"
#include "rulesys.h"
#include "platform.h"
#include "string_util.h"
#include "database.h"
@@ -35,229 +33,124 @@
std::ofstream process_log;
#ifdef _WINDOWS
#include <direct.h>
#include <conio.h>
#include <iostream>
#include <dos.h>
#include <windows.h>
#include <process.h>
#include <direct.h>
#include <conio.h>
#include <iostream>
#include <dos.h>
#include <windows.h>
#include <process.h>
#else
#include <unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/stat.h>
#endif
/**
* Linux ANSI console color defines
*/
/* Linux ANSI console color defines */
#define LC_RESET "\033[0m"
#define LC_BLACK "\033[30m" /* Black */
#define LC_RED "\033[31m" /* Red */
#define LC_GREEN "\033[32m" /* Green */
#define LC_YELLOW "\033[33m" /* Yellow */
#define LC_BLUE "\033[34m" /* Blue */
#define LC_MAGENTA "\033[35m" /* Magenta */
#define LC_CYAN "\033[36m" /* Cyan */
#define LC_WHITE "\033[37m" /* White */
#define LC_BLACK "\033[30m" /* Black */
#define LC_RED "\033[31m" /* Red */
#define LC_GREEN "\033[32m" /* Green */
#define LC_YELLOW "\033[33m" /* Yellow */
#define LC_BLUE "\033[34m" /* Blue */
#define LC_MAGENTA "\033[35m" /* Magenta */
#define LC_CYAN "\033[36m" /* Cyan */
#define LC_WHITE "\033[37m" /* White */
namespace Console {
enum Color {
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
LightMagenta = 13,
Yellow = 14,
White = 15
Yellow = 14,
White = 15
};
}
/**
* EQEmuLogSys Constructor
*/
EQEmuLogSys::EQEmuLogSys()
{
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
on_log_gmsay_hook = [](uint16 log_type, const std::string&) {};
bool file_logs_enabled = false;
int log_platform = 0;
}
/**
* EQEmuLogSys Deconstructor
*/
EQEmuLogSys::~EQEmuLogSys() = default;
EQEmuLogSys::~EQEmuLogSys()
{
}
void EQEmuLogSys::LoadLogSettingsDefaults()
{
/**
* Get Executable platform currently running this code (Zone/World/etc)
*/
/* Get Executable platform currently running this code (Zone/World/etc) */
log_platform = GetExecutablePlatformInt();
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
log_settings[log_category_id].log_to_console = 0;
log_settings[log_category_id].log_to_file = 0;
log_settings[log_category_id].log_to_gmsay = 0;
log_settings[log_category_id].is_category_enabled = 0;
}
/* Zero out Array */
memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID);
file_logs_enabled = false;
/* Set Defaults */
log_settings[Logs::World_Server].log_to_console = Logs::General;
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
log_settings[Logs::QS_Server].log_to_console = Logs::General;
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
log_settings[Logs::Crash].log_to_console = Logs::General;
log_settings[Logs::MySQLError].log_to_console = Logs::General;
log_settings[Logs::Login_Server].log_to_console = Logs::General;
/**
* Set Defaults
*/
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
/**
* RFC 5424
*/
log_settings[Logs::Emergency].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Alert].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Critical].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Notice].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
/**
* Set Category enabled status on defaults
*/
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
const bool log_to_console = log_settings[log_category_id].log_to_console > 0;
const bool log_to_file = log_settings[log_category_id].log_to_file > 0;
const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0;
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
if (is_category_enabled) {
log_settings[log_category_id].is_category_enabled = 1;
}
}
/**
* Declare process file names for log writing=
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) {
/* Declare process file names for log writing
If there is no process_file_name declared, no log file will be written, simply
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld)
platform_file_name = "world";
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ)
platform_file_name = "query_server";
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
platform_file_name = "zone";
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) {
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS)
platform_file_name = "ucs";
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) {
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
platform_file_name = "login";
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) {
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch)
platform_file_name = "launcher";
}
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) {
platform_file_name = "hc";
}
}
/**
* @param log_category
* @return
*/
bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
{
return (
log_category == Logs::Emergency ||
log_category == Logs::Alert ||
log_category == Logs::Critical ||
log_category == Logs::Error ||
log_category == Logs::Warning ||
log_category == Logs::Notice ||
log_category == Logs::Info ||
log_category == Logs::Debug
);
std::string ret;
ret.push_back('[');
ret.append(Logs::LogCategoryName[log_category]);
ret.push_back(']');
ret.push_back(' ');
ret.append(in_message);
return ret;
}
/**
* @param log_category
* @param in_message
* @return
*/
std::string EQEmuLogSys::FormatOutMessageString(
uint16 log_category,
const std::string &in_message
)
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
{
std::string return_string;
if (IsRfc5424LogCategory(log_category)) {
return_string = "[" + GetPlatformName() + "] ";
}
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessGMSay(
uint16 debug_level,
uint16 log_category,
const std::string &message
)
{
/**
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
*/
if (log_category == Logs::LogCategory::Netcode) {
/* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */
if (log_category == Logs::LogCategory::Netcode)
return;
}
/**
* Check to see if the process that actually ran this is zone
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
/* Check to see if the process that actually ran this is zone */
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
on_log_gmsay_hook(log_category, message);
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessLogWrite(
uint16 debug_level,
uint16 log_category,
const std::string &message
)
void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message)
{
if (log_category == Logs::Crash) {
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
std::ofstream crash_log;
EQEmuLogSys::MakeDirectory("logs/crashes");
crash_log.open(
StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
crash_log.open(StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
crash_log << time_stamp << " " << message << "\n";
crash_log.close();
}
@@ -265,17 +158,11 @@ void EQEmuLogSys::ProcessLogWrite(
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
if (process_log) {
if (process_log)
process_log << time_stamp << " " << message << std::endl;
}
}
/**
* @param log_category
* @return
*/
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category)
{
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) {
switch (log_category) {
case Logs::Status:
case Logs::Normal:
@@ -298,19 +185,12 @@ uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category)
}
}
/**
* @param log_category
* @return
*/
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
{
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) {
switch (log_category) {
case Logs::Status:
case Logs::Normal:
return LC_YELLOW;
case Logs::MySQLError:
case Logs::Warning:
case Logs::Critical:
case Logs::Error:
return LC_RED;
case Logs::MySQLQuery:
@@ -328,114 +208,52 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
}
}
/**
* @param log_category
* @return
*/
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
{
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
switch (log_category) {
case Logs::Status:
case Logs::Normal:
return Chat::Yellow;
return 15; /* Yellow */
case Logs::MySQLError:
case Logs::Error:
return Chat::Red;
return 13; /* Red */
case Logs::MySQLQuery:
case Logs::Debug:
return Chat::Lime;
return 14; /* Light Green */
case Logs::Quests:
return Chat::Group;
return 258; /* Light Cyan */
case Logs::Commands:
case Logs::Mercenaries:
return Chat::Magenta;
return 5; /* Light Purple */
case Logs::Crash:
return Chat::Red;
return 13; /* Red */
default:
return Chat::Yellow;
return 15; /* Yellow */
}
}
/**
* @param debug_level
* @param log_category
* @param message
*/
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
{
#ifdef _WINDOWS
HANDLE console_handle;
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFOEX info = { 0 };
info.cbSize = sizeof(info);
info.dwFontSize.Y = 12; // leave X as zero
info.FontWeight = FW_NORMAL;
wcscpy(info.FaceName, L"Lucida Console");
SetCurrentConsoleFontEx(console_handle, NULL, &info);
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
std::cout << message << "\n";
SetConsoleTextAttribute(console_handle, Console::Color::White);
#else
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
on_log_console_hook(debug_level, log_category, message);
#ifdef _WINDOWS
HANDLE console_handle;
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFOEX info = { 0 };
info.cbSize = sizeof(info);
info.dwFontSize.Y = 12; // leave X as zero
info.FontWeight = FW_NORMAL;
wcscpy(info.FaceName, L"Lucida Console");
SetCurrentConsoleFontEx(console_handle, NULL, &info);
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
std::cout << message << "\n";
SetConsoleTextAttribute(console_handle, Console::Color::White);
#else
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif
}
/**
* @param str
* @return
*/
constexpr const char *str_end(const char *str)
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
{
return *str ? str_end(str + 1) : str;
}
/**
* @param str
* @return
*/
constexpr bool str_slant(const char *str)
{
return *str == '/' ? true : (*str ? str_slant(str + 1) : false);
}
/**
* @param str
* @return
*/
constexpr const char *r_slant(const char *str)
{
return *str == '/' ? (str + 1) : r_slant(str - 1);
}
/**
* @param str
* @return
*/
constexpr const char *base_file_name(const char *str)
{
return str_slant(str) ? r_slant(str_end(str)) : str;
}
/**
* Core logging function
*
* @param debug_level
* @param log_category
* @param message
* @param ...
*/
void EQEmuLogSys::Out(
Logs::DebugLevel debug_level,
uint16 log_category,
const char *file,
const char *func,
int line,
const char *message,
...
)
{
bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) {
log_to_console = false;
@@ -452,49 +270,30 @@ void EQEmuLogSys::Out(
}
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log) {
if (nothing_to_log)
return;
}
std::string prefix;
if (RuleB(Logging, PrintFileFunctionAndLine)) {
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
}
va_list args;
va_start(args, message);
std::string output_message = vStringFormat(message, args);
std::string output_message = vStringFormat(message.c_str(), args);
va_end(args);
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message);
if (log_to_console) {
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
}
if (log_to_gmsay) {
EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
}
if (log_to_file) {
EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
}
if (log_to_console) EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
if (log_to_gmsay) EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
if (log_to_file) EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
}
/**
* @param time_stamp
*/
void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
void EQEmuLogSys::SetCurrentTimeStamp(char* time_stamp)
{
time_t raw_time;
struct tm *time_info;
time_t raw_time;
struct tm * time_info;
time(&raw_time);
time_info = localtime(&raw_time);
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
}
/**
* @param directory_name
*/
void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
{
#ifdef _WINDOWS
@@ -503,10 +302,9 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
return;
_mkdir(directory_name.c_str());
#else
struct stat st{};
if (stat(directory_name.c_str(), &st) == 0) { // exists
struct stat st;
if (stat(directory_name.c_str(), &st) == 0) // exists
return;
}
mkdir(directory_name.c_str(), 0755);
#endif
}
@@ -518,86 +316,29 @@ void EQEmuLogSys::CloseFileLogs()
}
}
/**
* @param log_name
*/
void EQEmuLogSys::StartFileLogs(const std::string &log_name)
{
EQEmuLogSys::CloseFileLogs();
/**
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
*/
if (!file_logs_enabled) {
/* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one... */
if (file_logs_enabled == false)
return;
}
/**
* Zone
*/
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
if (!log_name.empty()) {
if (!log_name.empty())
platform_file_name = log_name;
}
if (platform_file_name.empty()) {
if (platform_file_name.empty())
return;
}
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
/**
* Make directory if not exists
*/
EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid());
EQEmuLogSys::MakeDirectory("logs/zone");
/**
* Open file pointer
*/
process_log.open(
StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
}
else {
/**
* All other processes
*/
if (platform_file_name.empty()) {
process_log.open(StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
} else {
if (platform_file_name.empty())
return;
}
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
/**
* Open file pointer
*/
process_log.open(
StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()),
std::ios_base::app | std::ios_base::out
);
}
}
/**
* Silence console logging
*/
void EQEmuLogSys::SilenceConsoleLogging()
{
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
log_settings[log_index].log_to_console = 0;
log_settings[log_index].is_category_enabled = 0;
}
}
/**
* Enables console logging
*/
void EQEmuLogSys::EnableConsoleLogging()
{
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
log_settings[log_index].log_to_console = Logs::General;
log_settings[log_index].is_category_enabled = 1;
EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid());
process_log.open(StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
}
}
+74 -249
View File
@@ -1,21 +1,19 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_LOGSYS_H
@@ -26,13 +24,6 @@
#include <stdio.h>
#include <functional>
#ifdef _WIN32
#ifdef utf16_to_utf8
#undef utf16_to_utf8
#endif
#endif
#include <fmt/format.h>
#include "types.h"
namespace Logs {
@@ -42,18 +33,18 @@ namespace Logs {
Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */
};
/**
* If you add to this, make sure you update LogCategoryName
*
* NOTE: Only add to the bottom of the enum because that is the type ID assignment
*/
/*
If you add to this, make sure you update LogCategoryName
NOTE: Only add to the bottom of the enum because that is the type ID assignment
*/
enum LogCategory {
None = 0,
AA,
AI,
Aggro,
Attack,
PacketClientServer,
Client_Server_Packet,
Combat,
Commands,
Crash,
@@ -67,58 +58,36 @@ namespace Logs {
Normal,
Object,
Pathing,
QSServer,
QS_Server,
Quests,
Rules,
Skills,
Spawns,
Spells,
Status,
TCPConnection,
TCP_Connection,
Tasks,
Tradeskills,
Trading,
Tribute,
UCSServer,
WebInterfaceServer,
WorldServer,
ZoneServer,
UCS_Server,
WebInterface_Server,
World_Server,
Zone_Server,
MySQLError,
MySQLQuery,
Mercenaries,
QuestDebug,
PacketServerClient,
PacketClientServerUnhandled,
PacketServerClientWithDump,
PacketClientServerWithDump,
Loginserver,
ClientLogin,
HeadlessClient,
HPUpdate,
FixZ,
Food,
Traps,
NPCRoamBox,
NPCScaling,
MobAppearance,
Info,
Warning,
Critical,
Emergency,
Alert,
Notice,
AIScanClose,
AIYellForHelp,
AICastBeneficialClose,
AoeCast,
EntityManagement,
Flee,
MaxCategoryID /* Don't Remove this */
Server_Client_Packet,
Client_Server_Packet_Unhandled,
Server_Client_Packet_With_Dump,
Client_Server_Packet_With_Dump,
Login_Server,
Client_Login,
MaxCategoryID /* Don't Remove this*/
};
/**
* If you add to this, make sure you update LogCategory
*/
/* If you add to this, make sure you update LogCategory */
static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
"",
"AA",
@@ -164,89 +133,41 @@ namespace Logs {
"Packet :: Server -> Client (Dump)",
"Packet :: Client -> Server (Dump)",
"Login Server",
"Client Login",
"Headless Client",
"HP Update",
"FixZ",
"Food",
"Traps",
"NPC Roam Box",
"NPC Scaling",
"Mob Appearance",
"Info",
"Warning",
"Critical",
"Emergency",
"Alert",
"Notice",
"AI Scan Close",
"AI Yell For Help",
"AI Cast Beneficial Close",
"AOE Cast",
"Entity Management",
"Flee",
"Client Login"
};
}
#include "eqemu_logsys_log_aliases.h"
class EQEmuLogSys {
public:
EQEmuLogSys();
~EQEmuLogSys();
/**
* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else.
* This should be handled on deconstructor but to be safe we use it anyways.
*/
void CloseFileLogs();
void LoadLogSettingsDefaults();
void CloseFileLogs(); /* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else. This should be handled on deconstructor but to be safe we use it anyways. */
void LoadLogSettingsDefaults(); /* Initializes log_settings and sets some defaults if DB is not present */
void MakeDirectory(const std::string &directory_name); /* Platform independent way of performing a MakeDirectory based on name */
/*
The one and only Logging function that uses a debug level as a parameter, as well as a log_category
log_category - defined in Logs::LogCategory::[]
log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id]
/**
* @param directory_name
*/
void MakeDirectory(const std::string &directory_name);
/**
* The one and only Logging function that uses a debug level as a parameter, as well as a log_category
* log_category - defined in Logs::LogCategory::[]
* log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id]
*
* Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present");
* - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
* be checked against to see if that piped output is set to actually process it for the category and debug level
Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present");
- This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
be checked against to see if that piped output is set to actually process it for the category and debug level
*/
void Out(
Logs::DebugLevel debug_level,
uint16 log_category,
const char *file,
const char *func,
int line,
const char *message,
...
);
void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...);
void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */
void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */
/**
* Used in file logs to prepend a timestamp entry for logs
* @param time_stamp
*/
void SetCurrentTimeStamp(char* time_stamp);
/*
LogSettings Struct
/**
* @param log_name
*/
void StartFileLogs(const std::string &log_name = "");
This struct is the master reference for all settings for each category, and for each output
/**
* LogSettings Struct
*
* This struct is the master reference for all settings for each category, and for each output
*
* log_to_file[category_id] = [1-3] - Sets debug level for category to output to file
* log_to_console[category_id] = [1-3] - Sets debug level for category to output to console
* log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay
*
log_to_file[category_id] = [1-3] - Sets debug level for category to output to file
log_to_console[category_id] = [1-3] - Sets debug level for category to output to console
log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay
*/
struct LogSettings {
uint8 log_to_file;
uint8 log_to_console;
@@ -254,130 +175,34 @@ public:
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
};
/**
* Internally used memory reference for all log settings per category
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
* Database loaded via Database::LoadLogSettings(log_settings)
/* Internally used memory reference for all log settings per category.
These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults.
Database loaded via Database::LoadLogSettings(log_settings)
*/
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
LogSettings log_settings[Logs::LogCategory::MaxCategoryID];
bool file_logs_enabled = false;
bool file_logs_enabled; /* Set when log settings are loaded to determine if keeping a file open is necessary */
/**
* Sets Executable platform (Zone/World/UCS) etc.
*/
int log_platform = 0;
int log_platform; /* Sets Executable platform (Zone/World/UCS) etc. */
/**
* File name used in writing logs
*/
std::string platform_file_name;
std::string platform_file_name; /* File name used in writing logs */
/**
* GMSay Client Message colors mapped by category
*
* @param log_category
* @return
*/
uint16 GetGMSayColorFromCategory(uint16 log_category);
uint16 GetGMSayColorFromCategory(uint16 log_category); /* GMSay Client Message colors mapped by category */
/**
* @param f
*/
void SetGMSayHandler(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
/**
* @param f
*/
void SetConsoleHandler(std::function<void(uint16 debug_level, uint16 log_type, const std::string&)> f) { on_log_console_hook = f; }
/**
* Silence console logging
*/
void SilenceConsoleLogging();
/**
* Turn on all console logging
*/
void EnableConsoleLogging();
void OnLogHookCallBackZone(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
private:
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook; /* Callback pointer to zone process for hooking logs to zone using GMSay */
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message); /* Formats log messages like '[Category] This is a log message' */
std::string GetLinuxConsoleColorFromCategory(uint16 log_category); /* Linux console color messages mapped by category */
/**
* Callback pointer to zone process for hooking logs to zone using GMSay
*/
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook;
std::function<void(uint16 debug_level, uint16 log_category, const std::string&)> on_log_console_hook;
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category); /* Windows console color messages mapped by category */
/**
* Formats log messages like '[Category] This is a log message'
*/
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
/**
* Linux console color messages mapped by category
*
* @param log_category
* @return
*/
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
/**
* Windows console color messages mapped by category
*/
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
/**
* @param debug_level
* @param log_category
* @param message
*/
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
/**
* @param debug_level
* @param log_category
* @param message
*/
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
/**
* @param debug_level
* @param log_category
* @param message
*/
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
/**
* @param log_category
* @return
*/
bool IsRfc5424LogCategory(uint16 log_category);
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessConsoleMessage called via Log.Out */
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessGMSay called via Log.Out */
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessLogWrite called via Log.Out */
};
extern EQEmuLogSys LogSys;
/**
template<typename... Args>
void OutF(
EQEmuLogSys &ls,
Logs::DebugLevel debug_level,
uint16 log_category,
const char *file,
const char *func,
int line,
const char *fmt,
const Args &... args
)
{
std::string log_str = fmt::format(fmt, args...);
ls.Out(debug_level, log_category, file, func, line, log_str.c_str());
}
**/
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
do { \
ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
} while(0)
extern EQEmuLogSys Log;
#endif
-888
View File
@@ -1,888 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
#ifdef BUILD_LOGGING
/**
* RFC 5424
*/
#define LogEmergency(message, ...) do {\
if (LogSys.log_settings[Logs::Emergency].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Emergency, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAlert(message, ...) do {\
if (LogSys.log_settings[Logs::Alert].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Alert, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCritical(message, ...) do {\
if (LogSys.log_settings[Logs::Critical].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Critical, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogError(message, ...) do {\
if (LogSys.log_settings[Logs::Error].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogWarning(message, ...) do {\
if (LogSys.log_settings[Logs::Warning].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNotice(message, ...) do {\
if (LogSys.log_settings[Logs::Notice].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Notice, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogInfo(message, ...) do {\
if (LogSys.log_settings[Logs::Info].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDebug(message, ...) do {\
if (LogSys.log_settings[Logs::Debug].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
/**
* Category
*/
#define LogAA(message, ...) do {\
if (LogSys.log_settings[Logs::AA].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAADetail(message, ...) do {\
if (LogSys.log_settings[Logs::AA].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAI(message, ...) do {\
if (LogSys.log_settings[Logs::AI].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIDetail(message, ...) do {\
if (LogSys.log_settings[Logs::AI].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAggro(message, ...) do {\
if (LogSys.log_settings[Logs::Aggro].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAggroDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Aggro].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAttack(message, ...) do {\
if (LogSys.log_settings[Logs::Attack].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAttackDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Attack].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogPacketClientServer(message, ...) do {\
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogPacketClientServerDetail(message, ...) do {\
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCombat(message, ...) do {\
if (LogSys.log_settings[Logs::Combat].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCombatDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Combat].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCommands(message, ...) do {\
if (LogSys.log_settings[Logs::Commands].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCommandsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Commands].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCrash(message, ...) do {\
if (LogSys.log_settings[Logs::Crash].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogCrashDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Crash].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDoors(message, ...) do {\
if (LogSys.log_settings[Logs::Doors].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDoorsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Doors].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogGuilds(message, ...) do {\
if (LogSys.log_settings[Logs::Guilds].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogGuildsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Guilds].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogInventory(message, ...) do {\
if (LogSys.log_settings[Logs::Inventory].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogInventoryDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Inventory].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogLauncher(message, ...) do {\
if (LogSys.log_settings[Logs::Launcher].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogLauncherDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Launcher].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNetcode(message, ...) do {\
if (LogSys.log_settings[Logs::Netcode].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNetcodeDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Netcode].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNormal(message, ...) do {\
if (LogSys.log_settings[Logs::Normal].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNormalDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Normal].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogObject(message, ...) do {\
if (LogSys.log_settings[Logs::Object].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogObjectDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Object].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogPathing(message, ...) do {\
if (LogSys.log_settings[Logs::Pathing].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogPathingDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Pathing].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQSServer(message, ...) do {\
if (LogSys.log_settings[Logs::QSServer].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQSServerDetail(message, ...) do {\
if (LogSys.log_settings[Logs::QSServer].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQuests(message, ...) do {\
if (LogSys.log_settings[Logs::Quests].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQuestsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Quests].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogRules(message, ...) do {\
if (LogSys.log_settings[Logs::Rules].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogRulesDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Rules].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSkills(message, ...) do {\
if (LogSys.log_settings[Logs::Skills].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSkillsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Skills].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSpawns(message, ...) do {\
if (LogSys.log_settings[Logs::Spawns].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSpawnsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Spawns].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSpells(message, ...) do {\
if (LogSys.log_settings[Logs::Spells].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogSpellsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Spells].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTCPConnection(message, ...) do {\
if (LogSys.log_settings[Logs::TCPConnection].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTCPConnectionDetail(message, ...) do {\
if (LogSys.log_settings[Logs::TCPConnection].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTasks(message, ...) do {\
if (LogSys.log_settings[Logs::Tasks].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTasksDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Tasks].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTradeskills(message, ...) do {\
if (LogSys.log_settings[Logs::Tradeskills].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTradeskillsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Tradeskills].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTrading(message, ...) do {\
if (LogSys.log_settings[Logs::Trading].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTradingDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Trading].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTribute(message, ...) do {\
if (LogSys.log_settings[Logs::Tribute].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTributeDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Tribute].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMySQLError(message, ...) do {\
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMySQLErrorDetail(message, ...) do {\
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMySQLQuery(message, ...) do {\
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMySQLQueryDetail(message, ...) do {\
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMercenaries(message, ...) do {\
if (LogSys.log_settings[Logs::Mercenaries].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMercenariesDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Mercenaries].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQuestDebug(message, ...) do {\
if (LogSys.log_settings[Logs::QuestDebug].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogQuestDebugDetail(message, ...) do {\
if (LogSys.log_settings[Logs::QuestDebug].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogLoginserver(message, ...) do {\
if (LogSys.log_settings[Logs::Loginserver].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogLoginserverDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Loginserver].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogClientLogin(message, ...) do {\
if (LogSys.log_settings[Logs::ClientLogin].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogClientLoginDetail(message, ...) do {\
if (LogSys.log_settings[Logs::ClientLogin].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHeadlessClient(message, ...) do {\
if (LogSys.log_settings[Logs::HeadlessClient].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHeadlessClientDetail(message, ...) do {\
if (LogSys.log_settings[Logs::HeadlessClient].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHPUpdate(message, ...) do {\
if (LogSys.log_settings[Logs::HPUpdate].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogHPUpdateDetail(message, ...) do {\
if (LogSys.log_settings[Logs::HPUpdate].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogFixZ(message, ...) do {\
if (LogSys.log_settings[Logs::FixZ].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogFixZDetail(message, ...) do {\
if (LogSys.log_settings[Logs::FixZ].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogFood(message, ...) do {\
if (LogSys.log_settings[Logs::Food].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogFoodDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Food].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTraps(message, ...) do {\
if (LogSys.log_settings[Logs::Traps].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogTrapsDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Traps].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNPCRoamBox(message, ...) do {\
if (LogSys.log_settings[Logs::NPCRoamBox].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNPCRoamBoxDetail(message, ...) do {\
if (LogSys.log_settings[Logs::NPCRoamBox].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNPCScaling(message, ...) do {\
if (LogSys.log_settings[Logs::NPCScaling].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogNPCScalingDetail(message, ...) do {\
if (LogSys.log_settings[Logs::NPCScaling].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMobAppearance(message, ...) do {\
if (LogSys.log_settings[Logs::MobAppearance].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogMobAppearanceDetail(message, ...) do {\
if (LogSys.log_settings[Logs::MobAppearance].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogStatus(message, ...) do {\
if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogStatusDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIScanClose(message, ...) do {\
if (LogSys.log_settings[Logs::AIScanClose].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIScanCloseDetail(message, ...) do {\
if (LogSys.log_settings[Logs::AIScanClose].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIYellForHelp(message, ...) do {\
if (LogSys.log_settings[Logs::AIYellForHelp].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAIYellForHelpDetail(message, ...) do {\
if (LogSys.log_settings[Logs::AIYellForHelp].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAICastBeneficialClose(message, ...) do {\
if (LogSys.log_settings[Logs::AICastBeneficialClose].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAICastBeneficialCloseDetail(message, ...) do {\
if (LogSys.log_settings[Logs::AICastBeneficialClose].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAoeCast(message, ...) do {\
if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogAoeCastDetail(message, ...) do {\
if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogEntityManagement(message, ...) do {\
if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogEntityManagementDetail(message, ...) do {\
if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogFlee(message, ...) do {\
if (LogSys.log_settings[Logs::Flee].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogFleeDetail(message, ...) do {\
if (LogSys.log_settings[Logs::Flee].is_category_enabled == 1)\
OutF(LogSys, Logs::Detail, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogF(debug_level, log_category, message, ...) do {\
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#else
#define LogEmergency(message, ...) do {\
} while (0)
#define LogAlert(message, ...) do {\
} while (0)
#define LogCritical(message, ...) do {\
} while (0)
#define LogError(message, ...) do {\
} while (0)
#define LogWarning(message, ...) do {\
} while (0)
#define LogNotice(message, ...) do {\
} while (0)
#define LogInfo(message, ...) do {\
} while (0)
#define LogDebug(message, ...) do {\
} while (0)
/**
* Category
*/
#define LogAA(message, ...) do {\
} while (0)
#define LogAADetail(message, ...) do {\
} while (0)
#define LogAI(message, ...) do {\
} while (0)
#define LogAIDetail(message, ...) do {\
} while (0)
#define LogAggro(message, ...) do {\
} while (0)
#define LogAggroDetail(message, ...) do {\
} while (0)
#define LogAttack(message, ...) do {\
} while (0)
#define LogAttackDetail(message, ...) do {\
} while (0)
#define LogPacketClientServer(message, ...) do {\
} while (0)
#define LogPacketClientServerDetail(message, ...) do {\
} while (0)
#define LogCombat(message, ...) do {\
} while (0)
#define LogCombatDetail(message, ...) do {\
} while (0)
#define LogCommands(message, ...) do {\
} while (0)
#define LogCommandsDetail(message, ...) do {\
} while (0)
#define LogCrash(message, ...) do {\
} while (0)
#define LogCrashDetail(message, ...) do {\
} while (0)
#define LogDoors(message, ...) do {\
} while (0)
#define LogDoorsDetail(message, ...) do {\
} while (0)
#define LogGuilds(message, ...) do {\
} while (0)
#define LogGuildsDetail(message, ...) do {\
} while (0)
#define LogInventory(message, ...) do {\
} while (0)
#define LogInventoryDetail(message, ...) do {\
} while (0)
#define LogLauncher(message, ...) do {\
} while (0)
#define LogLauncherDetail(message, ...) do {\
} while (0)
#define LogNetcode(message, ...) do {\
} while (0)
#define LogNetcodeDetail(message, ...) do {\
} while (0)
#define LogNormal(message, ...) do {\
} while (0)
#define LogNormalDetail(message, ...) do {\
} while (0)
#define LogObject(message, ...) do {\
} while (0)
#define LogObjectDetail(message, ...) do {\
} while (0)
#define LogPathing(message, ...) do {\
} while (0)
#define LogPathingDetail(message, ...) do {\
} while (0)
#define LogQSServer(message, ...) do {\
} while (0)
#define LogQSServerDetail(message, ...) do {\
} while (0)
#define LogQuests(message, ...) do {\
} while (0)
#define LogQuestsDetail(message, ...) do {\
} while (0)
#define LogRules(message, ...) do {\
} while (0)
#define LogRulesDetail(message, ...) do {\
} while (0)
#define LogSkills(message, ...) do {\
} while (0)
#define LogSkillsDetail(message, ...) do {\
} while (0)
#define LogSpawns(message, ...) do {\
} while (0)
#define LogSpawnsDetail(message, ...) do {\
} while (0)
#define LogSpells(message, ...) do {\
} while (0)
#define LogSpellsDetail(message, ...) do {\
} while (0)
#define LogTCPConnection(message, ...) do {\
} while (0)
#define LogTCPConnectionDetail(message, ...) do {\
} while (0)
#define LogTasks(message, ...) do {\
} while (0)
#define LogTasksDetail(message, ...) do {\
} while (0)
#define LogTradeskills(message, ...) do {\
} while (0)
#define LogTradeskillsDetail(message, ...) do {\
} while (0)
#define LogTrading(message, ...) do {\
} while (0)
#define LogTradingDetail(message, ...) do {\
} while (0)
#define LogTribute(message, ...) do {\
} while (0)
#define LogTributeDetail(message, ...) do {\
} while (0)
#define LogMySQLError(message, ...) do {\
} while (0)
#define LogMySQLErrorDetail(message, ...) do {\
} while (0)
#define LogMySQLQuery(message, ...) do {\
} while (0)
#define LogMySQLQueryDetail(message, ...) do {\
} while (0)
#define LogMercenaries(message, ...) do {\
} while (0)
#define LogMercenariesDetail(message, ...) do {\
} while (0)
#define LogQuestDebug(message, ...) do {\
} while (0)
#define LogQuestDebugDetail(message, ...) do {\
} while (0)
#define LogLoginserver(message, ...) do {\
} while (0)
#define LogLoginserverDetail(message, ...) do {\
} while (0)
#define LogClientLogin(message, ...) do {\
} while (0)
#define LogClientLoginDetail(message, ...) do {\
} while (0)
#define LogHeadlessClient(message, ...) do {\
} while (0)
#define LogHeadlessClientDetail(message, ...) do {\
} while (0)
#define LogHPUpdate(message, ...) do {\
} while (0)
#define LogHPUpdateDetail(message, ...) do {\
} while (0)
#define LogFixZ(message, ...) do {\
} while (0)
#define LogFixZDetail(message, ...) do {\
} while (0)
#define LogFood(message, ...) do {\
} while (0)
#define LogFoodDetail(message, ...) do {\
} while (0)
#define LogTraps(message, ...) do {\
} while (0)
#define LogTrapsDetail(message, ...) do {\
} while (0)
#define LogNPCRoamBox(message, ...) do {\
} while (0)
#define LogNPCRoamBoxDetail(message, ...) do {\
} while (0)
#define LogNPCScaling(message, ...) do {\
} while (0)
#define LogNPCScalingDetail(message, ...) do {\
} while (0)
#define LogMobAppearance(message, ...) do {\
} while (0)
#define LogMobAppearanceDetail(message, ...) do {\
} while (0)
#define LogStatus(message, ...) do {\
} while (0)
#define LogStatusDetail(message, ...) do {\
} while (0)
#define LogAIScanClose(message, ...) do {\
} while (0)
#define LogAIScanCloseDetail(message, ...) do {\
} while (0)
#define LogAIYellForHelp(message, ...) do {\
} while (0)
#define LogAIYellForHelpDetail(message, ...) do {\
} while (0)
#define LogAICastBeneficialClose(message, ...) do {\
} while (0)
#define LogAICastBeneficialCloseDetail(message, ...) do {\
} while (0)
#define LogAoeCast(message, ...) do {\
} while (0)
#define LogAoeCastDetail(message, ...) do {\
} while (0)
#define LogEntityManagement(message, ...) do {\
} while (0)
#define LogEntityManagementDetail(message, ...) do {\
} while (0)
#define LogFlee(message, ...) do {\
} while (0)
#define LogFleeDetail(message, ...) do {\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
} while (0)
#define LogF(debug_level, log_category, message, ...) do {\
} while (0)
#endif
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
-41
View File
@@ -1,41 +0,0 @@
#pragma once
#include <functional>
#include <uv.h>
#include <cstring>
namespace EQ
{
class EventLoop
{
public:
static EventLoop &Get() {
static thread_local EventLoop inst;
return inst;
}
~EventLoop() {
uv_loop_close(&m_loop);
}
void Process() {
uv_run(&m_loop, UV_RUN_NOWAIT);
}
void Run() {
uv_run(&m_loop, UV_RUN_DEFAULT);
}
uv_loop_t* Handle() { return &m_loop; }
private:
EventLoop() {
memset(&m_loop, 0, sizeof(uv_loop_t));
uv_loop_init(&m_loop);
}
EventLoop(const EventLoop&);
EventLoop& operator=(const EventLoop&);
uv_loop_t m_loop;
};
}
-100
View File
@@ -1,100 +0,0 @@
#pragma once
#include <functional>
#include <exception>
#include "event_loop.h"
#include "../any.h"
namespace EQ {
class Task
{
public:
typedef std::function<void(const EQEmu::Any&)> ResolveFn;
typedef std::function<void(const std::exception&)> RejectFn;
typedef std::function<void()> FinallyFn;
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
struct TaskBaton
{
TaskFn fn;
ResolveFn on_then;
RejectFn on_catch;
FinallyFn on_finally;
bool has_result;
EQEmu::Any result;
bool has_error;
std::exception error;
};
Task(TaskFn fn) {
m_fn = fn;
}
~Task() {
}
Task& Then(ResolveFn fn) {
m_then = fn;
return *this;
}
Task& Catch(RejectFn fn) {
m_catch = fn;
return *this;
}
Task& Finally(FinallyFn fn) {
m_finally = fn;
return *this;
}
void Run() {
uv_work_t *m_work = new uv_work_t;
memset(m_work, 0, sizeof(uv_work_t));
TaskBaton *baton = new TaskBaton();
baton->fn = m_fn;
baton->on_then = m_then;
baton->on_catch = m_catch;
baton->on_finally = m_finally;
baton->has_result = false;
baton->has_error = false;
m_work->data = baton;
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
TaskBaton *baton = (TaskBaton*)req->data;
baton->fn([baton](const EQEmu::Any& result) {
baton->has_error = false;
baton->has_result = true;
baton->result = result;
}, [baton](const std::exception &err) {
baton->has_error = true;
baton->has_result = false;
baton->error = err;
});
}, [](uv_work_t* req, int status) {
TaskBaton *baton = (TaskBaton*)req->data;
if (baton->has_error && baton->on_catch) {
baton->on_catch(baton->error);
}
else if (baton->has_result && baton->on_then) {
baton->on_then(baton->result);
}
if (baton->on_finally) {
baton->on_finally();
}
delete baton;
delete req;
});
}
private:
TaskFn m_fn;
ResolveFn m_then;
RejectFn m_catch;
FinallyFn m_finally;
};
}
-114
View File
@@ -1,114 +0,0 @@
#pragma once
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <queue>
#include <future>
namespace EQ
{
namespace Event
{
class TaskScheduler
{
public:
static const int DefaultThreadCount = 4;
TaskScheduler() : _running(false)
{
Start(DefaultThreadCount);
}
TaskScheduler(size_t threads) : _running(false)
{
Start(threads);
}
~TaskScheduler() {
Stop();
}
void Start(size_t threads) {
if (true == _running) {
return;
}
_running = true;
for (size_t i = 0; i < threads; ++i) {
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
}
}
void Stop() {
if (false == _running) {
return;
}
{
std::unique_lock<std::mutex> lock(_lock);
_running = false;
}
_cv.notify_all();
for (auto &t : _threads) {
t.join();
}
}
template<typename Fn, typename... Args>
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::result_of<Fn(Args...)>::type> {
using return_type = typename std::result_of<Fn(Args...)>::type;
auto task = std::make_shared<std::packaged_task<return_type()>>(
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
);
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(_lock);
if (false == _running) {
throw std::runtime_error("Enqueue on stopped scheduler.");
}
_tasks.emplace([task]() { (*task)(); });
}
_cv.notify_one();
return res;
}
private:
void ProcessWork() {
for (;;) {
std::function<void()> work;
{
std::unique_lock<std::mutex> lock(_lock);
_cv.wait(lock, [this] { return !_running || !_tasks.empty(); });
if (false == _running) {
return;
}
work = std::move(_tasks.front());
_tasks.pop();
}
work();
}
}
bool _running = true;
std::vector<std::thread> _threads;
std::mutex _lock;
std::condition_variable _cv;
std::queue<std::function<void()>> _tasks;
};
}
}
-67
View File
@@ -1,67 +0,0 @@
#pragma once
#include <functional>
#include "event_loop.h"
namespace EQ {
class Timer
{
public:
Timer(std::function<void(Timer *)> cb)
{
m_timer = nullptr;
m_cb = cb;
}
Timer(uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb)
{
m_timer = nullptr;
m_cb = cb;
Start(duration_ms, repeats);
}
~Timer()
{
Stop();
}
void Start(uint64_t duration_ms, bool repeats) {
auto loop = EventLoop::Get().Handle();
if (!m_timer) {
m_timer = new uv_timer_t;
memset(m_timer, 0, sizeof(uv_timer_t));
uv_timer_init(loop, m_timer);
m_timer->data = this;
if (repeats) {
uv_timer_start(m_timer, [](uv_timer_t *handle) {
Timer *t = (Timer*)handle->data;
t->Execute();
}, duration_ms, duration_ms);
}
else {
uv_timer_start(m_timer, [](uv_timer_t *handle) {
Timer *t = (Timer*)handle->data;
t->Stop();
t->Execute();
}, duration_ms, 0);
}
}
}
void Stop() {
if (m_timer) {
uv_close((uv_handle_t*)m_timer, [](uv_handle_t* handle) {
delete handle;
});
m_timer = nullptr;
}
}
private:
void Execute() {
m_cb(this);
}
uv_timer_t *m_timer;
std::function<void(Timer*)> m_cb;
};
}
-21
View File
@@ -1,21 +0,0 @@
#include "event_sub.h"
void EventSubscriptionWatcher::Subscribe(const std::string &event_name)
{
m_subs[event_name] = 1;
}
void EventSubscriptionWatcher::Unsubscribe(const std::string &event_name)
{
m_subs[event_name] = 0;
}
bool EventSubscriptionWatcher::IsSubscribed(const std::string &event_name) const
{
auto iter = m_subs.find(event_name);
if (iter != m_subs.end()) {
return iter->second;
}
return false;
}
-29
View File
@@ -1,29 +0,0 @@
#pragma once
#include <unordered_map>
#include <string>
class EventSubscriptionWatcher
{
public:
~EventSubscriptionWatcher();
void Subscribe(const std::string &event_name);
void Unsubscribe(const std::string &event_name);
bool IsSubscribed(const std::string &event_name) const;
static EventSubscriptionWatcher *Get() {
static EventSubscriptionWatcher* inst = nullptr;
if(!inst) {
inst = new EventSubscriptionWatcher();
}
return inst;
}
private:
EventSubscriptionWatcher() { }
EventSubscriptionWatcher(const EventSubscriptionWatcher&);
EventSubscriptionWatcher& operator=(const EventSubscriptionWatcher&);
std::unordered_map<std::string, bool> m_subs;
};
+12 -10
View File
@@ -18,7 +18,6 @@
#include "faction.h"
#include "races.h"
#include "rulesys.h"
const char *FactionValueToString(FACTION_VALUE fv)
{
@@ -60,31 +59,34 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
if (fm) {
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
}
if (character_value >= RuleI(Faction, AllyFactionMinimum)) {
if (character_value >= 1101) {
return FACTION_ALLY;
}
if (character_value >= RuleI(Faction, WarmlyFactionMinimum)) {
if (character_value >= 701 && character_value <= 1100) {
return FACTION_WARMLY;
}
if (character_value >= RuleI(Faction, KindlyFactionMinimum)) {
if (character_value >= 401 && character_value <= 700) {
return FACTION_KINDLY;
}
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
if (character_value >= 101 && character_value <= 400) {
return FACTION_AMIABLE;
}
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
if (character_value >= 0 && character_value <= 100) {
return FACTION_INDIFFERENT;
}
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
if (character_value >= -100 && character_value <= -1) {
return FACTION_APPREHENSIVE;
}
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
if (character_value >= -700 && character_value <= -101) {
return FACTION_DUBIOUS;
}
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
if (character_value >= -999 && character_value <= -701) {
return FACTION_THREATENLY;
}
return FACTION_SCOWLS;
if (character_value <= -1000) {
return FACTION_SCOWLS;
}
return FACTION_INDIFFERENT;
}
// this function should check if some races have more than one race define
Executable → Regular
-4
View File
@@ -50,8 +50,6 @@ struct NPCFactionList {
struct FactionMods
{
int32 base;
int16 min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
int16 max; // The highest your personal earned faction can go - before race/class/diety adjustments.
int32 class_mod;
int32 race_mod;
int32 deity_mod;
@@ -61,8 +59,6 @@ struct Faction {
int32 id;
std::map<std::string, int16> mods;
int16 base;
int16 min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
int16 max; // The highest your personal earned faction can go - before race/class/diety adjustments.
char name[50];
};
+11 -13
View File
@@ -111,6 +111,9 @@ Zone extensions and features
//path to where sql logs should be placed
#define SQL_LOG_PATH "sql_logs/"
//New aggro system to reduce overhead.
#define REVERSE_AGGRO
//The highest you can #setskill / #setallskill
#define HIGHEST_CAN_SET_SKILL 400
@@ -150,17 +153,17 @@ enum { //reuse times
enum { //timer settings, all in milliseconds
AImovement_duration = 100,
AIthink_duration = 50,
AIthink_duration = 150,
AIscanarea_delay = 6000,
AIfeignremember_delay = 500,
AItarget_check_duration = 500,
AI_scan_door_open_interval = 1000,
// AIClientScanarea_delay = 750, //used in REVERSE_AGGRO
AIClientScanarea_delay = 750, //used in REVERSE_AGGRO
AIassistcheck_delay = 3000, //now often a fighting NPC will yell for help
AI_check_signal_timer_delay = 500, // How often EVENT_SIGNAL checks are processed
ClientProximity_interval = 150,
CombatEventTimer_expire = 12000,
Tribute_duration = 600000,
ZoneTimerResolution = 3, //sleep time between zone main loop runs (milliseconds)
FeignMemoryDuration = 120000, // Duration player must feign death to clear zonewide agro.
EnragedTimer = 360000,
EnragedDurationTimer = 10000
@@ -220,9 +223,6 @@ enum { //some random constants
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
#define USE_NPC_RANGE2 200*200 //arbitrary right now
// Squared range for rampage 75.0 * 75.0 for now
#define NPC_RAMPAGE_RANGE2 5625.0f
//the formula for experience for killing a mob.
//level is the only valid variable to use
#define EXP_FORMULA level*level*75*35/10
@@ -268,20 +268,18 @@ enum {
commandBanPlayers = 100, //can set bans on players
commandChangeDatarate = 201, //edit client's data rate
commandZoneToCoords = 0, //can #zone with coords
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
commandInvSnapshot = 150 //ability to clear/restore snapshots
commandInterrogateInv = 100 //below this == only log on error state and self-only target dump
};
//default states for logging flag on NPCs and clients (having NPCs on by default is prolly a bad idea)
#define CLIENT_DEFAULT_LOGGING_ENABLED true
#define NPC_DEFAULT_LOGGING_ENABLED false
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
#define SAYLINK_ITEM_ID 0xFFFFF
// consumption timers for food/drink here instead of rules because the client
// uses these. Times in ms.
#define CONSUMPTION_TIMER 46000
#define CONSUMPTION_MNK_TIMER 92000
/*
Developer configuration
+21
View File
@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2005 - 2013 G-Truc Creation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+42
View File
@@ -0,0 +1,42 @@
set(NAME glm_dummy)
file(GLOB ROOT_SOURCE *.cpp)
file(GLOB ROOT_INLINE *.inl)
file(GLOB ROOT_HEADER *.hpp)
file(GLOB ROOT_TEXT ../*.txt)
file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp)
file(GLOB_RECURSE CORE_INLINE ./detail/*.inl)
file(GLOB_RECURSE CORE_HEADER ./detail/*.hpp)
file(GLOB_RECURSE GTC_SOURCE ./gtc/*.cpp)
file(GLOB_RECURSE GTC_INLINE ./gtc/*.inl)
file(GLOB_RECURSE GTC_HEADER ./gtc/*.hpp)
file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp)
file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl)
file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp)
source_group("Text Files" FILES ${ROOT_TEXT})
source_group("Core Files" FILES ${CORE_SOURCE})
source_group("Core Files" FILES ${CORE_INLINE})
source_group("Core Files" FILES ${CORE_HEADER})
source_group("GTC Files" FILES ${GTC_SOURCE})
source_group("GTC Files" FILES ${GTC_INLINE})
source_group("GTC Files" FILES ${GTC_HEADER})
source_group("GTX Files" FILES ${GTX_SOURCE})
source_group("GTX Files" FILES ${GTX_INLINE})
source_group("GTX Files" FILES ${GTX_HEADER})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
if(GLM_TEST_ENABLE)
add_executable(${NAME} ${ROOT_TEXT}
${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER}
${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER}
${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER})
endif(GLM_TEST_ENABLE)
#add_library(glm STATIC glm.cpp)
#add_library(glm_shared SHARED glm.cpp)
+35
View File
@@ -0,0 +1,35 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/common.hpp
/// @date 2013-12-24 / 2013-12-24
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "detail/func_common.hpp"
+428
View File
@@ -0,0 +1,428 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/_features.hpp
/// @date 2013-02-20 / 2013-02-20
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
// #define GLM_CXX98_EXCEPTIONS
// #define GLM_CXX98_RTTI
// #define GLM_CXX11_RVALUE_REFERENCES
// Rvalue references - GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
// GLM_CXX11_TRAILING_RETURN
// Rvalue references for *this - GCC not supported
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm
// GLM_CXX11_NONSTATIC_MEMBER_INIT
// Initialization of class objects by rvalues - GCC any
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html
// GLM_CXX11_NONSTATIC_MEMBER_INIT
// Non-static data member initializers - GCC 4.7
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm
// #define GLM_CXX11_VARIADIC_TEMPLATE
// Variadic templates - GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
//
// Extending variadic template template parameters - GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf
// #define GLM_CXX11_GENERALIZED_INITIALIZERS
// Initializer lists - GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm
// #define GLM_CXX11_STATIC_ASSERT
// Static assertions - GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html
// #define GLM_CXX11_AUTO_TYPE
// auto-typed variables - GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf
// #define GLM_CXX11_AUTO_TYPE
// Multi-declarator auto - GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf
// #define GLM_CXX11_AUTO_TYPE
// Removal of auto as a storage-class specifier - GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm
// #define GLM_CXX11_AUTO_TYPE
// New function declarator syntax - GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm
// #define GLM_CXX11_LAMBDAS
// New wording for C++0x lambdas - GCC 4.5
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf
// #define GLM_CXX11_DECLTYPE
// Declared type of an expression - GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf
//
// Right angle brackets - GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
//
// Default template arguments for function templates DR226 GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226
//
// Solving the SFINAE problem for expressions DR339 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html
// #define GLM_CXX11_ALIAS_TEMPLATE
// Template aliases N2258 GCC 4.7
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf
//
// Extern templates N1987 Yes
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm
// #define GLM_CXX11_NULLPTR
// Null pointer constant N2431 GCC 4.6
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
// #define GLM_CXX11_STRONG_ENUMS
// Strongly-typed enums N2347 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf
//
// Forward declarations for enums N2764 GCC 4.6
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf
//
// Generalized attributes N2761 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf
//
// Generalized constant expressions N2235 GCC 4.6
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
//
// Alignment support N2341 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf
// #define GLM_CXX11_DELEGATING_CONSTRUCTORS
// Delegating constructors N1986 GCC 4.7
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
//
// Inheriting constructors N2540 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm
// #define GLM_CXX11_EXPLICIT_CONVERSIONS
// Explicit conversion operators N2437 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf
//
// New character types N2249 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html
//
// Unicode string literals N2442 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
//
// Raw string literals N2442 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
//
// Universal character name literals N2170 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html
// #define GLM_CXX11_USER_LITERALS
// User-defined literals N2765 GCC 4.7
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf
//
// Standard Layout Types N2342 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm
// #define GLM_CXX11_DEFAULTED_FUNCTIONS
// #define GLM_CXX11_DELETED_FUNCTIONS
// Defaulted and deleted functions N2346 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
//
// Extended friend declarations N1791 GCC 4.7
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf
//
// Extending sizeof N2253 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html
// #define GLM_CXX11_INLINE_NAMESPACES
// Inline namespaces N2535 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm
// #define GLM_CXX11_UNRESTRICTED_UNIONS
// Unrestricted unions N2544 GCC 4.6
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
// Local and unnamed types as template arguments N2657 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
// #define GLM_CXX11_RANGE_FOR
// Range-based for N2930 GCC 4.6
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html
// #define GLM_CXX11_OVERRIDE_CONTROL
// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
//
// Minimal support for garbage collection and reachability-based leak detection N2670 No
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm
// #define GLM_CXX11_NOEXCEPT
// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only)
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html
//
// Defining move special member functions N3053 GCC 4.6
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html
//
// Sequence points N2239 Yes
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html
//
// Atomic operations N2427 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html
//
// Strong Compare and Exchange N2748 GCC 4.5
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
//
// Bidirectional Fences N2752 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm
//
// Memory model N2429 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm
//
// Data-dependency ordering: atomics and memory model N2664 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm
//
// Propagating exceptions N2179 GCC 4.4
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html
//
// Abandoning a process and at_quick_exit N2440 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm
//
// Allow atomics use in signal handlers N2547 Yes
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm
//
// Thread-local storage N2659 GCC 4.8
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm
//
// Dynamic initialization and destruction with concurrency N2660 GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm
//
// __func__ predefined identifier N2340 GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm
//
// C99 preprocessor N1653 GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm
//
// long long N1811 GCC 4.3
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf
//
// Extended integral types N1988 Yes
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf
#if(GLM_COMPILER & GLM_COMPILER_GCC)
# if(GLM_COMPILER >= GLM_COMPILER_GCC43)
# define GLM_CXX11_STATIC_ASSERT
# endif
#elif(GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM))
# if(__has_feature(cxx_exceptions))
# define GLM_CXX98_EXCEPTIONS
# endif
# if(__has_feature(cxx_rtti))
# define GLM_CXX98_RTTI
# endif
# if(__has_feature(cxx_access_control_sfinae))
# define GLM_CXX11_ACCESS_CONTROL_SFINAE
# endif
# if(__has_feature(cxx_alias_templates))
# define GLM_CXX11_ALIAS_TEMPLATE
# endif
# if(__has_feature(cxx_alignas))
# define GLM_CXX11_ALIGNAS
# endif
# if(__has_feature(cxx_attributes))
# define GLM_CXX11_ATTRIBUTES
# endif
# if(__has_feature(cxx_constexpr))
# define GLM_CXX11_CONSTEXPR
# endif
# if(__has_feature(cxx_decltype))
# define GLM_CXX11_DECLTYPE
# endif
# if(__has_feature(cxx_default_function_template_args))
# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS
# endif
# if(__has_feature(cxx_defaulted_functions))
# define GLM_CXX11_DEFAULTED_FUNCTIONS
# endif
# if(__has_feature(cxx_delegating_constructors))
# define GLM_CXX11_DELEGATING_CONSTRUCTORS
# endif
# if(__has_feature(cxx_deleted_functions))
# define GLM_CXX11_DELETED_FUNCTIONS
# endif
# if(__has_feature(cxx_explicit_conversions))
# define GLM_CXX11_EXPLICIT_CONVERSIONS
# endif
# if(__has_feature(cxx_generalized_initializers))
# define GLM_CXX11_GENERALIZED_INITIALIZERS
# endif
# if(__has_feature(cxx_implicit_moves))
# define GLM_CXX11_IMPLICIT_MOVES
# endif
# if(__has_feature(cxx_inheriting_constructors))
# define GLM_CXX11_INHERITING_CONSTRUCTORS
# endif
# if(__has_feature(cxx_inline_namespaces))
# define GLM_CXX11_INLINE_NAMESPACES
# endif
# if(__has_feature(cxx_lambdas))
# define GLM_CXX11_LAMBDAS
# endif
# if(__has_feature(cxx_local_type_template_args))
# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
# endif
# if(__has_feature(cxx_noexcept))
# define GLM_CXX11_NOEXCEPT
# endif
# if(__has_feature(cxx_nonstatic_member_init))
# define GLM_CXX11_NONSTATIC_MEMBER_INIT
# endif
# if(__has_feature(cxx_nullptr))
# define GLM_CXX11_NULLPTR
# endif
# if(__has_feature(cxx_override_control))
# define GLM_CXX11_OVERRIDE_CONTROL
# endif
# if(__has_feature(cxx_reference_qualified_functions))
# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS
# endif
# if(__has_feature(cxx_range_for))
# define GLM_CXX11_RANGE_FOR
# endif
# if(__has_feature(cxx_raw_string_literals))
# define GLM_CXX11_RAW_STRING_LITERALS
# endif
# if(__has_feature(cxx_rvalue_references))
# define GLM_CXX11_RVALUE_REFERENCES
# endif
# if(__has_feature(cxx_static_assert))
# define GLM_CXX11_STATIC_ASSERT
# endif
# if(__has_feature(cxx_auto_type))
# define GLM_CXX11_AUTO_TYPE
# endif
# if(__has_feature(cxx_strong_enums))
# define GLM_CXX11_STRONG_ENUMS
# endif
# if(__has_feature(cxx_trailing_return))
# define GLM_CXX11_TRAILING_RETURN
# endif
# if(__has_feature(cxx_unicode_literals))
# define GLM_CXX11_UNICODE_LITERALS
# endif
# if(__has_feature(cxx_unrestricted_unions))
# define GLM_CXX11_UNRESTRICTED_UNIONS
# endif
# if(__has_feature(cxx_user_literals))
# define GLM_CXX11_USER_LITERALS
# endif
# if(__has_feature(cxx_variadic_templates))
# define GLM_CXX11_VARIADIC_TEMPLATES
# endif
#endif//(GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM))
+59
View File
@@ -0,0 +1,59 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/_fixes.hpp
/// @date 2011-02-21 / 2011-11-22
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#include <cmath>
//! Workaround for compatibility with other libraries
#ifdef max
#undef max
#endif
//! Workaround for compatibility with other libraries
#ifdef min
#undef min
#endif
//! Workaround for Android
#ifdef isnan
#undef isnan
#endif
//! Workaround for Android
#ifdef isinf
#undef isinf
#endif
//! Workaround for Chrone Native Client
#ifdef log2
#undef log2
#endif
+136
View File
@@ -0,0 +1,136 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/_noise.hpp
/// @date 2013-12-24 / 2013-12-24
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "../vec2.hpp"
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../common.hpp"
namespace glm{
namespace detail
{
template <typename T>
GLM_FUNC_QUALIFIER T mod289(T const & x)
{
return x - floor(x * static_cast<T>(1.0) / static_cast<T>(289.0)) * static_cast<T>(289.0);
}
template <typename T>
GLM_FUNC_QUALIFIER T permute(T const & x)
{
return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec2<T, P> permute(tvec2<T, P> const & x)
{
return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> permute(tvec3<T, P> const & x)
{
return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> permute(tvec4<T, P> const & x)
{
return mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);
}
/*
template <typename T, precision P, template<typename> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> permute(vecType<T, P> const & x)
{
return mod289(((x * T(34)) + T(1)) * x);
}
*/
template <typename T>
GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r)
{
return T(1.79284291400159) - T(0.85373472095314) * r;
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec2<T, P> taylorInvSqrt(tvec2<T, P> const & r)
{
return T(1.79284291400159) - T(0.85373472095314) * r;
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> taylorInvSqrt(tvec3<T, P> const & r)
{
return T(1.79284291400159) - T(0.85373472095314) * r;
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> taylorInvSqrt(tvec4<T, P> const & r)
{
return T(1.79284291400159) - T(0.85373472095314) * r;
}
/*
template <typename T, precision P, template<typename> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> taylorInvSqrt(vecType<T, P> const & r)
{
return T(1.79284291400159) - T(0.85373472095314) * r;
}
*/
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec2<T, P> fade(tvec2<T, P> const & t)
{
return (t * t * t) * (t * (t * T(6) - T(15)) + T(10));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> fade(tvec3<T, P> const & t)
{
return (t * t * t) * (t * (t * T(6) - T(15)) + T(10));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> fade(tvec4<T, P> const & t)
{
return (t * t * t) * (t * (t * T(6) - T(15)) + T(10));
}
/*
template <typename T, precision P, template <typename> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> fade(vecType<T, P> const & t)
{
return (t * t * t) * (t * (t * T(6) - T(15)) + T(10));
}
*/
}//namespace detail
}//namespace glm
+833
View File
@@ -0,0 +1,833 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/_swizzle.hpp
/// @date 2006-04-20 / 2011-02-16
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
namespace glm{
namespace detail
{
// Internal class for implementing swizzle operators
template <typename T, int N>
struct _swizzle_base0
{
typedef T value_type;
protected:
GLM_FUNC_QUALIFIER value_type& elem (size_t i) { return (reinterpret_cast<value_type*>(_buffer))[i]; }
GLM_FUNC_QUALIFIER const value_type& elem (size_t i) const { return (reinterpret_cast<const value_type*>(_buffer))[i]; }
// Use an opaque buffer to *ensure* the compiler doesn't call a constructor.
// The size 1 buffer is assumed to aligned to the actual members so that the
// elem()
char _buffer[1];
};
template <typename T, precision P, typename V, int E0, int E1, int E2, int E3, int N>
struct _swizzle_base1 : public _swizzle_base0<T, N>
{
};
template <typename T, precision P, typename V, int E0, int E1>
struct _swizzle_base1<T, P, V,E0,E1,-1,-2,2> : public _swizzle_base0<T, 2>
{
GLM_FUNC_QUALIFIER V operator ()() const { return V(this->elem(E0), this->elem(E1)); }
};
template <typename T, precision P, typename V, int E0, int E1, int E2>
struct _swizzle_base1<T, P, V,E0,E1,E2,-1,3> : public _swizzle_base0<T, 3>
{
GLM_FUNC_QUALIFIER V operator ()() const { return V(this->elem(E0), this->elem(E1), this->elem(E2)); }
};
template <typename T, precision P, typename V, int E0, int E1, int E2, int E3>
struct _swizzle_base1<T, P, V,E0,E1,E2,E3,4> : public _swizzle_base0<T, 4>
{
GLM_FUNC_QUALIFIER V operator ()() const { return V(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
};
// Internal class for implementing swizzle operators
/*
Template parameters:
ValueType = type of scalar values (e.g. float, double)
VecType = class the swizzle is applies to (e.g. tvec3<float>)
N = number of components in the vector (e.g. 3)
E0...3 = what index the n-th element of this swizzle refers to in the unswizzled vec
DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles
containing duplicate elements so that they cannot be used as r-values).
*/
template <typename ValueType, precision P, typename VecType, int N, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS>
struct _swizzle_base2 : public _swizzle_base1<ValueType, P, VecType,E0,E1,E2,E3,N>
{
typedef VecType vec_type;
typedef ValueType value_type;
GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const ValueType& t)
{
for (int i = 0; i < N; ++i)
(*this)[i] = t;
return *this;
}
GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const VecType& that)
{
struct op {
GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e = t; }
};
_apply_op(that, op());
return *this;
}
GLM_FUNC_QUALIFIER void operator -= (const VecType& that)
{
struct op {
GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e -= t; }
};
_apply_op(that, op());
}
GLM_FUNC_QUALIFIER void operator += (const VecType& that)
{
struct op {
GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e += t; }
};
_apply_op(that, op());
}
GLM_FUNC_QUALIFIER void operator *= (const VecType& that)
{
struct op {
GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e *= t; }
};
_apply_op(that, op());
}
GLM_FUNC_QUALIFIER void operator /= (const VecType& that)
{
struct op {
GLM_FUNC_QUALIFIER void operator() (value_type& e, value_type& t) { e /= t; }
};
_apply_op(that, op());
}
GLM_FUNC_QUALIFIER value_type& operator[] (size_t i)
{
const int offset_dst[4] = { E0, E1, E2, E3 };
return this->elem(offset_dst[i]);
}
GLM_FUNC_QUALIFIER value_type operator[] (size_t i) const
{
const int offset_dst[4] = { E0, E1, E2, E3 };
return this->elem(offset_dst[i]);
}
protected:
template <typename T>
GLM_FUNC_QUALIFIER void _apply_op(const VecType& that, T op)
{
// Make a copy of the data in this == &that.
// The copier should optimize out the copy in cases where the function is
// properly inlined and the copy is not necessary.
ValueType t[N];
for (int i = 0; i < N; ++i)
t[i] = that[i];
for (int i = 0; i < N; ++i)
op( (*this)[i], t[i] );
}
};
// Specialization for swizzles containing duplicate elements. These cannot be modified.
template <typename ValueType, precision P, typename VecType, int N, int E0, int E1, int E2, int E3>
struct _swizzle_base2<ValueType, P, VecType,N,E0,E1,E2,E3,1> : public _swizzle_base1<ValueType, P, VecType,E0,E1,E2,E3,N>
{
typedef VecType vec_type;
typedef ValueType value_type;
struct Stub {};
GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub const &) { return *this; }
GLM_FUNC_QUALIFIER value_type operator[] (size_t i) const
{
const int offset_dst[4] = { E0, E1, E2, E3 };
return this->elem(offset_dst[i]);
}
};
template <int N,typename ValueType, precision P, typename VecType, int E0,int E1,int E2,int E3>
struct _swizzle : public _swizzle_base2<ValueType, P, VecType, N, E0, E1, E2, E3, (E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)>
{
typedef _swizzle_base2<ValueType, P, VecType,N,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)> base_type;
using base_type::operator=;
GLM_FUNC_QUALIFIER operator VecType () const { return (*this)(); }
};
//
// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros
//
#define _GLM_SWIZZLE_TEMPLATE1 template <int N, typename T, precision P, typename V, int E0, int E1, int E2, int E3>
#define _GLM_SWIZZLE_TEMPLATE2 template <int N, typename T, precision P, typename V, int E0, int E1, int E2, int E3, int F0, int F1, int F2, int F3>
#define _GLM_SWIZZLE_TYPE1 _swizzle<N, T, P, V, E0, E1, E2, E3>
#define _GLM_SWIZZLE_TYPE2 _swizzle<N, T, P, V, F0, F1, F2, F3>
//
// Wrapper for a binary operator (e.g. u.yy + v.zy)
//
#define _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \
_GLM_SWIZZLE_TEMPLATE2 \
GLM_FUNC_QUALIFIER V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \
{ \
return a() OPERAND b(); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const V& b) \
{ \
return a() OPERAND b; \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER V operator OPERAND ( const V& a, const _GLM_SWIZZLE_TYPE1& b) \
{ \
return a OPERAND b(); \
}
//
// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz)
//
#define _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const T& b) \
{ \
return a() OPERAND b; \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER V operator OPERAND ( const T& a, const _GLM_SWIZZLE_TYPE1& b) \
{ \
return a OPERAND b(); \
}
//
// Macro for wrapping a function taking one argument (e.g. abs())
//
#define _GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION) \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a) \
{ \
return FUNCTION(a()); \
}
//
// Macro for wrapping a function taking two vector arguments (e.g. dot()).
//
#define _GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION) \
_GLM_SWIZZLE_TEMPLATE2 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \
{ \
return FUNCTION(a(), b()); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b) \
{ \
return FUNCTION(a(), b()); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename V& b) \
{ \
return FUNCTION(a(), b); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const _GLM_SWIZZLE_TYPE1& b) \
{ \
return FUNCTION(a, b()); \
}
//
// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()).
//
#define _GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION) \
_GLM_SWIZZLE_TEMPLATE2 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b, const T& c) \
{ \
return FUNCTION(a(), b(), c); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b, const T& c) \
{ \
return FUNCTION(a(), b(), c); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\
{ \
return FUNCTION(a(), b, c); \
} \
_GLM_SWIZZLE_TEMPLATE1 \
GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const _GLM_SWIZZLE_TYPE1& b, const T& c) \
{ \
return FUNCTION(a, b(), c); \
}
}//namespace detail
}//namespace glm
namespace glm
{
namespace detail
{
_GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-)
_GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*)
_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+)
_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-)
_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*)
_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/)
}
//
// Swizzles are distinct types from the unswizzled type. The below macros will
// provide template specializations for the swizzle types for the given functions
// so that the compiler does not have any ambiguity to choosing how to handle
// the function.
//
// The alternative is to use the operator()() when calling the function in order
// to explicitly convert the swizzled type to the unswizzled type.
//
//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, abs);
//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acos);
//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acosh);
//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, all);
//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, any);
//_GLM_SWIZZLE_FUNCTION_2_ARGS(value_type, dot);
//_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, cross);
//_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, step);
//_GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix);
}
#define _GLM_SWIZZLE2_2_MEMBERS(T, P, V, E0,E1) \
struct { detail::_swizzle<2, T, P, V<T, P>, 0,0,-1,-2> E0 ## E0; }; \
struct { detail::_swizzle<2, T, P, V<T, P>, 0,1,-1,-2> E0 ## E1; }; \
struct { detail::_swizzle<2, T, P, V<T, P>, 1,0,-1,-2> E1 ## E0; }; \
struct { detail::_swizzle<2, T, P, V<T, P>, 1,1,-1,-2> E1 ## E1; };
#define _GLM_SWIZZLE2_3_MEMBERS(T, P, V, E0,E1) \
struct { detail::_swizzle<3,T, P, V<T, P>, 0,0,0,-1> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 0,0,1,-1> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 0,1,0,-1> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 0,1,1,-1> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 1,0,0,-1> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 1,0,1,-1> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 1,1,0,-1> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T, P, V<T, P>, 1,1,1,-1> E1 ## E1 ## E1; };
#define _GLM_SWIZZLE2_4_MEMBERS(T, P, V, E0,E1) \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,1,1> E1 ## E1 ## E1 ## E1; };
#define _GLM_SWIZZLE3_2_MEMBERS(T, P, V, E0,E1,E2) \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,0,-1,-2> E0 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,1,-1,-2> E0 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,2,-1,-2> E0 ## E2; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,0,-1,-2> E1 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,1,-1,-2> E1 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,2,-1,-2> E1 ## E2; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,0,-1,-2> E2 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,1,-1,-2> E2 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,2,-1,-2> E2 ## E2; };
#define _GLM_SWIZZLE3_3_MEMBERS(T, P, V ,E0,E1,E2) \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,0,-1> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,1,-1> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,2,-1> E0 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,0,-1> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,1,-1> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,2,-1> E0 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,0,-1> E0 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,1,-1> E0 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,2,-1> E0 ## E2 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,0,-1> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,1,-1> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,2,-1> E1 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,0,-1> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,1,-1> E1 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,2,-1> E1 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,0,-1> E1 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,1,-1> E1 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,2,-1> E1 ## E2 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,0,-1> E2 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,1,-1> E2 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,2,-1> E2 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,0,-1> E2 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,1,-1> E2 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,2,-1> E2 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,0,-1> E2 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,1,-1> E2 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,2,-1> E2 ## E2 ## E2; };
#define _GLM_SWIZZLE3_4_MEMBERS(T, P, V, E0,E1,E2) \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4,T, P, V<T, P>, 2,2,2,2> E2 ## E2 ## E2 ## E2; };
#define _GLM_SWIZZLE4_2_MEMBERS(T, P, V, E0,E1,E2,E3) \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,0,-1,-2> E0 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,1,-1,-2> E0 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,2,-1,-2> E0 ## E2; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 0,3,-1,-2> E0 ## E3; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,0,-1,-2> E1 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,1,-1,-2> E1 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,2,-1,-2> E1 ## E2; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 1,3,-1,-2> E1 ## E3; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,0,-1,-2> E2 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,1,-1,-2> E2 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,2,-1,-2> E2 ## E2; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 2,3,-1,-2> E2 ## E3; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 3,0,-1,-2> E3 ## E0; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 3,1,-1,-2> E3 ## E1; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 3,2,-1,-2> E3 ## E2; }; \
struct { detail::_swizzle<2,T, P, V<T, P>, 3,3,-1,-2> E3 ## E3; };
#define _GLM_SWIZZLE4_3_MEMBERS(T,P, V, E0,E1,E2,E3) \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,0,-1> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,1,-1> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,2,-1> E0 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,0,3,-1> E0 ## E0 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,0,-1> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,1,-1> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,2,-1> E0 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,1,3,-1> E0 ## E1 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,0,-1> E0 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,1,-1> E0 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,2,-1> E0 ## E2 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,2,3,-1> E0 ## E2 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,3,0,-1> E0 ## E3 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,3,1,-1> E0 ## E3 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,3,2,-1> E0 ## E3 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 0,3,3,-1> E0 ## E3 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,0,-1> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,1,-1> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,2,-1> E1 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,0,3,-1> E1 ## E0 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,0,-1> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,1,-1> E1 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,2,-1> E1 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,1,3,-1> E1 ## E1 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,0,-1> E1 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,1,-1> E1 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,2,-1> E1 ## E2 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,2,3,-1> E1 ## E2 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,3,0,-1> E1 ## E3 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,3,1,-1> E1 ## E3 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,3,2,-1> E1 ## E3 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 1,3,3,-1> E1 ## E3 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,0,-1> E2 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,1,-1> E2 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,2,-1> E2 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,0,3,-1> E2 ## E0 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,0,-1> E2 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,1,-1> E2 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,2,-1> E2 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,1,3,-1> E2 ## E1 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,0,-1> E2 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,1,-1> E2 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,2,-1> E2 ## E2 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,2,3,-1> E2 ## E2 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,3,0,-1> E2 ## E3 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,3,1,-1> E2 ## E3 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,3,2,-1> E2 ## E3 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 2,3,3,-1> E2 ## E3 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,0,0,-1> E3 ## E0 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,0,1,-1> E3 ## E0 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,0,2,-1> E3 ## E0 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,0,3,-1> E3 ## E0 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,1,0,-1> E3 ## E1 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,1,1,-1> E3 ## E1 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,1,2,-1> E3 ## E1 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,1,3,-1> E3 ## E1 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,2,0,-1> E3 ## E2 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,2,1,-1> E3 ## E2 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,2,2,-1> E3 ## E2 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,2,3,-1> E3 ## E2 ## E3; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,3,0,-1> E3 ## E3 ## E0; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,3,1,-1> E3 ## E3 ## E1; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,3,2,-1> E3 ## E3 ## E2; }; \
struct { detail::_swizzle<3,T,P, V<T, P>, 3,3,3,-1> E3 ## E3 ## E3; };
#define _GLM_SWIZZLE4_4_MEMBERS(T, P, V, E0,E1,E2,E3) \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \
struct { detail::_swizzle<4, T, P, V<T, P>, 3,3,3,3> E3 ## E3 ## E3 ## E3; };
+725
View File
@@ -0,0 +1,725 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/_swizzle_func.hpp
/// @date 2011-10-16 / 2011-10-16
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#define GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \
SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B() CONST \
{ \
return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B); \
}
#define GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \
SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B ## C() CONST \
{ \
return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C); \
}
#define GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \
SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B ## C ## D() CONST \
{ \
return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C, this->D); \
}
#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \
template <typename TMPL_TYPE> \
SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B() CONST \
{ \
return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B); \
}
#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \
template <typename TMPL_TYPE> \
SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B ## C() CONST \
{ \
return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C); \
}
#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \
template <typename TMPL_TYPE> \
SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B ## C ## D() CONST \
{ \
return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C, this->D); \
}
#define GLM_MUTABLE
#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A)
#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE) \
GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, x, y) \
GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, r, g) \
GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, s, t)
//GLM_SWIZZLE_GEN_REF_FROM_VEC2(valType, detail::vec2, detail::ref2)
#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B)
#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B, A)
#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C)
#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE) \
GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, x, y, z) \
GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, r, g, b) \
GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, s, t, p)
//GLM_SWIZZLE_GEN_REF_FROM_VEC3(valType, detail::vec3, detail::ref2, detail::ref3)
#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, C)
#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B)
#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C, A)
#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)
#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \
GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \
GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p, q)
//GLM_SWIZZLE_GEN_REF_FROM_VEC4(valType, detail::vec4, detail::ref2, detail::ref3, detail::ref4)
#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B)
#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B)
#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B)
#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B) \
GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B)
#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t)
//GLM_SWIZZLE_GEN_VEC_FROM_VEC2(valType, detail::vec2, detail::vec2, detail::vec3, detail::vec4)
#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C)
#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C)
#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C)
#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C)
#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p)
//GLM_SWIZZLE_GEN_VEC_FROM_VEC3(valType, detail::vec3, detail::vec2, detail::vec3, detail::vec4)
#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C) \
GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D)
#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C) \
GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D)
#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, D) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, A) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, B) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, C) \
GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, D)
#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \
GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)
#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \
GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p, q)
//GLM_SWIZZLE_GEN_VEC_FROM_VEC4(valType, detail::vec4, detail::vec2, detail::vec3, detail::vec4)
+160
View File
@@ -0,0 +1,160 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/_vectorize.hpp
/// @date 2011-10-14 / 2011-10-14
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "type_vec1.hpp"
#include "type_vec2.hpp"
#include "type_vec3.hpp"
#include "type_vec4.hpp"
namespace glm{
namespace detail
{
template <typename R, typename T, precision P, template <typename, precision> class vecType>
struct functor1{};
template <typename R, typename T, precision P>
struct functor1<R, T, P, tvec1>
{
GLM_FUNC_QUALIFIER static tvec1<R, P> call(R (*Func) (T x), tvec1<T, P> const & v)
{
return tvec1<R, P>(Func(v.x));
}
};
template <typename R, typename T, precision P>
struct functor1<R, T, P, tvec2>
{
GLM_FUNC_QUALIFIER static tvec2<R, P> call(R (*Func) (T x), tvec2<T, P> const & v)
{
return tvec2<R, P>(Func(v.x), Func(v.y));
}
};
template <typename R, typename T, precision P>
struct functor1<R, T, P, tvec3>
{
GLM_FUNC_QUALIFIER static tvec3<R, P> call(R (*Func) (T x), tvec3<T, P> const & v)
{
return tvec3<R, P>(Func(v.x), Func(v.y), Func(v.z));
}
};
template <typename R, typename T, precision P>
struct functor1<R, T, P, tvec4>
{
GLM_FUNC_QUALIFIER static tvec4<R, P> call(R (*Func) (T x), tvec4<T, P> const & v)
{
return tvec4<R, P>(Func(v.x), Func(v.y), Func(v.z), Func(v.w));
}
};
template <typename T, precision P, template <typename, precision> class vecType>
struct functor2{};
template <typename T, precision P>
struct functor2<T, P, tvec1>
{
GLM_FUNC_QUALIFIER static tvec1<T, P> call(T (*Func) (T x, T y), tvec1<T, P> const & a, tvec1<T, P> const & b)
{
return tvec1<T, P>(Func(a.x, b.x));
}
};
template <typename T, precision P>
struct functor2<T, P, tvec2>
{
GLM_FUNC_QUALIFIER static tvec2<T, P> call(T (*Func) (T x, T y), tvec2<T, P> const & a, tvec2<T, P> const & b)
{
return tvec2<T, P>(Func(a.x, b.x), Func(a.y, b.y));
}
};
template <typename T, precision P>
struct functor2<T, P, tvec3>
{
GLM_FUNC_QUALIFIER static tvec3<T, P> call(T (*Func) (T x, T y), tvec3<T, P> const & a, tvec3<T, P> const & b)
{
return tvec3<T, P>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
}
};
template <typename T, precision P>
struct functor2<T, P, tvec4>
{
GLM_FUNC_QUALIFIER static tvec4<T, P> call(T (*Func) (T x, T y), tvec4<T, P> const & a, tvec4<T, P> const & b)
{
return tvec4<T, P>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
}
};
template <typename T, precision P, template <typename, precision> class vecType>
struct functor2_vec_sca{};
template <typename T, precision P>
struct functor2_vec_sca<T, P, tvec1>
{
GLM_FUNC_QUALIFIER static tvec1<T, P> call(T (*Func) (T x, T y), tvec1<T, P> const & a, T b)
{
return tvec1<T, P>(Func(a.x, b));
}
};
template <typename T, precision P>
struct functor2_vec_sca<T, P, tvec2>
{
GLM_FUNC_QUALIFIER static tvec2<T, P> call(T (*Func) (T x, T y), tvec2<T, P> const & a, T b)
{
return tvec2<T, P>(Func(a.x, b), Func(a.y, b));
}
};
template <typename T, precision P>
struct functor2_vec_sca<T, P, tvec3>
{
GLM_FUNC_QUALIFIER static tvec3<T, P> call(T (*Func) (T x, T y), tvec3<T, P> const & a, T b)
{
return tvec3<T, P>(Func(a.x, b), Func(a.y, b), Func(a.z, b));
}
};
template <typename T, precision P>
struct functor2_vec_sca<T, P, tvec4>
{
GLM_FUNC_QUALIFIER static tvec4<T, P> call(T (*Func) (T x, T y), tvec4<T, P> const & a, T b)
{
return tvec4<T, P>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b));
}
};
}//namespace detail
}//namespace glm
+222
View File
@@ -0,0 +1,222 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/core/dummy.cpp
/// @date 2011-01-19 / 2011-06-15
/// @author Christophe Riccio
///
/// GLM is a header only library. There is nothing to compile.
/// dummy.cpp exist only a wordaround for CMake file.
///////////////////////////////////////////////////////////////////////////////////
#define GLM_MESSAGES
#include "../glm.hpp"
#include <limits>
struct material
{
glm::vec4 emission; // Ecm
glm::vec4 ambient; // Acm
glm::vec4 diffuse; // Dcm
glm::vec4 specular; // Scm
float shininess; // Srm
};
struct light
{
glm::vec4 ambient; // Acli
glm::vec4 diffuse; // Dcli
glm::vec4 specular; // Scli
glm::vec4 position; // Ppli
glm::vec4 halfVector; // Derived: Hi
glm::vec3 spotDirection; // Sdli
float spotExponent; // Srli
float spotCutoff; // Crli
// (range: [0.0,90.0], 180.0)
float spotCosCutoff; // Derived: cos(Crli)
// (range: [1.0,0.0],-1.0)
float constantAttenuation; // K0
float linearAttenuation; // K1
float quadraticAttenuation;// K2
};
// Sample 1
#include <glm/vec3.hpp>// glm::vec3
#include <glm/geometric.hpp>// glm::cross, glm::normalize
glm::vec3 computeNormal
(
glm::vec3 const & a,
glm::vec3 const & b,
glm::vec3 const & c
)
{
return glm::normalize(glm::cross(c - a, b - a));
}
typedef unsigned int GLuint;
#define GL_FALSE 0
void glUniformMatrix4fv(GLuint, int, int, float*){}
// Sample 2
#include <glm/vec3.hpp> // glm::vec3
#include <glm/vec4.hpp> // glm::vec4, glm::ivec4
#include <glm/mat4x4.hpp> // glm::mat4
#include <glm/gtc/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale, glm::perspective
#include <glm/gtc/type_ptr.hpp> // glm::value_ptr
void func(GLuint LocationMVP, float Translate, glm::vec2 const & Rotate)
{
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.f);
glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate));
glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f));
glm::mat4 View = glm::rotate(ViewRotateX, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(LocationMVP, 1, GL_FALSE, glm::value_ptr(MVP));
}
// Sample 3
#include <glm/vec2.hpp>// glm::vec2
#include <glm/packing.hpp>// glm::packUnorm2x16
#include <glm/integer.hpp>// glm::uint
#include <glm/gtc/type_precision.hpp>// glm::i8vec2, glm::i32vec2
std::size_t const VertexCount = 4;
// Float quad geometry
std::size_t const PositionSizeF32 = VertexCount * sizeof(glm::vec2);
glm::vec2 const PositionDataF32[VertexCount] =
{
glm::vec2(-1.0f,-1.0f),
glm::vec2( 1.0f,-1.0f),
glm::vec2( 1.0f, 1.0f),
glm::vec2(-1.0f, 1.0f)
};
// Half-float quad geometry
std::size_t const PositionSizeF16 = VertexCount * sizeof(glm::uint);
glm::uint const PositionDataF16[VertexCount] =
{
glm::uint(glm::packUnorm2x16(glm::vec2(-1.0f, -1.0f))),
glm::uint(glm::packUnorm2x16(glm::vec2( 1.0f, -1.0f))),
glm::uint(glm::packUnorm2x16(glm::vec2( 1.0f, 1.0f))),
glm::uint(glm::packUnorm2x16(glm::vec2(-1.0f, 1.0f)))
};
// 8 bits signed integer quad geometry
std::size_t const PositionSizeI8 = VertexCount * sizeof(glm::i8vec2);
glm::i8vec2 const PositionDataI8[VertexCount] =
{
glm::i8vec2(-1,-1),
glm::i8vec2( 1,-1),
glm::i8vec2( 1, 1),
glm::i8vec2(-1, 1)
};
// 32 bits signed integer quad geometry
std::size_t const PositionSizeI32 = VertexCount * sizeof(glm::i32vec2);
glm::i32vec2 const PositionDataI32[VertexCount] =
{
glm::i32vec2 (-1,-1),
glm::i32vec2 ( 1,-1),
glm::i32vec2 ( 1, 1),
glm::i32vec2 (-1, 1)
};
struct intersection
{
glm::vec4 position;
glm::vec3 normal;
};
/*
// Sample 4
#include <glm/vec3.hpp>// glm::vec3
#include <glm/geometric.hpp>// glm::normalize, glm::dot, glm::reflect
#include <glm/exponential.hpp>// glm::pow
#include <glm/gtc/random.hpp>// glm::vecRand3
glm::vec3 lighting
(
intersection const & Intersection,
material const & Material,
light const & Light,
glm::vec3 const & View
)
{
glm::vec3 Color(0.0f);
glm::vec3 LightVertor(glm::normalize(
Light.position - Intersection.position +
glm::vecRand3(0.0f, Light.inaccuracy));
if(!shadow(Intersection.position, Light.position, LightVertor))
{
float Diffuse = glm::dot(Intersection.normal, LightVector);
if(Diffuse <= 0.0f)
return Color;
if(Material.isDiffuse())
Color += Light.color() * Material.diffuse * Diffuse;
if(Material.isSpecular())
{
glm::vec3 Reflect(glm::reflect(
glm::normalize(-LightVector),
glm::normalize(Intersection.normal)));
float Dot = glm::dot(Reflect, View);
float Base = Dot > 0.0f ? Dot : 0.0f;
float Specular = glm::pow(Base, Material.exponent);
Color += Material.specular * Specular;
}
}
return Color;
}
*/
template <typename T, glm::precision P, template<typename, glm::precision> class vecType>
T normalizeDotA(vecType<T, P> const & x, vecType<T, P> const & y)
{
return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y));
}
#define GLM_TEMPLATE_GENTYPE typename T, glm::precision P, template<typename, glm::precision> class
template <GLM_TEMPLATE_GENTYPE vecType>
T normalizeDotB(vecType<T, P> const & x, vecType<T, P> const & y)
{
return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y));
}
template <typename vecType>
typename vecType::value_type normalizeDotC(vecType const & a, vecType const & b)
{
return glm::dot(a, b) * glm::inversesqrt(glm::dot(a, a) * glm::dot(b, b));
}
int main()
{
glm::vec4 v(1);
float a = normalizeDotA(v, v);
float b = normalizeDotB(v, v);
float c = normalizeDotC(v, v);
return 0;
}
+456
View File
@@ -0,0 +1,456 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/func_common.hpp
/// @date 2008-03-08 / 2010-01-26
/// @author Christophe Riccio
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
///
/// @defgroup core_func_common Common functions
/// @ingroup core
///
/// These all operate component-wise. The description is per component.
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "setup.hpp"
#include "precision.hpp"
#include "type_int.hpp"
#include "_fixes.hpp"
namespace glm
{
/// @addtogroup core_func_common
/// @{
/// Returns x if x >= 0; otherwise, it returns -x.
///
/// @tparam genType floating-point or signed integer; scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType abs(genType x);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> abs(vecType<T, P> const & x);
/// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0.
///
/// @tparam genType Floating-point or signed integer; scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sign.xml">GLSL sign man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> sign(vecType<T, P> const & x);
/// Returns a value equal to the nearest integer that is less then or equal to x.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floor.xml">GLSL floor man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> floor(vecType<T, P> const & x);
/// Returns a value equal to the nearest integer to x
/// whose absolute value is not larger than the absolute value of x.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/trunc.xml">GLSL trunc man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> trunc(vecType<T, P> const & x);
/// Returns a value equal to the nearest integer to x.
/// The fraction 0.5 will round in a direction chosen by the
/// implementation, presumably the direction that is fastest.
/// This includes the possibility that round(x) returns the
/// same value as roundEven(x) for all values of x.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/round.xml">GLSL round man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> round(vecType<T, P> const & x);
/// Returns a value equal to the nearest integer to x.
/// A fractional part of 0.5 will round toward the nearest even
/// integer. (Both 3.5 and 4.5 for x will return 4.0.)
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/roundEven.xml">GLSL roundEven man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
/// @see <a href="http://developer.amd.com/documentation/articles/pages/New-Round-to-Even-Technique.aspx">New round to even technique</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> roundEven(vecType<T, P> const & x);
/// Returns a value equal to the nearest integer
/// that is greater than or equal to x.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ceil.xml">GLSL ceil man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> ceil(vecType<T, P> const & x);
/// Return x - floor(x).
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType fract(genType x);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> fract(vecType<T, P> const & x);
/// Modulus. Returns x - y * floor(x / y)
/// for each component in x using the floating point value y.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType mod(genType x, genType y);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> mod(vecType<T, P> const & x, T y);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> mod(vecType<T, P> const & x, vecType<T, P> const & y);
/// Returns the fractional part of x and sets i to the integer
/// part (as a whole number floating point value). Both the
/// return value and the output parameter will have the same
/// sign as x.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/modf.xml">GLSL modf man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType modf(genType x, genType & i);
/// Returns y if y < x; otherwise, it returns x.
///
/// @tparam genType Floating-point or integer; scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType min(genType x, genType y);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> min(vecType<T, P> const & x, T y);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> min(vecType<T, P> const & x, vecType<T, P> const & y);
/// Returns y if x < y; otherwise, it returns x.
///
/// @tparam genType Floating-point or integer; scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType max(genType x, genType y);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> max(vecType<T, P> const & x, T y);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> max(vecType<T, P> const & x, vecType<T, P> const & y);
/// Returns min(max(x, minVal), maxVal) for each component in x
/// using the floating-point values minVal and maxVal.
///
/// @tparam genType Floating-point or integer; scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType clamp(genType x, genType minVal, genType maxVal);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> clamp(vecType<T, P> const & x, T minVal, T maxVal);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> clamp(vecType<T, P> const & x, vecType<T, P> const & minVal, vecType<T, P> const & maxVal);
/// If genTypeU is a floating scalar or vector:
/// Returns x * (1.0 - a) + y * a, i.e., the linear blend of
/// x and y using the floating-point value a.
/// The value for a is not restricted to the range [0, 1].
///
/// If genTypeU is a boolean scalar or vector:
/// Selects which vector each returned component comes
/// from. For a component of <a> that is false, the
/// corresponding component of x is returned. For a
/// component of a that is true, the corresponding
/// component of y is returned. Components of x and y that
/// are not selected are allowed to be invalid floating point
/// values and will have no effect on the results. Thus, this
/// provides different functionality than
/// genType mix(genType x, genType y, genType(a))
/// where a is a Boolean vector.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mix.xml">GLSL mix man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
///
/// @param[in] x Value to interpolate.
/// @param[in] y Value to interpolate.
/// @param[in] a Interpolant.
///
/// @tparam genTypeT Floating point scalar or vector.
/// @tparam genTypeU Floating point or boolean scalar or vector. It can't be a vector if it is the length of genTypeT.
///
/// @code
/// #include <glm/glm.hpp>
/// ...
/// float a;
/// bool b;
/// glm::dvec3 e;
/// glm::dvec3 f;
/// glm::vec4 g;
/// glm::vec4 h;
/// ...
/// glm::vec4 r = glm::mix(g, h, a); // Interpolate with a floating-point scalar two vectors.
/// glm::vec4 s = glm::mix(g, h, b); // Teturns g or h;
/// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second.
/// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter.
/// @endcode
template <typename T, typename U, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> mix(vecType<T, P> const & x, vecType<T, P> const & y, vecType<U, P> const & a);
template <typename T, typename U, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> mix(vecType<T, P> const & x, vecType<T, P> const & y, U a);
template <typename genTypeT, typename genTypeU>
GLM_FUNC_DECL genTypeT mix(genTypeT x, genTypeT y, genTypeU a);
/// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType step(genType edge, genType x);
/// Returns 0.0 if x < edge, otherwise it returns 1.0.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <template <typename, precision> class vecType, typename T, precision P>
GLM_FUNC_DECL vecType<T, P> step(T edge, vecType<T, P> const & x);
/// Returns 0.0 if x < edge, otherwise it returns 1.0.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <template <typename, precision> class vecType, typename T, precision P>
GLM_FUNC_DECL vecType<T, P> step(vecType<T, P> const & edge, vecType<T, P> const & x);
/// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
/// performs smooth Hermite interpolation between 0 and 1
/// when edge0 < x < edge1. This is useful in cases where
/// you would want a threshold function with a smooth
/// transition. This is equivalent to:
/// genType t;
/// t = clamp ((x - edge0) / (edge1 - edge0), 0, 1);
/// return t * t * (3 - 2 * t);
/// Results are undefined if edge0 >= edge1.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml">GLSL smoothstep man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType smoothstep(genType edge0, genType edge1, genType x);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> smoothstep(T edge0, T edge1, vecType<T, P> const & x);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> smoothstep(vecType<T, P> const & edge0, vecType<T, P> const & edge1, vecType<T, P> const & x);
/// Returns true if x holds a NaN (not a number)
/// representation in the underlying implementation's set of
/// floating point representations. Returns false otherwise,
/// including for implementations with no NaN
/// representations.
///
/// /!\ When using compiler fast math, this function may fail.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isnan.xml">GLSL isnan man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<bool, P> isnan(vecType<T, P> const & x);
/// Returns true if x holds a positive infinity or negative
/// infinity representation in the underlying implementation's
/// set of floating point representations. Returns false
/// otherwise, including for implementations with no infinity
/// representations.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isinf.xml">GLSL isinf man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<bool, P> isinf(vecType<T, P> const & x);
/// Returns a signed integer value representing
/// the encoding of a floating-point value. The floating-point
/// value's bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
GLM_FUNC_DECL int floatBitsToInt(float const & v);
/// Returns a signed integer value representing
/// the encoding of a floating-point value. The floatingpoint
/// value's bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_DECL vecType<int, P> floatBitsToInt(vecType<float, P> const & v);
/// Returns a unsigned integer value representing
/// the encoding of a floating-point value. The floatingpoint
/// value's bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
GLM_FUNC_DECL uint floatBitsToUint(float const & v);
/// Returns a unsigned integer value representing
/// the encoding of a floating-point value. The floatingpoint
/// value's bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_DECL vecType<uint, P> floatBitsToUint(vecType<float, P> const & v);
/// Returns a floating-point value corresponding to a signed
/// integer encoding of a floating-point value.
/// If an inf or NaN is passed in, it will not signal, and the
/// resulting floating point value is unspecified. Otherwise,
/// the bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
GLM_FUNC_DECL float intBitsToFloat(int const & v);
/// Returns a floating-point value corresponding to a signed
/// integer encoding of a floating-point value.
/// If an inf or NaN is passed in, it will not signal, and the
/// resulting floating point value is unspecified. Otherwise,
/// the bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_DECL vecType<float, P> intBitsToFloat(vecType<int, P> const & v);
/// Returns a floating-point value corresponding to a
/// unsigned integer encoding of a floating-point value.
/// If an inf or NaN is passed in, it will not signal, and the
/// resulting floating point value is unspecified. Otherwise,
/// the bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
GLM_FUNC_DECL float uintBitsToFloat(uint const & v);
/// Returns a floating-point value corresponding to a
/// unsigned integer encoding of a floating-point value.
/// If an inf or NaN is passed in, it will not signal, and the
/// resulting floating point value is unspecified. Otherwise,
/// the bit-level representation is preserved.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_DECL vecType<float, P> uintBitsToFloat(vecType<uint, P> const & v);
/// Computes and returns a * b + c.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fma.xml">GLSL fma man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType>
GLM_FUNC_DECL genType fma(genType const & a, genType const & b, genType const & c);
/// Splits x into a floating-point significand in the range
/// [0.5, 1.0) and an integral exponent of two, such that:
/// x = significand * exp(2, exponent)
///
/// The significand is returned by the function and the
/// exponent is returned in the parameter exp. For a
/// floating-point value of zero, the significant and exponent
/// are both zero. For a floating-point value that is an
/// infinity or is not a number, the results are undefined.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/frexp.xml">GLSL frexp man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType, typename genIType>
GLM_FUNC_DECL genType frexp(genType const & x, genIType & exp);
/// Builds a floating-point number from x and the
/// corresponding integral exponent of two in exp, returning:
/// significand * exp(2, exponent)
///
/// If this product is too large to be represented in the
/// floating-point type, the result is undefined.
///
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ldexp.xml">GLSL ldexp man page</a>;
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
template <typename genType, typename genIType>
GLM_FUNC_DECL genType ldexp(genType const & x, genIType const & exp);
/// @}
}//namespace glm
#include "func_common.inl"
+758
View File
@@ -0,0 +1,758 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/func_common.inl
/// @date 2008-08-03 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
#include "func_vector_relational.hpp"
#include "type_vec2.hpp"
#include "type_vec3.hpp"
#include "type_vec4.hpp"
#include "_vectorize.hpp"
#include <limits>
namespace glm{
namespace detail
{
template <typename genFIType, bool /*signed*/>
struct compute_abs
{};
template <typename genFIType>
struct compute_abs<genFIType, true>
{
GLM_FUNC_QUALIFIER static genFIType call(genFIType x)
{
GLM_STATIC_ASSERT(
std::numeric_limits<genFIType>::is_iec559 || std::numeric_limits<genFIType>::is_signed,
"'abs' only accept floating-point and integer scalar or vector inputs");
return x >= genFIType(0) ? x : -x;
// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
}
};
template <typename genFIType>
struct compute_abs<genFIType, false>
{
GLM_FUNC_QUALIFIER static genFIType call(genFIType x)
{
GLM_STATIC_ASSERT(
!std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
"'abs' only accept floating-point and integer scalar or vector inputs");
return x;
}
};
template <typename T, typename U, precision P, template <class, precision> class vecType>
struct compute_mix_vector
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x, vecType<T, P> const & y, vecType<U, P> const & a)
{
GLM_STATIC_ASSERT(std::numeric_limits<U>::is_iec559, "'mix' only accept floating-point inputs for the interpolator a");
return vecType<T, P>(vecType<U, P>(x) + a * vecType<U, P>(y - x));
}
};
template <typename T, precision P, template <class, precision> class vecType>
struct compute_mix_vector<T, bool, P, vecType>
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x, vecType<T, P> const & y, vecType<bool, P> const & a)
{
vecType<T, P> Result(uninitialize);
for(detail::component_count_t i = 0; i < detail::component_count(x); ++i)
Result[i] = a[i] ? y[i] : x[i];
return Result;
}
};
template <typename T, typename U, precision P, template <class, precision> class vecType>
struct compute_mix_scalar
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x, vecType<T, P> const & y, U const & a)
{
GLM_STATIC_ASSERT(std::numeric_limits<U>::is_iec559, "'mix' only accept floating-point inputs for the interpolator a");
return vecType<T, P>(vecType<U, P>(x) + a * vecType<U, P>(y - x));
}
};
template <typename T, precision P, template <class, precision> class vecType>
struct compute_mix_scalar<T, bool, P, vecType>
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x, vecType<T, P> const & y, bool const & a)
{
return a ? y : x;
}
};
template <typename T, typename U>
struct compute_mix
{
GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, U const & a)
{
GLM_STATIC_ASSERT(std::numeric_limits<U>::is_iec559, "'mix' only accept floating-point inputs for the interpolator a");
return static_cast<T>(static_cast<U>(x) + a * static_cast<U>(y - x));
}
};
template <typename T>
struct compute_mix<T, bool>
{
GLM_FUNC_QUALIFIER static T call(T const & x, T const & y, bool const & a)
{
return a ? y : x;
}
};
template <typename T, precision P, template <class, precision> class vecType, bool isFloat = true, bool isSigned = true>
struct compute_sign
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x)
{
return vecType<T, P>(glm::lessThan(vecType<T, P>(0), x)) - vecType<T, P>(glm::lessThan(x, vecType<T, P>(0)));
}
};
template <typename T, precision P, template <class, precision> class vecType>
struct compute_sign<T, P, vecType, false, false>
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x)
{
return vecType<T, P>(glm::greaterThan(x , vecType<T, P>(0)));
}
};
template <typename T, precision P, template <class, precision> class vecType>
struct compute_sign<T, P, vecType, false, true>
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & x)
{
T const Shift(static_cast<T>(sizeof(T) * 8 - 1));
vecType<T, P> const y(vecType<typename make_unsigned<T>::type, P>(-x) >> typename make_unsigned<T>::type(Shift));
return (x >> Shift) | y;
}
};
template <typename T, precision P, template <class, precision> class vecType, typename genType, bool isFloat = true>
struct compute_mod
{
GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & a, genType const & b)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'mod' only accept floating-point inputs. Include <glm/gtc/integer.hpp> for integer inputs.");
return a - b * floor(a / b);
}
};
}//namespace detail
// abs
template <>
GLM_FUNC_QUALIFIER int32 abs(int32 x)
{
int32 const y = x >> 31;
return (x ^ y) - y;
}
template <typename genFIType>
GLM_FUNC_QUALIFIER genFIType abs(genFIType x)
{
return detail::compute_abs<genFIType, std::numeric_limits<genFIType>::is_signed>::call(x);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> abs(vecType<T, P> const & x)
{
return detail::functor1<T, T, P, vecType>::call(abs, x);
}
// sign
// fast and works for any type
template <typename genFIType>
GLM_FUNC_QUALIFIER genFIType sign(genFIType x)
{
GLM_STATIC_ASSERT(
std::numeric_limits<genFIType>::is_iec559 || (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer),
"'sign' only accept signed inputs");
return detail::compute_sign<genFIType, defaultp, tvec1, std::numeric_limits<genFIType>::is_iec559>::call(tvec1<genFIType>(x)).x;
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> sign(vecType<T, P> const & x)
{
GLM_STATIC_ASSERT(
std::numeric_limits<T>::is_iec559 || (std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_integer),
"'sign' only accept signed inputs");
return detail::compute_sign<T, P, vecType, std::numeric_limits<T>::is_iec559>::call(x);
}
// floor
using ::std::floor;
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> floor(vecType<T, P> const & x)
{
return detail::functor1<T, T, P, vecType>::call(floor, x);
}
// trunc
# if GLM_HAS_CXX11_STL
using ::std::trunc;
# else
template <typename genType>
GLM_FUNC_QUALIFIER genType trunc(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'trunc' only accept floating-point inputs");
return x < static_cast<genType>(0) ? -floor(-x) : floor(x);
}
# endif
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> trunc(vecType<T, P> const & x)
{
return detail::functor1<T, T, P, vecType>::call(trunc, x);
}
// round
# if GLM_HAS_CXX11_STL
using ::std::round;
# else
template <typename genType>
GLM_FUNC_QUALIFIER genType round(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'round' only accept floating-point inputs");
return x < static_cast<genType>(0) ? static_cast<genType>(int(x - static_cast<genType>(0.5))) : static_cast<genType>(int(x + static_cast<genType>(0.5)));
}
# endif
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> round(vecType<T, P> const & x)
{
return detail::functor1<T, T, P, vecType>::call(round, x);
}
/*
// roundEven
template <typename genType>
GLM_FUNC_QUALIFIER genType roundEven(genType const& x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'roundEven' only accept floating-point inputs");
return genType(int(x + genType(int(x) % 2)));
}
*/
// roundEven
template <typename genType>
GLM_FUNC_QUALIFIER genType roundEven(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'roundEven' only accept floating-point inputs");
int Integer = static_cast<int>(x);
genType IntegerPart = static_cast<genType>(Integer);
genType FractionalPart = fract(x);
if(FractionalPart > static_cast<genType>(0.5) || FractionalPart < static_cast<genType>(0.5))
{
return round(x);
}
else if((Integer % 2) == 0)
{
return IntegerPart;
}
else if(x <= static_cast<genType>(0)) // Work around...
{
return IntegerPart - static_cast<genType>(1);
}
else
{
return IntegerPart + static_cast<genType>(1);
}
//else // Bug on MinGW 4.5.2
//{
// return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0));
//}
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> roundEven(vecType<T, P> const & x)
{
return detail::functor1<T, T, P, vecType>::call(roundEven, x);
}
// ceil
using ::std::ceil;
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> ceil(vecType<T, P> const & x)
{
return detail::functor1<T, T, P, vecType>::call(ceil, x);
}
// fract
template <typename genType>
GLM_FUNC_QUALIFIER genType fract(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'fract' only accept floating-point inputs");
return fract(tvec1<genType>(x)).x;
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> fract(vecType<T, P> const & x)
{
return x - floor(x);
}
// mod
template <typename genType>
GLM_FUNC_QUALIFIER genType mod(genType x, genType y)
{
return mod(tvec1<genType>(x), y).x;
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> mod(vecType<T, P> const & x, T y)
{
return detail::compute_mod<T, P, vecType, T, std::numeric_limits<T>::is_iec559>::call(x, y);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> mod(vecType<T, P> const & x, vecType<T, P> const & y)
{
return detail::compute_mod<T, P, vecType, vecType<T, P>, std::numeric_limits<T>::is_iec559>::call(x, y);
}
// modf
template <typename genType>
GLM_FUNC_QUALIFIER genType modf(genType x, genType & i)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'modf' only accept floating-point inputs");
return std::modf(x, &i);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec1<T, P> modf(tvec1<T, P> const & x, tvec1<T, P> & i)
{
return tvec1<T, P>(
modf(x.x, i.x));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec2<T, P> modf(tvec2<T, P> const & x, tvec2<T, P> & i)
{
return tvec2<T, P>(
modf(x.x, i.x),
modf(x.y, i.y));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> modf(tvec3<T, P> const & x, tvec3<T, P> & i)
{
return tvec3<T, P>(
modf(x.x, i.x),
modf(x.y, i.y),
modf(x.z, i.z));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> modf(tvec4<T, P> const & x, tvec4<T, P> & i)
{
return tvec4<T, P>(
modf(x.x, i.x),
modf(x.y, i.y),
modf(x.z, i.z),
modf(x.w, i.w));
}
//// Only valid if (INT_MIN <= x-y <= INT_MAX)
//// min(x,y)
//r = y + ((x - y) & ((x - y) >> (sizeof(int) *
//CHAR_BIT - 1)));
//// max(x,y)
//r = x - ((x - y) & ((x - y) >> (sizeof(int) *
//CHAR_BIT - 1)));
// min
template <typename genType>
GLM_FUNC_QUALIFIER genType min(genType x, genType y)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || std::numeric_limits<genType>::is_integer, "'min' only accept floating-point or integer inputs");
return x < y ? x : y;
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> min(vecType<T, P> const & a, T b)
{
return detail::functor2_vec_sca<T, P, vecType>::call(min, a, b);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> min(vecType<T, P> const & a, vecType<T, P> const & b)
{
return detail::functor2<T, P, vecType>::call(min, a, b);
}
// max
template <typename genType>
GLM_FUNC_QUALIFIER genType max(genType x, genType y)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || std::numeric_limits<genType>::is_integer, "'max' only accept floating-point or integer inputs");
return x > y ? x : y;
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> max(vecType<T, P> const & a, T b)
{
return detail::functor2_vec_sca<T, P, vecType>::call(max, a, b);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> max(vecType<T, P> const & a, vecType<T, P> const & b)
{
return detail::functor2<T, P, vecType>::call(max, a, b);
}
// clamp
template <typename genType>
GLM_FUNC_QUALIFIER genType clamp(genType x, genType minVal, genType maxVal)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559 || std::numeric_limits<genType>::is_integer, "'clamp' only accept floating-point or integer inputs");
return min(max(x, minVal), maxVal);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> clamp(vecType<T, P> const & x, T minVal, T maxVal)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || std::numeric_limits<T>::is_integer, "'clamp' only accept floating-point or integer inputs");
return min(max(x, minVal), maxVal);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> clamp(vecType<T, P> const & x, vecType<T, P> const & minVal, vecType<T, P> const & maxVal)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559 || std::numeric_limits<T>::is_integer, "'clamp' only accept floating-point or integer inputs");
return min(max(x, minVal), maxVal);
}
template <typename genTypeT, typename genTypeU>
GLM_FUNC_QUALIFIER genTypeT mix(genTypeT x, genTypeT y, genTypeU a)
{
return detail::compute_mix<genTypeT, genTypeU>::call(x, y, a);
}
template <typename T, typename U, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> mix(vecType<T, P> const & x, vecType<T, P> const & y, U a)
{
return detail::compute_mix_scalar<T, U, P, vecType>::call(x, y, a);
}
template <typename T, typename U, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> mix(vecType<T, P> const & x, vecType<T, P> const & y, vecType<U, P> const & a)
{
return detail::compute_mix_vector<T, U, P, vecType>::call(x, y, a);
}
// step
template <typename genType>
GLM_FUNC_QUALIFIER genType step(genType edge, genType x)
{
return mix(static_cast<genType>(1), static_cast<genType>(0), glm::lessThan(x, edge));
}
template <template <typename, precision> class vecType, typename T, precision P>
GLM_FUNC_QUALIFIER vecType<T, P> step(T edge, vecType<T, P> const & x)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'step' only accept floating-point inputs");
return mix(vecType<T, P>(1), vecType<T, P>(0), glm::lessThan(x, vecType<T, P>(edge)));
}
template <template <typename, precision> class vecType, typename T, precision P>
GLM_FUNC_QUALIFIER vecType<T, P> step(vecType<T, P> const & edge, vecType<T, P> const & x)
{
return mix(vecType<T, P>(1), vecType<T, P>(0), glm::lessThan(x, edge));
}
// smoothstep
template <typename genType>
GLM_FUNC_QUALIFIER genType smoothstep(genType edge0, genType edge1, genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'smoothstep' only accept floating-point inputs");
genType const tmp(clamp((x - edge0) / (edge1 - edge0), genType(0), genType(1)));
return tmp * tmp * (genType(3) - genType(2) * tmp);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> smoothstep(T edge0, T edge1, vecType<T, P> const & x)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'smoothstep' only accept floating-point inputs");
vecType<T, P> const tmp(clamp((x - edge0) / (edge1 - edge0), static_cast<T>(0), static_cast<T>(1)));
return tmp * tmp * (static_cast<T>(3) - static_cast<T>(2) * tmp);
}
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<T, P> smoothstep(vecType<T, P> const & edge0, vecType<T, P> const & edge1, vecType<T, P> const & x)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'smoothstep' only accept floating-point inputs");
vecType<T, P> const tmp(clamp((x - edge0) / (edge1 - edge0), static_cast<T>(0), static_cast<T>(1)));
return tmp * tmp * (static_cast<T>(3) - static_cast<T>(2) * tmp);
}
# if GLM_HAS_CXX11_STL
using std::isnan;
# else
template <typename genType>
GLM_FUNC_QUALIFIER bool isnan(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'isnan' only accept floating-point inputs");
# if GLM_HAS_CXX11_STL
return std::isnan(x);
# elif GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_INTEL)
return _isnan(x) != 0;
# elif GLM_COMPILER & (GLM_COMPILER_GCC | (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM))
# if GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L
return _isnan(x) != 0;
# else
return std::isnan(x);
# endif
# elif GLM_COMPILER & GLM_COMPILER_CUDA
return isnan(x) != 0;
# else
return std::isnan(x);
# endif
}
# endif
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<bool, P> isnan(vecType<T, P> const & x)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isnan' only accept floating-point inputs");
return detail::functor1<bool, T, P, vecType>::call(isnan, x);
}
# if GLM_HAS_CXX11_STL
using std::isinf;
# else
template <typename genType>
GLM_FUNC_QUALIFIER bool isinf(genType x)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'isinf' only accept floating-point inputs");
# if GLM_HAS_CXX11_STL
return std::isinf(x);
# elif GLM_COMPILER & (GLM_COMPILER_INTEL | GLM_COMPILER_VC)
return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
# elif GLM_COMPILER & (GLM_COMPILER_GCC | (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM))
# if(GLM_PLATFORM & GLM_PLATFORM_ANDROID && __cplusplus < 201103L)
return _isinf(x) != 0;
# else
return std::isinf(x);
# endif
# elif GLM_COMPILER & GLM_COMPILER_CUDA
// http://developer.download.nvidia.com/compute/cuda/4_2/rel/toolkit/docs/online/group__CUDA__MATH__DOUBLE_g13431dd2b40b51f9139cbb7f50c18fab.html#g13431dd2b40b51f9139cbb7f50c18fab
return isinf(double(x)) != 0;
# else
return std::isinf(x);
# endif
}
# endif
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<bool, P> isinf(vecType<T, P> const & x)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isnan' only accept floating-point inputs");
return detail::functor1<bool, T, P, vecType>::call(isinf, x);
}
GLM_FUNC_QUALIFIER int floatBitsToInt(float const & v)
{
return reinterpret_cast<int&>(const_cast<float&>(v));
}
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_QUALIFIER vecType<int, P> floatBitsToInt(vecType<float, P> const & v)
{
return reinterpret_cast<vecType<int, P>&>(const_cast<vecType<float, P>&>(v));
}
GLM_FUNC_QUALIFIER uint floatBitsToUint(float const & v)
{
return reinterpret_cast<uint&>(const_cast<float&>(v));
}
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_QUALIFIER vecType<uint, P> floatBitsToUint(vecType<float, P> const & v)
{
return reinterpret_cast<vecType<uint, P>&>(const_cast<vecType<float, P>&>(v));
}
GLM_FUNC_QUALIFIER float intBitsToFloat(int const & v)
{
return reinterpret_cast<float&>(const_cast<int&>(v));
}
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_QUALIFIER vecType<float, P> intBitsToFloat(vecType<int, P> const & v)
{
return reinterpret_cast<vecType<float, P>&>(const_cast<vecType<int, P>&>(v));
}
GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const & v)
{
return reinterpret_cast<float&>(const_cast<uint&>(v));
}
template <template <typename, precision> class vecType, precision P>
GLM_FUNC_QUALIFIER vecType<float, P> uintBitsToFloat(vecType<uint, P> const & v)
{
return reinterpret_cast<vecType<float, P>&>(const_cast<vecType<uint, P>&>(v));
}
template <typename genType>
GLM_FUNC_QUALIFIER genType fma(genType const & a, genType const & b, genType const & c)
{
return a * b + c;
}
template <typename genType>
GLM_FUNC_QUALIFIER genType frexp(genType x, int & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'frexp' only accept floating-point inputs");
return std::frexp(x, exp);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec1<T, P> frexp(tvec1<T, P> const & x, tvec1<int, P> & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'frexp' only accept floating-point inputs");
return tvec1<T, P>(std::frexp(x.x, exp.x));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec2<T, P> frexp(tvec2<T, P> const & x, tvec2<int, P> & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'frexp' only accept floating-point inputs");
return tvec2<T, P>(
frexp(x.x, exp.x),
frexp(x.y, exp.y));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> frexp(tvec3<T, P> const & x, tvec3<int, P> & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'frexp' only accept floating-point inputs");
return tvec3<T, P>(
frexp(x.x, exp.x),
frexp(x.y, exp.y),
frexp(x.z, exp.z));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> frexp(tvec4<T, P> const & x, tvec4<int, P> & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'frexp' only accept floating-point inputs");
return tvec4<T, P>(
frexp(x.x, exp.x),
frexp(x.y, exp.y),
frexp(x.z, exp.z),
frexp(x.w, exp.w));
}
template <typename genType, precision P>
GLM_FUNC_QUALIFIER genType ldexp(genType const & x, int const & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'ldexp' only accept floating-point inputs");
return std::ldexp(x, exp);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec1<T, P> ldexp(tvec1<T, P> const & x, tvec1<int, P> const & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'ldexp' only accept floating-point inputs");
return tvec1<T, P>(
ldexp(x.x, exp.x));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec2<T, P> ldexp(tvec2<T, P> const & x, tvec2<int, P> const & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'ldexp' only accept floating-point inputs");
return tvec2<T, P>(
ldexp(x.x, exp.x),
ldexp(x.y, exp.y));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> ldexp(tvec3<T, P> const & x, tvec3<int, P> const & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'ldexp' only accept floating-point inputs");
return tvec3<T, P>(
ldexp(x.x, exp.x),
ldexp(x.y, exp.y),
ldexp(x.z, exp.z));
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> ldexp(tvec4<T, P> const & x, tvec4<int, P> const & exp)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'ldexp' only accept floating-point inputs");
return tvec4<T, P>(
ldexp(x.x, exp.x),
ldexp(x.y, exp.y),
ldexp(x.z, exp.z),
ldexp(x.w, exp.w));
}
}//namespace glm
+132
View File
@@ -0,0 +1,132 @@
///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/func_exponential.hpp
/// @date 2008-08-08 / 2011-06-14
/// @author Christophe Riccio
///
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
///
/// @defgroup core_func_exponential Exponential functions
/// @ingroup core
///
/// These all operate component-wise. The description is per component.
///////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "type_vec1.hpp"
#include "type_vec2.hpp"
#include "type_vec3.hpp"
#include "type_vec4.hpp"
#include <cmath>
namespace glm
{
/// @addtogroup core_func_exponential
/// @{
/// Returns 'base' raised to the power 'exponent'.
///
/// @param base Floating point value. pow function is defined for input values of 'base' defined in the range (inf-, inf+) in the limit of the type precision.
/// @param exponent Floating point value representing the 'exponent'.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/pow.xml">GLSL pow man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> pow(vecType<T, P> const & base, vecType<T, P> const & exponent);
/// Returns the natural exponentiation of x, i.e., e^x.
///
/// @param v exp function is defined for input values of v defined in the range (inf-, inf+) in the limit of the type precision.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp.xml">GLSL exp man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> exp(vecType<T, P> const & v);
/// Returns the natural logarithm of v, i.e.,
/// returns the value y which satisfies the equation x = e^y.
/// Results are undefined if v <= 0.
///
/// @param v log function is defined for input values of v defined in the range (0, inf+) in the limit of the type precision.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log.xml">GLSL log man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> log(vecType<T, P> const & v);
/// Returns 2 raised to the v power.
///
/// @param v exp2 function is defined for input values of v defined in the range (inf-, inf+) in the limit of the type precision.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp2.xml">GLSL exp2 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> exp2(vecType<T, P> const & v);
/// Returns the base 2 log of x, i.e., returns the value y,
/// which satisfies the equation x = 2 ^ y.
///
/// @param v log2 function is defined for input values of v defined in the range (0, inf+) in the limit of the type precision.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log2.xml">GLSL log2 man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> log2(vecType<T, P> const & v);
/// Returns the positive square root of v.
///
/// @param v sqrt function is defined for input values of v defined in the range [0, inf+) in the limit of the type precision.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sqrt.xml">GLSL sqrt man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
//template <typename genType>
//GLM_FUNC_DECL genType sqrt(genType const & x);
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> sqrt(vecType<T, P> const & v);
/// Returns the reciprocal of the positive square root of v.
///
/// @param v inversesqrt function is defined for input values of v defined in the range [0, inf+) in the limit of the type precision.
/// @tparam genType Floating-point scalar or vector types.
///
/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inversesqrt.xml">GLSL inversesqrt man page</a>
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
template <typename T, precision P, template <typename, precision> class vecType>
GLM_FUNC_DECL vecType<T, P> inversesqrt(vecType<T, P> const & v);
/// @}
}//namespace glm
#include "func_exponential.inl"

Some files were not shown because too many files have changed in this diff Show More