Merge branch 'build' into feature/remove_boost

This commit is contained in:
Alex 2019-09-27 16:32:13 -07:00 committed by GitHub
commit 895c8626b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2754 changed files with 66424 additions and 490313 deletions

17
.gitignore vendored
View File

@ -23,21 +23,14 @@ CMakeFiles
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt
Build/ [Bb]uild*/
build/
Build32/
build32/
Build64/
build64/
Build_32/
build_32/
Build_64/
build_64/
x64/
x86/
log/ log/
logs/ logs/
vcpkg/ vcpkg/
perl/
.idea/* .idea/*
*cbp *cbp
submodules/*
cmake-build-debug/

18
.gitmodules vendored Normal file
View File

@ -0,0 +1,18 @@
[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

64
BUILD.md Normal file
View File

@ -0,0 +1,64 @@
# 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

View File

@ -1,122 +1,28 @@
#EQEmu CMake CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
#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_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
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
IF(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
ENDIF()
#FindMySQL is located here so lets make it so CMake can find it
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH}) SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
#Our project name is EQEmu IF(POLICY CMP0074)
CMAKE_POLICY(SET CMP0074 NEW)
ENDIF()
PROJECT(EQEmu) PROJECT(EQEmu)
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
IF(NOT CMAKE_BUILD_TYPE) IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE) ENDIF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}") SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
#Add our various windows definitions SET(CMAKE_CXX_EXTENSIONS OFF)
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) IF(MSVC)
IF(CMAKE_CL_64) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
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")
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x64")
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
IF(MSVC_VERSION GREATER 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v140/dynamic")
ELSEIF(MSVC_VERSION EQUAL 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v120/dynamic")
ELSE()
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v110/dynamic")
ENDIF()
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")
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x86")
IF(MSVC_VERSION GREATER 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v140/dynamic")
ELSEIF(MSVC_VERSION EQUAL 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v120/dynamic")
ELSE()
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v110/dynamic")
ENDIF()
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)
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(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ELSE(MSVC) ELSE(MSVC)
#Normally set by perl but we don't use the perl flags anymore so we set it.
ADD_DEFINITIONS(-DHAS_UNION_SEMUN) ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC) ENDIF(MSVC)
@ -133,179 +39,276 @@ IF(UNIX)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin") ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF(UNIX) ENDIF(UNIX)
#debug level, 5 is default. Most people wont ever change this but it's there if you want to ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level: ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
0 - Quiet mode Errors to file Status and Normal ignored ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
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"
)
SET(EQEMU_LOG_LEVEL_STATUS 2 CACHE STRING "EQEmu logging level for [Status]: #MSVC can fetch dependencies automatically.
0 - Disabled IF(MSVC)
1 - Ouput to File Enabled INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
2 - Output to stdout Enabled ENDIF()
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"
)
SET(EQEMU_LOG_LEVEL_NORMAL 3 CACHE STRING "EQEmu logging level for [Normal]: #Find everything we need
0 - Disabled FIND_PACKAGE(MySQL)
1 - Ouput to File Enabled FIND_PACKAGE(MariaDB)
2 - Output to stdout Enabled FIND_PACKAGE(ZLIB)
3 - Output to File and stdout Enabled FIND_PACKAGE(OpenSSL)
8 - Output to stderr Enabled FIND_PACKAGE(Lua51)
9 - Output to File and stderr Enabled FIND_PACKAGE(PerlLibs)
11 - Output to File, stdout and stderr Enabled" FIND_PACKAGE(Sodium)
) FIND_PACKAGE(mbedTLS)
SET(EQEMU_LOG_LEVEL_ERROR 2 CACHE STRING "EQEmu logging level for [Error]: MESSAGE(STATUS "**************************************************")
0 - Disabled MESSAGE(STATUS "* Library Detection *")
1 - Ouput to File Enabled MESSAGE(STATUS "**************************************************")
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"
)
SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]: IF(MYSQL_FOUND)
0 - Disabled MESSAGE(STATUS "* MySQL: FOUND *")
1 - Ouput to File Enabled ELSE()
2 - Output to stdout Enabled MESSAGE(STATUS "* MySQL: MISSING *")
3 - Output to File and stdout Enabled ENDIF()
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
SET(EQEMU_LOG_LEVEL_QUEST 2 CACHE STRING "EQEmu logging level for [Quest]: IF(MARIADB_FOUND)
0 - Disabled MESSAGE(STATUS "* MariaDB: FOUND *")
1 - Ouput to File Enabled ELSE()
2 - Output to stdout Enabled MESSAGE(STATUS "* MariaDB: MISSING *")
3 - Output to File and stdout Enabled ENDIF()
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
SET(EQEMU_LOG_LEVEL_COMMANDS 1 CACHE STRING "EQEmu logging level for [Commands]: IF(ZLIB_FOUND)
0 - Disabled MESSAGE(STATUS "* ZLIB: FOUND *")
1 - Ouput to File Enabled ELSE()
2 - Output to stdout Enabled MESSAGE(STATUS "* ZLIB: MISSING *")
3 - Output to File and stdout Enabled ENDIF()
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]: IF(Lua51_FOUND)
0 - Disabled MESSAGE(STATUS "* Lua: FOUND *")
1 - Ouput to File Enabled ELSE()
2 - Output to stdout Enabled MESSAGE(STATUS "* Lua: MISSING *")
3 - Output to File and stdout Enabled ENDIF()
8 - Output to stderr Enabled
9 - Output to File and stderr Enabled
11 - Output to File, stdout and stderr Enabled"
)
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(PerlLibs_FOUND)
MESSAGE(STATUS "* Perl: FOUND *")
ELSE()
MESSAGE(STATUS "* Perl: MISSING *")
ENDIF()
#NPC Types Cache Behavior IF(SODIUM_FOUND)
MESSAGE(STATUS "* libsodium: FOUND *")
ELSE()
MESSAGE(STATUS "* libsodium: MISSING *")
ENDIF()
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
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON) 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) 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_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) IF(EQEMU_COMMANDS_LOGGING)
ADD_DEFINITIONS(-DCOMMANDS_LOGGING) ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
ENDIF(EQEMU_COMMANDS_LOGGING) ENDIF(EQEMU_COMMANDS_LOGGING)
IF(EQEMU_DISABLE_LOGSYS)
ADD_DEFINITIONS(-DDISABLE_LOGSYS)
ENDIF(EQEMU_DISABLE_LOGSYS)
IF(EQEMU_ENABLE_BOTS) IF(EQEMU_ENABLE_BOTS)
ADD_DEFINITIONS(-DBOTS) ADD_DEFINITIONS(-DBOTS)
ENDIF(EQEMU_ENABLE_BOTS) ENDIF(EQEMU_ENABLE_BOTS)
#What to build #database
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON) IF(MySQL_FOUND AND MariaDB_FOUND)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF) SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use:
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF) MySQL
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF) MariaDB"
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(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
IF(NOT MSVC) SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal") 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")
ENDIF() ENDIF()
ENDIF(NOT MSVC) 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()
#Various definitions #security
IF(EQEMU_BUILD_PERL) #prefer openssl to mbedtls (arbitrary)
ADD_DEFINITIONS(-DEMBPERL) IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN) SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
ENDIF(EQEMU_BUILD_PERL) OpenSSL
IF(EQEMU_BUILD_LUA) mbedTLS"
ADD_DEFINITIONS(-DLUA_EQEMU) )
ENDIF(EQEMU_BUILD_LUA)
#Disabled until reevaluation performed IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
#OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF) SET(TLS_LIBRARY_TYPE " OpenSSL")
#IF(EQEMU_USE_MAP_MMFS) SET(TLS_LIBRARY_ENABLED ON)
# ADD_DEFINITIONS(-DUSE_MAP_MMFS) SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
#ENDIF(EQEMU_USE_MAP_MMFS) 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()
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
ADD_DEFINITIONS(-DINVERSEXY)
ADD_DEFINITIONS(-DFIELD_ITEMS)
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
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)
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
#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)
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt recast_navigation)
FIND_PACKAGE(Sodium REQUIRED)
IF(SODIUM_FOUND) IF(SODIUM_FOUND)
OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON) SET(SODIUM_LIBRARY_TYPE "Libsodium")
IF(EQEMU_ENABLE_SECURITY) SET(SODIUM_LIBRARY_ENABLED ON)
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}") SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
ADD_DEFINITIONS(-DENABLE_SECURITY) SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES}) ADD_DEFINITIONS(-DENABLE_SECURITY)
ELSE()
SET(SODIUM_LIBRARY_TYPE " Disabled")
SET(SODIUM_LIBRARY_ENABLED OFF)
ENDIF()
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()
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()
#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()
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 "**************************************************")
#setup server libs and headers
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} uv_a fmt RecastNavigation::Detour)
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
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")
IF(TLS_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
ENDIF()
IF(SODIUM_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
ENDIF()
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()
ENDIF() ENDIF()
@ -321,31 +324,32 @@ IF(UNIX)
SET(SERVER_LIBS ${SERVER_LIBS} "uuid") SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
ENDIF() ENDIF()
IF(EQEMU_BUILD_LUA) IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
FIND_PACKAGE(EQLua51 REQUIRED) MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}") ENDIF()
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON) IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
IF(EQEMU_SANITIZE_LUA_LIBS) MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS) ENDIF()
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
ENDIF(EQEMU_BUILD_LUA)
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/cereal")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/src")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/format")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/recast/detour/include")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/recast/recast/include")
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 OR EQEMU_BUILD_HC)
ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(libs) 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 OR EQEMU_BUILD_HC)
IF(EQEMU_BUILD_SERVER) IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory) ADD_SUBDIRECTORY(shared_memory)
ADD_SUBDIRECTORY(world) ADD_SUBDIRECTORY(world)
@ -354,6 +358,7 @@ IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(queryserv) ADD_SUBDIRECTORY(queryserv)
ADD_SUBDIRECTORY(eqlaunch) ADD_SUBDIRECTORY(eqlaunch)
ENDIF(EQEMU_BUILD_SERVER) ENDIF(EQEMU_BUILD_SERVER)
IF(EQEMU_BUILD_LOGIN) IF(EQEMU_BUILD_LOGIN)
ADD_SUBDIRECTORY(loginserver) ADD_SUBDIRECTORY(loginserver)
ENDIF(EQEMU_BUILD_LOGIN) ENDIF(EQEMU_BUILD_LOGIN)

View File

@ -70,3 +70,9 @@ forum, although pull requests will be much quicker and easier on all parties.
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project) * GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
* CPPUnit - GLP StringUtilities - Apache * CPPUnit - GLP StringUtilities - Apache
* LUA - MIT * LUA - MIT
## Contributors
<a href="https://github.com/EQEmu/server/graphs/contributors">
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
</a>

3
SECURITY.md Normal file
View File

@ -0,0 +1,3 @@
# 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

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
add_subdirectory(import) add_subdirectory(import)
add_subdirectory(export) add_subdirectory(export)

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(export_sources SET(export_sources
main.cpp main.cpp

View File

@ -39,20 +39,19 @@ int main(int argc, char **argv) {
LogSys.LoadLogSettingsDefaults(); LogSys.LoadLogSettingsDefaults();
set_exception_handler(); set_exception_handler();
Log(Logs::General, Logs::Status, "Client Files Export Utility"); LogInfo("Client Files Export Utility");
if(!EQEmuConfig::LoadConfig()) { if(!EQEmuConfig::LoadConfig()) {
Log(Logs::General, Logs::Error, "Unable to load configuration file."); LogError("Unable to load configuration file");
return 1; return 1;
} }
auto Config = EQEmuConfig::get(); auto Config = EQEmuConfig::get();
SharedDatabase database; SharedDatabase database;
Log(Logs::General, Logs::Status, "Connecting to database..."); LogInfo("Connecting to database");
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(), if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) { Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " LogError("Unable to connect to the database, cannot continue without a database connection");
"database connection");
return 1; return 1;
} }
@ -60,6 +59,29 @@ int main(int argc, char **argv) {
database.LoadLogSettings(LogSys.log_settings); database.LoadLogSettings(LogSys.log_settings);
LogSys.StartFileLogs(); 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;
}
ExportSpells(&database); ExportSpells(&database);
ExportSkillCaps(&database); ExportSkillCaps(&database);
ExportBaseData(&database); ExportBaseData(&database);
@ -71,11 +93,11 @@ int main(int argc, char **argv) {
} }
void ExportSpells(SharedDatabase *db) { void ExportSpells(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Exporting Spells..."); LogInfo("Exporting Spells");
FILE *f = fopen("export/spells_us.txt", "w"); FILE *f = fopen("export/spells_us.txt", "w");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping."); LogError("Unable to open export/spells_us.txt to write, skipping.");
return; return;
} }
@ -142,11 +164,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
} }
void ExportSkillCaps(SharedDatabase *db) { void ExportSkillCaps(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Exporting Skill Caps..."); LogInfo("Exporting Skill Caps");
FILE *f = fopen("export/SkillCaps.txt", "w"); FILE *f = fopen("export/SkillCaps.txt", "w");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping."); LogError("Unable to open export/SkillCaps.txt to write, skipping.");
return; return;
} }
@ -171,11 +193,11 @@ void ExportSkillCaps(SharedDatabase *db) {
} }
void ExportBaseData(SharedDatabase *db) { void ExportBaseData(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Exporting Base Data..."); LogInfo("Exporting Base Data");
FILE *f = fopen("export/BaseData.txt", "w"); FILE *f = fopen("export/BaseData.txt", "w");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping."); LogError("Unable to open export/BaseData.txt to write, skipping.");
return; return;
} }
@ -202,11 +224,11 @@ void ExportBaseData(SharedDatabase *db) {
} }
void ExportDBStrings(SharedDatabase *db) { void ExportDBStrings(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Exporting DB Strings..."); LogInfo("Exporting DB Strings");
FILE *f = fopen("export/dbstr_us.txt", "w"); FILE *f = fopen("export/dbstr_us.txt", "w");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping."); LogError("Unable to open export/dbstr_us.txt to write, skipping.");
return; return;
} }

View File

@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(import_sources SET(import_sources
main.cpp main.cpp

View File

@ -37,19 +37,19 @@ int main(int argc, char **argv) {
LogSys.LoadLogSettingsDefaults(); LogSys.LoadLogSettingsDefaults();
set_exception_handler(); set_exception_handler();
Log(Logs::General, Logs::Status, "Client Files Import Utility"); LogInfo("Client Files Import Utility");
if(!EQEmuConfig::LoadConfig()) { if(!EQEmuConfig::LoadConfig()) {
Log(Logs::General, Logs::Error, "Unable to load configuration file."); LogError("Unable to load configuration file.");
return 1; return 1;
} }
auto Config = EQEmuConfig::get(); auto Config = EQEmuConfig::get();
SharedDatabase database; SharedDatabase database;
Log(Logs::General, Logs::Status, "Connecting to database..."); LogInfo("Connecting to database");
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(), if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) { Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " LogError("Unable to connect to the database, cannot continue without a "
"database connection"); "database connection");
return 1; return 1;
} }
@ -97,10 +97,10 @@ bool IsStringField(int i) {
} }
void ImportSpells(SharedDatabase *db) { void ImportSpells(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Importing Spells..."); LogInfo("Importing Spells");
FILE *f = fopen("import/spells_us.txt", "r"); FILE *f = fopen("import/spells_us.txt", "r");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping."); LogError("Unable to open import/spells_us.txt to read, skipping.");
return; return;
} }
@ -173,23 +173,23 @@ void ImportSpells(SharedDatabase *db) {
spells_imported++; spells_imported++;
if(spells_imported % 1000 == 0) { if(spells_imported % 1000 == 0) {
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported); LogInfo("[{}] spells imported", spells_imported);
} }
} }
if(spells_imported % 1000 != 0) { if(spells_imported % 1000 != 0) {
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported); LogInfo("[{}] spells imported", spells_imported);
} }
fclose(f); fclose(f);
} }
void ImportSkillCaps(SharedDatabase *db) { void ImportSkillCaps(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Importing Skill Caps..."); LogInfo("Importing Skill Caps");
FILE *f = fopen("import/SkillCaps.txt", "r"); FILE *f = fopen("import/SkillCaps.txt", "r");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping."); LogError("Unable to open import/SkillCaps.txt to read, skipping.");
return; return;
} }
@ -220,11 +220,11 @@ void ImportSkillCaps(SharedDatabase *db) {
} }
void ImportBaseData(SharedDatabase *db) { void ImportBaseData(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Importing Base Data..."); LogInfo("Importing Base Data");
FILE *f = fopen("import/BaseData.txt", "r"); FILE *f = fopen("import/BaseData.txt", "r");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping."); LogError("Unable to open import/BaseData.txt to read, skipping.");
return; return;
} }
@ -265,11 +265,11 @@ void ImportBaseData(SharedDatabase *db) {
} }
void ImportDBStrings(SharedDatabase *db) { void ImportDBStrings(SharedDatabase *db) {
Log(Logs::General, Logs::Status, "Importing DB Strings..."); LogInfo("Importing DB Strings");
FILE *f = fopen("import/dbstr_us.txt", "r"); FILE *f = fopen("import/dbstr_us.txt", "r");
if(!f) { if(!f) {
Log(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping."); LogError("Unable to open import/dbstr_us.txt to read, skipping.");
return; return;
} }

View File

@ -0,0 +1,94 @@
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-20180828-145854")
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-20180828-145455")
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/libperl530.a CACHE FILEPATH "Path to perl library" FORCE)
ENDIF()
ENDIF()

View File

@ -1,124 +0,0 @@
#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
cmake/FindLua51.cmake Normal file
View File

@ -0,0 +1,91 @@
# 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
cmake/FindMariaDB.cmake Normal file
View File

@ -0,0 +1,87 @@
# - 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
)

93
cmake/FindmbedTLS.cmake Normal file
View File

@ -0,0 +1,93 @@
# - 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
)

View File

@ -1,8 +1,9 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(common_sources SET(common_sources
base_packet.cpp base_packet.cpp
classes.cpp classes.cpp
cli/eqemu_command_handler.cpp
compression.cpp compression.cpp
condition.cpp condition.cpp
crash.cpp crash.cpp
@ -35,6 +36,7 @@ SET(common_sources
inventory_profile.cpp inventory_profile.cpp
inventory_slot.cpp inventory_slot.cpp
ipc_mutex.cpp ipc_mutex.cpp
ip_util.cpp
item_data.cpp item_data.cpp
item_instance.cpp item_instance.cpp
json_config.cpp json_config.cpp
@ -55,6 +57,7 @@ SET(common_sources
perl_eqdb.cpp perl_eqdb.cpp
perl_eqdb_res.cpp perl_eqdb_res.cpp
proc_launcher.cpp proc_launcher.cpp
profanity_manager.cpp
ptimer.cpp ptimer.cpp
races.cpp races.cpp
rdtsc.cpp rdtsc.cpp
@ -70,9 +73,7 @@ SET(common_sources
textures.cpp textures.cpp
timer.cpp timer.cpp
unix.cpp unix.cpp
xml_parser.cpp
platform.cpp platform.cpp
event/event_loop.cpp
json/jsoncpp.cpp json/jsoncpp.cpp
net/console_server.cpp net/console_server.cpp
net/console_server_connection.cpp net/console_server_connection.cpp
@ -86,6 +87,8 @@ SET(common_sources
net/servertalk_server_connection.cpp net/servertalk_server_connection.cpp
net/tcp_connection.cpp net/tcp_connection.cpp
net/tcp_server.cpp net/tcp_server.cpp
net/websocket_server.cpp
net/websocket_server_connection.cpp
patches/patches.cpp patches/patches.cpp
patches/sod.cpp patches/sod.cpp
patches/sod_limits.cpp patches/sod_limits.cpp
@ -100,13 +103,8 @@ SET(common_sources
patches/uf.cpp patches/uf.cpp
patches/uf_limits.cpp patches/uf_limits.cpp
StackWalker/StackWalker.cpp StackWalker/StackWalker.cpp
tinyxml/tinystr.cpp
tinyxml/tinyxml.cpp
tinyxml/tinyxmlerror.cpp
tinyxml/tinyxmlparser.cpp
util/directory.cpp util/directory.cpp
util/uuid.cpp util/uuid.cpp)
)
SET(common_headers SET(common_headers
any.h any.h
@ -119,6 +117,9 @@ SET(common_headers
crash.h crash.h
crc16.h crc16.h
crc32.h crc32.h
cli/argh.h
cli/eqemu_command_handler.h
cli/terminal_color.hpp
data_verification.h data_verification.h
database.h database.h
dbcore.h dbcore.h
@ -136,6 +137,7 @@ SET(common_headers
eqemu_config.h eqemu_config.h
eqemu_config_elements.h eqemu_config_elements.h
eqemu_logsys.h eqemu_logsys.h
eqemu_logsys_log_aliases.h
eq_limits.h eq_limits.h
eq_packet.h eq_packet.h
eq_stream_ident.h eq_stream_ident.h
@ -153,9 +155,11 @@ SET(common_headers
global_define.h global_define.h
guild_base.h guild_base.h
guilds.h guilds.h
http/httplib.h
inventory_profile.h inventory_profile.h
inventory_slot.h inventory_slot.h
ipc_mutex.h ipc_mutex.h
ip_util.h
item_data.h item_data.h
item_fieldlist.h item_fieldlist.h
item_instance.h item_instance.h
@ -181,6 +185,7 @@ SET(common_headers
packet_functions.h packet_functions.h
platform.h platform.h
proc_launcher.h proc_launcher.h
profanity_manager.h
profiler.h profiler.h
ptimer.h ptimer.h
queue.h queue.h
@ -205,10 +210,9 @@ SET(common_headers
unix.h unix.h
useperl.h useperl.h
version.h version.h
xml_parser.h
zone_numbers.h zone_numbers.h
event/background_task.h
event/event_loop.h event/event_loop.h
event/task.h
event/timer.h event/timer.h
json/json.h json/json.h
json/json-forwards.h json/json-forwards.h
@ -228,6 +232,8 @@ SET(common_headers
net/servertalk_server_connection.h net/servertalk_server_connection.h
net/tcp_connection.h net/tcp_connection.h
net/tcp_server.h net/tcp_server.h
net/websocket_server.h
net/websocket_server_connection.h
patches/patches.h patches/patches.h
patches/sod.h patches/sod.h
patches/sod_limits.h patches/sod_limits.h
@ -257,18 +263,14 @@ SET(common_headers
patches/uf_ops.h patches/uf_ops.h
patches/uf_structs.h patches/uf_structs.h
StackWalker/StackWalker.h StackWalker/StackWalker.h
tinyxml/tinystr.h
tinyxml/tinyxml.h
util/memory_stream.h util/memory_stream.h
util/directory.h util/directory.h
util/uuid.h util/uuid.h)
)
SOURCE_GROUP(Event FILES SOURCE_GROUP(Event FILES
event/background_task.h
event/event_loop.cpp
event/event_loop.h event/event_loop.h
event/timer.h event/timer.h
event/task.h
) )
SOURCE_GROUP(Json FILES SOURCE_GROUP(Json FILES
@ -308,6 +310,10 @@ SOURCE_GROUP(Net FILES
net/tcp_connection.h net/tcp_connection.h
net/tcp_server.cpp net/tcp_server.cpp
net/tcp_server.h net/tcp_server.h
net/websocket_server.cpp
net/websocket_server.h
net/websocket_server_connection.cpp
net/websocket_server_connection.h
) )
SOURCE_GROUP(Patches FILES SOURCE_GROUP(Patches FILES
@ -359,15 +365,6 @@ SOURCE_GROUP(StackWalker FILES
StackWalker/StackWalker.cpp StackWalker/StackWalker.cpp
) )
SOURCE_GROUP(TinyXML FILES
tinyxml/tinystr.h
tinyxml/tinyxml.h
tinyxml/tinystr.cpp
tinyxml/tinyxml.cpp
tinyxml/tinyxmlerror.cpp
tinyxml/tinyxmlparser.cpp
)
SOURCE_GROUP(Util FILES SOURCE_GROUP(Util FILES
util/memory_stream.h util/memory_stream.h
util/directory.cpp util/directory.cpp
@ -376,7 +373,7 @@ SOURCE_GROUP(Util FILES
util/uuid.h util/uuid.h
) )
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML) INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
ADD_LIBRARY(common ${common_sources} ${common_headers}) ADD_LIBRARY(common ${common_sources} ${common_headers})

View File

@ -75,6 +75,7 @@ public:
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; } uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); 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(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; void ReadString(char *str, uint32 Offset, uint32 MaxLength) const;
uint32 GetWritePosition() { return _wpos; } uint32 GetWritePosition() { return _wpos; }

434
common/cli/argh.h Normal file
View File

@ -0,0 +1,434 @@
#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));
}
}

View File

@ -0,0 +1,193 @@
/**
* 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)
std::cout << '\t' << pos_arg << std::endl;
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;
for (auto &arg : arguments) {
if (cmd(arg).str().empty()) {
arguments_filled = false;
}
}
if (!arguments_filled || argc == 2) {
std::string arguments_string;
for (auto &arg : arguments) {
arguments_string += " " + arg + "=*\n";
}
std::string options_string;
for (auto &opt : options) {
options_string += " " + opt + "\n";
}
std::cout << fmt::format(
"Command\n\n{0} \n\nArgs\n{1}\nOptions\n{2}",
argv[1],
arguments_string,
options_string
) << 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]) {
std::cout << std::endl;
std::cout << "> " << termcolor::cyan << "Executing CLI Command" << termcolor::reset << std::endl;
std::cout << std::endl;
(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;
}
else if (!ran_command) {
std::cerr << "Unknown command [" << argv[1] << "] ! Try --help" << std::endl;
}
exit(1);
}
}

View File

@ -0,0 +1,75 @@
/**
* 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

View File

@ -0,0 +1,557 @@
//!
//! 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_

View File

@ -111,7 +111,60 @@ void set_exception_handler() {
SetUnhandledExceptionFilter(windows_exception_handler); SetUnhandledExceptionFilter(windows_exception_handler);
} }
#else #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 // crash is off or an unhandled platform
void set_exception_handler() { 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));
} }
#endif #endif

View File

@ -1,53 +1,57 @@
/* EQEMu: Everquest Server Emulator /**
* EQEmulator: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. * the Free Software Foundation; version 2 of the License.
*
This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which * but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product; * are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ *
*/
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
namespace EQEmu namespace EQEmu {
{ template<typename T>
template <typename T> T Clamp(const T &value, const T &lower, const T &upper)
T Clamp(const T& value, const T& lower, const T& upper) { {
return std::max(lower, std::min(value, upper)); return std::max(lower, std::min(value, upper));
} }
template <typename T> template<typename T>
T ClampLower(const T& value, const T& lower) { T ClampLower(const T &value, const T &lower)
{
return std::max(lower, value); return std::max(lower, value);
} }
template <typename T> template<typename T>
T ClampUpper(const T& value, const T& upper) { T ClampUpper(const T &value, const T &upper)
{
return std::min(value, upper); return std::min(value, upper);
} }
template <typename T> template<typename T>
bool ValueWithin(const T& value, const T& lower, const T& upper) { bool ValueWithin(const T &value, const T &lower, const T &upper)
{
return value >= lower && value <= upper; return value >= lower && value <= upper;
} }
template <typename T1, typename T2, typename T3> template<typename T1, typename T2, typename T3>
bool ValueWithin(const T1& value, const T2& lower, const T3& upper) { bool ValueWithin(const T1 &value, const T2 &lower, const T3 &upper)
return value >= (T1)lower && value <= (T1)upper; {
return value >= (T1) lower && value <= (T1) upper;
} }
} /*EQEmu*/ } /*EQEmu*/

View File

@ -64,11 +64,11 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
uint32 errnum= 0; uint32 errnum= 0;
char errbuf[MYSQL_ERRMSG_SIZE]; char errbuf[MYSQL_ERRMSG_SIZE];
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) { if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); LogError("Failed to connect to database: Error: {}", errbuf);
return false; return false;
} }
else { else {
Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host,port); LogInfo("Using database [{}] at [{}]:[{}]", database, host,port);
return true; return true;
} }
} }
@ -86,7 +86,7 @@ Database::~Database()
Return the account id or zero if no account matches. Return the account id or zero if no account matches.
Zero will also be returned if there is a database error. Zero will also be returned if there is a database error.
*/ */
uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) { uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) {
if(strlen(name) >= 50 || strlen(password) >= 50) if(strlen(name) >= 50 || strlen(password) >= 50)
return(0); return(0);
@ -97,9 +97,10 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat
DoEscapeString(tmpUN, name, strlen(name)); DoEscapeString(tmpUN, name, strlen(name));
DoEscapeString(tmpPW, password, strlen(password)); DoEscapeString(tmpPW, password, strlen(password));
std::string query = StringFormat("SELECT id, status FROM account WHERE name='%s' AND password is not null " std::string query = StringFormat("SELECT id, status FROM account WHERE name='%s' AND ls_id='%s' AND password is not null "
"and length(password) > 0 and (password='%s' or password=MD5('%s'))", "and length(password) > 0 and (password='%s' or password=MD5('%s'))",
tmpUN, tmpPW, tmpPW); tmpUN, EscapeString(loginserver).c_str(), tmpPW, tmpPW);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) if (!results.Success())
@ -171,61 +172,87 @@ void Database::LoginIP(uint32 AccountID, const char* LoginIP) {
QueryDatabase(query); QueryDatabase(query);
} }
int16 Database::CheckStatus(uint32 account_id) { int16 Database::CheckStatus(uint32 account_id)
std::string query = StringFormat("SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`" {
" FROM `account` WHERE `id` = %i", account_id); std::string query = StringFormat(
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = %i",
account_id);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success())
return 0; return 0;
}
if (results.RowCount() != 1) if (results.RowCount() != 1)
return 0; return 0;
auto row = results.begin(); auto row = results.begin();
int16 status = atoi(row[0]); int16 status = atoi(row[0]);
int32 suspendeduntil = 0; int32 date_diff = 0;
// MariaDB initalizes with NULL if unix_timestamp() is out of range if (row[1] != nullptr)
if (row[1] != nullptr) { date_diff = atoi(row[1]);
suspendeduntil = atoi(row[1]);
}
int32 current = atoi(row[2]); if (date_diff > 0)
if(suspendeduntil > current)
return -1; return -1;
return status; return status;
} }
uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) { /**
* @param name
* @param password
* @param status
* @param loginserver
* @param lsaccount_id
* @return
*/
uint32 Database::CreateAccount(
const char *name,
const char *password,
int16 status,
const char *loginserver,
uint32 lsaccount_id
)
{
std::string query; std::string query;
if (password) if (password) {
query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name,password,status, lsaccount_id); query = StringFormat(
else "INSERT INTO account SET name='%s', password='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",
query = StringFormat("INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id); name,
password,
status,
loginserver,
lsaccount_id
);
}
else {
query = StringFormat(
"INSERT INTO account SET name='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",
name,
status,
loginserver,
lsaccount_id
);
}
Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s' status: %i", name, status); LogInfo("Account Attempting to be created: [{0}:{1}] status: {2}", loginserver, name, status);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
return 0; return 0;
} }
if (results.LastInsertedID() == 0) if (results.LastInsertedID() == 0) {
{
return 0; return 0;
} }
return results.LastInsertedID(); return results.LastInsertedID();
} }
bool Database::DeleteAccount(const char* name) { bool Database::DeleteAccount(const char* name, const char *loginserver) {
std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name); std::string query = StringFormat("DELETE FROM account WHERE name='%s' AND ls_id='%s'", name, loginserver);
Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name); LogInfo("Account Attempting to be deleted:'[{}]:[{}]'", loginserver, name);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
@ -272,7 +299,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
if (row[0] && atoi(row[0]) > 0){ if (row[0] && atoi(row[0]) > 0){
Log(Logs::General, Logs::World_Server, "Account: %i tried to request name: %s, but it is already taken...", account_id, name); LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
return false; return false;
} }
} }
@ -290,17 +317,17 @@ bool Database::ReserveName(uint32 account_id, char* name) {
bool Database::DeleteCharacter(char *name) { bool Database::DeleteCharacter(char *name) {
uint32 charid = 0; uint32 charid = 0;
if(!name || !strlen(name)) { if(!name || !strlen(name)) {
Log(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)"); LogInfo("DeleteCharacter: request to delete without a name (empty char slot)");
return false; return false;
} }
Log(Logs::General, Logs::World_Server, "Database::DeleteCharacter name : '%s'", name); LogInfo("Database::DeleteCharacter name : [{}]", name);
/* Get id from character_data before deleting record so we can clean up the rest of the tables */ /* Get id from character_data before deleting record so we can clean up the rest of the tables */
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", name); std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); } for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); }
if (charid <= 0){ if (charid <= 0){
Log(Logs::General, Logs::Error, "Database::DeleteCharacter :: Character (%s) not found, stopping delete...", name); LogError("Database::DeleteCharacter :: Character ({}) not found, stopping delete...", name);
return false; return false;
} }
@ -687,7 +714,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu
charid = GetCharacterID(pp->name); charid = GetCharacterID(pp->name);
if(!charid) { if(!charid) {
Log(Logs::General, Logs::Error, "StoreCharacter: no character id"); LogError("StoreCharacter: no character id");
return false; return false;
} }
@ -788,11 +815,12 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
return atoi(row[0]); return atoi(row[0]);
} }
uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* lsid) { uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver, int16* status, uint32* lsid) {
if (!isAlphaNumeric(accname)) if (!isAlphaNumeric(accname))
return 0; return 0;
std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' LIMIT 1", accname); std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1",
EscapeString(accname).c_str(), EscapeString(loginserver).c_str());
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
@ -921,18 +949,6 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
return true; return true;
} }
uint32 Database::GetMiniLoginAccount(char* ip)
{
std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
auto row = results.begin();
return atoi(row[0]);
}
// Get zone starting points from DB // Get zone starting points from DB
bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) { bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) {
@ -1194,25 +1210,46 @@ bool Database::AddToNameFilter(const char* name) {
return true; return true;
} }
uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) { /**
* @param in_loginserver_id
* @param in_loginserver_account_id
* @param in_account_name
* @param in_status
* @return
*/
uint32 Database::GetAccountIDFromLSID(
const std::string &in_loginserver_id,
uint32 in_loginserver_account_id,
char *in_account_name,
int16 *in_status
)
{
uint32 account_id = 0; uint32 account_id = 0;
std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID); auto query = fmt::format(
"SELECT id, name, status FROM account WHERE lsaccount_id = {0} AND ls_id = '{1}'",
in_loginserver_account_id,
in_loginserver_id
);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
return 0; return 0;
} }
if (results.RowCount() != 1) if (results.RowCount() != 1) {
return 0; return 0;
}
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
account_id = atoi(row[0]); account_id = std::stoi(row[0]);
if (oAccountName) if (in_account_name) {
strcpy(oAccountName, row[1]); strcpy(in_account_name, row[1]);
if (oStatus) }
*oStatus = atoi(row[2]); if (in_status) {
*in_status = std::stoi(row[2]);
}
} }
return account_id; return account_id;
@ -1445,9 +1482,9 @@ uint32 Database::GetCharacterInfo(
return charid; return charid;
} }
bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) { bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id); std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;", charname, account_id);
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()){ if (!results.Success()){
@ -1514,7 +1551,7 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) if (!results.Success())
Log(Logs::General, Logs::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str()); LogError("Error deleting character from group id: {}", results.ErrorMessage().c_str());
return; return;
} }
@ -1557,7 +1594,7 @@ uint32 Database::GetGroupID(const char* name){
if (results.RowCount() == 0) if (results.RowCount() == 0)
{ {
// Commenting this out until logging levels can prevent this from going to console // Commenting this out until logging levels can prevent this from going to console
//Log(Logs::General, Logs::None,, "Character not in a group: %s", name); //LogDebug(, "Character not in a group: [{}]", name);
return 0; return 0;
} }
@ -1604,7 +1641,7 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
result = QueryDatabase(query); result = QueryDatabase(query);
if(!result.Success()) { if(!result.Success()) {
Log(Logs::General, Logs::None, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str()); LogDebug("Error in Database::SetGroupLeaderName: [{}]", result.ErrorMessage().c_str());
} }
} }
@ -1810,7 +1847,7 @@ const char* Database::GetRaidLeaderName(uint32 raid_id)
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
Log(Logs::General, Logs::Debug, "Unable to get Raid Leader Name for Raid ID: %u", raid_id); LogDebug("Unable to get Raid Leader Name for Raid ID: [{}]", raid_id);
return "UNKNOWN"; return "UNKNOWN";
} }
@ -2077,9 +2114,11 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
return atoi(row[0]); return atoi(row[0]);
} }
void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) { /**
// log_settings previously initialized to '0' by EQEmuLogSys::LoadLogSettingsDefaults() * @param log_settings
*/
void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings)
{
std::string query = std::string query =
"SELECT " "SELECT "
"log_category_id, " "log_category_id, "
@ -2091,11 +2130,10 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) {
"logsys_categories " "logsys_categories "
"ORDER BY log_category_id"; "ORDER BY log_category_id";
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
int log_category_id = 0;
int log_category_id = 0; int *categories_in_database = new int[1000];
int categories_in_database[1000] = {};
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
log_category_id = atoi(row[0]); log_category_id = atoi(row[0]);
@ -2135,15 +2173,14 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) {
* Auto inject categories that don't exist in the database... * Auto inject categories that don't exist in the database...
*/ */
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
if (!categories_in_database[log_index]) { if (categories_in_database[log_index] != 1) {
Log(Logs::General, LogInfo(
Logs::Status, "New Log Category [{0}] doesn't exist... Automatically adding to [logsys_categories] table...",
"New Log Category '%s' doesn't exist... Automatically adding to `logsys_categories` table...",
Logs::LogCategoryName[log_index] Logs::LogCategoryName[log_index]
); );
std::string inject_query = StringFormat( auto inject_query = fmt::format(
"INSERT INTO logsys_categories " "INSERT INTO logsys_categories "
"(log_category_id, " "(log_category_id, "
"log_category_description, " "log_category_description, "
@ -2151,17 +2188,19 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) {
"log_to_file, " "log_to_file, "
"log_to_gmsay) " "log_to_gmsay) "
"VALUES " "VALUES "
"(%i, '%s', %i, %i, %i)", "({0}, '{1}', {2}, {3}, {4})",
log_index, log_index,
EscapeString(Logs::LogCategoryName[log_index]).c_str(), EscapeString(Logs::LogCategoryName[log_index]),
log_settings[log_category_id].log_to_console, std::to_string(log_settings[log_index].log_to_console),
log_settings[log_category_id].log_to_file, std::to_string(log_settings[log_index].log_to_file),
log_settings[log_category_id].log_to_gmsay std::to_string(log_settings[log_index].log_to_gmsay)
); );
QueryDatabase(inject_query); QueryDatabase(inject_query);
} }
} }
delete[] categories_in_database;
} }
int Database::CountInvSnapshots() { int Database::CountInvSnapshots() {
@ -2198,7 +2237,7 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success() || results.RowCount() == 0){ if (!results.Success() || results.RowCount() == 0){
Log(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults."); LogInfo("Loading EQ time of day failed. Using defaults");
eqTime.minute = 0; eqTime.minute = 0;
eqTime.hour = 9; eqTime.hour = 9;
eqTime.day = 1; eqTime.day = 1;

View File

@ -94,6 +94,8 @@ class PTimerList;
# define _ISNAN_(a) std::isnan(a) # define _ISNAN_(a) std::isnan(a)
#endif #endif
#define SQL(...) #__VA_ARGS__
class Database : public DBcore { class Database : public DBcore {
public: public:
Database(); Database();
@ -127,7 +129,7 @@ public:
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0); uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id); uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0); uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const char *name); 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 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); uint32 GetGuildIDByCharID(uint32 char_id);
@ -174,18 +176,17 @@ public:
/* Account Related */ /* Account Related */
bool DeleteAccount(const char* name); bool DeleteAccount(const char *name, const char* loginserver);
bool GetLiveChar(uint32 account_id, char* cname); bool GetLiveChar(uint32 account_id, char* cname);
bool SetAccountStatus(const char* name, int16 status); bool SetAccountStatus(const char* name, int16 status);
bool SetLocalPassword(uint32 accid, const char* password); bool SetLocalPassword(uint32 accid, const char* password);
bool UpdateLiveChar(char* charname, uint32 lsaccount_id); bool UpdateLiveChar(char* charname, uint32 account_id);
int16 CheckStatus(uint32 account_id); int16 CheckStatus(uint32 account_id);
uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0); uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0); uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0); uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
uint32 GetMiniLoginAccount(char* ip);
uint8 GetAgreementFlag(uint32 acctid); uint8 GetAgreementFlag(uint32 acctid);
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus); void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);

View File

@ -476,7 +476,7 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertCorpseDeblob(); CheckDatabaseConvertCorpseDeblob();
/* Run EQEmu Server script (Checks for database updates) */ /* Run EQEmu Server script (Checks for database updates) */
system("perl eqemu_server.pl ran_from_world"); if(system("perl eqemu_server.pl ran_from_world"));
return true; return true;
} }

View File

@ -2,8 +2,9 @@
#include <winsock2.h> #include <winsock2.h>
#endif #endif
#include "../common/misc_functions.h" #include "misc_functions.h"
#include "../common/eqemu_logsys.h" #include "eqemu_logsys.h"
#include "timer.h"
#include "dbcore.h" #include "dbcore.h"
@ -14,33 +15,37 @@
#include <string.h> #include <string.h>
#ifdef _WINDOWS #ifdef _WINDOWS
#define snprintf _snprintf #define snprintf _snprintf
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
#define strcasecmp _stricmp #define strcasecmp _stricmp
#include <process.h> #include <process.h>
#else #else
#include "unix.h"
#include <pthread.h> #include "unix.h"
#include <pthread.h>
#endif #endif
#ifdef _EQDEBUG #ifdef _EQDEBUG
#define DEBUG_MYSQL_QUERIES 0 #define DEBUG_MYSQL_QUERIES 0
#else #else
#define DEBUG_MYSQL_QUERIES 0 #define DEBUG_MYSQL_QUERIES 0
#endif #endif
DBcore::DBcore() { DBcore::DBcore()
{
mysql_init(&mysql); mysql_init(&mysql);
pHost = 0; pHost = 0;
pUser = 0; pUser = 0;
pPassword = 0; pPassword = 0;
pDatabase = 0; pDatabase = 0;
pCompress = false; pCompress = false;
pSSL = false; pSSL = false;
pStatus = Closed; pStatus = Closed;
} }
DBcore::~DBcore() { DBcore::~DBcore()
{
mysql_close(&mysql); mysql_close(&mysql);
safe_delete_array(pHost); safe_delete_array(pHost);
safe_delete_array(pUser); safe_delete_array(pUser);
@ -49,7 +54,8 @@ DBcore::~DBcore() {
} }
// Sends the MySQL server a keepalive // Sends the MySQL server a keepalive
void DBcore::ping() { void DBcore::ping()
{
if (!MDatabase.trylock()) { if (!MDatabase.trylock()) {
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive // well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
return; return;
@ -63,34 +69,35 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce); 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); LockMutex lock(&MDatabase);
// Reconnect if we are not connected before hand. // Reconnect if we are not connected before hand.
if (pStatus != Connected) if (pStatus != Connected) {
Open(); Open();
}
// request query. != 0 indicates some kind of error. // 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); unsigned int errorNumber = mysql_errno(&mysql);
if (errorNumber == CR_SERVER_GONE_ERROR) if (errorNumber == CR_SERVER_GONE_ERROR) {
pStatus = Error; pStatus = Error;
}
// error appears to be a disconnect error, may need to try again. // 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) if (retryOnFailureOnce) {
{ LogInfo("Database Error: Lost connection, attempting to recover");
std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl;
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false); MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
if (requestResult.Success()) if (requestResult.Success()) {
{ LogInfo("Reconnection to database successful");
std::cout << "Reconnection to database successful." << std::endl;
return requestResult; return requestResult;
} }
@ -102,109 +109,154 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); 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]; auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
/* Implement Logging at the Root */ /* Implement Logging at the Root */
if (mysql_errno(&mysql) > 0 && strlen(query) > 0){ if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1) 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); Log(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. // successful query. get results.
MYSQL_RES* res = mysql_store_result(&mysql); MYSQL_RES *res = mysql_store_result(&mysql);
uint32 rowCount = 0; uint32 rowCount = 0;
if (res != nullptr) if (res != nullptr) {
rowCount = (uint32)mysql_num_rows(res); 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)); 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 (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
{
if ((strncasecmp(query, "select", 6) == 0)) { if ((strncasecmp(query, "select", 6) == 0)) {
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s"); LogF(
Logs::General,
Logs::MySQLQuery,
"{0} ({1} row{2} returned) ({3}ms)",
query,
requestResult.RowCount(),
requestResult.RowCount() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
} }
else { else {
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s"); LogF(
Logs::General,
Logs::MySQLQuery,
"{0} ({1} row{2} affected) ({3}ms)",
query,
requestResult.RowsAffected(),
requestResult.RowsAffected() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
} }
} }
return requestResult; return requestResult;
} }
void DBcore::TransactionBegin() { void DBcore::TransactionBegin()
{
QueryDatabase("START TRANSACTION"); QueryDatabase("START TRANSACTION");
} }
void DBcore::TransactionCommit() { void DBcore::TransactionCommit()
{
QueryDatabase("COMMIT"); QueryDatabase("COMMIT");
} }
void DBcore::TransactionRollback() { void DBcore::TransactionRollback()
{
QueryDatabase("ROLLBACK"); 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. // No good reason to lock the DB, we only need it in the first place to check char encoding.
// LockMutex lock(&MDatabase); // LockMutex lock(&MDatabase);
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen); 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); LockMutex lock(&MDatabase);
safe_delete(pHost); safe_delete(pHost);
safe_delete(pUser); safe_delete(pUser);
safe_delete(pPassword); safe_delete(pPassword);
safe_delete(pDatabase); safe_delete(pDatabase);
pHost = strcpy(new char[strlen(iHost) + 1], iHost); pHost = strcpy(new char[strlen(iHost) + 1], iHost);
pUser = strcpy(new char[strlen(iUser) + 1], iUser); pUser = strcpy(new char[strlen(iUser) + 1], iUser);
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword); pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase); pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase);
pCompress = iCompress; pCompress = iCompress;
pPort = iPort; pPort = iPort;
pSSL = iSSL; pSSL = iSSL;
return Open(errnum, errbuf); return Open(errnum, errbuf);
} }
bool DBcore::Open(uint32* errnum, char* errbuf) { bool DBcore::Open(uint32 *errnum, char *errbuf)
if (errbuf) {
if (errbuf) {
errbuf[0] = 0; errbuf[0] = 0;
}
LockMutex lock(&MDatabase); LockMutex lock(&MDatabase);
if (GetStatus() == Connected) if (GetStatus() == Connected) {
return true; return true;
}
if (GetStatus() == Error) { if (GetStatus() == Error) {
mysql_close(&mysql); mysql_close(&mysql);
mysql_init(&mysql); // Initialize structure again mysql_init(&mysql); // Initialize structure again
} }
if (!pHost) if (!pHost) {
return false; return false;
}
/* /*
Added CLIENT_FOUND_ROWS flag to the connect Added CLIENT_FOUND_ROWS flag to the connect
otherwise DB update calls would say 0 rows affected when the value already equalled 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 what the function was tring to set it to, therefore the function would think it failed
*/ */
uint32 flags = CLIENT_FOUND_ROWS; uint32 flags = CLIENT_FOUND_ROWS;
if (pCompress) if (pCompress) {
flags |= CLIENT_COMPRESS; flags |= CLIENT_COMPRESS;
if (pSSL) }
if (pSSL) {
flags |= CLIENT_SSL; flags |= CLIENT_SSL;
}
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) { if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
pStatus = Connected; pStatus = Connected;
return true; return true;
} }
else { else {
if (errnum) if (errnum) {
*errnum = mysql_errno(&mysql); *errnum = mysql_errno(&mysql);
if (errbuf) }
if (errbuf) {
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
}
pStatus = Error; pStatus = Error;
return false; return false;
} }

View File

@ -118,3 +118,37 @@ EQEmu::bug::CategoryID EQEmu::bug::CategoryNameToCategoryID(const char* category
return catOther; 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;
}

View File

@ -77,6 +77,10 @@ namespace EQEmu
} // namespace invtype } // namespace invtype
namespace DevTools {
const int32 GM_ACCOUNT_STATUS_LEVEL = 150;
}
namespace popupresponse { namespace popupresponse {
const int32 SERVER_INTERNAL_USE_BASE = 2000000000; const int32 SERVER_INTERNAL_USE_BASE = 2000000000;
const int32 MOB_INFO_DISMISS = 2000000001; const int32 MOB_INFO_DISMISS = 2000000001;
@ -203,6 +207,26 @@ namespace EQEmu
const size_t SAY_LINK_CLOSER_SIZE = 1; 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); 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
};
const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type);
const int STANCE_TYPE_FIRST = stancePassive;
const int STANCE_TYPE_LAST = stanceBurnAE;
const int STANCE_TYPE_COUNT = stanceBurnAE;
} /*constants*/ } /*constants*/
namespace profile { namespace profile {
@ -287,6 +311,12 @@ namespace EQEmu
} // namespace bug } // namespace bug
enum WaypointStatus : int {
RoamBoxPauseInProgress = -3,
QuestControlNoGrid = -2,
QuestControlGrid = -1
};
} /*EQEmu*/ } /*EQEmu*/
#endif /*COMMON_EMU_CONSTANTS_H*/ #endif /*COMMON_EMU_CONSTANTS_H*/

View File

@ -18,6 +18,7 @@
*/ */
#include "emu_versions.h" #include "emu_versions.h"
#include "emu_constants.h"
bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version) bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version)
@ -493,7 +494,7 @@ EQEmu::expansions::Expansion EQEmu::expansions::ConvertExpansionBitToExpansion(u
} }
} }
uint32 EQEmu::expansions::ConvertExpansionToExpansionMask(Expansion expansion) uint32 EQEmu::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
{ {
switch (expansion) { switch (expansion) {
case Expansion::RoK: case Expansion::RoK:
@ -543,57 +544,15 @@ uint32 EQEmu::expansions::ConvertExpansionToExpansionMask(Expansion expansion)
EQEmu::expansions::Expansion EQEmu::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version) EQEmu::expansions::Expansion EQEmu::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
{ {
switch (client_version) { return EQEmu::constants::StaticLookup(client_version)->Expansion;
case versions::ClientVersion::Titanium:
return expansions::Expansion::PoR;
case versions::ClientVersion::SoF:
return expansions::Expansion::SoF;
case versions::ClientVersion::SoD:
return expansions::Expansion::SoD;
case versions::ClientVersion::UF:
return expansions::Expansion::UF;
case versions::ClientVersion::RoF:
case versions::ClientVersion::RoF2:
return expansions::Expansion::RoF;
default:
return expansions::Expansion::EverQuest;
}
} }
uint32 EQEmu::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version) uint32 EQEmu::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
{ {
switch (client_version) { return EQEmu::constants::StaticLookup(client_version)->ExpansionBit;
case versions::ClientVersion::Titanium:
return expansions::bitPoR;
case versions::ClientVersion::SoF:
return expansions::bitSoF;
case versions::ClientVersion::SoD:
return expansions::bitSoD;
case versions::ClientVersion::UF:
return expansions::bitUF;
case versions::ClientVersion::RoF:
case versions::ClientVersion::RoF2:
return expansions::bitRoF;
default:
return expansions::bitEverQuest;
}
} }
uint32 EQEmu::expansions::ConvertClientVersionToExpansionMask(versions::ClientVersion client_version) uint32 EQEmu::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
{ {
switch (client_version) { return EQEmu::constants::StaticLookup(client_version)->ExpansionsMask;
case versions::ClientVersion::Titanium:
return expansions::maskPoR;
case versions::ClientVersion::SoF:
return expansions::maskSoF;
case versions::ClientVersion::SoD:
return expansions::maskSoD;
case versions::ClientVersion::UF:
return expansions::maskUF;
case versions::ClientVersion::RoF:
case versions::ClientVersion::RoF2:
return expansions::maskRoF;
default:
return expansions::maskEverQuest;
}
} }

View File

@ -210,10 +210,10 @@ namespace EQEmu
const char* ExpansionName(uint32 expansion_bit); const char* ExpansionName(uint32 expansion_bit);
uint32 ConvertExpansionToExpansionBit(Expansion expansion); uint32 ConvertExpansionToExpansionBit(Expansion expansion);
Expansion ConvertExpansionBitToExpansion(uint32 expansion_bit); Expansion ConvertExpansionBitToExpansion(uint32 expansion_bit);
uint32 ConvertExpansionToExpansionMask(Expansion expansion); uint32 ConvertExpansionToExpansionsMask(Expansion expansion);
Expansion ConvertClientVersionToExpansion(versions::ClientVersion client_version); Expansion ConvertClientVersionToExpansion(versions::ClientVersion client_version);
uint32 ConvertClientVersionToExpansionBit(versions::ClientVersion client_version); uint32 ConvertClientVersionToExpansionBit(versions::ClientVersion client_version);
uint32 ConvertClientVersionToExpansionMask(versions::ClientVersion client_version); uint32 ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version);
} /*expansions*/ } /*expansions*/

View File

@ -71,7 +71,7 @@
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2) //#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
// animations for AT_Anim // animations for AT_Anim
#define ANIM_FREEZE 102 #define ANIM_FREEZE 102
#define ANIM_STAND 0x64 #define ANIM_STAND 0x64
#define ANIM_SIT 0x6e #define ANIM_SIT 0x6e
#define ANIM_CROUCH 0x6f #define ANIM_CROUCH 0x6f
@ -87,199 +87,114 @@ typedef enum {
_eaMaxAppearance _eaMaxAppearance
} EmuAppearance; } EmuAppearance;
// msg_type's for custom usercolors namespace Chat {
#define MT_Say 256 const uint16 White = 0;
#define MT_Tell 257 const uint16 DimGray = 1;
#define MT_Group 258 const uint16 Default = 1;
#define MT_Guild 259 const uint16 Green = 2;
#define MT_OOC 260 const uint16 BrightBlue = 3;
#define MT_Auction 261 const uint16 LightBlue = 4;
#define MT_Shout 262 const uint16 Magenta = 5;
#define MT_Emote 263 const uint16 Gray = 6;
#define MT_Spells 264 const uint16 LightGray = 7;
#define MT_YouHitOther 265 const uint16 NPCQuestSay = 10;
#define MT_OtherHitsYou 266 const uint16 DarkGray = 12;
#define MT_YouMissOther 267 const uint16 Red = 13;
#define MT_OtherMissesYou 268 const uint16 Lime = 14;
#define MT_Broadcasts 269 const uint16 Yellow = 15;
#define MT_Skills 270 const uint16 Blue = 16;
#define MT_Disciplines 271 const uint16 LightNavy = 17;
#define MT_Unused1 272 const uint16 Cyan = 18;
#define MT_DefaultText 273 const uint16 Black = 20;
#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
// TODO: Really should combine above and below into one /**
* User colors
//from showeq */
enum ChatColor const uint16 Say = 256;
{ const uint16 Tell = 257;
/* const uint16 Group = 258;
CC_Default = 0, const uint16 Guild = 259;
CC_DarkGrey = 1, const uint16 OOC = 260;
CC_DarkGreen = 2, const uint16 Auction = 261;
CC_DarkBlue = 3, const uint16 Shout = 262;
CC_Purple = 5, const uint16 Emote = 263;
CC_LightGrey = 6, const uint16 Spells = 264;
*/ const uint16 YouHitOther = 265;
const uint16 OtherHitYou = 266;
CC_WhiteSmoke = 0, // FF|F0F0F0 const uint16 YouMissOther = 267;
CC_Green = 2, // FF|008000 const uint16 OtherMissYou = 268;
CC_BrightBlue = 3, // FF|0040FF const uint16 Broadcasts = 269;
CC_Magenta = 5, // FF|F000F0 const uint16 Skills = 270;
CC_Gray = 6, // FF|808080 const uint16 Disciplines = 271;
CC_LightGray = 7, // FF|E0E0E0 const uint16 Unused1 = 272;
//CC_WhiteSmoke2 = 10, // FF|F0F0F0 const uint16 DefaultText = 273;
CC_DarkGray = 12, // FF|A0A0A0 const uint16 Unused2 = 274;
CC_Red = 13, // FF|F00000 const uint16 MerchantOffer = 275;
CC_Lime = 14, // FF|00F000 const uint16 MerchantExchange = 276;
CC_Yellow = 15, // FF|F0F000 const uint16 YourDeath = 277;
CC_Blue = 16, // FF|0000F0 const uint16 OtherDeath = 278;
CC_LightNavy = 17, // FF|0000AF const uint16 OtherHitOther = 279;
CC_Cyan = 18, // FF|00F0F0 const uint16 OtherMissOther = 280;
CC_Black = 20, // FF|000000 const uint16 Who = 281;
const uint16 YellForHelp = 282;
// any index <= 255 that is not defined above const uint16 NonMelee = 283;
CC_DimGray = 1, // FF|606060 const uint16 SpellWornOff = 284;
CC_Default = 1, const uint16 MoneySplit = 285;
const uint16 Loot = 286;
CC_User_Say = 256, const uint16 DiceRoll = 287;
CC_User_Tell = 257, const uint16 OtherSpells = 288;
CC_User_Group = 258, const uint16 SpellFailure = 289;
CC_User_Guild = 259, const uint16 ChatChannel = 290;
CC_User_OOC = 260, const uint16 Chat1 = 291;
CC_User_Auction = 261, const uint16 Chat2 = 292;
CC_User_Shout = 262, const uint16 Chat3 = 293;
CC_User_Emote = 263, const uint16 Chat4 = 294;
CC_User_Spells = 264, const uint16 Chat5 = 295;
CC_User_YouHitOther = 265, const uint16 Chat6 = 296;
CC_User_OtherHitYou = 266, const uint16 Chat7 = 297;
CC_User_YouMissOther = 267, const uint16 Chat8 = 298;
CC_User_OtherMissYou = 268, const uint16 Chat9 = 299;
CC_User_Duels = 269, const uint16 Chat10 = 300;
CC_User_Skills = 270, const uint16 MeleeCrit = 301;
CC_User_Disciplines = 271, const uint16 SpellCrit = 302;
CC_User_Default = 273, const uint16 TooFarAway = 303;
CC_User_MerchantOffer = 275, const uint16 NPCRampage = 304;
CC_User_MerchantExchange = 276, const uint16 NPCFlurry = 305;
CC_User_YourDeath = 277, const uint16 NPCEnrage = 306;
CC_User_OtherDeath = 278, const uint16 EchoSay = 307;
CC_User_OtherHitOther = 279, const uint16 EchoTell = 308;
CC_User_OtherMissOther = 280, const uint16 EchoGroup = 309;
CC_User_Who = 281, const uint16 EchoGuild = 310;
CC_User_Yell = 282, const uint16 EchoOOC = 311;
CC_User_NonMelee = 283, const uint16 EchoAuction = 312;
CC_User_SpellWornOff = 284, const uint16 EchoShout = 313;
CC_User_MoneySplit = 285, const uint16 EchoEmote = 314;
CC_User_Loot = 286, const uint16 EchoChat1 = 315;
CC_User_Random = 287, const uint16 EchoChat2 = 316;
CC_User_OtherSpells = 288, const uint16 EchoChat3 = 317;
CC_User_SpellFailure = 289, const uint16 EchoChat4 = 318;
CC_User_ChatChannel = 290, const uint16 EchoChat5 = 319;
CC_User_Chat1 = 291, const uint16 EchoChat6 = 320;
CC_User_Chat2 = 292, const uint16 EchoChat7 = 321;
CC_User_Chat3 = 293, const uint16 EchoChat8 = 322;
CC_User_Chat4 = 294, const uint16 EchoChat9 = 323;
CC_User_Chat5 = 295, const uint16 EchoChat10 = 324;
CC_User_Chat6 = 296, const uint16 DotDamage = 325;
CC_User_Chat7 = 297, const uint16 ItemLink = 326;
CC_User_Chat8 = 298, const uint16 RaidSay = 327;
CC_User_Chat9 = 299, const uint16 MyPet = 328;
CC_User_Chat10 = 300, const uint16 DamageShield = 329;
CC_User_MeleeCrit = 301, const uint16 LeaderShip = 330;
CC_User_SpellCrit = 302, const uint16 PetFlurry = 331;
CC_User_TooFarAway = 303, const uint16 PetCritical = 332;
CC_User_NPCRampage = 304, const uint16 FocusEffect = 333;
CC_User_NPCFurry = 305, const uint16 Experience = 334;
CC_User_NPCEnrage = 306, const uint16 System = 335;
CC_User_EchoSay = 307, const uint16 PetSpell = 336;
CC_User_EchoTell = 308, const uint16 PetResponse = 337;
CC_User_EchoGroup = 309, const uint16 ItemSpeech = 338;
CC_User_EchoGuild = 310, const uint16 StrikeThrough = 339;
CC_User_EchoOOC = 311, const uint16 Stun = 340;
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 //ZoneChange_Struct->success values
@ -523,4 +438,30 @@ static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // chang
static const uint32 MAX_SPELL_DB_ID_VAL = 65535; 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*/ #endif /*COMMON_EQ_CONSTANTS_H*/

View File

@ -43,17 +43,17 @@ static const EQEmu::constants::LookupEntry constants_static_lookup_entries[EQEmu
{ {
/*[ClientVersion::Unknown] =*/ /*[ClientVersion::Unknown] =*/
EQEmu::constants::LookupEntry( EQEmu::constants::LookupEntry(
EQEmu::expansions::Expansion::EverQuest, ClientUnknown::constants::EXPANSION,
ClientUnknown::INULL, ClientUnknown::constants::EXPANSION_BIT,
ClientUnknown::INULL, ClientUnknown::constants::EXPANSIONS_MASK,
ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL ClientUnknown::INULL
), ),
/*[ClientVersion::Client62] =*/ /*[ClientVersion::Client62] =*/
EQEmu::constants::LookupEntry( EQEmu::constants::LookupEntry(
EQEmu::expansions::Expansion::EverQuest, Client62::constants::EXPANSION,
Client62::INULL, Client62::constants::EXPANSION_BIT,
Client62::INULL, Client62::constants::EXPANSIONS_MASK,
Client62::INULL, Client62::INULL,
Client62::INULL Client62::INULL
), ),

View File

@ -243,6 +243,13 @@ namespace ClientUnknown
const int16 IINVALID = -1; const int16 IINVALID = -1;
const int16 INULL = 0; const int16 INULL = 0;
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
} /*ClientUnknown*/ } /*ClientUnknown*/
namespace Client62 namespace Client62
@ -250,6 +257,13 @@ namespace Client62
const int16 IINVALID = -1; const int16 IINVALID = -1;
const int16 INULL = 0; const int16 INULL = 0;
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
} /*Client62*/ } /*Client62*/
#endif /*COMMON_EQ_LIMITS_H*/ #endif /*COMMON_EQ_LIMITS_H*/

