PROTOCOL_VERSION, test items, MOTD fix (#18)

* Cleaned up protocol selection.

* cmake now works even if protocol option is omitted
* make now supports protocol selection
* removed PACKET_VERSION/CNPROTO_VERSION* redundancy
* ubuntu appveyor script has yet to be written
* cleaned up some trailing spaces

* Add some test items.

Ironically, this change is untested.

* [bugfix] Transmit MOTD when entering the game, not when loading screen fades.

This fixes unnecessary retransmission when /warping.
This commit is contained in:
dongresource 2020-08-21 19:38:45 +02:00 committed by GitHub
parent 1669ee3660
commit df18f3ccd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 30 deletions

View File

@ -4,11 +4,11 @@ project(OpenFusion)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
# OpenFusion supports multiple packet/struct versions # OpenFusion supports multiple packet/struct versions
# 0104 is the default version to build which can be changed # 104 is the default version to build which can be changed
# For example: cmake -B build -DPACKET_VERSION=0728 # For example: cmake -B build -DPROTOCOL_VERSION=728
OPTION(PACKET_VERSION "The packet version to build" "0104") 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 # Disallow in-source builds
if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})

View File

@ -1,10 +1,14 @@
CXX=clang++ CXX=clang++
# -w suppresses all warnings (the part that's commented out helps me find memory leaks, it ruins performance though!) # -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 LDFLAGS=-lpthread
# specifies the name of our exectuable # specifies the name of our exectuable
SERVER=bin/fusion SERVER=bin/fusion
# assign protocol version
# this can be overriden by ex. make PROTOCOL_VERSION=728
PROTOCOL_VERSION?=104
# Windows-specific # Windows-specific
WIN_CXX=x86_64-w64-mingw32-g++ WIN_CXX=x86_64-w64-mingw32-g++
WIN_CXXFLAGS=-std=c++17 -O3 #-g3 -fsanitize=address WIN_CXXFLAGS=-std=c++17 -O3 #-g3 -fsanitize=address
@ -49,7 +53,7 @@ all: $(SERVER)
windows: $(SERVER) windows: $(SERVER)
# Assign Windows-specific values if targeting Windows # assign Windows-specific values if targeting Windows
windows : CXX=$(WIN_CXX) windows : CXX=$(WIN_CXX)
windows : CXXFLAGS=$(WIN_CXXFLAGS) windows : CXXFLAGS=$(WIN_CXXFLAGS)
windows : LDFLAGS=$(WIN_LDFLAGS) windows : LDFLAGS=$(WIN_LDFLAGS)

View File

@ -43,7 +43,7 @@ for:
Remove-Item "build" -Recurse Remove-Item "build" -Recurse
Write-Output "Deleted existing build folder" 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") { if ($LASTEXITCODE -ne "0") {
Write-Error "cmake generation failed for version $version" -ErrorAction Stop Write-Error "cmake generation failed for version $version" -ErrorAction Stop
} }

View File

@ -1,4 +1,4 @@
/* /*
CNStructs.hpp - defines some basic structs & useful methods for packets used by FusionFall based on the version defined CNStructs.hpp - defines some basic structs & useful methods for packets used by FusionFall based on the version defined
*/ */
@ -21,9 +21,9 @@
#include <time.h> #include <time.h>
#endif #endif
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
// TODO: rewrite U16toU8 & U8toU16 to not use codecvt // 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 int U8toU16(std::string src, char16_t* des); // returns number of char16_t that was written at des
uint64_t getTime(); uint64_t getTime();
// The CNPROTO_OVERRIDE definition is defined by cmake if you use it. // The PROTOCOL_VERSION definition is defined by the build system.
// If you don't use cmake, feel free to comment this out and change it around. #if !defined(PROTOCOL_VERSION)
// Otherwise, use the PACKET_VERSION option (e.g. -DPACKET_VERSION=0104 in the cmake command) to change it. #error "PROTOCOL_VERSION not defined"
#if !defined(CNPROTO_OVERRIDE) #elif PROTOCOL_VERSION == 728
//#define CNPROTO_VERSION_0728
#define CNPROTO_VERSION_0104
#endif
#if defined(CNPROTO_VERSION_0104)
#include "structs/0104.hpp"
#elif defined(CNPROTO_VERSION_0728)
#include "structs/0728.hpp" #include "structs/0728.hpp"
#elif PROTOCOL_VERSION == 104
#include "structs/0104.hpp"
#else
#error Invalid PROTOCOL_VERSION
#endif #endif
#endif #endif

View File

@ -36,7 +36,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) {
players[key].plr = plr; players[key].plr = plr;
players[key].lastHeartbeat = 0; 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; 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_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_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 // TODO: check if serialkey exists, if it doesn't send sP_FE2CL_REP_PC_ENTER_FAIL
Player plr = CNSharedData::getPlayer(enter->iEnterSerialKey); 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++) for (int i = 0; i < AEQUIP_COUNT; i++)
response->PCLoadData2CL.aEquip[i] = plr.Equip[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.. // don't ask..
for (int i = 1; i < 37; i++) { for (int i = 1; i < 37; i++) {
response->PCLoadData2CL.aNanoBank[i].iID = i; response->PCLoadData2CL.aNanoBank[i].iID = i;
@ -205,10 +222,15 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
plr.SerialKey = enter->iEnterSerialKey; plr.SerialKey = enter->iEnterSerialKey;
plr.HP = response->PCLoadData2CL.iHP; 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->setEKey(CNSocketEncryption::createNewKey(response->uiSvrTime, response->iID + 1, response->PCLoadData2CL.iFusionMatter + 1));
sock->setFEKey(plr.FEKey); 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())); 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); 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_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_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( DEBUGLOG(
std::cout << "P_CL2FE_REQ_PC_LOADING_COMPLETE:" << std::endl; 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; 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*)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) { void PlayerManager::movePlayer(CNSocket* sock, CNPacketData* data) {

View File

@ -28,6 +28,7 @@ int main() {
} }
#endif #endif
settings::init(); settings::init();
std::cout << "[INFO] Protocol version: " << PROTOCOL_VERSION << std::endl;
std::cout << "[INFO] Intializing Packet Managers..." << std::endl; std::cout << "[INFO] Intializing Packet Managers..." << std::endl;
PlayerManager::init(); PlayerManager::init();
ChatManager::init(); ChatManager::init();
@ -50,4 +51,4 @@ int main() {
WSACleanup(); WSACleanup();
#endif #endif
return 0; return 0;
} }