diff --git a/.appveyor.yml b/.appveyor.yml
index 6bbe22d5..7b5dacf3 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,16 +1,14 @@
os:
- - Visual Studio 2015
+ - Visual Studio 2017
configuration:
- Debug
platform:
- - Win32
+ - Win64
environment:
MSVC_DEFAULT_OPTIONS: ON
- BOOST_ROOT_DIR: "C:\\Libraries\\boost_1_63_0"
- BOOST_LIB_DIR: "C:\\Libraries\\boost_1_63_0\\lib32-msvc-14.0"
MYSQL_PWD: "Password12!"
services:
@@ -22,7 +20,7 @@ before_build:
- git submodule update --init
- mkdir build
- cd build
- - cmake .. -G "Visual Studio 14 2015"
+ - cmake .. -G "Visual Studio 15 2017 Win64"
- cmake --build . --target ALL_BUILD --config Debug
build_script:
diff --git a/.gitmodules b/.gitmodules
index 14f0cb00..69f7a3a6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,6 @@
-[submodule "src/libraries"]
- path = src/libraries
- url = https://github.com/SapphireMordred/SapphireLibs.git
- ignore = dirty
+[submodule "deps/asio"]
+ path = deps/asio
+ url = https://github.com/chriskohlhoff/asio.git
+[submodule "deps/spdlog"]
+ path = deps/spdlog
+ url = https://github.com/gabime/spdlog.git
diff --git a/.travis.yml b/.travis.yml
index 017917dd..3df10328 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,7 @@ matrix:
- clang-6.0
- g++-7
env:
- - MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0"
+ - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
# Setup cache
cache:
@@ -32,7 +32,6 @@ before_install:
- gem install --no-ri --no-rdoc mtime_cache
- sudo add-apt-repository -y ppa:rexut/recoil
- sudo apt-get update
- - sudo apt-get install -y libboost1.63-dev libboost1.63-all-dev
- sudo apt-get install -y libmysqlclient-dev
# Build steps
@@ -41,6 +40,6 @@ script:
- mtime_cache src/**/*.{%{cpp}} -c .mtime_cache/cache.json
- mkdir -p build
- cd build
- - cmake .. -DSAPPHIRE_BOOST_VER="1.63.0" && make -j 3
+ - cmake .. && make -j 3
- cd ..
- bash sql_import.sh
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b9b359a5..4e82357f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,33 +1,17 @@
-cmake_policy(SET CMP0014 NEW)
-cmake_minimum_required(VERSION 3.0.2)
-project (Sapphire)
+cmake_policy( SET CMP0014 NEW )
+cmake_minimum_required( VERSION 3.0.2 )
+project( Sapphire )
-set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
+set( CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin )
-set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
-set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
-set(EXECUTABLE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
+set( EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin )
+set( LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin )
+set( EXECUTABLE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin )
-set(PROJECT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
-
-##########################################################################
-# Boost stuff
-
-# set(Boost_DEBUG 1)
-
-if( NOT SAPPHIRE_BOOST_VER )
- set( SAPPHIRE_BOOST_VER 1.63.0 )
-endif()
-set( SAPPHIRE_BOOST_FOLDER_NAME boost_1_63_0 )
-
-##########################################################################
-# Common and library path
-set( LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/libraries" )
+set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake )
##########################################################################
# Dependencies and compiler settings
-include( "cmake/boost.cmake" )
include( "cmake/mysql.cmake" )
include( "cmake/compiler.cmake" )
include( "cmake/cotire.cmake" )
@@ -40,12 +24,20 @@ git_describe( VERSION --all --dirty=-d )
configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/src/common/Version.cpp.in"
"${CMAKE_CURRENT_SOURCE_DIR}/src/common/Version.cpp" @ONLY )
+##############################
+# Mysql #
+##############################
+find_package( MySQL )
+
##########################################################################
-add_subdirectory( "src/libraries/sapphire/datReader" )
-add_subdirectory( "src/libraries/sapphire/mysqlConnector" )
+add_subdirectory( "deps/zlib" )
+add_subdirectory( "deps/MySQL" )
+add_subdirectory( "deps/datReader" )
+add_subdirectory( "deps/mysqlConnector" )
add_subdirectory( "src/common" )
add_subdirectory( "src/servers" )
+#add_subdirectory( "src/dbm" )
add_subdirectory( "src/tools/exd_common_gen" )
add_subdirectory( "src/tools/exd_struct_gen" )
@@ -53,5 +45,5 @@ add_subdirectory( "src/tools/exd_struct_test" )
add_subdirectory( "src/tools/quest_parser" )
add_subdirectory( "src/tools/discovery_parser" )
add_subdirectory( "src/tools/mob_parse" )
-#add_subdirectory("src/tools/pcb_reader")
-#add_subdirectory("src/tools/event_object_parser")
+add_subdirectory( "src/tools/pcb_reader" )
+add_subdirectory( "src/tools/event_object_parser" )
diff --git a/CMakeSettings.json b/CMakeSettings.json
index 90e895cd..c623adf2 100644
--- a/CMakeSettings.json
+++ b/CMakeSettings.json
@@ -1,75 +1,13 @@
{
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"configurations": [
- {
- "name": "x86-Debug",
- "generator": "Visual Studio 14 2015",
- "configurationType": "Debug",
- "buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"Debug\"",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc140"
- }
- ]
- },
- {
- "name": "x86-Release",
- "generator": "Visual Studio 14 2015",
- "configurationType": "Release",
- "buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc140"
- }
- ]
- },
- {
- "name": "x64-Debug",
- "generator": "Visual Studio 14 2015 Win64",
- "configurationType": "Debug",
- "buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"Debug\"",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc140"
- }
- ]
- },
- {
- "name": "x64-Release",
- "generator": "Visual Studio 14 2015 Win64",
- "configurationType": "Release",
- "buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc140"
- }
- ]
- },
{
"name": "x86-Debug",
"generator": "Visual Studio 15 2017",
"configurationType": "Debug",
"buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"Debug\"",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc141"
- }
- ]
+ "buildCommandArgs": "-m -v:minimal"
},
{
"name": "x86-Release",
@@ -77,13 +15,7 @@
"configurationType": "Release",
"buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc141"
- }
- ]
+ "buildCommandArgs": "-m -v:minimal"
},
{
"name": "x64-Debug",
@@ -91,13 +23,7 @@
"configurationType": "Debug",
"buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"Debug\"",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc141"
- }
- ]
+ "buildCommandArgs": "-m -v:minimal"
},
{
"name": "x64-Release",
@@ -105,13 +31,7 @@
"configurationType": "Release",
"buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "",
- "buildCommandArgs": "-m -v:minimal",
- "variables": [
- {
- "name": "Boost_COMPILER",
- "value": "-vc141"
- }
- ]
+ "buildCommandArgs": "-m -v:minimal"
}
]
}
diff --git a/README.md b/README.md
index 2b7b3878..0626bdf5 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,13 @@
# Sapphire - FINAL FANTASY XIV Server Emulator
+
+
+
+
+
[](https://discord.gg/xxcdCER)
[](https://travis-ci.org/SapphireMordred/Sapphire)
[](https://ci.appveyor.com/project/SapphireMordred/Sapphire)
-
+
Sapphire is a FINAL FANTASY XIV 4.0+ Server Emulator currently in development.
@@ -13,8 +18,7 @@ Sapphire requires the following software:
| *Name* | *Windows* | *Linux* |
| ------ | --------- | ------- |
-| CMake 3.0.2+ and C++14 capable compiler | [Visual Studio 2017](https://www.visualstudio.com/) | `gcc 4.9` and `g++ 4.9` or newer |
-| Boost 1.63.0 | [Win32 precompiled binaries](https://sourceforge.net/projects/boost/files/boost-binaries/1.63.0/boost_1_63_0-msvc-14.0-32.exe/download) | Boost libraries from your distribution's package manager |
+| CMake 3.0.2+ and C++17 capable compiler | [Visual Studio 2017](https://www.visualstudio.com/) | `gcc 7` and `g++ 7` or newer |
| MySQL Server 5.7 | [Official Site](https://dev.mysql.com/downloads/mysql/) | MySQL server from your distribution's package manager |
Please check the [wiki](https://github.com/SapphireMordred/Sapphire/wiki) for detailed installation/build instructions for your OS.
diff --git a/bin/config/config.ini.default b/bin/config/config.ini.default
new file mode 100644
index 00000000..4c11b849
--- /dev/null
+++ b/bin/config/config.ini.default
@@ -0,0 +1,58 @@
+[Database]
+Host = 127.0.0.1
+Port = 3306
+Database = sapphire
+Username = sapphire
+Password =
+SyncThreads = 2
+AsyncThreads = 2
+
+[GlobalParameters]
+ServerSecret = default
+DataPath = C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack
+
+[GlobalNetwork]
+; Values definining how Users and other servers will access - these have to be set to your public IP when running a public server
+ZoneHost = 127.0.0.1
+ZonePort = 54992
+
+LobbyHost = 127.0.0.1
+LobbyPort = 54994
+
+RestHost = 127.0.0.1
+RestPort = 80
+
+[Lobby]
+WorldID = 67
+AllowNoSessionConnect = false
+WorldName = Sapphire
+
+[LobbyNetwork]
+ListenIp = 0.0.0.0
+ListenPort = 54994
+
+[CharacterCreation]
+DefaultGMRank = 255
+
+[RestNetwork]
+ListenIp = 0.0.0.0
+ListenPort = 80
+
+[Scripts]
+; where compiled script modules are located
+Path = ./compiledscripts/
+; relative to Path, where we copy and load modules from
+CachePath = ./cache/
+; whether we should detect changes to script modules and reload them
+HotSwap = true
+
+[Network]
+DisconnectTimeout = 20
+
+[ZoneNetwork]
+ListenIp = 0.0.0.0
+ListenPort = 54992
+
+[General]
+; Sent on login - each line must be shorter than 307 characters, split lines with ';'
+MotD = Welcome to Sapphire!;This is a very good server;You can change these messages by editing General.MotD in config/zone.ini
\ No newline at end of file
diff --git a/bin/config/global.ini.default b/bin/config/global.ini.default
deleted file mode 100644
index 072d3f7c..00000000
--- a/bin/config/global.ini.default
+++ /dev/null
@@ -1,23 +0,0 @@
-[Database]
-Host = 127.0.0.1
-Port = 3306
-Database = sapphire
-Username = root
-Password =
-SyncThreads = 2
-AsyncThreads = 2
-
-[GlobalParameters]
-ServerSecret = default
-DataPath = C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack
-
-[GlobalNetwork]
-; Values definining how Users and other servers will access - these have to be set to your public IP when running a public server
-ZoneHost = 127.0.0.1
-ZonePort = 54992
-
-LobbyHost = 127.0.0.1
-LobbyPort = 54994
-
-RestHost = 127.0.0.1
-RestPort = 80
\ No newline at end of file
diff --git a/bin/config/lobby.ini.default b/bin/config/lobby.ini.default
deleted file mode 100644
index 077e947c..00000000
--- a/bin/config/lobby.ini.default
+++ /dev/null
@@ -1,8 +0,0 @@
-[Lobby]
-WorldID = 67
-AllowNoSessionConnect = false
-WorldName = Sapphire
-
-[LobbyNetwork]
-ListenIp = 0.0.0.0
-ListenPort = 54994
\ No newline at end of file
diff --git a/bin/config/rest.ini.default b/bin/config/rest.ini.default
deleted file mode 100644
index d51b4967..00000000
--- a/bin/config/rest.ini.default
+++ /dev/null
@@ -1,6 +0,0 @@
-[CharacterCreation]
-DefaultGMRank = 255
-
-[RestNetwork]
-ListenIp = 0.0.0.0
-ListenPort = 80
\ No newline at end of file
diff --git a/bin/config/zone.ini.default b/bin/config/zone.ini.default
deleted file mode 100644
index 7631e9eb..00000000
--- a/bin/config/zone.ini.default
+++ /dev/null
@@ -1,18 +0,0 @@
-[Scripts]
-; where compiled script modules are located
-Path = ./compiledscripts/
-; relative to Path, where we copy and load modules from
-CachePath = ./cache/
-; whether we should detect changes to script modules and reload them
-HotSwap = true
-
-[Network]
-DisconnectTimeout = 20
-
-[ZoneNetwork]
-ListenIp = 0.0.0.0
-ListenPort = 54992
-
-[General]
-; Sent on login - each line must be shorter than 307 characters, split lines with ';'
-MotD = Welcome to Sapphire!;This is a very good server;You can change these messages by editing General.MotD in config/zone.ini
\ No newline at end of file
diff --git a/bin/zlib1.dll b/bin/zlib1.dll
deleted file mode 100644
index ea747b42..00000000
Binary files a/bin/zlib1.dll and /dev/null differ
diff --git a/cmake/FindMySQL.cmake b/cmake/FindMySQL.cmake
new file mode 100644
index 00000000..5fd19dae
--- /dev/null
+++ b/cmake/FindMySQL.cmake
@@ -0,0 +1,291 @@
+#
+# Find the MySQL client includes and library
+#
+
+# This module defines
+# MYSQL_INCLUDE_DIR, where to find mysql.h
+# MYSQL_LIBRARIES, the libraries to link against to connect to MySQL
+# MYSQL_EXECUTABLE, the MySQL executable.
+# MYSQL_FOUND, if false, you cannot build anything that requires MySQL.
+
+# also defined, but not for general use are
+# MYSQL_LIBRARY, where to find the MySQL library.
+
+set( MYSQL_FOUND 0 )
+
+if( UNIX )
+ set(MYSQL_CONFIG_PREFER_PATH "$ENV{MYSQL_HOME}/bin" CACHE FILEPATH
+ "preferred path to MySQL (mysql_config)"
+ )
+
+ find_program(MYSQL_CONFIG mysql_config
+ ${MYSQL_CONFIG_PREFER_PATH}
+ /usr/local/mysql/bin/
+ /usr/local/bin/
+ /usr/bin/
+ )
+
+ if( MYSQL_CONFIG )
+ message(STATUS "Using mysql-config: ${MYSQL_CONFIG}")
+ # set INCLUDE_DIR
+ exec_program(${MYSQL_CONFIG}
+ ARGS --include
+ OUTPUT_VARIABLE MY_TMP
+ )
+
+ string(REGEX REPLACE "-I([^ ]*)( .*)?" "\\1" MY_TMP "${MY_TMP}")
+ set(MYSQL_ADD_INCLUDE_PATH ${MY_TMP} CACHE FILEPATH INTERNAL)
+ #message("[DEBUG] MYSQL ADD_INCLUDE_PATH : ${MYSQL_ADD_INCLUDE_PATH}")
+ # set LIBRARY_DIR
+ exec_program(${MYSQL_CONFIG}
+ ARGS --libs_r
+ OUTPUT_VARIABLE MY_TMP
+ )
+ set(MYSQL_ADD_LIBRARIES "")
+ string(REGEX MATCHALL "-l[^ ]*" MYSQL_LIB_LIST "${MY_TMP}")
+ foreach(LIB ${MYSQL_LIB_LIST})
+ string(REGEX REPLACE "[ ]*-l([^ ]*)" "\\1" LIB "${LIB}")
+ list(APPEND MYSQL_ADD_LIBRARIES "${LIB}")
+ #message("[DEBUG] MYSQL ADD_LIBRARIES : ${MYSQL_ADD_LIBRARIES}")
+ endforeach(LIB ${MYSQL_LIB_LIST})
+
+ set(MYSQL_ADD_LIBRARIES_PATH "")
+ string(REGEX MATCHALL "-L[^ ]*" MYSQL_LIBDIR_LIST "${MY_TMP}")
+ foreach(LIB ${MYSQL_LIBDIR_LIST})
+ string(REGEX REPLACE "[ ]*-L([^ ]*)" "\\1" LIB "${LIB}")
+ list(APPEND MYSQL_ADD_LIBRARIES_PATH "${LIB}")
+ #message("[DEBUG] MYSQL ADD_LIBRARIES_PATH : ${MYSQL_ADD_LIBRARIES_PATH}")
+ endforeach(LIB ${MYSQL_LIBS})
+
+ else( MYSQL_CONFIG )
+ set(MYSQL_ADD_LIBRARIES "")
+ list(APPEND MYSQL_ADD_LIBRARIES "mysqlclient_r")
+ endif( MYSQL_CONFIG )
+endif( UNIX )
+
+if( WIN32 )
+ # read environment variables and change \ to /
+ SET(PROGRAM_FILES_32 $ENV{ProgramFiles})
+ if (${PROGRAM_FILES_32})
+ STRING(REPLACE "\\\\" "/" PROGRAM_FILES_32 ${PROGRAM_FILES_32})
+ endif(${PROGRAM_FILES_32})
+
+ SET(PROGRAM_FILES_64 $ENV{ProgramW6432})
+ if (${PROGRAM_FILES_64})
+ STRING(REPLACE "\\\\" "/" PROGRAM_FILES_64 ${PROGRAM_FILES_64})
+ endif(${PROGRAM_FILES_64})
+endif ( WIN32 )
+
+find_path(MYSQL_INCLUDE_DIR
+ NAMES
+ mysql.h
+ PATHS
+ ${MYSQL_ADD_INCLUDE_PATH}
+ /usr/include
+ /usr/include/mysql
+ /usr/local/include
+ /usr/local/include/mysql
+ /usr/local/mysql/include
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.7/include"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.6/include"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.5/include"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.1/include"
+ "${PROGRAM_FILES_32}/MySQL/include"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/include"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.6/include"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.5/include"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.1/include"
+ "${PROGRAM_FILES_64}/MySQL/include"
+ "C:/MySQL/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.7;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/include"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.7/include"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.6/include"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.5/include"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.1/include"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.7/include"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.6/include"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.5/include"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.1/include"
+ "c:/msys/local/include"
+ "$ENV{MYSQL_ROOT}/include"
+ DOC
+ "Specify the directory containing mysql.h."
+)
+
+if( UNIX )
+ foreach(LIB ${MYSQL_ADD_LIBRARIES})
+ find_library( MYSQL_LIBRARY
+ NAMES
+ mysql libmysql ${LIB}
+ PATHS
+ ${MYSQL_ADD_LIBRARIES_PATH}
+ /usr/lib
+ /usr/lib/mysql
+ /usr/local/lib
+ /usr/local/lib/mysql
+ /usr/local/mysql/lib
+ DOC "Specify the location of the mysql library here."
+ )
+ endforeach(LIB ${MYSQL_ADD_LIBRARY})
+endif( UNIX )
+
+if( WIN32 )
+ find_library( MYSQL_LIBRARY
+ NAMES
+ libmysql
+ PATHS
+ ${MYSQL_ADD_LIBRARIES_PATH}
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.7/lib"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.6/lib"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.5/lib"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.1/lib"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.7/lib/opt"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.6/lib/opt"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.5/lib/opt"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.1/lib/opt"
+ "${PROGRAM_FILES_32}/MySQL/lib"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/lib"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.6/lib"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.5/lib"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.1/lib"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/lib/opt"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.6/lib/opt"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.5/lib/opt"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.1/lib/opt"
+ "${PROGRAM_FILES_64}/MySQL/lib"
+ "C:/MySQL/lib/debug"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.7;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.7;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/lib/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/lib/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.7/lib/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.6/lib/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.5/lib/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.1/lib/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.7/lib/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.6/lib/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.5/lib/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.1/lib/opt"
+ "c:/msys/local/include"
+ "$ENV{MYSQL_ROOT}/lib"
+ DOC "Specify the location of the mysql library here."
+ )
+endif( WIN32 )
+
+# On Windows you typically don't need to include any extra libraries
+# to build MYSQL stuff.
+
+if( NOT WIN32 )
+ find_library( MYSQL_EXTRA_LIBRARIES
+ NAMES
+ z zlib
+ PATHS
+ /usr/lib
+ /usr/local/lib
+ DOC
+ "if more libraries are necessary to link in a MySQL client (typically zlib), specify them here."
+ )
+else( NOT WIN32 )
+ set( MYSQL_EXTRA_LIBRARIES "" )
+endif( NOT WIN32 )
+
+if( UNIX )
+ find_program(MYSQL_EXECUTABLE mysql
+ PATHS
+ ${MYSQL_CONFIG_PREFER_PATH}
+ /usr/local/mysql/bin/
+ /usr/local/bin/
+ /usr/bin/
+ DOC
+ "path to your mysql binary."
+ )
+endif( UNIX )
+
+if( WIN32 )
+ find_program(MYSQL_EXECUTABLE mysql
+ PATHS
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.7/bin"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.6/bin"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.5/bin"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.1/bin"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.7/bin/opt"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.6/bin/opt"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.5/bin/opt"
+ "${PROGRAM_FILES_32}/MySQL/MySQL Server 5.1/bin/opt"
+ "${PROGRAM_FILES_32}/MySQL/bin"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/bin"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.6/bin"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.5/bin"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.1/bin"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/bin/opt"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.6/bin/opt"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.5/bin/opt"
+ "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.1/bin/opt"
+ "${PROGRAM_FILES_64}/MySQL/bin"
+ "C:/MySQL/bin/debug"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.7;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.7;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.6;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.5;Location]/bin/opt"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.1;Location]/bin/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.7/bin/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.6/bin/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.5/bin/opt"
+ "$ENV{ProgramFiles}/MySQL/MySQL Server 5.1/bin/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.7/bin/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.6/bin/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.5/bin/opt"
+ "$ENV{SystemDrive}/MySQL/MySQL Server 5.1/bin/opt"
+ "c:/msys/local/include"
+ "$ENV{MYSQL_ROOT}/bin"
+ DOC
+ "path to your mysql binary."
+ )
+endif( WIN32 )
+
+if( MYSQL_LIBRARY )
+ if( MYSQL_INCLUDE_DIR )
+ set( MYSQL_FOUND 1 )
+ message(STATUS "Found MySQL library: ${MYSQL_LIBRARY}")
+ message(STATUS "Found MySQL headers: ${MYSQL_INCLUDE_DIR}")
+ else( MYSQL_INCLUDE_DIR )
+ message(FATAL_ERROR "Could not find MySQL headers! Please install the development libraries and headers")
+ endif( MYSQL_INCLUDE_DIR )
+ if( MYSQL_EXECUTABLE )
+ message(STATUS "Found MySQL executable: ${MYSQL_EXECUTABLE}")
+ endif( MYSQL_EXECUTABLE )
+ mark_as_advanced( MYSQL_FOUND MYSQL_LIBRARY MYSQL_EXTRA_LIBRARIES MYSQL_INCLUDE_DIR MYSQL_EXECUTABLE)
+else( MYSQL_LIBRARY )
+ message(FATAL_ERROR "Could not find the MySQL libraries! Please install the development libraries and headers")
+endif( MYSQL_LIBRARY )
+
diff --git a/cmake/boost.cmake b/cmake/boost.cmake
deleted file mode 100644
index 3e1c37ef..00000000
--- a/cmake/boost.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-
-if(UNIX)
-
- find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS system)
- if(Boost_FOUND)
- set(BOOST_LIBRARY_DIR ${Boost_LIBRARY_DIR})
- else()
- if (EXISTS /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME})
- set(Boost_INCLUDE_DIR /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME})
- set(BOOST_LIBRARYDIR /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME}/stage/lib)
- else()
- message(FATAL_ERROR "Unable to find boost ${SAPPHIRE_BOOST_VER} package!")
- endif()
- endif()
-else()
-
- if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/external/${SAPPHIRE_BOOST_FOLDER_NAME})
- message(STATUS "Using boost in /libraries/external")
- set(Boost_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/external/${SAPPHIRE_BOOST_FOLDER_NAME})
- set(BOOST_LIBRARYDIR ${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/external/${SAPPHIRE_BOOST_FOLDER_NAME}/lib32-msvc-14.0)
- else()
- find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS system)
- if(Boost_FOUND)
- set(BOOST_LIBRARY_DIR ${Boost_LIBRARY_DIR})
- elseif ((EXISTS $ENV{BOOST_ROOT_DIR}) AND (EXISTS $ENV{BOOST_LIB_DIR}))
- set(Boost_INCLUDE_DIR $ENV{BOOST_ROOT_DIR})
- set(BOOST_LIBRARYDIR $ENV{BOOST_LIB_DIR})
- else()
- message(FATAL_ERROR "SapphireError: Unable to find boost ${SAPPHIRE_BOOST_VER} package and environment variables BOOST_ROOT_DIR and BOOST_LIB_DIR not set!")
- endif()
- endif()
-endif()
-
-set(Boost_USE_STATIC_LIBS ON)
-
-find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system)
-include_directories(${Boost_INCLUDE_DIR})
-link_directories(${BOOST_LIBRARYDIR})
-
diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake
index 20bab671..9ef1ee51 100644
--- a/cmake/compiler.cmake
+++ b/cmake/compiler.cmake
@@ -1,10 +1,11 @@
if(UNIX)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
else()
add_definitions(-D_WIN32_WINNT=0x601)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+ add_definitions(-DNOMINMAX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
@@ -16,7 +17,7 @@ else()
# edit and continue
message(STATUS "Enabling Edit and Continue..")
- add_definitions(/ZI)
+ add_definitions(/Zi)
# incremental linking
message(STATUS "Enabling Incremental Linking..")
@@ -28,4 +29,5 @@ else()
endif()
endif()
-
+# force standalone asio
+add_definitions( -DASIO_STANDALONE )
diff --git a/deps/MySQL/CMakeLists.txt b/deps/MySQL/CMakeLists.txt
new file mode 100644
index 00000000..bed5a1e8
--- /dev/null
+++ b/deps/MySQL/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2008-2018 TrinityCore
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+if (NOT MYSQL_FOUND)
+ message(FATAL_ERROR "MySQL wasn't found on your system but it's required to build the servers!")
+endif()
+
+add_library(mysql STATIC IMPORTED GLOBAL)
+
+set_target_properties(mysql
+ PROPERTIES
+ IMPORTED_LOCATION
+ "${MYSQL_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES
+"${MYSQL_INCLUDE_DIR}")
diff --git a/deps/asio b/deps/asio
new file mode 160000
index 00000000..28d9b8d6
--- /dev/null
+++ b/deps/asio
@@ -0,0 +1 @@
+Subproject commit 28d9b8d6df708024af5227c551673fdb2519f5bf
diff --git a/deps/datReader/CMakeLists.txt b/deps/datReader/CMakeLists.txt
new file mode 100644
index 00000000..a8c7ec6c
--- /dev/null
+++ b/deps/datReader/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 3.0.2)
+project(Sapphire)
+
+include_directories( "../" )
+
+file( GLOB UTILS_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*" )
+file( GLOB UTILS_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*" )
+
+set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
+
+add_library( xivdat ${UTILS_PUBLIC_INCLUDE_FILES} ${UTILS_SOURCE_FILES} )
+
+set_target_properties( xivdat PROPERTIES
+ CXX_STANDARD 17
+ CXX_STANDARD_REQUIRED ON
+ CXX_EXTENSIONS ON
+ )
+
+if (UNIX)
+ target_link_libraries( xivdat PUBLIC dl )
+ target_link_libraries( xivdat PUBLIC z )
+else()
+ target_link_libraries( xivdat PUBLIC zlib )
+endif()
+target_include_directories( xivdat PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} )
+#cotire( xivdat )
diff --git a/deps/datReader/Dat.cpp b/deps/datReader/Dat.cpp
new file mode 100644
index 00000000..94812a09
--- /dev/null
+++ b/deps/datReader/Dat.cpp
@@ -0,0 +1,311 @@
+#include "Dat.h"
+
+#include "zlib.h"
+
+#include "File.h"
+
+namespace
+{
+ const uint32_t model_section_count = 0xB;
+}
+
+namespace xiv
+{
+namespace dat
+{
+ struct DatFileHeader
+ {
+ uint32_t size;
+ FileType entry_type;
+ uint32_t total_uncompressed_size;
+ uint32_t unknown[0x2];
+ };
+
+ struct DatBlockRecord
+ {
+ uint32_t offset;
+ uint32_t size;
+ uint32_t unknown[0x4];
+ SqPackBlockHash block_hash;
+ };
+
+ struct DatBlockHeader
+ {
+ uint32_t size;
+ uint32_t unknown1;
+ uint32_t compressed_size;
+ uint32_t uncompressed_size;
+ };
+
+ struct DatStdFileBlockInfos
+ {
+ uint32_t offset;
+ uint16_t size;
+ uint16_t uncompressed_size;
+ };
+
+ struct DatMdlFileBlockInfos
+ {
+ uint32_t unknown1;
+ uint32_t uncompressed_sizes[::model_section_count];
+ uint32_t compressed_sizes[::model_section_count];
+ uint32_t offsets[::model_section_count];
+ uint16_t block_ids[::model_section_count];
+ uint16_t block_counts[::model_section_count];
+ uint32_t unknown2[0x2];
+ };
+
+ struct DatTexFileBlockInfos
+ {
+ uint32_t offset;
+ uint32_t size;
+ uint32_t uncompressed_size;
+ uint32_t block_id;
+ uint32_t block_count;
+ };
+
+}
+}
+
+namespace xiv
+{
+namespace utils
+{
+namespace bparse
+{
+ template <>
+ inline void reorder(xiv::dat::DatFileHeader& i_struct)
+ {
+ xiv::utils::bparse::reorder(i_struct.size);
+ xiv::utils::bparse::reorder(i_struct.entry_type);
+ xiv::utils::bparse::reorder(i_struct.total_uncompressed_size);
+ for (int32_t i = 0; i < 0x2; ++i) { xiv::utils::bparse::reorder(i_struct.unknown[i]); }
+ }
+
+ template <>
+ inline void reorder(xiv::dat::DatBlockRecord& i_struct)
+ {
+ xiv::utils::bparse::reorder(i_struct.offset);
+ xiv::utils::bparse::reorder(i_struct.size);
+ for (int32_t i = 0; i < 0x4; ++i) { xiv::utils::bparse::reorder(i_struct.unknown[i]); }
+ xiv::utils::bparse::reorder(i_struct.block_hash);
+ }
+
+ template <>
+ inline void reorder(xiv::dat::DatBlockHeader& i_struct)
+ {
+ xiv::utils::bparse::reorder(i_struct.size);
+ xiv::utils::bparse::reorder(i_struct.unknown1);
+ xiv::utils::bparse::reorder(i_struct.compressed_size);
+ xiv::utils::bparse::reorder(i_struct.uncompressed_size);
+ }
+
+ template <>
+ inline void reorder(xiv::dat::DatStdFileBlockInfos& i_struct)
+ {
+ xiv::utils::bparse::reorder(i_struct.offset);
+ xiv::utils::bparse::reorder(i_struct.size);
+ xiv::utils::bparse::reorder(i_struct.uncompressed_size);
+ }
+
+ template <>
+ inline void reorder(xiv::dat::DatMdlFileBlockInfos& i_struct)
+ {
+ xiv::utils::bparse::reorder(i_struct.unknown1);
+ for (auto i = 0; i < ::model_section_count; ++i) { xiv::utils::bparse::reorder(i_struct.uncompressed_sizes[i]); }
+ for (auto i = 0; i < ::model_section_count; ++i) { xiv::utils::bparse::reorder(i_struct.compressed_sizes[i]); }
+ for (auto i = 0; i < ::model_section_count; ++i) { xiv::utils::bparse::reorder(i_struct.offsets[i]); }
+ for (auto i = 0; i < ::model_section_count; ++i) { xiv::utils::bparse::reorder(i_struct.block_ids[i]); }
+ for (auto i = 0; i < ::model_section_count; ++i) { xiv::utils::bparse::reorder(i_struct.block_counts[i]); }
+ for (auto i = 0; i < 0x2; ++i) { xiv::utils::bparse::reorder(i_struct.unknown2[i]); }
+ }
+
+ template <>
+ inline void reorder(xiv::dat::DatTexFileBlockInfos& i_struct)
+ {
+ xiv::utils::bparse::reorder(i_struct.offset);
+ xiv::utils::bparse::reorder(i_struct.size);
+ xiv::utils::bparse::reorder(i_struct.uncompressed_size);
+ xiv::utils::bparse::reorder(i_struct.block_id);
+ xiv::utils::bparse::reorder(i_struct.block_count);
+ }
+}
+}
+};
+
+using xiv::utils::bparse::extract;
+
+namespace xiv
+{
+namespace dat
+{
+
+Dat::Dat( const std::experimental::filesystem::path& i_path, uint32_t i_nb ) :
+ SqPack( i_path ),
+ m_num( i_nb )
+{
+ auto block_record = extract(m_handle);
+ block_record.offset *= 0x80;
+ isBlockValid(block_record.offset, block_record.size, block_record.block_hash);
+}
+
+Dat::~Dat()
+{
+}
+
+std::unique_ptr Dat::getFile( uint32_t i_offset )
+{
+ std::unique_ptr outputFile(new File());
+ {
+ // Lock in this scope
+ std::lock_guard lock(m_fileMutex);
+
+ // Seek to the start of the header of the file record and extract it
+ m_handle.seekg(i_offset);
+ auto file_header = extract(m_handle);
+
+ switch (file_header.entry_type)
+ {
+ case FileType::empty:
+ throw std::runtime_error("File is empty");
+
+ case FileType::standard:
+ {
+ outputFile->_type = FileType::standard;
+
+ uint32_t number_of_blocks = extract(m_handle, "number_of_blocks");
+
+ // Just extract offset infos for the blocks to extract
+ std::vector std_file_block_infos;
+ extract( m_handle, number_of_blocks, std_file_block_infos );
+
+ // Pre allocate data vector for the whole file
+ outputFile->_data_sections.resize(1);
+ auto& data_section = outputFile->_data_sections.front();
+
+ data_section.reserve(file_header.total_uncompressed_size);
+ // Extract each block
+ for (auto& file_block_info : std_file_block_infos)
+ {
+ extractBlock(i_offset + file_header.size + file_block_info.offset, data_section);
+ }
+ }
+ break;
+
+ case FileType::model:
+ {
+ outputFile->_type = FileType::model;
+
+ DatMdlFileBlockInfos mdlBlockInfo = extract(m_handle);
+
+ // Getting the block number and read their sizes
+ const uint32_t block_count = mdlBlockInfo.block_ids[::model_section_count - 1] +
+ mdlBlockInfo.block_counts[::model_section_count - 1];
+ std::vector block_sizes;
+ extract(m_handle, "block_size", block_count, block_sizes);
+
+ // Preallocate sufficient space
+ outputFile->_data_sections.resize(::model_section_count);
+
+ for (uint32_t i = 0; i < ::model_section_count; ++i)
+ {
+ // Preallocating for section
+ auto& data_section = outputFile->_data_sections[i];
+ data_section.reserve(mdlBlockInfo.uncompressed_sizes[i]);
+
+ uint32_t current_offset = i_offset + file_header.size + mdlBlockInfo.offsets[i];
+ for (uint32_t j = 0; j < mdlBlockInfo.block_counts[i]; ++j)
+ {
+ extractBlock(current_offset, data_section);
+ current_offset += block_sizes[mdlBlockInfo.block_ids[i] + j];
+ }
+ }
+ }
+ break;
+
+ case FileType::texture:
+ {
+ outputFile->_type = FileType::texture;
+
+ // Extracts mipmap entries and the block sizes
+ uint32_t sectionCount = extract(m_handle, "sections_count");
+
+ std::vector texBlockInfo;
+ extract(m_handle, sectionCount, texBlockInfo);
+
+ // Extracting block sizes
+ uint32_t block_count = texBlockInfo.back().block_id + texBlockInfo.back().block_count;
+ std::vector block_sizes;
+ extract(m_handle, "block_size", block_count, block_sizes);
+
+ outputFile->_data_sections.resize(sectionCount + 1);
+
+ // Extracting header in section 0
+ const uint32_t header_size = texBlockInfo.front().offset;
+ auto& header_section = outputFile->_data_sections[0];
+ header_section.resize(header_size);
+
+ m_handle.seekg(i_offset + file_header.size);
+ m_handle.read(header_section.data(), header_size);
+
+ // Extracting other sections
+ for (uint32_t i = 0; i < sectionCount; ++i)
+ {
+ auto& data_section = outputFile->_data_sections[i + 1];
+ auto& section_infos = texBlockInfo[i];
+ data_section.reserve(section_infos.uncompressed_size);
+
+ uint32_t current_offset = i_offset + file_header.size + section_infos.offset;
+ for (uint32_t j = 0; j < section_infos.block_count; ++j)
+ {
+ extractBlock(current_offset, data_section);
+ current_offset += block_sizes[section_infos.block_id + j];
+ }
+ }
+ }
+ break;
+
+ default:
+ throw std::runtime_error("Invalid entry_type: " + std::to_string(static_cast(file_header.entry_type)));
+ }
+ }
+
+ return outputFile;
+}
+
+void Dat::extractBlock( uint32_t i_offset, std::vector& o_data )
+{
+ m_handle.seekg(i_offset);
+
+ DatBlockHeader block_header = extract(m_handle);
+
+ // Resizing the vector to write directly into it
+ const uint32_t data_size = o_data.size();
+ o_data.resize(data_size + block_header.uncompressed_size);
+
+ // 32000 in compressed_size means it is not compressed so take uncompressed_size
+ if (block_header.compressed_size == 32000)
+ {
+ m_handle.read(o_data.data() + data_size, block_header.uncompressed_size);
+ }
+ else
+ {
+ // If it is compressed use zlib
+ // Read the data to be decompressed
+ std::vector temp_buffer(block_header.compressed_size);
+ m_handle.read(temp_buffer.data(), block_header.compressed_size);
+
+ utils::zlib::no_header_decompress(reinterpret_cast(temp_buffer.data()),
+ temp_buffer.size(),
+ reinterpret_cast(o_data.data() + data_size),
+ block_header.uncompressed_size);
+ }
+}
+
+uint32_t Dat::getNum() const
+{
+ return m_num;
+}
+
+}
+}
diff --git a/deps/datReader/Dat.h b/deps/datReader/Dat.h
new file mode 100644
index 00000000..5311ab48
--- /dev/null
+++ b/deps/datReader/Dat.h
@@ -0,0 +1,45 @@
+#ifndef XIV_DAT_DAT_H
+#define XIV_DAT_DAT_H
+
+#include "SqPack.h"
+
+#include
+
+#include
+
+namespace xiv
+{
+namespace dat
+{
+
+class File;
+
+class Dat : public SqPack
+{
+public:
+ // Full path to the dat file
+ Dat( const std::experimental::filesystem::path& i_path, uint32_t i_nb );
+ virtual ~Dat();
+
+ // Retrieves a file given the offset in the dat file
+ std::unique_ptr getFile( uint32_t i_offset );
+
+ // Appends to the vector the data of this block, it is assumed to be preallocated
+ // Is it also assumed that the m_fileMutex is currently locked by this thread before the call
+ void extractBlock( uint32_t i_offset, std::vector& o_data );
+
+ // Returns the dat number
+ uint32_t getNum() const;
+
+protected:
+ // File reading mutex to have only one thread reading the file at a time
+ std::mutex m_fileMutex;
+
+ // Dat nb
+ uint32_t m_num;
+};
+
+}
+}
+
+#endif // XIV_DAT_DAT_H
diff --git a/deps/datReader/DatCat.cpp b/deps/datReader/DatCat.cpp
new file mode 100644
index 00000000..117c2b9b
--- /dev/null
+++ b/deps/datReader/DatCat.cpp
@@ -0,0 +1,86 @@
+#include "DatCat.h"
+
+#include "Index.h"
+#include "Dat.h"
+#include "File.h"
+#include "GameData.h"
+
+namespace xiv
+{
+namespace dat
+{
+
+Cat::Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum, const std::string& name ) :
+ m_name( name ),
+ m_catNum( catNum ),
+ m_chunk( -1 )
+{
+ // From the category number, compute back the real filename for.index .datXs
+ std::stringstream ss;
+ ss << std::setw( 2 ) << std::setfill( '0' ) << std::hex << catNum;
+ std::string prefix = ss.str() + "0000.win32";
+
+ // Creates the index: XX0000.win32.index
+ m_index = std::unique_ptr( new Index( basePath / "//ffxiv" / ( prefix + ".index" ) ) );
+
+ // For all dat files linked to this index, create it: XX0000.win32.datX
+ for( uint32_t i = 0; i < getIndex().getDatCount(); ++i )
+ {
+ m_dats.emplace_back( std::unique_ptr( new Dat( basePath / "//ffxiv" / ( prefix + ".dat" + std::to_string( i ) ), i ) ) );
+ }
+}
+
+Cat::Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk ) :
+ m_name( name ),
+ m_catNum( catNum ),
+ m_chunk( chunk )
+{
+ // Creates the index: XX0000.win32.index
+ m_index = std::unique_ptr( new Index( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "index" ) ) );
+
+ // For all dat files linked to this index, create it: XX0000.win32.datX
+ for( uint32_t i = 0; i < getIndex().getDatCount(); ++i )
+ {
+ m_dats.emplace_back( std::unique_ptr( new Dat( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "dat" + std::to_string( i ) ), i ) ) );
+ }
+}
+
+Cat::~Cat()
+{
+
+}
+
+const Index& Cat::getIndex() const
+{
+ return *m_index;
+}
+
+std::unique_ptr Cat::getFile(uint32_t dir_hash, uint32_t filename_hash) const
+{
+ // Fetch the correct hash_table_entry for these hashes, from that request the file from the right dat file
+ auto& hash_table_entry = getIndex().getHashTableEntry(dir_hash, filename_hash);
+ return m_dats[hash_table_entry.datNum]->getFile(hash_table_entry.datOffset);
+}
+
+bool Cat::doesFileExist( uint32_t dir_hash, uint32_t filename_hash ) const
+{
+ return getIndex().doesFileExist( dir_hash, filename_hash );
+}
+
+bool Cat::doesDirExist( uint32_t dir_hash ) const
+{
+ return getIndex().doesDirExist( dir_hash );
+}
+
+const std::string& Cat::getName() const
+{
+ return m_name;
+}
+
+uint32_t Cat::getCatNum() const
+{
+ return m_catNum;
+}
+
+}
+}
diff --git a/deps/datReader/DatCat.h b/deps/datReader/DatCat.h
new file mode 100644
index 00000000..1e1d0759
--- /dev/null
+++ b/deps/datReader/DatCat.h
@@ -0,0 +1,64 @@
+#ifndef XIV_DAT_CAT_H
+#define XIV_DAT_CAT_H
+
+#include
+#include
+#include
+
+namespace xiv {
+namespace dat {
+
+class Index;
+class Dat;
+class File;
+
+// A category represents an .index and its associated .datX
+class Cat
+{
+public:
+ // basePath: Path to the folder containingthe datfiles
+ // catNum: The number of the category
+ // name: The name of the category, empty if not known
+ Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum, const std::string& name );
+
+ // basePath: Path to the folder containingthe datfiles
+ // catNum: The number of the category
+ // name: The name of the category, empty if not known
+ // exNum: The number of the expansion to load from
+ // chunk: The chunk to load from
+ Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk );
+ ~Cat();
+
+ // Returns .index of the category
+ const Index& getIndex() const;
+
+ // Retrieve a file from the category given its hashes
+ std::unique_ptr getFile( uint32_t dir_hash, uint32_t filename_hash ) const;
+
+
+ bool doesFileExist( uint32_t dir_hash, uint32_t filename_hash ) const;
+ bool doesDirExist( uint32_t dir_hash ) const;
+
+
+ // Returns thename of the category
+ const std::string& getName() const;
+
+ // Returns the number of the category
+ uint32_t getCatNum() const;
+
+protected:
+ const std::string m_name;
+ const uint32_t m_catNum;
+ const uint32_t m_chunk;
+
+ // The .index
+ std::unique_ptr m_index;
+
+ // The .datXs such as dat nb X => m_dats[X]
+ std::vector> m_dats;
+};
+
+}
+}
+
+#endif // XIV_DAT_CAT_H
diff --git a/deps/datReader/Exd.cpp b/deps/datReader/Exd.cpp
new file mode 100644
index 00000000..b4513130
--- /dev/null
+++ b/deps/datReader/Exd.cpp
@@ -0,0 +1,278 @@
+#include "Exd.h"
+
+#include "bparse.h"
+#include "stream.h"
+
+#include "Exh.h"
+
+using xiv::utils::bparse::extract;
+
+
+namespace xiv
+{
+ namespace exd
+ {
+
+ struct ExdHeader
+ {
+ char magic[0x4];
+ uint16_t unknown;
+ uint16_t unknown2;
+ uint32_t index_size;
+ };
+
+ struct ExdRecordIndex
+ {
+ uint32_t id;
+ uint32_t offset;
+ };
+
+ }
+}
+
+namespace xiv
+{
+ namespace utils
+ {
+ namespace bparse
+ {
+ template <> inline void reorder( xiv::exd::ExdHeader& i_struct ) { for( int32_t i = 0; i < 0x4; ++i ) { xiv::utils::bparse::reorder( i_struct.magic[i] ); } i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown ); xiv::utils::bparse::reorder( i_struct.unknown ); i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 ); xiv::utils::bparse::reorder( i_struct.unknown2 ); i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size ); xiv::utils::bparse::reorder( i_struct.index_size ); }
+ template <> inline void reorder( xiv::exd::ExdRecordIndex& i_struct ) { i_struct.id = xiv::utils::bparse::byteswap( i_struct.id ); xiv::utils::bparse::reorder( i_struct.id ); i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset ); xiv::utils::bparse::reorder( i_struct.offset ); }
+ }
+ }
+};
+
+namespace xiv
+{
+ namespace exd
+ {
+
+ Exd::Exd( std::shared_ptr i_exh, const std::vector>& i_files )
+ {
+ _exh = i_exh;
+ _files = i_files;
+
+
+ // Iterates over all the files
+ const uint32_t member_count = _exh->get_members().size();
+ for ( auto &file_ptr : _files )
+ {
+ // Get a stream
+ std::vector< char > dataCpy = file_ptr->get_data_sections().front();
+ std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
+
+ // Extract the header and skip to the record indices
+ auto exd_header = extract< ExdHeader >( iss );
+ iss.seekg( 0x20 );
+
+ // Preallocate and extract the record_indices
+ const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex );
+ std::vector< ExdRecordIndex > record_indices;
+ record_indices.reserve( record_count );
+ for ( uint32_t i = 0; i < record_count; ++i )
+ {
+ auto recordIndex = extract< ExdRecordIndex >( iss );
+ _idCache[recordIndex.id] = ExdCacheEntry{file_ptr, recordIndex.offset};
+ }
+ }
+ }
+
+ Exd::~Exd()
+ {
+ }
+
+ const std::vector Exd::get_row( uint32_t id )
+ {
+
+ auto cacheEntryIt = _idCache.find( id );
+ if( cacheEntryIt == _idCache.end() )
+ throw std::runtime_error( "Id not found: " + std::to_string( id ) );
+
+ // Iterates over all the files
+ const uint32_t member_count = _exh->get_members().size();
+ auto& file_ptr = cacheEntryIt->second.file;
+
+ std::vector< char > dataCpy = file_ptr->get_data_sections().front();
+ std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
+
+ // Get the vector fields for the given record and preallocate it
+ auto fields = _data[id];
+ fields.reserve( member_count );
+
+ for( auto& member_entry : _exh->get_exh_members() )
+ {
+ // Seek to the position of the member to extract.
+ // 6 is because we have uint32_t/uint16_t at the start of each record
+ iss.seekg( cacheEntryIt->second.offset + 6 + member_entry.offset );
+
+ // Switch depending on the type to extract
+ switch( member_entry.type )
+ {
+ case DataType::string:
+ // Extract the offset to the actual string
+ // Seek to it then extract the actual string
+ {
+ auto string_offset = extract( iss, "string_offset", false );
+ iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset );
+ fields.emplace_back( utils::bparse::extract_cstring( iss, "string" ) );
+ }
+ break;
+
+ case DataType::boolean:
+ fields.emplace_back( extract( iss, "bool" ) );
+ break;
+
+ case DataType::int8:
+ fields.emplace_back( extract( iss, "int8_t" ) );
+ break;
+
+ case DataType::uint8:
+ fields.emplace_back( extract( iss, "uint8_t" ) );
+ break;
+
+ case DataType::int16:
+ fields.emplace_back( extract( iss, "int16_t", false ) );
+ break;
+
+ case DataType::uint16:
+ fields.emplace_back( extract( iss, "uint16_t", false ) );
+ break;
+
+ case DataType::int32:
+ fields.emplace_back( extract( iss, "int32_t", false ) );
+ break;
+
+ case DataType::uint32:
+ fields.emplace_back( extract( iss, "uint32_t", false ) );
+ break;
+
+ case DataType::float32:
+ fields.emplace_back( extract( iss, "float", false ) );
+ break;
+
+ case DataType::uint64:
+ fields.emplace_back( extract( iss, "uint64_t", false ) );
+ break;
+
+ default:
+ auto type = static_cast< uint16_t >( member_entry.type );
+ if( type < 0x19 || type > 0x20 )
+ throw std::runtime_error("Unknown DataType: " + std::to_string( type ));
+ uint64_t val = extract< uint64_t >( iss, "bool" );
+ int32_t shift = type - 0x19;
+ int32_t i = 1 << shift;
+ val &= i;
+ fields.emplace_back( ( val & i ) == i );
+ break;
+ }
+ }
+ return fields;
+
+ }
+
+ // Get all rows
+ const std::map>& Exd::get_rows()
+ {
+ // Iterates over all the files
+ const uint32_t member_count = _exh->get_members().size();
+ for( auto& file_ptr : _files )
+ {
+ // Get a stream
+ std::vector< char > dataCpy = file_ptr->get_data_sections().front();
+ std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) );
+
+ // Extract the header and skip to the record indices
+ auto exd_header = extract( iss );
+ iss.seekg( 0x20 );
+
+ // Preallocate and extract the record_indices
+ const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex );
+ std::vector record_indices;
+ record_indices.reserve( record_count );
+ for( uint32_t i = 0; i < record_count; ++i )
+ {
+ record_indices.emplace_back( extract( iss ) );
+ }
+
+ for( auto& record_index : record_indices )
+ {
+ // Get the vector fields for the given record and preallocate it
+ auto& fields = _data[record_index.id];
+ fields.reserve( member_count );
+
+ for( auto& member_entry : _exh->get_exh_members() )
+ //for( auto& member_entry : _exh->get_members() )
+ {
+ // Seek to the position of the member to extract.
+ // 6 is because we have uint32_t/uint16_t at the start of each record
+ iss.seekg( record_index.offset + 6 + member_entry.offset );
+
+ // Switch depending on the type to extract
+ switch( member_entry.type )
+ {
+ case DataType::string:
+ // Extract the offset to the actual string
+ // Seek to it then extract the actual string
+ {
+ auto string_offset = extract( iss, "string_offset", false );
+ iss.seekg( record_index.offset + 6 + _exh->get_header().data_offset + string_offset );
+ fields.emplace_back( utils::bparse::extract_cstring( iss, "string" ) );
+ }
+ break;
+
+ case DataType::boolean:
+ fields.emplace_back( extract( iss, "bool" ) );
+ break;
+
+ case DataType::int8:
+ fields.emplace_back( extract( iss, "int8_t" ) );
+ break;
+
+ case DataType::uint8:
+ fields.emplace_back( extract( iss, "uint8_t" ) );
+ break;
+
+ case DataType::int16:
+ fields.emplace_back( extract( iss, "int16_t", false ) );
+ break;
+
+ case DataType::uint16:
+ fields.emplace_back( extract( iss, "uint16_t", false ) );
+ break;
+
+ case DataType::int32:
+ fields.emplace_back( extract( iss, "int32_t", false ) );
+ break;
+
+ case DataType::uint32:
+ fields.emplace_back( extract( iss, "uint32_t", false ) );
+ break;
+
+ case DataType::float32:
+ fields.emplace_back( extract( iss, "float", false ) );
+ break;
+
+ case DataType::uint64:
+ fields.emplace_back( extract( iss, "uint64_t", false ) );
+ break;
+
+ default:
+ auto type = static_cast< uint16_t >( member_entry.type );
+ if( type < 0x19 || type > 0x20 )
+ throw std::runtime_error("Unknown DataType: " + std::to_string( type ));
+ uint64_t val = extract< uint64_t >( iss, "bool" );
+ int32_t shift = type - 0x19;
+ int32_t i = 1 << shift;
+ val &= i;
+ fields.emplace_back( ( val & i ) == i );
+ break;
+ }
+ }
+ }
+ }
+ return _data;
+ }
+
+ }
+}
+
diff --git a/deps/datReader/Exd.h b/deps/datReader/Exd.h
new file mode 100644
index 00000000..0bafa5e4
--- /dev/null
+++ b/deps/datReader/Exd.h
@@ -0,0 +1,64 @@
+#ifndef XIV_EXD_EXD_H
+#define XIV_EXD_EXD_H
+
+#include
+#include