View File

@ -1188,6 +1188,20 @@ struct SpecialMesg_Struct
/*24*/ char message[1]; // What is being said? /*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) ** When somebody changes what they're wearing or give a pet a weapon (model changes)
** Length: 19 Bytes ** Length: 19 Bytes

View File

@ -84,14 +84,14 @@ void EQStream::init(bool resetSession) {
OpMgr = nullptr; OpMgr = nullptr;
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); LogNetcode(_L "init Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
} }
} }
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p) EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
{ {
EQRawApplicationPacket *ap=nullptr; EQRawApplicationPacket *ap=nullptr;
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size); LogNetcode(_L "Creating new application packet, length [{}]" __L, p->size);
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p); // _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
ap = p->MakeAppPacket(); ap = p->MakeAppPacket();
return ap; return ap;
@ -100,7 +100,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len) EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
{ {
EQRawApplicationPacket *ap=nullptr; EQRawApplicationPacket *ap=nullptr;
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len); LogNetcode(_L "Creating new application packet, length [{}]" __L, len);
ap = new EQRawApplicationPacket(buf, len); ap = new EQRawApplicationPacket(buf, len);
return ap; return ap;
} }
@ -130,7 +130,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
} }
if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) { if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) {
Log(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L); LogNetcode(_L "Session not initialized, packet ignored" __L);
// _raw(NET__DEBUG, 0xFFFF, p); // _raw(NET__DEBUG, 0xFFFF, p);
return; return;
} }
@ -141,7 +141,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
while(processed < p->size) { while(processed < p->size) {
subpacket_length=*(p->pBuffer+processed); subpacket_length=*(p->pBuffer+processed);
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length); EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length);
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length); LogNetcode(_L "Extracting combined packet of length [{}]" __L, subpacket_length);
// _raw(NET__NET_CREATE_HEX, 0xFFFF, subp); // _raw(NET__NET_CREATE_HEX, 0xFFFF, subp);
subp->copyInfo(p); subp->copyInfo(p);
ProcessPacket(subp); ProcessPacket(subp);
@ -156,12 +156,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
while(processed<p->size) { while(processed<p->size) {
EQRawApplicationPacket *ap=nullptr; EQRawApplicationPacket *ap=nullptr;
if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) { if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) {
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length); ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length);
processed+=subpacket_length+1; processed+=subpacket_length+1;
} else { } else {
subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1)); subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1));
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length); ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length);
processed+=subpacket_length+3; processed+=subpacket_length+3;
} }
@ -176,29 +176,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_Packet: { case OP_Packet: {
if(!p->pBuffer || (p->Size() < 4)) if(!p->pBuffer || (p->Size() < 4))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L); LogNetcode(_L "Received OP_Packet that was of malformed size" __L);
break; break;
} }
uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
SeqOrder check=CompareSequence(NextInSeq,seq); SeqOrder check=CompareSequence(NextInSeq,seq);
if (check == SeqFuture) { if (check == SeqFuture) {
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); LogNetcode(_L "Future OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p); // _raw(NET__DEBUG, seq, p);
PacketQueue[seq]=p->Copy(); PacketQueue[seq]=p->Copy();
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
//SendOutOfOrderAck(seq); //SendOutOfOrderAck(seq);
} else if (check == SeqPast) { } else if (check == SeqPast) {
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); LogNetcode(_L "Duplicate OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p); // _raw(NET__DEBUG, seq, p);
SendOutOfOrderAck(seq); //we already got this packet but it was out of order SendOutOfOrderAck(seq); //we already got this packet but it was out of order
} else { } else {
// In case we did queue one before as well. // In case we did queue one before as well.
EQProtocolPacket *qp=RemoveQueue(seq); EQProtocolPacket *qp=RemoveQueue(seq);
if (qp) { if (qp) {
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq); LogNetcode("[NET_TRACE] OP_Packet: Removing older queued packet with sequence [{}]", seq);
delete qp; delete qp;
} }
@ -207,7 +207,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
// Check for an embedded OP_AppCombinded (protocol level 0x19) // Check for an embedded OP_AppCombinded (protocol level 0x19)
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) { if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2); EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2);
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size); LogNetcode(_L "seq [{}], Extracting combined packet of length [{}]" __L, seq, subp->size);
// _raw(NET__NET_CREATE_HEX, seq, subp); // _raw(NET__NET_CREATE_HEX, seq, subp);
subp->copyInfo(p); subp->copyInfo(p);
ProcessPacket(subp); ProcessPacket(subp);
@ -226,29 +226,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_Fragment: { case OP_Fragment: {
if(!p->pBuffer || (p->Size() < 4)) if(!p->pBuffer || (p->Size() < 4))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L); LogNetcode(_L "Received OP_Fragment that was of malformed size" __L);
break; break;
} }
uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
SeqOrder check=CompareSequence(NextInSeq,seq); SeqOrder check=CompareSequence(NextInSeq,seq);
if (check == SeqFuture) { if (check == SeqFuture) {
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); LogNetcode(_L "Future OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p); // _raw(NET__DEBUG, seq, p);
PacketQueue[seq]=p->Copy(); PacketQueue[seq]=p->Copy();
Log(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size()); LogNetcode(_L "OP_Fragment Queue size=[{}]" __L, PacketQueue.size());
//SendOutOfOrderAck(seq); //SendOutOfOrderAck(seq);
} else if (check == SeqPast) { } else if (check == SeqPast) {
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); LogNetcode(_L "Duplicate OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
// _raw(NET__DEBUG, seq, p); // _raw(NET__DEBUG, seq, p);
SendOutOfOrderAck(seq); SendOutOfOrderAck(seq);
} else { } else {
// In case we did queue one before as well. // In case we did queue one before as well.
EQProtocolPacket *qp=RemoveQueue(seq); EQProtocolPacket *qp=RemoveQueue(seq);
if (qp) { if (qp) {
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq); LogNetcode("[NET_TRACE] OP_Fragment: Removing older queued packet with sequence [{}]", seq);
delete qp; delete qp;
} }
SetNextAckToSend(seq); SetNextAckToSend(seq);
@ -256,18 +256,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
if (oversize_buffer) { if (oversize_buffer) {
memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2); memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2);
oversize_offset+=p->size-2; oversize_offset+=p->size-2;
Log(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); LogNetcode(_L "Fragment of oversized of length [{}], seq [{}]: now at [{}]/[{}]" __L, p->size-2, seq, oversize_offset, oversize_length);
if (oversize_offset==oversize_length) { if (oversize_offset==oversize_length) {
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) { if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset); EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset);
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size); LogNetcode(_L "seq [{}], Extracting combined oversize packet of length [{}]" __L, seq, subp->size);
//// _raw(NET__NET_CREATE_HEX, subp); //// _raw(NET__NET_CREATE_HEX, subp);
subp->copyInfo(p); subp->copyInfo(p);
ProcessPacket(subp); ProcessPacket(subp);
delete subp; delete subp;
} else { } else {
EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset); EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset);
Log(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size); LogNetcode(_L "seq [{}], completed combined oversize packet of length [{}]" __L, seq, ap->size);
if (ap) { if (ap) {
ap->copyInfo(p); ap->copyInfo(p);
InboundQueuePush(ap); InboundQueuePush(ap);
@ -282,20 +282,20 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
oversize_buffer=new unsigned char[oversize_length]; oversize_buffer=new unsigned char[oversize_length];
memcpy(oversize_buffer,p->pBuffer+6,p->size-6); memcpy(oversize_buffer,p->pBuffer+6,p->size-6);
oversize_offset=p->size-6; oversize_offset=p->size-6;
Log(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length); LogNetcode(_L "First fragment of oversized of seq [{}]: now at [{}]/[{}]" __L, seq, oversize_offset, oversize_length);
} }
} }
} }
break; break;
case OP_KeepAlive: { case OP_KeepAlive: {
NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size)); NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size));
Log(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L); LogNetcode(_L "Received and queued reply to keep alive" __L);
} }
break; break;
case OP_Ack: { case OP_Ack: {
if(!p->pBuffer || (p->Size() < 4)) if(!p->pBuffer || (p->Size() < 4))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L); LogNetcode(_L "Received OP_Ack that was of malformed size" __L);
break; break;
} }
uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
@ -309,11 +309,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_SessionRequest: { case OP_SessionRequest: {
if(p->Size() < sizeof(SessionRequest)) if(p->Size() < sizeof(SessionRequest))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L); LogNetcode(_L "Received OP_SessionRequest that was of malformed size" __L);
break; break;
} }
if (GetState()==ESTABLISHED) { if (GetState()==ESTABLISHED) {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts); LogNetcode(_L "Received OP_SessionRequest in ESTABLISHED state ([{}]) streamactive ([{}]) attempt ([{}])" __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 // 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 // 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; SessionRequest *Request=(SessionRequest *)p->pBuffer;
Session=ntohl(Request->Session); Session=ntohl(Request->Session);
SetMaxLen(ntohl(Request->MaxLength)); SetMaxLen(ntohl(Request->MaxLength));
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen); LogNetcode(_L "Received OP_SessionRequest: session [{}], maxlen [{}]" __L, (unsigned long)Session, MaxLen);
SetState(ESTABLISHED); SetState(ESTABLISHED);
Key=0x11223344; Key=0x11223344;
SendSessionResponse(); SendSessionResponse();
@ -340,7 +340,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_SessionResponse: { case OP_SessionResponse: {
if(p->Size() < sizeof(SessionResponse)) if(p->Size() < sizeof(SessionResponse))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L); LogNetcode(_L "Received OP_SessionResponse that was of malformed size" __L);
break; break;
} }
@ -356,7 +356,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
compressed=(Response->Format&FLAG_COMPRESSED); compressed=(Response->Format&FLAG_COMPRESSED);
encoded=(Response->Format&FLAG_ENCODED); encoded=(Response->Format&FLAG_ENCODED);
Log(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"); LogNetcode(_L "Received OP_SessionResponse: session [{}], maxlen [{}], key [{}], compressed? [{}], encoded? [{}]" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
// Kinda kludgy, but trie for now // Kinda kludgy, but trie for now
if (StreamType==UnknownStream) { if (StreamType==UnknownStream) {
@ -379,17 +379,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
EQStreamState state = GetState(); EQStreamState state = GetState();
if(state == ESTABLISHED) { if(state == ESTABLISHED) {
//client initiated disconnect? //client initiated disconnect?
Log(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L); LogNetcode(_L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect" __L);
_SendDisconnect(); _SendDisconnect();
SetState(CLOSED); SetState(CLOSED);
} else if(state == CLOSING) { } else if(state == CLOSING) {
//we were waiting for this anyways, ignore pending messages, send the reply and be closed. //we were waiting for this anyways, ignore pending messages, send the reply and be closed.
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L); LogNetcode(_L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though" __L);
_SendDisconnect(); _SendDisconnect();
SetState(CLOSED); SetState(CLOSED);
} else { } else {
//we are expecting this (or have already gotten it, but dont care either way) //we are expecting this (or have already gotten it, but dont care either way)
Log(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L); LogNetcode(_L "Received expected OP_SessionDisconnect. Moving to closed state" __L);
SetState(CLOSED); SetState(CLOSED);
} }
} }
@ -397,14 +397,14 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_OutOfOrderAck: { case OP_OutOfOrderAck: {
if(!p->pBuffer || (p->Size() < 4)) if(!p->pBuffer || (p->Size() < 4))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L); LogNetcode(_L "Received OP_OutOfOrderAck that was of malformed size" __L);
break; break;
} }
uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
MOutboundQueue.lock(); MOutboundQueue.lock();
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __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 the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
@ -414,7 +414,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
uint16 sqsize = SequencedQueue.size(); uint16 sqsize = SequencedQueue.size();
uint16 index = seq - SequencedBase; uint16 index = seq - SequencedBase;
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize); LogNetcode(_L "OP_OutOfOrderAck marking packet acked in queue (queue index = [{}], queue size = [{}])" __L, index, sqsize);
if (index < sqsize) { if (index < sqsize) {
SequencedQueue[index]->acked = true; SequencedQueue[index]->acked = true;
// flag packets for a resend // 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) { 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())) { if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) {
(*sitr)->sent_time = 0; (*sitr)->sent_time = 0;
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck Flagging packet %d for retransmission" __L, SequencedBase + count); LogNetcode(_L "OP_OutOfOrderAck Flagging packet [{}] for retransmission" __L, SequencedBase + count);
} }
} }
} }
@ -432,11 +432,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
retransmittimer = Timer::GetCurrentTime(); retransmittimer = Timer::GetCurrentTime();
} }
} else { } else {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq); LogNetcode(_L "Received OP_OutOfOrderAck for out-of-window [{}]. Window ([{}]->[{}])" __L, seq, SequencedBase, NextOutSeq);
} }
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); LogNetcode(_L "Post-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
} }
MOutboundQueue.unlock(); MOutboundQueue.unlock();
@ -445,7 +445,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
case OP_SessionStatRequest: { case OP_SessionStatRequest: {
if(p->Size() < sizeof(ClientSessionStats)) if(p->Size() < sizeof(ClientSessionStats))
{ {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L); LogNetcode(_L "Received OP_SessionStatRequest that was of malformed size" __L);
break; break;
} }
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer; ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
@ -468,7 +468,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
retransmittimeout += 300; retransmittimeout += 300;
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX) if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
retransmittimeout = RETRANSMIT_TIMEOUT_MAX; retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
Log(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); LogNetcode(_L "Retransmit timeout recalculated to [{}]ms" __L, retransmittimeout);
} }
} }
@ -485,11 +485,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
} }
break; break;
case OP_SessionStatResponse: { case OP_SessionStatResponse: {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L); LogNetcode(_L "Received OP_SessionStatResponse. Ignoring" __L);
} }
break; break;
case OP_OutOfSession: { case OP_OutOfSession: {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L); LogNetcode(_L "Received OP_OutOfSession. Ignoring" __L);
} }
break; break;
default: default:
@ -520,7 +520,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
return; return;
if(OpMgr == nullptr || *OpMgr == nullptr) { if(OpMgr == nullptr || *OpMgr == nullptr) {
Log(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L); LogNetcode(_L "Packet enqueued into a stream with no opcode manager, dropping" __L);
delete pack; delete pack;
return; return;
} }
@ -559,18 +559,18 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets // Convert the EQApplicationPacket to 1 or more EQProtocolPackets
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2) if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
Log(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size()); LogNetcode(_L "Making oversized packet, len [{}]" __L, p->Size());
auto tmpbuff = new unsigned char[p->size + 3]; auto tmpbuff = new unsigned char[p->size + 3];
length=p->serialize(opcode, tmpbuff); length=p->serialize(opcode, tmpbuff);
if (length != p->Size()) if (length != p->Size())
Log(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length); LogNetcode(_L "Packet adjustment, len [{}] to [{}]" __L, p->Size(), length);
auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4); auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4);
*(uint32 *)(out->pBuffer+2)=htonl(length); *(uint32 *)(out->pBuffer+2)=htonl(length);
used=MaxLen-10; used=MaxLen-10;
memcpy(out->pBuffer+6,tmpbuff,used); memcpy(out->pBuffer+6,tmpbuff,used);
Log(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size); LogNetcode(_L "First fragment: used [{}]/[{}]. Payload size [{}] in the packet" __L, used, length, p->size);
SequencedPush(out); SequencedPush(out);
@ -581,7 +581,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
out->size=chunksize+2; out->size=chunksize+2;
SequencedPush(out); SequencedPush(out);
used+=chunksize; used+=chunksize;
Log(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length); LogNetcode(_L "Subsequent fragment: len [{}], used [{}]/[{}]" __L, chunksize, used, length);
} }
delete p; delete p;
delete[] tmpbuff; delete[] tmpbuff;
@ -623,7 +623,7 @@ void EQStream::SequencedPush(EQProtocolPacket *p)
void EQStream::NonSequencedPush(EQProtocolPacket *p) void EQStream::NonSequencedPush(EQProtocolPacket *p)
{ {
MOutboundQueue.lock(); MOutboundQueue.lock();
Log(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size); LogNetcode(_L "Pushing non-sequenced packet of length [{}]" __L, p->size);
NonSequencedQueue.push(p); NonSequencedQueue.push(p);
MOutboundQueue.unlock(); MOutboundQueue.unlock();
} }
@ -631,14 +631,14 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
void EQStream::SendAck(uint16 seq) void EQStream::SendAck(uint16 seq)
{ {
uint16 Seq=htons(seq); uint16 Seq=htons(seq);
Log(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq); LogNetcode(_L "Sending ack with sequence [{}]" __L, seq);
SetLastAckSent(seq); SetLastAckSent(seq);
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16))); NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
} }
void EQStream::SendOutOfOrderAck(uint16 seq) void EQStream::SendOutOfOrderAck(uint16 seq)
{ {
Log(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq); LogNetcode(_L "Sending out of order ack with sequence [{}]" __L, seq);
uint16 Seq=htons(seq); uint16 Seq=htons(seq);
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16))); 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 // If we don't have a packet to try to combine into, use this one as the base
// And remove it form the queue // And remove it form the queue
p = NonSequencedQueue.front(); p = NonSequencedQueue.front();
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size); LogNetcode(_L "Starting combined packet with non-seq packet of len [{}]" __L, p->size);
NonSequencedQueue.pop(); NonSequencedQueue.pop();
} else if (!p->combine(NonSequencedQueue.front())) { } else if (!p->combine(NonSequencedQueue.front())) {
// Trying to combine this packet with the base didn't work (too big maybe) // 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) // So just send the base packet (we'll try this packet again later)
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size); LogNetcode(_L "Combined packet full at len [{}], next non-seq packet is len [{}]" __L, p->size, (NonSequencedQueue.front())->size);
ReadyToSend.push(p); ReadyToSend.push(p);
BytesWritten+=p->size; BytesWritten+=p->size;
p=nullptr; p=nullptr;
if (BytesWritten > threshold) { if (BytesWritten > threshold) {
// Sent enough this round, lets stop to be fair // Sent enough this round, lets stop to be fair
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold); LogNetcode(_L "Exceeded write threshold in nonseq ([{}] > [{}])" __L, BytesWritten, threshold);
break; break;
} }
} else { } else {
// Combine worked, so just remove this packet and it's spot in the queue // Combine worked, so just remove this packet and it's spot in the queue
Log(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size); LogNetcode(_L "Combined non-seq packet of len [{}], yeilding [{}] combined" __L, (NonSequencedQueue.front())->size, p->size);
delete NonSequencedQueue.front(); delete NonSequencedQueue.front();
NonSequencedQueue.pop(); NonSequencedQueue.pop();
} }
@ -718,7 +718,7 @@ void EQStream::Write(int eq_fd)
uint16 seq_send = SequencedBase + count; //just for logging... uint16 seq_send = SequencedBase + count; //just for logging...
if(SequencedQueue.empty()) { if(SequencedQueue.empty()) {
Log(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); LogNetcode(_L "Tried to write a packet with an empty queue ([{}] is past next out [{}])" __L, seq_send, NextOutSeq);
SeqEmpty=true; SeqEmpty=true;
continue; continue;
} }
@ -728,35 +728,35 @@ void EQStream::Write(int eq_fd)
++sitr; ++sitr;
++count; ++count;
if (p) { if (p) {
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
ReadyToSend.push(p); ReadyToSend.push(p);
BytesWritten += p->size; BytesWritten += p->size;
p = nullptr; p = nullptr;
} }
Log(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); LogNetcode(_L "Not retransmitting seq packet [{}] because already marked as acked" __L, seq_send);
} else if (!p) { } else if (!p) {
// If we don't have a packet to try to combine into, use this one as the base // 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 // Copy it first as it will still live until it is acked
p=(*sitr)->Copy(); p=(*sitr)->Copy();
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
(*sitr)->sent_time = Timer::GetCurrentTime(); (*sitr)->sent_time = Timer::GetCurrentTime();
++sitr; ++sitr;
++count; ++count;
} else if (!p->combine(*sitr)) { } else if (!p->combine(*sitr)) {
// Trying to combine this packet with the base didn't work (too big maybe) // 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) // So just send the base packet (we'll try this packet again later)
Log(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); LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send + 1, (*sitr)->size);
ReadyToSend.push(p); ReadyToSend.push(p);
BytesWritten+=p->size; BytesWritten+=p->size;
p=nullptr; p=nullptr;
if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) { if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) {
// Sent enough this round, lets stop to be fair // Sent enough this round, lets stop to be fair
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
break; break;
} }
} else { } else {
// Combine worked // Combine worked
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); LogNetcode(_L "Combined seq packet [{}] of len [{}], yeilding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
(*sitr)->sent_time = Timer::GetCurrentTime(); (*sitr)->sent_time = Timer::GetCurrentTime();
++sitr; ++sitr;
++count; ++count;
@ -766,7 +766,7 @@ void EQStream::Write(int eq_fd)
++sitr; ++sitr;
++count; ++count;
if (p) { if (p) {
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
ReadyToSend.push(p); ReadyToSend.push(p);
BytesWritten += p->size; BytesWritten += p->size;
p = nullptr; p = nullptr;
@ -776,25 +776,25 @@ void EQStream::Write(int eq_fd)
// Copy it first as it will still live until it is acked // Copy it first as it will still live until it is acked
p=(*sitr)->Copy(); p=(*sitr)->Copy();
(*sitr)->sent_time = Timer::GetCurrentTime(); (*sitr)->sent_time = Timer::GetCurrentTime();
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
++sitr; ++sitr;
++count; ++count;
} else if (!p->combine(*sitr)) { } else if (!p->combine(*sitr)) {
// Trying to combine this packet with the base didn't work (too big maybe) // 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) // So just send the base packet (we'll try this packet again later)
Log(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); LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send, (*sitr)->size);
ReadyToSend.push(p); ReadyToSend.push(p);
BytesWritten+=p->size; BytesWritten+=p->size;
p=nullptr; p=nullptr;
if (BytesWritten > threshold) { if (BytesWritten > threshold) {
// Sent enough this round, lets stop to be fair // Sent enough this round, lets stop to be fair
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
break; break;
} }
} else { } else {
// Combine worked // Combine worked
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yielding %d combined." __L, seq_send, (*sitr)->size, p->size); LogNetcode(_L "Combined seq packet [{}] of len [{}], yielding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
(*sitr)->sent_time = Timer::GetCurrentTime(); (*sitr)->sent_time = Timer::GetCurrentTime();
++sitr; ++sitr;
++count; ++count;
@ -802,7 +802,7 @@ void EQStream::Write(int eq_fd)
} }
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); LogNetcode(_L "Post send Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
} }
} else { } else {
// No more sequenced packets // 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 // We have a packet still, must have run out of both seq and non-seq, so send it
if (p) { if (p) {
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
ReadyToSend.push(p); ReadyToSend.push(p);
BytesWritten+=p->size; BytesWritten+=p->size;
} }
@ -831,7 +831,7 @@ void EQStream::Write(int eq_fd)
if(SeqEmpty && NonSeqEmpty) { if(SeqEmpty && NonSeqEmpty) {
//no more data to send //no more data to send
if(CheckState(CLOSING)) { if(CheckState(CLOSING)) {
Log(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L ); LogNetcode(_L "All outgoing data flushed, closing stream" __L );
//we are waiting for the queues to empty, now we can do our disconnect. //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(). //this packet will not actually go out until the next call to Write().
_SendDisconnect(); _SendDisconnect();
@ -910,7 +910,7 @@ void EQStream::SendSessionRequest()
Request->Session=htonl(time(nullptr)); Request->Session=htonl(time(nullptr));
Request->MaxLength=htonl(512); Request->MaxLength=htonl(512);
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength)); LogNetcode(_L "Sending OP_SessionRequest: session [{}], maxlen=[{}]" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
NonSequencedPush(out); NonSequencedPush(out);
} }
@ -924,7 +924,7 @@ void EQStream::_SendDisconnect()
*(uint32 *)out->pBuffer=htonl(Session); *(uint32 *)out->pBuffer=htonl(Session);
NonSequencedPush(out); NonSequencedPush(out);
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session); LogNetcode(_L "Sending OP_SessionDisconnect: session [{}]" __L, (unsigned long)Session);
} }
void EQStream::InboundQueuePush(EQRawApplicationPacket *p) void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
@ -976,7 +976,7 @@ EQRawApplicationPacket *p=nullptr;
if(OpMgr != nullptr && *OpMgr != nullptr) { if(OpMgr != nullptr && *OpMgr != nullptr) {
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode); EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
if(emu_op == OP_Unknown) { if(emu_op == OP_Unknown) {
Log(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode); LogNetcode("Unable to convert EQ opcode {:#04x} to an Application opcode", p->opcode);
} }
p->SetOpcode(emu_op); p->SetOpcode(emu_op);
@ -1004,7 +1004,7 @@ void EQStream::InboundQueueClear()
{ {
EQApplicationPacket *p=nullptr; EQApplicationPacket *p=nullptr;
Log(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L); LogNetcode(_L "Clearing inbound queue" __L);
MInboundQueue.lock(); MInboundQueue.lock();
if (!InboundQueue.empty()) { if (!InboundQueue.empty()) {
@ -1047,7 +1047,7 @@ void EQStream::OutboundQueueClear()
{ {
EQProtocolPacket *p=nullptr; EQProtocolPacket *p=nullptr;
Log(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L); LogNetcode(_L "Clearing outbound queue" __L);
MOutboundQueue.lock(); MOutboundQueue.lock();
while(!NonSequencedQueue.empty()) { while(!NonSequencedQueue.empty()) {
@ -1069,7 +1069,7 @@ void EQStream::PacketQueueClear()
{ {
EQProtocolPacket *p=nullptr; EQProtocolPacket *p=nullptr;
Log(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L); LogNetcode(_L "Clearing future packet queue" __L);
if(!PacketQueue.empty()) { if(!PacketQueue.empty()) {
std::map<unsigned short,EQProtocolPacket *>::iterator itr; std::map<unsigned short,EQProtocolPacket *>::iterator itr;
@ -1101,7 +1101,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
delete p; delete p;
ProcessQueue(); ProcessQueue();
} else { } else {
Log(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L); LogNetcode(_L "Incoming packet failed checksum" __L);
} }
} }
@ -1132,23 +1132,23 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
SeqOrder ord = CompareSequence(SequencedBase, seq); SeqOrder ord = CompareSequence(SequencedBase, seq);
if(ord == SeqInOrder) { if(ord == SeqInOrder) {
//they are not acking anything new... //they are not acking anything new...
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq); LogNetcode(_L "Received an ack with no window advancement (seq [{}])" __L, seq);
} else if(ord == SeqPast) { } else if(ord == SeqPast) {
//they are nacking blocks going back before our buffer, wtf? //they are nacking blocks going back before our buffer, wtf?
Log(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); LogNetcode(_L "Received an ack with backward window advancement (they gave [{}], our window starts at [{}]). This is bad" __L, seq, SequencedBase);
} else { } else {
Log(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase); LogNetcode(_L "Received an ack up through sequence [{}]. Our base is [{}]" __L, seq, SequencedBase);
//this is a good ack, we get to ack some blocks. //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. seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
while(SequencedBase != seq) { while(SequencedBase != seq) {
if(SequencedQueue.empty()) { if(SequencedQueue.empty()) {
Log(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()); LogNetcode(_L "OUT OF PACKETS acked packet with sequence [{}]. Next send is [{}] before this" __L, (unsigned long)SequencedBase, SequencedQueue.size());
SequencedBase = NextOutSeq; SequencedBase = NextOutSeq;
break; break;
} }
Log(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu." __L, (unsigned long)SequencedBase); LogNetcode(_L "Removing acked packet with sequence [{}]" __L, (unsigned long)SequencedBase);
//clean out the acked packet //clean out the acked packet
delete SequencedQueue.front(); delete SequencedQueue.front();
SequencedQueue.pop_front(); SequencedQueue.pop_front();
@ -1156,7 +1156,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
SequencedBase++; SequencedBase++;
} }
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq); LogNetcode(_L "Post-Ack on [{}] Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
} }
} }
@ -1166,7 +1166,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
void EQStream::SetNextAckToSend(uint32 seq) void EQStream::SetNextAckToSend(uint32 seq)
{ {
MAcks.lock(); MAcks.lock();
Log(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq); LogNetcode(_L "Set Next Ack To Send to [{}]" __L, (unsigned long)seq);
NextAckToSend=seq; NextAckToSend=seq;
MAcks.unlock(); MAcks.unlock();
} }
@ -1174,7 +1174,7 @@ void EQStream::SetNextAckToSend(uint32 seq)
void EQStream::SetLastAckSent(uint32 seq) void EQStream::SetLastAckSent(uint32 seq)
{ {
MAcks.lock(); MAcks.lock();
Log(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq); LogNetcode(_L "Set Last Ack Sent to [{}]" __L, (unsigned long)seq);
LastAckSent=seq; LastAckSent=seq;
MAcks.unlock(); MAcks.unlock();
} }
@ -1187,10 +1187,10 @@ void EQStream::ProcessQueue()
EQProtocolPacket *qp=nullptr; EQProtocolPacket *qp=nullptr;
while((qp=RemoveQueue(NextInSeq))!=nullptr) { while((qp=RemoveQueue(NextInSeq))!=nullptr) {
Log(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq); LogNetcode(_L "Processing Queued Packet: Seq=[{}]" __L, NextInSeq);
ProcessPacket(qp); ProcessPacket(qp);
delete qp; delete qp;
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
} }
} }
@ -1201,21 +1201,21 @@ EQProtocolPacket *qp=nullptr;
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) { if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
qp=itr->second; qp=itr->second;
PacketQueue.erase(itr); PacketQueue.erase(itr);
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
} }
return qp; return qp;
} }
void EQStream::SetStreamType(EQStreamType type) void EQStream::SetStreamType(EQStreamType type)
{ {
Log(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type)); LogNetcode(_L "Changing stream type from [{}] to [{}]" __L, StreamTypeString(StreamType), StreamTypeString(type));
StreamType=type; StreamType=type;
switch (StreamType) { switch (StreamType) {
case LoginStream: case LoginStream:
app_opcode_size=1; app_opcode_size=1;
compressed=false; compressed=false;
encoded=false; encoded=false;
Log(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size); LogNetcode(_L "Login stream has app opcode size [{}], is not compressed or encoded" __L, app_opcode_size);
break; break;
case ChatOrMailStream: case ChatOrMailStream:
case ChatStream: case ChatStream:
@ -1223,7 +1223,7 @@ void EQStream::SetStreamType(EQStreamType type)
app_opcode_size=1; app_opcode_size=1;
compressed=false; compressed=false;
encoded=true; encoded=true;
Log(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size); LogNetcode(_L "Chat/Mail stream has app opcode size [{}], is not compressed, and is encoded" __L, app_opcode_size);
break; break;
case ZoneStream: case ZoneStream:
case WorldStream: case WorldStream:
@ -1231,7 +1231,7 @@ void EQStream::SetStreamType(EQStreamType type)
app_opcode_size=2; app_opcode_size=2;
compressed=true; compressed=true;
encoded=false; encoded=false;
Log(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size); LogNetcode(_L "World/Zone stream has app opcode size [{}], is compressed, and is not encoded" __L, app_opcode_size);
break; break;
} }
} }
@ -1281,7 +1281,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
void EQStream::SetState(EQStreamState state) { void EQStream::SetState(EQStreamState state) {
MState.lock(); MState.lock();
Log(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state); LogNetcode(_L "Changing state from [{}] to [{}]" __L, State, state);
State=state; State=state;
MState.unlock(); MState.unlock();
} }
@ -1293,29 +1293,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
EQStreamState orig_state = GetState(); EQStreamState orig_state = GetState();
if (orig_state == CLOSING && !outgoing_data) { if (orig_state == CLOSING && !outgoing_data) {
Log(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L); LogNetcode(_L "Out of data in closing state, disconnecting" __L);
_SendDisconnect(); _SendDisconnect();
SetState(DISCONNECTING); SetState(DISCONNECTING);
} else if (LastPacket && (now-LastPacket) > timeout) { } else if (LastPacket && (now-LastPacket) > timeout) {
switch(orig_state) { switch(orig_state) {
case CLOSING: case CLOSING:
//if we time out in the closing state, they are not acking us, just give up //if we time out in the closing state, they are not acking us, just give up
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L); LogNetcode(_L "Timeout expired in closing state. Moving to closed state" __L);
_SendDisconnect(); _SendDisconnect();
SetState(CLOSED); SetState(CLOSED);
break; break;
case DISCONNECTING: case DISCONNECTING:
//we timed out waiting for them to send us the disconnect reply, just give up. //we timed out waiting for them to send us the disconnect reply, just give up.
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L); LogNetcode(_L "Timeout expired in disconnecting state. Moving to closed state" __L);
SetState(CLOSED); SetState(CLOSED);
break; break;
case CLOSED: case CLOSED:
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L); LogNetcode(_L "Timeout expired in closed state??" __L);
break; break;
case ESTABLISHED: case ESTABLISHED:
//we timed out during normal operation. Try to be nice about it. //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. //we will almost certainly time out again waiting for the disconnect reply, but oh well.
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L); LogNetcode(_L "Timeout expired in established state. Closing connection" __L);
_SendDisconnect(); _SendDisconnect();
SetState(DISCONNECTING); SetState(DISCONNECTING);
break; break;
@ -1342,7 +1342,7 @@ void EQStream::Decay()
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) { for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) {
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) { if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) {
(*sitr)->sent_time = 0; (*sitr)->sent_time = 0;
Log(Logs::Detail, Logs::Netcode, _L "Timeout exceeded for seq %d. Flagging packet for retransmission" __L, SequencedBase + count); LogNetcode(_L "Timeout exceeded for seq [{}]. Flagging packet for retransmission" __L, SequencedBase + count);
} }
} }
MOutboundQueue.unlock(); MOutboundQueue.unlock();
@ -1384,12 +1384,12 @@ void EQStream::AdjustRates(uint32 average_delta)
void EQStream::Close() { void EQStream::Close() {
if(HasOutgoingData()) { if(HasOutgoingData()) {
//there is pending data, wait for it to go out. //there is pending data, wait for it to go out.
Log(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L); LogNetcode(_L "Stream requested to Close(), but there is pending data, waiting for it" __L);
SetState(CLOSING); SetState(CLOSING);
} else { } else {
//otherwise, we are done, we can drop immediately. //otherwise, we are done, we can drop immediately.
_SendDisconnect(); _SendDisconnect();
Log(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L); LogNetcode(_L "Stream closing immediate due to Close()" __L);
SetState(DISCONNECTING); SetState(DISCONNECTING);
} }
} }
@ -1417,19 +1417,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
} else if(p->opcode == sig->first_eq_opcode) { } else if(p->opcode == sig->first_eq_opcode) {
//opcode matches, check length.. //opcode matches, check length..
if(p->size == sig->first_length) { if(p->size == sig->first_length) {
Log(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); LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length matched [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
res = MatchSuccessful; res = MatchSuccessful;
} else if(sig->first_length == 0) { } else if(sig->first_length == 0) {
Log(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); LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length ([{}]) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
res = MatchSuccessful; res = MatchSuccessful;
} else { } else {
//opcode matched but length did not. //opcode matched but length did not.
Log(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); 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);
res = MatchFailed; res = MatchFailed;
} }
} else { } else {
//first opcode did not match.. //first opcode did not match..
Log(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); LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode {:#04x} did not match expected {:#04x}", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
res = MatchFailed; res = MatchFailed;
} }
} }

View File

@ -46,7 +46,7 @@ void EQStreamIdentifier::Process() {
//first see if this stream has expired //first see if this stream has expired
if(r.expire.Check(false)) { if(r.expire.Check(false)) {
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort())); LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before timeout", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
r.stream->Close(); r.stream->Close();
cur = m_streams.erase(cur); cur = m_streams.erase(cur);
@ -62,23 +62,23 @@ void EQStreamIdentifier::Process() {
} }
if(r.stream->GetState() != ESTABLISHED) { if(r.stream->GetState() != ESTABLISHED) {
//the stream closed before it was identified. //the stream closed before it was identified.
Log(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())); LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before it closed", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
switch(r.stream->GetState()) switch(r.stream->GetState())
{ {
case ESTABLISHED: case ESTABLISHED:
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established"); LogNetcode("[StreamIdentify] Stream state was Established");
break; break;
case CLOSING: case CLOSING:
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing"); LogNetcode("[StreamIdentify] Stream state was Closing");
break; break;
case DISCONNECTING: case DISCONNECTING:
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting"); LogNetcode("[StreamIdentify] Stream state was Disconnecting");
break; break;
case CLOSED: case CLOSED:
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed"); LogNetcode("[StreamIdentify] Stream state was Closed");
break; break;
default: default:
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown"); LogNetcode("[StreamIdentify] Stream state was Unestablished or unknown");
break; break;
} }
r.stream->ReleaseFromUse(); r.stream->ReleaseFromUse();
@ -102,13 +102,13 @@ void EQStreamIdentifier::Process() {
switch(res) { switch(res) {
case EQStreamInterface::MatchNotReady: case EQStreamInterface::MatchNotReady:
//the stream has not received enough packets to compare with this signature //the stream has not received enough packets to compare with this signature
// 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()); // 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());
all_ready = false; all_ready = false;
break; break;
case EQStreamInterface::MatchSuccessful: { case EQStreamInterface::MatchSuccessful: {
//yay, a match. //yay, a match.
Log(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()); LogNetcode("[StreamIdentify] Identified stream [{}:{}] with signature [{}]", 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 // 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); r.stream->SetActive(true);
@ -122,7 +122,7 @@ void EQStreamIdentifier::Process() {
} }
case EQStreamInterface::MatchFailed: case EQStreamInterface::MatchFailed:
//do nothing... //do nothing...
Log(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()); LogNetcode("[StreamIdentify] [{}:{}] Tried patch [{}] and it did not match", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
break; break;
} }
} }
@ -130,7 +130,7 @@ void EQStreamIdentifier::Process() {
//if we checked all patches and did not find a match. //if we checked all patches and did not find a match.
if(all_ready && !found_one) { if(all_ready && !found_one) {
//the stream cannot be identified. //the stream cannot be identified.
Log(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())); LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}], no match found", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
r.stream->ReleaseFromUse(); r.stream->ReleaseFromUse();
} }

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
#include "emu_versions.h" #include "emu_versions.h"
#include "eq_packet.h" #include "eq_packet.h"
#include "net/daybreak_connection.h"
typedef enum { typedef enum {
ESTABLISHED, ESTABLISHED,
@ -18,6 +19,47 @@ typedef enum {
class EQApplicationPacket; class EQApplicationPacket;
class OpcodeManager; 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 { class EQStreamInterface {
public: public:
virtual ~EQStreamInterface() {} virtual ~EQStreamInterface() {}
@ -29,12 +71,20 @@ public:
uint16 first_eq_opcode; uint16 first_eq_opcode;
uint32 first_length; //0=dont check length uint32 first_length; //0=dont check length
}; };
typedef enum { typedef enum {
MatchNotReady, MatchNotReady,
MatchSuccessful, MatchSuccessful,
MatchFailed MatchFailed
} MatchState; } 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 QueuePacket(const EQApplicationPacket *p, bool ack_req=true) = 0;
virtual void FastQueuePacket(EQApplicationPacket **p, bool ack_req=true) = 0; virtual void FastQueuePacket(EQApplicationPacket **p, bool ack_req=true) = 0;
virtual EQApplicationPacket *PopPacket() = 0; virtual EQApplicationPacket *PopPacket() = 0;
@ -50,12 +100,10 @@ public:
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; } virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
virtual EQStreamState GetState() = 0; virtual EQStreamState GetState() = 0;
virtual void SetOpcodeManager(OpcodeManager **opm) = 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 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_*/ #endif /*EQSTREAMINTF_H_*/

View File

@ -42,8 +42,8 @@ void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
return; return;
if (p->GetOpcode() != OP_SpecialMesg) { 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(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
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(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(); EQApplicationPacket *newp = p->Copy();
@ -82,26 +82,6 @@ uint16 EQStreamProxy::GetRemotePort() const {
return(m_stream->GetRemotePort()); 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() { void EQStreamProxy::ReleaseFromUse() {
m_stream->ReleaseFromUse(); m_stream->ReleaseFromUse();
} }
@ -110,6 +90,21 @@ void EQStreamProxy::RemoveData() {
m_stream->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) { bool EQStreamProxy::CheckState(EQStreamState state) {
if(m_stream) if(m_stream)
return(m_stream->CheckState(state)); return(m_stream->CheckState(state));

View File

@ -31,11 +31,9 @@ public:
virtual const EQEmu::versions::ClientVersion ClientVersion() const; virtual const EQEmu::versions::ClientVersion ClientVersion() const;
virtual EQStreamState GetState(); virtual EQStreamState GetState();
virtual void SetOpcodeManager(OpcodeManager **opm); virtual void SetOpcodeManager(OpcodeManager **opm);
virtual Stats GetStats() const;
virtual const uint32 GetBytesSent() const; virtual void ResetStats();
virtual const uint32 GetBytesRecieved() const; virtual EQStreamManagerInterface* GetManager() const;
virtual const uint32 GetBytesSentPerSecond() const;
virtual const uint32 GetBytesRecvPerSecond() const;
protected: protected:
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object. std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.

View File

@ -26,24 +26,26 @@
std::string EQEmuConfig::ConfigFile = "eqemu_config.json"; std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
EQEmuConfig *EQEmuConfig::_config = nullptr; EQEmuConfig *EQEmuConfig::_config = nullptr;
void EQEmuConfig::parse_config() { void EQEmuConfig::parse_config()
{
ShortName = _root["server"]["world"].get("shortname", "").asString(); ShortName = _root["server"]["world"].get("shortname", "").asString();
LongName = _root["server"]["world"].get("longname", "").asString(); LongName = _root["server"]["world"].get("longname", "").asString();
WorldAddress = _root["server"]["world"].get("address", "").asString(); WorldAddress = _root["server"]["world"].get("address", "").asString();
LocalAddress = _root["server"]["world"].get("localaddress", "").asString(); LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str()); MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
SharedKey = _root["server"]["world"].get("key", "").asString(); SharedKey = _root["server"]["world"].get("key", "").asString();
LoginCount = 0; LoginCount = 0;
if (_root["server"]["world"]["loginserver"].isObject()) { if (_root["server"]["world"]["loginserver"].isObject()) {
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString(); LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str()); LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
LoginLegacy = false; LoginLegacy = false;
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") LoginLegacy = true; if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString(); LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString(); LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
} else { }
else {
char str[32]; char str[32];
loginlist.Clear(); loginlist.Clear();
do { do {
@ -53,13 +55,13 @@ void EQEmuConfig::parse_config() {
} }
auto loginconfig = new LoginConfig; auto loginconfig = new LoginConfig;
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString(); 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->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString(); loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString(); loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
loginconfig->LoginLegacy = false; loginconfig->LoginLegacy = false;
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") loginconfig->LoginLegacy = true; if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
loginlist.Insert(loginconfig); loginlist.Insert(loginconfig);
} while (LoginCount < 100); } while (LoginCount < 100);
} }
@ -68,59 +70,87 @@ void EQEmuConfig::parse_config() {
//<locked> from xml converts to json as locked: "", so i default to "false". //<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 //The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false; Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") Locked = true; if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString(); WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str()); WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString(); TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str()); TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
TelnetEnabled = false; TelnetEnabled = false;
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") TelnetEnabled = true; if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString(); WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str()); WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
WorldHTTPEnabled = false; WorldHTTPEnabled = false;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") WorldHTTPEnabled = true;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
WorldHTTPEnabled = true;
}
/**
* UCS
*/
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString(); ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str()); ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString(); MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str()); MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
/**
* Database
*/
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString(); DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
DatabasePassword = _root["server"]["database"].get("password", "eq").asString(); DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString(); DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str()); DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
DatabaseDB = _root["server"]["database"].get("db", "eq").asString(); DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString(); /**
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str()); * 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(); QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString(); QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString(); QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
/**
* Zones
*/
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str()); DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").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()); ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString(); /**
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString(); * Files
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString(); */
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();
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString(); /**
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString(); * Directories
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString(); */
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(); LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
PatchDir = _root["server"]["directories"].get("patches", "./").asString(); PatchDir = _root["server"]["directories"].get("patches", "./").asString();
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString(); SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
LogDir = _root["server"]["directories"].get("logs", "logs/").asString(); LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
/**
* Logs
*/
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString(); LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString(); LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
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()); * 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()); ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
#ifdef WIN32 #ifdef WIN32
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString(); ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
@ -230,6 +260,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "OpCodesFile") { if (var_name == "OpCodesFile") {
return (OpCodesFile); return (OpCodesFile);
} }
if (var_name == "MailOpCodesFile") {
return (MailOpCodesFile);
}
if (var_name == "PluginPlFile") { if (var_name == "PluginPlFile") {
return (PluginPlFile); return (PluginPlFile);
} }
@ -312,6 +345,7 @@ void EQEmuConfig::Dump() const
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl; std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
std::cout << "SpellsFile = " << SpellsFile << std::endl; std::cout << "SpellsFile = " << SpellsFile << std::endl;
std::cout << "OpCodesFile = " << OpCodesFile << std::endl; std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
std::cout << "MailOpcodesFile = " << MailOpCodesFile << std::endl;
std::cout << "PluginPlFile = " << PluginPlFile << std::endl; std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
std::cout << "MapDir = " << MapDir << std::endl; std::cout << "MapDir = " << MapDir << std::endl;
std::cout << "QuestDir = " << QuestDir << std::endl; std::cout << "QuestDir = " << QuestDir << std::endl;
@ -322,6 +356,6 @@ void EQEmuConfig::Dump() const
std::cout << "LogDir = " << LogDir << std::endl; std::cout << "LogDir = " << LogDir << std::endl;
std::cout << "ZonePortLow = " << ZonePortLow << std::endl; std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
std::cout << "ZonePortHigh = " << ZonePortHigh << 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; // std::cout << "DynamicCount = " << DynamicCount << std::endl;
} }

