From 5e569d43247769550860a5cd9ecb3aaae22d8765 Mon Sep 17 00:00:00 2001 From: dongresource Date: Sat, 6 Mar 2021 19:55:37 +0100 Subject: [PATCH] Disallow selling Croc-Potted items Also, make sure to explicitly terminate the connection when a player is kicked, and align a few fields in tables.sql. --- sql/tables.sql | 6 +++--- src/NPCManager.cpp | 14 ++++++++++---- src/PlayerManager.cpp | 3 +++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sql/tables.sql b/sql/tables.sql index 3a237eb..cbf97f8 100644 --- a/sql/tables.sql +++ b/sql/tables.sql @@ -28,9 +28,9 @@ CREATE TABLE IF NOT EXISTS Players ( AppearanceFlag INTEGER DEFAULT 0 NOT NULL, TutorialFlag INTEGER DEFAULT 0 NOT NULL, PayZoneFlag INTEGER DEFAULT 0 NOT NULL, - XCoordinate INTEGER NOT NULL, - YCoordinate INTEGER NOT NULL, - ZCoordinate INTEGER NOT NULL, + XCoordinate INTEGER NOT NULL, + YCoordinate INTEGER NOT NULL, + ZCoordinate INTEGER NOT NULL, Angle INTEGER NOT NULL, HP INTEGER NOT NULL, FusionMatter INTEGER DEFAULT 0 NOT NULL, diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 7fb575b..562a6b6 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -171,10 +171,12 @@ void NPCManager::npcVendorSell(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_VENDOR_ITEM_SELL* req = (sP_CL2FE_REQ_PC_VENDOR_ITEM_SELL*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + // prepare a fail packet + INITSTRUCT(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, failResp); + failResp.iErrorCode = 0; + if (req->iInvenSlotNum < 0 || req->iInvenSlotNum >= AINVEN_COUNT || req->iItemCnt < 0) { std::cout << "[WARN] Client failed to sell item in slot " << req->iInvenSlotNum << std::endl; - INITSTRUCT(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, failResp); - failResp.iErrorCode = 0; sock->sendPacket((void*)&failResp, P_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, sizeof(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL)); return; } @@ -184,8 +186,12 @@ void NPCManager::npcVendorSell(CNSocket* sock, CNPacketData* data) { if (itemData == nullptr || !itemData->sellable || plr->Inven[req->iInvenSlotNum].iOpt < req->iItemCnt) { // sanity + sellable check std::cout << "[WARN] Item id " << item->iID << " with type " << item->iType << " not found (sell)" << std::endl; - INITSTRUCT(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, failResp); - failResp.iErrorCode = 0; + sock->sendPacket((void*)&failResp, P_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, sizeof(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL)); + return; + } + + // fail to sell croc-potted items + if (plr->Inven[req->iInvenSlotNum].iOpt >= 1 << 16) { sock->sendPacket((void*)&failResp, P_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, sizeof(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL)); return; } diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 6c77d12..d5399dc 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -1082,6 +1082,9 @@ void PlayerManager::kickPlayer(CNSocket *sock, CNPacketData *data) { // send to target player otherSock->sendPacket((void*)&response, P_FE2CL_REP_PC_EXIT_SUCC, sizeof(sP_FE2CL_REP_PC_EXIT_SUCC)); + + // ensure that the connection has terminated + otherSock->kill(); } void PlayerManager::warpToPlayer(CNSocket *sock, CNPacketData *data) {