DB async query synching to peers, code/logging cleanup
This commit is contained in:
parent
2a133292b0
commit
1ba65aba78
@ -7360,7 +7360,7 @@ void Player::SaveCustomSpellFields(LuaSpell* luaspell) {
|
|||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT INTO character_custom_spell_data (charid, spell_id, field, type, value) VALUES (%u, %u, '%s', '%s', '%s')",
|
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT IGNORE INTO character_custom_spell_data (charid, spell_id, field, type, value) VALUES (%u, %u, '%s', '%s', '%s')",
|
||||||
GetCharacterID(),
|
GetCharacterID(),
|
||||||
luaspell->spell->GetSpellData()->inherited_spell_id,
|
luaspell->spell->GetSpellData()->inherited_spell_id,
|
||||||
database.getSafeEscapeString(field.c_str()).c_str(),
|
database.getSafeEscapeString(field.c_str()).c_str(),
|
||||||
@ -7407,7 +7407,7 @@ void Player::SaveCustomSpellDataIndex(LuaSpell* luaspell) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT INTO character_custom_spell_dataindex (charid, spell_id, idx, type, value1, value2) VALUES (%u, %u, %d, '%s', '%s', '%s')", GetCharacterID(),
|
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT IGNORE INTO character_custom_spell_dataindex (charid, spell_id, idx, type, value1, value2) VALUES (%u, %u, %d, '%s', '%s', '%s')", GetCharacterID(),
|
||||||
luaspell->spell->GetSpellData()->inherited_spell_id,
|
luaspell->spell->GetSpellData()->inherited_spell_id,
|
||||||
i,
|
i,
|
||||||
type.c_str(), value1.c_str(), value2.c_str());
|
type.c_str(), value1.c_str(), value2.c_str());
|
||||||
@ -7428,14 +7428,14 @@ void Player::SaveCustomSpellEffectsDisplay(LuaSpell* luaspell) {
|
|||||||
|
|
||||||
std::string charid = std::to_string(GetCharacterID());
|
std::string charid = std::to_string(GetCharacterID());
|
||||||
|
|
||||||
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT INTO character_custom_spell_display (charid, spell_id, idx, field, value) VALUES (%u, %u, %d, 'description', '%s')",
|
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT IGNORE INTO character_custom_spell_display (charid, spell_id, idx, field, value) VALUES (%u, %u, %d, 'description', '%s')",
|
||||||
GetCharacterID(), luaspell->spell->GetSpellData()->inherited_spell_id, i,
|
GetCharacterID(), luaspell->spell->GetSpellData()->inherited_spell_id, i,
|
||||||
database.getSafeEscapeString(eff->description.c_str()).c_str());
|
database.getSafeEscapeString(eff->description.c_str()).c_str());
|
||||||
|
|
||||||
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT INTO character_custom_spell_display (charid, spell_id, idx, field, value) VALUES (%u, %u, %d, 'bullet', '%d')",
|
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT IGNORE INTO character_custom_spell_display (charid, spell_id, idx, field, value) VALUES (%u, %u, %d, 'bullet', '%d')",
|
||||||
GetCharacterID(), luaspell->spell->GetSpellData()->inherited_spell_id, i, eff->subbullet);
|
GetCharacterID(), luaspell->spell->GetSpellData()->inherited_spell_id, i, eff->subbullet);
|
||||||
|
|
||||||
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT INTO character_custom_spell_display (charid, spell_id, idx, field, value) VALUES (%u, %u, %d, 'percentage', '%d')",
|
savedEffects.AddQueryAsync(GetCharacterID(), &database, Q_INSERT, "INSERT IGNORE INTO character_custom_spell_display (charid, spell_id, idx, field, value) VALUES (%u, %u, %d, 'percentage', '%d')",
|
||||||
GetCharacterID(), luaspell->spell->GetSpellData()->inherited_spell_id, i, eff->percentage);
|
GetCharacterID(), luaspell->spell->GetSpellData()->inherited_spell_id, i, eff->percentage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7443,7 +7443,7 @@ void Player::SaveSpellEffects()
|
|||||||
{
|
{
|
||||||
if(stop_save_spell_effects)
|
if(stop_save_spell_effects)
|
||||||
{
|
{
|
||||||
LogWrite(PLAYER__WARNING, 0, "Player", "SaveSpellEffects called while player constructing / deconstructing!");
|
LogWrite(PLAYER__WARNING, 0, "Player", "%s: SaveSpellEffects called while player constructing / deconstructing!", GetName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,25 +906,6 @@ int32 PlayerGroupManager::GetGroupSize(int32 group_id) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerGroupManager::SendGroupQuests(int32 group_id, Client* client) {
|
|
||||||
std::shared_lock lock(MGroups);
|
|
||||||
GroupMemberInfo* info = 0;
|
|
||||||
if (m_groups.count(group_id) > 0) {
|
|
||||||
m_groups[group_id]->MGroupMembers.readlock(__FUNCTION__, __LINE__);
|
|
||||||
deque<GroupMemberInfo*>* members = m_groups[group_id]->GetMembers();
|
|
||||||
deque<GroupMemberInfo*>::iterator itr;
|
|
||||||
for (itr = members->begin(); itr != members->end(); itr++) {
|
|
||||||
info = *itr;
|
|
||||||
if (info->client) {
|
|
||||||
LogWrite(PLAYER__DEBUG, 0, "Player", "Send Quest Journal...");
|
|
||||||
info->client->SendQuestJournal(false, client);
|
|
||||||
client->SendQuestJournal(false, info->client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_groups[group_id]->MGroupMembers.releasereadlock(__FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlayerGroupManager::HasGroupCompletedQuest(int32 group_id, int32 quest_id) {
|
bool PlayerGroupManager::HasGroupCompletedQuest(int32 group_id, int32 quest_id) {
|
||||||
std::shared_lock lock(MGroups);
|
std::shared_lock lock(MGroups);
|
||||||
bool questComplete = true;
|
bool questComplete = true;
|
||||||
|
@ -220,7 +220,6 @@ public:
|
|||||||
|
|
||||||
int32 GetGroupSize(int32 group_id);
|
int32 GetGroupSize(int32 group_id);
|
||||||
|
|
||||||
void SendGroupQuests(int32 group_id, Client* client);
|
|
||||||
bool HasGroupCompletedQuest(int32 group_id, int32 quest_id);
|
bool HasGroupCompletedQuest(int32 group_id, int32 quest_id);
|
||||||
|
|
||||||
void SimpleGroupMessage(int32 group_id, const char* message);
|
void SimpleGroupMessage(int32 group_id, const char* message);
|
||||||
|
@ -838,3 +838,21 @@ void PeerManager::sendPeersMessage(const std::string& endpoint, int32 command, i
|
|||||||
peer_https_pool.sendPostRequestToPeerAsync(peer->id, peer->webAddr, std::to_string(peer->webPort), endpoint.c_str(), jsonPayload);
|
peer_https_pool.sendPostRequestToPeerAsync(peer->id, peer->webAddr, std::to_string(peer->webPort), endpoint.c_str(), jsonPayload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PeerManager::sendPeersActiveQuery(int32 character_id, bool remove) {
|
||||||
|
|
||||||
|
boost::property_tree::ptree root;
|
||||||
|
|
||||||
|
root.put("char_id", character_id);
|
||||||
|
root.put("remove", remove);
|
||||||
|
|
||||||
|
std::ostringstream jsonStream;
|
||||||
|
boost::property_tree::write_json(jsonStream, root);
|
||||||
|
std::string jsonPayload = jsonStream.str();
|
||||||
|
for (const auto& [id, peer] : peers) {
|
||||||
|
if (peer->healthCheck.status != HealthStatus::OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
peer_https_pool.sendPostRequestToPeerAsync(peer->id, peer->webAddr, std::to_string(peer->webPort), "/activequery", jsonPayload);
|
||||||
|
}
|
||||||
|
}
|
@ -220,6 +220,7 @@ public:
|
|||||||
std::shared_ptr<Peer> getCurrentPrimary();
|
std::shared_ptr<Peer> getCurrentPrimary();
|
||||||
|
|
||||||
void sendPeersMessage(const std::string& endpoint, int32 command, int32 sub_command = 0);
|
void sendPeersMessage(const std::string& endpoint, int32 command, int32 sub_command = 0);
|
||||||
|
void sendPeersActiveQuery(int32 character_id, bool remove = false);
|
||||||
|
|
||||||
void sendZonePlayerList(std::vector<string>* queries, std::vector<WhoAllPeerPlayer>* peer_list, bool isGM);
|
void sendZonePlayerList(std::vector<string>* queries, std::vector<WhoAllPeerPlayer>* peer_list, bool isGM);
|
||||||
|
|
||||||
|
@ -1377,3 +1377,29 @@ void World::Web_worldhandle_peerstatus(const http::request<http::string_body>& r
|
|||||||
res.body() = json;
|
res.body() = json;
|
||||||
res.prepare_payload();
|
res.prepare_payload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::Web_worldhandle_activequery(const http::request<http::string_body>& req, http::response<http::string_body>& res) {
|
||||||
|
res.set(http::field::content_type, "application/json; charset=utf-8");
|
||||||
|
boost::property_tree::ptree pt, json_tree;
|
||||||
|
|
||||||
|
std::istringstream json_stream(req.body());
|
||||||
|
boost::property_tree::read_json(json_stream, json_tree);
|
||||||
|
|
||||||
|
int32 character_id = 0;
|
||||||
|
bool remove_query = false;
|
||||||
|
if (auto char_id = json_tree.get_optional<int32>("char_id")) {
|
||||||
|
character_id = char_id.get();
|
||||||
|
}
|
||||||
|
if (auto remove = json_tree.get_optional<bool>("remove")) {
|
||||||
|
remove_query = remove.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(character_id) {
|
||||||
|
if(remove_query) {
|
||||||
|
database.RemovePeerActiveQuery(character_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
database.AddPeerActiveQuery(character_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
EQ2Emulator: Everquest II Server Emulator
|
EQ2Emulator: Everquest II Server Emulator
|
||||||
Copyright (C) 2005 - 2025 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net)
|
Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net)
|
||||||
|
|
||||||
This file is part of EQ2Emulator.
|
This file is part of EQ2Emulator.
|
||||||
|
|
||||||
@ -282,6 +282,7 @@ void World::init(std::string web_ipaddr, int16 web_port, std::string cert_file,
|
|||||||
world_webserver->register_route("/setguildeventfilter", World::Web_worldhandle_setguildeventfilter);
|
world_webserver->register_route("/setguildeventfilter", World::Web_worldhandle_setguildeventfilter);
|
||||||
|
|
||||||
world_webserver->register_route("/peerstatus", World::Web_worldhandle_peerstatus);
|
world_webserver->register_route("/peerstatus", World::Web_worldhandle_peerstatus);
|
||||||
|
world_webserver->register_route("/activequery", World::Web_worldhandle_activequery);
|
||||||
world_webserver->run();
|
world_webserver->run();
|
||||||
LogWrite(INIT__INFO, 0, "Init", "World Web Server is listening on %s:%u..", web_ipaddr.c_str(), web_port);
|
LogWrite(INIT__INFO, 0, "Init", "World Web Server is listening on %s:%u..", web_ipaddr.c_str(), web_port);
|
||||||
web_success = true;
|
web_success = true;
|
||||||
@ -377,8 +378,6 @@ void World::Process(){
|
|||||||
WritePlayerStatistics();
|
WritePlayerStatistics();
|
||||||
if (server_stats_timer.Check())
|
if (server_stats_timer.Check())
|
||||||
WriteServerStatistics();
|
WriteServerStatistics();
|
||||||
/*if(remove_grouped_player.Check())
|
|
||||||
CheckRemoveGroupedPlayer();*/
|
|
||||||
if (group_buff_updates.Check())
|
if (group_buff_updates.Check())
|
||||||
GetGroupManager()->UpdateGroupBuffs();
|
GetGroupManager()->UpdateGroupBuffs();
|
||||||
if (guilds_timer.Check())
|
if (guilds_timer.Check())
|
||||||
@ -2104,57 +2103,11 @@ void World::DeleteMerchantsInfo(){
|
|||||||
|
|
||||||
|
|
||||||
void World::DeleteSpawns(){
|
void World::DeleteSpawns(){
|
||||||
//reloading = true;
|
|
||||||
//ClearLootTables();
|
|
||||||
/*
|
|
||||||
map<int32, NPC*>::iterator npc_list_iter;
|
|
||||||
for(npc_list_iter=npc_list.begin();npc_list_iter!=npc_list.end();npc_list_iter++) {
|
|
||||||
safe_delete(npc_list_iter->second);
|
|
||||||
}
|
|
||||||
npc_list.clear();
|
|
||||||
map<int32, Object*>::iterator object_list_iter;
|
|
||||||
for(object_list_iter=object_list.begin();object_list_iter!=object_list.end();object_list_iter++) {
|
|
||||||
safe_delete(object_list_iter->second);
|
|
||||||
}
|
|
||||||
object_list.clear();
|
|
||||||
map<int32, GroundSpawn*>::iterator groundspawn_list_iter;
|
|
||||||
for(groundspawn_list_iter=groundspawn_list.begin();groundspawn_list_iter!=groundspawn_list.end();groundspawn_list_iter++) {
|
|
||||||
safe_delete(groundspawn_list_iter->second);
|
|
||||||
}
|
|
||||||
groundspawn_list.clear();
|
|
||||||
map<int32, Widget*>::iterator widget_list_iter;
|
|
||||||
for(widget_list_iter=widget_list.begin();widget_list_iter!=widget_list.end();widget_list_iter++) {
|
|
||||||
safe_delete(widget_list_iter->second);
|
|
||||||
}
|
|
||||||
widget_list.clear();
|
|
||||||
map<int32, Sign*>::iterator sign_list_iter;
|
|
||||||
for(sign_list_iter=sign_list.begin();sign_list_iter!=sign_list.end();sign_list_iter++) {
|
|
||||||
safe_delete(sign_list_iter->second);
|
|
||||||
}
|
|
||||||
sign_list.clear();*/
|
|
||||||
map<int32, AppearanceData*>::iterator appearance_list_iter;
|
map<int32, AppearanceData*>::iterator appearance_list_iter;
|
||||||
for(appearance_list_iter=npc_appearance_list.begin();appearance_list_iter!=npc_appearance_list.end();appearance_list_iter++) {
|
for(appearance_list_iter=npc_appearance_list.begin();appearance_list_iter!=npc_appearance_list.end();appearance_list_iter++) {
|
||||||
safe_delete(appearance_list_iter->second);
|
safe_delete(appearance_list_iter->second);
|
||||||
}
|
}
|
||||||
npc_appearance_list.clear();
|
npc_appearance_list.clear();
|
||||||
|
|
||||||
/*
|
|
||||||
map<int32, vector<EntityCommand*>* >::iterator command_list_iter;
|
|
||||||
for(command_list_iter=entity_command_list.begin();command_list_iter!=entity_command_list.end();command_list_iter++) {
|
|
||||||
vector<EntityCommand*>* v = command_list_iter->second;
|
|
||||||
if(v){
|
|
||||||
for(int32 i=0;i<v->size();i++){
|
|
||||||
safe_delete(v->at(i));
|
|
||||||
}
|
|
||||||
safe_delete(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entity_command_list.clear();
|
|
||||||
*/
|
|
||||||
|
|
||||||
//DeleteGroundSpawnItems();
|
|
||||||
//DeleteTransporters();
|
|
||||||
//DeleteTransporterMaps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::ReloadGuilds() {
|
void World::ReloadGuilds() {
|
||||||
@ -2216,46 +2169,6 @@ void World::RemoveServerStatistics() {
|
|||||||
server_statistics.clear();
|
server_statistics.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::SendGroupQuests(PlayerGroup* group, Client* client){
|
|
||||||
return;
|
|
||||||
/*if(!group)
|
|
||||||
return;
|
|
||||||
GroupMemberInfo* info = 0;
|
|
||||||
MGroups.readlock(__FUNCTION__, __LINE__);
|
|
||||||
deque<GroupMemberInfo*>::iterator itr;
|
|
||||||
for(itr = group->members.begin(); itr != group->members.end(); itr++){
|
|
||||||
info = *itr;
|
|
||||||
if(info->client){
|
|
||||||
LogWrite(PLAYER__DEBUG, 0, "Player", "Send Quest Journal...");
|
|
||||||
info->client->SendQuestJournal(false, client);
|
|
||||||
client->SendQuestJournal(false, info->client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MGroups.releasereadlock(__FUNCTION__, __LINE__);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*void World::CheckRemoveGroupedPlayer(){
|
|
||||||
map<GroupMemberInfo*, int32>::iterator itr;
|
|
||||||
GroupMemberInfo* found = 0;
|
|
||||||
MGroups.readlock(__FUNCTION__, __LINE__);
|
|
||||||
for(itr = group_removal_pending.begin(); itr != group_removal_pending.end(); itr++){
|
|
||||||
if(itr->second < Timer::GetCurrentTime2()){
|
|
||||||
found = itr->first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MGroups.releasereadlock(__FUNCTION__, __LINE__);
|
|
||||||
if(found){
|
|
||||||
if(!found->client || (found->client && found->client->IsConnected() == false))
|
|
||||||
DeleteGroupMember(found);
|
|
||||||
else{
|
|
||||||
MGroups.writelock(__FUNCTION__, __LINE__);
|
|
||||||
group_removal_pending.erase(found);
|
|
||||||
MGroups.releasewritelock(__FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
bool World::RejoinGroup(Client* client, int32 group_id){
|
bool World::RejoinGroup(Client* client, int32 group_id){
|
||||||
if (!group_id) // no need if no group id!
|
if (!group_id) // no need if no group id!
|
||||||
return false;
|
return false;
|
||||||
|
@ -627,24 +627,7 @@ public:
|
|||||||
sint32 GetServerStatisticValue(int32 stat_id);
|
sint32 GetServerStatisticValue(int32 stat_id);
|
||||||
void RemoveServerStatistics();
|
void RemoveServerStatistics();
|
||||||
|
|
||||||
//PlayerGroup* AddGroup(Client* leader);
|
|
||||||
//void AddGroupMember(PlayerGroup* group, Client* member);
|
|
||||||
//void RemoveGroupMember(Client* member, bool immediate = false);
|
|
||||||
//void DisbandGroup(PlayerGroup* group, bool lock = true);
|
|
||||||
void SendGroupQuests(PlayerGroup* group, Client* client);
|
|
||||||
//void UpdateGroupBuffs();
|
|
||||||
//void RemoveGroupBuffs(PlayerGroup *group, Client *client);
|
|
||||||
//void SetPendingGroup(char* name, char* leader);
|
|
||||||
//void GroupMessage(PlayerGroup* group, const char* message, ...);
|
|
||||||
//void SimpleGroupMessage(PlayerGroup* group, const char* message);
|
|
||||||
//void GroupChatMessage(PlayerGroup* group, Spawn* from, const char* message);
|
|
||||||
//const char* GetPendingGroup(string name);
|
|
||||||
//void GroupReadLock();
|
|
||||||
//void GroupReadUnLock();
|
|
||||||
//void CheckRemoveGroupedPlayer();
|
|
||||||
//void SendGroupUpdate(PlayerGroup* group, Client* exclude = 0);
|
|
||||||
bool RejoinGroup(Client* client, int32 group_id);
|
bool RejoinGroup(Client* client, int32 group_id);
|
||||||
//bool MakeLeader(Client* leader, string new_leader);
|
|
||||||
|
|
||||||
void AddBonuses(Item* item, ItemStatsValues* values, int16 type, float value, Entity* entity);
|
void AddBonuses(Item* item, ItemStatsValues* values, int16 type, float value, Entity* entity);
|
||||||
int32 CreateGuild(const char* guild_name, Client* leader = 0, int32 group_id = 0);
|
int32 CreateGuild(const char* guild_name, Client* leader = 0, int32 group_id = 0);
|
||||||
@ -754,6 +737,7 @@ public:
|
|||||||
static void Web_worldhandle_setguildpermission(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
static void Web_worldhandle_setguildpermission(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
||||||
static void Web_worldhandle_setguildeventfilter(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
static void Web_worldhandle_setguildeventfilter(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
||||||
static void Web_worldhandle_peerstatus(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
static void Web_worldhandle_peerstatus(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
||||||
|
static void Web_worldhandle_activequery(const http::request<http::string_body>& req, http::response<http::string_body>& res);
|
||||||
|
|
||||||
static void Web_populate_status(boost::property_tree::ptree& pt);
|
static void Web_populate_status(boost::property_tree::ptree& pt);
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ void Client::SendLoginInfo() {
|
|||||||
database.LoadCharacterQuestRewards(this);
|
database.LoadCharacterQuestRewards(this);
|
||||||
database.LoadPlayerMail(this);
|
database.LoadPlayerMail(this);
|
||||||
}
|
}
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
LogWrite(CCLIENT__DEBUG, 0, "Client", "Client::SendLoginInfo %s Send Quest Journal...", GetPlayer()->GetName());
|
||||||
SendQuestJournal(true, 0, false);
|
SendQuestJournal(true, 0, false);
|
||||||
|
|
||||||
if (version > 561) // right version? possibly not!
|
if (version > 561) // right version? possibly not!
|
||||||
@ -7204,14 +7204,15 @@ void Client::AddPlayerQuest(Quest* quest, bool call_accepted, bool send_packets)
|
|||||||
quest->SetPlayer(player);
|
quest->SetPlayer(player);
|
||||||
quest->SetSaveNeeded(true);
|
quest->SetSaveNeeded(true);
|
||||||
|
|
||||||
|
LogWrite(CCLIENT__DEBUG, 0, "Client", "Client::AddPlayerQuest %s added quest %s id %u...", GetPlayer()->GetName(), quest->GetName(), quest->GetQuestID());
|
||||||
|
|
||||||
current_quest_id = quest->GetQuestID();
|
current_quest_id = quest->GetQuestID();
|
||||||
if (send_packets && quest->GetQuestGiver() > 0)
|
if (send_packets && quest->GetQuestGiver() > 0)
|
||||||
GetCurrentZone()->SendSpawnChangesByDBID(quest->GetQuestGiver(), this, false, true);
|
GetCurrentZone()->SendSpawnChangesByDBID(quest->GetQuestGiver(), this, false, true);
|
||||||
if (lua_interface && call_accepted)
|
if (lua_interface && call_accepted)
|
||||||
lua_interface->CallQuestFunction(quest, "Accepted", player);
|
lua_interface->CallQuestFunction(quest, "Accepted", player);
|
||||||
|
|
||||||
if (send_packets) {
|
if (send_packets) {
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
|
||||||
//SendQuestJournal();
|
|
||||||
SendQuestJournalUpdate(quest);
|
SendQuestJournalUpdate(quest);
|
||||||
|
|
||||||
// sent twice to match live
|
// sent twice to match live
|
||||||
@ -7240,15 +7241,15 @@ void Client::RemovePlayerQuest(int32 id, bool send_update, bool delete_quest) {
|
|||||||
int32 quest_giver = player->player_quests[id]->GetQuestGiver();
|
int32 quest_giver = player->player_quests[id]->GetQuestGiver();
|
||||||
GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
GetPlayer()->MPlayerQuests.releasewritelock(__FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
LogWrite(CCLIENT__DEBUG, 0, "Client", "Client::RemovePlayerQuest %s remove quest id %u...", GetPlayer()->GetName(), id);
|
||||||
|
|
||||||
if (send_update && quest_giver > 0)
|
if (send_update && quest_giver > 0)
|
||||||
GetCurrentZone()->SendSpawnChangesByDBID(quest_giver, this, false, true);
|
GetCurrentZone()->SendSpawnChangesByDBID(quest_giver, this, false, true);
|
||||||
if (send_update) {
|
if (send_update) {
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
|
||||||
SendQuestJournal(false, 0, true);
|
SendQuestJournal(false, 0, true);
|
||||||
}
|
}
|
||||||
player->RemoveQuest(id, delete_quest);
|
player->RemoveQuest(id, delete_quest);
|
||||||
if (send_update) {
|
if (send_update) {
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
|
||||||
SendQuestJournal(false, 0, true);
|
SendQuestJournal(false, 0, true);
|
||||||
GetCurrentZone()->SendAllSpawnsForVisChange(this);
|
GetCurrentZone()->SendAllSpawnsForVisChange(this);
|
||||||
}
|
}
|
||||||
@ -7290,7 +7291,7 @@ void Client::SendQuestFailure(Quest* quest) {
|
|||||||
for (int32 i = 0; i < failures->size(); i++) {
|
for (int32 i = 0; i < failures->size(); i++) {
|
||||||
step = failures->at(i);
|
step = failures->at(i);
|
||||||
QueuePacket(quest->QuestJournalReply(GetVersion(), GetNameCRC(), player, step, 1, false, true));
|
QueuePacket(quest->QuestJournalReply(GetVersion(), GetNameCRC(), player, step, 1, false, true));
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
LogWrite(CCLIENT__DEBUG, 0, "Client", "Client::SendQuestFailure %s quest failure for %s id %u...", GetPlayer()->GetName(), quest->GetName(), quest->GetQuestID());
|
||||||
SendQuestJournal(false, 0, true);
|
SendQuestJournal(false, 0, true);
|
||||||
}
|
}
|
||||||
failures->clear();
|
failures->clear();
|
||||||
@ -7318,8 +7319,9 @@ void Client::SendQuestUpdate(Quest* quest) {
|
|||||||
QueuePacket(quest->QuestJournalReply(GetVersion(), GetNameCRC(), player, step));
|
QueuePacket(quest->QuestJournalReply(GetVersion(), GetNameCRC(), player, step));
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
if(updated) {
|
||||||
|
LogWrite(CCLIENT__DEBUG, 0, "Client", "Client::SendQuestUpdate %s step %u updated %s id %u...", GetPlayer()->GetName(), step->GetStepID(), quest->GetName(), quest->GetQuestID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (lua_interface && quest->GetCompleted() && quest->GetCompleteAction()) {
|
if (lua_interface && quest->GetCompleted() && quest->GetCompleteAction()) {
|
||||||
lua_interface->CallQuestFunction(quest, quest->GetCompleteAction(), player);
|
lua_interface->CallQuestFunction(quest, quest->GetCompleteAction(), player);
|
||||||
@ -7810,8 +7812,10 @@ void Client::GiveQuestReward(Quest* quest, bool has_displayed) {
|
|||||||
|
|
||||||
AddPendingQuestAcceptReward(quest);
|
AddPendingQuestAcceptReward(quest);
|
||||||
|
|
||||||
|
LogWrite(CCLIENT__DEBUG, 0, "Client", "Client::GiveQuestReward %s completed quest, displaying reward for %s id %u...", GetPlayer()->GetName(), quest->GetName(), quest->GetQuestID());
|
||||||
|
|
||||||
DisplayQuestComplete(quest, quest->GetQuestTemporaryState(), quest->GetQuestTemporaryDescription());
|
DisplayQuestComplete(quest, quest->GetQuestTemporaryState(), quest->GetQuestTemporaryDescription());
|
||||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
|
|
||||||
SendQuestJournal();
|
SendQuestJournal();
|
||||||
|
|
||||||
if (quest->GetQuestTemporaryState()) {
|
if (quest->GetQuestTemporaryState()) {
|
||||||
|
@ -3243,7 +3243,7 @@ bool ZoneServer::CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn, const char
|
|||||||
bool fileExists = (stat(tmpScript.c_str(), &buffer) == 0);
|
bool fileExists = (stat(tmpScript.c_str(), &buffer) == 0);
|
||||||
if (fileExists)
|
if (fileExists)
|
||||||
{
|
{
|
||||||
LogWrite(SPAWN__WARNING, 0, "Spawn", "No script file described in the database, overriding with SpawnScript at %s", (char*)tmpScript.c_str());
|
LogWrite(SPAWN__WARNING, 0, "Spawn", "No script file described in the database for spawn %s with database spawn id %u, overriding with SpawnScript at %s", npc->GetName(), npc->GetDatabaseID(), (char*)tmpScript.c_str());
|
||||||
npc->SetSpawnScript(tmpScript);
|
npc->SetSpawnScript(tmpScript);
|
||||||
script = npc->GetSpawnScript();
|
script = npc->GetSpawnScript();
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,9 @@ using namespace std;
|
|||||||
#include "emu_opcodes.h"
|
#include "emu_opcodes.h"
|
||||||
#ifdef WORLD
|
#ifdef WORLD
|
||||||
#include "../WorldServer/WorldDatabase.h"
|
#include "../WorldServer/WorldDatabase.h"
|
||||||
|
#include "../WorldServer/Web/PeerManager.h"
|
||||||
extern WorldDatabase database;
|
extern WorldDatabase database;
|
||||||
|
extern PeerManager peer_manager;
|
||||||
#endif
|
#endif
|
||||||
#ifdef LOGIN
|
#ifdef LOGIN
|
||||||
#include "../LoginServer/LoginDatabase.h"
|
#include "../LoginServer/LoginDatabase.h"
|
||||||
@ -401,7 +403,7 @@ void Database::RunAsyncQueries(int32 queryid)
|
|||||||
}
|
}
|
||||||
FreeDBInstance(asyncdb);
|
FreeDBInstance(asyncdb);
|
||||||
|
|
||||||
bool isActive = IsActiveQuery(queryid);
|
bool isActive = LocalIsActiveQuery(queryid);
|
||||||
if (isActive)
|
if (isActive)
|
||||||
{
|
{
|
||||||
continueAsync = true;
|
continueAsync = true;
|
||||||
@ -444,7 +446,7 @@ void Database::AddAsyncQuery(Query* query)
|
|||||||
asyncQueriesMutex[query->GetQueryID()]->releasewritelock();
|
asyncQueriesMutex[query->GetQueryID()]->releasewritelock();
|
||||||
DBAsyncMutex.releasewritelock();
|
DBAsyncMutex.releasewritelock();
|
||||||
|
|
||||||
bool isActive = IsActiveQuery(query->GetQueryID(), query);
|
bool isActive = LocalIsActiveQuery(query->GetQueryID(), query);
|
||||||
if (!isActive)
|
if (!isActive)
|
||||||
{
|
{
|
||||||
continueAsync = true;
|
continueAsync = true;
|
||||||
@ -533,35 +535,68 @@ void Database::RemoveActiveQuery(Query* query)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBQueryMutex.releasewritelock(__FUNCTION__, __LINE__);
|
DBQueryMutex.releasewritelock(__FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
bool isActive = LocalIsActiveQuery(query->GetQueryID());
|
||||||
|
if(!isActive) {
|
||||||
|
peer_manager.sendPeersActiveQuery(query->GetQueryID(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::AddActiveQuery(Query* query)
|
void Database::AddActiveQuery(Query* query)
|
||||||
{
|
{
|
||||||
|
peer_manager.sendPeersActiveQuery(query->GetQueryID(), false);
|
||||||
DBQueryMutex.writelock(__FUNCTION__, __LINE__);
|
DBQueryMutex.writelock(__FUNCTION__, __LINE__);
|
||||||
activeQuerySessions.push_back(query);
|
activeQuerySessions.push_back(query);
|
||||||
DBQueryMutex.releasewritelock(__FUNCTION__, __LINE__);
|
DBQueryMutex.releasewritelock(__FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::IsActiveQuery(int32 id, Query* skip)
|
bool Database::IsActiveQuery(int32 id, Query* skip) {
|
||||||
|
if (LocalIsActiveQuery(id, skip))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
std::lock_guard<std::mutex> lock(_peerMtx);
|
||||||
|
|
||||||
|
// remove any entries older than timeout
|
||||||
|
for (auto it = _peerActive.begin(); it != _peerActive.end(); ) {
|
||||||
|
if (now - it->second > kStaleTimeout)
|
||||||
|
it = _peerActive.erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this id is still in the map, it's active
|
||||||
|
if (_peerActive.find(id) != _peerActive.end())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::LocalIsActiveQuery(int32 id, Query* skip)
|
||||||
{
|
{
|
||||||
bool isActive = false;
|
bool isActive = false;
|
||||||
|
|
||||||
DBQueryMutex.readlock(__FUNCTION__, __LINE__);
|
DBQueryMutex.readlock(__FUNCTION__, __LINE__);
|
||||||
vector<Query*>::iterator itr;
|
for (auto query : activeQuerySessions) {
|
||||||
for (itr = activeQuerySessions.begin(); itr != activeQuerySessions.end(); itr++)
|
if (query == skip) continue;
|
||||||
{
|
if (query->GetQueryID() == id) {
|
||||||
Query* query = *itr;
|
|
||||||
if (query == skip)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (query->GetQueryID() == id)
|
|
||||||
{
|
|
||||||
isActive = true;
|
isActive = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBQueryMutex.releasereadlock(__FUNCTION__, __LINE__);
|
DBQueryMutex.releasereadlock(__FUNCTION__, __LINE__);
|
||||||
|
|
||||||
return isActive;
|
return isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::AddPeerActiveQuery(int32 charID) {
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
std::lock_guard<std::mutex> lock(_peerMtx);
|
||||||
|
_peerActive[charID] = now; // inserts or updates timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::RemovePeerActiveQuery(int32 charID) {
|
||||||
|
std::lock_guard<std::mutex> lock(_peerMtx);
|
||||||
|
_peerActive.erase(charID);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
@ -35,6 +35,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
class Query;
|
class Query;
|
||||||
@ -60,12 +63,15 @@ public:
|
|||||||
void AddActiveQuery(Query* query);
|
void AddActiveQuery(Query* query);
|
||||||
bool IsActiveQuery(int32 id, Query* skip=0);
|
bool IsActiveQuery(int32 id, Query* skip=0);
|
||||||
void PingAsyncDatabase();
|
void PingAsyncDatabase();
|
||||||
|
|
||||||
|
void AddPeerActiveQuery(int32 charID);
|
||||||
|
void RemovePeerActiveQuery(int32 charID);
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitVars();
|
void InitVars();
|
||||||
|
bool LocalIsActiveQuery(int32 id, Query* skip = nullptr);
|
||||||
#ifdef WORLD
|
#ifdef WORLD
|
||||||
void PurgeDBInstances();
|
void PurgeDBInstances();
|
||||||
void FreeDBInstance(Database* cur);
|
void FreeDBInstance(Database* cur);
|
||||||
@ -77,6 +83,9 @@ private:
|
|||||||
Mutex DBAsyncMutex;
|
Mutex DBAsyncMutex;
|
||||||
Mutex DBInstanceMutex;
|
Mutex DBInstanceMutex;
|
||||||
Mutex DBQueryMutex;
|
Mutex DBQueryMutex;
|
||||||
|
std::unordered_map<int32, std::chrono::steady_clock::time_point> _peerActive;
|
||||||
|
std::mutex _peerMtx;
|
||||||
|
static constexpr std::chrono::seconds kStaleTimeout{30};
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user