mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 14:37:44 +00:00
commit
57e6770ffd
20 changed files with 470 additions and 955 deletions
|
@ -218,9 +218,21 @@ struct LGB_MAPRANGE_HEADER :
|
||||||
public LGB_ENTRY_HEADER
|
public LGB_ENTRY_HEADER
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint16_t unknown2;
|
uint8_t unknown2;
|
||||||
|
uint8_t unknown2_1;
|
||||||
uint16_t unknown3;
|
uint16_t unknown3;
|
||||||
uint8_t unknown4[0x10];
|
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 :
|
struct LGB_MAPRANGE_ENTRY :
|
||||||
|
@ -240,7 +252,7 @@ public:
|
||||||
|
|
||||||
struct LGB_GROUP_HEADER
|
struct LGB_GROUP_HEADER
|
||||||
{
|
{
|
||||||
uint32_t unknown;
|
uint32_t id;
|
||||||
int32_t groupNameOffset;
|
int32_t groupNameOffset;
|
||||||
int32_t entriesOffset;
|
int32_t entriesOffset;
|
||||||
int32_t entryCount;
|
int32_t entryCount;
|
||||||
|
@ -278,7 +290,7 @@ struct LGB_GROUP
|
||||||
{
|
{
|
||||||
const auto type = *reinterpret_cast<LgbEntryType*>( buf + entryOffset );
|
const auto type = *reinterpret_cast<LgbEntryType*>( buf + entryOffset );
|
||||||
// garbage to skip model loading
|
// garbage to skip model loading
|
||||||
if( !ignoreModels && 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 ) );
|
||||||
}
|
}
|
||||||
|
@ -298,12 +310,11 @@ struct LGB_GROUP
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) );
|
entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) );
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
entries[i] = nullptr;
|
entries.push_back( std::make_shared< LGB_ENTRY >( buf, entryOffset ) );
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
|
@ -331,9 +342,15 @@ struct LGB_FILE
|
||||||
{
|
{
|
||||||
LGB_FILE_HEADER header;
|
LGB_FILE_HEADER header;
|
||||||
std::vector< LGB_GROUP > groups;
|
std::vector< LGB_GROUP > groups;
|
||||||
std::string name;
|
std::string m_name;
|
||||||
|
|
||||||
LGB_FILE( char* buf, const std::string& name )
|
LGB_FILE( char* buf, const std::string& name ) :
|
||||||
|
LGB_FILE( buf )
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
LGB_FILE( char* buf )
|
||||||
{
|
{
|
||||||
header = *reinterpret_cast< LGB_FILE_HEADER* >( buf );
|
header = *reinterpret_cast< LGB_FILE_HEADER* >( buf );
|
||||||
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 )
|
|
@ -11,9 +11,6 @@
|
||||||
|
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
// garbage to skip model loading
|
|
||||||
extern bool ignoreModels;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs
|
// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs
|
||||||
|
|
||||||
|
@ -36,6 +33,7 @@ enum SgbGroupEntryType :
|
||||||
uint32_t
|
uint32_t
|
||||||
{
|
{
|
||||||
Model = 0x01,
|
Model = 0x01,
|
||||||
|
Gimmick = 0x06,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SGB_GROUP_HEADER
|
struct SGB_GROUP_HEADER
|
||||||
|
@ -64,6 +62,35 @@ struct SGB_GROUP_HEADER
|
||||||
uint32_t unknown44;
|
uint32_t unknown44;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SGB_GROUP1C_HEADER
|
||||||
|
{
|
||||||
|
SgbDataType type;
|
||||||
|
int32_t nameOffset;
|
||||||
|
uint32_t unknown08;
|
||||||
|
|
||||||
|
int32_t entryCount;
|
||||||
|
uint32_t unknown14;
|
||||||
|
int32_t modelFileOffset;
|
||||||
|
vec3 unknownFloat3;
|
||||||
|
vec3 unknownFloat3_2;
|
||||||
|
int32_t stateOffset;
|
||||||
|
int32_t modelFileOffset2;
|
||||||
|
uint32_t unknown3;
|
||||||
|
float unknown4;
|
||||||
|
int32_t nameOffset2;
|
||||||
|
vec3 unknownFloat3_3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SGB_GROUP1C_ENTRY
|
||||||
|
{
|
||||||
|
uint32_t unk;
|
||||||
|
uint32_t unk2;
|
||||||
|
int32_t nameOffset;
|
||||||
|
uint32_t index;
|
||||||
|
uint32_t unk3;
|
||||||
|
int32_t modelFileOffset;
|
||||||
|
};
|
||||||
|
|
||||||
struct SGB_GROUP_ENTRY
|
struct SGB_GROUP_ENTRY
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -113,8 +140,9 @@ struct SGB_MODEL_ENTRY :
|
||||||
std::string modelFileName;
|
std::string modelFileName;
|
||||||
std::string collisionFileName;
|
std::string collisionFileName;
|
||||||
|
|
||||||
SGB_MODEL_ENTRY( char* buf, uint32_t offset )
|
SGB_MODEL_ENTRY( char* buf, uint32_t offset, SgbGroupEntryType type )
|
||||||
{
|
{
|
||||||
|
this->type = type;
|
||||||
header = *reinterpret_cast< SGB_MODEL_HEADER* >( buf + offset );
|
header = *reinterpret_cast< SGB_MODEL_HEADER* >( 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 + header.modelFileOffset );
|
||||||
|
@ -143,9 +171,9 @@ struct SGB_GROUP
|
||||||
if( entryOffset > fileSize )
|
if( entryOffset > fileSize )
|
||||||
throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" );
|
throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" );
|
||||||
auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset );
|
auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset );
|
||||||
if( type == SgbGroupEntryType::Model && !ignoreModels )
|
if( type == SgbGroupEntryType::Model || type == SgbGroupEntryType::Gimmick )
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset ) );
|
entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset, ( SgbGroupEntryType )type ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -249,5 +277,4 @@ struct SGB_FILE
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // !_SGB_H
|
#endif // !_SGB_H
|
|
@ -26,3 +26,4 @@ add_subdirectory( "pcb_reader" )
|
||||||
add_subdirectory( "nav_export" )
|
add_subdirectory( "nav_export" )
|
||||||
add_subdirectory( "event_object_parser" )
|
add_subdirectory( "event_object_parser" )
|
||||||
add_subdirectory( "action_parse" )
|
add_subdirectory( "action_parse" )
|
||||||
|
add_subdirectory( "questbattle_bruteforce" )
|
|
@ -1,404 +0,0 @@
|
||||||
#ifndef _LGB_H
|
|
||||||
#define _LGB_H
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <memory>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "matrix4.h"
|
|
||||||
#include "vec3.h"
|
|
||||||
#include "sgb.h"
|
|
||||||
|
|
||||||
// garbage to skip model loading
|
|
||||||
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_HEADER;
|
|
||||||
struct LGB_GROUP;
|
|
||||||
struct LGB_GROUP_HEADER;
|
|
||||||
|
|
||||||
enum class LgbEntryType :
|
|
||||||
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:
|
|
||||||
char* m_buf;
|
|
||||||
uint32_t m_offset;
|
|
||||||
LGB_ENTRY_HEADER header;
|
|
||||||
|
|
||||||
LGB_ENTRY()
|
|
||||||
{
|
|
||||||
m_buf = nullptr;
|
|
||||||
m_offset = 0;
|
|
||||||
memset( &header, 0, sizeof( header ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
LGB_ENTRY( char* buf, uint32_t offset )
|
|
||||||
{
|
|
||||||
m_buf = buf;
|
|
||||||
m_offset = offset;
|
|
||||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
|
||||||
};
|
|
||||||
|
|
||||||
const LgbEntryType getType() const
|
|
||||||
{
|
|
||||||
return header.type;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~LGB_ENTRY()
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct LGB_BGPARTS_HEADER :
|
|
||||||
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:
|
|
||||||
LGB_BGPARTS_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
std::string modelFileName;
|
|
||||||
std::string collisionFileName;
|
|
||||||
|
|
||||||
LGB_BGPARTS_ENTRY()
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
|
||||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_GIMMICK_HEADER :
|
|
||||||
public LGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
uint32_t gimmickFileOffset;
|
|
||||||
char unknownBytes[100];
|
|
||||||
};
|
|
||||||
|
|
||||||
class LGB_GIMMICK_ENTRY :
|
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LGB_GIMMICK_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
std::string gimmickFileName;
|
|
||||||
|
|
||||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
|
||||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_ENPC_HEADER :
|
|
||||||
public LGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
uint32_t enpcId;
|
|
||||||
uint8_t unknown1[0x24];
|
|
||||||
};
|
|
||||||
|
|
||||||
class LGB_ENPC_ENTRY :
|
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LGB_ENPC_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_EOBJ_HEADER :
|
|
||||||
public LGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
uint32_t eobjId;
|
|
||||||
uint32_t levelHierachyId;
|
|
||||||
uint8_t unknown1[0xC];
|
|
||||||
};
|
|
||||||
|
|
||||||
class LGB_EOBJ_ENTRY :
|
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LGB_EOBJ_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) :
|
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset );
|
|
||||||
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_MAPRANGE_HEADER :
|
|
||||||
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, 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:
|
|
||||||
LGB_MAPRANGE_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_POPRANGE_ENTRY :
|
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LGB_MAPRANGE_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
LGB_POPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_GROUP_HEADER
|
|
||||||
{
|
|
||||||
uint32_t unknown;
|
|
||||||
int32_t groupNameOffset;
|
|
||||||
int32_t entriesOffset;
|
|
||||||
int32_t entryCount;
|
|
||||||
uint32_t unknown2;
|
|
||||||
uint32_t unknown3;
|
|
||||||
uint32_t unknown4;
|
|
||||||
uint32_t unknown5;
|
|
||||||
uint32_t unknown6;
|
|
||||||
uint32_t unknown7;
|
|
||||||
uint32_t unknown8;
|
|
||||||
uint32_t unknown9;
|
|
||||||
uint32_t unknown10;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_GROUP
|
|
||||||
{
|
|
||||||
LGB_FILE* parent;
|
|
||||||
LGB_GROUP_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
std::vector< std::shared_ptr< LGB_ENTRY > > entries;
|
|
||||||
|
|
||||||
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
|
|
||||||
{
|
|
||||||
parent = parentStruct;
|
|
||||||
header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset );
|
|
||||||
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;
|
|
||||||
for( auto i = 0; i < header.entryCount; ++i )
|
|
||||||
{
|
|
||||||
const auto entryOffset = entriesOffset + *reinterpret_cast< int32_t* >( buf + ( entriesOffset + i * 4 ) );
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const auto type = *reinterpret_cast<LgbEntryType*>( buf + entryOffset );
|
|
||||||
// garbage to skip model loading
|
|
||||||
if( type == LgbEntryType::PopRange )
|
|
||||||
{
|
|
||||||
entries.push_back( std::make_shared< LGB_POPRANGE_ENTRY >( buf, entryOffset ) );
|
|
||||||
}
|
|
||||||
else if( type == LgbEntryType::MapRange )
|
|
||||||
{
|
|
||||||
entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) );
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entries[i] = nullptr;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( std::exception& e )
|
|
||||||
{
|
|
||||||
std::cout << name << " " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_FILE_HEADER
|
|
||||||
{
|
|
||||||
char magic[4]; // LGB 1
|
|
||||||
uint32_t fileSize;
|
|
||||||
uint32_t unknown;
|
|
||||||
char magic2[4]; // LGP1
|
|
||||||
uint32_t unknown2;
|
|
||||||
uint32_t unknown3;
|
|
||||||
uint32_t unknown4;
|
|
||||||
uint32_t unknown5;
|
|
||||||
int32_t groupCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LGB_FILE
|
|
||||||
{
|
|
||||||
LGB_FILE_HEADER header;
|
|
||||||
std::vector< LGB_GROUP > groups;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
LGB_FILE( char* buf, const std::string& name )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast< LGB_FILE_HEADER* >( buf );
|
|
||||||
if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 )
|
|
||||||
throw std::runtime_error( "Invalid LGB file!" );
|
|
||||||
|
|
||||||
//groups.resize(header.groupCount);
|
|
||||||
|
|
||||||
constexpr auto baseOffset = sizeof( header );
|
|
||||||
for( auto i = 0; i < header.groupCount; ++i )
|
|
||||||
{
|
|
||||||
const auto groupOffset = baseOffset + *reinterpret_cast< int32_t* >( buf + ( baseOffset + i * 4 ) );
|
|
||||||
const auto group = LGB_GROUP( buf, this, groupOffset );
|
|
||||||
groups.push_back( group );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
#if __cplusplus >= 201703L
|
|
||||||
#include <experimental/filesystem>
|
|
||||||
std::map<std::string, LGB_FILE> getLgbFiles( const std::string& dir )
|
|
||||||
{
|
|
||||||
namespace fs = std::experimental::filesystem;
|
|
||||||
std::map<std::string, LGB_FILE> fileMap;
|
|
||||||
for( const auto& path : fs::recursive_directory_iterator( dir ) )
|
|
||||||
{
|
|
||||||
if( path.path().extension() == ".lgb" )
|
|
||||||
{
|
|
||||||
const auto& strPath = path.path().string();
|
|
||||||
auto f = fopen( strPath.c_str(), "rb" );
|
|
||||||
fseek( f, 0, SEEK_END );
|
|
||||||
const auto size = ftell( f );
|
|
||||||
std::vector<char> bytes( size );
|
|
||||||
rewind( f );
|
|
||||||
fread( bytes.data(), 1, size, f );
|
|
||||||
fclose( f );
|
|
||||||
try
|
|
||||||
{
|
|
||||||
LGB_FILE lgbFile( bytes.data() );
|
|
||||||
fileMap.insert( std::make_pair( strPath, lgbFile ) );
|
|
||||||
}
|
|
||||||
catch( std::exception& e )
|
|
||||||
{
|
|
||||||
std::cout << "Unable to load " << strPath << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fileMap;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
#endif
|
|
|
@ -13,9 +13,9 @@
|
||||||
|
|
||||||
#include <Util/Util.h>
|
#include <Util/Util.h>
|
||||||
|
|
||||||
#include "pcb.h"
|
#include <datReader/DatCategories/bg/pcb.h>
|
||||||
#include "lgb.h"
|
#include <datReader/DatCategories/bg/lgb.h>
|
||||||
#include "sgb.h"
|
#include <datReader/DatCategories/bg/sgb.h>
|
||||||
#include "tex.h"
|
#include "tex.h"
|
||||||
#include "tex_decode.h"
|
#include "tex_decode.h"
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ std::string zoneName;
|
||||||
|
|
||||||
std::set< std::string > zoneDumpList;
|
std::set< std::string > zoneDumpList;
|
||||||
|
|
||||||
xiv::dat::GameData* data1 = nullptr;
|
xiv::dat::GameData* gameData = nullptr;
|
||||||
xiv::exd::ExdData* eData = nullptr;
|
xiv::exd::ExdData* eData = nullptr;
|
||||||
|
|
||||||
void readFileToBuffer( const std::string& path, std::vector< char >& buf );
|
void readFileToBuffer( const std::string& path, std::vector< char >& buf );
|
||||||
|
@ -135,8 +135,8 @@ struct face
|
||||||
// init
|
// init
|
||||||
void initExd( const std::string& gamePath )
|
void initExd( const std::string& gamePath )
|
||||||
{
|
{
|
||||||
data1 = data1 ? data1 : new xiv::dat::GameData( gamePath );
|
gameData = gameData ? gameData : new xiv::dat::GameData( gamePath );
|
||||||
eData = eData ? eData : new xiv::exd::ExdData( *data1 );
|
eData = eData ? eData : new xiv::exd::ExdData( *gameData );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string zoneNameToPath( const std::string& name )
|
std::string zoneNameToPath( const std::string& name )
|
||||||
|
@ -338,13 +338,13 @@ int main( int argc, char* argv[] )
|
||||||
std::vector< char > section1;
|
std::vector< char > section1;
|
||||||
std::vector< char > section2;
|
std::vector< char > section2;
|
||||||
|
|
||||||
auto test_file = data1->getFile( bgLgbPath );
|
auto test_file = gameData->getFile( bgLgbPath );
|
||||||
section = test_file->access_data_sections().at( 0 );
|
section = test_file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
auto planmap_file = data1->getFile( planmapLgbPath );
|
auto planmap_file = gameData->getFile( planmapLgbPath );
|
||||||
section2 = planmap_file->access_data_sections().at( 0 );
|
section2 = planmap_file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
auto test_file1 = data1->getFile( listPcbPath );
|
auto test_file1 = gameData->getFile( listPcbPath );
|
||||||
section1 = test_file1->access_data_sections().at( 0 );
|
section1 = test_file1->access_data_sections().at( 0 );
|
||||||
|
|
||||||
std::vector< std::string > stringList;
|
std::vector< std::string > stringList;
|
||||||
|
@ -467,7 +467,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
if( eData )
|
if( eData )
|
||||||
delete eData;
|
delete eData;
|
||||||
if( data1 )
|
if( gameData )
|
||||||
delete data1;
|
delete gameData;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,222 +0,0 @@
|
||||||
#ifndef _SGB_H
|
|
||||||
#define _SGB_H
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <memory>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "vec3.h"
|
|
||||||
|
|
||||||
// garbage to skip model loading
|
|
||||||
extern bool ignoreModels;
|
|
||||||
|
|
||||||
//
|
|
||||||
// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs
|
|
||||||
|
|
||||||
struct SGB_FILE;
|
|
||||||
struct SGB_HEADER;
|
|
||||||
struct SGB_MODEL_ENTRY;
|
|
||||||
struct SGB_MODEL_HEADER;
|
|
||||||
struct SGB_GROUP;
|
|
||||||
struct SGB_GROUP_HEADER;
|
|
||||||
|
|
||||||
|
|
||||||
enum SgbDataType :
|
|
||||||
uint32_t
|
|
||||||
{
|
|
||||||
Unknown0008 = 0x0008,
|
|
||||||
Group = 0x0100,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SgbGroupEntryType :
|
|
||||||
uint32_t
|
|
||||||
{
|
|
||||||
Model = 0x01,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_GROUP_HEADER
|
|
||||||
{
|
|
||||||
SgbDataType type;
|
|
||||||
int32_t nameOffset;
|
|
||||||
uint32_t unknown08;
|
|
||||||
uint32_t unknown0C;
|
|
||||||
|
|
||||||
uint32_t unknown10;
|
|
||||||
uint32_t unknown14;
|
|
||||||
uint32_t unknown18;
|
|
||||||
uint32_t unknown1C;
|
|
||||||
|
|
||||||
int32_t entryCount;
|
|
||||||
uint32_t unknown24;
|
|
||||||
uint32_t unknown28;
|
|
||||||
uint32_t unknown2C;
|
|
||||||
|
|
||||||
uint32_t unknown30;
|
|
||||||
uint32_t unknown34;
|
|
||||||
uint32_t unknown38;
|
|
||||||
uint32_t unknown3C;
|
|
||||||
|
|
||||||
uint32_t unknown40;
|
|
||||||
uint32_t unknown44;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_GROUP_ENTRY
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
char* m_buf;
|
|
||||||
uint32_t m_offset;
|
|
||||||
|
|
||||||
SGB_GROUP_ENTRY()
|
|
||||||
{
|
|
||||||
m_buf = nullptr;
|
|
||||||
m_offset = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
SGB_GROUP_ENTRY( char* buf, uint32_t offset )
|
|
||||||
{
|
|
||||||
m_buf = buf;
|
|
||||||
m_offset = offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~SGB_GROUP_ENTRY()
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
SgbGroupEntryType type;
|
|
||||||
uint32_t unknown2;
|
|
||||||
int32_t nameOffset;
|
|
||||||
vec3 translation;
|
|
||||||
vec3 rotation;
|
|
||||||
vec3 scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_MODEL_HEADER :
|
|
||||||
public SGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
int32_t modelFileOffset;
|
|
||||||
int32_t collisionFileOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_MODEL_ENTRY :
|
|
||||||
public SGB_GROUP_ENTRY
|
|
||||||
{
|
|
||||||
SGB_MODEL_HEADER header;
|
|
||||||
SgbGroupEntryType type;
|
|
||||||
std::string name;
|
|
||||||
std::string modelFileName;
|
|
||||||
std::string collisionFileName;
|
|
||||||
|
|
||||||
SGB_MODEL_ENTRY( char* buf, uint32_t offset )
|
|
||||||
{
|
|
||||||
header = *reinterpret_cast< SGB_MODEL_HEADER* >( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
|
||||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_GROUP
|
|
||||||
{
|
|
||||||
SGB_GROUP_HEADER header;
|
|
||||||
std::string name;
|
|
||||||
SGB_FILE* parent;
|
|
||||||
std::vector< std::shared_ptr< SGB_GROUP_ENTRY > > entries;
|
|
||||||
|
|
||||||
SGB_GROUP( char* buf, SGB_FILE* file, uint32_t fileSize, uint32_t offset )
|
|
||||||
{
|
|
||||||
parent = file;
|
|
||||||
header = *reinterpret_cast< SGB_GROUP_HEADER* >( buf + offset );
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
|
||||||
|
|
||||||
auto entriesOffset = offset + sizeof( header );
|
|
||||||
|
|
||||||
for( auto i = 0; i < header.entryCount; ++i )
|
|
||||||
{
|
|
||||||
auto entryOffset = entriesOffset + *reinterpret_cast< uint32_t* >( buf + ( entriesOffset + ( i * 4 ) ) );
|
|
||||||
if( entryOffset > fileSize )
|
|
||||||
throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" );
|
|
||||||
auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset );
|
|
||||||
if( type == SgbGroupEntryType::Model && !ignoreModels )
|
|
||||||
{
|
|
||||||
entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// std::cout << "\t\tUnknown SGB entry! Group: " << name << " type: " << type << " index: " << i << " entryOffset: " << entryOffset << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_HEADER
|
|
||||||
{
|
|
||||||
char magic[4]; // SGB1
|
|
||||||
uint32_t fileSize;
|
|
||||||
uint32_t unknown1;
|
|
||||||
char magic2[4]; // SCN1
|
|
||||||
|
|
||||||
uint32_t unknown10;
|
|
||||||
int32_t sharedOffset;
|
|
||||||
uint32_t unknown18;
|
|
||||||
int32_t offset1C;
|
|
||||||
|
|
||||||
uint32_t unknown20;
|
|
||||||
uint32_t unknown24;
|
|
||||||
uint32_t unknown28;
|
|
||||||
uint32_t unknown2C;
|
|
||||||
|
|
||||||
uint32_t unknown30;
|
|
||||||
uint32_t unknown34;
|
|
||||||
uint32_t unknown38;
|
|
||||||
uint32_t unknown3C;
|
|
||||||
|
|
||||||
uint32_t unknown40;
|
|
||||||
uint32_t unknown44;
|
|
||||||
uint32_t unknown48;
|
|
||||||
uint32_t unknown4C;
|
|
||||||
|
|
||||||
uint32_t unknown50;
|
|
||||||
uint32_t unknown54;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SGB_FILE
|
|
||||||
{
|
|
||||||
SGB_HEADER header;
|
|
||||||
std::vector< SGB_GROUP > entries;
|
|
||||||
|
|
||||||
SGB_FILE()
|
|
||||||
{
|
|
||||||
memset( &header, 0, sizeof( header ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
SGB_FILE( char* buf )
|
|
||||||
{
|
|
||||||
constexpr int baseOffset = 0x14;
|
|
||||||
header = *reinterpret_cast< SGB_HEADER* >( buf );
|
|
||||||
|
|
||||||
if( strncmp( &header.magic[ 0 ], "SGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "SCN1", 4 ) != 0 )
|
|
||||||
throw std::runtime_error( "Unable to load SGB File!" );
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto group = SGB_GROUP( buf, this, header.fileSize, baseOffset + header.sharedOffset );
|
|
||||||
entries.push_back( group );
|
|
||||||
auto group2 = SGB_GROUP( buf, this, header.fileSize, baseOffset + header.offset1C );
|
|
||||||
entries.push_back( group2 );
|
|
||||||
}
|
|
||||||
catch( std::exception& e )
|
|
||||||
{
|
|
||||||
std::cout << e.what() << "\n";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !_SGB_H
|
|
|
@ -1,60 +0,0 @@
|
||||||
#ifndef _VEC3_H
|
|
||||||
#define _VEC3_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include "matrix4.h"
|
|
||||||
|
|
||||||
struct vec3
|
|
||||||
{
|
|
||||||
float x, y, z;
|
|
||||||
|
|
||||||
vec3()
|
|
||||||
{
|
|
||||||
x = 0.0f;
|
|
||||||
y = 0.0f;
|
|
||||||
z = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3( float x, float y, float z )
|
|
||||||
{
|
|
||||||
this->x = x;
|
|
||||||
this->y = y;
|
|
||||||
this->z = z;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
static vec3 operator*( const vec3& lhs, const matrix4& rhs )
|
|
||||||
{
|
|
||||||
vec3 ret;
|
|
||||||
ret.x = rhs( 0, 0 ) * lhs.x + rhs( 0, 1 ) * lhs.y + rhs( 0, 2 ) * lhs.z;
|
|
||||||
ret.y = rhs( 1, 0 ) * lhs.x + rhs( 1, 1 ) * lhs.y + rhs( 1, 2 ) * lhs.z;
|
|
||||||
ret.z = rhs( 2, 0 ) * lhs.x + rhs( 2, 1 ) * lhs.y + rhs( 2, 2 ) * lhs.z;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
static vec3 operator*( const vec3& lhs, float scalar )
|
|
||||||
{
|
|
||||||
return { lhs.x * scalar, lhs.y * scalar, lhs.z * scalar };
|
|
||||||
}
|
|
||||||
|
|
||||||
static vec3 operator+( const vec3& lhs, const vec3& rhs )
|
|
||||||
{
|
|
||||||
return { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z };
|
|
||||||
}
|
|
||||||
|
|
||||||
static vec3 operator-( const vec3& lhs, const vec3& rhs )
|
|
||||||
{
|
|
||||||
return { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z };
|
|
||||||
}
|
|
||||||
|
|
||||||
static vec3 operator/( const vec3& lhs, const vec3& rhs )
|
|
||||||
{
|
|
||||||
return { lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z };
|
|
||||||
}
|
|
||||||
|
|
||||||
static vec3 operator/( const vec3& lhs, float scalar )
|
|
||||||
{
|
|
||||||
return { lhs.x / scalar, lhs.y / scalar, lhs.z / scalar };
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include <Util/Util.h>
|
#include <Util/Util.h>
|
||||||
#include <Util/CrashHandler.h>
|
#include <Util/CrashHandler.h>
|
||||||
|
|
||||||
#include "pcb.h"
|
#include <datReader/DatCategories/bg/pcb.h>
|
||||||
#include "lgb.h"
|
#include <datReader/DatCategories/bg/lgb.h>
|
||||||
#include "sgb.h"
|
#include <datReader/DatCategories/bg/sgb.h>
|
||||||
|
|
||||||
#include <Exd/ExdDataGenerated.h>
|
#include <Exd/ExdDataGenerated.h>
|
||||||
#include <Logging/Logger.h>
|
#include <Logging/Logger.h>
|
||||||
|
@ -37,7 +37,7 @@ namespace fs = std::experimental::filesystem;
|
||||||
|
|
||||||
// garbage to ignore models
|
// garbage to ignore models
|
||||||
bool ignoreModels = false;
|
bool ignoreModels = false;
|
||||||
std::string gamePath( "/home/mordred/sqpack" );
|
std::string gamePath( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" );
|
||||||
//std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
|
//std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
|
||||||
std::unordered_map< uint32_t, std::string > eobjNameMap;
|
std::unordered_map< uint32_t, std::string > eobjNameMap;
|
||||||
|
|
||||||
|
@ -241,9 +241,14 @@ int main( int argc, char* argv[] )
|
||||||
std::string listPcbPath( zonePath + "/collision/list.pcb" );
|
std::string listPcbPath( zonePath + "/collision/list.pcb" );
|
||||||
std::string bgLgbPath( zonePath + "/level/bg.lgb" );
|
std::string bgLgbPath( zonePath + "/level/bg.lgb" );
|
||||||
std::string planmapLgbPath( zonePath + "/level/planmap.lgb" );
|
std::string planmapLgbPath( zonePath + "/level/planmap.lgb" );
|
||||||
|
std::string planeventLgbPath( zonePath + "/level/planevent.lgb" );
|
||||||
std::string collisionFilePath( zonePath + "/collision/" );
|
std::string collisionFilePath( zonePath + "/collision/" );
|
||||||
|
std::string plannerFilePath( zonePath + "/level/planner.lgb" );
|
||||||
|
std::string lcbFilePath( zonePath + "/level/" + zoneName + ".lcb" );
|
||||||
|
std::string svbFilePath( zonePath + "/level/" + zoneName + ".svb" );
|
||||||
std::vector< char > section;
|
std::vector< char > section;
|
||||||
std::vector< char > section2;
|
std::vector< char > section2;
|
||||||
|
std::vector< char > section3;
|
||||||
|
|
||||||
const xiv::dat::Cat& test = data1->getCategory( "bg" );
|
const xiv::dat::Cat& test = data1->getCategory( "bg" );
|
||||||
|
|
||||||
|
@ -254,6 +259,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
LGB_FILE bgLgb( §ion[ 0 ], "bg" );
|
LGB_FILE bgLgb( §ion[ 0 ], "bg" );
|
||||||
LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" );
|
LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" );
|
||||||
|
LGB_FILE planeventLgb( §ion3[ 0 ], "planevent" );
|
||||||
|
|
||||||
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
||||||
|
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
#ifndef _MATRIX4_H
|
|
||||||
#define _MATRIX4_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
// https://github.com/jpd002/Play--Framework/tree/master/include/math
|
|
||||||
struct matrix4
|
|
||||||
{
|
|
||||||
// 4x4
|
|
||||||
float grid[16];
|
|
||||||
|
|
||||||
matrix4()
|
|
||||||
{
|
|
||||||
memset( &grid[ 0 ], 0, sizeof( grid ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
float operator()( int row, int col ) const
|
|
||||||
{
|
|
||||||
return grid[ ( row * 4 ) + col ];
|
|
||||||
}
|
|
||||||
|
|
||||||
float& operator()( int row, int col )
|
|
||||||
{
|
|
||||||
return grid[ ( row * 4 ) + col ];
|
|
||||||
}
|
|
||||||
|
|
||||||
static matrix4 rotateX( float angle )
|
|
||||||
{
|
|
||||||
matrix4 ret = matrix4();
|
|
||||||
ret( 0, 0 ) = 1.000000000f;
|
|
||||||
ret( 1, 1 ) = cos( angle );
|
|
||||||
ret( 1, 2 ) = -sin( angle );
|
|
||||||
ret( 2, 1 ) = sin( angle );
|
|
||||||
ret( 2, 2 ) = cos( angle );
|
|
||||||
ret( 3, 3 ) = 1.000000000f;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static matrix4 rotateY( float angle )
|
|
||||||
{
|
|
||||||
matrix4 ret = matrix4();
|
|
||||||
ret( 0, 0 ) = cos( angle );
|
|
||||||
ret( 0, 2 ) = sin( angle );
|
|
||||||
ret( 1, 1 ) = 1.000000000f;
|
|
||||||
ret( 2, 0 ) = -sin( angle );
|
|
||||||
ret( 2, 2 ) = cos( angle );
|
|
||||||
ret( 3, 3 ) = 1.000000000f;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static matrix4 rotateZ( float angle )
|
|
||||||
{
|
|
||||||
matrix4 ret = matrix4();
|
|
||||||
ret( 0, 0 ) = cos( angle );
|
|
||||||
ret( 0, 1 ) = -sin( angle );
|
|
||||||
ret( 1, 0 ) = sin( angle );
|
|
||||||
ret( 1, 1 ) = cos( angle );
|
|
||||||
ret( 2, 2 ) = 1.000000000f;
|
|
||||||
ret( 3, 3 ) = 1.000000000f;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static matrix4 scale( float x, float y, float z )
|
|
||||||
{
|
|
||||||
matrix4 ret = matrix4();
|
|
||||||
ret( 0, 0 ) = x;
|
|
||||||
ret( 1, 1 ) = y;
|
|
||||||
ret( 2, 2 ) = z;
|
|
||||||
ret( 3, 3 ) = 1;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static matrix4 translate( float x, float y, float z )
|
|
||||||
{
|
|
||||||
matrix4 ret = matrix4();
|
|
||||||
ret( 0, 0 ) = 1;
|
|
||||||
ret( 1, 1 ) = 1;
|
|
||||||
ret( 2, 2 ) = 1;
|
|
||||||
ret( 3, 3 ) = 1;
|
|
||||||
|
|
||||||
ret( 3, 0 ) = x;
|
|
||||||
ret( 3, 1 ) = y;
|
|
||||||
ret( 3, 2 ) = z;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix4 operator*( const matrix4& rhs ) const
|
|
||||||
{
|
|
||||||
matrix4 ret;
|
|
||||||
for( unsigned int i = 0; i < 4; i++ )
|
|
||||||
{
|
|
||||||
ret( i, 0 ) =
|
|
||||||
( *this )( i, 0 ) * rhs( 0, 0 ) + ( *this )( i, 1 ) * rhs( 1, 0 ) + ( *this )( i, 2 ) * rhs( 2, 0 ) +
|
|
||||||
( *this )( i, 3 ) * rhs( 3, 0 );
|
|
||||||
ret( i, 1 ) =
|
|
||||||
( *this )( i, 0 ) * rhs( 0, 1 ) + ( *this )( i, 1 ) * rhs( 1, 1 ) + ( *this )( i, 2 ) * rhs( 2, 1 ) +
|
|
||||||
( *this )( i, 3 ) * rhs( 3, 1 );
|
|
||||||
ret( i, 2 ) =
|
|
||||||
( *this )( i, 0 ) * rhs( 0, 2 ) + ( *this )( i, 1 ) * rhs( 1, 2 ) + ( *this )( i, 2 ) * rhs( 2, 2 ) +
|
|
||||||
( *this )( i, 3 ) * rhs( 3, 2 );
|
|
||||||
ret( i, 3 ) =
|
|
||||||
( *this )( i, 0 ) * rhs( 0, 3 ) + ( *this )( i, 1 ) * rhs( 1, 3 ) + ( *this )( i, 2 ) * rhs( 2, 3 ) +
|
|
||||||
( *this )( i, 3 ) * rhs( 3, 3 );
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,92 +0,0 @@
|
||||||
#ifndef _PCB_H
|
|
||||||
#define _PCB_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct PCB_HEADER
|
|
||||||
{
|
|
||||||
uint32_t unknown_1;
|
|
||||||
uint32_t unknown_2;
|
|
||||||
uint32_t num_entries; // count starts at 0
|
|
||||||
uint32_t total_indices;
|
|
||||||
uint64_t padding;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_BLOCK_HEADER
|
|
||||||
{
|
|
||||||
uint32_t type; // 0 for entry, 0x30 for group
|
|
||||||
uint32_t group_size; // when group size in bytes for the group block
|
|
||||||
// bounding box
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float x1;
|
|
||||||
float y1;
|
|
||||||
float z1;
|
|
||||||
// number of vertices packed into 16 bit
|
|
||||||
uint16_t num_v16;
|
|
||||||
// number of indices
|
|
||||||
uint16_t num_indices;
|
|
||||||
// number of normal floar vertices
|
|
||||||
uint32_t num_vertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_VERTEXDATA
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_INDEXDATA
|
|
||||||
{
|
|
||||||
uint8_t index[3];
|
|
||||||
uint8_t unknown[3];
|
|
||||||
uint8_t unknown1[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_VERTEXDATAI16
|
|
||||||
{
|
|
||||||
uint16_t x;
|
|
||||||
uint16_t y;
|
|
||||||
uint16_t z;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_BLOCK_DATA
|
|
||||||
{
|
|
||||||
std::vector< PCB_VERTEXDATA > vertices;
|
|
||||||
std::vector< PCB_VERTEXDATAI16 > vertices_i16;
|
|
||||||
std::vector< PCB_INDEXDATA > indices;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_BLOCK_ENTRY
|
|
||||||
{
|
|
||||||
PCB_BLOCK_HEADER header;
|
|
||||||
PCB_BLOCK_DATA data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_FILE
|
|
||||||
{
|
|
||||||
PCB_HEADER header;
|
|
||||||
std::vector< PCB_BLOCK_ENTRY > entries;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_LIST_ENTRY
|
|
||||||
{
|
|
||||||
uint32_t id;
|
|
||||||
float x, y, z, x2, y2, z2, rot;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_LIST_BASE_ENTRY
|
|
||||||
{
|
|
||||||
float x, y, z, x2, y2, z2, rot;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PCB_LIST_FILE
|
|
||||||
{
|
|
||||||
uint32_t count;
|
|
||||||
PCB_LIST_BASE_ENTRY entry;
|
|
||||||
std::vector< PCB_LIST_ENTRY > entries;
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -16,18 +16,97 @@
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
#include <datReader/DatCategories/bg/pcb.h>
|
||||||
|
#include <datReader/DatCategories/bg/lgb.h>
|
||||||
|
#include <datReader/DatCategories/bg/sgb.h>
|
||||||
|
|
||||||
#include <Util/CrashHandler.h>
|
#include <Util/CrashHandler.h>
|
||||||
|
|
||||||
|
#include <experimental/filesystem>
|
||||||
|
|
||||||
Sapphire::Common::Util::CrashHandler crashHandler;
|
Sapphire::Common::Util::CrashHandler crashHandler;
|
||||||
|
|
||||||
Sapphire::Data::ExdDataGenerated g_exdData;
|
Sapphire::Data::ExdDataGenerated g_exdData;
|
||||||
|
xiv::dat::GameData* gameData = nullptr;
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
namespace fs = std::experimental::filesystem;
|
||||||
|
|
||||||
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
|
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
|
||||||
const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" );
|
const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" );
|
||||||
|
|
||||||
int main()
|
void exportFile( const std::string& path )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto file = gameData->getFile( path );
|
||||||
|
|
||||||
|
if( !file )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto p = fs::path( path );
|
||||||
|
fs::create_directories( p.parent_path() );
|
||||||
|
file->exportToFile( p );
|
||||||
|
}
|
||||||
|
catch( const std::exception& ex )
|
||||||
|
{
|
||||||
|
Logger::error( "Failed to export file {0}, error: {1}", path, ex.what() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string getTypeString( uint32_t type )
|
||||||
|
{
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case 1: return "BgParts";
|
||||||
|
case 3: return "Light";
|
||||||
|
case 4: return "Vfx";
|
||||||
|
case 5: return "PositionMarker";
|
||||||
|
case 6: return "Gimmick/SharedGroup6";
|
||||||
|
case 7: return "Sound";
|
||||||
|
case 8: return "EventNpc";
|
||||||
|
case 9: return "BattleNpc";
|
||||||
|
case 12: return "Aetheryte";
|
||||||
|
case 13: return "EnvSpace";
|
||||||
|
case 14: return "Gathering";
|
||||||
|
case 15: return "SharedGroup15";
|
||||||
|
case 16: return "Treasure";
|
||||||
|
case 39: return "Weapon";
|
||||||
|
case 40: return "PopRange";
|
||||||
|
case 41: return "ExitRange";
|
||||||
|
case 43: return "MapRange";
|
||||||
|
case 44: return "NaviMeshRange";
|
||||||
|
case 45: return "EventObject";
|
||||||
|
case 47: return "EnvLocation";
|
||||||
|
case 49: return "EventRange";
|
||||||
|
case 51: return "QuestMarker";
|
||||||
|
case 57: return "CollisionBox";
|
||||||
|
case 58: return "DoorRange";
|
||||||
|
case 59: return "LineVfx";
|
||||||
|
case 65: return "ClientPath";
|
||||||
|
case 66: return "ServerPath";
|
||||||
|
case 67: return "GimmickRange";
|
||||||
|
case 68: return "TargetMarker";
|
||||||
|
case 69: return "ChairMarker";
|
||||||
|
case 70: return "ClickableRange";
|
||||||
|
case 71: return "PrefetchRange";
|
||||||
|
case 72: return "FateRange";
|
||||||
|
case 75: return "SphereCastRange";
|
||||||
|
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DupeResult
|
||||||
|
{
|
||||||
|
std::string groupName;
|
||||||
|
std::string lgb;
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
|
|
||||||
Logger::init( "struct_test" );
|
Logger::init( "struct_test" );
|
||||||
|
@ -39,14 +118,130 @@ int main()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gld = g_exdData.get< Sapphire::Data::ClassJob >( 1 );
|
gameData = new xiv::dat::GameData( datLocation );
|
||||||
if( gld )
|
|
||||||
|
if( argc > 1 )
|
||||||
{
|
{
|
||||||
Logger::info( "got {0}", gld->name );
|
while( argc-- > 1 )
|
||||||
|
{
|
||||||
|
Logger::info( "Exporting file: {}", argv[ argc ] );
|
||||||
|
exportFile( argv[ argc ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::string > levelNames;
|
||||||
|
std::vector< std::string > paths;
|
||||||
|
|
||||||
|
std::vector< uint32_t > lgbGroupIds;
|
||||||
|
std::vector< DupeResult > lgbGroupDupes;
|
||||||
|
std::vector< uint32_t > foundTypes;
|
||||||
|
|
||||||
|
paths.emplace_back( "level/bg.lgb" );
|
||||||
|
paths.emplace_back( "level/planmap.lgb" );
|
||||||
|
paths.emplace_back( "level/planevent.lgb" );
|
||||||
|
paths.emplace_back( "level/planlive.lgb" );
|
||||||
|
paths.emplace_back( "level/sound.lgb" );
|
||||||
|
paths.emplace_back( "level/planner.lgb" );
|
||||||
|
|
||||||
|
auto ids = g_exdData.getTerritoryTypeIdList();
|
||||||
|
|
||||||
|
for( auto id : ids )
|
||||||
|
{
|
||||||
|
auto territoryType = g_exdData.get< Data::TerritoryType >( id );
|
||||||
|
if( !territoryType )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto bg = territoryType->bg;
|
||||||
|
bg = bg.substr( 0, bg.find( "/level/" ) );
|
||||||
|
|
||||||
|
if( bg.empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( std::find( levelNames.begin(), levelNames.end(), bg ) != levelNames.end() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
levelNames.push_back( bg );
|
||||||
|
|
||||||
|
Logger::info( "LGB groups for: {}", bg );
|
||||||
|
|
||||||
|
for( const auto& path : paths )
|
||||||
|
{
|
||||||
|
auto filePath = fmt::format( "bg/{}/{}", bg, path );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto file = gameData->getFile( filePath );
|
||||||
|
auto data = file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
|
LGB_FILE lgb( &data[ 0 ], "wtf" );
|
||||||
|
|
||||||
|
Logger::info(" {} groups: {}", path, lgb.header.groupCount );
|
||||||
|
|
||||||
|
for( const auto& group : lgb.groups )
|
||||||
|
{
|
||||||
|
std::vector< uint32_t > types;
|
||||||
|
|
||||||
|
for( const auto& entry : group.entries )
|
||||||
|
{
|
||||||
|
types.emplace_back( static_cast< uint32_t >( entry->getType() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string typeStr;
|
||||||
|
|
||||||
|
std::sort( types.begin(), types.end() );
|
||||||
|
auto end = std::unique( types.begin(), types.end() );
|
||||||
|
types.erase( end, types.end() );
|
||||||
|
|
||||||
|
foundTypes.insert( foundTypes.end(), types.begin(), types.end() );
|
||||||
|
|
||||||
|
for( auto type : types )
|
||||||
|
{
|
||||||
|
typeStr.append( " " + std::to_string( type ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info( " - {:<7} {:<25} groups: {:<3} types:{}",
|
||||||
|
group.header.id, group.name, group.header.entryCount, typeStr );
|
||||||
|
|
||||||
|
if( std::find( lgbGroupIds.begin(), lgbGroupIds.end(), group.header.id ) == lgbGroupIds.end() )
|
||||||
|
{
|
||||||
|
lgbGroupIds.emplace_back( group.header.id );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Logger::warn( "failed to get classjob {}", 1 );
|
{
|
||||||
|
lgbGroupDupes.push_back( { group.name, filePath, group.header.id } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger::info( "" );
|
||||||
|
}
|
||||||
|
catch( const std::exception& ex )
|
||||||
|
{
|
||||||
|
Logger::warn( "Failed on file {}, error: {}", path, ex.what() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !lgbGroupDupes.empty() )
|
||||||
|
{
|
||||||
|
Logger::info( "Found duplicate LGB group ids: " );
|
||||||
|
|
||||||
|
for( const auto& result : lgbGroupDupes )
|
||||||
|
{
|
||||||
|
Logger::info( " - id: {:<7} group: {:<30} file: {} ", result.id, result.groupName, result.lgb );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info( "Found LGB entry types:" );
|
||||||
|
|
||||||
|
std::sort( foundTypes.begin(), foundTypes.end() );
|
||||||
|
auto end = std::unique( foundTypes.begin(), foundTypes.end() );
|
||||||
|
foundTypes.erase( end, foundTypes.end() );
|
||||||
|
|
||||||
|
for( auto type : foundTypes )
|
||||||
|
{
|
||||||
|
Logger::info( " - {:<3} {}", type, getTypeString( type ) );
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ std::set< std::string > zoneDumpList;
|
||||||
std::shared_ptr< Cache > pCache;
|
std::shared_ptr< Cache > pCache;
|
||||||
std::map< uint32_t, uint16_t > eobjSgbPaths;
|
std::map< uint32_t, uint16_t > eobjSgbPaths;
|
||||||
|
|
||||||
xiv::dat::GameData* data1 = nullptr;
|
xiv::dat::GameData* gameData = nullptr;
|
||||||
xiv::exd::ExdData* eData = nullptr;
|
xiv::exd::ExdData* eData = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,9 +57,9 @@ using namespace std::chrono_literals;
|
||||||
|
|
||||||
void initExd( const std::string& gamePath )
|
void initExd( const std::string& gamePath )
|
||||||
{
|
{
|
||||||
data1 = data1 ? data1 : new xiv::dat::GameData( gamePath );
|
gameData = gameData ? gameData : new xiv::dat::GameData( gamePath );
|
||||||
eData = eData ? eData : new xiv::exd::ExdData( *data1 );
|
eData = eData ? eData : new xiv::exd::ExdData( *gameData );
|
||||||
pCache = std::make_shared< Cache >( data1 );
|
pCache = std::make_shared< Cache >( gameData );
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceAll( std::string& str, const std::string& from, const std::string& to ) {
|
void replaceAll( std::string& str, const std::string& from, const std::string& to ) {
|
||||||
|
@ -360,15 +360,15 @@ int main( int argc, char* argv[] )
|
||||||
std::vector< char > section1;
|
std::vector< char > section1;
|
||||||
std::vector< char > section2;
|
std::vector< char > section2;
|
||||||
|
|
||||||
const xiv::dat::Cat& test = data1->getCategory( "bg" );
|
const xiv::dat::Cat& test = gameData->getCategory( "bg" );
|
||||||
|
|
||||||
auto test_file = data1->getFile( bgLgbPath );
|
auto test_file = gameData->getFile( bgLgbPath );
|
||||||
section = test_file->access_data_sections().at( 0 );
|
section = test_file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
auto planmap_file = data1->getFile( planmapLgbPath );
|
auto planmap_file = gameData->getFile( planmapLgbPath );
|
||||||
section2 = planmap_file->access_data_sections().at( 0 );
|
section2 = planmap_file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
auto test_file1 = data1->getFile( listPcbPath );
|
auto test_file1 = gameData->getFile( listPcbPath );
|
||||||
section1 = test_file1->access_data_sections().at( 0 );
|
section1 = test_file1->access_data_sections().at( 0 );
|
||||||
|
|
||||||
std::vector< std::string > stringList;
|
std::vector< std::string > stringList;
|
||||||
|
@ -456,7 +456,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
if( auto pGimmick = pCache->getSgbFile( sgbPath ) )
|
if( auto pGimmick = pCache->getSgbFile( sgbPath ) )
|
||||||
{
|
{
|
||||||
for( const auto& offset1cFile : pGimmick->offset1cObjects )
|
for( const auto& offset1cFile : pGimmick->stateEntries )
|
||||||
exportSgbModel( offset1cFile, pEobj, exportedGroup, true );
|
exportSgbModel( offset1cFile, pEobj, exportedGroup, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ int main( int argc, char* argv[] )
|
||||||
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count() );
|
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count() );
|
||||||
|
|
||||||
delete eData;
|
delete eData;
|
||||||
delete data1;
|
delete gameData;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ struct SGB_FILE
|
||||||
{
|
{
|
||||||
SGB_HEADER header;
|
SGB_HEADER header;
|
||||||
std::vector< SGB_GROUP > entries;
|
std::vector< SGB_GROUP > entries;
|
||||||
std::set< std::string > offset1cObjects;
|
std::set< std::string > stateEntries;
|
||||||
|
|
||||||
SGB_FILE()
|
SGB_FILE()
|
||||||
{
|
{
|
||||||
|
@ -260,9 +260,9 @@ struct SGB_FILE
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto group = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset + header.sharedOffset );
|
auto group = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset + header.sharedOffset );
|
||||||
entries.push_back( group );
|
entries.push_back( group );
|
||||||
auto group2 = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset+ header.offset1C, true );
|
auto group2 = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset+ header.offset1C, true );
|
||||||
entries.push_back( group2 );
|
entries.push_back( group2 );
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
|
|
|
@ -44,7 +44,7 @@ std::set< std::string > zoneDumpList;
|
||||||
std::shared_ptr< Cache > pCache;
|
std::shared_ptr< Cache > pCache;
|
||||||
std::map< uint32_t, uint16_t > eobjSgbPaths;
|
std::map< uint32_t, uint16_t > eobjSgbPaths;
|
||||||
|
|
||||||
xiv::dat::GameData* data1 = nullptr;
|
xiv::dat::GameData* gameData = nullptr;
|
||||||
xiv::exd::ExdData* eData = nullptr;
|
xiv::exd::ExdData* eData = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ using namespace std::chrono_literals;
|
||||||
|
|
||||||
void initExd( const std::string& gamePath )
|
void initExd( const std::string& gamePath )
|
||||||
{
|
{
|
||||||
data1 = data1 ? data1 : new xiv::dat::GameData( gamePath );
|
gameData = gameData ? gameData : new xiv::dat::GameData( gamePath );
|
||||||
eData = eData ? eData : new xiv::exd::ExdData( *data1 );
|
eData = eData ? eData : new xiv::exd::ExdData( *gameData );
|
||||||
pCache = std::make_shared< Cache >( data1 );
|
pCache = std::make_shared< Cache >( gameData );
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceAll( std::string& str, const std::string& from, const std::string& to ) {
|
void replaceAll( std::string& str, const std::string& from, const std::string& to ) {
|
||||||
|
@ -249,15 +249,15 @@ int main( int argc, char* argv[] )
|
||||||
std::vector< char > section1;
|
std::vector< char > section1;
|
||||||
std::vector< char > section2;
|
std::vector< char > section2;
|
||||||
|
|
||||||
const xiv::dat::Cat& test = data1->getCategory( "bg" );
|
const xiv::dat::Cat& test = gameData->getCategory( "bg" );
|
||||||
|
|
||||||
auto test_file = data1->getFile( bgLgbPath );
|
auto test_file = gameData->getFile( bgLgbPath );
|
||||||
section = test_file->access_data_sections().at( 0 );
|
section = test_file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
auto planmap_file = data1->getFile( planmapLgbPath );
|
auto planmap_file = gameData->getFile( planmapLgbPath );
|
||||||
section2 = planmap_file->access_data_sections().at( 0 );
|
section2 = planmap_file->access_data_sections().at( 0 );
|
||||||
|
|
||||||
auto test_file1 = data1->getFile( listPcbPath );
|
auto test_file1 = gameData->getFile( listPcbPath );
|
||||||
section1 = test_file1->access_data_sections().at( 0 );
|
section1 = test_file1->access_data_sections().at( 0 );
|
||||||
|
|
||||||
std::vector< std::string > stringList;
|
std::vector< std::string > stringList;
|
||||||
|
@ -499,7 +499,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
if( auto pGimmick = pCache->getSgbFile( sgbPath ) )
|
if( auto pGimmick = pCache->getSgbFile( sgbPath ) )
|
||||||
{
|
{
|
||||||
for( const auto& offset1cFile : pGimmick->offset1cObjects )
|
for( const auto& offset1cFile : pGimmick->stateEntries )
|
||||||
exportSgbModel( offset1cFile, pEobj, true );
|
exportSgbModel( offset1cFile, pEobj, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,7 @@ int main( int argc, char* argv[] )
|
||||||
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count() );
|
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::high_resolution_clock::now() - startTime ).count() );
|
||||||
|
|
||||||
delete eData;
|
delete eData;
|
||||||
delete data1;
|
delete gameData;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ struct SGB_FILE
|
||||||
{
|
{
|
||||||
SGB_HEADER header;
|
SGB_HEADER header;
|
||||||
std::vector< SGB_GROUP > entries;
|
std::vector< SGB_GROUP > entries;
|
||||||
std::set< std::string > offset1cObjects;
|
std::set< std::string > stateEntries;
|
||||||
|
|
||||||
SGB_FILE()
|
SGB_FILE()
|
||||||
{
|
{
|
||||||
|
@ -260,9 +260,9 @@ struct SGB_FILE
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto group = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset + header.sharedOffset );
|
auto group = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset + header.sharedOffset );
|
||||||
entries.push_back( group );
|
entries.push_back( group );
|
||||||
auto group2 = SGB_GROUP( buf, this, &offset1cObjects, header.fileSize, baseOffset+ header.offset1C, true );
|
auto group2 = SGB_GROUP( buf, this, &stateEntries, header.fileSize, baseOffset+ header.offset1C, true );
|
||||||
entries.push_back( group2 );
|
entries.push_back( group2 );
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
|
|
15
src/tools/questbattle_bruteforce/CMakeLists.txt
Normal file
15
src/tools/questbattle_bruteforce/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
cmake_policy(SET CMP0015 NEW)
|
||||||
|
project(Tool_QuestBattle_BruteForce)
|
||||||
|
|
||||||
|
file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
||||||
|
file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
||||||
|
|
||||||
|
add_executable(questbattle_bruteforce ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
target_link_libraries (questbattle_bruteforce common xivdat pthread mysqlclient dl z stdc++fs )
|
||||||
|
else()
|
||||||
|
target_link_libraries (questbattle_bruteforce common xivdat mysql zlib)
|
||||||
|
endif()
|
||||||
|
|
143
src/tools/questbattle_bruteforce/main.cpp
Normal file
143
src/tools/questbattle_bruteforce/main.cpp
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
|
||||||
|
#include <GameData.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <DatCat.h>
|
||||||
|
#include <ExdData.h>
|
||||||
|
#include <ExdCat.h>
|
||||||
|
#include <Exd.h>
|
||||||
|
#include <Exh.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cctype>
|
||||||
|
#include <set>
|
||||||
|
#include <Exd/ExdDataGenerated.h>
|
||||||
|
#include <Logging/Logger.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <streambuf>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include <Util/CrashHandler.h>
|
||||||
|
|
||||||
|
#include <experimental/filesystem>
|
||||||
|
|
||||||
|
Sapphire::Common::Util::CrashHandler crashHandler;
|
||||||
|
|
||||||
|
Sapphire::Data::ExdDataGenerated g_exdData;
|
||||||
|
xiv::dat::GameData* gameData = nullptr;
|
||||||
|
|
||||||
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
namespace fs = std::experimental::filesystem;
|
||||||
|
|
||||||
|
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
|
||||||
|
const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" );
|
||||||
|
|
||||||
|
void exportFile( const std::string& path )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto file = gameData->getFile( path );
|
||||||
|
|
||||||
|
if( !file )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto p = fs::path( path );
|
||||||
|
fs::create_directories( p.parent_path() );
|
||||||
|
file->exportToFile( p );
|
||||||
|
}
|
||||||
|
catch( const std::exception& ex )
|
||||||
|
{
|
||||||
|
Logger::error( "Failed to export file {0}, error: {1}", path, ex.what() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool replace( std::string& str, const std::string& from, const std::string& to )
|
||||||
|
{
|
||||||
|
size_t start_pos = str.find( from );
|
||||||
|
|
||||||
|
if( start_pos == std::string::npos )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str.replace( start_pos, from.length(), to );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main( int argc, char* argv[] )
|
||||||
|
{
|
||||||
|
|
||||||
|
Logger::init( "questbattle_bruteforce" );
|
||||||
|
|
||||||
|
Logger::info( "Setting up EXD data" );
|
||||||
|
if( !g_exdData.init( datLocation ) )
|
||||||
|
{
|
||||||
|
Logger::fatal( "Error setting up EXD data " );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::create_directory( "questbattle_scripts" );
|
||||||
|
|
||||||
|
std::vector< std::string > luabFiles;
|
||||||
|
|
||||||
|
gameData = new xiv::dat::GameData( datLocation );
|
||||||
|
|
||||||
|
auto questExdIds = g_exdData.getQuestIdList();
|
||||||
|
|
||||||
|
for( auto id : questExdIds )
|
||||||
|
{
|
||||||
|
auto quest = g_exdData.get< Data::Quest >( id );
|
||||||
|
|
||||||
|
if( !quest )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto idString = quest->id;
|
||||||
|
|
||||||
|
if( idString.empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// galaxy brain shit right here
|
||||||
|
auto folderId = fmt::format( "{:06d}", id & 0xFFFF ).substr( 1, 3 );
|
||||||
|
|
||||||
|
replace( idString, "_", "Btl_" );
|
||||||
|
|
||||||
|
auto path = fmt::format( "game_script/quest/{}/{}.luab", folderId, idString );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto file = gameData->getFile( path );
|
||||||
|
|
||||||
|
if( !file )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto filename = fmt::format( "questbattle_scripts/{}.luab", idString );
|
||||||
|
|
||||||
|
luabFiles.emplace_back( filename );
|
||||||
|
file->exportToFile( filename );
|
||||||
|
|
||||||
|
Logger::info( "Exported file: {}", filename );
|
||||||
|
}
|
||||||
|
catch( const std::exception& ex )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info( "Decompiling luab scripts, pls wait..." );
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for( auto& filename : luabFiles )
|
||||||
|
{
|
||||||
|
filename.pop_back();
|
||||||
|
|
||||||
|
system( fmt::format( "java -jar unluac_2015_06_13.jar {}b > {}", filename, filename ).c_str() );
|
||||||
|
|
||||||
|
Logger::info( "Decompiling luab files - {} of {}", ++i, luabFiles.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue