1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 22:57:45 +00:00

Merge remote-tracking branch 'SapphireServer/develop' into develop

This commit is contained in:
Jeido 2020-11-26 19:14:12 +01:00
commit a9e6c85a5e
371 changed files with 32780 additions and 21115 deletions

View file

@ -1,5 +1,5 @@
os: os:
- Visual Studio 2017 - Visual Studio 2019
configuration: configuration:
- Debug - Debug
@ -20,8 +20,8 @@ before_build:
- git submodule update --init - git submodule update --init
- mkdir build - mkdir build
- cd build - cd build
- cmake .. -G "Visual Studio 15 2017 Win64" - cmake .. -G "Visual Studio 16 2019" -A x64
- cmake --build . --target ALL_BUILD --config Release - cmake --build . --target ALL_BUILD --config RelWithDebInfo
build_script: build_script:
- cd bin - cd bin

3
.gitmodules vendored
View file

@ -7,3 +7,6 @@
[submodule "deps/recastnavigation"] [submodule "deps/recastnavigation"]
path = deps/recastnavigation path = deps/recastnavigation
url = https://github.com/SapphireServer/recastnavigation url = https://github.com/SapphireServer/recastnavigation
[submodule "deps/ffxiv-actions"]
path = deps/ffxiv-actions
url = https://github.com/SapphireServer/ffxiv-actions.git

View file

@ -14,9 +14,10 @@ matrix:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
packages: packages:
- g++-7 - g++-8
env: env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8"
- CXX=g++-8
# Setup cache # Setup cache
cache: cache:

View file

@ -13,7 +13,9 @@ add_custom_target( copy_runtime_files ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/config ${CMAKE_BINARY_DIR}/bin/config COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/config ${CMAKE_BINARY_DIR}/bin/config
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/sql ${CMAKE_BINARY_DIR}/bin/sql COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/sql ${CMAKE_BINARY_DIR}/bin/sql
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/web ${CMAKE_BINARY_DIR}/bin/web COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/web ${CMAKE_BINARY_DIR}/bin/web
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/sql_import.sh ${CMAKE_BINARY_DIR}/bin/sql_import.sh ) COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/sql_import.sh ${CMAKE_BINARY_DIR}/bin/sql_import.sh
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/bin/data/actions
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/deps/ffxiv-actions/actions ${CMAKE_BINARY_DIR}/bin/data/actions )
###################################### ######################################
# Dependencies and compiler settings # # Dependencies and compiler settings #
@ -44,7 +46,6 @@ add_subdirectory( "deps/MySQL" )
add_subdirectory( "deps/datReader" ) add_subdirectory( "deps/datReader" )
add_subdirectory( "deps/mysqlConnector" ) add_subdirectory( "deps/mysqlConnector" )
add_subdirectory( "deps/recastnavigation" ) add_subdirectory( "deps/recastnavigation" )
add_subdirectory( "deps/stackwalker" )
############################## ##############################
# Main Sapphire Components # # Main Sapphire Components #

View file

@ -1,21 +1,32 @@
{ {
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file. // See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"environments": [
{
"BuildDir": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build"
}
],
"configurations": [ "configurations": [
{ {
"name": "x64-Debug", "name": "x64-Debug",
"generator": "Visual Studio 15 2017 Win64", "generator": "Visual Studio 16 2019 Win64",
"configurationType": "Debug", "configurationType": "Debug",
"buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}", "buildRoot": "${env.BuildDir}\\${name}",
"cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"Debug\"", "cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"Debug\"",
"buildCommandArgs": "-m -v:minimal" "buildCommandArgs": "-m -v:minimal",
"inheritEnvironments": [
"msvc_x64"
]
}, },
{ {
"name": "x64-Release", "name": "x64-Release",
"generator": "Visual Studio 15 2017 Win64", "generator": "Visual Studio 16 2019 Win64",
"configurationType": "Release", "configurationType": "Release",
"buildRoot": "${env.USERPROFILE}\\CMakeBuild\\${workspaceHash}\\build\\${name}", "buildRoot": "${env.BuildDir}\\${name}",
"cmakeCommandArgs": "", "cmakeCommandArgs": "-DCMAKE_BUILD_TYPE=\"RelWithDebInfo\"",
"buildCommandArgs": "-m -v:minimal" "buildCommandArgs": "-m -v:minimal",
"inheritEnvironments": [
"msvc_x64"
]
} }
] ]
} }

View file

@ -18,7 +18,7 @@ Sapphire requires the following software:
| *Name* | *Windows* | *Linux* | | *Name* | *Windows* | *Linux* |
| ------ | --------- | ------- | | ------ | --------- | ------- |
| CMake 3.0.2+ and C++17 capable compiler | [Visual Studio 2017](https://www.visualstudio.com/) | `gcc 7` and `g++ 7` or newer | | CMake 3.0.2+ and C++17 capable compiler | [Visual Studio 2019](https://www.visualstudio.com/) | `gcc 8` and `g++ 8` or newer, or equivalent `clang` version. |
| MySQL Server 5.7 | [Official Site](https://dev.mysql.com/downloads/mysql/) | MySQL server from your distribution's package manager | | 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. Please check the [wiki](https://github.com/SapphireMordred/Sapphire/wiki) for detailed installation/build instructions for your OS.

View file

@ -60,6 +60,7 @@ if( UNIX )
else( MYSQL_CONFIG ) else( MYSQL_CONFIG )
set(MYSQL_ADD_LIBRARIES "") set(MYSQL_ADD_LIBRARIES "")
list(APPEND MYSQL_ADD_LIBRARIES "mysqlclient_r") list(APPEND MYSQL_ADD_LIBRARIES "mysqlclient_r")
list(APPEND MYSQL_ADD_LIBRARIES "mariadbclient")
endif( MYSQL_CONFIG ) endif( MYSQL_CONFIG )
endif( UNIX ) endif( UNIX )
@ -76,6 +77,7 @@ find_path(MYSQL_INCLUDE_DIR
PATHS PATHS
${MYSQL_ADD_INCLUDE_PATH} ${MYSQL_ADD_INCLUDE_PATH}
/usr/include /usr/include
/usr/include/mariadb
/usr/include/mysql /usr/include/mysql
/usr/local/include /usr/local/include
/usr/local/include/mysql /usr/local/include/mysql
@ -83,6 +85,8 @@ find_path(MYSQL_INCLUDE_DIR
"${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/include" "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/include"
"${PROGRAM_FILES_64}/MySQL/include" "${PROGRAM_FILES_64}/MySQL/include"
"${PROGRAM_FILES_64}/MariaDB 10.3/include/mysql" "${PROGRAM_FILES_64}/MariaDB 10.3/include/mysql"
"${PROGRAM_FILES_64}/MariaDB 10.4/include/mysql"
"${PROGRAM_FILES_64}/MariaDB 10.5/include/mysql"
"C:/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.7;Location]/include"
"$ENV{ProgramFiles}/MySQL/MySQL Server 5.7/include" "$ENV{ProgramFiles}/MySQL/MySQL Server 5.7/include"
@ -97,7 +101,7 @@ if( UNIX )
foreach(LIB ${MYSQL_ADD_LIBRARIES}) foreach(LIB ${MYSQL_ADD_LIBRARIES})
find_library( MYSQL_LIBRARY find_library( MYSQL_LIBRARY
NAMES NAMES
mysql libmysql ${LIB} mysql libmysql libmariadb ${LIB}
PATHS PATHS
${MYSQL_ADD_LIBRARIES_PATH} ${MYSQL_ADD_LIBRARIES_PATH}
/usr/lib /usr/lib
@ -105,6 +109,7 @@ if( UNIX )
/usr/local/lib /usr/local/lib
/usr/local/lib/mysql /usr/local/lib/mysql
/usr/local/mysql/lib /usr/local/mysql/lib
/usr/lib/x86_64-linux-gnu
DOC "Specify the location of the mysql library here." DOC "Specify the location of the mysql library here."
) )
endforeach(LIB ${MYSQL_ADD_LIBRARY}) endforeach(LIB ${MYSQL_ADD_LIBRARY})
@ -121,6 +126,8 @@ if( WIN32 )
"${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/lib/opt" "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/lib/opt"
"${PROGRAM_FILES_64}/MySQL/lib" "${PROGRAM_FILES_64}/MySQL/lib"
"${PROGRAM_FILES_64}/MariaDB 10.3/lib" "${PROGRAM_FILES_64}/MariaDB 10.3/lib"
"${PROGRAM_FILES_64}/MariaDB 10.4/lib"
"${PROGRAM_FILES_64}/MariaDB 10.5/lib"
"C:/MySQL/lib/debug" "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.7;Location]/lib"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/lib/opt" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/lib/opt"
@ -174,6 +181,8 @@ if( WIN32 )
"${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/bin/opt" "${PROGRAM_FILES_64}/MySQL/MySQL Server 5.7/bin/opt"
"${PROGRAM_FILES_64}/MySQL/bin" "${PROGRAM_FILES_64}/MySQL/bin"
"${PROGRAM_FILES_64}/MariaDB 10.3/bin" "${PROGRAM_FILES_64}/MariaDB 10.3/bin"
"${PROGRAM_FILES_64}/MariaDB 10.4/bin"
"${PROGRAM_FILES_64}/MariaDB 10.5/bin"
"C:/MySQL/bin/debug" "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.7;Location]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/bin/opt" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.7;Location]/bin/opt"

View file

@ -13,3 +13,4 @@ endif()
# Create log folder # Create log folder
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/log ) file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/log )
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/navi ) file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/navi )
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin/data )

View file

@ -4,14 +4,11 @@
#include "File.h" #include "File.h"
namespace namespace {
{
const uint32_t model_section_count = 0xB; const uint32_t model_section_count = 0xB;
} }
namespace xiv namespace xiv::dat
{
namespace dat
{ {
struct DatFileHeader struct DatFileHeader
{ {
@ -63,15 +60,9 @@ namespace dat
uint32_t block_id; uint32_t block_id;
uint32_t block_count; uint32_t block_count;
}; };
}
} }
namespace xiv namespace xiv::utils::bparse
{
namespace utils
{
namespace bparse
{ {
template<> template<>
inline void reorder< xiv::dat::DatFileHeader >( xiv::dat::DatFileHeader& i_struct ) inline void reorder< xiv::dat::DatFileHeader >( xiv::dat::DatFileHeader& i_struct )
@ -79,7 +70,10 @@ namespace bparse
xiv::utils::bparse::reorder( i_struct.size ); xiv::utils::bparse::reorder( i_struct.size );
xiv::utils::bparse::reorder( i_struct.entry_type ); xiv::utils::bparse::reorder( i_struct.entry_type );
xiv::utils::bparse::reorder( i_struct.total_uncompressed_size ); 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]); } for( int32_t i = 0; i < 0x2; ++i )
{
xiv::utils::bparse::reorder( i_struct.unknown[ i ] );
}
} }
template<> template<>
@ -87,7 +81,10 @@ namespace bparse
{ {
xiv::utils::bparse::reorder( i_struct.offset ); xiv::utils::bparse::reorder( i_struct.offset );
xiv::utils::bparse::reorder( i_struct.size ); xiv::utils::bparse::reorder( i_struct.size );
for (int32_t i = 0; i < 0x4; ++i) { xiv::utils::bparse::reorder(i_struct.unknown[i]); } for( int32_t i = 0; i < 0x4; ++i )
{
xiv::utils::bparse::reorder( i_struct.unknown[ i ] );
}
xiv::utils::bparse::reorder( i_struct.block_hash ); xiv::utils::bparse::reorder( i_struct.block_hash );
} }
@ -112,12 +109,30 @@ namespace bparse
inline void reorder< xiv::dat::DatMdlFileBlockInfos >( xiv::dat::DatMdlFileBlockInfos& i_struct ) inline void reorder< xiv::dat::DatMdlFileBlockInfos >( xiv::dat::DatMdlFileBlockInfos& i_struct )
{ {
xiv::utils::bparse::reorder( i_struct.unknown1 ); 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 )
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]); } xiv::utils::bparse::reorder( i_struct.uncompressed_sizes[ 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 < ::model_section_count; ++i )
for (auto i = 0; i < 0x2; ++i) { xiv::utils::bparse::reorder(i_struct.unknown2[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<> template<>
@ -130,17 +145,13 @@ namespace bparse
xiv::utils::bparse::reorder( i_struct.block_count ); xiv::utils::bparse::reorder( i_struct.block_count );
} }
} }
}
};
using xiv::utils::bparse::extract; using xiv::utils::bparse::extract;
namespace xiv namespace xiv::dat
{
namespace dat
{ {
Dat::Dat( const std::experimental::filesystem::path& i_path, uint32_t i_nb ) : Dat::Dat( const std::filesystem::path& i_path, uint32_t i_nb ) :
SqPack( i_path ), SqPack( i_path ),
m_num( i_nb ) m_num( i_nb )
{ {
@ -266,7 +277,8 @@ std::unique_ptr<File> Dat::getFile( uint32_t i_offset )
break; break;
default: default:
throw std::runtime_error("Invalid entry_type: " + std::to_string(static_cast<uint32_t>(file_header.entry_type))); throw std::runtime_error(
"Invalid entry_type: " + std::to_string( static_cast<uint32_t>(file_header.entry_type) ) );
} }
} }
@ -308,4 +320,3 @@ uint32_t Dat::getNum() const
} }
} }
}

View file

@ -5,11 +5,9 @@
#include <mutex> #include <mutex>
#include <experimental/filesystem> #include <filesystem>
namespace xiv namespace xiv::dat
{
namespace dat
{ {
class File; class File;
@ -18,7 +16,7 @@ class Dat : public SqPack
{ {
public: public:
// Full path to the dat file // Full path to the dat file
Dat( const std::experimental::filesystem::path& i_path, uint32_t i_nb ); Dat( const std::filesystem::path& i_path, uint32_t i_nb );
virtual ~Dat(); virtual ~Dat();
// Retrieves a file given the offset in the dat file // Retrieves a file given the offset in the dat file
@ -39,7 +37,6 @@ protected:
uint32_t m_num; uint32_t m_num;
}; };
}
} }
#endif // XIV_DAT_DAT_H #endif // XIV_DAT_DAT_H

View file

@ -10,7 +10,7 @@ namespace xiv
namespace dat namespace dat
{ {
Cat::Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum, const std::string& name ) : Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name ) :
m_name( name ), m_name( name ),
m_catNum( catNum ), m_catNum( catNum ),
m_chunk( -1 ) m_chunk( -1 )
@ -21,27 +21,27 @@ Cat::Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum,
std::string prefix = ss.str() + "0000.win32"; std::string prefix = ss.str() + "0000.win32";
// Creates the index: XX0000.win32.index // Creates the index: XX0000.win32.index
m_index = std::unique_ptr<Index>( new Index( basePath / "//ffxiv" / ( prefix + ".index" ) ) ); m_index = std::unique_ptr<Index>( new Index( basePath / "ffxiv" / ( prefix + ".index" ) ) );
// For all dat files linked to this index, create it: XX0000.win32.datX // For all dat files linked to this index, create it: XX0000.win32.datX
for( uint32_t i = 0; i < getIndex().getDatCount(); ++i ) for( uint32_t i = 0; i < getIndex().getDatCount(); ++i )
{ {
m_dats.emplace_back( std::unique_ptr<Dat>( new Dat( basePath / "//ffxiv" / ( prefix + ".dat" + std::to_string( i ) ), i ) ) ); m_dats.emplace_back( std::make_unique< 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 ) : Cat::Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum, uint32_t chunk ) :
m_name( name ), m_name( name ),
m_catNum( catNum ), m_catNum( catNum ),
m_chunk( chunk ) m_chunk( chunk )
{ {
// Creates the index: XX0000.win32.index // Creates the index: XX0000.win32.index
m_index = std::unique_ptr<Index>( new Index( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "index" ) ) ); m_index = std::make_unique< 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 all dat files linked to this index, create it: XX0000.win32.datX
for( uint32_t i = 0; i < getIndex().getDatCount(); ++i ) for( uint32_t i = 0; i < getIndex().getDatCount(); ++i )
{ {
m_dats.emplace_back( std::unique_ptr<Dat>( new Dat( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "dat" + std::to_string( i ) ), i ) ) ); m_dats.emplace_back( std::make_unique< Dat >( basePath / GameData::buildDatStr( "ex" + std::to_string( exNum ), catNum, exNum, chunk, "win32", "dat" + std::to_string( i ) ), i ) );
} }
} }

View file

@ -3,13 +3,15 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <experimental/filesystem> #include <filesystem>
namespace xiv { namespace xiv::dat
namespace dat { {
class Index; class Index;
class Dat; class Dat;
class File; class File;
// A category represents an .index and its associated .datX // A category represents an .index and its associated .datX
@ -19,14 +21,16 @@ public:
// basePath: Path to the folder containingthe datfiles // basePath: Path to the folder containingthe datfiles
// catNum: The number of the category // catNum: The number of the category
// name: The name of the category, empty if not known // name: The name of the category, empty if not known
Cat( const std::experimental::filesystem::path& basePath, uint32_t catNum, const std::string& name ); Cat( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name );
// basePath: Path to the folder containingthe datfiles // basePath: Path to the folder containingthe datfiles
// catNum: The number of the category // catNum: The number of the category
// name: The name of the category, empty if not known // name: The name of the category, empty if not known
// exNum: The number of the expansion to load from // exNum: The number of the expansion to load from
// chunk: The chunk 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( const std::filesystem::path& basePath, uint32_t catNum, const std::string& name, uint32_t exNum,
uint32_t chunk );
~Cat(); ~Cat();
// Returns .index of the category // Returns .index of the category
@ -37,6 +41,7 @@ public:
bool doesFileExist( 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; bool doesDirExist( uint32_t dir_hash ) const;
@ -58,7 +63,6 @@ protected:
std::vector< std::unique_ptr< Dat>> m_dats; std::vector< std::unique_ptr< Dat>> m_dats;
}; };
}
} }
#endif // XIV_DAT_CAT_H #endif // XIV_DAT_CAT_H

View file

@ -0,0 +1,198 @@
#ifndef SAPPHIRE_LGBTYPES_H
#define SAPPHIRE_LGBTYPES_H
#include "vec3.h"
enum class LgbEntryType : uint32_t
{
BgParts = 1,
Attribute = 2,
Light = 3,
Vfx = 4,
PositionMarker = 5,
Gimmick = 6,
SharedGroup6 = 6,// secondary variable is set to 2
Sound = 7,
EventNpc = 8,
BattleNpc = 9,
RoutePath = 10,
Character = 11,
Aetheryte = 12,
EnvSpace = 13,
Gathering = 14,
SharedGroup15 = 15,// secondary variable is set to 13
Treasure = 16,
Player = 37,
Monster = 38,
Weapon = 39,
PopRange = 40,
ExitRange = 41,
LVB = 42,
MapRange = 43,
NaviMeshRange = 44,
EventObject = 45,
DemiHuman = 46,
EnvLocation = 47,
ControlPoint = 48,
EventRange = 49,
RestBonusRange = 50,
QuestMarker = 51,
TimeLine = 52,
ObjectBehaviorSet = 53,
Movie = 54,
ScenarioEXD = 55,
ScenarioText = 56,
CollisionBox = 57,
DoorRange = 58,
LineVfx = 59,
SoundEnvSet = 60,
CutActionTimeline = 61,
CharaScene = 62,
CutAction = 63,
EquipPreset = 64,
ClientPath = 65,
ServerPath = 66,
GimmickRange = 67,
TargetMarker = 68,
ChairMarker = 69,
ClickableRange = 70,
PrefetchRange = 71,
FateRange = 72,
PartyMember = 73,
KeepRange = 74,
SphereCastRange = 75,
IndoorObject = 76,
OutdoorObject = 77,
EditGroup = 78,
StableChocobo = 79
};
enum PopType : uint32_t
{
PopTypePC = 0x1,
PopTypeNPC = 0x2,
PopTypeBNPC = 0x2,
PopTypeContent = 0x3,
};
struct Transformation
{
vec3 translation;
vec3 rotation;
vec3 scale;
};
struct InstanceObject
{
LgbEntryType type;
uint32_t instanceId;
uint32_t nameOffset;
Transformation transform;
};
struct BgPartsData : public InstanceObject
{
uint32_t modelFileOffset;
uint32_t collisionFileOffset;
uint32_t unknown4;
uint32_t unknown5;
uint32_t unknown6;
uint32_t unknown7;
uint32_t unknown8;
uint32_t unknown9;
};
struct RelativePositions
{
int32_t Pos;
int32_t PosCount;
};
struct PopRangeData : public InstanceObject
{
PopType popType;
RelativePositions relativePositions;
float innerRadiusRatio;
uint8_t index;
uint8_t padding00[3];
uint32_t reserved;
};
struct GimmickData : public InstanceObject
{
uint32_t gimmickFileOffset;
char unknownBytes[100];
};
struct ENpcData : public InstanceObject
{
uint32_t enpcId;
uint8_t unknown1[0x24];
};
struct EObjData : public InstanceObject
{
uint32_t eobjId;
uint32_t levelHierachyId;
uint8_t unknown1[0xC];
};
enum TriggerBoxShape : uint32_t
{
TriggerBoxShapeBox = 0x1,
TriggerBoxShapeSphere = 0x2,
TriggerBoxShapeCylinder = 0x3,
TriggerBoxShapeBoard = 0x4,
TriggerBoxShapeMesh = 0x5,
TriggerBoxShapeBoardBothSides = 0x6,
};
struct TriggerBoxInstanceObject
{
TriggerBoxShape triggerBoxShape;
int16_t priority;
int8_t enabled;
uint8_t padding;
uint32_t reserved;
};
struct ExitRangeData : public InstanceObject
{
TriggerBoxInstanceObject triggerBoxType;
uint32_t exitType;
uint16_t zoneId;
uint16_t destTerritoryType;
int index;
uint32_t destInstanceObjectId;
uint32_t returnInstanceObjectId;
float direction;
uint32_t reserved;
};
struct MapRangeData : public InstanceObject
{
TriggerBoxInstanceObject triggerBoxType;
uint32_t mapId;
uint32_t placeNameBlock;
uint32_t placeNameSpot;
uint32_t bGM;
uint32_t weather;
uint32_t reserved;
uint32_t reserved2;
uint16_t reserved3;
uint8_t housingBlockId;
int8_t restBonusEffective;
uint8_t discoveryIndex;
int8_t mapEnabled;
int8_t placeNameEnabled;
int8_t discoveryEnabled;
int8_t bGMEnabled;
int8_t weatherEnabled;
int8_t restBonusEnabled;
int8_t bGMPlayZoneInOnly;
int8_t liftEnabled;
int8_t housingEnabled;
uint16_t padding;
};
#endif //SAPPHIRE_LGBTYPES_H

View file

