mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 07:07:45 +00:00
Oodle support for 6.15
Requires the oodle2base.h and oodle2net.h header files, and oo2net_9_win64.dll, to be placed in /deps/Oodle/ - they are not included here
This commit is contained in:
parent
6389597004
commit
7449d16c7e
8 changed files with 130 additions and 7 deletions
|
@ -15,6 +15,7 @@ add_custom_target( copy_runtime_files ALL
|
||||||
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 remove_directory ${CMAKE_BINARY_DIR}/bin/data/actions
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/deps/oo2net_9_win64.dll ${CMAKE_BINARY_DIR}/bin/oo2net_9_win64.dll
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/deps/ffxiv-actions/actions ${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 )
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
|
@ -43,6 +44,7 @@ find_package( MySQL )
|
||||||
##############################
|
##############################
|
||||||
add_subdirectory( "deps/zlib" )
|
add_subdirectory( "deps/zlib" )
|
||||||
add_subdirectory( "deps/MySQL" )
|
add_subdirectory( "deps/MySQL" )
|
||||||
|
add_subdirectory( "deps/Oodle" )
|
||||||
add_subdirectory( "deps/datReader" )
|
add_subdirectory( "deps/datReader" )
|
||||||
add_subdirectory( "deps/mysqlConnector" )
|
add_subdirectory( "deps/mysqlConnector" )
|
||||||
add_subdirectory( "deps/recastnavigation" )
|
add_subdirectory( "deps/recastnavigation" )
|
||||||
|
|
9
deps/Oodle/CMakeLists.txt
vendored
Normal file
9
deps/Oodle/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
add_library(OodleNet STATIC IMPORTED GLOBAL)
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
OodleNet
|
||||||
|
PROPERTIES
|
||||||
|
IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/deps/Oodle/oo2net_9_win64.lib"
|
||||||
|
IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/deps/Oodle/oo2net_9_win64.lib"
|
||||||
|
LINKER_LANGUAGE C
|
||||||
|
)
|
|
@ -20,7 +20,8 @@ target_link_libraries( common
|
||||||
PUBLIC
|
PUBLIC
|
||||||
xivdat
|
xivdat
|
||||||
mysqlConnector
|
mysqlConnector
|
||||||
mysql )
|
mysql
|
||||||
|
OodleNet )
|
||||||
if( UNIX )
|
if( UNIX )
|
||||||
target_link_libraries( common
|
target_link_libraries( common
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
@ -32,6 +33,7 @@ target_include_directories( common
|
||||||
PUBLIC
|
PUBLIC
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/"
|
"${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/Oodle/"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/asio/asio/include/"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/asio/asio/include/"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/spdlog/include/" )
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/spdlog/include/" )
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace Sapphire::Network::Packets
|
||||||
* +-------------------------------+---------------+-------+-------+
|
* +-------------------------------+---------------+-------+-------+
|
||||||
* | timestamp | size | cType | count |
|
* | timestamp | size | cType | count |
|
||||||
* +---+---+-------+---------------+---------------+-------+-------+
|
* +---+---+-------+---------------+---------------+-------+-------+
|
||||||
* | ? |CMP| ? | ? |
|
* | ? |CMP| ? | oodleDcmpSize |
|
||||||
* +---+---+-------+---------------+
|
* +---+---+-------+---------------+
|
||||||
* (followed by /count/ FFXIVARR_PACKET_SEGMENTs)
|
* (followed by /count/ FFXIVARR_PACKET_SEGMENTs)
|
||||||
*/
|
*/
|
||||||
|
@ -62,9 +62,13 @@ namespace Sapphire::Network::Packets
|
||||||
/** The number of packet segments that follow. */
|
/** The number of packet segments that follow. */
|
||||||
uint16_t count;
|
uint16_t count;
|
||||||
uint8_t unknown_20;
|
uint8_t unknown_20;
|
||||||
/** Indicates if the data segments of this packet are compressed. */
|
/** Indicates compression method of the data segments of this packet.
|
||||||
uint8_t isCompressed;
|
* 0: none, 1: Zlib, 2: Oodle
|
||||||
uint32_t unknown_24;
|
*/
|
||||||
|
uint8_t compressionType;
|
||||||
|
uint16_t unknown_22;
|
||||||
|
/** The size of the packet payload when decompressed, only used if compressionType = Oodle */
|
||||||
|
uint32_t oodleDecompressedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<( std::ostream& os, const FFXIVARR_PACKET_HEADER& hdr )
|
inline std::ostream& operator<<( std::ostream& os, const FFXIVARR_PACKET_HEADER& hdr )
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "CommonNetwork.h"
|
#include "CommonNetwork.h"
|
||||||
#include "GamePacketParser.h"
|
#include "GamePacketParser.h"
|
||||||
|
#include "Oodle.h"
|
||||||
|
|
||||||
#include <string.h> // memcpy
|
#include <string.h> // memcpy
|
||||||
|
#include <Logging/Logger.h>
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
using namespace Sapphire::Network::Packets;
|
using namespace Sapphire::Network::Packets;
|
||||||
|
@ -49,10 +51,51 @@ PacketParseResult Network::Packets::getPackets( const std::vector< uint8_t >& bu
|
||||||
std::vector< FFXIVARR_PACKET_RAW >& packets )
|
std::vector< FFXIVARR_PACKET_RAW >& packets )
|
||||||
{
|
{
|
||||||
// sanity check: check there's enough bytes in the buffer
|
// sanity check: check there's enough bytes in the buffer
|
||||||
const auto bytesExpected = packetHeader.size - sizeof( struct FFXIVARR_PACKET_HEADER );
|
auto bytesExpected = packetHeader.size - sizeof( struct FFXIVARR_PACKET_HEADER );
|
||||||
if( buffer.size() - offset < bytesExpected )
|
if( buffer.size() - offset < bytesExpected )
|
||||||
return Incomplete;
|
return Incomplete;
|
||||||
|
|
||||||
|
std::vector< uint8_t > decompBuf;
|
||||||
|
|
||||||
|
// check compression, do decompress if Oodle/Zlib
|
||||||
|
if( packetHeader.compressionType == Oodle )
|
||||||
|
{
|
||||||
|
std::vector< uint8_t > inBuf;
|
||||||
|
inBuf.assign( buffer.begin() + sizeof( struct FFXIVARR_PACKET_HEADER ), buffer.end() );
|
||||||
|
|
||||||
|
std::vector< uint8_t > outBuf;
|
||||||
|
outBuf.resize( packetHeader.oodleDecompressedSize );
|
||||||
|
|
||||||
|
auto _oodle = Network::Oodle();
|
||||||
|
bool oodleSuccess = _oodle.oodleDecode( inBuf, bytesExpected, outBuf, packetHeader.oodleDecompressedSize );
|
||||||
|
|
||||||
|
if( !oodleSuccess )
|
||||||
|
{
|
||||||
|
Logger::warn( "Oodle decompression failed." );
|
||||||
|
return Malformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesExpected = packetHeader.oodleDecompressedSize;
|
||||||
|
|
||||||
|
decompBuf.assign( buffer.begin(), buffer.begin() + sizeof( struct FFXIVARR_PACKET_HEADER ) );
|
||||||
|
decompBuf.insert( decompBuf.end(), outBuf.begin(), outBuf.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( packetHeader.compressionType == Zlib )
|
||||||
|
{
|
||||||
|
// to do(?): Zlib decompression should go here,
|
||||||
|
// but I don't think the client ever sends Zlib packets? So it may not be needed
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( packetHeader.compressionType == NoCompression )
|
||||||
|
decompBuf.assign( buffer.begin(), buffer.end() );
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::warn( "Unknown packet compression type: {}", packetHeader.compressionType );
|
||||||
|
return Malformed;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop each message
|
// Loop each message
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint32_t bytesProcessed = 0;
|
uint32_t bytesProcessed = 0;
|
||||||
|
@ -61,7 +104,7 @@ PacketParseResult Network::Packets::getPackets( const std::vector< uint8_t >& bu
|
||||||
FFXIVARR_PACKET_RAW rawPacket;
|
FFXIVARR_PACKET_RAW rawPacket;
|
||||||
|
|
||||||
// Copy ipc packet message
|
// Copy ipc packet message
|
||||||
const auto packetResult = getPacket( buffer, offset + bytesProcessed, rawPacket );
|
const auto packetResult = getPacket( decompBuf, offset + bytesProcessed, rawPacket );
|
||||||
if( packetResult != Success )
|
if( packetResult != Success )
|
||||||
return packetResult;
|
return packetResult;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,13 @@ namespace Sapphire::Network::Packets
|
||||||
Malformed
|
Malformed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CompressionType
|
||||||
|
{
|
||||||
|
NoCompression,
|
||||||
|
Zlib,
|
||||||
|
Oodle,
|
||||||
|
};
|
||||||
|
|
||||||
/// Read packet header from buffer with given offset.
|
/// Read packet header from buffer with given offset.
|
||||||
/// Buffer with given offset must be pointing to start of the new FFXIV packet.
|
/// Buffer with given offset must be pointing to start of the new FFXIV packet.
|
||||||
PacketParseResult getHeader( const std::vector< uint8_t >& buffer, const uint32_t offset,
|
PacketParseResult getHeader( const std::vector< uint8_t >& buffer, const uint32_t offset,
|
||||||
|
|
28
src/common/Network/Oodle.cpp
Normal file
28
src/common/Network/Oodle.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include "Oodle.h"
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
Network::Oodle::Oodle() :
|
||||||
|
m_htbits(19)
|
||||||
|
{
|
||||||
|
auto stateSize = OodleNetwork1UDP_State_Size();
|
||||||
|
auto sharedSize = OodleNetwork1_Shared_Size( m_htbits );
|
||||||
|
|
||||||
|
m_state = std::vector< uint8_t >( stateSize, 0 );
|
||||||
|
m_shared = std::vector< uint8_t >( sharedSize, 0 );
|
||||||
|
m_window = std::vector< uint8_t >( 0x8000, 0 );
|
||||||
|
|
||||||
|
oodleInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::Oodle::oodleInit()
|
||||||
|
{
|
||||||
|
OodleNetwork1_Shared_SetWindow( (OodleNetwork1_Shared*) &m_shared[0], m_htbits, &m_window[0], (int) m_window.size() );
|
||||||
|
OodleNetwork1UDP_Train( (OodleNetwork1UDP_State*) &m_state[0], (OodleNetwork1_Shared*) &m_shared[0], nullptr, nullptr, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Network::Oodle::oodleDecode( const std::vector< uint8_t > &enc, uint32_t encSize, std::vector< uint8_t > &dec, uint32_t decSize )
|
||||||
|
{
|
||||||
|
OodleNetwork1_Shared_SetWindow( (OodleNetwork1_Shared*) &m_shared[0], m_htbits, &m_window[0], (int) m_window.size() );
|
||||||
|
return OodleNetwork1UDP_Decode( (OodleNetwork1UDP_State*) &m_state[0], (OodleNetwork1_Shared*) &m_shared[0], &enc[0], encSize, &dec[0], decSize );
|
||||||
|
}
|
28
src/common/Network/Oodle.h
Normal file
28
src/common/Network/Oodle.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef _OODLE_H
|
||||||
|
#define _OODLE_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <oodle2net.h>
|
||||||
|
|
||||||
|
namespace Sapphire::Network
|
||||||
|
{
|
||||||
|
class Oodle
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector< uint8_t > m_state;
|
||||||
|
std::vector< uint8_t > m_shared;
|
||||||
|
std::vector< uint8_t > m_window;
|
||||||
|
|
||||||
|
int m_htbits;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Oodle();
|
||||||
|
virtual ~Oodle() = default;
|
||||||
|
|
||||||
|
void oodleInit();
|
||||||
|
bool oodleDecode( const std::vector< uint8_t > &enc, uint32_t encSize, std::vector< uint8_t > &dec, uint32_t decSize );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _OODLE_H
|
Loading…
Add table
Reference in a new issue