mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 11:50:04 +00:00
vehicle has a proper expiration day when bought, implemented checking expired vehicles while login
This commit is contained in:
parent
00f64ce992
commit
5a58908462
@ -432,8 +432,9 @@ Player Database::DbToPlayer(DbPlayer player) {
|
||||
result.aSkywayLocationFlag[1] = player.SkywayLocationFlag2;
|
||||
|
||||
Database::getInventory(&result);
|
||||
Database::removeExpiredVehicles(&result);
|
||||
Database::getNanos(&result);
|
||||
Database::getQuests(&result);
|
||||
Database::getQuests(&result);
|
||||
|
||||
std::vector<char>::iterator it = player.QuestFlag.begin();
|
||||
for (int i = 0; i < 16; i++)
|
||||
@ -606,6 +607,39 @@ void Database::getInventory(Player* player) {
|
||||
player->QInven[current.slot - AEQUIP_COUNT - AINVEN_COUNT - ABANK_COUNT] = toSet;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Database::removeExpiredVehicles(Player* player) {
|
||||
uint64_t currentTime = getTime();
|
||||
//remove from bank immediately
|
||||
for (int i = 0; i < ABANK_COUNT; i++) {
|
||||
if (player->Bank[i].iType == 10 && player->Bank[i].iTimeLimit < currentTime)
|
||||
player->Bank[i] = {};
|
||||
}
|
||||
//for the rest, we want to leave only 1 expired vehicle on player to delete it with the client packet
|
||||
std::vector<sItemBase*> toRemove;
|
||||
|
||||
//equiped vehicle
|
||||
if (player->Equip[8].iOpt > 0 && player->Equip[8].iTimeLimit < currentTime)
|
||||
{
|
||||
toRemove.push_back(&player->Equip[8]);
|
||||
player->toRemoveVehicle.eIL = 0;
|
||||
player->toRemoveVehicle.iSlotNum = 8;
|
||||
}
|
||||
//inventory
|
||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||
if (player->Inven[i].iType == 10 && player->Inven[i].iTimeLimit < currentTime) {
|
||||
toRemove.push_back(&player->Inven[i]);
|
||||
player->toRemoveVehicle.eIL = 1;
|
||||
player->toRemoveVehicle.iSlotNum = i;
|
||||
}
|
||||
}
|
||||
|
||||
//delete all but one vehicles, leave last one for ceremonial deletion
|
||||
for (int i = 1; i < toRemove.size(); i++) {
|
||||
memset(toRemove[i-1], 0, sizeof(sItemBase));
|
||||
}
|
||||
}
|
||||
|
||||
void Database::getNanos(Player* player) {
|
||||
|
@ -126,6 +126,7 @@ namespace Database {
|
||||
void updateQuests(Player* player);
|
||||
|
||||
void getInventory(Player* player);
|
||||
void removeExpiredVehicles(Player* player);
|
||||
void getNanos(Player* player);
|
||||
void getQuests(Player* player);
|
||||
|
||||
|
@ -767,3 +767,35 @@ Item* ItemManager::getItemData(int32_t id, int32_t type) {
|
||||
return &ItemData[std::pair<int32_t, int32_t>(id, type)];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ItemManager::checkItemExpire(CNSocket* sock, Player* player) {
|
||||
if (player->toRemoveVehicle.eIL == 0 && player->toRemoveVehicle.iSlotNum == 0)
|
||||
return;
|
||||
|
||||
/* prepare packet
|
||||
* yes, this is a varadic packet, however analyzing client behavior and code
|
||||
* it only checks takes the first item sent into account
|
||||
* yes, this is very stupid
|
||||
* therefore, we delete all but 1 expired vehicle while loading player
|
||||
* to delete the last one here so player gets a notification
|
||||
*/
|
||||
|
||||
const size_t resplen = sizeof(sP_FE2CL_PC_DELETE_TIME_LIMIT_ITEM) + sizeof(sTimeLimitItemDeleteInfo2CL);
|
||||
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
|
||||
// we know it's only one trailing struct, so we can skip full validation
|
||||
uint8_t respbuf[resplen]; // not a variable length array, don't worry
|
||||
sP_FE2CL_PC_DELETE_TIME_LIMIT_ITEM* packet = (sP_FE2CL_PC_DELETE_TIME_LIMIT_ITEM*)respbuf;
|
||||
sTimeLimitItemDeleteInfo2CL* itemData = (sTimeLimitItemDeleteInfo2CL*)(respbuf + sizeof(sP_FE2CL_PC_DELETE_TIME_LIMIT_ITEM));
|
||||
memset(respbuf, 0, resplen);
|
||||
|
||||
packet->iItemListCount = 1;
|
||||
itemData->eIL = player->toRemoveVehicle.eIL;
|
||||
itemData->iSlotNum = player->toRemoveVehicle.iSlotNum;
|
||||
sock->sendPacket((void*)&respbuf, P_FE2CL_PC_DELETE_TIME_LIMIT_ITEM, resplen);
|
||||
|
||||
//delete serverside
|
||||
if (player->toRemoveVehicle.eIL == 0)
|
||||
memset(&player->Equip[8], 0, sizeof(sItemBase));
|
||||
else
|
||||
memset(&player->Inven[player->toRemoveVehicle.iSlotNum], 0, sizeof(sItemBase));
|
||||
}
|
||||
|
@ -47,4 +47,5 @@ namespace ItemManager {
|
||||
|
||||
int findFreeSlot(Player *plr);
|
||||
Item* getItemData(int32_t id, int32_t type);
|
||||
void checkItemExpire(CNSocket* sock, Player* player);
|
||||
}
|
||||
|
@ -115,6 +115,11 @@ void NPCManager::npcVendorBuy(CNSocket* sock, CNPacketData* data) {
|
||||
sock->sendPacket((void*)&failResp, P_FE2CL_REP_PC_VENDOR_ITEM_BUY_FAIL, sizeof(sP_FE2CL_REP_PC_VENDOR_ITEM_BUY_FAIL));
|
||||
return;
|
||||
}
|
||||
// if vehicle
|
||||
if (req->Item.iType == 10)
|
||||
// set time limit: current time + 7days
|
||||
req->Item.iTimeLimit = getTime() + 604800;
|
||||
|
||||
|
||||
if (slot != req->iInvenSlotNum) {
|
||||
// possible item stacking?
|
||||
|
@ -49,4 +49,6 @@ struct Player {
|
||||
int RemainingNPCCount[ACTIVE_MISSION_COUNT][3];
|
||||
sItemBase QInven[AQINVEN_COUNT];
|
||||
int32_t CurrentMissionID;
|
||||
|
||||
sTimeLimitItemDeleteInfo2CL toRemoveVehicle;
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "CNShardServer.hpp"
|
||||
#include "CNShared.hpp"
|
||||
#include "MissionManager.hpp"
|
||||
#include "ItemManager.hpp"
|
||||
|
||||
#include "settings.hpp"
|
||||
|
||||
@ -283,6 +284,8 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
sock->sendPacket((void*)&motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN));
|
||||
|
||||
addPlayer(sock, plr);
|
||||
//check if there is an expiring vehicle
|
||||
ItemManager::checkItemExpire(sock, getPlayer(sock));
|
||||
}
|
||||
|
||||
void PlayerManager::sendToViewable(CNSocket* sock, void* buf, uint32_t type, size_t size) {
|
||||
|
Loading…
Reference in New Issue
Block a user