@ -12,87 +12,33 @@
#include "matrix4.h" #include "matrix4.h"
#include "vec3.h" #include "vec3.h"
#include "sgb.h" #include "sgb.h"
#include "LgbTypes.h"
// garbage to skip model loading // based on https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/
extern bool ignoreModels;
// all credit to
// https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/
// this is simply their work ported to c++ since we dont c#
struct LGB_FILE; struct LGB_FILE;
struct LGB_FILE_HEADER; struct LGB_FILE_HEADER;
struct LGB_GROUP; struct LGB_GROUP;
struct LGB_GROUP_HEADER; struct LGB_GROUP_HEADER;
enum class LgbEntryType : class LgbEntry
uint32_t
{
BgParts = 1,
Light = 3,
Vfx = 4,
PositionMarker = 5,
Gimmick = 6,
SharedGroup6 = 6,// secondary variable is set to 2
Sound = 7,
EventNpc = 8,
BattleNpc = 9,
Aetheryte = 12,
EnvSpace = 13,
Gathering = 14,
SharedGroup15 = 15,// secondary variable is set to 13
Treasure = 16,
Weapon = 39,
PopRange = 40,
ExitRange = 41,
MapRange = 43,
NaviMeshRange = 44,
EventObject = 45,
EnvLocation = 47,
EventRange = 49,
QuestMarker = 51,
CollisionBox = 57,
DoorRange = 58,
LineVfx = 59,
ClientPath = 65,
ServerPath = 66,
GimmickRange = 67,
TargetMarker = 68,
ChairMarker = 69,
ClickableRange = 70,
PrefetchRange = 71,
FateRange = 72,
SphereCastRange = 75,
};
struct LGB_ENTRY_HEADER
{
LgbEntryType type;
uint32_t unknown;
uint32_t nameOffset;
vec3 translation;
vec3 rotation;
vec3 scale;
};
class LGB_ENTRY
{ {
public: public:
char* m_buf; char* m_buf;
uint32_t m_offset; uint32_t m_offset;
LGB_ENTRY_HEADER header; InstanceObject header;
LGB_ENTRY() LgbEntry()
{ {
m_buf = nullptr; m_buf = nullptr;
m_offset = 0; m_offset = 0;
memset( &header, 0, sizeof( header ) ); memset( &header, 0, sizeof( header ) );
}; };
LGB_ENTRY( char* buf, uint32_t offset ) LgbEntry( char* buf, uint32_t offset )
{ {
m_buf = buf; m_buf = buf;
m_offset = offset; m_offset = offset;
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset ); header = *reinterpret_cast< InstanceObject* >( buf + offset );
}; };
const LgbEntryType getType() const const LgbEntryType getType() const
@ -100,30 +46,16 @@ public:
return header.type; return header.type;
}; };
virtual ~LGB_ENTRY() virtual ~LgbEntry()
{ {
}; };
}; };
struct LGB_BGPARTS_HEADER : class LGB_BGPARTS_ENTRY : public LgbEntry
public LGB_ENTRY_HEADER
{
uint32_t modelFileOffset;
uint32_t collisionFileOffset;
uint32_t unknown4;
uint32_t unknown5;
uint32_t unknown6;
uint32_t unknown7;
uint32_t unknown8;
uint32_t unknown9;
};
class LGB_BGPARTS_ENTRY :
public LGB_ENTRY
{ {
public: public:
LGB_BGPARTS_HEADER header; BgPartsData data;
std::string name; std::string name;
std::string modelFileName; std::string modelFileName;
std::string collisionFileName; std::string collisionFileName;
@ -132,124 +64,94 @@ public:
{ {
}; };
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
LGB_ENTRY( buf, offset )
{ {
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset ); data = *reinterpret_cast< BgPartsData* >( buf + offset );
name = std::string( buf + offset + header.nameOffset ); name = std::string( buf + offset + header.nameOffset );
modelFileName = std::string( buf + offset + header.modelFileOffset ); modelFileName = std::string( buf + offset + data.modelFileOffset );
collisionFileName = std::string( buf + offset + header.collisionFileOffset ); collisionFileName = std::string( buf + offset + data.collisionFileOffset );
}; };
}; };
struct LGB_GIMMICK_HEADER : class LGB_GIMMICK_ENTRY : public LgbEntry
public LGB_ENTRY_HEADER
{
uint32_t gimmickFileOffset;
char unknownBytes[100];
};
class LGB_GIMMICK_ENTRY :
public LGB_ENTRY
{ {
public: public:
LGB_GIMMICK_HEADER header; GimmickData data;
std::string name; std::string name;
std::string gimmickFileName; std::string gimmickFileName;
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
LGB_ENTRY( buf, offset )
{ {
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset ); data = *reinterpret_cast< GimmickData* >( buf + offset );
name = std::string( buf + offset + header.nameOffset ); name = std::string( buf + offset + header.nameOffset );
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset ); gimmickFileName = std::string( buf + offset + data.gimmickFileOffset );
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
}; };
}; };
struct LGB_ENPC_HEADER : class LGB_ENPC_ENTRY : public LgbEntry
public LGB_ENTRY_HEADER
{
uint32_t enpcId;
uint8_t unknown1[0x24];
};
class LGB_ENPC_ENTRY :
public LGB_ENTRY
{ {
public: public:
LGB_ENPC_HEADER header; ENpcData data;
std::string name; std::string name;
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) : LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
LGB_ENTRY( buf, offset ) LgbEntry( buf, offset )
{ {
header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset ); data = *reinterpret_cast< ENpcData* >( buf + offset );
name = std::string( buf + offset + header.nameOffset ); name = std::string( buf + offset + header.nameOffset );
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
}; };
}; };
struct LGB_EOBJ_HEADER : class LGB_EOBJ_ENTRY : public LgbEntry
public LGB_ENTRY_HEADER
{
uint32_t eobjId;
uint32_t levelHierachyId;
uint8_t unknown1[0xC];
};
class LGB_EOBJ_ENTRY :
public LGB_ENTRY
{ {
public: public:
LGB_EOBJ_HEADER header; EObjData data;
std::string name; std::string name;
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
LGB_ENTRY( buf, offset )
{ {
header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset ); data = *reinterpret_cast< EObjData* >( buf + offset );
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
name = std::string( buf + offset + header.nameOffset ); name = std::string( buf + offset + header.nameOffset );
}; };
}; };
struct LGB_MAPRANGE_HEADER : struct LGB_MAP_RANGE_ENTRY : public LgbEntry
public LGB_ENTRY_HEADER
{
uint32_t type;
uint8_t unknown2;
uint8_t unknown2_1;
uint16_t unknown3;
uint32_t unknown5;
uint32_t mapId;
uint32_t offsetX;
uint32_t offsetY;
uint32_t unkInts[4];
uint16_t unkShort;
uint8_t unkFlag;
uint8_t unkFlag2;
uint8_t discoveryIndex;
uint8_t unkFlag3;
uint8_t unkFlag4;
uint8_t unknown4[0x09];
};
struct LGB_MAPRANGE_ENTRY :
public LGB_ENTRY
{ {
public: public:
LGB_MAPRANGE_HEADER header; MapRangeData data;
std::string name; std::string name;
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) : LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
LGB_ENTRY( buf, offset )
{ {
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset ); data = *reinterpret_cast< MapRangeData* >( buf + offset );
name = std::string( buf + offset + header.nameOffset ); name = std::string( buf + offset + header.nameOffset );
}; };
}; };
struct LGB_EXIT_RANGE_ENTRY : public LgbEntry
{
public:
ExitRangeData data;
std::string name;
LGB_EXIT_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
{
data = *reinterpret_cast< ExitRangeData* >( buf + offset );
name = std::string( buf + offset + header.nameOffset );
};
};
struct LGB_POP_RANGE_ENTRY : public LgbEntry
{
public:
PopRangeData data;
LGB_POP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
{
data = *reinterpret_cast< PopRangeData* >( buf + offset );
};
};
struct LGB_GROUP_HEADER struct LGB_GROUP_HEADER
{ {
uint32_t id; uint32_t id;
@ -272,15 +174,13 @@ struct LGB_GROUP
LGB_FILE* parent; LGB_FILE* parent;
LGB_GROUP_HEADER header; LGB_GROUP_HEADER header;
std::string name; std::string name;
std::vector< std::shared_ptr< LGB_ENTRY > > entries; std::vector< std::shared_ptr< LgbEntry > > entries;
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset ) LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
{ {
parent = parentStruct; parent = parentStruct;
header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset ); header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset );
name = std::string( buf + offset + header.groupNameOffset ); name = std::string( buf + offset + header.groupNameOffset );
//entries.resize( header.entryCount );
//std::cout << name << "\n\t unknown: " << header.unknown << "\n";
const auto entriesOffset = offset + header.entriesOffset; const auto entriesOffset = offset + header.entriesOffset;
for( auto i = 0; i < header.entryCount; ++i ) for( auto i = 0; i < header.entryCount; ++i )
{ {
@ -289,7 +189,6 @@ struct LGB_GROUP
try try
{ {
const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset ); const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset );
// garbage to skip model loading
if( type == LgbEntryType::BgParts ) if( type == LgbEntryType::BgParts )
{ {
entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) ); entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
@ -306,16 +205,18 @@ struct LGB_GROUP
{ {
entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) ); entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
} }
else if( type == LgbEntryType::ExitRange )
{
entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
}
else if( type == LgbEntryType::MapRange ) else if( type == LgbEntryType::MapRange )
{ {
entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) ); entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
} }
else else
{ {
entries.push_back( std::make_shared< LGB_ENTRY >( buf, entryOffset ) ); entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
} }
} }
catch( std::exception& e ) catch( std::exception& e )
{ {
@ -344,8 +245,7 @@ struct LGB_FILE
std::vector< LGB_GROUP > groups; std::vector< LGB_GROUP > groups;
std::string m_name; std::string m_name;
LGB_FILE( char* buf, const std::string& name ) : LGB_FILE( char* buf, const std::string& name ) : LGB_FILE( buf )
LGB_FILE( buf )
{ {
m_name = name; m_name = name;
} }
@ -356,8 +256,6 @@ struct LGB_FILE
if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 ) if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 )
throw std::runtime_error( "Invalid LGB file!" ); throw std::runtime_error( "Invalid LGB file!" );
//groups.resize(header.groupCount);
constexpr auto baseOffset = sizeof( header ); constexpr auto baseOffset = sizeof( header );
for( auto i = 0; i < header.groupCount; ++i ) for( auto i = 0; i < header.groupCount; ++i )
{ {

View file

@ -22,15 +22,13 @@ struct SGB_GROUP;
struct SGB_GROUP_HEADER; struct SGB_GROUP_HEADER;
enum SgbDataType : enum SgbDataType : uint32_t
uint32_t
{ {
Unknown0008 = 0x0008, Unknown0008 = 0x0008,
Group = 0x0100, Group = 0x0100,
}; };
enum SgbGroupEntryType : enum SgbGroupEntryType : uint32_t
uint32_t
{ {
Model = 0x01, Model = 0x01,
Gimmick = 0x06, Gimmick = 0x06,
@ -124,15 +122,13 @@ struct SGB_ENTRY_HEADER
vec3 scale; vec3 scale;
}; };
struct SGB_MODEL_HEADER : struct SGB_MODEL_HEADER : public SGB_ENTRY_HEADER
public SGB_ENTRY_HEADER
{ {
int32_t modelFileOffset; int32_t modelFileOffset;
int32_t collisionFileOffset; int32_t collisionFileOffset;
}; };
struct SGB_MODEL_ENTRY : struct SGB_MODEL_ENTRY : public SGB_GROUP_ENTRY
public SGB_GROUP_ENTRY
{ {
SGB_MODEL_HEADER header; SGB_MODEL_HEADER header;
SgbGroupEntryType type; SgbGroupEntryType type;

View file

@ -8,11 +8,8 @@
using xiv::utils::bparse::extract; using xiv::utils::bparse::extract;
namespace xiv namespace xiv::exd
{ {
namespace exd
{
struct ExdHeader struct ExdHeader
{ {
char magic[0x4]; char magic[0x4];
@ -26,27 +23,36 @@ namespace xiv
uint32_t id; uint32_t id;
uint32_t offset; uint32_t offset;
}; };
}
} }
namespace xiv namespace xiv::utils::bparse {
template<>
inline void reorder< xiv::exd::ExdHeader >( xiv::exd::ExdHeader& i_struct )
{ {
namespace utils for( int32_t i = 0; i < 0x4; ++i )
{ {
namespace bparse xiv::utils::bparse::reorder( i_struct.magic[ i ] );
{
template <> inline void reorder<xiv::exd::ExdHeader>( 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>( 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 ); }
} }
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 >( 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 xiv::exd
{ {
namespace exd
{
Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files ) Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files )
{ {
_exh = i_exh; _exh = i_exh;
@ -376,5 +382,4 @@ namespace xiv
} }
} }
}

12
deps/datReader/Exd.h vendored
View file

@ -8,9 +8,7 @@
#include "File.h" #include "File.h"
namespace xiv namespace xiv::exd
{
namespace exd
{ {
class Exh; class Exh;
@ -40,8 +38,12 @@ class Exd
public: public:
// i_exh: the header // i_exh: the header
// i_files: the multiple exd files // i_files: the multiple exd files
Exd() {} Exd()
{
}
Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files ); Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files );
~Exd(); ~Exd();
// Get a row by its id // Get a row by its id
@ -49,6 +51,7 @@ public:
// Get a row by its id and sub-row // Get a row by its id and sub-row
const std::vector< Field > get_row( uint32_t id, uint32_t subRow ); const std::vector< Field > get_row( uint32_t id, uint32_t subRow );
// Get all rows // Get all rows
const std::map< uint32_t, std::vector< Field>>& get_rows(); const std::map< uint32_t, std::vector< Field>>& get_rows();
@ -60,7 +63,6 @@ protected:
std::map< uint32_t, ExdCacheEntry > _idCache; std::map< uint32_t, ExdCacheEntry > _idCache;
}; };
}
} }
#endif // XIV_EXD_EXD_H #endif // XIV_EXD_EXD_H

View file

@ -11,19 +11,18 @@ namespace
{ {
// Suffix of the filenames given a language // Suffix of the filenames given a language
std::map<xiv::exd::Language, std::string> language_map = std::map<xiv::exd::Language, std::string> language_map =
{{xiv::exd::Language::none, ""}, {
{xiv::exd::Language::none, ""},
{xiv::exd::Language::ja, "_ja"}, {xiv::exd::Language::ja, "_ja"},
{xiv::exd::Language::en, "_en"}, {xiv::exd::Language::en, "_en"},
{xiv::exd::Language::de, "_de"}, {xiv::exd::Language::de, "_de"},
{xiv::exd::Language::fr, "_fr"}, {xiv::exd::Language::fr, "_fr"},
{xiv::exd::Language::chs, "_chs"}}; {xiv::exd::Language::chs, "_chs"}
};
} }
namespace xiv namespace xiv::exd
{ {
namespace exd
{
Cat::Cat( dat::GameData& i_game_data, const std::string& i_name ) : Cat::Cat( dat::GameData& i_game_data, const std::string& i_name ) :
_name( i_name ) _name( i_name )
{ {
@ -44,10 +43,11 @@ namespace xiv
std::vector< std::shared_ptr< dat::File>> files; std::vector< std::shared_ptr< dat::File>> files;
for( auto& exd_def: _header->get_exd_defs() ) for( auto& exd_def: _header->get_exd_defs() )
{ {
files.emplace_back( i_game_data.getFile("exd/" + i_name + "_" + std::to_string(exd_def.start_id) + language_map.at(language) + ".exd") ); files.emplace_back( i_game_data.getFile(
"exd/" + i_name + "_" + std::to_string( exd_def.start_id ) + language_map.at( language ) + ".exd" ) );
} }
// Instantiate the data for this language // Instantiate the data for this language
_data[language] = std::unique_ptr<Exd>(new Exd(_header, files)); _data[ language ] = std::make_unique< Exd >( _header, files );
} }
} }
} }
@ -79,4 +79,3 @@ namespace xiv
} }
} }
}

View file

@ -4,7 +4,7 @@
#include <memory> #include <memory>
#include <map> #include <map>
#include <experimental/filesystem> #include <filesystem>
#include "bparse.h" #include "bparse.h"
#include "Exd.h" #include "Exd.h"

View file

@ -7,10 +7,7 @@
#include "ExdCat.h" #include "ExdCat.h"
namespace xiv namespace xiv::exd {
{
namespace exd
{
ExdData::ExdData( dat::GameData& i_game_data ) try : ExdData::ExdData( dat::GameData& i_game_data ) try :
_game_data( i_game_data ) _game_data( i_game_data )
@ -42,7 +39,7 @@ ExdData::ExdData(dat::GameData& i_game_data) try :
// instantiate the creation mutex for this category // instantiate the creation mutex for this category
_cat_names.push_back( category ); _cat_names.push_back( category );
_cats[ category ] = std::unique_ptr< Cat >(); _cats[ category ] = std::unique_ptr< Cat >();
_cat_creation_mutexes[category] = std::unique_ptr<std::mutex>(new std::mutex()); _cat_creation_mutexes[ category ] = std::make_unique< std::mutex >();
std::getline( stream, line ); std::getline( stream, line );
} }
@ -92,9 +89,8 @@ void ExdData::create_category(const std::string& i_cat_name)
// Maybe after unlocking it has already been created, so check (most likely if it blocked) // Maybe after unlocking it has already been created, so check (most likely if it blocked)
if( !_cats[ i_cat_name ] ) if( !_cats[ i_cat_name ] )
{ {
_cats[i_cat_name] = std::unique_ptr<Cat>(new Cat(_game_data, i_cat_name)); _cats[ i_cat_name ] = std::make_unique< Cat >( _game_data, i_cat_name );
} }
} }
} }
}

View file

@ -5,7 +5,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <experimental/filesystem> #include <filesystem>
namespace xiv namespace xiv
{ {
@ -34,7 +34,7 @@ namespace xiv
const Cat& get_category(const std::string& i_cat_name); const Cat& get_category(const std::string& i_cat_name);
// Export in csv in base flder i_ouput_path // Export in csv in base flder i_ouput_path
void export_as_csvs(const std::experimental::filesystem::path& i_output_path); void export_as_csvs(const std::filesystem::path& i_output_path);
protected: protected:
// Lazy instantiation of category // Lazy instantiation of category

View file

@ -7,10 +7,9 @@
using xiv::utils::bparse::extract; using xiv::utils::bparse::extract;
namespace xiv namespace xiv::exd
{
namespace exd
{ {
Exh::Exh( const dat::File& i_file ) Exh::Exh( const dat::File& i_file )
{ {
// Get a stream from the file // Get a stream from the file
@ -74,4 +73,3 @@ const std::vector<ExhMember>& Exh::get_exh_members() const
} }
} }
}

66
deps/datReader/Exh.h vendored
View file

@ -5,11 +5,10 @@
#include "bparse.h" #include "bparse.h"
namespace xiv namespace xiv::exd
{ {
namespace exd enum class DataType :
{ uint16_t
enum class DataType : uint16_t
{ {
string = 0, string = 0,
boolean = 1, boolean = 1,
@ -47,32 +46,60 @@ namespace xiv
uint32_t start_id; uint32_t start_id;
uint32_t count_id; uint32_t count_id;
}; };
};
namespace xiv::utils::bparse {
template<>
inline void reorder< xiv::exd::ExhHeader >( xiv::exd::ExhHeader& 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.data_offset = xiv::utils::bparse::byteswap( i_struct.data_offset );
xiv::utils::bparse::reorder( i_struct.data_offset );
i_struct.field_count = xiv::utils::bparse::byteswap( i_struct.field_count );
xiv::utils::bparse::reorder( i_struct.field_count );
i_struct.exd_count = xiv::utils::bparse::byteswap( i_struct.exd_count );
xiv::utils::bparse::reorder( i_struct.exd_count );
i_struct.language_count = xiv::utils::bparse::byteswap( i_struct.language_count );
xiv::utils::bparse::reorder( i_struct.language_count );
}
template<>
inline void reorder< xiv::exd::ExhMember >( xiv::exd::ExhMember& i_struct )
{
i_struct.type = xiv::utils::bparse::byteswap( i_struct.type );
xiv::utils::bparse::reorder( i_struct.type );
i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset );
xiv::utils::bparse::reorder( i_struct.offset );
}
template<>
inline void reorder< xiv::exd::ExhExdDef >( xiv::exd::ExhExdDef& i_struct )
{
i_struct.start_id = xiv::utils::bparse::byteswap( i_struct.start_id );
xiv::utils::bparse::reorder( i_struct.start_id );
i_struct.count_id = xiv::utils::bparse::byteswap( i_struct.count_id );
xiv::utils::bparse::reorder( i_struct.count_id );
} }
}; };
namespace xiv namespace xiv
{ {
namespace utils
{
namespace bparse
{
template <> inline void reorder<xiv::exd::ExhHeader>( xiv::exd::ExhHeader& 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.data_offset = xiv::utils::bparse::byteswap( i_struct.data_offset ); xiv::utils::bparse::reorder( i_struct.data_offset ); i_struct.field_count = xiv::utils::bparse::byteswap( i_struct.field_count ); xiv::utils::bparse::reorder( i_struct.field_count ); i_struct.exd_count = xiv::utils::bparse::byteswap( i_struct.exd_count ); xiv::utils::bparse::reorder( i_struct.exd_count ); i_struct.language_count = xiv::utils::bparse::byteswap( i_struct.language_count ); xiv::utils::bparse::reorder( i_struct.language_count ); }
template <> inline void reorder<xiv::exd::ExhMember>( xiv::exd::ExhMember& i_struct ) { i_struct.type = xiv::utils::bparse::byteswap( i_struct.type ); xiv::utils::bparse::reorder( i_struct.type ); i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset ); xiv::utils::bparse::reorder( i_struct.offset ); }
template <> inline void reorder<xiv::exd::ExhExdDef>( xiv::exd::ExhExdDef& i_struct ) { i_struct.start_id = xiv::utils::bparse::byteswap( i_struct.start_id ); xiv::utils::bparse::reorder( i_struct.start_id ); i_struct.count_id = xiv::utils::bparse::byteswap( i_struct.count_id ); xiv::utils::bparse::reorder( i_struct.count_id ); }
}
}
};
namespace xiv
{
namespace dat namespace dat
{ {
class File; class File;
} }
namespace exd namespace exd
{ {
enum Language : uint16_t; enum Language :
uint16_t;
// Header file for exd data // Header file for exd data
class Exh class Exh
@ -80,12 +107,17 @@ namespace xiv
public: public:
// The header file // The header file
Exh( const dat::File& i_file ); Exh( const dat::File& i_file );
~Exh(); ~Exh();
const ExhHeader& get_header() const; const ExhHeader& get_header() const;
const std::vector< ExhExdDef >& get_exd_defs() const; const std::vector< ExhExdDef >& get_exd_defs() const;
const std::vector< Language >& get_languages() const; const std::vector< Language >& get_languages() const;
const std::map< uint32_t, ExhMember >& get_members() const; const std::map< uint32_t, ExhMember >& get_members() const;
const std::vector< ExhMember >& get_exh_members() const; const std::vector< ExhMember >& get_exh_members() const;
protected: protected:

View file

@ -2,9 +2,7 @@
#include <fstream> #include <fstream>
namespace xiv namespace xiv::dat
{
namespace dat
{ {
File::File() : File::File() :
@ -31,7 +29,7 @@ std::vector<std::vector<char>>& File::access_data_sections()
return _data_sections; return _data_sections;
} }
void File::exportToFile(const std::experimental::filesystem::path& i_path) const void File::exportToFile( const std::filesystem::path& i_path ) const
{ {
std::ofstream ofs( i_path.string(), std::ios_base::binary | std::ios_base::out ); std::ofstream ofs( i_path.string(), std::ios_base::binary | std::ios_base::out );
for( auto& data_section : _data_sections ) for( auto& data_section : _data_sections )
@ -42,4 +40,3 @@ void File::exportToFile(const std::experimental::filesystem::path& i_path) const
} }
} }
}

24
deps/datReader/File.h vendored
View file

@ -3,29 +3,20 @@
#include <vector> #include <vector>
#include <experimental/filesystem> #include <filesystem>
#include <stdint.h> #include <stdint.h>
#include "bparse.h" #include "bparse.h"
namespace xiv::dat
namespace xiv
{ {
namespace dat enum class FileType :
{ uint32_t
enum class FileType : uint32_t
{ {
empty = 1, empty = 1,
standard = 2, standard = 2,
model = 3, model = 3,
texture = 4, texture = 4,
}; };
}
};
namespace xiv
{
namespace dat
{
class Dat; class Dat;
@ -33,24 +24,25 @@ namespace xiv
class File class File
{ {
friend class Dat; friend class Dat;
public: public:
File(); File();
~File(); ~File();
FileType get_type() const; FileType get_type() const;
// Getters functions for the data in the file // Getters functions for the data in the file
const std::vector< std::vector< char>>& get_data_sections() const; const std::vector< std::vector< char>>& get_data_sections() const;
std::vector< std::vector< char>>& access_data_sections(); std::vector< std::vector< char>>& access_data_sections();
void exportToFile( const std::experimental::filesystem::path& i_path ) const; void exportToFile( const std::filesystem::path& i_path ) const;
protected: protected:
FileType _type; FileType _type;
std::vector< std::vector< char>> _data_sections; std::vector< std::vector< char>> _data_sections;
}; };
}
} }
#endif // XIV_DAT_FILE_H #endif // XIV_DAT_FILE_H

View file

@ -11,8 +11,7 @@
#include "DatCat.h" #include "DatCat.h"
#include "File.h" #include "File.h"
namespace namespace {
{
// Relation between category number and category name // Relation between category number and category name
// These names are taken straight from the exe, it helps resolve dispatching when getting files by path // These names are taken straight from the exe, it helps resolve dispatching when getting files by path
@ -48,12 +47,9 @@ namespace
{ 0x0C, "music" } }; { 0x0C, "music" } };
} }
namespace xiv namespace xiv::dat
{ {
namespace dat GameData::GameData( const std::filesystem::path& path ) try :
{
GameData::GameData(const std::experimental::filesystem::path& path) try :
m_path( path ) m_path( path )
{ {
int maxExLevel = 0; int maxExLevel = 0;
@ -62,18 +58,21 @@ GameData::GameData(const std::experimental::filesystem::path& path) try :
#ifdef _WIN32 #ifdef _WIN32
static constexpr auto sep = "\\"; static constexpr auto sep = "\\";
#else #else
static constexpr auto sep = std::experimental::filesystem::path::preferred_separator; static constexpr auto sep = std::filesystem::path::preferred_separator;
#endif #endif
// Determine which expansions are available // Determine which expansions are available
while( std::experimental::filesystem::exists( std::experimental::filesystem::path( m_path.string() + sep + "ex" + std::to_string( maxExLevel + 1 ) + sep + "ex" + std::to_string( maxExLevel + 1 ) + ".ver" ) ) ) while( std::filesystem::exists( std::filesystem::path(
m_path.string() + sep + "ex" + std::to_string( maxExLevel + 1 ) + sep + "ex" + std::to_string( maxExLevel + 1 ) +
".ver" ) ) )
{ {
maxExLevel++; maxExLevel++;
} }
// Iterate over the files in path // Iterate over the files in path
for( auto it = std::experimental::filesystem::directory_iterator( m_path.string() + "//ffxiv" ); it != std::experimental::filesystem::directory_iterator(); ++it ) for( auto it = std::filesystem::directory_iterator( m_path.string() + "//ffxiv" );
it != std::filesystem::directory_iterator(); ++it )
{ {
// Get the filename of the current element // Get the filename of the current element
auto filename = it->path().filename().string(); auto filename = it->path().filename().string();
@ -92,21 +91,24 @@ GameData::GameData(const std::experimental::filesystem::path& path) try :
// instantiate the creation mutex for this category // instantiate the creation mutex for this category
m_catNums.push_back( cat_nb ); m_catNums.push_back( cat_nb );
m_cats[ cat_nb ] = std::unique_ptr< Cat >(); m_cats[ cat_nb ] = std::unique_ptr< Cat >();
m_catCreationMutexes[cat_nb] = std::unique_ptr<std::mutex>( new std::mutex() ); m_catCreationMutexes[ cat_nb ] = std::make_unique< std::mutex >();
// Check for expansion // Check for expansion
for( int exNum = 1; exNum <= maxExLevel; exNum++ ) for( int exNum = 1; exNum <= maxExLevel; exNum++ )
{ {
const std::string path = m_path.string() + sep + buildDatStr( "ex" + std::to_string( exNum ), cat_nb, exNum, 0, "win32", "index" ); const std::string path =
m_path.string() + sep + buildDatStr( "ex" + std::to_string( exNum ), cat_nb, exNum, 0, "win32", "index" );
if( std::experimental::filesystem::exists( std::experimental::filesystem::path( path ) ) ) if( std::filesystem::exists( std::filesystem::path( path ) ) )
{ {
int chunkCount = 0; int chunkCount = 0;
for( int chunkTest = 0; chunkTest < 256; chunkTest++ ) for( int chunkTest = 0; chunkTest < 256; chunkTest++ )
{ {
if( std::experimental::filesystem::exists( m_path.string() + sep + buildDatStr( "ex" + std::to_string( exNum ), cat_nb, exNum, chunkTest, "win32", "index" ) ) ) if( std::filesystem::exists( m_path.string() + sep +
buildDatStr( "ex" + std::to_string( exNum ), cat_nb, exNum, chunkTest, "win32",
"index" ) ) )
{ {
m_exCats[ cat_nb ].exNumToChunkMap[ exNum ].chunkToCatMap[ chunkTest ] = std::unique_ptr< Cat >(); m_exCats[ cat_nb ].exNumToChunkMap[ exNum ].chunkToCatMap[ chunkTest ] = std::unique_ptr< Cat >();
chunkCount++; chunkCount++;
@ -130,7 +132,8 @@ GameData::~GameData()
} }
const std::string GameData::buildDatStr( const std::string folder, const int cat, const int exNum, const int chunk, const std::string platform, const std::string type ) const std::string GameData::buildDatStr( const std::string folder, const int cat, const int exNum, const int chunk,
const std::string platform, const std::string type )
{ {
char dat[1024]; char dat[1024];
sprintf( dat, "%s/%02x%02x%02x.%s.%s", folder.c_str(), cat, exNum, chunk, platform.c_str(), type.c_str() ); sprintf( dat, "%s/%02x%02x%02x.%s.%s", folder.c_str(), cat, exNum, chunk, platform.c_str(), type.c_str() );
@ -290,7 +293,7 @@ void GameData::createCategory(uint32_t catNum)
} }
// Actually creates the category // Actually creates the category
m_cats[catNum] = std::unique_ptr<Cat>( new Cat( m_path, catNum, catName ) ); m_cats[ catNum ] = std::make_unique< Cat >( m_path, catNum, catName );
} }
} }
@ -312,11 +315,11 @@ void GameData::createExCategory( uint32_t catNum )
for( auto const& chunk : m_exCats[ catNum ].exNumToChunkMap[ ex.first ].chunkToCatMap ) for( auto const& chunk : m_exCats[ catNum ].exNumToChunkMap[ ex.first ].chunkToCatMap )
{ {
// Actually creates the category // Actually creates the category
m_exCats[catNum].exNumToChunkMap[ex.first].chunkToCatMap[chunk.first] = std::unique_ptr<Cat>( new Cat( m_path, catNum, catName, ex.first, chunk.first ) ); m_exCats[ catNum ].exNumToChunkMap[ ex.first ].chunkToCatMap[ chunk.first ] = std::unique_ptr< Cat >(
new Cat( m_path, catNum, catName, ex.first, chunk.first ) );
} }
} }
} }
} }
} }
}

View file

