diff --git a/sql/import.bat b/sql/import.bat index 73359eae..3f9de0e9 100644 --- a/sql/import.bat +++ b/sql/import.bat @@ -32,13 +32,13 @@ FOR %%X IN (*.sql) DO ( REM handle update.sql last ) ELSE ( ECHO Importing %%X - %PATH_MYSQL% %DBNAME% -h %DBADDRESS% -u %USER% < %%X + %PATH_MYSQL% %DBNAME% -h %DBADDRESS% -u %USER% %PASSWORD% < %%X ) ) IF EXIST "update.sql" ( ECHO Importing update.sql - %PATH_MYSQL% %DBNAME% -h %DBADDRESS% -u %USER% < update.sql + %PATH_MYSQL% %DBNAME% -h %DBADDRESS% -u %USER% %PASSWORD% < update.sql ) ECHO Finished! diff --git a/src/servers/Server_Common/Network/GamePacket.h b/src/servers/Server_Common/Network/GamePacket.h index d98f0316..6fcc584e 100644 --- a/src/servers/Server_Common/Network/GamePacket.h +++ b/src/servers/Server_Common/Network/GamePacket.h @@ -45,31 +45,37 @@ public: template T getValAt( uint16_t pos ) const { - assert(m_segHdr.size > pos); + assert( m_segHdr.size > pos ); return *reinterpret_cast< const T* >( &m_dataBuf[0] + pos ); } void setBytesAt( uint16_t offset, uint8_t * bytes, uint16_t length ) { - assert(m_segHdr.size > offset); + assert( m_segHdr.size > offset ); memcpy( reinterpret_cast< uint8_t* >( &m_dataBuf[0] + offset ), bytes, length ); } const char * getStringAt( uint16_t pos ) const { - assert(m_segHdr.size > pos); + assert( m_segHdr.size > pos ); return reinterpret_cast< const char* >( &m_dataBuf[0] + pos ); } void setStringAt( uint16_t pos, const std::string& str ) { - assert(m_segHdr.size > pos); + assert( m_segHdr.size > pos ); memcpy( reinterpret_cast< uint8_t* >( &m_dataBuf[0] + pos ), str.c_str(), str.length() ); } - uint8_t * getData() + const uint8_t * getData() const { - return reinterpret_cast< uint8_t* >( &m_dataBuf[0] ); + return reinterpret_cast< const uint8_t* >( &m_dataBuf[0] ); + } + + const uint8_t * getDataAt(uint16_t pos) const + { + assert( m_segHdr.size > pos ); + return reinterpret_cast< const uint8_t* >( &m_dataBuf[0] + pos ); } void setHeader( uint16_t size, uint16_t type, uint32_t id1, uint32_t id2, uint16_t subType, uint32_t unknown = 0xFED2E000 ); diff --git a/src/servers/Server_Zone/Inventory/Inventory.cpp b/src/servers/Server_Zone/Inventory/Inventory.cpp index ee982043..dbcd2080 100644 --- a/src/servers/Server_Zone/Inventory/Inventory.cpp +++ b/src/servers/Server_Zone/Inventory/Inventory.cpp @@ -884,7 +884,7 @@ uint16_t Core::Inventory::calculateEquippedGearItemLevel() it++; } - return boost::algorithm::clamp( iLvlResult / 12, 0, 9999 ); + return boost::algorithm::clamp( iLvlResult / 13, 0, 9999 ); } diff --git a/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp index 0f397f2a..4fc80e64 100644 --- a/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp @@ -601,10 +601,10 @@ void Core::Network::GameConnection::tellHandler( const Packets::GamePacket& inPa void Core::Network::GameConnection::performNoteHandler( const Packets::GamePacket& inPacket, Entity::Player& player ) { - GamePacketNew< FFXIVIpcPerformNote, ServerZoneIpcType > performPacket( player.getId() ); + ZoneChannelPacket< FFXIVIpcPerformNote > performPacket( player.getId() ); - uint8_t inVal = inPacket.getValAt< uint8_t >( 0x20 ); - memcpy( &performPacket.data().data[0], &inVal, 32 ); + auto inVal = inPacket.getDataAt( 0x20 ); + memcpy( &performPacket.data().data[0], inVal, 32 ); player.sendToInRangeSet( performPacket ); } diff --git a/src/tools/pcb_reader/README.md b/src/tools/pcb_reader/README.md index ec422bd4..66fb849f 100644 --- a/src/tools/pcb_reader/README.md +++ b/src/tools/pcb_reader/README.md @@ -5,10 +5,12 @@ compile with STANDALONE defined to compile without boost and sapphire dependenci usage: - regular - compile with root sapphire dir cmakelists - - sapphire/src/tools/bin/pcb_reader2 "" + - sapphire/src/tools/bin/pcb_reader2 "" - standalone - compile main.cpp with STANDALONE defined in build arg - download ffxivexplorer + - ffxivexplorer > path/to/ffxiv's/game/sqpack/ffxiv/0a0000.dat + - exd/territorytype.exh > `File > Export` and copy `territorytype.exh.csv` from exproted directory to `pcb_reader.exe` directory - ffxivexplorer > path/to/ffxiv's/game/sqpack/ffxiv/020000.dat - ctrl click the following: - `bg/ffxiv/[REGION]/common/collision` diff --git a/src/tools/pcb_reader/main.cpp b/src/tools/pcb_reader/main.cpp index 9d5bb22a..7022dbe3 100644 --- a/src/tools/pcb_reader/main.cpp +++ b/src/tools/pcb_reader/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "pcb.h" #include "lgb.h" @@ -84,39 +85,38 @@ int parseBlockEntry( char* data, std::vector& entries, int gOff std::string zoneNameToPath( const std::string& name ) { - char teri = name[0]; - char region = name[1]; - char type = name[2]; - char zone = name[3]; - static std::map< char, std::string > teriMap + std::string path; + auto inFile = std::ifstream( "territorytype.exh.csv" ); + if( inFile.good() ) { - { 'r', "roc" }, - { 'w', "wil" }, - { 'l', "lak" }, - { 'o', "ocn" }, - { 'f', "fst" }, - { 'a', "air" }, - { 's', "sea" }, - { 'z', "zon" } - }; - - static std::map< char, std::string > typeMap + std::string line; + std::regex re("(\\d+),\"(.*)\",\"(.*)\",.*"); + while( std::getline( inFile, line ) ) + { + std::smatch match; + if( std::regex_match( line, match, re ) ) + { + if( name == match[2].str() ) + { + path = match[3].str(); + break; + } + } + } + } + if( !path.empty() ) { - { 'f', "fld" }, - { 't', "twn" }, - { 'd', "dun" }, - { 'b', "bah" }, - { 'i', "ind" }, - { 'e', "evt" }, - }; - std::string ret; - const auto& teriRet = teriMap[teri]; - const auto& typeRet = typeMap[type]; - ret += teriRet + "_"; - ret += teri; - ret += region; - ret += "/" + typeRet + "/" + name; - return ret; + //path = path.substr( path.find_first_of( "/" ) + 1, path.size() - path.find_first_of( "/" )); + //path = std::string( "ffxiv/" ) + path; + path = std::string( "bg" ) + path.substr( 0, path.find( "/level/" ) ); + std::cout << "[Info] " << "Found path for " << name << ": " << path << std::endl; + } + else + { + throw std::runtime_error( "Unable to find path for " + name + + ".\n\tPlease open 0a0000.win32.index with FFXIV Explorer and extract territorytype.exh as CSV\n\tand copy territorytype.exh.csv into pcb_reader.exe directory" ); + } + return path; } void readFileToBuffer( const std::string& path, std::vector< char >& buf ) @@ -141,24 +141,25 @@ int main( int argc, char* argv[] ) { auto startTime = std::chrono::system_clock::now(); - std::string gamePath = "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv"; + // todo: support expansions + std::string gamePath = "C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv"; std::string zoneName = "r1f1"; if( argc > 1 ) { - gamePath = argv[1]; + zoneName = argv[1]; if( argc > 2 ) { - zoneName = argv[2]; + gamePath = argv[2]; } } - const auto& zonePath = zoneNameToPath( zoneName ); try { - std::string listPcbPath( "bg/ffxiv/" + zonePath + "/collision/list.pcb" ); - std::string bgLgbPath( "bg/ffxiv/" + zonePath + "/level/bg.lgb" ); - std::string collisionFilePath( "bg/ffxiv/" + zonePath + "/collision/" ); + const auto& zonePath = zoneNameToPath( zoneName ); + std::string listPcbPath( zonePath + "/collision/list.pcb" ); + std::string bgLgbPath( zonePath + "/level/bg.lgb" ); + std::string collisionFilePath( zonePath + "/collision/" ); std::vector< char > section; std::vector< char > section1; @@ -274,7 +275,7 @@ int main( int argc, char* argv[] ) } catch( std::exception& e ) { - std::cout << "Unable to load collision mesh " << fileName << "\n\tError:\n\t" << e.what() << "\n"; + std::cout << "[Error] " << "Unable to load collision mesh " << fileName << "\n\tError:\n\t" << e.what() << "\n"; return false; } }; @@ -301,7 +302,7 @@ int main( int argc, char* argv[] ) } catch( std::exception& e ) { - std::cout << "Unable to load SGB " << fileName << "\n\tError:\n\t" << e.what() << "\n"; + std::cout << "[Error] " << "Unable to load SGB " << fileName << "\n\tError:\n\t" << e.what() << "\n"; sgbFiles.insert( std::make_pair( fileName, sgbFile ) ); } return false; @@ -394,8 +395,8 @@ int main( int argc, char* argv[] ) loadPcbFile( fileName ); pushVerts( pcbFiles[fileName], fileName ); } - std::cout << "Writing obj file " << "\n"; - std::cout << bgLgb.groups.size() << " groups " << "\n"; + std::cout << "[Info] " << "Writing obj file " << "\n"; + std::cout << "[Info] " << bgLgb.groups.size() << " groups " << "\n"; uint32_t totalGroups = 0; uint32_t totalGroupEntries = 0; for( const auto& group : bgLgb.groups ) @@ -467,15 +468,18 @@ int main( int argc, char* argv[] ) } } } - std::cout << "\n\nLoaded " << pcbFiles.size() << " PCB Files \n"; - std::cout << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n"; + std::cout << "\n[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n"; + std::cout << "[Info] " << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n"; } - std::cout << "Finished exporting " << zoneName << " in " << + std::cout << "[Success] " << "Finished exporting " << zoneName << " in " << std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count() << " seconds\n"; } catch( std::exception& e ) { - std::cout << e.what() << std::endl; + std::cout << "[Error] " << e.what() << std::endl; + std::cout << "[Error] " << "Unable to extract collision data.\n\tIf using standalone ensure your working directory folder layout is \n\tbg/[ffxiv|ex1|ex2]/teri/type/zone/[level|collision]" << std::endl; + std::cout << std::endl; + std::cout << "[Info] " << "Usage: pcb_reader2 territory \"path/to/game/sqpack/ffxiv\" " << std::endl; } return 0; }