diff --git a/README.md b/README.md index a242792..b897783 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![](res/radiorave_logo.png) -[![AppVeyor](https://ci.appveyor.com/api/projects/status/github/OpenFusionProject/OpenFusion?svg=true)](https://ci.appveyor.com/project/Raymonf/openfusion) +[![AppVeyor](https://ci.appveyor.com/api/projects/status/github/OpenFusionProject/OpenFusion?svg=true)](https://ci.appveyor.com/project/OpenFusionProject/openfusion) [![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?logo=discord)](https://discord.gg/DYavckB) OpenFusion is a landwalker server for FusionFall. It currently supports versions `beta-20100104` and `beta-20100728` of the original game. diff --git a/src/CNProtocol.cpp b/src/CNProtocol.cpp index f7df999..ce76875 100644 --- a/src/CNProtocol.cpp +++ b/src/CNProtocol.cpp @@ -1,6 +1,10 @@ #include "CNProtocol.hpp" #include "CNStructs.hpp" +#ifdef _MSC_VER + #define _WINSOCK_DEPRECATED_NO_WARNINGS +#endif + // ========================================================[[ CNSocketEncryption ]]======================================================== // literally C/P from the client and converted to C++ (does some byte swapping /shrug) diff --git a/src/CNProtocol.hpp b/src/CNProtocol.hpp index 5887384..8f87962 100644 --- a/src/CNProtocol.hpp +++ b/src/CNProtocol.hpp @@ -133,7 +133,7 @@ protected: void init(); bool active = true; - long int lastTimer; + uint64_t lastTimer; public: PacketHandler pHandler; diff --git a/src/CNShardServer.cpp b/src/CNShardServer.cpp index 6aa26b4..e603d01 100644 --- a/src/CNShardServer.cpp +++ b/src/CNShardServer.cpp @@ -37,7 +37,7 @@ void CNShardServer::killConnection(CNSocket* cns) { } void CNShardServer::onTimer() { - long int currTime = getTime(); + uint64_t currTime = getTime(); auto cachedPlayers = PlayerManager::players; diff --git a/src/CNStructs.cpp b/src/CNStructs.cpp index b580cc3..c58c6fe 100644 --- a/src/CNStructs.cpp +++ b/src/CNStructs.cpp @@ -10,7 +10,7 @@ std::string U16toU8(char16_t* src) { } // returns number of char16_t that was written at des -int U8toU16(std::string src, char16_t* des) { +size_t U8toU16(std::string src, char16_t* des) { std::wstring_convert,char16_t> convert; std::u16string tmp = convert.from_bytes(src); diff --git a/src/CNStructs.hpp b/src/CNStructs.hpp index 113d794..6adebec 100644 --- a/src/CNStructs.hpp +++ b/src/CNStructs.hpp @@ -28,7 +28,7 @@ // TODO: rewrite U16toU8 & U8toU16 to not use codecvt std::string U16toU8(char16_t* src); -int U8toU16(std::string src, char16_t* des); // returns number of char16_t that was written at des +size_t U8toU16(std::string src, char16_t* des); // returns number of char16_t that was written at des uint64_t getTime(); // The PROTOCOL_VERSION definition is defined by the build system. diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index efbc77f..f786c95 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -6,12 +6,12 @@ void ChatManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_FREECHAT_MESSAGE, chatHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT, emoteHandler); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_SEND_MENUCHAT_MESSAGE, menuChatHandler); } void ChatManager::chatHandler(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE)) return; // malformed packet - sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE* chat = (sP_CL2FE_REQ_SEND_FREECHAT_MESSAGE*)data->buf; PlayerView plr = PlayerManager::players[sock]; @@ -31,7 +31,28 @@ void ChatManager::chatHandler(CNSocket* sock, CNPacketData* data) { otherSock->sendPacket(new CNPacketData((void*)resp, P_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC), otherSock->getFEKey())); } } +void ChatManager::menuChatHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_SEND_MENUCHAT_MESSAGE)) + return; // malformed packet + sP_CL2FE_REQ_SEND_MENUCHAT_MESSAGE* chat = (sP_CL2FE_REQ_SEND_MENUCHAT_MESSAGE*)data->buf; + PlayerView plr = PlayerManager::players[sock]; + // send to client + sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC* resp = (sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC)); + memcpy(resp->szFreeChat, chat->szFreeChat, sizeof(chat->szFreeChat)); + resp->iPC_ID = PlayerManager::players[sock].plr.iID; + resp->iEmoteCode = chat->iEmoteCode; + sock->sendPacket(new CNPacketData((void*)resp, P_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC), sock->getFEKey())); + + // send to visible players + for (CNSocket* otherSock : plr.viewable) { + sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC* resp = (sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC)); + memcpy(resp->szFreeChat, chat->szFreeChat, sizeof(chat->szFreeChat)); + resp->iPC_ID = PlayerManager::players[sock].plr.iID; + resp->iEmoteCode = chat->iEmoteCode; + otherSock->sendPacket(new CNPacketData((void*)resp, P_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC, sizeof(sP_FE2CL_REP_SEND_MENUCHAT_MESSAGE_SUCC), otherSock->getFEKey())); + } +} void ChatManager::emoteHandler(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT)) return; // ignore the malformed packet diff --git a/src/ChatManager.hpp b/src/ChatManager.hpp index 3f669d7..241d47b 100644 --- a/src/ChatManager.hpp +++ b/src/ChatManager.hpp @@ -8,6 +8,7 @@ namespace ChatManager { void chatHandler(CNSocket* sock, CNPacketData* data); void emoteHandler(CNSocket* sock, CNPacketData* data); + void menuChatHandler(CNSocket* sock, CNPacketData* data); } -#endif \ No newline at end of file +#endif diff --git a/src/Defines.hpp b/src/Defines.hpp index a10fa75..21eb8f2 100644 --- a/src/Defines.hpp +++ b/src/Defines.hpp @@ -8,12 +8,12 @@ * implementing just yet anyway. */ -const float VALUE_BATTERY_EMPTY_PENALTY = 0.5; -const float CN_EP_RANK_1 = 0.8; -const float CN_EP_RANK_2 = 0.7; -const float CN_EP_RANK_3 = 0.5; -const float CN_EP_RANK_4 = 0.3; -const float CN_EP_RANK_5 = 0.29; +const float VALUE_BATTERY_EMPTY_PENALTY = 0.5f; +const float CN_EP_RANK_1 = 0.8f; +const float CN_EP_RANK_2 = 0.7f; +const float CN_EP_RANK_3 = 0.5f; +const float CN_EP_RANK_4 = 0.3f; +const float CN_EP_RANK_5 = 0.29f; enum { SUCC = 1, diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index 38534d9..c692060 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -86,6 +86,7 @@ void NanoManager::nanoSkillUseHandler(CNSocket* sock, CNPacketData* data) { resp->iNanoStamina = 150; // Hardcoded for now sock->sendPacket(new CNPacketData((void*)resp, P_FE2CL_NANO_SKILL_USE_SUCC, sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC), sock->getFEKey())); + DEBUGLOG( std::cout << U16toU8(plr.plr.PCStyle.szFirstName) << U16toU8(plr.plr.PCStyle.szLastName) << " requested to summon nano skill " << std::endl; ) diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 47dd443..f956bbc 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -553,6 +553,9 @@ void PlayerManager::heartbeatPlayer(CNSocket* sock, CNPacketData* data) { } void PlayerManager::exitGame(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_EXIT)) + return; + sP_CL2FE_REQ_PC_EXIT* exitData = (sP_CL2FE_REQ_PC_EXIT*)data->buf; sP_FE2CL_REP_PC_EXIT_SUCC* response = (sP_FE2CL_REP_PC_EXIT_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_EXIT_SUCC)); diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index 3105f51..34cfb6a 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -13,7 +13,7 @@ struct PlayerView { std::list viewable; std::list viewableNPCs; Player plr; - int long lastHeartbeat; + uint64_t lastHeartbeat; };