@ -5,14 +5,13 @@
#include <unordered_map> #include <unordered_map>
#include <mutex> #include <mutex>
#include <experimental/filesystem> #include <filesystem>
namespace xiv namespace xiv::dat
{
namespace dat
{ {
class Cat; class Cat;
class File; class File;
// Interface to all the datfiles - Main entry point // Interface to all the datfiles - Main entry point
@ -21,16 +20,20 @@ class GameData
{ {
public: public:
// This should be the path in which the .index/.datX files are located // This should be the path in which the .index/.datX files are located
GameData( const std::experimental::filesystem::path& path ); GameData( const std::filesystem::path& path );
~GameData(); ~GameData();
static const std::string buildDatStr( const std::string folder, const int cat, const int exNum, const int chunk, const std::string platform, const std::string type ); static const std::string
buildDatStr( const std::string folder, const int cat, const int exNum, const int chunk, const std::string platform,
const std::string type );
// Returns all the scanned category number available in the path // Returns all the scanned category number available in the path
const std::vector< uint32_t >& getCatNumbers() const; const std::vector< uint32_t >& getCatNumbers() const;
// Return a specific category by its number (see getCatNumbers() for loops) // Return a specific category by its number (see getCatNumbers() for loops)
const Cat& getCategory( uint32_t catNum ); const Cat& getCategory( uint32_t catNum );
// Return a specific category by it's name (e.g.: "exd"/"game_script"/ etc...) // Return a specific category by it's name (e.g.: "exd"/"game_script"/ etc...)
const Cat& getCategory( const std::string& catName ); const Cat& getCategory( const std::string& catName );
@ -61,7 +64,7 @@ protected:
void createExCategory( uint32_t catNum ); void createExCategory( uint32_t catNum );
// Path given to constructor, pointing to the folder with the .index/.datX files // Path given to constructor, pointing to the folder with the .index/.datX files
const std::experimental::filesystem::path m_path; const std::filesystem::path m_path;
// Stored categories, indexed by their number, categories are instantiated and parsed individually when they are needed // Stored categories, indexed by their number, categories are instantiated and parsed individually when they are needed
std::unordered_map< uint32_t, std::unique_ptr< Cat>> m_cats; std::unordered_map< uint32_t, std::unique_ptr< Cat>> m_cats;
@ -71,14 +74,19 @@ protected:
// Map of all EX categories and their chunks, "CatNum - (ExNum - (ChunkNum - Cat))" // Map of all EX categories and their chunks, "CatNum - (ExNum - (ChunkNum - Cat))"
// Map of all EX categories and their chunks, "CatNum - (ExNum - (ChunkNum - Cat))" // Map of all EX categories and their chunks, "CatNum - (ExNum - (ChunkNum - Cat))"
using ChunkToCatMap = struct { std::unordered_map< uint32_t, std::unique_ptr< Cat > > chunkToCatMap; }; using ChunkToCatMap = struct
using ExNumToChunkMap = struct { std::unordered_map< uint32_t, ChunkToCatMap > exNumToChunkMap; }; {
std::unordered_map< uint32_t, std::unique_ptr< Cat > > chunkToCatMap;
};
using ExNumToChunkMap = struct
{
std::unordered_map< uint32_t, ChunkToCatMap > exNumToChunkMap;
};
using CatNumToExNumMap = std::unordered_map< uint32_t, ExNumToChunkMap >; using CatNumToExNumMap = std::unordered_map< uint32_t, ExNumToChunkMap >;
CatNumToExNumMap m_exCats; CatNumToExNumMap m_exCats;
std::unordered_map< uint32_t, std::unique_ptr< std::mutex>> m_catCreationMutexes; std::unordered_map< uint32_t, std::unique_ptr< std::mutex>> m_catCreationMutexes;
}; };
}
} }
#endif // XIV_DAT_GAMEDATA_H #endif // XIV_DAT_GAMEDATA_H

View file

@ -2,9 +2,7 @@
#include "bparse.h" #include "bparse.h"
namespace xiv namespace xiv::dat
{
namespace dat
{ {
struct IndexBlockRecord struct IndexBlockRecord
{ {
@ -21,13 +19,8 @@ namespace dat
uint32_t padding; uint32_t padding;
}; };
} }
}
namespace xiv namespace xiv::utils::bparse
{
namespace utils
{
namespace bparse
{ {
template<> template<>
inline void reorder< xiv::dat::IndexBlockRecord >( xiv::dat::IndexBlockRecord& i_struct ) inline void reorder< xiv::dat::IndexBlockRecord >( xiv::dat::IndexBlockRecord& i_struct )
@ -46,17 +39,13 @@ namespace bparse
xiv::utils::bparse::reorder( i_struct.padding ); xiv::utils::bparse::reorder( i_struct.padding );
} }
} }
}
};
using xiv::utils::bparse::extract; using xiv::utils::bparse::extract;
namespace xiv namespace xiv::dat
{
namespace dat
{ {
Index::Index(const std::experimental::filesystem::path& path) : Index::Index( const std::filesystem::path& path ) :
SqPack( path ) SqPack( path )
{ {
if( !m_handle ) if( !m_handle )
@ -84,7 +73,7 @@ Index::Index(const std::experimental::filesystem::path& path) :
// The dat number is found in the offset, last four bits // The dat number is found in the offset, last four bits
hashTableEntry.datNum = ( indexHashTableEntry.datOffset & 0xF ) / 0x2; hashTableEntry.datNum = ( indexHashTableEntry.datOffset & 0xF ) / 0x2;
// The offset in the dat file, needs to strip the dat number indicator // The offset in the dat file, needs to strip the dat number indicator
hashTableEntry.datOffset = ( indexHashTableEntry.datOffset & 0xFFFFFFF0 ) * 0x08; hashTableEntry.datOffset = ( indexHashTableEntry.datOffset - ( indexHashTableEntry.datOffset & 0x000F ) ) * 0x08;
hashTableEntry.dirHash = indexHashTableEntry.dirHash; hashTableEntry.dirHash = indexHashTableEntry.dirHash;
hashTableEntry.filenameHash = indexHashTableEntry.filenameHash; hashTableEntry.filenameHash = indexHashTableEntry.filenameHash;
} }
@ -164,4 +153,3 @@ void Index::isIndexBlockValid( const IndexBlockRecord& i_index_block_record )
} }
} }
}

View file

@ -5,18 +5,20 @@
#include <unordered_map> #include <unordered_map>
#include <experimental/filesystem> #include <filesystem>
namespace xiv { namespace xiv::dat
namespace dat { {
struct IndexBlockRecord; struct IndexBlockRecord;
class Index : public SqPack class Index :
public SqPack
{ {
public: public:
// Full path to the index file // Full path to the index file
Index( const std::experimental::filesystem::path& i_path ); Index( const std::filesystem::path& i_path );
virtual ~Index(); virtual ~Index();
// An entry in the hash table, representing a file in a given dat // An entry in the hash table, representing a file in a given dat
@ -36,12 +38,15 @@ public:
uint32_t getDatCount() const; uint32_t getDatCount() const;
bool doesFileExist( 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; bool doesDirExist( uint32_t dir_hash ) const;
// Returns the whole HashTable // Returns the whole HashTable
const HashTable& getHashTable() const; const HashTable& getHashTable() const;
// Returns the hash table for a specific dir // Returns the hash table for a specific dir
const DirHashTable& getDirHashTable( uint32_t dir_hash ) const; const DirHashTable& getDirHashTable( uint32_t dir_hash ) const;
// Returns the HashTableEntry for a given file given its hashes // Returns the HashTableEntry for a given file given its hashes
const HashTableEntry& getHashTableEntry( uint32_t dir_hash, uint32_t filename_hash ) const; const HashTableEntry& getHashTableEntry( uint32_t dir_hash, uint32_t filename_hash ) const;
@ -53,7 +58,6 @@ protected:
HashTable m_hashTable; HashTable m_hashTable;
}; };
}
} }
#endif // XIV_DAT_INDEX_H #endif // XIV_DAT_INDEX_H

View file

@ -1,11 +1,19 @@
#include "SqPack.h" #include "SqPack.h"
namespace xiv { namespace xiv::dat {
namespace dat { enum PlatformId :
uint8_t
{
Win32,
PS3,
PS4
};
struct SqPackHeader struct SqPackHeader
{ {
char magic[0x8]; char magic[0x8];
uint32_t zero; PlatformId platformId;
uint8_t padding0[3];
uint32_t size; uint32_t size;
uint32_t version; uint32_t version;
uint32_t type; uint32_t type;
@ -17,10 +25,9 @@ namespace dat {
uint32_t type; uint32_t type;
}; };
} }
}
namespace xiv { namespace xiv::utils:: bparse
namespace utils { {
namespace bparse {
template<> template<>
inline void reorder< xiv::dat::SqPackHeader >( xiv::dat::SqPackHeader& i_struct ) inline void reorder< xiv::dat::SqPackHeader >( xiv::dat::SqPackHeader& i_struct )
{ {
@ -28,7 +35,7 @@ namespace bparse {
{ {
xiv::utils::bparse::reorder( i_struct.magic[ i ] ); xiv::utils::bparse::reorder( i_struct.magic[ i ] );
} }
xiv::utils::bparse::reorder(i_struct.zero); xiv::utils::bparse::reorder( i_struct.platformId );
xiv::utils::bparse::reorder( i_struct.size ); xiv::utils::bparse::reorder( i_struct.size );
xiv::utils::bparse::reorder( i_struct.version ); xiv::utils::bparse::reorder( i_struct.version );
xiv::utils::bparse::reorder( i_struct.type ); xiv::utils::bparse::reorder( i_struct.type );
@ -41,18 +48,14 @@ namespace bparse {
xiv::utils::bparse::reorder( i_struct.type ); xiv::utils::bparse::reorder( i_struct.type );
} }
} }
}
};
using xiv::utils::bparse::extract; using xiv::utils::bparse::extract;
namespace xiv namespace xiv::dat
{
namespace dat
{ {
SqPack::SqPack( const std::experimental::filesystem::path& path ) :
// Open the file // Open the file
SqPack::SqPack( const std::filesystem::path& path ) :
m_handle( path.string(), std::ios_base::in | std::ios_base::binary ) m_handle( path.string(), std::ios_base::in | std::ios_base::binary )
{ {
// Extract the header // Extract the header
@ -73,4 +76,3 @@ namespace dat
} }
} }
}

View file

@ -3,28 +3,24 @@
#include <fstream> #include <fstream>
#include <experimental/filesystem> #include <filesystem>
#include "bparse.h" #include "bparse.h"
namespace xiv namespace xiv::dat
{ {
namespace dat
{
struct SqPackBlockHash struct SqPackBlockHash
{ {
uint8_t hash[0x14]; uint8_t hash[0x14];
uint32_t padding[0xB]; uint32_t padding[0xB];
}; };
}
} namespace xiv::utils::bparse
} {
namespace xiv { template<>
namespace utils { inline void reorder< xiv::dat::SqPackBlockHash >( xiv::dat::SqPackBlockHash& i_struct )
namespace bparse {
template <> inline void reorder<xiv::dat::SqPackBlockHash>( xiv::dat::SqPackBlockHash& i_struct )
{ {
for( auto i = 0; i < 0x14; ++i ) for( auto i = 0; i < 0x14; ++i )
{ {
@ -35,13 +31,9 @@ namespace xiv {
xiv::utils::bparse::reorder( i_struct.padding[ i ] ); xiv::utils::bparse::reorder( i_struct.padding[ i ] );
} }
} }
}
}
}; };
namespace xiv namespace xiv::dat
{
namespace dat
{ {
class SqPack class SqPack
@ -49,7 +41,8 @@ class SqPack
public: public:
// Full path to the sqpack file // Full path to the sqpack file
SqPack( const std::experimental::filesystem::path& i_path ); SqPack( const std::filesystem::path& i_path );
virtual ~SqPack(); virtual ~SqPack();
protected: protected:
@ -61,6 +54,5 @@ protected:
}; };
} }
}
#endif // XIV_DAT_SQPACK_H #endif // XIV_DAT_SQPACK_H

View file

@ -6,11 +6,7 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
namespace xiv namespace xiv::utils::bparse
{
namespace utils
{
namespace bparse
{ {
// Internal macro for byteswapping // Internal macro for byteswapping
@ -40,7 +36,10 @@ void read(std::istream& i_stream, StructType& i_struct)
} }
// By default a type does not need reordering // By default a type does not need reordering
template <typename StructType> void reorder(StructType& i_struct) {} template< typename StructType >
void reorder( StructType& i_struct )
{
}
// "Overload" for passed struct as arg // "Overload" for passed struct as arg
template< typename StructType > template< typename StructType >
@ -84,7 +83,8 @@ StructType extract(std::istream& i_stream, const std::string& i_name, bool i_is_
} }
template< typename StructType > template< typename StructType >
void extract(std::istream& i_stream, const std::string& i_name, uint32_t i_size, std::vector<StructType>& o_structs, bool i_is_le = true) void extract( std::istream& i_stream, const std::string& i_name, uint32_t i_size, std::vector< StructType >& o_structs,
bool i_is_le = true )
{ {
o_structs.reserve( i_size ); o_structs.reserve( i_size );
for( uint32_t i = 0; i < i_size; ++i ) for( uint32_t i = 0; i < i_size; ++i )
@ -96,8 +96,6 @@ void extract(std::istream& i_stream, const std::string& i_name, uint32_t i_size,
// For cstrings // For cstrings
std::string extract_cstring( std::istream& i_stream, const std::string& i_name ); std::string extract_cstring( std::istream& i_stream, const std::string& i_name );
}
}
} }
#endif // XIV_UTILS_BPARSE_H #endif // XIV_UTILS_BPARSE_H

View file

@ -1,8 +1,8 @@
#include "conv.h" #include "conv.h"
namespace xiv { namespace xiv::utils::conv
namespace utils { {
namespace conv {
float half2float( const uint16_t i_value ) float half2float( const uint16_t i_value )
{ {
uint32_t t1; uint32_t t1;
@ -30,6 +30,4 @@ namespace conv {
} }
} }
}
}

View file

@ -5,13 +5,11 @@
#include <vector> #include <vector>
#include <ostream> #include <ostream>
namespace xiv { namespace xiv::utils::conv
namespace utils { {
namespace conv {
float half2float( const uint16_t i_value ); float half2float( const uint16_t i_value );
float ubyte2float( const uint8_t i_value ); float ubyte2float( const uint8_t i_value );
} }
}
}
#endif // XIV_UTILS_CONV_H #endif // XIV_UTILS_CONV_H

View file

@ -65,11 +65,7 @@ namespace internal
} }
} }
namespace xiv namespace xiv::utils::crc32
{
namespace utils
{
namespace crc32
{ {
uint32_t compute( const std::string& i_input, uint32_t init_crc ) uint32_t compute( const std::string& i_input, uint32_t init_crc )
@ -130,7 +126,8 @@ void generate_hashes_1(std::string& i_format, const uint32_t i_first_index, std:
} }
} }
void generate_hashes_2(std::string& i_format, const uint32_t i_first_index, const uint32_t i_second_index, std::vector<uint32_t>& o_hashes) void generate_hashes_2( std::string& i_format, const uint32_t i_first_index, const uint32_t i_second_index,
std::vector< uint32_t >& o_hashes )
{ {
char* str = const_cast<char*>(i_format.data()); char* str = const_cast<char*>(i_format.data());
const uint32_t str_size = i_format.size(); const uint32_t str_size = i_format.size();
@ -176,5 +173,3 @@ void generate_hashes_2(std::string& i_format, const uint32_t i_first_index, cons
} }
}
}

View file

@ -5,9 +5,8 @@
#include <vector> #include <vector>
#include <string> #include <string>
namespace xiv { namespace xiv::utils::crc32
namespace utils { {
namespace crc32 {
// Normal crc32 computation from a given intial crc value, use zlib.crc32 instead, the final XOR 0xFFFFFFFF is not done // Normal crc32 computation from a given intial crc value, use zlib.crc32 instead, the final XOR 0xFFFFFFFF is not done
uint32_t compute( const std::string& i_input, uint32_t init_crc = 0xFFFFFFFF ); uint32_t compute( const std::string& i_input, uint32_t init_crc = 0xFFFFFFFF );
@ -17,10 +16,10 @@ namespace crc32 {
uint32_t rev_compute( const std::string& i_input, uint32_t init_crc = 0 ); uint32_t rev_compute( const std::string& i_input, uint32_t init_crc = 0 );
void generate_hashes_1( std::string& i_format, const uint32_t i_first_index, std::vector< uint32_t >& o_hashes ); void generate_hashes_1( std::string& i_format, const uint32_t i_first_index, std::vector< uint32_t >& o_hashes );
void generate_hashes_2( std::string& i_format, const uint32_t i_first_index, const uint32_t i_second_index, std::vector< uint32_t >& o_hashes );
} void generate_hashes_2( std::string& i_format, const uint32_t i_first_index, const uint32_t i_second_index,
} std::vector< uint32_t >& o_hashes );
} }
#endif // XIV_UTILS_CRC32_H #endif // XIV_UTILS_CRC32_H

View file

@ -4,13 +4,7 @@
#include <sstream> #include <sstream>
#include <streambuf> #include <streambuf>
namespace xiv namespace xiv::utils::stream
{
namespace utils
{
namespace stream
{ {
} }
}
}

View file

@ -5,14 +5,11 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
namespace xiv namespace xiv::utils::stream
{
namespace utils
{
namespace stream
{ {
template< typename CharT, typename TraitsT = std::char_traits< CharT > > template< typename CharT, typename TraitsT = std::char_traits< CharT > >
class vectorwrapbuf : public std::basic_streambuf<CharT, TraitsT> class vectorwrapbuf :
public std::basic_streambuf< CharT, TraitsT >
{ {
public: public:
vectorwrapbuf( std::vector< CharT >& vec ) vectorwrapbuf( std::vector< CharT >& vec )
@ -21,7 +18,4 @@ public:
} }
}; };
} }
}
}
#endif // XIV_UTILS_STREAM_H #endif // XIV_UTILS_STREAM_H

View file

@ -4,11 +4,7 @@
#include <zlib/zlib.h> #include <zlib/zlib.h>
#include <vector> #include <vector>
namespace xiv namespace xiv::utils::zlib
{
namespace utils
{
namespace zlib
{ {
void compress( const std::vector< char >& in, std::vector< char >& out ) void compress( const std::vector< char >& in, std::vector< char >& out )
@ -61,5 +57,3 @@ void no_header_decompress(uint8_t* in, uint32_t in_size, uint8_t* out, uint32_t
} }
} }
}
}

View file

@ -4,18 +4,13 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
namespace xiv namespace xiv::utils::zlib
{
namespace utils
{
namespace zlib
{ {
void compress( const std::vector< char >& in, std::vector< char >& out ); void compress( const std::vector< char >& in, std::vector< char >& out );
void no_header_decompress( uint8_t* in, uint32_t in_size, uint8_t* out, uint32_t out_size ); void no_header_decompress( uint8_t* in, uint32_t in_size, uint8_t* out, uint32_t out_size );
}
}
} }
#endif // XIV_UTILS_ZLIB_H #endif // XIV_UTILS_ZLIB_H

1
deps/ffxiv-actions vendored Submodule

@ -0,0 +1 @@
Subproject commit dde9b5bbfc7c0197de0b0b49b982a0ee9fe761ab

View file