View File

@ -84,6 +84,7 @@ class EQEmuConfig
// From <files/> // From <files/>
std::string SpellsFile; std::string SpellsFile;
std::string OpCodesFile; std::string OpCodesFile;
std::string MailOpCodesFile;
std::string PluginPlFile; std::string PluginPlFile;
// From <directories/> // From <directories/>

View File

@ -19,6 +19,7 @@
*/ */
#include "eqemu_logsys.h" #include "eqemu_logsys.h"
#include "rulesys.h"
#include "platform.h" #include "platform.h"
#include "string_util.h" #include "string_util.h"
#include "database.h" #include "database.h"
@ -81,30 +82,19 @@ namespace Console {
}; };
} }
enum GameChatColor {
yellow = 15,
red = 13,
light_green = 14,
light_cyan = 258,
light_purple = 5
};
/** /**
* EQEmuLogSys Constructor * EQEmuLogSys Constructor
*/ */
EQEmuLogSys::EQEmuLogSys() EQEmuLogSys::EQEmuLogSys()
{ {
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
bool file_logs_enabled = false; on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
int log_platform = 0;
} }
/** /**
* EQEmuLogSys Deconstructor * EQEmuLogSys Deconstructor
*/ */
EQEmuLogSys::~EQEmuLogSys() EQEmuLogSys::~EQEmuLogSys() = default;
{
}
void EQEmuLogSys::LoadLogSettingsDefaults() void EQEmuLogSys::LoadLogSettingsDefaults()
{ {
@ -125,15 +115,26 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
/** /**
* Set Defaults * Set Defaults
*/ */
log_settings[Logs::World_Server].log_to_console = Logs::General; log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Zone_Server].log_to_console = Logs::General; log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::QS_Server].log_to_console = Logs::General; log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::UCS_Server].log_to_console = Logs::General; log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Crash].log_to_console = Logs::General; log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::MySQLError].log_to_console = Logs::General; log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Login_Server].log_to_console = Logs::General; log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Headless_Client].log_to_console = Logs::General; log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::NPCScaling].log_to_gmsay = 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 * Set Category enabled status on defaults
@ -174,20 +175,41 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
} }
} }
/**
* @param log_category
* @return
*/
bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
{
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
);
}
/** /**
* @param log_category * @param log_category
* @param in_message * @param in_message
* @return * @return
*/ */
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message) std::string EQEmuLogSys::FormatOutMessageString(
uint16 log_category,
const std::string &in_message
)
{ {
std::string ret; std::string return_string;
ret.push_back('[');
ret.append(Logs::LogCategoryName[log_category]); if (IsRfc5424LogCategory(log_category)) {
ret.push_back(']'); return_string = "[" + GetPlatformName() + "] ";
ret.push_back(' '); }
ret.append(in_message);
return ret; return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
} }
/** /**
@ -195,7 +217,11 @@ std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::
* @param log_category * @param log_category
* @param message * @param message
*/ */
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &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 * Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
@ -217,7 +243,11 @@ void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const st
* @param log_category * @param log_category
* @param message * @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) { if (log_category == Logs::Crash) {
char time_stamp[80]; char time_stamp[80];
@ -279,6 +309,8 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
case Logs::Normal: case Logs::Normal:
return LC_YELLOW; return LC_YELLOW;
case Logs::MySQLError: case Logs::MySQLError:
case Logs::Warning:
case Logs::Critical:
case Logs::Error: case Logs::Error:
return LC_RED; return LC_RED;
case Logs::MySQLQuery: case Logs::MySQLQuery:
@ -305,22 +337,22 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
switch (log_category) { switch (log_category) {
case Logs::Status: case Logs::Status:
case Logs::Normal: case Logs::Normal:
return GameChatColor::yellow; return Chat::Yellow;
case Logs::MySQLError: case Logs::MySQLError:
case Logs::Error: case Logs::Error:
return GameChatColor::red; return Chat::Red;
case Logs::MySQLQuery: case Logs::MySQLQuery:
case Logs::Debug: case Logs::Debug:
return GameChatColor::light_green; return Chat::Lime;
case Logs::Quests: case Logs::Quests:
return GameChatColor::light_cyan; return Chat::Group;
case Logs::Commands: case Logs::Commands:
case Logs::Mercenaries: case Logs::Mercenaries:
return GameChatColor::light_purple; return Chat::Magenta;
case Logs::Crash: case Logs::Crash:
return GameChatColor::red; return Chat::Red;
default: default:
return GameChatColor::yellow; return Chat::Yellow;
} }
} }
@ -346,6 +378,44 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
#else #else
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl; std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
#endif #endif
on_log_console_hook(debug_level, log_category, message);
}
/**
* @param str
* @return
*/
constexpr const char *str_end(const char *str)
{
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;
} }
/** /**
@ -356,7 +426,15 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
* @param message * @param message
* @param ... * @param ...
*/ */
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...) 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; bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) { if (log_settings[log_category].log_to_console < debug_level) {
@ -378,12 +456,18 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st
return; return;
} }
std::string prefix;
if (RuleB(Logging, PrintFileFunctionAndLine)) {
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
}
va_list args; va_list args;
va_start(args, message); va_start(args, message);
std::string output_message = vStringFormat(message.c_str(), args); std::string output_message = vStringFormat(message, args);
va_end(args); va_end(args);
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message); std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
if (log_to_console) { if (log_to_console) {
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message); EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
@ -419,7 +503,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
return; return;
_mkdir(directory_name.c_str()); _mkdir(directory_name.c_str());
#else #else
struct stat st; struct stat st{};
if (stat(directory_name.c_str(), &st) == 0) { // exists if (stat(directory_name.c_str(), &st) == 0) { // exists
return; return;
} }
@ -460,12 +544,7 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
return; return;
} }
EQEmuLogSys::Out( LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
Logs::General,
Logs::Status,
"Starting File Log 'logs/%s_%i.log'",
platform_file_name.c_str(),
getpid());
/** /**
* Make directory if not exists * Make directory if not exists
@ -485,17 +564,11 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
/** /**
* All other processes * All other processes
*/ */
if (platform_file_name.empty()) { if (platform_file_name.empty()) {
return; return;
} }
EQEmuLogSys::Out( LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
Logs::General,
Logs::Status,
"Starting File Log 'logs/%s_%i.log'",
platform_file_name.c_str(),
getpid());
/** /**
* Open file pointer * Open file pointer

View File

@ -21,11 +21,18 @@
#ifndef EQEMU_LOGSYS_H #ifndef EQEMU_LOGSYS_H
#define EQEMU_LOGSYS_H #define EQEMU_LOGSYS_H
#include <fmt/format.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <stdio.h> #include <stdio.h>
#include <functional> #include <functional>
#ifdef _WIN32
#ifdef utf16_to_utf8
#undef utf16_to_utf8
#endif
#endif
#include <fmt/format.h>
#include "types.h" #include "types.h"
namespace Logs { namespace Logs {
@ -46,7 +53,7 @@ namespace Logs {
AI, AI,
Aggro, Aggro,
Attack, Attack,
Client_Server_Packet, PacketClientServer,
Combat, Combat,
Commands, Commands,
Crash, Crash,
@ -60,40 +67,46 @@ namespace Logs {
Normal, Normal,
Object, Object,
Pathing, Pathing,
QS_Server, QSServer,
Quests, Quests,
Rules, Rules,
Skills, Skills,
Spawns, Spawns,
Spells, Spells,
Status, Status,
TCP_Connection, TCPConnection,
Tasks, Tasks,
Tradeskills, Tradeskills,
Trading, Trading,
Tribute, Tribute,
UCS_Server, UCSServer,
WebInterface_Server, WebInterfaceServer,
World_Server, WorldServer,
Zone_Server, ZoneServer,
MySQLError, MySQLError,
MySQLQuery, MySQLQuery,
Mercenaries, Mercenaries,
QuestDebug, QuestDebug,
Server_Client_Packet, PacketServerClient,
Client_Server_Packet_Unhandled, PacketClientServerUnhandled,
Server_Client_Packet_With_Dump, PacketServerClientWithDump,
Client_Server_Packet_With_Dump, PacketClientServerWithDump,
Login_Server, Loginserver,
Client_Login, ClientLogin,
Headless_Client, HeadlessClient,
HP_Update, HPUpdate,
FixZ, FixZ,
Food, Food,
Traps, Traps,
NPCRoamBox, NPCRoamBox,
NPCScaling, NPCScaling,
MobAppearance, MobAppearance,
Info,
Warning,
Critical,
Emergency,
Alert,
Notice,
MaxCategoryID /* Don't Remove this */ MaxCategoryID /* Don't Remove this */
}; };
@ -153,19 +166,17 @@ namespace Logs {
"Traps", "Traps",
"NPC Roam Box", "NPC Roam Box",
"NPC Scaling", "NPC Scaling",
"Mob Appearance" "Mob Appearance",
"Info",
"Warning",
"Critical",
"Emergency",
"Alert",
"Notice"
}; };
} }
#define Log(debug_level, log_category, message, ...) do {\ #include "eqemu_logsys_log_aliases.h"
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\
} while (0)
#define LogF(debug_level, log_category, message, ...) do {\
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
LogSys.OutF(debug_level, log_category, message, ##__VA_ARGS__);\
} while (0)
class EQEmuLogSys { class EQEmuLogSys {
public: public:
@ -178,6 +189,10 @@ public:
*/ */
void CloseFileLogs(); void CloseFileLogs();
void LoadLogSettingsDefaults(); void LoadLogSettingsDefaults();
/**
* @param directory_name
*/
void MakeDirectory(const std::string &directory_name); void MakeDirectory(const std::string &directory_name);
/** /**
@ -189,20 +204,26 @@ public:
* - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would * - 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 * 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, std::string message, ...); void Out(
Logs::DebugLevel debug_level,
uint16 log_category,
const char *file,
const char *func,
int line,
const char *message,
...
);
/** /**
* Used in file logs to prepend a timestamp entry for logs * Used in file logs to prepend a timestamp entry for logs
* @param time_stamp
*/ */
void SetCurrentTimeStamp(char* time_stamp); void SetCurrentTimeStamp(char* time_stamp);
void StartFileLogs(const std::string &log_name = "");
template <typename... Args> /**
void OutF(Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args) * @param log_name
{ */
std::string log_str = fmt::format(fmt, args...); void StartFileLogs(const std::string &log_name = "");
Out(debug_level, log_category, log_str);
}
/** /**
* LogSettings Struct * LogSettings Struct
@ -226,14 +247,14 @@ public:
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults * These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
* Database loaded via Database::LoadLogSettings(log_settings) * Database loaded via Database::LoadLogSettings(log_settings)
*/ */
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]; LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
bool file_logs_enabled; bool file_logs_enabled = false;
/** /**
* Sets Executable platform (Zone/World/UCS) etc. * Sets Executable platform (Zone/World/UCS) etc.
*/ */
int log_platform; int log_platform = 0;
/** /**
* File name used in writing logs * File name used in writing logs
@ -248,7 +269,15 @@ public:
*/ */
uint16 GetGMSayColorFromCategory(uint16 log_category); uint16 GetGMSayColorFromCategory(uint16 log_category);
void OnLogHookCallBackZone(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; } /**
* @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; }
private: private:
@ -256,6 +285,7 @@ private:
* Callback pointer to zone process for hooking logs to zone using GMSay * 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 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;
/** /**
* Formats log messages like '[Category] This is a log message' * Formats log messages like '[Category] This is a log message'
@ -264,6 +294,7 @@ private:
/** /**
* Linux console color messages mapped by category * Linux console color messages mapped by category
*
* @param log_category * @param log_category
* @return * @return
*/ */
@ -274,11 +305,57 @@ private:
*/ */
uint16 GetWindowsConsoleColorFromCategory(uint16 log_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); 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); 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); void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
/**
* @param log_category
* @return
*/
bool IsRfc5424LogCategory(uint16 log_category);
}; };
extern EQEmuLogSys LogSys; 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)
#endif #endif

View File

@ -0,0 +1,507 @@
/**
* 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
/**
* 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)
/**
* Misc
*/
#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)
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H

View File

@ -1,42 +0,0 @@
#pragma once
#include <functional>
#include "../any.h"
#include "event_loop.h"
namespace EQ {
class BackgroundTask
{
public:
typedef std::function<void(EQEmu::Any&)> BackgroundTaskFunction;
struct BackgroundTaskBaton
{
BackgroundTaskFunction fn;
BackgroundTaskFunction on_finish;
EQEmu::Any data;
};
BackgroundTask(BackgroundTaskFunction fn, BackgroundTaskFunction on_finish, EQEmu::Any data) {
uv_work_t *m_work = new uv_work_t;
memset(m_work, 0, sizeof(uv_work_t));
BackgroundTaskBaton *baton = new BackgroundTaskBaton();
baton->fn = fn;
baton->on_finish = on_finish;
baton->data = data;
m_work->data = baton;
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
baton->fn(baton->data);
}, [](uv_work_t* req, int status) {
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
baton->on_finish(baton->data);
delete baton;
delete req;
});
}
~BackgroundTask() {
}
};
}

View File

@ -9,7 +9,7 @@ namespace EQ
{ {
public: public:
static EventLoop &Get() { static EventLoop &Get() {
static EventLoop inst; static thread_local EventLoop inst;
return inst; return inst;
} }

100
common/event/task.h Normal file
View File

@ -0,0 +1,100 @@
#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;
};
}

View File

@ -0,0 +1,114 @@
#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;
};
}
}

View File

@ -18,6 +18,7 @@
#include "faction.h" #include "faction.h"
#include "races.h" #include "races.h"
#include "rulesys.h"
const char *FactionValueToString(FACTION_VALUE fv) const char *FactionValueToString(FACTION_VALUE fv)
{ {
@ -59,34 +60,31 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
if (fm) { if (fm) {
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod; character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
} }
if (character_value >= 1101) { if (character_value >= RuleI(Faction, AllyFactionMinimum)) {
return FACTION_ALLY; return FACTION_ALLY;
} }
if (character_value >= 701 && character_value <= 1100) { if (character_value >= RuleI(Faction, WarmlyFactionMinimum)) {
return FACTION_WARMLY; return FACTION_WARMLY;
} }
if (character_value >= 401 && character_value <= 700) { if (character_value >= RuleI(Faction, KindlyFactionMinimum)) {
return FACTION_KINDLY; return FACTION_KINDLY;
} }
if (character_value >= 101 && character_value <= 400) { if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
return FACTION_AMIABLE; return FACTION_AMIABLE;
} }
if (character_value >= 0 && character_value <= 100) { if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
return FACTION_INDIFFERENT; return FACTION_INDIFFERENT;
} }
if (character_value >= -100 && character_value <= -1) { if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
return FACTION_APPREHENSIVE; return FACTION_APPREHENSIVE;
} }
if (character_value >= -700 && character_value <= -101) { if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
return FACTION_DUBIOUS; return FACTION_DUBIOUS;
} }
if (character_value >= -999 && character_value <= -701) { if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
return FACTION_THREATENLY; return FACTION_THREATENLY;
} }
if (character_value <= -1000) { return FACTION_SCOWLS;
return FACTION_SCOWLS;
}
return FACTION_INDIFFERENT;
} }
// this function should check if some races have more than one race define // this function should check if some races have more than one race define

