From 64accecc30c7b98f097c680c40ad6b3fc85b5fe0 Mon Sep 17 00:00:00 2001 From: dongresource Date: Thu, 27 Aug 2020 22:16:52 +0200 Subject: [PATCH] Initial implementation of CombatManager. Overflow detection must still be implemented. --- Makefile | 2 ++ src/CombatManager.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++ src/CombatManager.hpp | 16 +++++++++ src/Player.hpp | 1 + src/main.cpp | 2 ++ 5 files changed, 105 insertions(+) create mode 100644 src/CombatManager.cpp create mode 100644 src/CombatManager.hpp diff --git a/Makefile b/Makefile index 97e18b6..d32e769 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ CXX_SRC=\ src/contrib/sqlite/sqlite3pp.cpp\ src/contrib/sqlite/sqlite3ppext.cpp\ src/ChatManager.cpp\ + src/CombatManager.cpp\ src/CNLoginServer.cpp\ src/CNProtocol.cpp\ src/CNShardServer.cpp\ @@ -63,6 +64,7 @@ CXX_HDR=\ src/contrib/INIReader.hpp\ src/contrib/JSON.hpp\ src/ChatManager.hpp\ + src/CombatManager.hpp\ src/CNLoginServer.hpp\ src/CNProtocol.hpp\ src/CNShardServer.hpp\ diff --git a/src/CombatManager.cpp b/src/CombatManager.cpp new file mode 100644 index 0000000..73fde1d --- /dev/null +++ b/src/CombatManager.cpp @@ -0,0 +1,84 @@ +#include "CombatManager.hpp" +#include "PlayerManager.hpp" +#include "NPCManager.hpp" + +#include + +void CombatManager::init() { + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_ATTACK_NPCs, pcAttackNpcs); + + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_COMBAT_BEGIN, combatBegin); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_COMBAT_END, combatEnd); + REGISTER_SHARD_PACKET(P_CL2FE_DOT_DAMAGE_ONOFF, dotDamageOnOff); +} + +void CombatManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) { + // generic malformed packet checks are not applicable to variable-length packets + sP_CL2FE_REQ_PC_ATTACK_NPCs* pkt = (sP_CL2FE_REQ_PC_ATTACK_NPCs*)data->buf; + + if (data->size != sizeof(sP_CL2FE_REQ_PC_ATTACK_NPCs) + pkt->iNPCCnt * 4) { + std::cout << "bad sP_CL2FE_REQ_PC_ATTACK_NPCs packet size\n"; + return; + } + int32_t *pktdata = (int32_t*)((uint8_t*)data->buf + sizeof(sP_CL2FE_REQ_PC_ATTACK_NPCs)); + + std::printf("iNPCCnt: %d\n", pkt->iNPCCnt); + + // initialize response struct + // IMPORTANT TODO: verify that resplen doesn't overflow!!! + size_t resplen = sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC) + pkt->iNPCCnt * sizeof(sAttackResult); + uint8_t *respbuf = (uint8_t*)xmalloc(resplen); + memset(respbuf, 0, resplen); + sP_FE2CL_PC_ATTACK_NPCs_SUCC *resp = (sP_FE2CL_PC_ATTACK_NPCs_SUCC*)respbuf; + sAttackResult *respdata = (sAttackResult*)(respbuf+sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC)); + + resp->iNPCCnt = pkt->iNPCCnt; + + for (int i = 0; i < pkt->iNPCCnt; i++) { + std::cout << pktdata[i] << std::endl; + + if (NPCManager::NPCs.find(pktdata[i]) == NPCManager::NPCs.end()) { + // not sure how to best handle this + std::cout << "[WARN] pcAttackNpcs: mob ID not found" << std::endl; + return; + } + BaseNPC& mob = NPCManager::NPCs[pktdata[i]]; + + mob.appearanceData.iHP -= 100; + std::cout << "mob health is now " << mob.appearanceData.iHP << std::endl; + + if (mob.appearanceData.iHP <= 0) + giveReward(sock); + + respdata[i].iID = mob.appearanceData.iNPC_ID; + respdata[i].iDamage = 100; + respdata[i].iHP = mob.appearanceData.iHP; + respdata[i].iHitFlag = 2; + } + + std::cout << "sending packet of length " << resplen << std::endl; + sock->sendPacket((void*)respbuf, P_FE2CL_PC_ATTACK_NPCs_SUCC, resplen); + + free(respbuf); +} + +void CombatManager::combatBegin(CNSocket *sock, CNPacketData *data) {} // stub +void CombatManager::combatEnd(CNSocket *sock, CNPacketData *data) {} // stub +void CombatManager::dotDamageOnOff(CNSocket *sock, CNPacketData *data) {} // stub + +void CombatManager::giveReward(CNSocket *sock) { + // reward testing + INITSTRUCT(sP_FE2CL_REP_REWARD_ITEM, reward); + Player *plr = PlayerManager::getPlayer(sock); + + // update player + plr->money += 50; + plr->fusionmatter += 70; + + reward.m_iCandy = plr->money; + reward.m_iFusionMatter = plr->fusionmatter; + reward.iFatigue = 100; // prevents warning message + reward.iFatigue_Level = 1; + + sock->sendPacket((void*)&reward, P_FE2CL_REP_REWARD_ITEM, sizeof(sP_FE2CL_REP_REWARD_ITEM)); +} diff --git a/src/CombatManager.hpp b/src/CombatManager.hpp new file mode 100644 index 0000000..5d321ac --- /dev/null +++ b/src/CombatManager.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "CNProtocol.hpp" +#include "CNShared.hpp" +#include "CNShardServer.hpp" + +namespace CombatManager { + void init(); + + void pcAttackNpcs(CNSocket *sock, CNPacketData *data); + void combatBegin(CNSocket *sock, CNPacketData *data); + void combatEnd(CNSocket *sock, CNPacketData *data); + void dotDamageOnOff(CNSocket *sock, CNPacketData *data); + + void giveReward(CNSocket *sock); +} diff --git a/src/Player.hpp b/src/Player.hpp index e60bdf8..3d780d1 100644 --- a/src/Player.hpp +++ b/src/Player.hpp @@ -15,6 +15,7 @@ struct Player { int HP; int slot; // player slot, not nano slot int32_t money; + int32_t fusionmatter; sPCStyle PCStyle; sPCStyle2 PCStyle2; sNano Nanos[37]; // acquired nanos diff --git a/src/main.cpp b/src/main.cpp index ef79250..1a1990b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include "CNShardServer.hpp" #include "PlayerManager.hpp" #include "ChatManager.hpp" +#include "CombatManager.hpp" #include "ItemManager.hpp" #include "MissionManager.hpp" #include "NanoManager.hpp" @@ -49,6 +50,7 @@ int main() { std::cout << "[INFO] Intializing Packet Managers..." << std::endl; PlayerManager::init(); ChatManager::init(); + CombatManager::init(); ItemManager::init(); MissionManager::init(); NanoManager::init();