1
0

added zone info into memory, you can use /reload zoneinfo to clear the cache if GM status available.

This commit is contained in:
Emagi 2024-12-30 10:10:48 -05:00
parent a4e44dd520
commit 04f38a6599
6 changed files with 168 additions and 38 deletions

View File

@ -5818,6 +5818,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
case COMMAND_LEAVERAID: { Command_LeaveRaid(client, sep); break; } case COMMAND_LEAVERAID: { Command_LeaveRaid(client, sep); break; }
case COMMAND_SPLIT: { Command_Split(client, sep); break; } case COMMAND_SPLIT: { Command_Split(client, sep); break; }
case COMMAND_RAIDSAY: { Command_RaidSay(client, sep); break; } case COMMAND_RAIDSAY: { Command_RaidSay(client, sep); break; }
case COMMAND_RELOAD_ZONEINFO: { Command_ReloadZoneInfo(client, sep); break; }
default: default:
{ {
LogWrite(COMMAND__WARNING, 0, "Command", "Unhandled command: %s", command->command.data.c_str()); LogWrite(COMMAND__WARNING, 0, "Command", "Unhandled command: %s", command->command.data.c_str());
@ -12851,3 +12852,12 @@ void Commands::Command_RaidSay(Client* client, Seperator* sep) {
} }
} }
} }
/*
Function: Command_ReloadZoneInfo()
Purpose : Clears ZoneInfoMemory used for database.LoadZoneInfo
Example : /reload zoneinfo
*/
void Commands::Command_ReloadZoneInfo(Client* client, Seperator* sep) {
world.ClearZoneInfoCache();
}

View File

@ -465,6 +465,8 @@ public:
void Command_Split(Client* client, Seperator* sep); void Command_Split(Client* client, Seperator* sep);
void Command_RaidSay(Client* client, Seperator* sep); void Command_RaidSay(Client* client, Seperator* sep);
void Command_ReloadZoneInfo(Client* client, Seperator* sep);
// AA Commands // AA Commands
void Get_AA_Xml(Client* client, Seperator* sep); void Get_AA_Xml(Client* client, Seperator* sep);
void Add_AA(Client* client, Seperator* sep); void Add_AA(Client* client, Seperator* sep);
@ -993,4 +995,6 @@ private:
#define COMMAND_MODIFY_SPELL 1008 #define COMMAND_MODIFY_SPELL 1008
#define COMMAND_MODIFY_ZONE 1009 #define COMMAND_MODIFY_ZONE 1009
#define COMMAND_RELOAD_ZONEINFO 1010
#endif #endif

View File

