diff --git a/CMakeLists.txt b/CMakeLists.txt index dada585..52d99e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,11 @@ project(OpenFusion) set(CMAKE_CXX_STANDARD 17) # OpenFusion supports multiple packet/struct versions -# 0104 is the default version to build which can be changed -# For example: cmake -B build -DPACKET_VERSION=0728 -OPTION(PACKET_VERSION "The packet version to build" "0104") +# 104 is the default version to build which can be changed +# For example: cmake -B build -DPROTOCOL_VERSION=728 +set(PROTOCOL_VERSION 104 CACHE STRING "The packet version to build") -ADD_DEFINITIONS(-DCNPROTO_OVERRIDE -DCNPROTO_VERSION_${PACKET_VERSION}) +add_compile_definitions(PROTOCOL_VERSION=${PROTOCOL_VERSION}) # Disallow in-source builds if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) diff --git a/Makefile b/Makefile index 8f455c9..9614d43 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,14 @@ CXX=clang++ # -w suppresses all warnings (the part that's commented out helps me find memory leaks, it ruins performance though!) -CXXFLAGS=-std=c++17 -O3 #-g3 -fsanitize=address +CXXFLAGS=-std=c++17 -O3 -DPROTOCOL_VERSION=$(PROTOCOL_VERSION) #-g3 -fsanitize=address LDFLAGS=-lpthread # specifies the name of our exectuable SERVER=bin/fusion +# assign protocol version +# this can be overriden by ex. make PROTOCOL_VERSION=728 +PROTOCOL_VERSION?=104 + # Windows-specific WIN_CXX=x86_64-w64-mingw32-g++ WIN_CXXFLAGS=-std=c++17 -O3 #-g3 -fsanitize=address @@ -49,7 +53,7 @@ all: $(SERVER) windows: $(SERVER) -# Assign Windows-specific values if targeting Windows +# assign Windows-specific values if targeting Windows windows : CXX=$(WIN_CXX) windows : CXXFLAGS=$(WIN_CXXFLAGS) windows : LDFLAGS=$(WIN_LDFLAGS) diff --git a/appveyor.yml b/appveyor.yml index acad59a..4e780bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,7 +43,7 @@ for: Remove-Item "build" -Recurse Write-Output "Deleted existing build folder" } - Invoke-Expression "cmake -B build -DPACKET_VERSION=$version" + Invoke-Expression "cmake -B build -DPROTOCOL_VERSION=$version" if ($LASTEXITCODE -ne "0") { Write-Error "cmake generation failed for version $version" -ErrorAction Stop } diff --git a/src/CNStructs.hpp b/src/CNStructs.hpp index 9df5f31..f41e1ea 100644 --- a/src/CNStructs.hpp +++ b/src/CNStructs.hpp @@ -1,4 +1,4 @@ -/* +/* CNStructs.hpp - defines some basic structs & useful methods for packets used by FusionFall based on the version defined */ @@ -21,9 +21,9 @@ #include #endif #include -#include -#include -#include +#include +#include +#include // TODO: rewrite U16toU8 & U8toU16 to not use codecvt @@ -31,18 +31,15 @@ std::string U16toU8(char16_t* src); int U8toU16(std::string src, char16_t* des); // returns number of char16_t that was written at des uint64_t getTime(); -// The CNPROTO_OVERRIDE definition is defined by cmake if you use it. -// If you don't use cmake, feel free to comment this out and change it around. -// Otherwise, use the PACKET_VERSION option (e.g. -DPACKET_VERSION=0104 in the cmake command) to change it. -#if !defined(CNPROTO_OVERRIDE) - //#define CNPROTO_VERSION_0728 - #define CNPROTO_VERSION_0104 -#endif - -#if defined(CNPROTO_VERSION_0104) - #include "structs/0104.hpp" -#elif defined(CNPROTO_VERSION_0728) +// The PROTOCOL_VERSION definition is defined by the build system. +#if !defined(PROTOCOL_VERSION) + #error "PROTOCOL_VERSION not defined" +#elif PROTOCOL_VERSION == 728 #include "structs/0728.hpp" +#elif PROTOCOL_VERSION == 104 + #include "structs/0104.hpp" +#else + #error Invalid PROTOCOL_VERSION #endif #endif diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 2d8f694..9848de5 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -36,7 +36,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) { players[key].plr = plr; players[key].lastHeartbeat = 0; - std::cout << U16toU8(plr.PCStyle.szFirstName) << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl; + std::cout << U16toU8(plr.PCStyle.szFirstName) << " " << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl; std::cout << players.size() << " players" << std::endl; } @@ -157,6 +157,7 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_ENTER* enter = (sP_CL2FE_REQ_PC_ENTER*)data->buf; sP_FE2CL_REP_PC_ENTER_SUCC* response = (sP_FE2CL_REP_PC_ENTER_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_ENTER_SUCC)); + sP_FE2CL_PC_MOTD_LOGIN* motd = (sP_FE2CL_PC_MOTD_LOGIN*)xmalloc(sizeof(sP_FE2CL_PC_MOTD_LOGIN)); // TODO: check if serialkey exists, if it doesn't send sP_FE2CL_REP_PC_ENTER_FAIL Player plr = CNSharedData::getPlayer(enter->iEnterSerialKey); @@ -188,6 +189,22 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { for (int i = 0; i < AEQUIP_COUNT; i++) response->PCLoadData2CL.aEquip[i] = plr.Equip[i]; + // protocol-agnostic sItemBase usage + sItemBase item = (sItemBase){0}; + item.iID = 495; + + for (int i = 0; i < AINVEN_COUNT; i++) { + switch (i) { + case 6: case 8: case 11: case 13: case 20: + case 24: case 26: case 27: case 28: + plr.Inven[i] = item; + break; + default: + plr.Inven[i] = (sItemBase){0}; + } + response->PCLoadData2CL.aInven[i] = plr.Inven[i]; + } + // don't ask.. for (int i = 1; i < 37; i++) { response->PCLoadData2CL.aNanoBank[i].iID = i; @@ -205,10 +222,15 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { plr.SerialKey = enter->iEnterSerialKey; plr.HP = response->PCLoadData2CL.iHP; + motd->iType = 1; + U8toU16(settings::MOTDSTRING, (char16_t*)motd->szSystemMsg); + sock->setEKey(CNSocketEncryption::createNewKey(response->uiSvrTime, response->iID + 1, response->PCLoadData2CL.iFusionMatter + 1)); sock->setFEKey(plr.FEKey); sock->sendPacket(new CNPacketData((void*)response, P_FE2CL_REP_PC_ENTER_SUCC, sizeof(sP_FE2CL_REP_PC_ENTER_SUCC), sock->getFEKey())); + // transmit MOTD after entering the game, so the client hopefully changes modes on time + sock->sendPacket(new CNPacketData((void*)motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN), sock->getFEKey())); addPlayer(sock, plr); } @@ -219,20 +241,15 @@ void PlayerManager::loadPlayer(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_LOADING_COMPLETE* complete = (sP_CL2FE_REQ_PC_LOADING_COMPLETE*)data->buf; sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC* response = (sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC)); - sP_FE2CL_PC_MOTD_LOGIN* motd = (sP_FE2CL_PC_MOTD_LOGIN*)xmalloc(sizeof(sP_FE2CL_PC_MOTD_LOGIN)); DEBUGLOG( std::cout << "P_CL2FE_REQ_PC_LOADING_COMPLETE:" << std::endl; - std::cout << "\tPC_ID: " << complete->iPC_ID << std::endl; + std::cout << "\tPC_ID: " << complete->iPC_ID << std::endl; ) response->iPC_ID = complete->iPC_ID; - motd->iType = 1; - U8toU16(settings::MOTDSTRING, (char16_t*)motd->szSystemMsg); - sock->sendPacket(new CNPacketData((void*)response, P_FE2CL_REP_PC_LOADING_COMPLETE_SUCC, sizeof(sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC), sock->getFEKey())); - sock->sendPacket(new CNPacketData((void*)motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN), sock->getFEKey())); } void PlayerManager::movePlayer(CNSocket* sock, CNPacketData* data) { diff --git a/src/main.cpp b/src/main.cpp index 56e9055..e598470 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,7 @@ int main() { } #endif settings::init(); + std::cout << "[INFO] Protocol version: " << PROTOCOL_VERSION << std::endl; std::cout << "[INFO] Intializing Packet Managers..." << std::endl; PlayerManager::init(); ChatManager::init(); @@ -50,4 +51,4 @@ int main() { WSACleanup(); #endif return 0; -} \ No newline at end of file +}