4
common/faction.h Normal file → Executable file
View File

@ -50,6 +50,8 @@ struct NPCFactionList {
struct FactionMods struct FactionMods
{ {
int32 base; 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 class_mod;
int32 race_mod; int32 race_mod;
int32 deity_mod; int32 deity_mod;
@ -59,6 +61,8 @@ struct Faction {
int32 id; int32 id;
std::map<std::string, int16> mods; std::map<std::string, int16> mods;
int16 base; 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]; char name[50];
}; };

View File

@ -1,61 +0,0 @@
shallow_clone: true
platform:
- x86
- x64
configuration:
- Debug
- Release
image:
- Visual Studio 2013
- Visual Studio 2015
- Visual Studio 2017
environment:
matrix:
- GLM_ARGUMENTS: -DGLM_TEST_FORCE_PURE=ON
- GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
- GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
matrix:
exclude:
- image: Visual Studio 2013
GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
- image: Visual Studio 2013
configuration: Debug
- image: Visual Studio 2015
platform: x86
- image: Visual Studio 2015
configuration: Debug
- image: Visual Studio 2017
platform: x86
before_build:
- ps: |
mkdir build
cd build
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2013") {
$env:generator="Visual Studio 12 2013"
}
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") {
$env:generator="Visual Studio 14 2015"
}
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2017") {
$env:generator="Visual Studio 15 2017"
}
if ($env:PLATFORM -eq "x64") {
$env:generator="$env:generator Win64"
}
echo generator="$env:generator"
cmake .. -G "$env:generator" -DGLM_QUIET=ON -DGLM_TEST_ENABLE=ON "$env:GLM_ARGUMENTS"
build_script:
- cmake --build . --config %CONFIGURATION% -- /m /v:minimal
test_script:
- ctest -j4 -C %CONFIGURATION%
deploy: off

57
common/glm/.gitignore vendored
View File

@ -1,57 +0,0 @@
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# CMake
CMakeCache.txt
CMakeFiles
cmake_install.cmake
install_manifest.txt
*.cmake
# ^ May need to add future .cmake files as exceptions
# Test logs
Testing/*
# Test input
test/gtc/*.dds
# Project Files
Makefile
*.cbp
*.user
# Misc.
*.log
# local build(s)
build*
/.vs
/CMakeSettings.json
.DS_Store

View File

@ -1,575 +0,0 @@
language: cpp
matrix:
include:
- os: osx
osx_image: xcode6.4
script:
- cmake --version
- mkdir ./build_unknown_release
- cd ./build_unknown_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_DISABLE_AUTO_DETECTION=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++unknown-release"
- os: osx
osx_image: xcode6.4
script:
- cmake --version
- mkdir ./build_pure_98_release
- cd ./build_pure_98_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++98-pure-release"
- os: osx
osx_image: xcode6.4
script:
- cmake --version
- mkdir ./build_pure_ms_release
- cd ./build_pure_ms_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++98-pure-ms-release"
- os: osx
osx_image: xcode6.4
script:
- cmake --version
- mkdir ./build_pure_11_release
- cd ./build_pure_11_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++11-pure-release"
- os: osx
osx_image: xcode6.4
script:
- cmake --version
- mkdir ./build_sse2_11_release
- cd ./build_sse2_11_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++11-sse2-release"
- os: osx
osx_image: xcode8
script:
- cmake --version
- mkdir ./build_pure_14_release
- cd ./build_pure_14_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++14-pure-release"
- os: osx
osx_image: xcode8
script:
- cmake --version
- mkdir ./build_sse3_14_release
- cd ./build_sse3_14_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++14-sse3-release"
- os: osx
osx_image: xcode8
script:
- cmake --version
- mkdir ./build_avx_14_release
- cd ./build_avx_14_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++14-avx-release"
- os: osx
osx_image: xcode8
script:
- cmake --version
- mkdir ./build_avx_14_debug
- cd ./build_avx_14_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++14-avx-debug"
- os: osx
osx_image: xcode10
script:
- cmake --version
- mkdir ./build_pure_17_release
- cd ./build_pure_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++17-pure-release"
- os: osx
osx_image: xcode10
script:
- cmake --version
- mkdir ./build_pure_17_debug
- cd ./build_pure_17_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++17-pure-debug"
- os: osx
osx_image: xcode10
script:
- cmake --version
- mkdir ./build_avx_17_release
- cd ./build_avx_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++17-avx-release"
- os: osx
osx_image: xcode10
script:
- cmake --version
- mkdir ./build_avx_17_debug
- cd ./build_avx_17_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
env:
- MATRIX_EVAL="INFO=C++17-avx-debug"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
env:
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9 && INFO=C++98-pure-release"
script:
- cmake --version
- mkdir ./build_pure_98_release
- cd ./build_pure_98_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
env:
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9 && INFO=C++98-pure-debug"
script:
- cmake --version
- mkdir ./build_pure_98_debug
- cd ./build_pure_98_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
env:
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9 && INFO=C++98-pure-ms"
script:
- cmake --version
- mkdir ./build_pure_ms_release
- cd ./build_pure_ms_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_98=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && INFO=C++11-pure-release"
script:
- cmake --version
- mkdir ./build_pure_11_release
- cd ./build_pure_11_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && INFO=C++11-pure-debug"
script:
- cmake --version
- mkdir ./build_pure_11_debug
- cd ./build_pure_11_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && INFO=C++11-pure-ms"
script:
- cmake --version
- mkdir ./build_pure_ms_release
- cd ./build_pure_ms_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && INFO=C++11-sse3-release"
script:
- cmake --version
- mkdir ./build_sse3_ms_release
- cd ./build_sse3_ms_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_11=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && INFO=C++14-pure-release"
script:
- cmake --version
- mkdir ./build_pure_14_release
- cd ./build_pure_14_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && INFO=C++14-pure-debug"
script:
- cmake --version
- mkdir ./build_pure_14_debug
- cd ./build_pure_14_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && INFO=C++14-pure-ms"
script:
- cmake --version
- mkdir ./build_pure_ms_release
- cd ./build_pure_ms_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && INFO=C++14-sse3-release"
script:
- cmake --version
- mkdir ./build_sse3_ms_release
- cd ./build_sse3_ms_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && INFO=C++17-pure-release"
script:
- cmake --version
- mkdir ./build_pure_17_release
- cd ./build_pure_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && INFO=C++17-sse2-release"
script:
- cmake --version
- mkdir ./build_sse2_17_release
- cd ./build_sse2_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE2=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && INFO=C++17-sse3-release"
script:
- cmake --version
- mkdir ./build_sse3_17_release
- cd ./build_sse3_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && INFO=C++17-avx-release"
script:
- cmake --version
- mkdir ./build_avx_17_release
- cd ./build_avx_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && INFO=C++17-avx2-release"
script:
- cmake --version
- mkdir ./build_avx2_17_release
- cd ./build_avx2_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX2=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
packages:
- clang-3.6
env:
- MATRIX_EVAL="CC=clang-3.6 && CXX=clang++-3.6 && INFO=C++14-pure-release"
script:
- cmake --version
- mkdir ./build_pure_14_release
- cd ./build_pure_14_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
packages:
- clang-3.6
env:
- MATRIX_EVAL="CC=clang-3.6 && CXX=clang++-3.6 && INFO=C++14-pure-debug"
script:
- cmake --version
- mkdir ./build_pure_14_debug
- cd ./build_pure_14_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
packages:
- clang-3.6
env:
- MATRIX_EVAL="CC=clang-3.6 && CXX=clang++-3.6 && INFO=C++14-avx-debug"
script:
- cmake --version
- mkdir ./build_avx_14_debug
- cd ./build_avx_14_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_14=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_AVX=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && INFO=C++17-pure-release"
script:
- cmake --version
- mkdir ./build_pure_17_release
- cd ./build_pure_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && INFO=C++17-pure-debug"
script:
- cmake --version
- mkdir ./build_pure_17_debug
- cd ./build_pure_17_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_FORCE_PURE=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && INFO=C++17-sse3-release"
script:
- cmake --version
- mkdir ./build_sse3_17_release
- cd ./build_sse3_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && INFO=C++17-sse3-debug"
script:
- cmake --version
- mkdir ./build_sse3_17_debug
- cd ./build_sse3_17_debug
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Debug -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSE3=ON ..
- cmake -E time cmake --build .
- ctest
- os: linux
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && INFO=C++17-ssse3-release"
script:
- cmake --version
- mkdir ./build_ssse3_17_release
- cd ./build_ssse3_17_release
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_BUILD_TYPE=Release -DGLM_TEST_ENABLE=ON -DGLM_TEST_ENABLE_CXX_17=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_SIMD_SSSE3=ON ..
- cmake -E time cmake --build .
- ctest
before_install:
- eval "${MATRIX_EVAL}"

View File

@ -1,277 +0,0 @@
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
cmake_policy(VERSION 3.2)
set(GLM_VERSION "0.9.9")
project(glm VERSION ${GLM_VERSION} LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
enable_testing()
option(GLM_QUIET "No CMake Message" OFF)
option(GLM_TEST_ENABLE_CXX_98 "Enable C++ 98" OFF)
option(GLM_TEST_ENABLE_CXX_11 "Enable C++ 11" OFF)
option(GLM_TEST_ENABLE_CXX_14 "Enable C++ 14" OFF)
option(GLM_TEST_ENABLE_CXX_17 "Enable C++ 17" OFF)
option(GLM_TEST_ENABLE_CXX_20 "Enable C++ 20" OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(GLM_TEST_ENABLE_CXX_20)
set(CMAKE_CXX_STANDARD 20)
add_definitions(-DGLM_FORCE_CXX2A)
if(NOT GLM_QUIET)
message(STATUS "GLM: Build with C++20 features")
endif()
elseif(GLM_TEST_ENABLE_CXX_17)
set(CMAKE_CXX_STANDARD 17)
add_definitions(-DGLM_FORCE_CXX17)
if(NOT GLM_QUIET)
message(STATUS "GLM: Build with C++17 features")
endif()
elseif(GLM_TEST_ENABLE_CXX_14)
set(CMAKE_CXX_STANDARD 14)
add_definitions(-DGLM_FORCE_CXX14)
if(NOT GLM_QUIET)
message(STATUS "GLM: Build with C++14 features")
endif()
elseif(GLM_TEST_ENABLE_CXX_11)
set(CMAKE_CXX_STANDARD 11)
add_definitions(-DGLM_FORCE_CXX11)
if(NOT GLM_QUIET)
message(STATUS "GLM: Build with C++11 features")
endif()
elseif(GLM_TEST_ENABLE_CXX_98)
set(CMAKE_CXX_STANDARD 98)
add_definitions(-DGLM_FORCE_CXX98)
if(NOT GLM_QUIET)
message(STATUS "GLM: Build with C++98 features")
endif()
endif()
option(GLM_TEST_ENABLE_LANG_EXTENSIONS "Enable language extensions" OFF)
option(GLM_DISABLE_AUTO_DETECTION "Enable language extensions" OFF)
if(GLM_DISABLE_AUTO_DETECTION)
add_definitions(-DGLM_FORCE_PLATFORM_UNKNOWN -DGLM_FORCE_COMPILER_UNKNOWN -DGLM_FORCE_ARCH_UNKNOWN -DGLM_FORCE_CXX_UNKNOWN)
endif()
if(GLM_TEST_ENABLE_LANG_EXTENSIONS)
set(CMAKE_CXX_EXTENSIONS ON)
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
add_compile_options(-fms-extensions)
endif()
message(STATUS "GLM: Build with C++ language extensions")
else()
set(CMAKE_CXX_EXTENSIONS OFF)
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/Za)
if(MSVC15)
add_compile_options(/permissive-)
endif()
endif()
endif()
option(GLM_TEST_ENABLE_FAST_MATH "Enable fast math optimizations" OFF)
if(GLM_TEST_ENABLE_FAST_MATH)
if(NOT GLM_QUIET)
message(STATUS "GLM: Build with fast math optimizations")
endif()
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
add_compile_options(-ffast-math)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/fp:fast)
endif()
else()
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/fp:precise)
endif()
endif()
option(GLM_TEST_ENABLE "Build unit tests" ON)
option(GLM_TEST_ENABLE_SIMD_SSE2 "Enable SSE2 optimizations" OFF)
option(GLM_TEST_ENABLE_SIMD_SSE3 "Enable SSE3 optimizations" OFF)
option(GLM_TEST_ENABLE_SIMD_SSSE3 "Enable SSSE3 optimizations" OFF)
option(GLM_TEST_ENABLE_SIMD_SSE4_1 "Enable SSE 4.1 optimizations" OFF)
option(GLM_TEST_ENABLE_SIMD_SSE4_2 "Enable SSE 4.2 optimizations" OFF)
option(GLM_TEST_ENABLE_SIMD_AVX "Enable AVX optimizations" OFF)
option(GLM_TEST_ENABLE_SIMD_AVX2 "Enable AVX2 optimizations" OFF)
option(GLM_TEST_FORCE_PURE "Force 'pure' instructions" OFF)
if(GLM_TEST_FORCE_PURE)
add_definitions(-DGLM_FORCE_PURE)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-mfpmath=387)
endif()
message(STATUS "GLM: No SIMD instruction set")
elseif(GLM_TEST_ENABLE_SIMD_AVX2)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-mavx2)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxAVX2)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/arch:AVX2)
endif()
message(STATUS "GLM: AVX2 instruction set")
elseif(GLM_TEST_ENABLE_SIMD_AVX)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-mavx)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxAVX)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/arch:AVX)
endif()
message(STATUS "GLM: AVX instruction set")
elseif(GLM_TEST_ENABLE_SIMD_SSE4_2)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-msse4.2)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxSSE4.2)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
add_compile_options(/arch:SSE2) # VC doesn't support SSE4.2
endif()
message(STATUS "GLM: SSE4.2 instruction set")
elseif(GLM_TEST_ENABLE_SIMD_SSE4_1)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-msse4.1)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxSSE4.1)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
add_compile_options(/arch:SSE2) # VC doesn't support SSE4.1
endif()
message(STATUS "GLM: SSE4.1 instruction set")
elseif(GLM_TEST_ENABLE_SIMD_SSSE3)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-mssse3)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxSSSE3)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
add_compile_options(/arch:SSE2) # VC doesn't support SSSE3
endif()
message(STATUS "GLM: SSSE3 instruction set")
elseif(GLM_TEST_ENABLE_SIMD_SSE3)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-msse3)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxSSE3)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
add_compile_options(/arch:SSE2) # VC doesn't support SSE3
endif()
message(STATUS "GLM: SSE3 instruction set")
elseif(GLM_TEST_ENABLE_SIMD_SSE2)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-msse2)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxSSE2)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
add_compile_options(/arch:SSE2)
endif()
message(STATUS "GLM: SSE2 instruction set")
endif()
# Compiler and default options
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(NOT GLM_QUIET)
message("GLM: Clang - ${CMAKE_CXX_COMPILER_ID} compiler")
endif()
add_compile_options(-Werror -Weverything)
add_compile_options(-Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-c++11-long-long -Wno-padded -Wno-gnu-anonymous-struct -Wno-nested-anon-types)
add_compile_options(-Wno-undefined-reinterpret-cast -Wno-sign-conversion -Wno-unused-variable -Wno-missing-prototypes -Wno-unreachable-code -Wno-missing-variable-declarations -Wno-sign-compare -Wno-global-constructors -Wno-unused-macros -Wno-format-nonliteral)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if(NOT GLM_QUIET)
message("GLM: GCC - ${CMAKE_CXX_COMPILER_ID} compiler")
endif()
add_compile_options(-O2)
add_compile_options(-Wno-long-long)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
if(NOT GLM_QUIET)
message("GLM: Intel - ${CMAKE_CXX_COMPILER_ID} compiler")
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if(NOT GLM_QUIET)
message("GLM: Visual C++ - ${CMAKE_CXX_COMPILER_ID} compiler")
endif()
add_compile_options(/W4 /WX)
add_compile_options(/wd4309 /wd4324 /wd4389 /wd4127 /wd4267 /wd4146 /wd4201 /wd4464 /wd4514 /wd4701 /wd4820 /wd4365)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
include_directories("${PROJECT_SOURCE_DIR}")
add_subdirectory(glm)
add_subdirectory(test)
set(GLM_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/glm")
install(DIRECTORY glm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/glmConfigVersion.cmake" VERSION ${GLM_VERSION} COMPATIBILITY AnyNewerVersion)
# build tree package config
configure_file(cmake/glmBuildConfig.cmake.in glmConfig.cmake @ONLY)
# install tree package config
configure_package_config_file(
cmake/glmConfig.cmake.in
${GLM_INSTALL_CONFIGDIR}/glmConfig.cmake
INSTALL_DESTINATION ${GLM_INSTALL_CONFIGDIR}
PATH_VARS CMAKE_INSTALL_INCLUDEDIR
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${GLM_INSTALL_CONFIGDIR}/glmConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/glmConfigVersion.cmake"
DESTINATION ${GLM_INSTALL_CONFIGDIR})
add_library(glm INTERFACE)
target_include_directories(glm INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
install(TARGETS glm EXPORT glmTargets)
export(EXPORT glmTargets FILE "${CMAKE_CURRENT_BINARY_DIR}/glmTargets.cmake")
install(EXPORT glmTargets FILE glmTargets.cmake DESTINATION ${GLM_INSTALL_CONFIGDIR})
# build pkg-config file
configure_file("./cmake/glm.pc.in" "glm.pc" @ONLY)
# install pkg-config file
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/glm.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
export(PACKAGE glm)
if(NOT TARGET uninstall)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()

View File

@ -1,7 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
includedir=${prefix}/include
Name: GLM
Description: OpenGL Mathematics
Version: @GLM_VERSION@
Cflags: -I${includedir}

View File

@ -1,6 +0,0 @@
set(GLM_VERSION "@GLM_VERSION@")
set(GLM_INCLUDE_DIRS "@CMAKE_CURRENT_SOURCE_DIR@")
if (NOT CMAKE_VERSION VERSION_LESS "3.0")
include("${CMAKE_CURRENT_LIST_DIR}/glmTargets.cmake")
endif()

View File

@ -1,9 +0,0 @@
set(GLM_VERSION "@GLM_VERSION@")
@PACKAGE_INIT@
set_and_check(GLM_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
if (NOT CMAKE_VERSION VERSION_LESS "3.0")
include("${CMAKE_CURRENT_LIST_DIR}/glmTargets.cmake")
endif()

View File

@ -1,26 +0,0 @@
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
if (NOT DEFINED CMAKE_INSTALL_PREFIX)
set (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
endif ()
message(${CMAKE_INSTALL_PREFIX})
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

View File

@ -1,207 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: common.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#func-members">Functions</a> </div>
<div class="headertitle">
<div class="title">common.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00002_source.html">Go to the source code of this file.</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:ga439e60a72eadecfeda2df5449c613a64"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga439e60a72eadecfeda2df5449c613a64"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga439e60a72eadecfeda2df5449c613a64">abs</a> (genType x)</td></tr>
<tr class="separator:ga439e60a72eadecfeda2df5449c613a64"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga81d3abddd0ef0c8de579bc541ecadab6"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga81d3abddd0ef0c8de579bc541ecadab6"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga81d3abddd0ef0c8de579bc541ecadab6">abs</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga81d3abddd0ef0c8de579bc541ecadab6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gafb9d2a645a23aca12d4d6de0104b7657"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gafb9d2a645a23aca12d4d6de0104b7657"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gafb9d2a645a23aca12d4d6de0104b7657">ceil</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:gafb9d2a645a23aca12d4d6de0104b7657"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga7cd77683da6361e297c56443fc70806d"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga7cd77683da6361e297c56443fc70806d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga7cd77683da6361e297c56443fc70806d">clamp</a> (genType x, genType minVal, genType maxVal)</td></tr>
<tr class="separator:ga7cd77683da6361e297c56443fc70806d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gafba2e0674deb5953878d89483cd6323d"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gafba2e0674deb5953878d89483cd6323d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gafba2e0674deb5953878d89483cd6323d">clamp</a> (vec&lt; L, T, Q &gt; const &amp;x, T minVal, T maxVal)</td></tr>
<tr class="separator:gafba2e0674deb5953878d89483cd6323d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaa0f2f12e9108b09e22a3f0b2008a0b5d"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gaa0f2f12e9108b09e22a3f0b2008a0b5d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gaa0f2f12e9108b09e22a3f0b2008a0b5d">clamp</a> (vec&lt; L, T, Q &gt; const &amp;x, vec&lt; L, T, Q &gt; const &amp;minVal, vec&lt; L, T, Q &gt; const &amp;maxVal)</td></tr>
<tr class="separator:gaa0f2f12e9108b09e22a3f0b2008a0b5d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga1425c1c3160ec51214b03a0469a3013d"><td class="memItemLeft" align="right" valign="top">GLM_FUNC_DECL int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00662.html#ga1425c1c3160ec51214b03a0469a3013d">floatBitsToInt</a> (float const &amp;v)</td></tr>
<tr class="separator:ga1425c1c3160ec51214b03a0469a3013d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga99f7d62f78ac5ea3b49bae715c9488ed"><td class="memTemplParams" colspan="2">template&lt;length_t L, qualifier Q&gt; </td></tr>
<tr class="memitem:ga99f7d62f78ac5ea3b49bae715c9488ed"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, int, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga99f7d62f78ac5ea3b49bae715c9488ed">floatBitsToInt</a> (vec&lt; L, float, Q &gt; const &amp;v)</td></tr>
<tr class="separator:ga99f7d62f78ac5ea3b49bae715c9488ed"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga70e0271c34af52f3100c7960e18c3f2b"><td class="memItemLeft" align="right" valign="top">GLM_FUNC_DECL uint&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00662.html#ga70e0271c34af52f3100c7960e18c3f2b">floatBitsToUint</a> (float const &amp;v)</td></tr>
<tr class="separator:ga70e0271c34af52f3100c7960e18c3f2b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga49418ba4c8a60fbbb5d57b705f3e26db"><td class="memTemplParams" colspan="2">template&lt;length_t L, qualifier Q&gt; </td></tr>
<tr class="memitem:ga49418ba4c8a60fbbb5d57b705f3e26db"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, uint, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga49418ba4c8a60fbbb5d57b705f3e26db">floatBitsToUint</a> (vec&lt; L, float, Q &gt; const &amp;v)</td></tr>
<tr class="separator:ga49418ba4c8a60fbbb5d57b705f3e26db"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaa9d0742639e85b29c7c5de11cfd6840d"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gaa9d0742639e85b29c7c5de11cfd6840d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gaa9d0742639e85b29c7c5de11cfd6840d">floor</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:gaa9d0742639e85b29c7c5de11cfd6840d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gad0f444d4b81cc53c3b6edf5aa25078c2"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:gad0f444d4b81cc53c3b6edf5aa25078c2"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gad0f444d4b81cc53c3b6edf5aa25078c2">fma</a> (genType const &amp;a, genType const &amp;b, genType const &amp;c)</td></tr>
<tr class="separator:gad0f444d4b81cc53c3b6edf5aa25078c2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga8ba89e40e55ae5cdf228548f9b7639c7"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga8ba89e40e55ae5cdf228548f9b7639c7"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga8ba89e40e55ae5cdf228548f9b7639c7">fract</a> (genType x)</td></tr>
<tr class="separator:ga8ba89e40e55ae5cdf228548f9b7639c7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga2df623004f634b440d61e018d62c751b"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga2df623004f634b440d61e018d62c751b"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga2df623004f634b440d61e018d62c751b">fract</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga2df623004f634b440d61e018d62c751b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga20620e83544d1a988857a3bc4ebe0e1d"><td class="memTemplParams" colspan="2">template&lt;typename genType , typename genIType &gt; </td></tr>
<tr class="memitem:ga20620e83544d1a988857a3bc4ebe0e1d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga20620e83544d1a988857a3bc4ebe0e1d">frexp</a> (genType const &amp;x, genIType &amp;exp)</td></tr>
<tr class="separator:ga20620e83544d1a988857a3bc4ebe0e1d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga4fb7c21c2dce064b26fd9ccdaf9adcd4"><td class="memItemLeft" align="right" valign="top">GLM_FUNC_DECL float&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00662.html#ga4fb7c21c2dce064b26fd9ccdaf9adcd4">intBitsToFloat</a> (int const &amp;v)</td></tr>
<tr class="separator:ga4fb7c21c2dce064b26fd9ccdaf9adcd4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga7a0a8291a1cf3e1c2aee33030a1bd7b0"><td class="memTemplParams" colspan="2">template&lt;length_t L, qualifier Q&gt; </td></tr>
<tr class="memitem:ga7a0a8291a1cf3e1c2aee33030a1bd7b0"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, float, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga7a0a8291a1cf3e1c2aee33030a1bd7b0">intBitsToFloat</a> (vec&lt; L, int, Q &gt; const &amp;v)</td></tr>
<tr class="separator:ga7a0a8291a1cf3e1c2aee33030a1bd7b0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga2885587c23a106301f20443896365b62"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga2885587c23a106301f20443896365b62"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, bool, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga2885587c23a106301f20443896365b62">isinf</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga2885587c23a106301f20443896365b62"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga29ef934c00306490de837b4746b4e14d"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga29ef934c00306490de837b4746b4e14d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, bool, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga29ef934c00306490de837b4746b4e14d">isnan</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga29ef934c00306490de837b4746b4e14d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga52e319d7289b849ec92055abd4830533"><td class="memTemplParams" colspan="2">template&lt;typename genType , typename genIType &gt; </td></tr>
<tr class="memitem:ga52e319d7289b849ec92055abd4830533"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga52e319d7289b849ec92055abd4830533">ldexp</a> (genType const &amp;x, genIType const &amp;exp)</td></tr>
<tr class="separator:ga52e319d7289b849ec92055abd4830533"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gae02d42887fc5570451f880e3c624b9ac"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:gae02d42887fc5570451f880e3c624b9ac"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gae02d42887fc5570451f880e3c624b9ac">max</a> (genType x, genType y)</td></tr>
<tr class="separator:gae02d42887fc5570451f880e3c624b9ac"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga03e45d6e60d1c36edb00c52edeea0f31"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga03e45d6e60d1c36edb00c52edeea0f31"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga03e45d6e60d1c36edb00c52edeea0f31">max</a> (vec&lt; L, T, Q &gt; const &amp;x, T y)</td></tr>
<tr class="separator:ga03e45d6e60d1c36edb00c52edeea0f31"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gac1fec0c3303b572a6d4697a637213870"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gac1fec0c3303b572a6d4697a637213870"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gac1fec0c3303b572a6d4697a637213870">max</a> (vec&lt; L, T, Q &gt; const &amp;x, vec&lt; L, T, Q &gt; const &amp;y)</td></tr>
<tr class="separator:gac1fec0c3303b572a6d4697a637213870"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga6cf8098827054a270ee36b18e30d471d"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga6cf8098827054a270ee36b18e30d471d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga6cf8098827054a270ee36b18e30d471d">min</a> (genType x, genType y)</td></tr>
<tr class="separator:ga6cf8098827054a270ee36b18e30d471d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaa7d015eba1f9f48519251f4abe69b14d"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gaa7d015eba1f9f48519251f4abe69b14d"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gaa7d015eba1f9f48519251f4abe69b14d">min</a> (vec&lt; L, T, Q &gt; const &amp;x, T y)</td></tr>
<tr class="separator:gaa7d015eba1f9f48519251f4abe69b14d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga31f49ef9e7d1beb003160c5e009b0c48"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga31f49ef9e7d1beb003160c5e009b0c48"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL GLM_CONSTEXPR vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga31f49ef9e7d1beb003160c5e009b0c48">min</a> (vec&lt; L, T, Q &gt; const &amp;x, vec&lt; L, T, Q &gt; const &amp;y)</td></tr>
<tr class="separator:ga31f49ef9e7d1beb003160c5e009b0c48"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga8e93f374aae27d1a88b921860351f8d4"><td class="memTemplParams" colspan="2">template&lt;typename genTypeT , typename genTypeU &gt; </td></tr>
<tr class="memitem:ga8e93f374aae27d1a88b921860351f8d4"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genTypeT&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga8e93f374aae27d1a88b921860351f8d4">mix</a> (genTypeT x, genTypeT y, genTypeU a)</td></tr>
<tr class="separator:ga8e93f374aae27d1a88b921860351f8d4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga9b197a452cd52db3c5c18bac72bd7798"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga9b197a452cd52db3c5c18bac72bd7798"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga9b197a452cd52db3c5c18bac72bd7798">mod</a> (vec&lt; L, T, Q &gt; const &amp;x, vec&lt; L, T, Q &gt; const &amp;y)</td></tr>
<tr class="separator:ga9b197a452cd52db3c5c18bac72bd7798"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga85e33f139b8db1b39b590a5713b9e679"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga85e33f139b8db1b39b590a5713b9e679"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga85e33f139b8db1b39b590a5713b9e679">modf</a> (genType x, genType &amp;i)</td></tr>
<tr class="separator:ga85e33f139b8db1b39b590a5713b9e679"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gafa03aca8c4713e1cc892aa92ca135a7e"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gafa03aca8c4713e1cc892aa92ca135a7e"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gafa03aca8c4713e1cc892aa92ca135a7e">round</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:gafa03aca8c4713e1cc892aa92ca135a7e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga76b81785045a057989a84d99aeeb1578"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga76b81785045a057989a84d99aeeb1578"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga76b81785045a057989a84d99aeeb1578">roundEven</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga76b81785045a057989a84d99aeeb1578"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga1e2e5cfff800056540e32f6c9b604b28"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga1e2e5cfff800056540e32f6c9b604b28"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga1e2e5cfff800056540e32f6c9b604b28">sign</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga1e2e5cfff800056540e32f6c9b604b28"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga562edf7eca082cc5b7a0aaf180436daf"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga562edf7eca082cc5b7a0aaf180436daf"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga562edf7eca082cc5b7a0aaf180436daf">smoothstep</a> (genType edge0, genType edge1, genType x)</td></tr>
<tr class="separator:ga562edf7eca082cc5b7a0aaf180436daf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga015a1261ff23e12650211aa872863cce"><td class="memTemplParams" colspan="2">template&lt;typename genType &gt; </td></tr>
<tr class="memitem:ga015a1261ff23e12650211aa872863cce"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL genType&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga015a1261ff23e12650211aa872863cce">step</a> (genType edge, genType x)</td></tr>
<tr class="separator:ga015a1261ff23e12650211aa872863cce"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga8f9a911a48ef244b51654eaefc81c551"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:ga8f9a911a48ef244b51654eaefc81c551"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga8f9a911a48ef244b51654eaefc81c551">step</a> (T edge, vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:ga8f9a911a48ef244b51654eaefc81c551"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaf4a5fc81619c7d3e8b22f53d4a098c7f"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gaf4a5fc81619c7d3e8b22f53d4a098c7f"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gaf4a5fc81619c7d3e8b22f53d4a098c7f">step</a> (vec&lt; L, T, Q &gt; const &amp;edge, vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:gaf4a5fc81619c7d3e8b22f53d4a098c7f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaf9375e3e06173271d49e6ffa3a334259"><td class="memTemplParams" colspan="2">template&lt;length_t L, typename T , qualifier Q&gt; </td></tr>
<tr class="memitem:gaf9375e3e06173271d49e6ffa3a334259"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, T, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#gaf9375e3e06173271d49e6ffa3a334259">trunc</a> (vec&lt; L, T, Q &gt; const &amp;x)</td></tr>
<tr class="separator:gaf9375e3e06173271d49e6ffa3a334259"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gab2bae0d15dcdca6093f88f76b3975d97"><td class="memItemLeft" align="right" valign="top">GLM_FUNC_DECL float&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00662.html#gab2bae0d15dcdca6093f88f76b3975d97">uintBitsToFloat</a> (uint const &amp;v)</td></tr>
<tr class="separator:gab2bae0d15dcdca6093f88f76b3975d97"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga97f46b5f7b42fe44482e13356eb394ae"><td class="memTemplParams" colspan="2">template&lt;length_t L, qualifier Q&gt; </td></tr>
<tr class="memitem:ga97f46b5f7b42fe44482e13356eb394ae"><td class="memTemplItemLeft" align="right" valign="top">GLM_FUNC_DECL vec&lt; L, float, Q &gt;&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="a00662.html#ga97f46b5f7b42fe44482e13356eb394ae">uintBitsToFloat</a> (vec&lt; L, uint, Q &gt; const &amp;v)</td></tr>
<tr class="separator:ga97f46b5f7b42fe44482e13356eb394ae"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<dl class="section see"><dt>See also</dt><dd><a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a> </dd></dl>
<p class="definition">Definition in file <a class="el" href="a00002_source.html">common.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,81 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: _fixes.hpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">_fixes.hpp</div> </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;<span class="preprocessor">#include &lt;cmath&gt;</span></div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160;</div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160;<span class="preprocessor">#ifdef max</span></div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160;<span class="preprocessor">#undef max</span></div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span>&#160;<span class="preprocessor">#ifdef min</span></div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160;<span class="preprocessor">#undef min</span></div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span>&#160;</div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160;<span class="preprocessor">#ifdef isnan</span></div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160;<span class="preprocessor">#undef isnan</span></div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00017"></a><span class="lineno"> 17</span>&#160;</div><div class="line"><a name="l00019"></a><span class="lineno"> 19</span>&#160;<span class="preprocessor">#ifdef isinf</span></div><div class="line"><a name="l00020"></a><span class="lineno"> 20</span>&#160;<span class="preprocessor">#undef isinf</span></div><div class="line"><a name="l00021"></a><span class="lineno"> 21</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00022"></a><span class="lineno"> 22</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno"> 24</span>&#160;<span class="preprocessor">#ifdef log2</span></div><div class="line"><a name="l00025"></a><span class="lineno"> 25</span>&#160;<span class="preprocessor">#undef log2</span></div><div class="line"><a name="l00026"></a><span class="lineno"> 26</span>&#160;<span class="preprocessor">#endif</span></div><div class="line"><a name="l00027"></a><span class="lineno"> 27</span>&#160;</div></div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,82 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: compute_vector_relational.hpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">compute_vector_relational.hpp</div> </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;<span class="preprocessor">#pragma once</span></div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160;<span class="comment">//#include &quot;compute_common.hpp&quot;</span></div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160;<span class="preprocessor">#include &quot;setup.hpp&quot;</span></div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160;<span class="preprocessor">#include &lt;limits&gt;</span></div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160;<span class="keyword">namespace </span><a class="code" href="a00792.html">glm</a>{</div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span>&#160;<span class="keyword">namespace </span>detail</div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span>&#160;{</div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160; <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keywordtype">bool</span> isFloat&gt;</div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span>&#160; <span class="keyword">struct </span>compute_equal</div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span>&#160; {</div><div class="line"><a name="l00013"></a><span class="lineno"> 13</span>&#160; GLM_FUNC_QUALIFIER GLM_CONSTEXPR <span class="keyword">static</span> <span class="keywordtype">bool</span> call(T a, T b)</div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160; {</div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160; <span class="keywordflow">return</span> a == b;</div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span>&#160; }</div><div class="line"><a name="l00017"></a><span class="lineno"> 17</span>&#160; };</div><div class="line"><a name="l00018"></a><span class="lineno"> 18</span>&#160;<span class="comment">/*</span></div><div class="line"><a name="l00019"></a><span class="lineno"> 19</span>&#160;<span class="comment"> template &lt;typename T&gt;</span></div><div class="line"><a name="l00020"></a><span class="lineno"> 20</span>&#160;<span class="comment"> struct compute_equal&lt;T, true&gt;</span></div><div class="line"><a name="l00021"></a><span class="lineno"> 21</span>&#160;<span class="comment"> {</span></div><div class="line"><a name="l00022"></a><span class="lineno"> 22</span>&#160;<span class="comment"> GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T a, T b)</span></div><div class="line"><a name="l00023"></a><span class="lineno"> 23</span>&#160;<span class="comment"> {</span></div><div class="line"><a name="l00024"></a><span class="lineno"> 24</span>&#160;<span class="comment"> return detail::compute_abs&lt;T, std::numeric_limits&lt;T&gt;::is_signed&gt;::call(b - a) &lt;= static_cast&lt;T&gt;(0);</span></div><div class="line"><a name="l00025"></a><span class="lineno"> 25</span>&#160;<span class="comment"> //return std::memcmp(&amp;a, &amp;b, sizeof(T)) == 0;</span></div><div class="line"><a name="l00026"></a><span class="lineno"> 26</span>&#160;<span class="comment"> }</span></div><div class="line"><a name="l00027"></a><span class="lineno"> 27</span>&#160;<span class="comment"> };</span></div><div class="line"><a name="l00028"></a><span class="lineno"> 28</span>&#160;<span class="comment">*/</span></div><div class="line"><a name="l00029"></a><span class="lineno"> 29</span>&#160;}<span class="comment">//namespace detail</span></div><div class="line"><a name="l00030"></a><span class="lineno"> 30</span>&#160;}<span class="comment">//namespace glm</span></div><div class="ttc" id="a00792_html"><div class="ttname"><a href="a00792.html">glm</a></div><div class="ttdef"><b>Definition:</b> <a href="a00002_source.html#l00020">common.hpp:20</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,82 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_half.hpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_half.hpp</div> </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;<span class="preprocessor">#pragma once</span></div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160;<span class="preprocessor">#include &quot;setup.hpp&quot;</span></div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160;</div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160;<span class="keyword">namespace </span><a class="code" href="a00792.html">glm</a>{</div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160;<span class="keyword">namespace </span>detail</div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160;{</div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span>&#160; <span class="keyword">typedef</span> <span class="keywordtype">short</span> hdata;</div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span>&#160;</div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160; GLM_FUNC_DECL <span class="keywordtype">float</span> toFloat32(hdata value);</div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span>&#160; GLM_FUNC_DECL hdata toFloat16(<span class="keywordtype">float</span> <span class="keyword">const</span>&amp; value);</div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span>&#160;</div><div class="line"><a name="l00013"></a><span class="lineno"> 13</span>&#160;}<span class="comment">//namespace detail</span></div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160;}<span class="comment">//namespace glm</span></div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160;</div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span>&#160;<span class="preprocessor">#include &quot;type_half.inl&quot;</span></div><div class="ttc" id="a00792_html"><div class="ttname"><a href="a00792.html">glm</a></div><div class="ttdef"><b>Definition:</b> <a href="a00002_source.html#l00020">common.hpp:20</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat2x2.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat2x2.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00038_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00038_source.html">type_mat2x2.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat2x3.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat2x3.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00041_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00041_source.html">type_mat2x3.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat2x4.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat2x4.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00044_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00044_source.html">type_mat2x4.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat3x2.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat3x2.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00047_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00047_source.html">type_mat3x2.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat3x3.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat3x3.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00050_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00050_source.html">type_mat3x3.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat3x4.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat3x4.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00053_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00053_source.html">type_mat3x4.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat4x2.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat4x2.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00056_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00056_source.html">type_mat4x2.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat4x3.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat4x3.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00059_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00059_source.html">type_mat4x3.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_mat4x4.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_mat4x4.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00062_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00062_source.html">type_mat4x4.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_vec1.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_vec1.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00068_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00068_source.html">type_vec1.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_vec2.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_vec2.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00071_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00071_source.html">type_vec2.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,87 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>0.9.9 API documenation: type_vec3.hpp File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="logo-mini.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">0.9.9 API documenation
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="dir_d522931ffa1371640980b621734a4381.html">Users</a></li><li class="navelem"><a class="el" href="dir_02cc19cee4c4780485bfe81520450212.html">christophericcio</a></li><li class="navelem"><a class="el" href="dir_54de7df3bc9880881b14ec07f256fd2e.html">Documents</a></li><li class="navelem"><a class="el" href="dir_6399a054f5929b58eaa476233e406ce8.html">Repository</a></li><li class="navelem"><a class="el" href="dir_627f4a52155b61a75c7c4851d7df9027.html">Github</a></li><li class="navelem"><a class="el" href="dir_ffdfd01cf51cdb2fe8bd5e55c6e0c4e8.html">glm</a></li><li class="navelem"><a class="el" href="dir_4ca6aa55b50e6be994025af27820140e.html">glm</a></li><li class="navelem"><a class="el" href="dir_2c9f37f6a8d2004101d7524672238505.html">detail</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">type_vec3.hpp File Reference</div> </div>
</div><!--header-->
<div class="contents">
<p><a href="a00074_source.html">Go to the source code of this file.</a></p>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p><a class="el" href="a00698.html">Core features</a> </p>
<p class="definition">Definition in file <a class="el" href="a00074_source.html">type_vec3.hpp</a>.</p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>

File diff suppressed because one or more lines are too long

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