mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 13:30:06 +00:00
Buddy DB integration
This commit is contained in:
parent
803f1a246a
commit
7be79010fc
@ -3,6 +3,7 @@
|
||||
#include "ChatManager.hpp"
|
||||
#include "PlayerManager.hpp"
|
||||
#include "BuddyManager.hpp"
|
||||
#include "Database.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
@ -22,6 +23,54 @@ void BuddyManager::init() {
|
||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_BUDDY_WARP, reqBuddyWarp);
|
||||
}
|
||||
|
||||
// Refresh buddy list
|
||||
void BuddyManager::refreshBuddyList(CNSocket* sock) {
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
int buddyCnt = Database::getNumBuddies(plr);
|
||||
|
||||
if (!validOutVarPacket(sizeof(sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC), buddyCnt, sizeof(sBuddyBaseInfo))) {
|
||||
std::cout << "[WARN] bad sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC packet size\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize response struct
|
||||
size_t resplen = sizeof(sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC) + buddyCnt * sizeof(sBuddyBaseInfo);
|
||||
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
||||
|
||||
memset(respbuf, 0, resplen);
|
||||
|
||||
sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC* resp = (sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC*)respbuf;
|
||||
sBuddyBaseInfo* respdata = (sBuddyBaseInfo*)(respbuf + sizeof(sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC));
|
||||
|
||||
// base response fields
|
||||
resp->iBuddyCnt = buddyCnt;
|
||||
resp->iID = plr->iID;
|
||||
resp->iPCUID = plr->PCStyle.iPC_UID;
|
||||
resp->iListNum = 0; // ???
|
||||
|
||||
int buddyIndex = 0;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
int64_t buddyID = plr->buddyIDs[i];
|
||||
if (buddyID != 0) {
|
||||
sBuddyBaseInfo buddyInfo = {};
|
||||
Database::DbPlayer buddyPlayerData = Database::getDbPlayerById(buddyID);
|
||||
buddyInfo.bBlocked = 0;
|
||||
buddyInfo.bFreeChat = 1;
|
||||
buddyInfo.iGender = buddyPlayerData.Gender;
|
||||
buddyInfo.iID = buddyID;
|
||||
buddyInfo.iPCUID = buddyID;
|
||||
buddyInfo.iNameCheckFlag = buddyPlayerData.NameCheck;
|
||||
buddyInfo.iPCState = buddyPlayerData.PCState;
|
||||
U8toU16(buddyPlayerData.FirstName, buddyInfo.szFirstName, sizeof(buddyInfo.szFirstName));
|
||||
U8toU16(buddyPlayerData.LastName, buddyInfo.szLastName, sizeof(buddyInfo.szLastName));
|
||||
respdata[buddyIndex] = buddyInfo;
|
||||
buddyIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
sock->sendPacket((void*)respbuf, P_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC, resplen);
|
||||
}
|
||||
|
||||
// Buddy request
|
||||
void BuddyManager::requestBuddy(CNSocket* sock, CNPacketData* data) {
|
||||
if (data->size != sizeof(sP_CL2FE_REQ_REQUEST_MAKE_BUDDY))
|
||||
@ -321,17 +370,32 @@ void BuddyManager::reqBuddyDelete(CNSocket* sock, CNPacketData* data) {
|
||||
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
|
||||
// remove buddy on our side
|
||||
INITSTRUCT(sP_FE2CL_REP_REMOVE_BUDDY_SUCC, resp);
|
||||
|
||||
resp.iBuddyPCUID = pkt->iBuddyPCUID;
|
||||
resp.iBuddySlot = pkt->iBuddySlot;
|
||||
|
||||
if (pkt->iBuddySlot < 0 || pkt->iBuddySlot >= 50)
|
||||
return; // sanity check
|
||||
|
||||
plr->buddyIDs[resp.iBuddySlot] = 0;
|
||||
|
||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_REMOVE_BUDDY_SUCC, sizeof(sP_FE2CL_REP_REMOVE_BUDDY_SUCC));
|
||||
|
||||
// remove buddy on their side, reusing the struct
|
||||
CNSocket* otherSock = PlayerManager::getSockFromID(pkt->iBuddyPCUID);
|
||||
if (otherSock == nullptr)
|
||||
return; // other player isn't online, no broadcast needed
|
||||
Player* otherPlr = PlayerManager::getPlayer(otherSock);
|
||||
// search for the slot with the requesting player's ID
|
||||
resp.iBuddyPCUID = plr->PCStyle.iPC_UID;
|
||||
for (int i = 0; i < 50; i++) {
|
||||
if (otherPlr->buddyIDs[i] == plr->PCStyle.iPC_UID) {
|
||||
// remove buddy
|
||||
otherPlr->buddyIDs[i] = 0;
|
||||
// broadcast
|
||||
resp.iBuddySlot = i;
|
||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_REMOVE_BUDDY_SUCC, sizeof(sP_FE2CL_REP_REMOVE_BUDDY_SUCC));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Warping to buddy
|
||||
|
@ -11,6 +11,9 @@
|
||||
namespace BuddyManager {
|
||||
void init();
|
||||
|
||||
// Buddy list
|
||||
void refreshBuddyList(CNSocket* sock);
|
||||
|
||||
// Buddy requests
|
||||
void requestBuddy(CNSocket* sock, CNPacketData* data);
|
||||
void reqBuddyByName(CNSocket* sock, CNPacketData* data);
|
||||
|
@ -93,6 +93,11 @@ auto db = make_storage("database.db",
|
||||
make_column("RemainingNPCCount1", &Database::DbQuest::RemainingNPCCount1),
|
||||
make_column("RemainingNPCCount2", &Database::DbQuest::RemainingNPCCount2),
|
||||
make_column("RemainingNPCCount3", &Database::DbQuest::RemainingNPCCount3)
|
||||
),
|
||||
make_table("Buddyships",
|
||||
make_column("PlayerAId", &Database::Buddyship::PlayerAId),
|
||||
make_column("PlayerBId", &Database::Buddyship::PlayerBId),
|
||||
make_column("Status", &Database::Buddyship::Status)
|
||||
)
|
||||
);
|
||||
|
||||
@ -463,6 +468,7 @@ Player Database::DbToPlayer(DbPlayer player) {
|
||||
Database::removeExpiredVehicles(&result);
|
||||
Database::getNanos(&result);
|
||||
Database::getQuests(&result);
|
||||
Database::getBuddies(&result);
|
||||
|
||||
// load completed quests
|
||||
memcpy(&result.aQuestFlag, player.QuestFlag.data(), std::min(sizeof(result.aQuestFlag), player.QuestFlag.size()));
|
||||
@ -492,6 +498,7 @@ void Database::updatePlayer(Player *player) {
|
||||
updateInventory(player);
|
||||
updateNanos(player);
|
||||
updateQuests(player);
|
||||
updateBuddies(player);
|
||||
}
|
||||
|
||||
void Database::updateInventory(Player *player){
|
||||
@ -604,6 +611,27 @@ void Database::updateQuests(Player* player) {
|
||||
db.commit();
|
||||
}
|
||||
|
||||
void Database::updateBuddies(Player* player) {
|
||||
db.begin_transaction();
|
||||
|
||||
db.remove_all<Buddyship>( // remove all buddyships with this player involved
|
||||
where(c(&Buddyship::PlayerAId) == player->iID || c(&Buddyship::PlayerBId) == player->iID)
|
||||
);
|
||||
|
||||
// iterate through player's buddies and add records for each non-zero entry
|
||||
for (int i = 0; i < 50; i++) {
|
||||
if (player->buddyIDs[i] != 0) {
|
||||
Buddyship record;
|
||||
record.PlayerAId = player->iID;
|
||||
record.PlayerBId = player->buddyIDs[i];
|
||||
record.Status = 0; // still not sure how we'll handle blocking
|
||||
db.insert(record);
|
||||
}
|
||||
}
|
||||
|
||||
db.commit();
|
||||
}
|
||||
|
||||
void Database::getInventory(Player* player) {
|
||||
// get items from DB
|
||||
auto items = db.get_all<Inventory>(
|
||||
@ -691,4 +719,28 @@ void Database::getQuests(Player* player) {
|
||||
}
|
||||
}
|
||||
|
||||
void Database::getBuddies(Player* player) {
|
||||
auto buddies = db.get_all<Buddyship>( // player can be on either side
|
||||
where(c(&Buddyship::PlayerAId) == player->iID || c(&Buddyship::PlayerBId) == player->iID)
|
||||
);
|
||||
|
||||
// there should never be more than 50 buddyships per player, but just in case
|
||||
for (int i = 0; i < 50 && i < buddies.size(); i++) {
|
||||
// if the player is player A, then the buddy is player B, and vice versa
|
||||
player->buddyIDs[i] = player->iID == buddies.at(i).PlayerAId
|
||||
? buddies.at(i).PlayerBId : buddies.at(i).PlayerAId;
|
||||
}
|
||||
}
|
||||
|
||||
int Database::getNumBuddies(Player* player) {
|
||||
std::lock_guard<std::mutex> lock(dbCrit);
|
||||
|
||||
auto buddies = db.get_all<Buddyship>( // player can be on either side
|
||||
where(c(&Buddyship::PlayerAId) == player->iID || c(&Buddyship::PlayerBId) == player->iID)
|
||||
);
|
||||
|
||||
// again, for peace of mind
|
||||
return buddies.size() > 50 ? 50 : buddies.size();
|
||||
}
|
||||
|
||||
#pragma endregion ShardServer
|
||||
|
@ -79,6 +79,11 @@ namespace Database {
|
||||
int RemainingNPCCount2;
|
||||
int RemainingNPCCount3;
|
||||
};
|
||||
struct Buddyship {
|
||||
int PlayerAId;
|
||||
int PlayerBId;
|
||||
int16_t Status;
|
||||
};
|
||||
|
||||
|
||||
#pragma endregion DatabaseStructs
|
||||
@ -121,11 +126,14 @@ namespace Database {
|
||||
void updateInventory(Player *player);
|
||||
void updateNanos(Player *player);
|
||||
void updateQuests(Player* player);
|
||||
void updateBuddies(Player* player);
|
||||
|
||||
void getInventory(Player* player);
|
||||
void removeExpiredVehicles(Player* player);
|
||||
void getNanos(Player* player);
|
||||
void getQuests(Player* player);
|
||||
void getBuddies(Player* player);
|
||||
int getNumBuddies(Player* player);
|
||||
|
||||
// parsing blobs
|
||||
void appendBlob(std::vector<char>*blob, int64_t input);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "GroupManager.hpp"
|
||||
#include "ChatManager.hpp"
|
||||
#include "Database.hpp"
|
||||
#include "BuddyManager.hpp"
|
||||
|
||||
#include "settings.hpp"
|
||||
|
||||
@ -403,6 +404,9 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
|
||||
MissionManager::failInstancedMissions(sock);
|
||||
|
||||
// send over buddy list
|
||||
BuddyManager::refreshBuddyList(sock);
|
||||
|
||||
for (auto& pair : PlayerManager::players)
|
||||
if (pair.second.plr->notify)
|
||||
ChatManager::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(&plr) + " has joined.");
|
||||
|
Loading…
Reference in New Issue
Block a user