mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 23:01:30 +00:00
Reduced #repop time dramatically by taking down hundreds of individual SELECT/DELETE/INSERT queries in routines and bringing it down to very few
See: https://www.youtube.com/watch?v=9kSFbyTBuAk
This commit is contained in:
parent
1149f04389
commit
cb81d956f6
@ -1,5 +1,9 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 02/06/2015 ==
|
||||
Akkadius: Reduced #repop time dramatically by taking down hundreds of individual SELECT/DELETE/INSERT queries in routines and bringing it down to very few
|
||||
See: https://www.youtube.com/watch?v=9kSFbyTBuAk
|
||||
|
||||
== 02/06/2015 ==
|
||||
Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const)
|
||||
Uleat: Replaced 'iter_inst' and 'iter_contents' typedefs with their stl definitions
|
||||
|
||||
@ -297,7 +297,7 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id)
|
||||
}
|
||||
}
|
||||
|
||||
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
|
||||
database.UpdateRespawnTime(spawn2_id, zone->GetInstanceID(), 0);
|
||||
found_spawn->SetCurrentNPCID(npcid);
|
||||
|
||||
auto position = glm::vec4(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading());
|
||||
@ -2388,7 +2388,7 @@ void QuestManager::UpdateSpawnTimer(uint32 id, uint32 newTime)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
database.UpdateSpawn2Timeleft(id, 0, (newTime/1000));
|
||||
database.UpdateRespawnTime(id, 0, (newTime/1000));
|
||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements())
|
||||
|
||||
@ -214,9 +214,6 @@ bool Spawn2::Process() {
|
||||
if(IsDespawned)
|
||||
return true;
|
||||
|
||||
if(spawn2_id)
|
||||
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), 0);
|
||||
|
||||
currentnpcid = npcid;
|
||||
NPC* npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), FlyMode3);
|
||||
|
||||
@ -348,7 +345,7 @@ void Spawn2::DeathReset(bool realdeath)
|
||||
//if we have a valid spawn id
|
||||
if(spawn2_id)
|
||||
{
|
||||
database.UpdateSpawn2Timeleft(spawn2_id, zone->GetInstanceID(), (cur/1000));
|
||||
database.UpdateRespawnTime(spawn2_id, zone->GetInstanceID(), (cur/1000));
|
||||
Log.Out(Logs::Detail, Logs::Spawns, "Spawn2 %d: Spawn reset by death, repop in %d ms", spawn2_id, timer.GetRemainingTime());
|
||||
//store it to database too
|
||||
}
|
||||
@ -356,27 +353,91 @@ void Spawn2::DeathReset(bool realdeath)
|
||||
|
||||
bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay) {
|
||||
|
||||
std::unordered_map<uint32, uint32> spawn_times;
|
||||
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
|
||||
std::string spawn_query = StringFormat(
|
||||
"SELECT "
|
||||
"respawn_times.id, "
|
||||
"respawn_times.`start`, "
|
||||
"respawn_times.duration "
|
||||
"FROM "
|
||||
"respawn_times "
|
||||
"WHERE instance_id = %u",
|
||||
zone->GetInstanceID()
|
||||
);
|
||||
auto results = QueryDatabase(spawn_query);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
uint32 start_duration = atoi(row[1]) > 0 ? atoi(row[1]) : 0;
|
||||
uint32 end_duration = atoi(row[2]) > 0 ? atoi(row[2]) : 0;
|
||||
|
||||
/* Our current time was expired */
|
||||
if ((start_duration + end_duration) <= tv.tv_sec) {
|
||||
spawn_times[atoi(row[0])] = 0;
|
||||
}
|
||||
/* We still have time left on this timer */
|
||||
else {
|
||||
spawn_times[atoi(row[0])] = ((start_duration + end_duration) - tv.tv_sec) * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
const char *zone_name = database.GetZoneName(zoneid);
|
||||
std::string query = StringFormat("SELECT id, spawngroupID, x, y, z, heading, "
|
||||
"respawntime, variance, pathgrid, _condition, "
|
||||
"cond_value, enabled, animation FROM spawn2 "
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"id, "
|
||||
"spawngroupID, "
|
||||
"x, "
|
||||
"y, "
|
||||
"z, "
|
||||
"heading, "
|
||||
"respawntime, "
|
||||
"variance, "
|
||||
"pathgrid, "
|
||||
"_condition, "
|
||||
"cond_value, "
|
||||
"enabled, "
|
||||
"animation "
|
||||
"FROM "
|
||||
"spawn2 "
|
||||
"WHERE zone = '%s' AND version = %u",
|
||||
zone_name, version);
|
||||
auto results = QueryDatabase(query);
|
||||
zone_name,
|
||||
version
|
||||
);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Spawn2* newSpawn = 0;
|
||||
|
||||
bool perl_enabled = atoi(row[11]) == 1? true: false;
|
||||
uint32 spawnLeft = (GetSpawnTimeLeft(atoi(row[0]), zone->GetInstanceID()) * 1000);
|
||||
newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]),
|
||||
atof(row[5]), atoi(row[6]), atoi(row[7]), spawnLeft, atoi(row[8]),
|
||||
atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12]));
|
||||
uint32 spawn_time_left = 0;
|
||||
Spawn2* new_spawn = 0;
|
||||
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
|
||||
|
||||
spawn2_list.Insert(newSpawn);
|
||||
if (spawn_times.count(atoi(row[0])) != 0)
|
||||
spawn_time_left = spawn_times[atoi(row[0])];
|
||||
|
||||
new_spawn = new Spawn2( //
|
||||
atoi(row[0]), // uint32 in_spawn2_id
|
||||
atoi(row[1]), // uint32 spawngroup_id
|
||||
atof(row[2]), // float in_x
|
||||
atof(row[3]), // float in_y
|
||||
atof(row[4]), // float in_z
|
||||
atof(row[5]), // float in_heading
|
||||
atoi(row[6]), // uint32 respawn
|
||||
atoi(row[7]), // uint32 variance
|
||||
spawn_time_left, // uint32 timeleft
|
||||
atoi(row[8]), // uint32 grid
|
||||
atoi(row[9]), // uint16 in_cond_id
|
||||
atoi(row[10]), // int16 in_min_value
|
||||
perl_enabled, // bool in_enabled
|
||||
(EmuAppearance)atoi(row[12]) // EmuAppearance anim
|
||||
);
|
||||
|
||||
spawn2_list.Insert(new_spawn);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -427,8 +488,6 @@ bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* z
|
||||
if (results.RowsAffected() != 1)
|
||||
return false;
|
||||
|
||||
if(client)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -931,6 +931,9 @@ bool Zone::Init(bool iStaticZone) {
|
||||
Log.Out(Logs::General, Logs::Error, "Loading World Objects failed. continuing.");
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Status, "Flushing old respawn timers...");
|
||||
database.QueryDatabase("DELETE FROM `respawn_times` WHERE (`start` + `duration`) < UNIX_TIMESTAMP(NOW())");
|
||||
|
||||
//load up the zone's doors (prints inside)
|
||||
zone->LoadZoneDoors(zone->GetShortName(), zone->GetInstanceVersion());
|
||||
zone->LoadBlockedSpells(zone->GetZoneID());
|
||||
|
||||
@ -185,28 +185,40 @@ bool ZoneDatabase::GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct
|
||||
return true;
|
||||
}
|
||||
|
||||
//updates or clears the respawn time in the database for the current spawn id
|
||||
void ZoneDatabase::UpdateSpawn2Timeleft(uint32 id, uint16 instance_id, uint32 timeleft)
|
||||
void ZoneDatabase::UpdateRespawnTime(uint32 spawn2_id, uint16 instance_id, uint32 time_left)
|
||||
{
|
||||
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
uint32 cur = tv.tv_sec;
|
||||
uint32 current_time = tv.tv_sec;
|
||||
|
||||
//if we pass timeleft as 0 that means we clear from respawn time
|
||||
//otherwise we update with a REPLACE INTO
|
||||
if(timeleft == 0) {
|
||||
std::string query = StringFormat("DELETE FROM respawn_times WHERE id=%lu AND instance_id = %lu",(unsigned long)id, (unsigned long)instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
/* If we pass timeleft as 0 that means we clear from respawn time
|
||||
otherwise we update with a REPLACE INTO
|
||||
*/
|
||||
|
||||
if(time_left == 0) {
|
||||
std::string query = StringFormat("DELETE FROM `respawn_times` WHERE `id` = %u AND `instance_id` = %u", spawn2_id, instance_id);
|
||||
QueryDatabase(query);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = StringFormat("REPLACE INTO respawn_times (id, start, duration, instance_id) "
|
||||
"VALUES (%lu, %lu, %lu, %lu)",
|
||||
(unsigned long)id, (unsigned long)cur,
|
||||
(unsigned long)timeleft, (unsigned long)instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
std::string query = StringFormat(
|
||||
"REPLACE INTO `respawn_times` "
|
||||
"(id, "
|
||||
"start, "
|
||||
"duration, "
|
||||
"instance_id) "
|
||||
"VALUES "
|
||||
"(%u, "
|
||||
"%u, "
|
||||
"%u, "
|
||||
"%u)",
|
||||
spawn2_id,
|
||||
current_time,
|
||||
time_left,
|
||||
instance_id
|
||||
);
|
||||
QueryDatabase(query);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ public:
|
||||
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
|
||||
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft);
|
||||
bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value);
|
||||
void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft);
|
||||
void UpdateRespawnTime(uint32 id, uint16 instance_id,uint32 timeleft);
|
||||
uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id);
|
||||
void UpdateSpawn2Status(uint32 id, uint8 new_status);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user