@ -3651,3 +3651,65 @@ void World::ClientAuthApproval(int32 success, std::string charName, int32 accoun
// can't find client // can't find client
} }
} }
void World::ClearZoneInfoCache() {
std::unique_lock<std::shared_mutex> lock(cacheMutex);
zoneInfoByID.clear();
zoneInfoByName.clear();
}
std::shared_ptr<ZoneInfoMemory> World::GetZoneInfoById(int32 zoneID) {
std::shared_lock<std::shared_mutex> lock(cacheMutex);
auto it = zoneInfoByID.find(zoneID);
if (it != zoneInfoByID.end()) {
return it->second;
}
return nullptr;
}
std::shared_ptr<ZoneInfoMemory> World::GetZoneInfoByName(const std::string& zoneName) {
std::shared_lock<std::shared_mutex> lock(cacheMutex);
auto it = zoneInfoByName.find(zoneName);
if (it != zoneInfoByName.end()) {
return it->second;
}
return nullptr;
}
void World::AddZoneInfo(int32 zoneID, std::shared_ptr<ZoneInfoMemory> zoneInfo) {
std::unique_lock<std::shared_mutex> lock(cacheMutex);
zoneInfoByID[zoneInfo->zoneID] = zoneInfo;
zoneInfoByName[zoneInfo->zoneName] = zoneInfo;
}
void ZoneInfoMemory::LoadFromDatabaseRow(MYSQL_ROW row) {
zoneID = atoul(row[0]);
zoneFile = (row[1] != nullptr) ? row[1] : "";
zoneDescription = (row[2] != nullptr) ? row[2] : "";
underworld = atof(row[3]);
safeX = atof(row[4]);
safeY = atof(row[5]);
safeZ = atof(row[6]);
minimumLevel = atoi(row[8]);
maximumLevel = atoi(row[9]);
int8 type = (atoi(row[10]) == 0) ? 0 : atoi(row[10]) - 1;
shutdownTime = atoul(row[11]);
instanceType = (Instance_Type)type;
zoneMotd = (row[12] != nullptr) ? row[12] : "";
defReenterTime = atoi(row[13]);
defResetTime = atoi(row[14]);
defLockoutTime = atoi(row[15]);
groupZoneOption = atoi(row[16]);
safeHeading = atof(row[17]);
xpModifier = atof(row[18]);
rulesetID = atoul(row[19]);
if (rulesetID > 0 && !rule_manager.SetZoneRuleSet(zoneID, rulesetID))
LogWrite(ZONE__ERROR, 0, "Zones", "Error setting rule set for zone '%s' (%u). A rule set with ID %u does not exist.", zoneFile.c_str(), zoneID, rulesetID);
minimumVersion = database.GetMinimumClientVersion(atoul(row[20]));
weatherAllowed = atoul(row[21]);
zoneSkyFile = (row[22] != nullptr) ? row[22] : "";
canBind = atoul(row[23]);
canGate = atoul(row[24]);
cityZone = atoul(row[25]);
canEvac = atoul(row[26]);
}

View File

@ -27,6 +27,7 @@
#include <mutex> #include <mutex>
#include <shared_mutex> #include <shared_mutex>
#include <atomic> #include <atomic>
#include <mysql.h>
#include "SpawnLists.h" #include "SpawnLists.h"
#include "zoneserver.h" #include "zoneserver.h"
#include "NPC.h" #include "NPC.h"
@ -412,6 +413,37 @@ struct WhoAllPeerPlayer {
level = inLevel; level = inLevel;
} }
}; };
class ZoneInfoMemory {
public:
int32 zoneID;
std::string zoneName;
std::string zoneFile;
std::string zoneDescription;
std::string zoneMotd;
std::string zoneSkyFile;
float underworld;
float safeX, safeY, safeZ, safeHeading;
int16 minimumLevel, maximumLevel, minimumVersion;
int32 defReenterTime, defResetTime, defLockoutTime;
int8 groupZoneOption;
float xpModifier;
bool cityZone, canBind, canGate, canEvac, weatherAllowed;
int32 rulesetID;
Instance_Type instanceType;
int32 shutdownTime;
// Add other fields as necessary
// Constructor
ZoneInfoMemory() : zoneID(0), underworld(0.0f), safeX(0.0f), safeY(0.0f), safeZ(0.0f),
safeHeading(0.0f), minimumLevel(0), maximumLevel(0), minimumVersion(0),
defReenterTime(0), defResetTime(0), defLockoutTime(0), groupZoneOption(0),
xpModifier(1.0f), cityZone(false), canBind(false), canGate(false),
canEvac(false), weatherAllowed(true), rulesetID(0) {}
void LoadFromDatabaseRow(MYSQL_ROW row);
};
class ZoneList { class ZoneList {
public: public:
ZoneList(); ZoneList();
@ -713,9 +745,16 @@ public:
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_populate_status(boost::property_tree::ptree& pt); static void Web_populate_status(boost::property_tree::ptree& pt);
void ClearZoneInfoCache();
std::shared_ptr<ZoneInfoMemory> GetZoneInfoById(int32 zoneID);
std::shared_ptr<ZoneInfoMemory> GetZoneInfoByName(const std::string& zoneName);
void AddZoneInfo(int32 zoneID, std::shared_ptr<ZoneInfoMemory> zoneInfo);
Mutex MVoiceOvers; Mutex MVoiceOvers;
static sint64 newValue; static sint64 newValue;
private: private:
multimap<int32, multimap<int16, VoiceOverStruct>*> voiceover_map[3]; multimap<int32, multimap<int16, VoiceOverStruct>*> voiceover_map[3];
int32 suppressed_warning = 0; int32 suppressed_warning = 0;
@ -786,5 +825,9 @@ private:
map<int32, map<int32, NPCSpell*> > npc_spell_list; map<int32, map<int32, NPCSpell*> > npc_spell_list;
WebServer* world_webserver; WebServer* world_webserver;
std::unordered_map<int32, std::shared_ptr<ZoneInfoMemory>> zoneInfoByID;
std::unordered_map<std::string, std::shared_ptr<ZoneInfoMemory>> zoneInfoByName;
mutable std::shared_mutex cacheMutex;
}; };
#endif #endif

