mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 03:40:05 +00:00
Trading Refactor
- Its no longer possible to dupe items by stacking inventory slots in a trade. - Stacked items work correctly now.
This commit is contained in:
parent
ddc7caf959
commit
74e06f1084
@ -32,15 +32,15 @@ void ItemManager::init() {
|
||||
// Bank
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_BANK_OPEN, itemBankOpenHandler);
|
||||
// Trade handlers
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER, itemTradeOfferHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT, itemTradeOfferAcceptHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL, itemTradeOfferRefusalHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM, itemTradeConfirmHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL, itemTradeConfirmCancelHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_ITEM_REGISTER, itemTradeRegisterItemHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER, itemTradeUnregisterItemHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CASH_REGISTER, itemTradeRegisterCashHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_EMOTES_CHAT, itemTradeChatHandler);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER, tradeOffer);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT, tradeOfferAccept);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL, tradeOfferRefusal);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM, tradeConfirm);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL, tradeConfirmCancel);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_ITEM_REGISTER, tradeRegisterItem);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER, tradeUnregisterItem);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CASH_REGISTER, tradeRegisterCash);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_EMOTES_CHAT, tradeChat);
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_ITEM_CHEST_OPEN, chestOpenHandler);
|
||||
}
|
||||
|
||||
@ -332,284 +332,155 @@ void ItemManager::itemBankOpenHandler(CNSocket* sock, CNPacketData* data) {
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_BANK_OPEN_SUCC, sizeof(sP_FE2CL_REP_PC_BANK_OPEN_SUCC));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeOfferHandler(CNSocket* sock, CNPacketData* data) {
|
||||
void ItemManager::tradeOffer(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_OFFER))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_OFFER* pacdat = (sP_CL2FE_REQ_PC_TRADE_OFFER*)data->buf;
|
||||
|
||||
int iID_Check;
|
||||
CNSocket* otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto& pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
Player* plr = PlayerManager::getPlayer(otherSock);
|
||||
|
||||
if (plr->isTrading) {
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_To;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL));
|
||||
|
||||
return; // prevent trading with a player already trading
|
||||
}
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeOfferAcceptHandler(CNSocket* sock, CNPacketData* data) {
|
||||
void ItemManager::tradeOfferAccept(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT* pacdat = (sP_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT*)data->buf;
|
||||
|
||||
int iID_Check;
|
||||
CNSocket* otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto& pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
// Clearing up trade slots
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
Player* plr2 = PlayerManager::getPlayer(otherSock);
|
||||
|
||||
if (plr2->isTrading) {
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_To;
|
||||
resp.iID_Request = pacdat->iID_From;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL));
|
||||
|
||||
return; // prevent trading with a player already trading
|
||||
}
|
||||
|
||||
plr->isTrading = true;
|
||||
plr2->isTrading = true;
|
||||
plr->isTradeConfirm = false;
|
||||
plr2->isTradeConfirm = false;
|
||||
|
||||
// clearing up trade slots
|
||||
plr->moneyInTrade = 0;
|
||||
plr2->moneyInTrade = 0;
|
||||
|
||||
memset(&plr->Trade, 0, sizeof(plr->Trade));
|
||||
memset(&plr2->Trade, 0, sizeof(plr2->Trade));
|
||||
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_SUCC));
|
||||
}
|
||||
// marking players as traders
|
||||
plr->isTrading = true;
|
||||
plr2->isTrading = true;
|
||||
|
||||
void ItemManager::itemTradeOfferRefusalHandler(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL* pacdat = (sP_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL*)data->buf;
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, resp);
|
||||
// marking players as unconfirmed
|
||||
plr->isTradeConfirm = false;
|
||||
plr2->isTradeConfirm = false;
|
||||
|
||||
// inform the other player that offer is accepted
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
int iID_Check;
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_SUCC));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_SUCC));
|
||||
}
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
void ItemManager::tradeOfferRefusal(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
sP_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL* pacdat = (sP_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL*)data->buf;
|
||||
|
||||
for (auto& pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CNSocket* otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeConfirmHandler(CNSocket* sock, CNPacketData* data) {
|
||||
void ItemManager::tradeConfirm(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_CONFIRM))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_CONFIRM* pacdat = (sP_CL2FE_REQ_PC_TRADE_CONFIRM*)data->buf;
|
||||
|
||||
int iID_Check;
|
||||
CNSocket* otherSock; // weird flip flop because we need to know who the other player is
|
||||
if (pacdat->iID_Request == pacdat->iID_From)
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
else
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto& pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
Player* plr2 = PlayerManager::getPlayer(otherSock);
|
||||
|
||||
if (plr2->isTradeConfirm) {
|
||||
|
||||
plr->isTrading = false;
|
||||
plr2->isTrading = false;
|
||||
plr->isTradeConfirm = false;
|
||||
plr2->isTradeConfirm = false;
|
||||
|
||||
// Check if we have enough free slots
|
||||
int freeSlots = 0;
|
||||
int freeSlotsNeeded = 0;
|
||||
int freeSlots2 = 0;
|
||||
int freeSlotsNeeded2 = 0;
|
||||
|
||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||
if (plr->Inven[i].iID == 0)
|
||||
freeSlots++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (plr->Trade[i].iID != 0)
|
||||
freeSlotsNeeded++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||
if (plr2->Inven[i].iID == 0)
|
||||
freeSlots2++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (plr2->Trade[i].iID != 0)
|
||||
freeSlotsNeeded2++;
|
||||
}
|
||||
|
||||
if (freeSlotsNeeded2 - freeSlotsNeeded > freeSlots) {
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT));
|
||||
return; // Fail trade because of the lack of slots
|
||||
}
|
||||
|
||||
if (freeSlotsNeeded - freeSlotsNeeded2 > freeSlots2) {
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL));
|
||||
return; // Fail trade because of the lack of slots
|
||||
}
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
|
||||
if (!(plr->isTrading && plr2->isTrading)) { // both players must be trading
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, resp);
|
||||
resp.iID_Request = plr2->iID;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT));
|
||||
resp.iID_Request = plr->iID;
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT));
|
||||
return;
|
||||
}
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM));
|
||||
// ^^ this is a must have or else the player won't accept a succ packet for some reason
|
||||
// send the confirm packet
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM));
|
||||
|
||||
for (int i = 0; i < freeSlotsNeeded; i++) {
|
||||
plr->Inven[plr->Trade[i].iInvenNum].iID = 0;
|
||||
plr->Inven[plr->Trade[i].iInvenNum].iType = 0;
|
||||
plr->Inven[plr->Trade[i].iInvenNum].iOpt = 0;
|
||||
}
|
||||
if (!(plr2->isTradeConfirm)) {
|
||||
plr->isTradeConfirm = true;
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < freeSlotsNeeded2; i++) {
|
||||
plr2->Inven[plr2->Trade[i].iInvenNum].iID = 0;
|
||||
plr2->Inven[plr2->Trade[i].iInvenNum].iType = 0;
|
||||
plr2->Inven[plr2->Trade[i].iInvenNum].iOpt = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||
if (freeSlotsNeeded <= 0)
|
||||
break;
|
||||
|
||||
if (plr2->Inven[i].iID == 0) {
|
||||
|
||||
plr2->Inven[i].iID = plr->Trade[freeSlotsNeeded - 1].iID;
|
||||
plr2->Inven[i].iType = plr->Trade[freeSlotsNeeded - 1].iType;
|
||||
plr2->Inven[i].iOpt = plr->Trade[freeSlotsNeeded - 1].iOpt;
|
||||
plr->Trade[freeSlotsNeeded - 1].iInvenNum = i;
|
||||
freeSlotsNeeded--;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||
if (freeSlotsNeeded2 <= 0)
|
||||
break;
|
||||
|
||||
if (plr->Inven[i].iID == 0) {
|
||||
|
||||
plr->Inven[i].iID = plr2->Trade[freeSlotsNeeded2 - 1].iID;
|
||||
plr->Inven[i].iType = plr2->Trade[freeSlotsNeeded2 - 1].iType;
|
||||
plr->Inven[i].iOpt = plr2->Trade[freeSlotsNeeded2 - 1].iOpt;
|
||||
plr2->Trade[freeSlotsNeeded2 - 1].iInvenNum = i;
|
||||
freeSlotsNeeded2--;
|
||||
}
|
||||
}
|
||||
// both players are no longer trading
|
||||
plr->isTrading = false;
|
||||
plr2->isTrading = false;
|
||||
plr->isTradeConfirm = false;
|
||||
plr2->isTradeConfirm = false;
|
||||
|
||||
if (doTrade(plr, plr2)) { // returns false if not enough slots
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_SUCC, resp2);
|
||||
|
||||
resp2.iID_Request = pacdat->iID_Request;
|
||||
resp2.iID_From = pacdat->iID_From;
|
||||
resp2.iID_To = pacdat->iID_To;
|
||||
|
||||
plr->money = plr->money + plr2->moneyInTrade - plr->moneyInTrade;
|
||||
resp2.iCandy = plr->money;
|
||||
|
||||
memcpy(resp2.Item, plr2->Trade, sizeof(plr2->Trade));
|
||||
memcpy(resp2.ItemStay, plr->Trade, sizeof(plr->Trade));
|
||||
|
||||
@ -617,152 +488,223 @@ void ItemManager::itemTradeConfirmHandler(CNSocket* sock, CNPacketData* data) {
|
||||
|
||||
plr2->money = plr2->money + plr->moneyInTrade - plr2->moneyInTrade;
|
||||
resp2.iCandy = plr2->money;
|
||||
|
||||
memcpy(resp2.Item, plr->Trade, sizeof(plr->Trade));
|
||||
memcpy(resp2.ItemStay, plr2->Trade, sizeof(plr2->Trade));
|
||||
|
||||
otherSock->sendPacket((void*)&resp2, P_FE2CL_REP_PC_TRADE_CONFIRM_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_SUCC));
|
||||
} else {
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, resp);
|
||||
resp.iID_Request = plr2->iID;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
plr->isTradeConfirm = true;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM));
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT));
|
||||
resp.iID_Request = plr->iID;
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_ABORT));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeConfirmCancelHandler(CNSocket* sock, CNPacketData* data) {
|
||||
bool ItemManager::doTrade(Player* plr, Player* plr2) {
|
||||
// init dummy inventories
|
||||
sItemBase plrInven[AINVEN_COUNT];
|
||||
sItemBase plr2Inven[AINVEN_COUNT];
|
||||
memcpy(plrInven, plr->Inven, AINVEN_COUNT * sizeof(sItemBase));
|
||||
memcpy(plr2Inven, plr2->Inven, AINVEN_COUNT * sizeof(sItemBase));
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
// remove items offered by us
|
||||
if (plr->Trade[i].iID != 0) {
|
||||
if (plrInven[plr->Trade[i].iInvenNum].iID == 0) // pulling a fast one on us
|
||||
return false;
|
||||
|
||||
// for stacked items
|
||||
plrInven[plr->Trade[i].iInvenNum].iOpt -= plr->Trade[i].iOpt;
|
||||
|
||||
if (plrInven[plr->Trade[i].iInvenNum].iOpt == 0) {
|
||||
plrInven[plr->Trade[i].iInvenNum].iID = 0;
|
||||
plrInven[plr->Trade[i].iInvenNum].iType = 0;
|
||||
plrInven[plr->Trade[i].iInvenNum].iOpt = 0;
|
||||
} else if (plrInven[plr->Trade[i].iInvenNum].iOpt < 0) { // another dupe attempt
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (plr2->Trade[i].iID != 0) {
|
||||
if (plr2Inven[plr2->Trade[i].iInvenNum].iID == 0) // pulling a fast one on us
|
||||
return false;
|
||||
|
||||
// for stacked items
|
||||
plr2Inven[plr2->Trade[i].iInvenNum].iOpt -= plr2->Trade[i].iOpt;
|
||||
|
||||
if (plr2Inven[plr2->Trade[i].iInvenNum].iOpt == 0) {
|
||||
plr2Inven[plr2->Trade[i].iInvenNum].iID = 0;
|
||||
plr2Inven[plr2->Trade[i].iInvenNum].iType = 0;
|
||||
plr2Inven[plr2->Trade[i].iInvenNum].iOpt = 0;
|
||||
} else if (plr2Inven[plr2->Trade[i].iInvenNum].iOpt < 0) { // another dupe attempt
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// add items offered to us
|
||||
if (plr2->Trade[i].iID != 0) {
|
||||
for (int n = 0; n < AINVEN_COUNT; n++) {
|
||||
if (plrInven[n].iID == 0) {
|
||||
plrInven[n].iID = plr2->Trade[i].iID;
|
||||
plrInven[n].iType = plr2->Trade[i].iType;
|
||||
plrInven[n].iOpt = plr2->Trade[i].iOpt;
|
||||
plr2->Trade[i].iInvenNum = n;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n >= AINVEN_COUNT - 1)
|
||||
return false; // not enough space
|
||||
}
|
||||
}
|
||||
|
||||
if (plr->Trade[i].iID != 0) {
|
||||
for (int n = 0; n < AINVEN_COUNT; n++) {
|
||||
if (plr2Inven[n].iID == 0) {
|
||||
plr2Inven[n].iID = plr->Trade[i].iID;
|
||||
plr2Inven[n].iType = plr->Trade[i].iType;
|
||||
plr2Inven[n].iOpt = plr->Trade[i].iOpt;
|
||||
plr->Trade[i].iInvenNum = n;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n >= AINVEN_COUNT - 1)
|
||||
return false; // not enough space
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if everything went well, back into player inventory it goes
|
||||
memcpy(plr->Inven, plrInven, AINVEN_COUNT * sizeof(sItemBase));
|
||||
memcpy(plr2->Inven, plr2Inven, AINVEN_COUNT * sizeof(sItemBase));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ItemManager::tradeConfirmCancel(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL* pacdat = (sP_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL*)data->buf;
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL, resp);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
CNSocket* otherSock; // weird flip flop because we need to know who the other player is
|
||||
if (pacdat->iID_Request == pacdat->iID_From)
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
else
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
int iID_Check;
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
}
|
||||
}
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
Player* plr2 = PlayerManager::getPlayer(otherSock);
|
||||
|
||||
// both players are not trading nor are in a confirmed state
|
||||
plr->isTrading = false;
|
||||
plr->isTradeConfirm = false;
|
||||
plr2->isTrading = false;
|
||||
plr2->isTradeConfirm = false;
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL, sizeof(sP_FE2CL_REP_PC_TRADE_CONFIRM_CANCEL));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeRegisterItemHandler(CNSocket* sock, CNPacketData* data) {
|
||||
void ItemManager::tradeRegisterItem(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_ITEM_REGISTER))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_ITEM_REGISTER* pacdat = (sP_CL2FE_REQ_PC_TRADE_ITEM_REGISTER*)data->buf;
|
||||
|
||||
if (pacdat->Item.iSlotNum < 0 || pacdat->Item.iSlotNum > 4)
|
||||
return; // sanity check
|
||||
return; // sanity check, there are only 5 trade slots
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC, resp);
|
||||
CNSocket* otherSock; // weird flip flop because we need to know who the other player is
|
||||
if (pacdat->iID_Request == pacdat->iID_From)
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
else
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
resp.TradeItem = pacdat->Item;
|
||||
resp.InvenItem = pacdat->Item;
|
||||
|
||||
int iID_Check;
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
}
|
||||
}
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
plr->Trade[pacdat->Item.iSlotNum] = pacdat->Item;
|
||||
plr->isTradeConfirm = false;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeUnregisterItemHandler(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER* pacdat = (sP_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER*)data->buf;
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_ITEM_UNREGISTER_SUCC, resp);
|
||||
// since you can spread items like gumballs over multiple slots, we need to count them all
|
||||
// to make sure the inventory shows the right value during trade.
|
||||
int count = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (plr->Trade[i].iInvenNum == pacdat->Item.iInvenNum)
|
||||
count += plr->Trade[i].iOpt;
|
||||
}
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
resp.TradeItem = pacdat->Item;
|
||||
resp.InvenItem = pacdat->Item;
|
||||
resp.InvenItem.iOpt = plr->Inven[pacdat->Item.iInvenNum].iOpt - count; // subtract this count
|
||||
|
||||
if (resp.InvenItem.iOpt < 0) // negative count items, doTrade() will block this later on
|
||||
std::cout << "[WARN] tradeRegisterItem: an item went negative count client side." << std::endl;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_ITEM_REGISTER_SUCC));
|
||||
}
|
||||
|
||||
void ItemManager::tradeUnregisterItem(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER* pacdat = (sP_CL2FE_REQ_PC_TRADE_ITEM_UNREGISTER*)data->buf;
|
||||
|
||||
if (pacdat->Item.iSlotNum < 0 || pacdat->Item.iSlotNum > 4)
|
||||
return; // sanity check, there are only 5 trade slots
|
||||
|
||||
CNSocket* otherSock; // weird flip flop because we need to know who the other player is
|
||||
if (pacdat->iID_Request == pacdat->iID_From)
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
else
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
resp.InvenItem = plr->Trade[pacdat->Item.iSlotNum];
|
||||
plr->isTradeConfirm = false;
|
||||
|
||||
int iID_Check;
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_ITEM_UNREGISTER_SUCC, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
resp.TradeItem = pacdat->Item;
|
||||
resp.InvenItem = plr->Trade[pacdat->Item.iSlotNum];
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
memset(&plr->Trade[pacdat->Item.iSlotNum], 0, sizeof(plr->Trade[pacdat->Item.iSlotNum])); // clean up item slot
|
||||
|
||||
// since you can spread items like gumballs over multiple slots, we need to count them all
|
||||
// to make sure the inventory shows the right value during trade.
|
||||
int count = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (plr->Trade[i].iInvenNum == resp.InvenItem.iInvenNum)
|
||||
count += plr->Trade[i].iOpt;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
int temp_num = pacdat->Item.iSlotNum;
|
||||
|
||||
if (temp_num >= 0 && temp_num <= 4) {
|
||||
plr->Trade[temp_num].iID = 0;
|
||||
plr->Trade[temp_num].iType = 0;
|
||||
plr->Trade[temp_num].iOpt = 0;
|
||||
plr->Trade[temp_num].iInvenNum = 0;
|
||||
plr->Trade[temp_num].iSlotNum = 0;
|
||||
}
|
||||
resp.InvenItem.iOpt = plr->Inven[resp.InvenItem.iInvenNum].iOpt - count; // subtract this count
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_ITEM_UNREGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_ITEM_UNREGISTER_SUCC));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_ITEM_UNREGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_ITEM_UNREGISTER_SUCC));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeRegisterCashHandler(CNSocket* sock, CNPacketData* data) {
|
||||
void ItemManager::tradeRegisterCash(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_CASH_REGISTER))
|
||||
return; // ignore the malformed packet
|
||||
|
||||
@ -773,71 +715,57 @@ void ItemManager::itemTradeRegisterCashHandler(CNSocket* sock, CNPacketData* dat
|
||||
if (pacdat->iCandy < 0 || pacdat->iCandy > plr->money)
|
||||
return; // famous glitch, begone
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC, resp);
|
||||
CNSocket* otherSock; // weird flip flop because we need to know who the other player is
|
||||
if (pacdat->iID_Request == pacdat->iID_From)
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
else
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC, resp);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
resp.iCandy = pacdat->iCandy;
|
||||
|
||||
int iID_Check;
|
||||
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = sock;
|
||||
|
||||
for (auto pair : PlayerManager::players) {
|
||||
if (pair.second->iID == iID_Check) {
|
||||
otherSock = pair.first;
|
||||
}
|
||||
}
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC));
|
||||
|
||||
plr->moneyInTrade = pacdat->iCandy;
|
||||
plr->isTradeConfirm = false;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC, sizeof(sP_FE2CL_REP_PC_TRADE_CASH_REGISTER_SUCC));
|
||||
}
|
||||
|
||||
void ItemManager::itemTradeChatHandler(CNSocket* sock, CNPacketData* data) {
|
||||
void ItemManager::tradeChat(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT))
|
||||
return; // malformed packet
|
||||
sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT* pacdat = (sP_CL2FE_REQ_PC_TRADE_EMOTES_CHAT*)data->buf;
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT, resp);
|
||||
Player *plr = PlayerManager::getPlayer(sock);
|
||||
CNSocket* otherSock; // weird flip flop because we need to know who the other player is
|
||||
if (pacdat->iID_Request == pacdat->iID_From)
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_To);
|
||||
else
|
||||
otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
||||
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
|
||||
std::string fullChat = ChatManager::sanitizeText(U16toU8(pacdat->szFreeChat));
|
||||
U8toU16(fullChat, resp.szFreeChat, sizeof(resp.szFreeChat));
|
||||
|
||||
int iID_Check;
|
||||
if (pacdat->iID_Request == pacdat->iID_From) {
|
||||
iID_Check = pacdat->iID_To;
|
||||
} else {
|
||||
iID_Check = pacdat->iID_From;
|
||||
}
|
||||
|
||||
CNSocket* otherSock = PlayerManager::getSockFromID(iID_Check);;
|
||||
if (otherSock == nullptr)
|
||||
return;
|
||||
|
||||
Player *otherPlr = PlayerManager::getPlayer(otherSock);
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT, resp);
|
||||
Player *plr = PlayerManager::getPlayer(sock);
|
||||
resp.iID_Request = pacdat->iID_Request;
|
||||
resp.iID_From = pacdat->iID_From;
|
||||
resp.iID_To = pacdat->iID_To;
|
||||
std::string fullChat = ChatManager::sanitizeText(U16toU8(pacdat->szFreeChat));
|
||||
U8toU16(fullChat, resp.szFreeChat, sizeof(resp.szFreeChat));
|
||||
|
||||
std::string logLine = "[TradeChat] " + PlayerManager::getPlayerName(plr) + " (to " + PlayerManager::getPlayerName(otherPlr) + "): " + fullChat;
|
||||
|
||||
std::cout << logLine << std::endl;
|
||||
ChatManager::dump.push_back(logLine);
|
||||
|
||||
resp.iEmoteCode = pacdat->iEmoteCode;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT));
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_EMOTES_CHAT, sizeof(sP_FE2CL_REP_PC_TRADE_EMOTES_CHAT));
|
||||
}
|
||||
|
@ -44,15 +44,16 @@ namespace ItemManager {
|
||||
void itemUseHandler(CNSocket* sock, CNPacketData* data);
|
||||
// Bank
|
||||
void itemBankOpenHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeOfferHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeOfferAcceptHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeOfferRefusalHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeConfirmHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeConfirmCancelHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeRegisterItemHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeUnregisterItemHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeRegisterCashHandler(CNSocket* sock, CNPacketData* data);
|
||||
void itemTradeChatHandler(CNSocket* sock, CNPacketData* data);
|
||||
void tradeOffer(CNSocket* sock, CNPacketData* data);
|
||||
void tradeOfferAccept(CNSocket* sock, CNPacketData* data);
|
||||
void tradeOfferRefusal(CNSocket* sock, CNPacketData* data);
|
||||
void tradeConfirm(CNSocket* sock, CNPacketData* data);
|
||||
bool doTrade(Player* plr, Player* plr2);
|
||||
void tradeConfirmCancel(CNSocket* sock, CNPacketData* data);
|
||||
void tradeRegisterItem(CNSocket* sock, CNPacketData* data);
|
||||
void tradeUnregisterItem(CNSocket* sock, CNPacketData* data);
|
||||
void tradeRegisterCash(CNSocket* sock, CNPacketData* data);
|
||||
void tradeChat(CNSocket* sock, CNPacketData* data);
|
||||
void chestOpenHandler(CNSocket* sock, CNPacketData* data);
|
||||
|
||||
// crate opening logic with all helper functions
|
||||
|
Loading…
Reference in New Issue
Block a user