@ -4,6 +4,10 @@
#include "PreparedStatement.h" #include "PreparedStatement.h"
#include <mysql.h> #include <mysql.h>
#ifdef _MSC_VER
// fixes compile error when compiling with vs2019
#include <stdexcept>
#endif
#include <vector> #include <vector>
Mysql::Connection::Connection( std::shared_ptr< MySqlBase > pBase, Mysql::Connection::Connection( std::shared_ptr< MySqlBase > pBase,

View file

@ -3,6 +3,8 @@
#include <memory> #include <memory>
#include <map> #include <map>
#include <string>
#include "MysqlCommon.h" #include "MysqlCommon.h"
typedef struct st_mysql MYSQL; typedef struct st_mysql MYSQL;

View file

@ -1,11 +0,0 @@
cmake_minimum_required(VERSION 3.0.2)
project(Sapphire)
if( WIN32 )
file( GLOB STACKWALKER_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h*" )
file( GLOB STACKWALKER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.c*" )
add_library( stackwalker ${STACKWALKER_INCLUDE_FILES} ${STACKWALKER_SOURCE_FILES} )
endif()

File diff suppressed because it is too large Load diff

View file

@ -1,255 +0,0 @@
#ifndef __STACKWALKER_H__
#define __STACKWALKER_H__
#if defined(_MSC_VER)
/**********************************************************************
*
* StackWalker.h
*
*
*
* LICENSE (http://www.opensource.org/licenses/bsd-license.php)
*
* Copyright (c) 2005-2009, Jochen Kalmbach
* 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 name of Jochen Kalmbach nor the names of its 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 OWNER 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.
*
* **********************************************************************/
// #pragma once is supported starting with _MSC_VER 1000,
// so we need not to check the version (because we only support _MSC_VER >= 1100)!
#pragma once
#include <windows.h>
#if _MSC_VER >= 1900
#pragma warning(disable : 4091)
#endif
// special defines for VC5/6 (if no actual PSDK is installed):
#if _MSC_VER < 1300
typedef unsigned __int64 DWORD64, *PDWORD64;
#if defined(_WIN64)
typedef unsigned __int64 SIZE_T, *PSIZE_T;
#else
typedef unsigned long SIZE_T, *PSIZE_T;
#endif
#endif // _MSC_VER < 1300
class StackWalkerInternal; // forward
class StackWalker
{
public:
typedef enum StackWalkOptions
{
// No addition info will be retrieved
// (only the address is available)
RetrieveNone = 0,
// Try to get the symbol-name
RetrieveSymbol = 1,
// Try to get the line for this symbol
RetrieveLine = 2,
// Try to retrieve the module-infos
RetrieveModuleInfo = 4,
// Also retrieve the version for the DLL/EXE
RetrieveFileVersion = 8,
// Contains all the above
RetrieveVerbose = 0xF,
// Generate a "good" symbol-search-path
SymBuildPath = 0x10,
// Also use the public Microsoft-Symbol-Server
SymUseSymSrv = 0x20,
// Contains all the above "Sym"-options
SymAll = 0x30,
// Contains all options (default)
OptionsAll = 0x3F
} StackWalkOptions;
StackWalker(int options = OptionsAll, // 'int' is by design, to combine the enum-flags
LPCSTR szSymPath = NULL,
DWORD dwProcessId = GetCurrentProcessId(),
HANDLE hProcess = GetCurrentProcess());
StackWalker(DWORD dwProcessId, HANDLE hProcess);
virtual ~StackWalker();
typedef BOOL(__stdcall* PReadProcessMemoryRoutine)(
HANDLE hProcess,
DWORD64 qwBaseAddress,
PVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesRead,
LPVOID pUserData // optional data, which was passed in "ShowCallstack"
);
BOOL LoadModules();
BOOL ShowCallstack(
HANDLE hThread = GetCurrentThread(),
const CONTEXT* context = NULL,
PReadProcessMemoryRoutine readMemoryFunction = NULL,
LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback
);
BOOL ShowObject(LPVOID pObject);
#if _MSC_VER >= 1300
// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public"
// in older compilers in order to use it... starting with VC7 we can declare it as "protected"
protected:
#endif
enum
{
STACKWALK_MAX_NAMELEN = 1024
}; // max name length for found symbols
protected:
// Entry for each Callstack-Entry
typedef struct CallstackEntry
{
DWORD64 offset; // if 0, we have no valid entry
CHAR name[STACKWALK_MAX_NAMELEN];
CHAR undName[STACKWALK_MAX_NAMELEN];
CHAR undFullName[STACKWALK_MAX_NAMELEN];
DWORD64 offsetFromSmybol;
DWORD offsetFromLine;
DWORD lineNumber;
CHAR lineFileName[STACKWALK_MAX_NAMELEN];
DWORD symType;
LPCSTR symTypeString;
CHAR moduleName[STACKWALK_MAX_NAMELEN];
DWORD64 baseOfImage;
CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
} CallstackEntry;
typedef enum CallstackEntryType
{
firstEntry,
nextEntry,
lastEntry
} CallstackEntryType;
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
virtual void OnLoadModule(LPCSTR img,
LPCSTR mod,
DWORD64 baseAddr,
DWORD size,
DWORD result,
LPCSTR symType,
LPCSTR pdbName,
ULONGLONG fileVersion);
virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry);
virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
virtual void OnOutput(LPCSTR szText);
StackWalkerInternal* m_sw;
HANDLE m_hProcess;
DWORD m_dwProcessId;
BOOL m_modulesLoaded;
LPSTR m_szSymPath;
int m_options;
int m_MaxRecursionCount;
static BOOL __stdcall myReadProcMem(HANDLE hProcess,
DWORD64 qwBaseAddress,
PVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesRead);
friend StackWalkerInternal;
}; // class StackWalker
// The "ugly" assembler-implementation is needed for systems before XP
// If you have a new PSDK and you only compile for XP and later, then you can use
// the "RtlCaptureContext"
// Currently there is no define which determines the PSDK-Version...
// So we just use the compiler-version (and assumes that the PSDK is
// the one which was installed by the VS-IDE)
// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later...
// But I currently use it in x64/IA64 environments...
//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400)
#if defined(_M_IX86)
#ifdef CURRENT_THREAD_VIA_EXCEPTION
// TODO: The following is not a "good" implementation,
// because the callstack is only valid in the "__except" block...
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
do \
{ \
memset(&c, 0, sizeof(CONTEXT)); \
EXCEPTION_POINTERS* pExp = NULL; \
__try \
{ \
throw 0; \
} \
__except (((pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER \
: EXCEPTION_EXECUTE_HANDLER)) \
{ \
} \
if (pExp != NULL) \
memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \
c.ContextFlags = contextFlags; \
} while (0);
#else
// clang-format off
// The following should be enough for walking the callstack...
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
do \
{ \
memset(&c, 0, sizeof(CONTEXT)); \
c.ContextFlags = contextFlags; \
__asm call x \
__asm x: pop eax \
__asm mov c.Eip, eax \
__asm mov c.Ebp, ebp \
__asm mov c.Esp, esp \
} while (0)
// clang-format on
#endif
#else
// The following is defined for x86 (XP and higher), x64 and IA64:
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
do \
{ \
memset(&c, 0, sizeof(CONTEXT)); \
c.ContextFlags = contextFlags; \
RtlCaptureContext(&c); \
} while (0);
#endif
#endif //defined(_MSC_VER)
#endif // __STACKWALKER_H__

View file

@ -31,8 +31,8 @@
#include <mutex> #include <mutex>
#include <functional> #include <functional>
#include <experimental/filesystem> #include <filesystem>
namespace ci { namespace fs = std::experimental::filesystem; } namespace ci { namespace fs = std::filesystem; }
//! Exception for when Watchdog can't locate a file or parse the wildcard //! Exception for when Watchdog can't locate a file or parse the wildcard
class WatchedFileSystemExc : public std::exception { class WatchedFileSystemExc : public std::exception {
@ -319,7 +319,7 @@ protected:
std::string mFilter; std::string mFilter;
std::function<void(const ci::fs::path&)> mCallback; std::function<void(const ci::fs::path&)> mCallback;
std::function<void(const std::vector<ci::fs::path>&)> mListCallback; std::function<void(const std::vector<ci::fs::path>&)> mListCallback;
std::map< std::string, std::experimental::filesystem::file_time_type > mModificationTimes; std::map< std::string, std::filesystem::file_time_type > mModificationTimes;
}; };
std::mutex mMutex; std::mutex mMutex;

View file

@ -0,0 +1,15 @@
-- Migration generated at 2019/07/06 03:52:54
-- 20190706035254_ConvertFixedSizeDataToBlobs.sql
ALTER TABLE `charainfo`
CHANGE COLUMN `TitleList` `TitleList` BLOB NULL DEFAULT NULL AFTER `ActiveTitle`,
CHANGE COLUMN `Achievement` `Achievement` BLOB NULL DEFAULT NULL AFTER `TitleList`,
CHANGE COLUMN `Aetheryte` `Aetheryte` BLOB NULL DEFAULT NULL AFTER `Achievement`,
CHANGE COLUMN `HowTo` `HowTo` BLOB NULL DEFAULT NULL AFTER `Aetheryte`,
CHANGE COLUMN `Minions` `Minions` BLOB NULL DEFAULT NULL AFTER `HowTo`,
CHANGE COLUMN `Mounts` `Mounts` BLOB NULL DEFAULT NULL AFTER `Minions`,
CHANGE COLUMN `Orchestrion` `Orchestrion` BLOB NULL DEFAULT NULL AFTER `Mounts`,
CHANGE COLUMN `QuestCompleteFlags` `QuestCompleteFlags` BLOB NULL DEFAULT NULL AFTER `ConfigFlags`,
CHANGE COLUMN `QuestTracking` `QuestTracking` BLOB NULL DEFAULT NULL AFTER `OpeningSequence`,
CHANGE COLUMN `Discovery` `Discovery` BLOB NULL DEFAULT NULL AFTER `GrandCompanyRank`,
CHANGE COLUMN `Unlocks` `Unlocks` BLOB NULL DEFAULT NULL AFTER `Pose`;

File diff suppressed because it is too large Load diff

View file

@ -400,13 +400,6 @@ CREATE TABLE `dbupdate` (
PRIMARY KEY(`name`) PRIMARY KEY(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `discoveryinfo` (
`id` int(10) NOT NULL,
`map_id` int(3) NOT NULL,
`discover_id` int(3) NOT NULL,
PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `house` ( CREATE TABLE `house` (
`HouseId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `HouseId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`LandSetId` int(10) UNSIGNED DEFAULT NULL, `LandSetId` int(10) UNSIGNED DEFAULT NULL,
@ -602,3 +595,8 @@ CREATE TABLE `charamonsternote` (
`UPDATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP, `UPDATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(`CharacterId`) PRIMARY KEY(`CharacterId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `__Migration` (
`MigrationName` VARCHAR(250) NOT NULL,
PRIMARY KEY (`MigrationName`)
) ENGINE=InnoDB;

View file

@ -1,89 +0,0 @@
#ifndef _FORWARDS_H
#define _FORWARDS_H
#include <memory>
namespace Sapphire
{
class Cell;
class Zone;
class Item;
class ItemContainer;
class Inventory;
class Session;
class ZonePosition;
using ZonePtr = std::shared_ptr< Zone >;
using ItemPtr = std::shared_ptr< Item >;
using ItemContainerPtr = std::shared_ptr< ItemContainer >;
using InventoryPtr = std::shared_ptr< Inventory >;
using SessionPtr = std::shared_ptr< Session >;
using ZonePositionPtr = std::shared_ptr< ZonePosition >;
namespace StatusEffect
{
class StatusEffect;
class StatusEffectContainer;
using StatusEffectPtr = std::shared_ptr< StatusEffect >;
using StatusEffectContainerPtr = std::shared_ptr< StatusEffectContainer >;
}
namespace Entity
{
class Chara;
class Player;
class BattleNpc;
using ActorPtr = std::shared_ptr< Chara >;
using PlayerPtr = std::shared_ptr< Player >;
using BattleNpcPtr = std::shared_ptr< BattleNpc >;
}
namespace Event
{
class EventHandler;
using EventPtr = std::shared_ptr< EventHandler >;
}
namespace Action
{
class Action;
class ActionTeleport;
class EventAction;
using ActionPtr = std::shared_ptr< Action >;
using ActionTeleportPtr = std::shared_ptr< ActionTeleport >;
using EventActionPtr = std::shared_ptr< EventAction >;
}
namespace Network
{
class Hive;
class Acceptor;
class Connection;
class WorldConnection;
class SessionConnection;
class ZoneConnection;
using HivePtr = std::shared_ptr< Hive >;
using AcceptorPtr = std::shared_ptr< Acceptor >;
using ConnectionPtr = std::shared_ptr< Connection >;
using WorldConnectionPtr = std::shared_ptr< WorldConnection >;
using ZoneConnectionPtr = std::shared_ptr< ZoneConnection >;
using SessionConnectionPtr = std::shared_ptr< SessionConnection >;
namespace Packets
{
class GamePacket;
using GamePacketPtr = std::shared_ptr< GamePacket >;
}
}
namespace Scripting
{
using EventReturnCallback = std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t,
uint16_t ) >;
}
using ActionCallback = std::function< void( Entity::Player&, uint32_t, uint64_t ) >;
}
#endif

View file

@ -1,14 +0,0 @@
#include "LoginSession.h"
namespace Sapphire {
LoginSession::LoginSession( void )
{
//setSocket(NULL);
}
LoginSession::~LoginSession( void )
{
}
}

View file

@ -1,57 +0,0 @@
#pragma once
#ifndef _CLoginSession_H_
#define _CLoginSession_H_
#include <stdint.h>
#include <string>
#include <string.h>
namespace Sapphire
{
class LoginSession
{
private:
uint32_t m_ip;
uint32_t m_accountId;
uint8_t m_sessionId[56];
public:
std::string newCharName;
LoginSession( void );
~LoginSession( void );
uint32_t getIp()
{
return m_ip;
}
void setSessionId( uint8_t* sessionId )
{
memcpy( m_sessionId, sessionId, 56 );
}
void setIp( uint32_t ip )
{
m_ip = ip;
}
uint32_t getAccountId()
{
return m_accountId;
}
void setAccountId( uint32_t id )
{
m_accountId = id;
}
};
}
#endif

View file

@ -1,29 +1,24 @@
#include "PlayerMinimal.h" #include "PlayerMinimal.h"
#include <Util/Util.h>
#include <Common.h> #include <Common.h>
#include <Exd/ExdDataGenerated.h> #include <Exd/ExdDataGenerated.h>
#include <Database/DatabaseDef.h> #include <Database/DatabaseDef.h>
#include <nlohmann/json.hpp>
extern Sapphire::Data::ExdDataGenerated g_exdDataGen; extern Sapphire::Data::ExdDataGenerated g_exdDataGen;
namespace Sapphire { namespace Sapphire::Api {
using namespace Common; using namespace Common;
// player constructor // player constructor
PlayerMinimal::PlayerMinimal( void ) : PlayerMinimal::PlayerMinimal() :
m_id( 0 ) m_id( 0 )
{ {
}
// deconstructor
PlayerMinimal::~PlayerMinimal( void )
{
} }
// load player from the db // load player from the db
@ -84,64 +79,101 @@ void PlayerMinimal::load( uint32_t charId )
} }
} }
std::string PlayerMinimal::getLookString()
{
auto it = m_lookMap.begin();
std::string lookString;
for( ; it != m_lookMap.end(); ++it )
{
std::string s = std::to_string( it->second );
lookString += "\"" + s + "\"";
if( it != m_lookMap.end() )
{
lookString += ",";
}
}
return lookString.substr( 0, lookString.size() - 1 );
}
std::string PlayerMinimal::getModelString()
{
std::string modelString = "\""
+ std::to_string( m_modelEquip[ 0 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 1 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 2 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 3 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 4 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 5 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 6 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 7 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 8 ] ) + "\",\""
+ std::to_string( m_modelEquip[ 9 ] ) + "\"";
return modelString;
}
std::string PlayerMinimal::getInfoJson() std::string PlayerMinimal::getInfoJson()
{ {
std::string charDetails = "{\"content\":[\"" + std::string( getName() ) + "\"," + auto payload = nlohmann::json();
"[\"0\",\"0\",\"0\",\"0\",\"" + std::to_string( m_classLevel ) + auto& c = payload["content"];
"\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"],"
"\"0\",\"0\",\"0\",\"" + // DisplayName
std::to_string( getBirthMonth() ) + c.push_back( getName() );
"\",\"" + std::to_string( getBirthDay() ) +
"\",\"" + std::to_string( getGuardianDeity() ) + // class levels
"\",\"" + std::to_string( m_class ) + auto levelsArray = nlohmann::json();
"\",\"0\",\"" + std::to_string( getZoneId() ) + for( int i = 0; i < Common::CLASSJOB_SLOTS; ++i )
"\",\"0\"," + {
"[" + getLookString() + "]," + // these must be strings
"\"" + std::to_string( m_modelMainWeapon ) + "\",\"" + std::to_string( m_modelSubWeapon ) + "\"," + levelsArray.push_back( std::to_string( m_classMap[ i ] ) );
"[" + getModelString() + "]," + }
"\"1\",\"0\",\"0\",\"0\",\"" + std::to_string( m_equipDisplayFlags ) +
"\",\"0\",\"\",\"0\",\"0\"]," + // ClassLv
"\"classname\":\"ClientSelectData\",\"classid\":116}"; c.push_back( levelsArray );
return charDetails;
// Race
c.push_back( "0" );
// Tribe
c.push_back( "0" );
// Sex
c.push_back( "0" );
// BirthMonth
c.push_back( std::to_string( getBirthMonth() ) );
// Birthday
c.push_back( std::to_string( getBirthDay() ) );
// GuardianDeity
c.push_back( std::to_string( getGuardianDeity() ) );
// Class
c.push_back( std::to_string( m_class ) );
// ZoneId
c.push_back( "0" );
// TerritoryType
c.push_back( std::to_string( getZoneId() ) );
// ContentFinderCondition
c.push_back( "0" );
// look map
auto lookArray = nlohmann::json();
for( auto& it : m_lookMap )
{
lookArray.push_back( std::to_string( it.second ) );
}
// Customize
c.push_back( lookArray );
// ModelMainWeapon
c.push_back( std::to_string( m_modelMainWeapon ) );
// ModelSubWeapon
c.push_back( std::to_string( m_modelSubWeapon ) );
// model
auto modelArray = nlohmann::json();
for( auto i : m_modelEquip )
{
modelArray.push_back( std::to_string( i ) );
}
// ModelEquip
c.push_back( modelArray );
// MainWeapon
c.push_back( "1" );
// SubWeapon
c.push_back( "0" );
// JobStone
c.push_back( "0" );
// RemakeFlag
c.push_back( "0" );
// ConfigFlags
c.push_back( std::to_string( m_equipDisplayFlags ) );
// Voice
c.push_back( "0" );
// WorldName
c.push_back( "" );
// LoginStatus
c.push_back( "0" );
// IsOutTerritory
c.push_back( "0" );
payload["classname"] = "ClientSelectData";
payload["classid"] = 116;
return payload.dump();
} }
uint8_t PlayerMinimal::getClassLevel() uint8_t PlayerMinimal::getClassLevel()
@ -150,30 +182,6 @@ uint8_t PlayerMinimal::getClassLevel()
return static_cast< uint8_t >( m_classMap[ classJobIndex ] ); return static_cast< uint8_t >( m_classMap[ classJobIndex ] );
} }
std::string PlayerMinimal::getClassString()
{
std::map< uint8_t, uint16_t >::iterator it;
it = m_classMap.begin();
std::string classString;
for( ; it != m_classMap.end(); ++it )
{
std::string s = std::to_string( it->second );
classString += "\"" + s + "\"";
if( it != m_classMap.end() )
{
classString += ",";
}
}
return classString.substr( 0, classString.size() - 1 );
}
void PlayerMinimal::saveAsNew() void PlayerMinimal::saveAsNew()
{ {

View file

@ -2,18 +2,19 @@
#define _PLAYERMINIMAL_H #define _PLAYERMINIMAL_H
#include <map> #include <map>
#include <stdint.h> #include <cstdint>
#include <string.h> #include <string>
#include <cstring>
namespace Sapphire namespace Sapphire::Api
{ {
class PlayerMinimal class PlayerMinimal
{ {
public: public:
PlayerMinimal( void ); PlayerMinimal();
~PlayerMinimal( void ); ~PlayerMinimal() = default;
// write player to the database // write player to the database
void write(); void write();
@ -23,14 +24,8 @@ namespace Sapphire
void saveAsNew(); void saveAsNew();
std::string getLookString();
std::string getInfoJson(); std::string getInfoJson();
std::string getModelString();
std::string getClassString();
uint8_t getClassLevel(); uint8_t getClassLevel();
// return the id of the actor // return the id of the actor

View file

@ -1,4 +1,4 @@
#include "SapphireAPI.h" #include "SapphireApi.h"
#include <Crypt/base64.h> #include <Crypt/base64.h>
#include "Session.h" #include "Session.h"
#include "PlayerMinimal.h" #include "PlayerMinimal.h"
@ -10,7 +10,9 @@
#include <Database/DatabaseDef.h> #include <Database/DatabaseDef.h>
bool Sapphire::Network::SapphireAPI::login( const std::string& username, const std::string& pass, std::string& sId ) using namespace Sapphire::Api;
bool SapphireApi::login( const std::string& username, const std::string& pass, std::string& sId )
{ {
std::string query = std::string query =
"SELECT account_id FROM accounts WHERE account_name = '" + username + "' AND account_pass = '" + pass + "';"; "SELECT account_id FROM accounts WHERE account_name = '" + username + "' AND account_pass = '" + pass + "';";
@ -53,7 +55,7 @@ bool Sapphire::Network::SapphireAPI::login( const std::string& username, const s
} }
bool Sapphire::Network::SapphireAPI::insertSession( const uint32_t accountId, std::string& sId ) bool SapphireApi::insertSession( const uint32_t accountId, std::string& sId )
{ {
// create session for the new sessionid and store to sessionlist // create session for the new sessionid and store to sessionlist
auto pSession = std::make_shared< Session >(); auto pSession = std::make_shared< Session >();
@ -66,7 +68,7 @@ bool Sapphire::Network::SapphireAPI::insertSession( const uint32_t accountId, st
} }
bool Sapphire::Network::SapphireAPI::createAccount( const std::string& username, const std::string& pass, std::string& sId ) bool SapphireApi::createAccount( const std::string& username, const std::string& pass, std::string& sId )
{ {
// get account from login name // get account from login name
auto pQR = g_charaDb.query( "SELECT account_id FROM accounts WHERE account_name = '" + username + "';" ); auto pQR = g_charaDb.query( "SELECT account_id FROM accounts WHERE account_name = '" + username + "';" );
@ -96,11 +98,11 @@ bool Sapphire::Network::SapphireAPI::createAccount( const std::string& username,
} }
int Sapphire::Network::SapphireAPI::createCharacter( const uint32_t accountId, const std::string& name, int SapphireApi::createCharacter( const uint32_t accountId, const std::string& name,
const std::string& infoJson, const std::string& infoJson,
const uint32_t gmRank ) const uint32_t gmRank )
{ {
Sapphire::PlayerMinimal newPlayer; Api::PlayerMinimal newPlayer;
newPlayer.setAccountId( accountId ); newPlayer.setAccountId( accountId );
newPlayer.setId( getNextCharId() ); newPlayer.setId( getNextCharId() );
@ -169,7 +171,7 @@ int Sapphire::Network::SapphireAPI::createCharacter( const uint32_t accountId, c
return newPlayer.getAccountId(); return newPlayer.getAccountId();
} }
void Sapphire::Network::SapphireAPI::deleteCharacter( std::string name, const uint32_t accountId ) void SapphireApi::deleteCharacter( std::string name, const uint32_t accountId )
{ {
PlayerMinimal deletePlayer; PlayerMinimal deletePlayer;
auto charList = getCharList( accountId ); auto charList = getCharList( accountId );
@ -190,26 +192,28 @@ void Sapphire::Network::SapphireAPI::deleteCharacter( std::string name, const ui
g_charaDb.execute( "DELETE FROM characlass WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM characlass WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaglobalitem WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaglobalitem WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charainfoblacklist WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charainfoblacklist WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charainfofriendlist WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charainfolinkshell WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charainfolinkshell WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charainfosearch WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charainfosearch WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaitemcrystal WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaitemcrystal WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaitemcurrency WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaiteminventory WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaiteminventory WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaitemgearset WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaitemgearset WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charamonsternote WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charaquest WHERE CharacterId LIKE '" + std::to_string( id ) + "';" ); g_charaDb.execute( "DELETE FROM charaquest WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
g_charaDb.execute( "DELETE FROM charastatus WHERE CharacterId LIKE '" + std::to_string( id ) + "';" );
} }
std::vector< Sapphire::PlayerMinimal > Sapphire::Network::SapphireAPI::getCharList( uint32_t accountId ) std::vector< PlayerMinimal > SapphireApi::getCharList( uint32_t accountId )
{ {
std::vector< Sapphire::PlayerMinimal > charList; std::vector< Api::PlayerMinimal > charList;
auto pQR = g_charaDb.query( auto pQR = g_charaDb.query(
"SELECT CharacterId, ContentId FROM charainfo WHERE AccountId = " + std::to_string( accountId ) + ";" ); "SELECT CharacterId, ContentId FROM charainfo WHERE AccountId = " + std::to_string( accountId ) + ";" );
while( pQR->next() ) while( pQR->next() )
{ {
Sapphire::PlayerMinimal player; Api::PlayerMinimal player;
uint32_t charId = pQR->getUInt( 1 ); uint32_t charId = pQR->getUInt( 1 );
@ -220,7 +224,7 @@ std::vector< Sapphire::PlayerMinimal > Sapphire::Network::SapphireAPI::getCharLi
return charList; return charList;
} }
bool Sapphire::Network::SapphireAPI::checkNameTaken( std::string name ) bool SapphireApi::checkNameTaken( std::string name )
{ {
g_charaDb.escapeString( name ); g_charaDb.escapeString( name );
@ -234,7 +238,7 @@ bool Sapphire::Network::SapphireAPI::checkNameTaken( std::string name )
return true; return true;
} }
uint32_t Sapphire::Network::SapphireAPI::getNextCharId() uint32_t SapphireApi::getNextCharId()
{ {
uint32_t charId = 0; uint32_t charId = 0;
@ -250,7 +254,7 @@ uint32_t Sapphire::Network::SapphireAPI::getNextCharId()
return charId; return charId;
} }
uint64_t Sapphire::Network::SapphireAPI::getNextContentId() uint64_t SapphireApi::getNextContentId()
{ {
uint64_t contentId = 0; uint64_t contentId = 0;
@ -266,7 +270,7 @@ uint64_t Sapphire::Network::SapphireAPI::getNextContentId()
return contentId; return contentId;
} }
int Sapphire::Network::SapphireAPI::checkSession( const std::string& sId ) int SapphireApi::checkSession( const std::string& sId )
{ {
auto it = m_sessionMap.find( sId ); auto it = m_sessionMap.find( sId );
@ -277,7 +281,7 @@ int Sapphire::Network::SapphireAPI::checkSession( const std::string& sId )
} }
bool Sapphire::Network::SapphireAPI::removeSession( const std::string& sId ) bool SapphireApi::removeSession( const std::string& sId )
{ {
auto it = m_sessionMap.find( sId ); auto it = m_sessionMap.find( sId );

View file

@ -7,19 +7,15 @@
#include <memory> #include <memory>
#include "PlayerMinimal.h" #include "PlayerMinimal.h"
namespace Sapphire namespace Sapphire::Api
{ {
class Session; class Session;
}
namespace Sapphire::Network class SapphireApi
{
class SapphireAPI
{ {
public: public:
SapphireAPI() = default; SapphireApi() = default;
~SapphireAPI() = default; ~SapphireApi() = default;
using SessionMap = std::map< std::string, std::shared_ptr< Session > >; using SessionMap = std::map< std::string, std::shared_ptr< Session > >;
@ -34,7 +30,7 @@ namespace Sapphire::Network
bool insertSession( uint32_t accountId, std::string& sId ); bool insertSession( uint32_t accountId, std::string& sId );
std::vector< Sapphire::PlayerMinimal > getCharList( uint32_t accountId ); std::vector< Api::PlayerMinimal > getCharList( uint32_t accountId );
bool checkNameTaken( std::string name ); bool checkNameTaken( std::string name );

View file

@ -1,6 +1,7 @@
#include "Session.h" #include "Session.h"
namespace Sapphire { using namespace Sapphire::Api;
Session::Session() Session::Session()
{ {
@ -35,4 +36,3 @@ void Session::setAccountId( uint32_t id )
{ {
m_accountId = id; m_accountId = id;
} }
}

View file

@ -5,7 +5,7 @@
#include <string> #include <string>
#include <string.h> #include <string.h>
namespace Sapphire namespace Sapphire::Api
{ {
class Session class Session

View file

@ -22,25 +22,23 @@
//Added for the default_resource example //Added for the default_resource example
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <experimental/filesystem> #include <filesystem>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <Framework.h>
#include <Logging/Logger.h> #include <Logging/Logger.h>
#include "Forwards.h" #include "SapphireApi.h"
#include "SapphireAPI.h"
#include <Util/CrashHandler.h> #include <Util/CrashHandler.h>
Sapphire::Common::Util::CrashHandler crashHandler; [[maybe_unused]] Sapphire::Common::Util::CrashHandler crashHandler;
Sapphire::Db::DbWorkerPool< Sapphire::Db::ZoneDbConnection > g_charaDb; Sapphire::Db::DbWorkerPool< Sapphire::Db::ZoneDbConnection > g_charaDb;
Sapphire::Data::ExdDataGenerated g_exdDataGen; Sapphire::Data::ExdDataGenerated g_exdDataGen;
Sapphire::Network::SapphireAPI g_sapphireAPI; Sapphire::Api::SapphireApi g_sapphireAPI;
namespace fs = std::experimental::filesystem; namespace fs = std::filesystem;
using namespace std; using namespace std;
using namespace Sapphire; using namespace Sapphire;
@ -59,7 +57,7 @@ Sapphire::Common::Config::ApiConfig m_config;
void reloadConfig() void reloadConfig()
{ {
auto pConfig = std::make_shared< Sapphire::ConfigMgr >(); auto pConfig = std::make_shared< Sapphire::Common::ConfigMgr >();
Logger::info( "Loading config " + configPath ); Logger::info( "Loading config " + configPath );
@ -106,7 +104,7 @@ bool loadSettings( int32_t argc, char* argv[] )
try try
{ {
arg = Sapphire::Util::toLowerCopy( std::string( args[ i ] ) ); arg = Common::Util::toLowerCopy( std::string( args[ i ] ) );
val = std::string( args[ i + 1 ] ); val = std::string( args[ i + 1 ] );
// trim '-' from start of arg // trim '-' from start of arg
@ -336,7 +334,7 @@ void createCharacter( shared_ptr< HttpServer::Response > response, shared_ptr< H
std::string name = json["name"]; std::string name = json["name"];
std::string infoJson = json["infoJson"]; std::string infoJson = json["infoJson"];
std::string finalJson = Sapphire::Util::base64Decode( infoJson ); std::string finalJson = Common::Util::base64Decode( infoJson );
// reloadConfig(); // reloadConfig();
@ -672,8 +670,9 @@ void defaultGet( shared_ptr< HttpServer::Response > response, shared_ptr< HttpSe
print_request_info( request ); print_request_info( request );
try try
{ {
auto web_root_path = fs::canonical( "web" ); auto web_root_path = fs::current_path() / "web";
auto path = fs::canonical( web_root_path / request->path ); auto path = web_root_path / request->path;
//Check if path is within web_root_path //Check if path is within web_root_path
if( distance( web_root_path.begin(), web_root_path.end() ) > distance( path.begin(), path.end() ) || if( distance( web_root_path.begin(), web_root_path.end() ) > distance( path.begin(), path.end() ) ||
!std::equal( web_root_path.begin(), web_root_path.end(), path.begin() ) ) !std::equal( web_root_path.begin(), web_root_path.end(), path.begin() ) )
@ -700,7 +699,7 @@ void defaultGet( shared_ptr< HttpServer::Response > response, shared_ptr< HttpSe
catch( const exception& ) catch( const exception& )
{ {
string content = "Path not found: " + request->path; string content = "Path not found: " + request->path;
*response << buildHttpResponse( 400, content ); *response << buildHttpResponse( 404, content );
} }
} }
@ -719,19 +718,19 @@ int main( int argc, char* argv[] )
Logger::setLogLevel( m_config.global.general.logLevel ); Logger::setLogLevel( m_config.global.general.logLevel );
server.resource[ "^/ZoneName/([0-9]+)$" ][ "GET" ] = &getZoneName; server.resource[ "^ZoneName/([0-9]+)$" ][ "GET" ] = &getZoneName;
server.resource[ "^/sapphire-api/lobby/createAccount" ][ "POST" ] = &createAccount; server.resource[ "^sapphire-api/lobby/createAccount" ][ "POST" ] = &createAccount;
server.resource[ "^/sapphire-api/lobby/login" ][ "POST" ] = &login; server.resource[ "^sapphire-api/lobby/login" ][ "POST" ] = &login;
server.resource[ "^/sapphire-api/lobby/deleteCharacter" ][ "POST" ] = &deleteCharacter; server.resource[ "^sapphire-api/lobby/deleteCharacter" ][ "POST" ] = &deleteCharacter;
server.resource[ "^/sapphire-api/lobby/createCharacter" ][ "POST" ] = &createCharacter; server.resource[ "^sapphire-api/lobby/createCharacter" ][ "POST" ] = &createCharacter;
server.resource[ "^/sapphire-api/lobby/insertSession" ][ "POST" ] = &insertSession; server.resource[ "^sapphire-api/lobby/insertSession" ][ "POST" ] = &insertSession;
server.resource[ "^/sapphire-api/lobby/checkNameTaken" ][ "POST" ] = &checkNameTaken; server.resource[ "^sapphire-api/lobby/checkNameTaken" ][ "POST" ] = &checkNameTaken;
server.resource[ "^/sapphire-api/lobby/checkSession" ][ "POST" ] = &checkSession; server.resource[ "^sapphire-api/lobby/checkSession" ][ "POST" ] = &checkSession;
server.resource[ "^/sapphire-api/lobby/getNextCharId" ][ "POST" ] = &getNextCharId; server.resource[ "^sapphire-api/lobby/getNextCharId" ][ "POST" ] = &getNextCharId;
server.resource[ "^/sapphire-api/lobby/getNextContentId" ][ "POST" ] = &getNextContentId; server.resource[ "^sapphire-api/lobby/getNextContentId" ][ "POST" ] = &getNextContentId;
server.resource[ "^/sapphire-api/lobby/getCharacterList" ][ "POST" ] = &getCharacterList; server.resource[ "^sapphire-api/lobby/getCharacterList" ][ "POST" ] = &getCharacterList;
server.resource[ "^(/frontier-api/ffxivsupport/view/get_init)(.*)" ][ "GET" ] = &get_init; server.resource[ "^(frontier-api/ffxivsupport/view/get_init)(.*)" ][ "GET" ] = &get_init;
server.resource[ "^(/frontier-api/ffxivsupport/information/get_headline_all)(.*)" ][ "GET" ] = &get_headline_all; server.resource[ "^(frontier-api/ffxivsupport/information/get_headline_all)(.*)" ][ "GET" ] = &get_headline_all;
server.default_resource[ "GET" ] = &defaultGet; server.default_resource[ "GET" ] = &defaultGet;

View file

@ -18,7 +18,7 @@
class case_insensitive_equals { class case_insensitive_equals {
public: public:
bool operator()(const std::string &key1, const std::string &key2) const { bool operator()(const std::string &key1, const std::string &key2) const {
return Sapphire::Util::toLowerCopy( key1 ) == Sapphire::Util::toLowerCopy( key2 ); return Sapphire::Common::Util::toLowerCopy( key1 ) == Sapphire::Common::Util::toLowerCopy( key2 );
} }
}; };
class case_insensitive_hash { class case_insensitive_hash {
@ -27,7 +27,7 @@ public:
{ {
std::size_t seed=0; std::size_t seed=0;
for( auto &c : key ) for( auto &c : key )
Sapphire::Util::hashCombine< char >( seed, std::tolower( c ) ); Sapphire::Common::Util::hashCombine< char >( seed, std::tolower( c ) );
return seed; return seed;
} }
}; };
@ -304,7 +304,7 @@ namespace SimpleWeb {
size_t path_end; size_t path_end;
if((path_end=line.find(' ', method_end+1))!=std::string::npos) { if((path_end=line.find(' ', method_end+1))!=std::string::npos) {
request->method=line.substr(0, method_end); request->method=line.substr(0, method_end);
request->path=line.substr(method_end+1, path_end-method_end-1); request->path=line.substr(method_end+2, path_end-method_end-2);
size_t protocol_end; size_t protocol_end;
if((protocol_end=line.find('/', path_end+1))!=std::string::npos) { if((protocol_end=line.find('/', path_end+1))!=std::string::npos) {
@ -388,7 +388,7 @@ namespace SimpleWeb {
auto range=request->header.equal_range("Connection"); auto range=request->header.equal_range("Connection");
for(auto it=range.first;it!=range.second;it++) { for(auto it=range.first;it!=range.second;it++) {
if( Sapphire::Util::toLowerCopy( it->second ) == "close" ) if( Sapphire::Common::Util::toLowerCopy( it->second ) == "close" )
return; return;
} }
if(http_version>1.05) if(http_version>1.05)

View file

@ -26,10 +26,6 @@ if( UNIX )
PUBLIC PUBLIC
pthread pthread
stdc++fs ) stdc++fs )
else()
target_link_libraries( common
PUBLIC
stackwalker )
endif() endif()
target_include_directories( common target_include_directories( common

View file

@ -21,6 +21,14 @@ namespace Sapphire::Common
const int32_t INVALID_GAME_OBJECT_ID = 0xE0000000; const int32_t INVALID_GAME_OBJECT_ID = 0xE0000000;
const uint64_t INVALID_GAME_OBJECT_ID64 = 0xE0000000; const uint64_t INVALID_GAME_OBJECT_ID64 = 0xE0000000;
const uint16_t MAX_PLAYER_LEVEL = 80;
const uint8_t CURRENT_EXPANSION_ID = 3;
const uint8_t CLASSJOB_TOTAL = 38;
const uint8_t CLASSJOB_SLOTS = 28;
const uint8_t TOWN_COUNT = 6;
/*! /*!
* @brief The maximum length (in ms) of a combo before it is canceled/voided. * @brief The maximum length (in ms) of a combo before it is canceled/voided.
* *
@ -41,13 +49,13 @@ namespace Sapphire::Common
uint8_t plot; uint8_t plot;
}; };
enum InventoryOperation : uint8_t enum InventoryOperation : uint16_t
{ {
Discard = 0x07, Discard = 0x013C,
Move = 0x08, Move = 0x013D,
Swap = 0x09, Swap = 0x013E,
Merge = 0x0C, Split = 0x013F,
Split = 0x0A Merge = 0x0141,
}; };
enum ClientLanguage : uint8_t enum ClientLanguage : uint8_t
@ -151,44 +159,46 @@ namespace Sapphire::Common
ModelRing2 = 9 ModelRing2 = 9
}; };
enum EquipSlotCategory : uint8_t enum class EquipSlotCategory : uint8_t
{ {
Unequippable = 0,
// main slots // main slots
CharaMainHand = 1, CharaMainHand = 0,
CharaOffHand = 2, CharaOffHand = 1,
CharaHead = 3, CharaHead = 2,
CharaBody = 4, CharaBody = 3,
CharaHands = 5, CharaHands = 4,
CharaWaist = 6, CharaWaist = 5,
CharaLegs = 7, CharaLegs = 6,
CharaFeet = 8, CharaFeet = 7,
CharaEars = 9, CharaEars = 8,
CharaNeck = 10, CharaNeck = 9,
CharaWrist = 11, CharaWrist = 10,
CharaRing = 12, CharaRing = 11,
CharaSoulCrystal = 17, CharaSoulCrystal = 12,
// specials /* following slots not seem to exist any more.
when multi-slot gear is moved into equipment slot, normal slot listed above is used.
client will move any incompatible gears into armory but no InventoryModifiyHandler is sent.
server need to move those silently in order to sync with client.
*/
/*! Cannot equip gear to offhand slot */ /*! Cannot equip gear to offhand slot */
MainTwoHandedWeapon = 13, //MainTwoHandedWeapon = 13,
/*! Can be equipped in either main or offhand slot */ /*! Can be equipped in either main or offhand slot */
MainOrOffHand = 14, // unused //MainOrOffHand = 14, // unused
/*! Cannot equip gear to head */ /*! Cannot equip gear to head */
BodyDisallowHead = 15, //BodyDisallowHead = 15,
/*! Cannot equip gear to hands, legs and feet slots */ /*! Cannot equip gear to hands, legs and feet slots */
BodyDisallowHandsLegsFeet = 16, //BodyDisallowHandsLegsFeet = 16,
/*! Cannot equip gear to feet slot */ /*! Cannot equip gear to feet slot */
LegsDisallowFeet = 18, //LegsDisallowFeet = 18,
/*! Cannot equp gear to head, hands, legs, feet slots */ /*! Cannot equp gear to head, hands, legs, feet slots */
BodyDisallowAll = 19, //BodyDisallowAll = 19,
/*! Cannot equip gear to hands slot */ /*! Cannot equip gear to hands slot */
BodyDisallowHands = 20, //BodyDisallowHands = 20,
/*! Cannot equip gear to legs & feet slots */ /*! Cannot equip gear to legs & feet slots */
BodyDisallowLegsFeet = 21, //BodyDisallowLegsFeet = 21,
}; };
enum InventoryType : uint16_t enum InventoryType : uint16_t
@ -208,6 +218,8 @@ namespace Sapphire::Common
HandIn = 2005, HandIn = 2005,
DamagedGear = 2007, DamagedGear = 2007,
//UNKNOWN_1 = 2008, //UNKNOWN_1 = 2008,
// Temporary inventory that is used for the "trade" window
TradeInventory = 2009,
ArmoryOff = 3200, ArmoryOff = 3200,
ArmoryHead = 3201, ArmoryHead = 3201,
@ -216,14 +228,20 @@ namespace Sapphire::Common
ArmoryWaist = 3204, ArmoryWaist = 3204,
ArmoryLegs = 3205, ArmoryLegs = 3205,
ArmoryFeet = 3206, ArmoryFeet = 3206,
ArmoryNeck = 3207, ArmoryEar = 3207,
ArmoryEar = 3208, ArmoryNeck = 3208,
ArmoryWrist = 3209, ArmoryWrist = 3209,
ArmoryRing = 3300, ArmoryRing = 3300,
ArmorySoulCrystal = 3400, ArmorySoulCrystal = 3400,
ArmoryMain = 3500, ArmoryMain = 3500,
SaddleBag0 = 4000,
SaddleBag1 = 4001,
// These are the ones you get when paying for premium companion app
PremiumSaddleBag0 = 4100,
PremiumSaddleBag1 = 4101,
RetainerBag0 = 10000, RetainerBag0 = 10000,
RetainerBag1 = 10001, RetainerBag1 = 10001,
RetainerBag2 = 10002, RetainerBag2 = 10002,
@ -396,7 +414,7 @@ namespace Sapphire::Common
struct StatusEffect struct StatusEffect
{ {
uint16_t effect_id; uint16_t effect_id;
uint16_t unknown1; uint16_t param;
float duration; float duration;
uint32_t sourceActorId; uint32_t sourceActorId;
}; };
@ -548,6 +566,30 @@ namespace Sapphire::Common
}; };
enum FieldMarkerStatus : uint32_t
{
A = 0x1,
B = 0x2,
C = 0x4,
D = 0x8,
One = 0x10,
Two = 0x20,
Three = 0x40,
Four = 0x80
};
// TODO: consolidate these two into one since FieldMarkerStatus == 1 << FieldMarkerId?
enum class FieldMarkerId : uint8_t
{
A,
B,
C,
D,
One,
Two,
Three,
Four
};
enum struct ActionAspect : uint8_t enum struct ActionAspect : uint8_t
{ {
None = 0, // Doesn't imply unaspected None = 0, // Doesn't imply unaspected
@ -565,19 +607,27 @@ namespace Sapphire::Common
None = 0, // ? None = 0, // ?
MagicPoints = 3, MagicPoints = 3,
TacticsPoints = 5, TacticsPoints = 5,
// WARGauge = 22, StatusEffect = 10,
// DRKGauge = 25, WARGauge = 22,
DRKGauge = 25,
// AetherflowStack = 30, // AetherflowStack = 30,
// Status = 32, // Status = 32,
// PLDGauge = 41, SAMKenki = 39,
SAMSen = 40,
PLDGauge = 41,
GNBAmmo = 55,
WHMBloodLily = 56,
WHMLily = 57,
SAMMeditation = 63,
// RDMGaugeBoth = 74, // RDMGaugeBoth = 74,
//// RDMGaugeBlack = 75, // not right? //// RDMGaugeBlack = 75, // not right?
// DRGGauge3Eyes = 76, // DRGGauge3Eyes = 76,
}; };
enum class ActionType : int8_t enum class AttackType : int8_t
{ {
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)? //WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
Physical = -1, // seems to be the case
Unknown_0 = 0, Unknown_0 = 0,
Slashing = 1, Slashing = 1,
Piercing = 2, Piercing = 2,
@ -606,28 +656,41 @@ namespace Sapphire::Common
TpLoss = 12, TpLoss = 12,
TpGain = 13, TpGain = 13,
GpGain = 14, GpGain = 14,
ApplyStatusEffectTarget = 15,
ApplyStatusEffectSource = 16, // effect entry on target but buff applies to source, like storm's eye
StatusNoEffect = 20, // shifted one up from 5.18
/*! /*!
* @brief Tells the client that it should show combo indicators on actions. * @brief Tells the client that it should show combo indicators on actions.
* *
* @param flags Required to be 128, doesn't show combo rings on hotbars otherwise * @param flags Required to be 128, doesn't show combo rings on hotbars otherwise
* @param value The actionid that starts/continues the combo. eg, 3617 will start a spinning slash and/or syphon strike combo * @param value The actionid that starts/continues the combo. eg, 3617 will start a spinning slash and/or syphon strike combo
*/ */
StartActionCombo = 28, StartActionCombo = 27, // shifted one up from 5.18
ComboSucceed = 28, // shifted one up from 5.18, on retail this is not seen anymore, still working though.
Knockback = 33, Knockback = 33,
Mount = 38, Mount = 40, // shifted one down from 5.18
VFX = 59, // links to VFX sheet VFX = 59, // links to VFX sheet
}; };
enum class ActionHitSeverityType : uint8_t enum class ActionHitSeverityType : uint8_t
{ {
NormalDamage = 0, NormalDamage = 0,
CritHeal = 0, NormalHeal = 0,
CritDamage = 1, CritDamage = 1,
NormalHeal = 1, CritHeal = 1,
DirectHitDamage = 2, DirectHitDamage = 2,
CritDirectHitDamage = 3 CritDirectHitDamage = 3
}; };
enum class ActionEffectResultFlag : uint8_t
{
None = 0,
Absorbed = 0x04,
ExtendedValue = 0x40,
EffectOnSource = 0x80,
Reflected = 0xA0,
};
enum ItemActionType : uint16_t enum ItemActionType : uint16_t
{ {
ItemActionVFX = 852, ItemActionVFX = 852,
@ -644,15 +707,15 @@ namespace Sapphire::Common
struct EffectEntry struct EffectEntry
{ {
Common::ActionEffectType effectType; Common::ActionEffectType effectType;
Common::ActionHitSeverityType hitSeverity; uint8_t param0;
uint8_t param; uint8_t param1;
/*! /*!
* @brief Shows an additional percentage in the battle log * @brief Shows an additional percentage in the battle log
* *
* Has no effect on what is shown and stored in value * Has no effect on what is shown and stored in value
*/ */
int8_t bonusPercent; uint8_t param2;
uint8_t valueMultiplier; // This multiplies whatever value is in the 'value' param by 10. Possibly a workaround for big numbers uint8_t extendedValueHighestByte;
uint8_t flags; uint8_t flags;
int16_t value; int16_t value;
}; };
@ -968,8 +1031,6 @@ namespace Sapphire::Common
enum LevelTableEntry : uint8_t enum LevelTableEntry : uint8_t
{ {
PIE,
MP,
MAIN, MAIN,
SUB, SUB,
DIV, DIV,
@ -982,7 +1043,225 @@ namespace Sapphire::Common
{ {
SingleTarget = 1, SingleTarget = 1,
CircularAOE = 2, CircularAOE = 2,
Type3 = 3, // another single target? no idea how to call it
RectangularAOE = 4, RectangularAOE = 4,
CircularAoEPlaced = 7
};
enum class Role : uint8_t
{
None,
Tank,
Healer,
RangedPhysical,
RangedMagical,
Melee,
Crafter,
Gatherer
};
enum class AstCardType : uint8_t
{
None = 0,
Balance = 1,
Bole = 2,
Arrow = 3,
Spear = 4,
Ewer = 5,
Spire = 6,
Lord = 0x70,
Lady = 0x80,
};
enum class AstSealType : uint8_t
{
None = 0,
Sun = 1,
Moon = 2,
Celestrial = 3,
};
enum class DrgState : uint8_t
{
None = 0,
BloodOfTheDragon = 1,
LifeOfTheDragon = 2,
};
enum class SamSen : uint8_t
{
None = 0,
Setsu = 1,
Getsu = 2,
Ka = 4,
};
enum class SchDismissedFairy : uint8_t
{
None = 0,
Eos = 6,
Selene = 7,
};
enum class SmnPet : uint8_t
{
None = 0,
Ifrit = 3,
Titan = 4,
Garuda = 5,
};
enum class SmnPetGlam : uint8_t
{
None = 0,
Emerald = 1,
Topaz = 2,
Ruby = 3,
};
enum class BrdSong : uint8_t
{
Mage = 5,
Army = 0x0A,
Wanderer = 0x0F,
};
union JobGauge
{
struct
{
uint8_t gauge_data[15];
} _raw;
struct
{
uint32_t unused;
AstCardType card;
AstSealType seals[3];
} ast;
struct
{
uint16_t timeUntilNextPolyglot;
uint16_t elementTimer;
uint8_t elementStance;
uint8_t umbralhearts;
uint8_t polyglotStacks;
uint8_t enochainState;
} blm;
struct
{
uint16_t songTimer;
uint8_t songStacks;
uint8_t unused;
BrdSong song;
} brd;
struct
{
uint8_t feathers;
uint8_t esprit;
uint8_t stepOrder[4];
uint8_t completeSteps;
} dnc;
struct
{
uint16_t dragonTimer;
DrgState dragonState;
uint8_t eyes;
} drg;
struct
{
uint8_t blood;
uint8_t unused;
uint16_t darksideTimer;
uint8_t darkArts;
uint8_t unused2;
uint16_t shadowTimer;
} drk;
struct
{
uint8_t ammo;
uint8_t unused;
uint16_t maxTimerDuration;
uint8_t ammoComboStep;
} gnb;
struct
{
uint16_t overheatTimer;
uint16_t robotTimer;
uint8_t heat;
uint8_t battery;
uint8_t lastRobotBatteryPower;
uint8_t activeTimerFlag;
} mch;
struct
{
uint8_t greasedLightningTimer;
uint8_t unused;
uint8_t greasedLightningStacks;
uint8_t chakra;
uint8_t greasedLightningTimerFreezed;
} mnk;
struct
{
uint32_t hutonTimer;
uint8_t tenChiJinMudrasUsed;
uint8_t ninki;
uint8_t hutonManualCasts;
} nin;
struct
{
uint8_t oathGauge;
} pld;
struct
{
uint8_t whiteGauge;
uint8_t blackGauge;
} rdm;
struct
{
uint16_t unused;
uint8_t unused2;
uint8_t kenki;
uint8_t meditationStacks;
SamSen sen;
} sam;
struct
{
uint16_t unused;
uint8_t aetherflowStacks;
uint8_t fairyGauge;
uint16_t seraphTimer;
SchDismissedFairy dismissedFairy;
} sch;
struct
{
uint16_t timer;
SmnPet returnSummon;
SmnPetGlam petGlam;
uint8_t stacks;
} smn;
struct
{
uint8_t beastGauge;
} war;
struct
{
uint16_t unused;
uint16_t lilyTimer;
uint8_t lilies;
uint8_t bloodLilies;
} whm;
};
enum class LootMessageType : uint8_t
{
GetItem1 = 1, // p1: actorId, p4: itemId (HQ: itemId + 1,000,000 lol), p5: amount
GetItem2 = 3, // p1: actorId, p2: itemId, p3: amount, seems like same thing as GetItem1 but different param position.
FailedToGetLootNoFreeInventorySlot = 5, // p1: actorId
LootRolled = 7, // p1: actorId, p2: itemId, p3: amount
GetGil = 9, // p1: gil
EmptyCoffer = 11, // seems like no param
}; };
using PlayerStateFlagList = std::vector< PlayerStateFlag >; using PlayerStateFlagList = std::vector< PlayerStateFlag >;

View file

@ -6,8 +6,7 @@
/* This file has been automatically generated. /* This file has been automatically generated.
Changes will be lost upon regeneration. Changes will be lost upon regeneration.
To change the content edit tools/exd_common_gen */ To change the content edit tools/exd_common_gen */
namespace Sapphire { namespace Sapphire::Common {
namespace Common {
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
//ActionCategory.exd //ActionCategory.exd
@ -173,6 +172,8 @@ enum class ClassJob : uint8_t
Samurai = 34, Samurai = 34,
Redmage = 35, Redmage = 35,
Bluemage = 36, Bluemage = 36,
Gunbreaker = 37,
Dancer = 38,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -199,14 +200,10 @@ enum class ContentType : uint8_t
DisciplesoftheHand = 17, DisciplesoftheHand = 17,
RetainerVentures = 18, RetainerVentures = 18,
GoldSaucer = 19, GoldSaucer = 19,
one = 20,
DeepDungeons = 21, DeepDungeons = 21,
two = 22,
three = 23,
WondrousTails = 24, WondrousTails = 24,
CustomDeliveries = 25, CustomDeliveries = 25,
Eureka = 26, Eureka = 26,
four = 27,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -217,7 +214,6 @@ enum class EmoteCategory : uint8_t
General = 1, General = 1,
Special = 2, Special = 2,
Expressions = 3, Expressions = 3,
one = 4,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -227,7 +223,7 @@ enum class ExVersion : uint8_t
ARealmReborn = 0, ARealmReborn = 0,
Heavensward = 1, Heavensward = 1,
Stormblood = 2, Stormblood = 2,
three = 3, Shadowbringers = 3,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -369,6 +365,8 @@ enum class ItemUICategory : uint8_t
SubmersibleBow = 103, SubmersibleBow = 103,
SubmersibleBridge = 104, SubmersibleBridge = 104,
BlueMagesArm = 105, BlueMagesArm = 105,
GunbreakersArm = 106,
DancersArm = 107,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -393,7 +391,7 @@ enum class ItemSearchCategory : uint8_t
ConjurersArms = 15, ConjurersArms = 15,
ArcanistsArms = 16, ArcanistsArms = 16,
Shields = 17, Shields = 17,
ThrowingWeapons = 18, DancersArms = 18,
CarpentersTools = 19, CarpentersTools = 19,
BlacksmithsTools = 20, BlacksmithsTools = 20,
ArmorersTools = 21, ArmorersTools = 21,
@ -454,13 +452,15 @@ enum class ItemSearchCategory : uint8_t
DarkKnightsArms = 76, DarkKnightsArms = 76,
MachinistsArms = 77, MachinistsArms = 77,
AstrologiansArms = 78, AstrologiansArms = 78,
Airship_SubmersibleComponents = 79, AirshipSubmersibleComponents = 79,
OrchestrionComponents = 80, OrchestrionComponents = 80,
GardeningItems = 81, GardeningItems = 81,
Paintings = 82, Paintings = 82,
SamuraisArms = 83, SamuraisArms = 83,
RedMagesArms = 84, RedMagesArms = 84,
ScholarsArms = 85, ScholarsArms = 85,
GunbreakersArms = 86,
ThrowingWeapons = 87,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -527,6 +527,8 @@ enum class Race : uint8_t
Miqote = 4, Miqote = 4,
Roegadyn = 5, Roegadyn = 5,
AuRa = 6, AuRa = 6,
Hrothgar = 7,
Viera = 8,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -546,6 +548,10 @@ enum class Tribe : uint8_t
Hellsguard = 10, Hellsguard = 10,
Raen = 11, Raen = 11,
Xaela = 12, Xaela = 12,
Helions = 13,
TheLost = 14,
Rava = 15,
Veena = 16,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -558,6 +564,7 @@ enum class Town : uint8_t
Uldah = 3, Uldah = 3,
Ishgard = 4, Ishgard = 4,
Kugane = 7, Kugane = 7,
TheCrystarium = 10,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -680,7 +687,21 @@ enum class Weather : uint8_t
TrueBlue = 113, TrueBlue = 113,
TrueBlue1 = 114, TrueBlue1 = 114,
TrueBlue2 = 115, TrueBlue2 = 115,
UmbralTurbulence = 116,
TrueBlue3 = 117, TrueBlue3 = 117,
EverlastingLight = 118,
Gales2 = 119,
Termination = 120,
Termination1 = 121,
Dreams = 122,
Dreams1 = 123,
Dreams2 = 124,
Brilliance = 125,
Brilliance1 = 126,
Termination2 = 127,
Termination3 = 128,
EverlastingLight1 = 129,
Termination4 = 131,
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -703,8 +724,12 @@ enum class HousingAppeal : uint8_t
Library = 14, Library = 14,
PhotoStudio = 15, PhotoStudio = 15,
HauntedHouse = 16, HauntedHouse = 16,
Atelier = 17,
Bathhouse = 18,
Garden = 19,
FarEastern = 20,
}; };
}
} }
#endif #endif

View file

@ -1,16 +1,18 @@
#include "ConfigMgr.h" #include "ConfigMgr.h"
#include <iostream> #include <iostream>
#include <fstream> #include <filesystem>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem; namespace fs = std::filesystem;
using namespace Sapphire;
using namespace Sapphire::Common;
/** /**
* Loads an ini file and parses it * Loads an ini file and parses it
* @param configName the name of ini file relative to m_configFolderRoot to load alongside global.ini * @param configName the name of ini file relative to m_configFolderRoot to load alongside global.ini
* @return true if loading was successful * @return true if loading was successful
*/ */
bool Sapphire::ConfigMgr::loadConfig( const std::string& configName ) bool ConfigMgr::loadConfig( const std::string& configName )
{ {
// get global config // get global config
auto configFile = fs::path( fs::path( m_configFolderRoot ) / configName ); auto configFile = fs::path( fs::path( m_configFolderRoot ) / configName );
@ -29,7 +31,7 @@ bool Sapphire::ConfigMgr::loadConfig( const std::string& configName )
return true; return true;
} }
bool Sapphire::ConfigMgr::loadGlobalConfig( Common::Config::GlobalConfig& config, const std::string& configName ) bool ConfigMgr::loadGlobalConfig( Common::Config::GlobalConfig& config, const std::string& configName )
{ {
auto configFile = fs::path( fs::path( m_configFolderRoot ) / configName ); auto configFile = fs::path( fs::path( m_configFolderRoot ) / configName );
@ -71,7 +73,7 @@ bool Sapphire::ConfigMgr::loadGlobalConfig( Common::Config::GlobalConfig& config
return true; return true;
} }
bool Sapphire::ConfigMgr::copyDefaultConfig( const std::string& configName ) bool ConfigMgr::copyDefaultConfig( const std::string& configName )
{ {
fs::path configPath( m_configFolderRoot ); fs::path configPath( m_configFolderRoot );
configPath /= configName; configPath /= configName;

View file

@ -8,7 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include "ConfigDef.h" #include "ConfigDef.h"
namespace Sapphire namespace Sapphire::Common
{ {
class ConfigMgr class ConfigMgr
{ {

View file

@ -41,7 +41,7 @@ static inline bool is_base64( uint8_t c )
return ( isalnum( c ) || ( c == '+' ) || ( c == '/' ) ); return ( isalnum( c ) || ( c == '+' ) || ( c == '/' ) );
} }
std::string Sapphire::Util::base64Encode( uint8_t const* bytes_to_encode, uint32_t in_len ) std::string Sapphire::Common::Util::base64Encode( uint8_t const* bytes_to_encode, uint32_t in_len )
{ {
std::string ret; std::string ret;
int32_t i = 0; int32_t i = 0;
@ -87,7 +87,7 @@ std::string Sapphire::Util::base64Encode( uint8_t const* bytes_to_encode, uint32
} }
std::string Sapphire::Util::base64Decode( std::string const& encoded_string ) std::string Sapphire::Common::Util::base64Decode( std::string const& encoded_string )
{ {
int32_t in_len = encoded_string.size(); int32_t in_len = encoded_string.size();
int32_t i = 0; int32_t i = 0;

View file

@ -1,6 +1,6 @@
#include <string> #include <string>
namespace Sapphire::Util namespace Sapphire::Common::Util
{ {
std::string base64Encode( uint8_t const*, uint32_t len ); std::string base64Encode( uint8_t const*, uint32_t len );

View file

@ -37,7 +37,7 @@
(b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \ (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \
} }
void Sapphire::Util::md5_starts( md5_context* ctx ) void Sapphire::Common::Util::md5_starts( md5_context* ctx )
{ {
ctx->total[ 0 ] = 0; ctx->total[ 0 ] = 0;
ctx->total[ 1 ] = 0; ctx->total[ 1 ] = 0;
@ -48,7 +48,7 @@ void Sapphire::Util::md5_starts( md5_context* ctx )
ctx->state[ 3 ] = 0x10325476; ctx->state[ 3 ] = 0x10325476;
} }
void md5_process( Sapphire::Util::md5_context* ctx, uint8_t data[64] ) void md5_process( Sapphire::Common::Util::md5_context* ctx, uint8_t data[64] )
{ {
uint32_t X[16], A, B, C, D; uint32_t X[16], A, B, C, D;
@ -171,7 +171,7 @@ void md5_process( Sapphire::Util::md5_context* ctx, uint8_t data[64] )
ctx->state[ 3 ] += D; ctx->state[ 3 ] += D;
} }
void Sapphire::Util::md5_update( md5_context* ctx, uint8_t* input, uint32_t length ) void Sapphire::Common::Util::md5_update( md5_context* ctx, uint8_t* input, uint32_t length )
{ {
uint32_t left, fill; uint32_t left, fill;
@ -219,7 +219,7 @@ static uint8_t md5_padding[64] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
void Sapphire::Util::md5_finish( md5_context* ctx, uint8_t digest[16] ) void Sapphire::Common::Util::md5_finish( md5_context* ctx, uint8_t digest[16] )
{ {
uint32_t last, padn; uint32_t last, padn;
uint32_t high, low; uint32_t high, low;
@ -248,7 +248,7 @@ void Sapphire::Util::md5_finish( md5_context* ctx, uint8_t digest[16] )
* those are the standard RFC 1321 test vectors * those are the standard RFC 1321 test vectors
*/ */
void Sapphire::Util::md5( uint8_t* text, uint8_t* hash, int32_t size ) void Sapphire::Common::Util::md5( uint8_t* text, uint8_t* hash, int32_t size )
{ {
md5_context ctx; md5_context ctx;
md5_starts( &ctx ); md5_starts( &ctx );

View file

@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
namespace Sapphire::Util namespace Sapphire::Common::Util
{ {
using md5_context = struct using md5_context = struct
{ {

View file

@ -1,6 +1,8 @@
#ifndef SAPPHIRE_DBCOMMON_H #ifndef SAPPHIRE_DBCOMMON_H
#define SAPPHIRE_DBCOMMON_H #define SAPPHIRE_DBCOMMON_H
#include <string>
namespace Sapphire::Db namespace Sapphire::Db
{ {
struct ConnectionInfo struct ConnectionInfo

View file

@ -4,7 +4,6 @@
#include "Logging/Logger.h" #include "Logging/Logger.h"
#include "PreparedStatement.h" #include "PreparedStatement.h"
#include "Framework.h"
Sapphire::Db::DbConnection::DbConnection( ConnectionInfo& connInfo ) : Sapphire::Db::DbConnection::DbConnection( ConnectionInfo& connInfo ) :
m_reconnecting( false ), m_reconnecting( false ),
@ -17,7 +16,7 @@ Sapphire::Db::DbConnection::DbConnection( ConnectionInfo& connInfo ) :
} }
Sapphire::Db::DbConnection::DbConnection( Sapphire::LockedWaitQueue< std::shared_ptr< Operation > >* queue, Sapphire::Db::DbConnection::DbConnection( Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* queue,
Sapphire::Db::ConnectionInfo& connInfo ) : Sapphire::Db::ConnectionInfo& connInfo ) :
m_reconnecting( false ), m_reconnecting( false ),
m_prepareError( false ), m_prepareError( false ),

View file

@ -42,7 +42,7 @@ namespace Sapphire::Db
DbConnection( ConnectionInfo& connInfo ); DbConnection( ConnectionInfo& connInfo );
// Constructor for asynchronous connections. // Constructor for asynchronous connections.
DbConnection( Sapphire::LockedWaitQueue< std::shared_ptr< Operation > >* queue, ConnectionInfo& connInfo ); DbConnection( Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* queue, ConnectionInfo& connInfo );
virtual ~DbConnection(); virtual ~DbConnection();
@ -92,7 +92,7 @@ namespace Sapphire::Db
bool m_prepareError; bool m_prepareError;
private: private:
LockedWaitQueue< std::shared_ptr< Operation > >* m_queue; Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* m_queue;
std::shared_ptr< DbWorker > m_worker; std::shared_ptr< DbWorker > m_worker;
std::shared_ptr< Mysql::Connection > m_pConnection; std::shared_ptr< Mysql::Connection > m_pConnection;
ConnectionInfo& m_connectionInfo; ConnectionInfo& m_connectionInfo;

View file

@ -2,7 +2,9 @@
#include "Operation.h" #include "Operation.h"
#include "Util/LockedWaitQueue.h" #include "Util/LockedWaitQueue.h"
Sapphire::Db::DbWorker::DbWorker( Sapphire::LockedWaitQueue< std::shared_ptr< Operation > >* newQueue, using namespace Sapphire::Common;
Sapphire::Db::DbWorker::DbWorker( Util::LockedWaitQueue< std::shared_ptr< Operation > >* newQueue,
DbConnection* pConn ) DbConnection* pConn )
{ {
m_pConn = pConn; m_pConn = pConn;

View file

@ -14,12 +14,12 @@ namespace Sapphire::Db
class DbWorker class DbWorker
{ {
public: public:
DbWorker( LockedWaitQueue< std::shared_ptr< Operation > >* newQueue, DbConnection* connection ); DbWorker( Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* newQueue, DbConnection* connection );
~DbWorker(); ~DbWorker();
private: private:
LockedWaitQueue< std::shared_ptr< Operation > >* m_queue; Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* m_queue;
DbConnection* m_pConn; DbConnection* m_pConn;
void workerThread(); void workerThread();

View file

@ -5,7 +5,6 @@
#include "StatementTask.h" #include "StatementTask.h"
#include "Operation.h" #include "Operation.h"
#include "ZoneDbConnection.h" #include "ZoneDbConnection.h"
#include "Framework.h"
#include "Logging/Logger.h" #include "Logging/Logger.h"
#include <mysql.h> #include <mysql.h>
@ -21,7 +20,7 @@ class PingOperation : public Sapphire::Db::Operation
template< class T > template< class T >
Sapphire::Db::DbWorkerPool< T >::DbWorkerPool() : Sapphire::Db::DbWorkerPool< T >::DbWorkerPool() :
m_queue( new Sapphire::LockedWaitQueue< std::shared_ptr< Operation > >() ), m_queue( new Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >() ),
m_asyncThreads( 0 ), m_asyncThreads( 0 ),
m_synchThreads( 0 ) m_synchThreads( 0 )
{ {

View file

@ -83,7 +83,7 @@ namespace Sapphire::Db
const std::string& getDatabaseName() const; const std::string& getDatabaseName() const;
std::unique_ptr< Sapphire::LockedWaitQueue< std::shared_ptr< Operation > > > m_queue; std::unique_ptr< Common::Util::LockedWaitQueue< std::shared_ptr< Operation > > > m_queue;
std::array< std::vector< std::shared_ptr< T > >, IDX_SIZE > m_connections; std::array< std::vector< std::shared_ptr< T > >, IDX_SIZE > m_connections;
ConnectionInfo m_connectionInfo; ConnectionInfo m_connectionInfo;
uint8_t m_asyncThreads; uint8_t m_asyncThreads;

View file

@ -6,7 +6,7 @@ Sapphire::Db::ZoneDbConnection::ZoneDbConnection( ConnectionInfo& connInfo ) :
{ {
} }
Sapphire::Db::ZoneDbConnection::ZoneDbConnection( Sapphire::LockedWaitQueue< std::shared_ptr< Operation > >* q, Sapphire::Db::ZoneDbConnection::ZoneDbConnection( Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* q,
ConnectionInfo& connInfo ) : ConnectionInfo& connInfo ) :
DbConnection( q, connInfo ) DbConnection( q, connInfo )
{ {
@ -22,7 +22,8 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
m_stmts.resize( MAX_STATEMENTS ); m_stmts.resize( MAX_STATEMENTS );
/// CHARA /// CHARA
prepareStatement( CHARA_SEL, "SELECT ContentId, Name, Hp, Mp, Tp, Gp, Mode, Mount, InvincibleGM, Voice, " prepareStatement( CHARA_SEL,
"SELECT ContentId, Name, Hp, Mp, Tp, Gp, Mode, Mount, InvincibleGM, Voice, "
"Customize, ModelMainWeapon, ModelSubWeapon, ModelSystemWeapon, " "Customize, ModelMainWeapon, ModelSubWeapon, ModelSystemWeapon, "
"ModelEquip, EmoteModeType, FirstLoginTime, Language, IsNewGame, " "ModelEquip, EmoteModeType, FirstLoginTime, Language, IsNewGame, "
"IsNewAdventurer, TerritoryType, TerritoryId, PosX, PosY, PosZ, PosR, " "IsNewAdventurer, TerritoryType, TerritoryId, PosX, PosY, PosZ, PosR, "
@ -33,7 +34,8 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
"QuestCompleteFlags, OpeningSequence, QuestTracking, GrandCompany, " "QuestCompleteFlags, OpeningSequence, QuestTracking, GrandCompany, "
"GrandCompanyRank, Discovery, GMRank, EquipDisplayFlags, Unlocks, CFPenaltyUntil, " "GrandCompanyRank, Discovery, GMRank, EquipDisplayFlags, Unlocks, CFPenaltyUntil, "
"Pose " "Pose "
"FROM charainfo WHERE CharacterId = ?;", CONNECTION_SYNC ); "FROM charainfo WHERE CharacterId = ?;",
CONNECTION_SYNC );
prepareStatement( CHARA_UP, prepareStatement( CHARA_UP,
@ -47,14 +49,18 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
"ActiveTitle = ?, TitleList = ?, Achievement = ?, Aetheryte = ?, HowTo = ?, Minions = ?, Mounts = ?, Orchestrion = ?, " "ActiveTitle = ?, TitleList = ?, Achievement = ?, Aetheryte = ?, HowTo = ?, Minions = ?, Mounts = ?, Orchestrion = ?, "
"EquippedMannequin = ?, ConfigFlags = ?, QuestCompleteFlags = ?, OpeningSequence = ?, " "EquippedMannequin = ?, ConfigFlags = ?, QuestCompleteFlags = ?, OpeningSequence = ?, "
"QuestTracking = ?, GrandCompany = ?, GrandCompanyRank = ?, Discovery = ?, GMRank = ?, EquipDisplayFlags = ?, Unlocks = ?, " "QuestTracking = ?, GrandCompany = ?, GrandCompanyRank = ?, Discovery = ?, GMRank = ?, EquipDisplayFlags = ?, Unlocks = ?, "
"CFPenaltyUntil = ?, Pose = ? WHERE CharacterId = ?;", CONNECTION_ASYNC ); "CFPenaltyUntil = ?, Pose = ? WHERE CharacterId = ?;",
CONNECTION_ASYNC );
prepareStatement( CHARA_SEL_MINIMAL, "SELECT Name, Customize, ModelMainWeapon, ModelSubWeapon, ModelEquip, TerritoryType, GuardianDeity, " prepareStatement( CHARA_SEL_MINIMAL,
"SELECT Name, Customize, ModelMainWeapon, ModelSubWeapon, ModelEquip, TerritoryType, GuardianDeity, "
"Class, ContentId, BirthDay, BirthMonth, EquipDisplayFlags " "Class, ContentId, BirthDay, BirthMonth, EquipDisplayFlags "
"FROM charainfo WHERE CharacterId = ?;", CONNECTION_SYNC ); "FROM charainfo WHERE CharacterId = ?;",
CONNECTION_SYNC );
prepareStatement( CHARA_INS, "INSERT INTO charainfo (AccountId, CharacterId, ContentId, Name, Hp, Mp, " prepareStatement( CHARA_INS,
"INSERT INTO charainfo (AccountId, CharacterId, ContentId, Name, Hp, Mp, "
"Customize, Voice, IsNewGame, TerritoryType, PosX, PosY, PosZ, PosR, ModelEquip, " "Customize, Voice, IsNewGame, TerritoryType, PosX, PosY, PosZ, PosR, ModelEquip, "
"IsNewAdventurer, GuardianDeity, Birthday, BirthMonth, Class, Status, FirstClass, " "IsNewAdventurer, GuardianDeity, Birthday, BirthMonth, Class, Status, FirstClass, "
"HomePoint, StartTown, Discovery, HowTo, QuestCompleteFlags, Unlocks, QuestTracking, " "HomePoint, StartTown, Discovery, HowTo, QuestCompleteFlags, Unlocks, QuestTracking, "

View file

@ -112,7 +112,7 @@ namespace Sapphire::Db
ZoneDbConnection( ConnectionInfo& connInfo ); ZoneDbConnection( ConnectionInfo& connInfo );
ZoneDbConnection( Sapphire::LockedWaitQueue< std::shared_ptr< Operation > >* q, ConnectionInfo& connInfo ); ZoneDbConnection( Common::Util::LockedWaitQueue< std::shared_ptr< Operation > >* q, ConnectionInfo& connInfo );
~ZoneDbConnection(); ~ZoneDbConnection();

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,12 +5,16 @@
namespace Sapphire namespace Sapphire
{ {
class ConfigMgr;
class Framework; class Framework;
using ConfigMgrPtr = std::shared_ptr< ConfigMgr >;
using FrameworkPtr = std::shared_ptr< Framework >; using FrameworkPtr = std::shared_ptr< Framework >;
} }
namespace Sapphire::Common
{
class ConfigMgr;
using ConfigMgrPtr = std::shared_ptr< ConfigMgr >;
}
namespace Sapphire::Network namespace Sapphire::Network
{ {
class Hive; class Hive;

View file

@ -1,2 +0,0 @@
#include "Framework.h"
#include "Logging/Logger.h"

View file

@ -1,37 +0,0 @@
#ifndef _CORE_FRAMEWORK_H
#define _CORE_FRAMEWORK_H
#include <map>
#include <typeindex>
#include <typeinfo>
#include <memory>
#include <cassert>
namespace Sapphire
{
class Framework
{
using TypenameToObject = std::map< std::type_index, std::shared_ptr< void > >;
TypenameToObject ObjectMap;
public:
template< typename T >
std::shared_ptr< T > get()
{
auto iType = ObjectMap.find( typeid( T ) );
assert( !( iType == ObjectMap.end() ) );
return std::static_pointer_cast< T >( iType->second );
}
template< typename T >
void set( std::shared_ptr< T > value )
{
assert( value ); // why would anyone store nullptrs....
ObjectMap[ typeid( T ) ] = value;
}
};
}
#endif // _CORE_FRAMEWORK_H

View file

@ -1,6 +1,6 @@
#include "Logger.h" #include "Logger.h"
#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "fatal", "off" } #define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warn", "error", "fatal", "off" }
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <spdlog/async.h> #include <spdlog/async.h>
@ -8,9 +8,9 @@
#include <spdlog/sinks/daily_file_sink.h> #include <spdlog/sinks/daily_file_sink.h>
// #include <iostream> // #include <iostream>
#include <experimental/filesystem> // or #include <filesystem> #include <filesystem> // or #include <filesystem>
namespace fs = std::experimental::filesystem; namespace fs = std::filesystem;
void Sapphire::Logger::init( const std::string& logPath ) void Sapphire::Logger::init( const std::string& logPath )
{ {

View file

@ -2,7 +2,10 @@
#include "Acceptor.h" #include "Acceptor.h"
#include "Connection.h" #include "Connection.h"
Sapphire::Network::Acceptor::Acceptor( HivePtr hive ) :
using namespace Sapphire;
Network::Acceptor::Acceptor( HivePtr hive ) :
m_hive( hive ), m_hive( hive ),
m_acceptor( hive->getService() ), m_acceptor( hive->getService() ),
m_io_strand( hive->getService() ), m_io_strand( hive->getService() ),
@ -10,21 +13,21 @@ Sapphire::Network::Acceptor::Acceptor( HivePtr hive ) :
{ {
} }
Sapphire::Network::Acceptor::~Acceptor() Network::Acceptor::~Acceptor()
{ {
} }
bool Sapphire::Network::Acceptor::onAccept( ConnectionPtr connection, const std::string& host, uint16_t port ) bool Network::Acceptor::onAccept( ConnectionPtr connection, const std::string& host, uint16_t port )
{ {
return true; return true;
} }
void Sapphire::Network::Acceptor::onError( const asio::error_code& error ) void Network::Acceptor::onError( const asio::error_code& error )
{ {
} }
void Sapphire::Network::Acceptor::startError( const asio::error_code& error ) void Network::Acceptor::startError( const asio::error_code& error )
{ {
uint32_t v1 = 1; uint32_t v1 = 1;
uint32_t v2 = 0; uint32_t v2 = 0;
@ -37,7 +40,7 @@ void Sapphire::Network::Acceptor::startError( const asio::error_code& error )
} }
} }
void Sapphire::Network::Acceptor::dispatchAccept( ConnectionPtr connection ) void Network::Acceptor::dispatchAccept( ConnectionPtr connection )
{ {
m_acceptor.async_accept( connection->getSocket(), m_acceptor.async_accept( connection->getSocket(),
connection->getStrand().wrap( std::bind( &Acceptor::handleAccept, connection->getStrand().wrap( std::bind( &Acceptor::handleAccept,
@ -46,7 +49,7 @@ void Sapphire::Network::Acceptor::dispatchAccept( ConnectionPtr connection )
connection ) ) ); connection ) ) );
} }
void Sapphire::Network::Acceptor::handleAccept( const asio::error_code& error, ConnectionPtr connection ) void Network::Acceptor::handleAccept( const asio::error_code& error, ConnectionPtr connection )
{ {
if( error || hasError() || m_hive->hasStopped() ) if( error || hasError() || m_hive->hasStopped() )
{ {
@ -72,17 +75,17 @@ void Sapphire::Network::Acceptor::handleAccept( const asio::error_code& error, C
} }
} }
void Sapphire::Network::Acceptor::stop() void Network::Acceptor::stop()
{ {
} }
void Sapphire::Network::Acceptor::accept( ConnectionPtr connection ) void Network::Acceptor::accept( ConnectionPtr connection )
{ {
m_io_strand.post( std::bind( &Acceptor::dispatchAccept, shared_from_this(), connection ) ); m_io_strand.post( std::bind( &Acceptor::dispatchAccept, shared_from_this(), connection ) );
} }
void Sapphire::Network::Acceptor::listen( const std::string& host, const uint16_t& port ) void Network::Acceptor::listen( const std::string& host, const uint16_t& port )
{ {
try try
{ {
@ -103,17 +106,17 @@ void Sapphire::Network::Acceptor::listen( const std::string& host, const uint16_
} }
Sapphire::Network::HivePtr Sapphire::Network::Acceptor::getHive() Network::HivePtr Network::Acceptor::getHive()
{ {
return m_hive; return m_hive;
} }
asio::ip::tcp::acceptor& Sapphire::Network::Acceptor::getAcceptor() asio::ip::tcp::acceptor& Network::Acceptor::getAcceptor()
{ {
return m_acceptor; return m_acceptor;
} }
bool Sapphire::Network::Acceptor::hasError() bool Network::Acceptor::hasError()
{ {
uint32_t v1 = 1; uint32_t v1 = 1;
uint32_t v2 = 1; uint32_t v2 = 1;

View file

@ -24,6 +24,9 @@ enum ActorControlType : uint16_t
SetStatus = 0x02, SetStatus = 0x02,
CastStart = 0x03, CastStart = 0x03,
ToggleAggro = 0x04, ToggleAggro = 0x04,
/*!
* param1 = ClassJob ID
*/
ClassJobChange = 0x05, ClassJobChange = 0x05,
DefeatMsg = 0x06, DefeatMsg = 0x06,
GainExpMsg = 0x07, GainExpMsg = 0x07,
@ -98,6 +101,8 @@ enum ActorControlType : uint16_t
FreeEventPos = 0x8A, FreeEventPos = 0x8A,
DailyQuestSeed = 0x90, // param1 = the daily quest seed
SetBGM = 0xA1, SetBGM = 0xA1,
UnlockAetherCurrentMsg = 0xA4, UnlockAetherCurrentMsg = 0xA4,
@ -140,6 +145,15 @@ enum ActorControlType : uint16_t
SetPose = 0x127, SetPose = 0x127,
/*!
* This is used for general crafting events, I found some of them but some are missing:
*
* param1 = event type, the rest of the struct depends on this param.
* - 18 & 19: Quicksynth result, 19 means HQ result item, item ID is param2 and is + 1 000 000 when HQ.
* Quantity is param3 (possible quicksynth that gives more than one item in the future?)
*
* All the other values have unkown behavior for now.
*/
CraftingUnk = 0x12C, CraftingUnk = 0x12C,
GatheringSenseMsg = 0x130, GatheringSenseMsg = 0x130,
@ -173,6 +187,14 @@ enum ActorControlType : uint16_t
RelicInfuseMsg = 0x179, RelicInfuseMsg = 0x179,
/*!
* Sent as result of an aetherial reduction.
* param1 = Reduced item ID + 500 000 (idk what this 500 000 is but it's always here no matter what)
* param2 = First result item id (+ 1 000 000 if HQ)
* param3 = First result item quantity
* param4 = (Optional) Second result item id (+ 1 000 000 if HQ)
* param5 = (Optional) Second result item quantity
*/
AetherReductionDlg = 0x17D, AetherReductionDlg = 0x17D,
/*! /*!
@ -204,6 +226,22 @@ enum ActorControlType : uint16_t
ChallengeEntryCompleteMsg = 0x20B, ChallengeEntryCompleteMsg = 0x20B,
ChallengeEntryUnlockMsg = 0x20C, ChallengeEntryUnlockMsg = 0x20C,
/*!
* Sent when a player desynths an item, one packet per result type (one for consumed item, one for each obtained items, and one for exp if the player received exp)
* param1 = result type
* 4921 => Desynth item consumed
* 4922 => Desynth item obtained
* 4925 => Desynth exp obtained)
* 3553 => Reduction item used
* 3555 => Reduction item obtained
* param3 = u32 item id (+100 000 if item is HQ)
* param4 = item amount (used only for reduction it seems)
* param5 = exp amount (x 100)
*
* Idk exactly how reduce's param3 is formatted, it seems like it's item id + 500 000 but it seems too... shady.
*/
DesynthOrReductionResult = 0x20F,
GilTrailMsg = 0x211, GilTrailMsg = 0x211,
HuntingLogRankUnlock = 0x21D, HuntingLogRankUnlock = 0x21D,
@ -220,10 +258,22 @@ enum ActorControlType : uint16_t
GearSetEquipMsg = 0x321, GearSetEquipMsg = 0x321,
SetBait = 0x325, // param1: bait ID
SetFestival = 0x386, // param1: festival.exd index SetFestival = 0x386, // param1: festival.exd index
ToggleOrchestrionUnlock = 0x396, ToggleOrchestrionUnlock = 0x396,
Dismount = 0x3A1, // updated 4.5
EventBattleDialog = 0x39D,
/*!
* param1 = mountSpeed
* Retail sends 12 for mount speed star 1 unlocked and 15 for mount speed star 2 unlocked
* This also has to be sent before mounting finishes for it to take effect
*/
SetMountSpeed = 0x3A0, // updated 5.35 hotfix
Dismount = 0x3A2, // updated 5.35 hotfix
// Duty Recorder // Duty Recorder
BeginReplayAck = 0x3A2, BeginReplayAck = 0x3A2,
@ -300,6 +350,7 @@ enum ActorControlType : uint16_t
DismountReq = 0x65, DismountReq = 0x65,
SpawnCompanionReq = 0x66, SpawnCompanionReq = 0x66,
DespawnCompanionReq = 0x67,
RemoveStatusEffect = 0x68, RemoveStatusEffect = 0x68,
CastCancel = 0x69, CastCancel = 0x69,
@ -315,20 +366,26 @@ enum ActorControlType : uint16_t
UpdatedSeenHowTos = 0x133, UpdatedSeenHowTos = 0x133,
AllotAttribute = 0x135, AllotAttribute = 0x135,
ClearWaymarks = 0x13A, ClearFieldMarkers = 0x13A,
CameraMode = 0x13B, // param12, 1 = camera mode enable, 0 = disable CameraMode = 0x13B, // param12, 1 = camera mode enable, 0 = disable
CharaNameReq = 0x13D, // requests character name by content id CharaNameReq = 0x13D, // requests character name by content id
HuntingLogDetails = 0x194, HuntingLogDetails = 0x194,
Timers = 0x1AB, Timers = 0x1AB,
DyeItem = 0x1B5, DyeItem = 0x1B0, // updated 5.21
RequestChocoboInventory = 0x1C4, RequestChocoboInventory = 0x1C4,
EmoteReq = 0x1F4, EmoteReq = 0x1F4,
EmoteCancel = 0x1F6, EmoteCancel = 0x1F6,
PersistentEmoteCancel = 0x1F7, PersistentEmoteCancel = 0x1F7,
/*!
* param2 = pose ID
* 0 = idle pose 0 (just standing)
* 1 = idle pose 1
* 2-4 = idle poses 2-4
*/
PoseChange = 0x1F9, PoseChange = 0x1F9,
PoseReapply = 0x1FA, PoseReapply = 0x1FA,
PoseCancel = 0x1FB, PoseCancel = 0x1FB,
@ -337,6 +394,8 @@ enum ActorControlType : uint16_t
AchievementComp = 0x203, AchievementComp = 0x203,
AchievementCatChat = 0x206, AchievementCatChat = 0x206,
RequestEventBattle = 0x232C,
QuestJournalUpdateQuestVisibility = 0x2BE, QuestJournalUpdateQuestVisibility = 0x2BE,
QuestJournalClosed = 0x2BF, QuestJournalClosed = 0x2BF,

View file

@ -1,23 +1,21 @@
#include "Connection.h" #include "Connection.h"
#include "Hive.h" #include "Hive.h"
#include <functional> #include <functional>
#include "Framework.h"
Sapphire::Network::Connection::Connection( HivePtr hive, FrameworkPtr pFw ) : using namespace Sapphire;
Network::Connection::Connection( HivePtr hive ) :
m_hive( hive ), m_hive( hive ),
m_socket( hive->getService() ), m_socket( hive->getService() ),
m_io_strand( hive->getService() ), m_io_strand( hive->getService() ),
m_receive_buffer_size( 32000 ), m_receive_buffer_size( 32000 ),
m_error_state( 0 ), m_error_state( 0 )
m_pFw( pFw )
{ {
} }
Sapphire::Network::Connection::~Connection() Network::Connection::~Connection() = default;
{
}
void Sapphire::Network::Connection::bind( const std::string& ip, uint16_t port ) void Network::Connection::bind( const std::string& ip, uint16_t port )
{ {
asio::ip::tcp::endpoint endpoint( asio::ip::address::from_string( ip ), port ); asio::ip::tcp::endpoint endpoint( asio::ip::address::from_string( ip ), port );
m_socket.open( endpoint.protocol() ); m_socket.open( endpoint.protocol() );
@ -25,7 +23,7 @@ void Sapphire::Network::Connection::bind( const std::string& ip, uint16_t port )
m_socket.bind( endpoint ); m_socket.bind( endpoint );
} }
void Sapphire::Network::Connection::startSend() void Network::Connection::startSend()
{ {
if( !m_pending_sends.empty() ) if( !m_pending_sends.empty() )
{ {
@ -38,7 +36,7 @@ void Sapphire::Network::Connection::startSend()
} }
} }
void Sapphire::Network::Connection::startRecv( int32_t total_bytes ) void Network::Connection::startRecv( int32_t total_bytes )
{ {
if( total_bytes > 0 ) if( total_bytes > 0 )
{ {
@ -61,7 +59,7 @@ void Sapphire::Network::Connection::startRecv( int32_t total_bytes )
} }
} }
void Sapphire::Network::Connection::startError( const asio::error_code& error ) void Network::Connection::startError( const asio::error_code& error )
{ {
uint32_t v1 = 1; uint32_t v1 = 1;
uint32_t v2 = 0; uint32_t v2 = 0;
@ -74,7 +72,7 @@ void Sapphire::Network::Connection::startError( const asio::error_code& error )
} }
} }
void Sapphire::Network::Connection::handleConnect( const asio::error_code& error ) void Network::Connection::handleConnect( const asio::error_code& error )
{ {
if( error || hasError() || m_hive->hasStopped() ) if( error || hasError() || m_hive->hasStopped() )
{ {
@ -94,7 +92,7 @@ void Sapphire::Network::Connection::handleConnect( const asio::error_code& error
} }
} }
void Sapphire::Network::Connection::handleSend( const asio::error_code& error, void Network::Connection::handleSend( const asio::error_code& error,
std::list< std::vector< uint8_t > >::iterator itr ) std::list< std::vector< uint8_t > >::iterator itr )
{ {
if( error || hasError() || m_hive->hasStopped() ) if( error || hasError() || m_hive->hasStopped() )
@ -109,7 +107,7 @@ void Sapphire::Network::Connection::handleSend( const asio::error_code& error,
} }
} }
void Sapphire::Network::Connection::handleRecv( const asio::error_code& error, int32_t actual_bytes ) void Network::Connection::handleRecv( const asio::error_code& error, int32_t actual_bytes )
{ {
if( error || hasError() || m_hive->hasStopped() ) if( error || hasError() || m_hive->hasStopped() )
{ {
@ -128,7 +126,7 @@ void Sapphire::Network::Connection::handleRecv( const asio::error_code& error, i
} }
} }
void Sapphire::Network::Connection::dispatchSend( std::vector< uint8_t > buffer ) void Network::Connection::dispatchSend( std::vector< uint8_t > buffer )
{ {
bool should_start_send = m_pending_sends.empty(); bool should_start_send = m_pending_sends.empty();
m_pending_sends.push_back( buffer ); m_pending_sends.push_back( buffer );
@ -138,7 +136,7 @@ void Sapphire::Network::Connection::dispatchSend( std::vector< uint8_t > buffer
} }
} }
void Sapphire::Network::Connection::dispatchRecv( int32_t total_bytes ) void Network::Connection::dispatchRecv( int32_t total_bytes )
{ {
bool should_start_receive = m_pending_recvs.empty(); bool should_start_receive = m_pending_recvs.empty();
m_pending_recvs.push_back( total_bytes ); m_pending_recvs.push_back( total_bytes );
@ -149,7 +147,7 @@ void Sapphire::Network::Connection::dispatchRecv( int32_t total_bytes )
} }
void Sapphire::Network::Connection::connect( const std::string& host, uint16_t port ) void Network::Connection::connect( const std::string& host, uint16_t port )
{ {
asio::ip::tcp::resolver resolver( m_hive->getService() ); asio::ip::tcp::resolver resolver( m_hive->getService() );
asio::ip::tcp::resolver::query query( host, std::to_string( port ) ); asio::ip::tcp::resolver::query query( host, std::to_string( port ) );
@ -160,48 +158,48 @@ void Sapphire::Network::Connection::connect( const std::string& host, uint16_t p
} }
void Sapphire::Network::Connection::disconnect() void Network::Connection::disconnect()
{ {
onDisconnect(); onDisconnect();
m_socket.close(); m_socket.close();
} }
void Sapphire::Network::Connection::recv( int32_t total_bytes ) void Network::Connection::recv( int32_t total_bytes )
{ {
m_io_strand.post( std::bind( &Connection::dispatchRecv, shared_from_this(), total_bytes ) ); m_io_strand.post( std::bind( &Connection::dispatchRecv, shared_from_this(), total_bytes ) );
} }
void Sapphire::Network::Connection::send( const std::vector< uint8_t >& buffer ) void Network::Connection::send( const std::vector< uint8_t >& buffer )
{ {
m_io_strand.post( std::bind( &Connection::dispatchSend, shared_from_this(), buffer ) ); m_io_strand.post( std::bind( &Connection::dispatchSend, shared_from_this(), buffer ) );
} }
asio::ip::tcp::socket& Sapphire::Network::Connection::getSocket() asio::ip::tcp::socket& Network::Connection::getSocket()
{ {
return m_socket; return m_socket;
} }
asio::strand& Sapphire::Network::Connection::getStrand() asio::strand& Network::Connection::getStrand()
{ {
return m_io_strand; return m_io_strand;
} }
Sapphire::Network::HivePtr Sapphire::Network::Connection::getHive() Network::HivePtr Network::Connection::getHive()
{ {
return m_hive; return m_hive;
} }
void Sapphire::Network::Connection::setReceiveBufferSize( int32_t size ) void Network::Connection::setReceiveBufferSize( int32_t size )
{ {
m_receive_buffer_size = size; m_receive_buffer_size = size;
} }
int32_t Sapphire::Network::Connection::getReceiveBufferSize() const int32_t Network::Connection::getReceiveBufferSize() const
{ {
return m_receive_buffer_size; return m_receive_buffer_size;
} }
bool Sapphire::Network::Connection::hasError() bool Network::Connection::hasError()
{ {
uint32_t v1 = 1; uint32_t v1 = 1;
uint32_t v2 = 1; uint32_t v2 = 1;

View file

@ -12,12 +12,6 @@
#include "Acceptor.h" #include "Acceptor.h"
#include <memory> #include <memory>
namespace Sapphire
{
class Framework;
using FrameworkPtr = std::shared_ptr< Framework >;
}
namespace Sapphire::Network namespace Sapphire::Network
{ {
@ -41,9 +35,8 @@ namespace Sapphire::Network
std::list< std::vector< uint8_t > > m_pending_sends; std::list< std::vector< uint8_t > > m_pending_sends;
int32_t m_receive_buffer_size; int32_t m_receive_buffer_size;
std::atomic< uint32_t > m_error_state; std::atomic< uint32_t > m_error_state;
Sapphire::FrameworkPtr m_pFw;
Connection( HivePtr hive, FrameworkPtr pFw ); Connection( HivePtr hive );
virtual ~Connection(); virtual ~Connection();
@ -147,13 +140,13 @@ namespace Sapphire::Network
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template< class T > template< class T >
std::shared_ptr< T > addServerToHive( const std::string& listenIp, uint32_t port, HivePtr pHive, FrameworkPtr pFw ) std::shared_ptr< T > addServerToHive( const std::string& listenIp, uint32_t port, HivePtr pHive )
{ {
try try
{ {
AcceptorPtr acceptor( new Acceptor( pHive ) ); AcceptorPtr acceptor( new Acceptor( pHive ) );
acceptor->listen( listenIp, port ); acceptor->listen( listenIp, port );
std::shared_ptr< T > connection( new T( pHive, acceptor, pFw ) ); std::shared_ptr< T > connection( new T( pHive, acceptor ) );
acceptor->accept( connection ); acceptor->accept( connection );
return connection; return connection;
} }

View file

@ -257,7 +257,7 @@ namespace Sapphire::Network::Packets
// The IPC type itself. // The IPC type itself.
m_ipcHdr.type = static_cast< ServerZoneIpcType >( m_data._ServerIpcType ); m_ipcHdr.type = static_cast< ServerZoneIpcType >( m_data._ServerIpcType );
m_ipcHdr.timestamp = Util::getTimeSeconds(); m_ipcHdr.timestamp = Common::Util::getTimeSeconds();
m_segHdr.size = sizeof( T ) + sizeof( FFXIVARR_IPC_HEADER ) + sizeof( FFXIVARR_PACKET_SEGMENT_HEADER ); m_segHdr.size = sizeof( T ) + sizeof( FFXIVARR_IPC_HEADER ) + sizeof( FFXIVARR_PACKET_SEGMENT_HEADER );
}; };

View file

@ -3,9 +3,10 @@
#include <string.h> // memcpy #include <string.h> // memcpy
using namespace Sapphire;
using namespace Sapphire::Network::Packets; using namespace Sapphire::Network::Packets;
PacketParseResult Sapphire::Network::Packets::getHeader( const std::vector< uint8_t >& buffer, PacketParseResult Network::Packets::getHeader( const std::vector< uint8_t >& buffer,
const uint32_t offset, const uint32_t offset,
FFXIVARR_PACKET_HEADER& header ) FFXIVARR_PACKET_HEADER& header )
{ {
@ -25,7 +26,7 @@ PacketParseResult Sapphire::Network::Packets::getHeader( const std::vector< uint
return Success; return Success;
} }
PacketParseResult Sapphire::Network::Packets::getSegmentHeader( const std::vector< uint8_t >& buffer, PacketParseResult Network::Packets::getSegmentHeader( const std::vector< uint8_t >& buffer,
const uint32_t offset, const uint32_t offset,
FFXIVARR_PACKET_SEGMENT_HEADER& header ) FFXIVARR_PACKET_SEGMENT_HEADER& header )
{ {
@ -42,7 +43,7 @@ PacketParseResult Sapphire::Network::Packets::getSegmentHeader( const std::vecto
return Success; return Success;
} }
PacketParseResult Sapphire::Network::Packets::getPackets( const std::vector< uint8_t >& buffer, PacketParseResult Network::Packets::getPackets( const std::vector< uint8_t >& buffer,
const uint32_t offset, const uint32_t offset,
const FFXIVARR_PACKET_HEADER& packetHeader, const FFXIVARR_PACKET_HEADER& packetHeader,
std::vector< FFXIVARR_PACKET_RAW >& packets ) std::vector< FFXIVARR_PACKET_RAW >& packets )
@ -81,7 +82,7 @@ PacketParseResult Sapphire::Network::Packets::getPackets( const std::vector< uin
return Success; return Success;
} }
PacketParseResult Sapphire::Network::Packets::getPacket( const std::vector< uint8_t >& buffer, const uint32_t offset, PacketParseResult Network::Packets::getPacket( const std::vector< uint8_t >& buffer, const uint32_t offset,
FFXIVARR_PACKET_RAW& packet ) FFXIVARR_PACKET_RAW& packet )
{ {
// Copy segment header // Copy segment header
@ -103,7 +104,7 @@ PacketParseResult Sapphire::Network::Packets::getPacket( const std::vector< uint
return Success; return Success;
} }
bool Sapphire::Network::Packets::checkHeader( const FFXIVARR_PACKET_HEADER& header ) bool Network::Packets::checkHeader( const FFXIVARR_PACKET_HEADER& header )
{ {
// Max size of the packet is capped at 1MB for now. // Max size of the packet is capped at 1MB for now.
if( header.size > 1 * 1024 * 1024 ) if( header.size > 1 * 1024 * 1024 )
@ -116,7 +117,7 @@ bool Sapphire::Network::Packets::checkHeader( const FFXIVARR_PACKET_HEADER& head
return true; return true;
} }
bool Sapphire::Network::Packets::checkSegmentHeader( const FFXIVARR_PACKET_SEGMENT_HEADER& header ) bool Network::Packets::checkSegmentHeader( const FFXIVARR_PACKET_SEGMENT_HEADER& header )
{ {
// Max size of individual message is capped at 256KB for now. // Max size of individual message is capped at 256KB for now.
if( header.size > 256 * 1024 ) if( header.size > 256 * 1024 )

View file

@ -2,41 +2,43 @@
#include <functional> #include <functional>
#include "Hive.h" #include "Hive.h"
using namespace Sapphire;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
Sapphire::Network::Hive::Hive() : Network::Hive::Hive() :
m_work_ptr( new asio::io_service::work( m_io_service ) ), m_work_ptr( new asio::io_service::work( m_io_service ) ),
m_shutdown( 0 ) m_shutdown( 0 )
{ {
} }
Sapphire::Network::Hive::~Hive() Network::Hive::~Hive()
{ {
} }
asio::io_service& Sapphire::Network::Hive::getService() asio::io_service& Network::Hive::getService()
{ {
return m_io_service; return m_io_service;
} }
bool Sapphire::Network::Hive::hasStopped() bool Network::Hive::hasStopped()
{ {
uint32_t v1 = 1; uint32_t v1 = 1;
uint32_t v2 = 1; uint32_t v2 = 1;
return m_shutdown.compare_exchange_strong( v1, v2 ); return m_shutdown.compare_exchange_strong( v1, v2 );
} }
void Sapphire::Network::Hive::poll() void Network::Hive::poll()
{ {
m_io_service.poll(); m_io_service.poll();
} }
void Sapphire::Network::Hive::run() void Network::Hive::run()
{ {
m_io_service.run(); m_io_service.run();
} }
void Sapphire::Network::Hive::stop() void Network::Hive::stop()
{ {
uint32_t v1 = 1; uint32_t v1 = 1;
uint32_t v2 = 0; uint32_t v2 = 0;
@ -48,7 +50,7 @@ void Sapphire::Network::Hive::stop()
} }
} }
void Sapphire::Network::Hive::reset() void Network::Hive::reset()
{ {
uint32_t v1 = 0; uint32_t v1 = 0;
uint32_t v2 = 1; uint32_t v2 = 1;

View file

@ -7,7 +7,9 @@
#include <string.h> #include <string.h>
#include <memory> #include <memory>
Sapphire::Network::Packets::PacketContainer::PacketContainer( uint32_t segmentTargetOverride ) : using namespace Sapphire;
Network::Packets::PacketContainer::PacketContainer( uint32_t segmentTargetOverride ) :
m_segmentTargetOverride( segmentTargetOverride ) m_segmentTargetOverride( segmentTargetOverride )
{ {
memset( &m_ipcHdr, 0, sizeof( FFXIVARR_PACKET_HEADER ) ); memset( &m_ipcHdr, 0, sizeof( FFXIVARR_PACKET_HEADER ) );
@ -15,12 +17,12 @@ Sapphire::Network::Packets::PacketContainer::PacketContainer( uint32_t segmentTa
m_ipcHdr.count = 0; m_ipcHdr.count = 0;
} }
Sapphire::Network::Packets::PacketContainer::~PacketContainer() Network::Packets::PacketContainer::~PacketContainer()
{ {
m_entryList.clear(); m_entryList.clear();
} }
void Sapphire::Network::Packets::PacketContainer::addPacket( Sapphire::Network::Packets::FFXIVPacketBasePtr entry ) void Network::Packets::PacketContainer::addPacket( Network::Packets::FFXIVPacketBasePtr entry )
{ {
m_entryList.push_back( entry ); m_entryList.push_back( entry );
@ -28,7 +30,7 @@ void Sapphire::Network::Packets::PacketContainer::addPacket( Sapphire::Network::
m_ipcHdr.count++; m_ipcHdr.count++;
} }
void Sapphire::Network::Packets::PacketContainer::fillSendBuffer( std::vector< uint8_t >& sendBuffer ) void Network::Packets::PacketContainer::fillSendBuffer( std::vector< uint8_t >& sendBuffer )
{ {
std::vector< uint8_t > tempBuffer( m_ipcHdr.size ); std::vector< uint8_t > tempBuffer( m_ipcHdr.size );
memset( &tempBuffer[ 0 ], 0, m_ipcHdr.size ); memset( &tempBuffer[ 0 ], 0, m_ipcHdr.size );
@ -67,7 +69,7 @@ void Sapphire::Network::Packets::PacketContainer::fillSendBuffer( std::vector< u
} }
std::string Sapphire::Network::Packets::PacketContainer::toString() std::string Network::Packets::PacketContainer::toString()
{ {
std::vector< uint8_t > tmpBuffer; std::vector< uint8_t > tmpBuffer;
@ -76,7 +78,7 @@ std::string Sapphire::Network::Packets::PacketContainer::toString()
std::string str = "\n"; std::string str = "\n";
for( uint32_t i = 0; i < m_ipcHdr.size; i++ ) for( uint32_t i = 0; i < m_ipcHdr.size; i++ )
{ {
str += Util::intToHexString( static_cast< int32_t >( tmpBuffer[ i ] & 0xFF ) ) + " "; str += Common::Util::intToHexString( static_cast< int32_t >( tmpBuffer[ i ] & 0xFF ) ) + " ";
if( ( i + 1 ) % 16 == 0 ) if( ( i + 1 ) % 16 == 0 )
str += "\n"; str += "\n";

View file

@ -4,10 +4,8 @@
#include <Common.h> #include <Common.h>
#include <Network/CommonNetwork.h> #include <Network/CommonNetwork.h>
namespace Sapphire { namespace Sapphire::Network::Packets::Server
namespace Network { {
namespace Packets {
namespace Server {
/** /**
* Structural representation of the packet sent by the server as response * Structural representation of the packet sent by the server as response
@ -31,10 +29,37 @@ struct FFXIVIpcTellErrNotFound : FFXIVIpcBasePacket< TellErrNotFound >
char receipientName[32]; char receipientName[32];
}; };
} /* Server */ struct FFXIVIpcFreeCompanyEvent : FFXIVIpcBasePacket< FreeCompanyEvent >
} /* Packets */ {
} /* Network */ uint16_t unknown;
} /* Sapphire */ uint16_t unknown1;
uint16_t unknown2;
uint16_t unknown3;
uint16_t unknown4;
char padding[6];
uint8_t eventID;
/*
* 0x0F Login
* 0x10 Logout
*/
uint8_t padding1;
char padding2[6];
uint16_t unknown5;
char parameter[46];
/**
* eventID | parameter usage
* 0x0F FC name
* 0x10 FC name
*/
char parameter1[32];
/**
* eventID | parameter1 usage
* 0x0F Character name
* 0x10 Character name
*/
};
} /* Sapphire::Common::Network::Packets::Server */

View file

@ -43,176 +43,219 @@ namespace Sapphire::Network::Packets
*/ */
enum ServerZoneIpcType : uint16_t enum ServerZoneIpcType : uint16_t
{ {
Ping = 0x0219, // updated 5.35 hotfix
Init = 0x0185, // updated 5.35 hotfix
// static opcode ( the ones that rarely, if ever, change ) ActorFreeSpawn = 0x0239, // updated 5.35 hotfix
Ping = 0x0065, InitZone = 0x03CD, // updated 5.35 hotfix
Init = 0x0066,
ActorFreeSpawn = 0x0191, EffectResult = 0x01C2, // updated 5.35 hotfix
InitZone = 0x019A, ActorControl = 0x02A4, // updated 5.35 hotfix
ActorControlSelf = 0x02C8, // updated 5.35 hotfix
ActorControlTarget = 0x0209, // updated 5.35 hotfix
AddStatusEffect = 0x0141, /*!
ActorControl142 = 0x0142, * @brief Used when resting
ActorControl143 = 0x0143, */
ActorControl144 = 0x0144, UpdateHpMpTp = 0x0319, // updated 5.35 hotfix
UpdateHpMpTp = 0x0145,
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
ChatBanned = 0x006B, ChatBanned = 0xF06B,
Playtime = 0x006C, // updated 4.5 Playtime = 0x03A4, // updated 5.35 hotfix
Logout = 0x0077, // updated 4.5 Logout = 0x02AD, // updated 5.35 hotfix
CFNotify = 0x0078, CFNotify = 0x02C4, // updated 5.35 hotfix
CFMemberStatus = 0x0079, CFMemberStatus = 0x0079,
CFDutyInfo = 0x007A, CFDutyInfo = 0x007A,
CFPlayerInNeed = 0x007F, CFPlayerInNeed = 0xF07F,
CFPreferredRole = 0x0196, // updated 5.35 hotfix
CFCancel = 0x00EC, // updated 5.35 hotfix
SocialRequestError = 0xF0AD,
SocialRequestError = 0x00AD, CFRegistered = 0x010C, // updated 5.35 hotfix
SocialRequestResponse = 0x01C7, // updated 5.35 hotfix
CFRegistered = 0x00B8, // updated 4.1 SocialMessage = 0x0308, // updated 5.35 hotfix
SocialRequestResponse = 0x00BB, // updated 4.1 SocialMessage2 = 0x037C, // updated 5.35 hotfix
CancelAllianceForming = 0x00C6, // updated 4.2 CancelAllianceForming = 0x00C6, // updated 4.2
Chat = 0x00F7, // updated 4.5?
SocialList = 0x0103, // updated 4.5
UpdateSearchInfo = 0x0106, // updated 4.5
InitSearchInfo = 0x0107, // updated 4.4
ExamineSearchComment = 0x0102, // updated 4.1
ServerNoticeShort = 0x010B, // added 4.5
ServerNotice = 0x010C, // updated 4.5
SetOnlineStatus = 0x010D, // updated 4.5
CountdownInitiate = 0x0114, // updated 4.5
CountdownCancel = 0x0115, // updated 4.5
BlackList = 0x0118, // updated 4.5
LogMessage = 0x00D0, LogMessage = 0x00D0,
LinkshellList = 0x011F, // updated 4.5 Chat = 0x0349, // updated 5.35 hotfix
PartyChat = 0x0065,
MailDeleteRequest = 0x0120, // updated 4.5 WorldVisitList = 0xF0FE, // added 4.5
ReqMoogleMailList = 0x0121, // updated 4.5
ReqMoogleMailLetter = 0x0122, // updated 4.5
MailLetterNotification = 0x0123, // updated 4.5
MarketBoardItemListingCount = 0x0125, // updated 4.5 SocialList = 0x0216, // updated 5.35 hotfix
MarketBoardItemListing = 0x0126, // updated 4.5
MarketBoardItemListingHistory = 0x012A, // updated 4.5 ExamineSearchInfo = 0x03C3, // updated 5.35 hotfix
MarketBoardSearchResult = 0x0139, // updated 4.5 UpdateSearchInfo = 0x0121, // updated 5.35 hotfix
InitSearchInfo = 0x036F, // updated 5.35 hotfix
ExamineSearchComment = 0x0102, // updated 4.1
ServerNoticeShort = 0x0115, // updated 5.0
ServerNotice = 0x02F8, // updated 5.35 hotfix
SetOnlineStatus = 0x03D7, // updated 5.35 hotfix
CountdownInitiate = 0x0237, // updated 5.25
CountdownCancel = 0x00D9, // updated 5.18
PlayerAddedToBlacklist = 0x033F, // updated 5.1
PlayerRemovedFromBlacklist = 0x0385, // updated 5.1
BlackList = 0x02DB, // updated 5.35 hotfix
LinkshellList = 0x01F0, // updated 5.35 hotfix
MailDeleteRequest = 0xF12B, // updated 5.0
// 12D - 137 - constant gap between 4.5x -> 5.0
ReqMoogleMailList = 0xF138, // updated 5.0
ReqMoogleMailLetter = 0xF139, // updated 5.0
MailLetterNotification = 0x013A, // updated 5.0
MarketTaxRates = 0x01F8, // updated 5.35 hotfix
MarketBoardSearchResult = 0x032C, // updated 5.35 hotfix
MarketBoardItemListingCount = 0x038F, // updated 5.35 hotfix
MarketBoardItemListingHistory = 0x0186, // updated 5.35 hotfix
MarketBoardItemListing = 0x025F, // updated 5.35 hotfix
CharaFreeCompanyTag = 0x013B, // updated 4.5 CharaFreeCompanyTag = 0x013B, // updated 4.5
FreeCompanyBoardMsg = 0x013C, // updated 4.5 FreeCompanyBoardMsg = 0x013C, // updated 4.5
FreeCompanyInfo = 0x013D, // updated 4.5 FreeCompanyInfo = 0xF13D, // updated 4.5
ExamineFreeCompanyInfo = 0x013E, // updated 4.5 ExamineFreeCompanyInfo = 0xF13E, // updated 4.5
StatusEffectList = 0x0151, // updated 4.5 FreeCompanyUpdateShortMessage = 0xF157, // added 5.0
Effect = 0x0154, // updated 4.5
AoeEffect8 = 0x0157, // updated 4.5
AoeEffect16 = 0x0158, // updated 4.5
AoeEffect24 = 0x0159, // updated 4.5
AoeEffect32 = 0x015A, // updated 4.5
PersistantEffect = 0x015B, // updated 4.5
GCAffiliation = 0x0165, // updated 4.5 StatusEffectList = 0x0382, // updated 5.35 hotfix
EurekaStatusEffectList = 0x0167, // updated 5.18
BossStatusEffectList = 0x0312, // added 5.1
Effect = 0x0192, // updated 5.35 hotfix
AoeEffect8 = 0x012C, // updated 5.35 hotfix
AoeEffect16 = 0x03BF, // updated 5.3
AoeEffect24 = 0x027E, // updated 5.3
AoeEffect32 = 0x017E, // updated 5.3
PersistantEffect = 0x0317, // updated 5.35 hotfix
PlayerSpawn = 0x0175, // updated 4.5 GCAffiliation = 0xF16F, // updated 5.0
NpcSpawn = 0x0176, // updated 4.5
NpcSpawn2 = 0x0177, // ( Bigger statuseffectlist? ) updated 4.5
ActorMove = 0x0178, // updated 4.5
ActorSetPos = 0x017A, // updated 4.5 PlayerSpawn = 0x0179, // updated 5.35 hotfix
NpcSpawn = 0x03A8, // updated 5.35 hotfix
NpcSpawn2 = 0x01CB, // ( Bigger statuseffectlist? ) updated 5.3
ActorMove = 0x01BF, // updated 5.35 hotfix
ActorCast = 0x017C, // updated 4.5 ActorSetPos = 0x03DF, // updated 5.35 hotfix
PartyList = 0x017E, // updated 4.5 ActorCast = 0x0302, // updated 5.35 hotfix
SomeCustomiseChangePacketProbably = 0x00CD, // added 5.18
HateList = 0x0180, // updated 4.5 PartyList = 0x02B2, // updated 5.35 hotfix
ObjectSpawn = 0x0181, // updated 4.5 PartyMessage = 0x00AE, // updated 5.35 hotfix
ObjectDespawn = 0x0182, // updated 4.5 HateRank = 0x02CC, // updated 5.35 hotfix
UpdateClassInfo = 0x0183, // updated 4.5 HateList = 0x0198, // updated 5.35 hotfix
SilentSetClassJob = 0x0184, // updated 4.5 - seems to be the case, not sure if it's actually used for anything ObjectSpawn = 0x02B8, // updated 5.35 hotfix
InitUI = 0x0185, // updated 4.5 ObjectDespawn = 0xF34B, // updated 5.18
PlayerStats = 0x0186, // updated 4.5 UpdateClassInfo = 0x0235, // updated 5.35 hotfix
ActorOwner = 0x0187, // updated 4.5 SilentSetClassJob = 0x018E, // updated 5.0 - seems to be the case, not sure if it's actually used for anything
PlayerStateFlags = 0x0188, // updated 4.5 PlayerSetup = 0x0290, // updated 5.35 hotfix
PlayerClassInfo = 0x0189, // updated 4.5 PlayerStats = 0x023B, // updated 5.35 hotfix
ActorOwner = 0x00E8, // updated 5.35 hotfix
PlayerStateFlags = 0x00F8, // updated 5.35 hotfix
PlayerClassInfo = 0x02C3, // updated 5.35 hotfix
CharaVisualEffect = 0x02E2, // updated 5.35 hotfix
ModelEquip = 0x018B, // updated 4.5 ModelEquip = 0x0277, // updated 5.35 hotfix
Examine = 0x018C, // updated 4.5 Examine = 0x00BC, // updated 5.35 hotfix
CharaNameReq = 0x018D, // updated 4.5 CharaNameReq = 0x008E, // updated 5.35 hotfix
// nb: see #565 on github
UpdateRetainerItemSalePrice = 0xF19F, // updated 5.0
RetainerSaleHistory = 0x020E, // updated 5.21 hotfix
RetainerInformation = 0x01F9, // updated 5.35 hotfix
SetLevelSync = 0x1186, // not updated for 4.4, not sure what it is anymore SetLevelSync = 0x1186, // not updated for 4.4, not sure what it is anymore
ItemInfo = 0x0196, // updated 4.5 ItemInfo = 0x0214, // updated 5.35 hotfix
ContainerInfo = 0x0197, // updated 4.5 ContainerInfo = 0x00C5, // updated 5.35 hotfix
InventoryTransactionFinish = 0x0198, // updated 4.5 InventoryTransactionFinish = 0x02F0, // updated 5.35 hotfix
InventoryTransaction = 0x0199, // updated 4.5 InventoryTransaction = 0x01FD, // updated 5.35 hotfix
CurrencyCrystalInfo = 0x0379, // updated 5.35 hotfix
CurrencyCrystalInfo = 0x019B, // updated 4.5 InventoryActionAck = 0x03E4, // updated 5.35 hotfix
UpdateInventorySlot = 0x036A, // updated 5.35 hotfix
InventoryActionAck = 0x019D, // updated 4.5 HuntingLogEntry = 0x0146, // updated 5.35 hotfix
UpdateInventorySlot = 0x019E, // updated 4.5
HuntingLogEntry = 0x01A9, // added 4.5 EventPlay = 0x00F3, // updated 5.35 hotfix
EventPlay4 = 0x00AC, // updated 5.35 hotfix
EventPlay8 = 0x023F, // updated 5.35 hotfix
EventPlay16 = 0x025B, // updated 5.35 hotfix
EventPlay32 = 0x029A, // updated 5.35 hotfix
EventPlay64 = 0x02C1, // updated 5.35 hotfix
EventPlay128 = 0x038A, // updated 5.35 hotfix
EventPlay255 = 0x034B, // updated 5.35 hotfix
EventPlay = 0x01AB, // updated 4.5 EventStart = 0x009A, // updated 5.35 hotfix
DirectorPlayScene = 0x01AF, // updated 4.5 EventFinish = 0x007E, // updated 5.35 hotfix
EventOpenGilShop = 0x01B2, // updated 4.5
EventStart = 0x01B4, // updated 4.5
EventFinish = 0x01B5, // updated 4.5
EventLinkshell = 0x1169, EventLinkshell = 0x1169,
QuestActiveList = 0x01C8, // updated 4.5 QuestActiveList = 0x0117, // updated 5.35 hotfix
QuestUpdate = 0x01C9, // updated 4.5 QuestUpdate = 0x0073, // updated 5.35 hotfix
QuestCompleteList = 0x01CA, // updated 4.5 QuestCompleteList = 0x0240, // updated 5.35 hotfix
QuestFinish = 0x01CB, // updated 4.5 QuestFinish = 0x00E9, // updated 5.35 hotfix
MSQTrackerComplete = 0x01CC, // updated 4.5 MSQTrackerComplete = 0xF1D6, // updated 5.0
MSQTrackerProgress = 0xF1CD, // updated 4.5 ? this actually looks like the two opcodes have been combined, see #474 MSQTrackerProgress = 0xF1CD, // updated 4.5 ? this actually looks like the two opcodes have been combined, see #474
QuestMessage = 0x01D3, // updated 4.5 QuestMessage = 0x0381, // updated 5.35 hotfix
QuestTracker = 0x01D8, // updated 4.5 QuestTracker = 0x018B, // updated 5.35 hotfix
Mount = 0x01E8, // updated 4.5 Mount = 0x01B5, // updated 5.35 hotfix
DirectorVars = 0x01EA, // updated 4.5 DirectorVars = 0x00E6, // updated 5.18
DirectorPopUp = 0x01F5, // display dialogue pop-ups in duties and FATEs, for example, Teraflare's countdown SomeDirectorUnk1 = 0x0084, // updated 5.18
SomeDirectorUnk2 = 0xF0C1, // updated 5.18
SomeDirectorUnk4 = 0x0202, // updated 5.35 hotfix
SomeDirectorUnk8 = 0x028A, // updated 5.18
SomeDirectorUnk16 = 0x028C, // updated 5.18
DirectorPopUp = 0xF162, // updated 5.18 - display dialogue pop-ups in duties and FATEs, for example, Teraflare's countdown
DirectorPopUp4 = 0x0214, // updated 5.18
DirectorPopUp8 = 0x00F8, // updated 5.18
CFAvailableContents = 0xF1FD, // updated 4.2 CFAvailableContents = 0xF1FD, // updated 4.2
WeatherChange = 0x0205, // updated 4.5 WeatherChange = 0x027B, // updated 5.35 hotfix
PlayerTitleList = 0x0206, // updated 4.5? PlayerTitleList = 0x037D, // updated 5.1
Discovery = 0x0207, // updated 4.5? Discovery = 0x031B, // updated 5.35 hotfix
EorzeaTimeOffset = 0x0209, // updated 4.5 EorzeaTimeOffset = 0xF3B8, // updated 5.1
EquipDisplayFlags = 0x0215, // updated 4.5 EquipDisplayFlags = 0x00BE, // updated 5.35 hotfix
MiniCactpotInit = 0x0286, // added 5.31
ShopMessage = 0x0197, // updated 5.35 hotfix
LootMessage = 0x01B7, // updated 5.35 hotfix
/// Housing ////////////////////////////////////// /// Housing //////////////////////////////////////
LandSetInitialize = 0x0229, // updated 4.5 LandSetInitialize = 0x0234, // updated 5.0
LandUpdate = 0x022A, // updated 4.5 LandUpdate = 0x0235, // updated 5.0
YardObjectSpawn = 0x022B, // updated 4.5 YardObjectSpawn = 0xF236, // updated 5.0
HousingIndoorInitialize = 0x022C, // updated 4.5 HousingIndoorInitialize = 0x0237, // updated 5.0
LandPriceUpdate = 0x022D, // updated 4.5 LandPriceUpdate = 0x0238, // updated 5.0
LandInfoSign = 0x022E, // updated 4.5 LandInfoSign = 0x023D, // updated 5.35 hotfix
LandRename = 0x022F, // updated 4.5 LandRename = 0x023A, // updated 5.0
HousingEstateGreeting = 0x0230, // updated 4.5 HousingEstateGreeting = 0x023B, // updated 5.0
HousingUpdateLandFlagsSlot = 0x0231, // updated 4.5 HousingUpdateLandFlagsSlot = 0x023C, // updated 5.0
HousingLandFlags = 0x0232, // updated 4.5 HousingLandFlags = 0x022F, // updated 5.35 hotfix
HousingShowEstateGuestAccess = 0x0233, // updated 4.5 HousingShowEstateGuestAccess = 0x023E, // updated 5.0
HousingObjectInitialize = 0x0235, // updated 4.45 HousingObjectInitialize = 0x01AA, // updated 5.35 hotfix
HousingInternalObjectSpawn = 0x236, // updated 4.5 HousingInternalObjectSpawn = 0xF241, // updated 5.0
HousingWardInfo = 0x0238, // updated 4.5 HousingWardInfo = 0x02FD, // updated 5.35 hotfix
HousingObjectMove = 0x0239, // updated 4.5 HousingObjectMove = 0xF244, // updated 5.0
SharedEstateSettingsResponse = 0x0245, // updated 4.5 SharedEstateSettingsResponse = 0x0245, // updated 4.5
@ -225,16 +268,15 @@ namespace Sapphire::Network::Packets
DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui
PerformNote = 0x0286, // updated 4.3 PerformNote = 0x0286, // updated 4.3
PrepareZoning = 0x0299, // updated 4.5 PrepareZoning = 0x026C, // updated 5.35 hotfix
ActorGauge = 0x0292, // updated 4.3 ActorGauge = 0x0112, // updated 5.35 hotfix
// Unknown IPC types that still need to be sent // daily quest info -> without them sent, login will take longer...
// TODO: figure all these out properly DailyQuests = 0x0139, // updated 5.35 hotfix
IPCTYPE_UNK_320 = 0x0253, // updated 4.5 DailyQuestRepeatFlags = 0x024C, // updated 5.35 hotfix
IPCTYPE_UNK_322 = 0x0255, // updated 4.5
/// Doman Mahjong ////////////////////////////////////// /// Doman Mahjong //////////////////////////////////////
MahjongOpenGui = 0x02BC, // only available in mahjong instance MahjongOpenGui = 0x02A4, // only available in mahjong instance
MahjongNextRound = 0x02BD, // initial hands(baipai), # of riichi(wat), winds, honba, score and stuff MahjongNextRound = 0x02BD, // initial hands(baipai), # of riichi(wat), winds, honba, score and stuff
MahjongPlayerAction = 0x02BE, // tsumo(as in drawing a tile) called chi/pon/kan/riichi MahjongPlayerAction = 0x02BE, // tsumo(as in drawing a tile) called chi/pon/kan/riichi
MahjongEndRoundTsumo = 0x02BF, // called tsumo MahjongEndRoundTsumo = 0x02BF, // called tsumo
@ -251,37 +293,43 @@ namespace Sapphire::Network::Packets
*/ */
enum ClientZoneIpcType : uint16_t enum ClientZoneIpcType : uint16_t
{ {
PingHandler = 0x0219, // updated 5.35 hotfix
InitHandler = 0x0185, // updated 5.35 hotfix
PingHandler = 0x0065, // unchanged 4.5 FinishLoadingHandler = 0x01BE, // updated 5.35 hotfix
InitHandler = 0x0066, // unchanged 4.5
FinishLoadingHandler = 0x0069, // unchanged 4.5 CFCommenceHandler = 0x0118, // updated 5.35 hotfix
CFCommenceHandler = 0x006F, CFCancelHandler = 0x0332, // updated 5.35 hotfix
CFRegisterDuty = 0x0289, // updated 5.35 hotfix
CFRegisterRoulette = 0x0088, // updated 5.35 hotfix
CFRegisterDuty = 0x0071, PlayTimeHandler = 0x02A8, // updated 5.35 hotfix
CFRegisterRoulette = 0x0072, LogoutHandler = 0x00EC, // updated 5.35 hotfix
PlayTimeHandler = 0x0073, // unchanged 4.5 CancelLogout = 0x03DB, // updated 5.35 hotfix
LogoutHandler = 0x0074, // unchanged 4.5
CFDutyInfoHandler = 0x0078, // updated 4.2 CFDutyInfoHandler = 0x0078, // updated 4.2
SocialReqSendHandler = 0x00AE, // updated 4.1 SocialReqSendHandler = 0x0387, // updated 5.35 hotfix
SocialResponseHandler = 0x028D, // updated 5.35 hotfix
CreateCrossWorldLS = 0x00AF, // updated 4.3 CreateCrossWorldLS = 0x00AF, // updated 4.3
ChatHandler = 0x00D7, // updated 4.5 ChatHandler = 0x0131, // updated 5.35 hotfix
PartyChatHandler = 0x0065,
PartySetLeaderHandler = 0x0208, // updated 5.35 hotfix
LeavePartyHandler = 0x0337, // updated 5.35 hotfix
KickPartyMemberHandler = 0x014C, // updated 5.35 hotfix
DisbandPartyHandler = 0x0205, // updated 5.35 hotfix
SocialListHandler = 0x00DF, // updated 4.5 SocialListHandler = 0x0340, // updated 5.35 hotfix
ReqSearchInfoHandler = 0x00E4, // updated 4.5 SetSearchInfoHandler = 0x0314, // updated 5.35 hotfix
ReqExamineSearchCommentHandler = 0x00E5, // updated 4.5 ReqSearchInfoHandler = 0x01E9, // updated 5.35 hotfix
ReqExamineSearchCommentHandler = 0x00E7, // updated 5.0
SetSearchInfoHandler = 0x00E2, // unchanged 4.5 ReqRemovePlayerFromBlacklist = 0x00F1, // updated 5.0
BlackListHandler = 0x0079, // updated 5.35 hotfix
PlayerSearchHandler = 0x00F4, // updated 5.0
BlackListHandler = 0x00F0, // updated 4.5 LinkshellListHandler = 0x024B, // updated 5.35 hotfix
PlayerSearchHandler = 0x00E6, // updated 4.5
LinkshellListHandler = 0x00F8, // updated 4.5
MarketBoardRequestItemListingInfo = 0x0102, // updated 4.5 MarketBoardRequestItemListingInfo = 0x0102, // updated 4.5
MarketBoardRequestItemListings = 0x0103, // updated 4.5 MarketBoardRequestItemListings = 0x0103, // updated 4.5
@ -291,58 +339,63 @@ namespace Sapphire::Network::Packets
FcInfoReqHandler = 0x011A, // updated 4.2 FcInfoReqHandler = 0x011A, // updated 4.2
FreeCompanyUpdateShortMessageHandler = 0x0123, // added 5.0
ReqMarketWishList = 0x012C, // updated 4.3 ReqMarketWishList = 0x012C, // updated 4.3
ReqJoinNoviceNetwork = 0x0129, // updated 4.2 ReqJoinNoviceNetwork = 0x0129, // updated 4.2
ReqCountdownInitiate = 0x0133, // updated 4.5 ReqCountdownInitiate = 0x009A, // updated 5.25
ReqCountdownCancel = 0x0134, // updated 4.5 ReqCountdownCancel = 0x0244, // updated 5.25
ClearWaymarks = 0x0135, // updated 4.5
ZoneLineHandler = 0x0137, // updated 4.5 ZoneLineHandler = 0x0279, // updated 5.35 hotfix
ClientTrigger = 0x0138, // updated 4.5 ClientTrigger = 0x03D3, // updated 5.35 hotfix
DiscoveryHandler = 0x0139, // updated 4.5 DiscoveryHandler = 0x00E3, // updated 5.35 hotfix
AddWaymark = 0x013A, // updated 4.5 PlaceFieldMarkerPreset = 0x023F, // updated 5.25
PlaceFieldMarker = 0x01BA, // updated 5.25
SkillHandler = 0x01CD, // updated 5.35 hotfix
GMCommand1 = 0x02AC, // updated 5.35 hotfix
GMCommand2 = 0x029F, // updated 5.35 hotfix
AoESkillHandler = 0x030C, // updated 5.35 hotfix
SkillHandler = 0x013B, // updated 4.5 UpdatePositionHandler = 0x0236, // updated 5.35 hotfix
GMCommand1 = 0x013C, // updated 4.5
GMCommand2 = 0x013D, // updated 4.5
AoESkillHandler = 0x13E, // updated 4.5
UpdatePositionHandler = 0x013F, // updated 4.5 InventoryModifyHandler = 0x0135, // updated 5.35 hotfix
UpdatePositionInstance = 0x0183, // updated 4.3
InventoryModifyHandler = 0x0146, // updated 4.5 ( +4 ) InventoryEquipRecommendedItems = 0x0149, // updated 5.0
ReqPlaceHousingItem = 0x149, // updated 4.5 ReqPlaceHousingItem = 0x014B, // updated 5.0
BuildPresetHandler = 0x0150, // updated 5.0
BuildPresetHandler = 0x014E, // updated 4.5 TalkEventHandler = 0x02A4, // updated 5.35 hotfix
TalkEventHandler = 0x014F, // updated 4.5 EmoteEventHandler = 0x02C8, // updated 5.35 hotfix
EmoteEventHandler = 0x0150, // updated 4.5 WithinRangeEventHandler = 0x0209, // updated 5.35 hotfix
WithinRangeEventHandler = 0x0151, // updated 4.5 OutOfRangeEventHandler = 0x0319, // updated 5.35 hotfix
OutOfRangeEventHandler = 0x0152, // updated 4.5 EnterTeriEventHandler = 0x0192, // updated 5.35 hotfix
EnterTeriEventHandler = 0x0153, // updated 4.5 ShopEventHandler = 0x0156, // updated 5.0
ShopEventHandler = 0x0155, // updated 4.5 ReturnEventHandler = 0x02B4, // updated 5.35 hotfix
TradeReturnEventHandler = 0x00A4, // updated 5.35 hotfix
ReturnEventHandler = 0x0158, // updated 4.5 TradeMultipleReturnEventHander = 0x035C, // updated 5.35 hotfix
TradeReturnEventHandler = 0x0159, // updated 4.5
LinkshellEventHandler = 0x016B, // updated 4.5 LinkshellEventHandler = 0x016B, // updated 4.5
LinkshellEventHandler1 = 0x016C, // updated 4.5 LinkshellEventHandler1 = 0x016C, // updated 4.5
LandRenameHandler = 0x0175, // updated 4.5 ReqEquipDisplayFlagsChange = 0x02F6, // updated 5.35 hotfix
HousingUpdateHouseGreeting = 0x0176, // updated 4.5
HousingUpdateObjectPosition = 0x0177, // updated 4.5
SetSharedEstateSettings = 0x017B, // updated 4.5 LandRenameHandler = 0xF177, // updated 5.0
HousingUpdateHouseGreeting = 0x0178, // updated 5.0
HousingUpdateObjectPosition = 0x0159, // updated 5.25
SetSharedEstateSettings = 0x017B, // updated 5.0
UpdatePositionInstance = 0x0345, // updated 5.35 hotfix
PerformNoteHandler = 0x029B, // updated 4.3 PerformNoteHandler = 0x029B, // updated 4.3
ReqEquipDisplayFlagsChange = 0x0173, // updated 4.5 WorldInteractionHandler = 0x00A9, // updated 5.35 hotfix
Dive = 0x02CC, // updated 5.35 hotfix
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -354,6 +407,8 @@ namespace Sapphire::Network::Packets
{ {
Tell = 0x0064, // updated for sb Tell = 0x0064, // updated for sb
TellErrNotFound = 0x0066, TellErrNotFound = 0x0066,
FreeCompanyEvent = 0x012C, // added 5.0
}; };
/** /**

View file

@ -4,10 +4,7 @@
#include <Common.h> #include <Common.h>
#include <Network/CommonNetwork.h> #include <Network/CommonNetwork.h>
namespace Sapphire { namespace Sapphire::Network::Packets::Server {
namespace Network {
namespace Packets {
namespace Server {
struct FFXIVIpcRetainerList : struct FFXIVIpcRetainerList :
FFXIVIpcBasePacket< LobbyRetainerList > FFXIVIpcBasePacket< LobbyRetainerList >
@ -152,7 +149,5 @@ struct FFXIVIpcLobbyError : FFXIVIpcBasePacket< LobbyError >
}; };
} }
}
}
}
#endif #endif

View file

@ -4,10 +4,8 @@
#include <Common.h> #include <Common.h>
#include <Network/CommonNetwork.h> #include <Network/CommonNetwork.h>
namespace Sapphire { namespace Sapphire::Network::Packets::Client
namespace Network { {
namespace Packets {
namespace Client {
struct FFXIVIpcGmCommand1 : struct FFXIVIpcGmCommand1 :
FFXIVIpcBasePacket< GMCommand1 > FFXIVIpcBasePacket< GMCommand1 >
@ -51,15 +49,26 @@ struct FFXIVIpcUpdatePosition :
FFXIVIpcBasePacket< UpdatePositionHandler > FFXIVIpcBasePacket< UpdatePositionHandler >
{ {
/* 0000 */ float rotation; /* 0000 */ float rotation;
/* 0004 */ uint8_t unk_1[ 3 ]; /* 0004 */ uint8_t animationType;
/* 0005 */ uint8_t animationState;
/* 0006 */ uint8_t clientAnimationType;
/* 0007 */ uint8_t headPosition; /* 0007 */ uint8_t headPosition;
/* 0008 */ uint8_t animationType; /* 0008 */ Common::FFXIVARR_POSITION3 position;
/* 0009 */ uint8_t animationState; /* 000C */ uint8_t unk[ 4 ]; // padding?
/* 000A */ uint8_t clientAnimationType;
/* 000B */ uint8_t unk_2;
/* 000C */ Common::FFXIVARR_POSITION3 position;
}; };
struct FFXIVIpcUpdatePositionInstance :
FFXIVIpcBasePacket< UpdatePositionInstance >
{
/* 0000 */ float rotation;
/* 0004 */ float interpolateRotation;
/* 0008 */ uint32_t flags;
/* 000C */ Common::FFXIVARR_POSITION3 position;
/* 0018 */ Common::FFXIVARR_POSITION3 interpolatePosition;
/* 0024 */ uint32_t unknown;
};
struct FFXIVIpcSkillHandler : struct FFXIVIpcSkillHandler :
FFXIVIpcBasePacket< SkillHandler > FFXIVIpcBasePacket< SkillHandler >
{ {
@ -198,6 +207,13 @@ struct FFXIVIpcChatHandler :
/* 001A */ char message[1012]; /* 001A */ char message[1012];
}; };
struct FFXIVIpcPartyChatHandler :
FFXIVIpcBasePacket< ChatHandler >
{
uint64_t unknown;
char message[1024];
};
struct FFXIVIpcShopEventHandler : struct FFXIVIpcShopEventHandler :
FFXIVIpcBasePacket< ShopEventHandler > FFXIVIpcBasePacket< ShopEventHandler >
{ {
@ -219,7 +235,7 @@ struct FFXIVIpcInventoryModifyHandler :
{ {
/* 0000 */ uint32_t seq; /* 0000 */ uint32_t seq;
/* 0004 */ Common::InventoryOperation action; /* 0004 */ Common::InventoryOperation action;
/* 0005 */ uint8_t pad_0005[7]; /* 0006 */ uint8_t pad_0006[6];
/* 000C */ uint16_t fromContainer; /* 000C */ uint16_t fromContainer;
/* 000E */ uint8_t pad_000E[2]; /* 000E */ uint8_t pad_000E[2];
/* 0010 */ uint8_t fromSlot; /* 0010 */ uint8_t fromSlot;
@ -325,9 +341,91 @@ struct FFXIVIpcMarketBoardRequestItemListingInfo :
/* 0000 */ uint32_t requestId; /* 0000 */ uint32_t requestId;
}; };
} struct FFXIVIpcFreeCompanyUpdateShortMessageHandler :
} FFXIVIpcBasePacket< FreeCompanyUpdateShortMessageHandler >
} {
char shortMessage[104];
uint8_t padding;
uint8_t unknown;
uint32_t unknown1;
uint16_t unknown2;
};
struct FFXIVIpcWorldInteractionHandler :
FFXIVIpcBasePacket< WorldInteractionHandler >
{
uint32_t action;
uint32_t param1;
uint32_t param2;
uint32_t param3;
uint32_t param4;
Common::FFXIVARR_POSITION3 position;
};
struct FFXIVIpcSocialReqSendHandler :
FFXIVIpcBasePacket< SocialReqSendHandler >
{
uint64_t unknown;
uint8_t p1;
uint8_t p2;
uint8_t socialType;
char name[32];
uint8_t padding[5];
};
struct FFXIVIpcSocialResponseHandler :
FFXIVIpcBasePacket< SocialResponseHandler >
{
uint64_t contentId;
uint8_t p1;
uint8_t p2;
uint8_t socialType;
uint8_t response;
uint32_t unknown;
};
struct FFXIVIpcPartySetLeaderHandler :
FFXIVIpcBasePacket< PartySetLeaderHandler >
{
uint64_t contentId;
uint8_t p1;
uint8_t p2;
char name[32];
uint8_t padding[6];
};
struct FFXIVIpcLeavePartyHandler :
FFXIVIpcBasePacket< LeavePartyHandler >
{
uint64_t empty;
};
struct FFXIVIpcKickPartyMemberHander :
FFXIVIpcBasePacket< KickPartyMemberHandler >
{
uint64_t contentId;
uint8_t p1;
uint8_t p2;
char name[32];
uint8_t padding[6];
};
struct FFXIVIpcDisbandPartyHandler :
FFXIVIpcBasePacket< DisbandPartyHandler >
{
uint64_t empty;
};
struct FFXIVIpcDive :
FFXIVIpcBasePacket< Dive >
{
float unknown;
Common::FFXIVARR_POSITION3 posTarget;
Common::FFXIVARR_POSITION3 posOriginal;
uint32_t padding;
};
} }
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H #endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H

File diff suppressed because it is too large Load diff

115
src/common/Service.h Normal file
View file

@ -0,0 +1,115 @@
#ifndef SAPPHIRE_SERVICE_H
#define SAPPHIRE_SERVICE_H
#include <memory>
#include <utility>
#include <cassert>
// stolen from: https://github.com/skypjack/entt/blob/master/src/entt/locator/locator.hpp
namespace Sapphire::Common
{
/**
* @brief Service locator, nothing more.
*
* A service locator can be used to do what it promises: locate services.<br/>
* Usually service locators are tightly bound to the services they expose and
* thus it's hard to define a general purpose class to do that. This template
* based implementation tries to fill the gap and to get rid of the burden of
* defining a different specific locator for each application.
*
* @tparam SvcType Type of service managed by the locator.
*/
template< typename SvcType >
struct Service
{
/*! @brief Type of service offered. */
using ServiceType = SvcType;
/*! @brief Default constructor, deleted on purpose. */
Service() = delete;
/*! @brief Default destructor, deleted on purpose. */
~Service() = delete;
/**
* @brief Tests if a valid service implementation is set.
* @return True if the service is set, false otherwise.
*/
static bool empty() noexcept
{
return !static_cast< bool >( service );
}
/**
* @brief Returns a weak pointer to a service implementation, if any.
*
* Clients of a service shouldn't retain references to it. The recommended
* way is to retrieve the service implementation currently set each and
* every time the need of using it arises. Otherwise users can incur in
* unexpected behaviors.
*
* @return A reference to the service implementation currently set, if any.
*/
static std::weak_ptr< SvcType > get() noexcept
{
return service;
}
/**
* @brief Returns a weak reference to a service implementation, if any.
*
* Clients of a service shouldn't retain references to it. The recommended
* way is to retrieve the service implementation currently set each and
* every time the need of using it arises. Otherwise users can incur in
* unexpected behaviors.
*
* @warning
* In case no service implementation has been set, a call to this function
* results in undefined behavior.
*
* @return A reference to the service implementation currently set, if any.
*/
static SvcType& ref() noexcept
{
return *service;
}
/**
* @brief Sets or replaces a service.
* @tparam Impl Type of the new service to use.
* @tparam Args Types of arguments to use to construct the service.
* @param args Parameters to use to construct the service.
*/
template< typename Impl = SvcType, typename... Args >
static void set( Args&& ... args )
{
service = std::make_shared< Impl >( std::forward< Args >( args )... );
}
/**
* @brief Sets or replaces a service.
* @param ptr Service to use to replace the current one.
*/
static void set( std::shared_ptr< SvcType > ptr )
{
assert( static_cast< bool >( ptr ) );
service = std::move( ptr );
}
/**
* @brief Resets a service.
*
* The service is no longer valid after a reset.
*/
static void reset()
{
service.reset();
}
private:
inline static std::shared_ptr< SvcType > service = nullptr;
};
}
#endif //SAPPHIRE_SERVICE_H

View file

@ -7,18 +7,26 @@
#include <execinfo.h> #include <execinfo.h>
#include <cxxabi.h> #include <cxxabi.h>
#else #else
#include <stackwalker/StackWalker.h>
class SapphireStackWalker : public StackWalker #include <windows.h>
#include <intrin.h>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
inline std::string basename( const std::string& file )
{ {
public: size_t i = file.find_last_of( "\\/" );
SapphireStackWalker() : StackWalker() {} if ( i == std::string::npos )
protected:
virtual void OnOutput( LPCSTR szText )
{ {
Sapphire::Logger::fatal( "{}", szText ); return file;
} }
}; else
{
return file.substr( i + 1 );
}
}
#endif #endif
using namespace Sapphire::Common; using namespace Sapphire::Common;
@ -148,8 +156,74 @@ void Util::CrashHandler::printStackTrace( unsigned int max_frames )
#else #else
SapphireStackWalker sw; DWORD machine = IMAGE_FILE_MACHINE_AMD64;
sw.ShowCallstack();
HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread();
CONTEXT context = {};
context.ContextFlags = CONTEXT_FULL;
RtlCaptureContext( &context );
SymInitialize( process, NULL, TRUE );
SymSetOptions( SYMOPT_LOAD_LINES );
STACKFRAME frame = {};
frame.AddrPC.Offset = context.Rip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Rbp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Rsp;
frame.AddrStack.Mode = AddrModeFlat;
while( StackWalk( machine, process, thread, &frame, &context, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL ) )
{
auto moduleBase = SymGetModuleBase( process, frame.AddrPC.Offset );
std::string moduleName;
std::string funcName;
std::string fileName;
int lineNum = 0;
char moduelBuff[MAX_PATH];
if( moduleBase && GetModuleFileNameA( ( HINSTANCE ) moduleBase, moduelBuff, MAX_PATH ) )
{
moduleName = basename( moduelBuff );
}
else
{
moduleName = "Unknown Module";
}
DWORD64 offset = 0;
char symbolBuffer[sizeof( IMAGEHLP_SYMBOL ) + 255];
PIMAGEHLP_SYMBOL symbol = ( PIMAGEHLP_SYMBOL ) symbolBuffer;
symbol->SizeOfStruct = ( sizeof IMAGEHLP_SYMBOL ) + 255;
symbol->MaxNameLength = 254;
if( SymGetSymFromAddr( process, frame.AddrPC.Offset, &offset, symbol ) )
{
funcName = symbol->Name;
}
else
{
funcName = "Unknown Function";
}
IMAGEHLP_LINE line;
line.SizeOfStruct = sizeof( IMAGEHLP_LINE );
DWORD offset_ln = 0;
if( SymGetLineFromAddr( process, frame.AddrPC.Offset, &offset_ln, &line ) )
{
fileName = line.FileName;
lineNum = line.LineNumber;
}
Logger::fatal( "[{:x}] {}({}): {} ({})", frame.AddrPC.Offset, fileName, lineNum, funcName, moduleName );
}
SymCleanup( process );
#endif #endif
} }

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