View File

@ -2961,44 +2961,55 @@ void WorldDatabase::LoadZoneInfo(ZoneServer* zone, int32 minLevel, int32 maxLeve
zone->setGroupRaidLevels(minLevel, maxLevel, avgLevel, firstLevel); zone->setGroupRaidLevels(minLevel, maxLevel, avgLevel, firstLevel);
char* escaped = getEscapeString(zone->GetZoneName()); char* escaped = getEscapeString(zone->GetZoneName());
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT id, file, description, underworld, safe_x, safe_y, safe_z, min_status, min_level, max_level, instance_type+0, shutdown_timer, zone_motd, default_reenter_time, default_reset_time, default_lockout_time, force_group_to_zone, safe_heading, xp_modifier, ruleset_id, expansion_id, weather_allowed, sky_file, can_bind, can_gate, city_zone, can_evac FROM zones where name='%s'",escaped); std::shared_ptr<ZoneInfoMemory> zoneInfo = world.GetZoneInfoByName(escaped);
if(result && mysql_num_rows(result) > 0) {
MYSQL_RES* result = nullptr;
if(zoneInfo == nullptr)
result = query.RunQuery2(Q_SELECT, "SELECT id, file, description, underworld, safe_x, safe_y, safe_z, min_status, min_level, max_level, instance_type+0, shutdown_timer, zone_motd, default_reenter_time, default_reset_time, default_lockout_time, force_group_to_zone, safe_heading, xp_modifier, ruleset_id, expansion_id, weather_allowed, sky_file, can_bind, can_gate, city_zone, can_evac FROM zones where name='%s'",escaped);
if((zoneInfo || (result && mysql_num_rows(result) > 0))) {
if(result && zoneInfo == nullptr)
{
MYSQL_ROW row; MYSQL_ROW row;
row = mysql_fetch_row(result); row = mysql_fetch_row(result);
zoneInfo = std::make_shared<ZoneInfoMemory>();
zoneInfo->LoadFromDatabaseRow(row);
world.AddZoneInfo(zoneInfo->zoneID, zoneInfo);
}
if(!result && !zoneInfo) {
LogWrite(ZONE__ERROR, 0, "Zones", "Failed to get zone info for %s.", escaped);
safe_delete_array(escaped);
return;
}
zone->SetZoneName(escaped); zone->SetZoneName(escaped);
zone->SetZoneID(strtoul(row[0], NULL, 0)); zone->SetZoneID(zoneInfo->zoneID);
zone->SetZoneFile(row[1]); zone->SetZoneFile((char*)zoneInfo->zoneFile.c_str());
zone->SetZoneDescription(row[2]); zone->SetZoneDescription((char*)zoneInfo->zoneDescription.c_str());
zone->SetUnderWorld(atof(row[3])); zone->SetUnderWorld(zoneInfo->underworld);
zone->SetSafeX(atof(row[4])); zone->SetSafeX(zoneInfo->safeX);
zone->SetSafeY(atof(row[5])); zone->SetSafeY(zoneInfo->safeY);
zone->SetSafeZ(atof(row[6])); zone->SetSafeZ(zoneInfo->safeZ);
zone->SetMinimumStatus(atoi(row[7])); zone->SetMinimumStatus(zoneInfo->minimumVersion);
zone->SetMinimumLevel(atoi(row[8])); zone->SetMinimumLevel(zoneInfo->minimumLevel);
zone->SetMaximumLevel(atoi(row[9])); zone->SetMaximumLevel(zoneInfo->maximumLevel);
int8 type = (atoi(row[10]) == 0) ? 0 : atoi(row[10]) - 1; zone->SetInstanceType(zoneInfo->instanceType);
zone->SetInstanceType(type); zone->SetShutdownTimer(zoneInfo->shutdownTime);
zone->SetShutdownTimer(atoul(row[11])); zone->SetZoneMOTD(zoneInfo->zoneMotd);
char* zone_motd = row[12]; zone->SetDefaultReenterTime(zoneInfo->defReenterTime);
if (zone_motd && strlen(zone_motd) > 0) zone->SetDefaultResetTime(zoneInfo->defResetTime);
zone->SetZoneMOTD(string(zone_motd)); zone->SetDefaultLockoutTime(zoneInfo->defLockoutTime);
zone->SetForceGroupZoneOption(zoneInfo->groupZoneOption);
zone->SetDefaultReenterTime(atoi(row[13])); zone->SetSafeHeading(zoneInfo->safeHeading);
zone->SetDefaultResetTime(atoi(row[14])); zone->SetXPModifier(zoneInfo->xpModifier);
zone->SetDefaultLockoutTime(atoi(row[15]));
zone->SetForceGroupZoneOption(atoi(row[16]));
zone->SetSafeHeading(atof(row[17]));
zone->SetXPModifier(atof(row[18]));
if ((ruleset_id = atoul(row[19])) > 0 && !rule_manager.SetZoneRuleSet(zone->GetZoneID(), ruleset_id))
LogWrite(ZONE__ERROR, 0, "Zones", "Error setting rule set for zone '%s' (%u). A rule set with ID %u does not exist.", zone->GetZoneName(), zone->GetZoneID(), ruleset_id);
// check data_version to see if client has proper expansion to enter a zone // check data_version to see if client has proper expansion to enter a zone
zone->SetMinimumVersion(GetMinimumClientVersion(atoi(row[20]))); zone->SetMinimumVersion(zoneInfo->minimumVersion);
zone->SetWeatherAllowed(atoi(row[21]) == 0 ? false : true); zone->SetWeatherAllowed(zoneInfo->weatherAllowed);
zone->SetZoneSkyFile(row[22]); zone->SetZoneSkyFile((char*)zoneInfo->zoneSkyFile.c_str());
if (zone->IsInstanceZone()) if (zone->IsInstanceZone())
{ {
@ -3011,10 +3022,10 @@ void WorldDatabase::LoadZoneInfo(ZoneServer* zone, int32 minLevel, int32 maxLeve
LoadZonePlayerLevels(zone); LoadZonePlayerLevels(zone);
} }
} }
zone->SetCanBind(atoul(row[23])); zone->SetCanBind(zoneInfo->canBind);
zone->SetCanGate(atoul(row[24])); zone->SetCanGate(zoneInfo->canGate);
zone->SetCityZone(atoi(row[25])); zone->SetCityZone(zoneInfo->cityZone);
zone->SetCanEvac(atoul(row[26])); zone->SetCanEvac(zoneInfo->canEvac);
} }
safe_delete_array(escaped); safe_delete_array(escaped);
} }

View File

@ -8770,7 +8770,7 @@ void ZoneServer::SendFlightPathsPackets(Client* client) {
} }
} }
} }
packet->PrintPacket(); //packet->PrintPacket();
client->QueuePacket(packet->serialize()); client->QueuePacket(packet->serialize());
safe_delete(packet); safe_delete(packet);
} }