mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 17:51:28 +00:00
Keeps spawns from doing individual loads and prefer bulk loading [skip ci]
This commit is contained in:
parent
0c3dd7dc93
commit
019735c654
@ -199,6 +199,7 @@ SET(common_headers
|
||||
repositories/character_recipe_list_repository.h
|
||||
repositories/grid_repository.h
|
||||
repositories/grid_entries_repository.h
|
||||
repositories/spawngroup_repository.h
|
||||
repositories/tradeskill_recipe_repository.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
|
||||
164
common/repositories/spawngroup_repository.h
Normal file
164
common/repositories/spawngroup_repository.h
Normal file
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#ifndef EQEMU_SPAWNGROUP_REPOSITORY_H
|
||||
#define EQEMU_SPAWNGROUP_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../string_util.h"
|
||||
|
||||
class SpawnGroupRepository {
|
||||
public:
|
||||
struct SpawnGroup {
|
||||
int id;
|
||||
std::string name;
|
||||
int8 spawn_limit;
|
||||
int dist;
|
||||
float max_x;
|
||||
float min_x;
|
||||
float max_y;
|
||||
float min_y;
|
||||
int delay;
|
||||
int mindelay;
|
||||
int despawn;
|
||||
int despawn_timer;
|
||||
int wp_spawns;
|
||||
};
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"name",
|
||||
"spawn_limit",
|
||||
"dist",
|
||||
"max_x",
|
||||
"min_x",
|
||||
"max_y",
|
||||
"min_y",
|
||||
"delay",
|
||||
"mindelay",
|
||||
"despawn",
|
||||
"despawn_timer",
|
||||
"wp_spawns",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("spawngroup");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return std::string(
|
||||
fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
ColumnsRaw(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static SpawnGroup New()
|
||||
{
|
||||
SpawnGroup entry;
|
||||
|
||||
entry.id = 0;
|
||||
entry.name = "";
|
||||
entry.spawn_limit = 0;
|
||||
entry.dist = 0;
|
||||
entry.max_x = 0;
|
||||
entry.min_x = 0;
|
||||
entry.max_y = 0;
|
||||
entry.min_y = 0;
|
||||
entry.delay = 0;
|
||||
entry.mindelay = 0;
|
||||
entry.despawn = 0;
|
||||
entry.despawn_timer = 0;
|
||||
entry.wp_spawns = 0;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static std::vector<SpawnGroup> GetZoneSpawnGroups(
|
||||
const std::string &zone_short_name,
|
||||
int zone_version
|
||||
)
|
||||
{
|
||||
std::vector<SpawnGroup> spawn_groups;
|
||||
|
||||
auto results = content_db.QueryDatabase(
|
||||
fmt::format(
|
||||
SQL (
|
||||
{} INNER JOIN spawn2 ON spawn2.spawngroupID = spawngroup.id
|
||||
WHERE spawn2.zone = '{}' and spawn2.version = {}
|
||||
),
|
||||
BaseSelect(),
|
||||
zone_short_name,
|
||||
zone_version
|
||||
)
|
||||
);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
SpawnGroup entry{};
|
||||
|
||||
entry.id = atoi(row[0]);
|
||||
entry.name = row[1];
|
||||
entry.spawn_limit = atoi(row[2]);
|
||||
entry.dist = atof(row[3]);
|
||||
entry.max_x = atof(row[4]);
|
||||
entry.min_x = atof(row[5]);
|
||||
entry.max_y = atof(row[6]);
|
||||
entry.min_y = atof(row[7]);
|
||||
entry.delay = atoi(row[8]);
|
||||
entry.mindelay = atoi(row[9]);
|
||||
entry.despawn = atoi(row[10]);
|
||||
entry.despawn_timer = atoi(row[11]);
|
||||
entry.wp_spawns = atoi(row[12]);
|
||||
|
||||
spawn_groups.push_back(entry);
|
||||
}
|
||||
|
||||
return spawn_groups;
|
||||
}
|
||||
|
||||
static SpawnGroup GetGrid(
|
||||
const std::vector<SpawnGroup> &spawn_groups,
|
||||
int spawn_group_id
|
||||
)
|
||||
{
|
||||
for (auto &row : spawn_groups) {
|
||||
if (row.id == spawn_group_id) {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
return New();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_SPAWNGROUP_REPOSITORY_H
|
||||
@ -345,7 +345,6 @@ int command_init(void)
|
||||
command_add("reloadworld", "[0|1] - Clear quest cache (0 - no repop, 1 - repop)", 255, command_reloadworld) ||
|
||||
command_add("reloadzps", "- Reload zone points from database", 150, command_reloadzps) ||
|
||||
command_add("repop", "[delay] - Repop the zone with optional delay", 100, command_repop) ||
|
||||
command_add("repopclose", "[distance in units] Repops only NPC's nearby for fast development purposes", 100, command_repopclose) ||
|
||||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
|
||||
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
|
||||
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
|
||||
@ -5320,33 +5319,6 @@ void command_repop(Client *c, const Seperator *sep)
|
||||
zone->spawn2_timer.Trigger();
|
||||
}
|
||||
|
||||
void command_repopclose(Client *c, const Seperator *sep)
|
||||
{
|
||||
int repop_distance = 500;
|
||||
|
||||
if (sep->arg[1] && strcasecmp(sep->arg[1], "force") == 0) {
|
||||
|
||||
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
std::string query = StringFormat(
|
||||
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
|
||||
(unsigned long)iterator.GetData()->GetID(),
|
||||
(unsigned long)zone->GetInstanceID()
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
iterator.Advance();
|
||||
}
|
||||
c->Message(Chat::White, "Zone depop: Force resetting spawn timers.");
|
||||
}
|
||||
if (sep->IsNumber(1)) {
|
||||
repop_distance = atoi(sep->arg[1]);
|
||||
}
|
||||
|
||||
c->Message(Chat::White, "Zone depoped. Repopping NPC's within %i distance units", repop_distance);
|
||||
zone->RepopClose(c->GetPosition(), repop_distance);
|
||||
}
|
||||
|
||||
void command_spawnstatus(Client *c, const Seperator *sep)
|
||||
{
|
||||
if((sep->arg[1][0] == 'e') | (sep->arg[1][0] == 'E'))
|
||||
|
||||
@ -246,7 +246,6 @@ void command_reloadworld(Client *c, const Seperator *sep);
|
||||
void command_reloadworldrules(Client *c, const Seperator *sep);
|
||||
void command_reloadzps(Client *c, const Seperator *sep);
|
||||
void command_repop(Client *c, const Seperator *sep);
|
||||
void command_repopclose(Client *c, const Seperator *sep);
|
||||
void command_resetaa(Client* c,const Seperator *sep);
|
||||
void command_resetaa_timer(Client *c, const Seperator *sep);
|
||||
void command_revoke(Client *c, const Seperator *sep);
|
||||
|
||||
@ -165,7 +165,10 @@ bool Spawn2::Process() {
|
||||
return (true);
|
||||
}
|
||||
|
||||
if (spawn_group == nullptr) {
|
||||
/**
|
||||
* Wait for init grids timer because we bulk load this data before trying to fetch it individually
|
||||
*/
|
||||
if (spawn_group == nullptr && zone->GetInitgridsTimer().Check()) {
|
||||
content_db.LoadSpawnGroupsByID(spawngroup_id_, &zone->spawn_group_list);
|
||||
spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_);
|
||||
}
|
||||
@ -916,7 +919,7 @@ void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 inst
|
||||
"(id, value, zone, instance_id) "
|
||||
"VALUES( %u, %u, '%s', %u)",
|
||||
cond_id, value, zone_name, instance_id);
|
||||
content_db.QueryDatabase(query);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std::string &zone_name) {
|
||||
@ -1376,7 +1379,7 @@ int16 SpawnConditionManager::GetCondition(const char *zone_short, uint32 instanc
|
||||
"WHERE zone = '%s' AND instance_id = %u AND id = %d",
|
||||
zone_short, instance_id, condition_id
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogSpawns("Unable to query remote condition [{}] from zone [{}] in Get request", condition_id, zone_short);
|
||||
return 0; //dunno a better thing to do...
|
||||
|
||||
@ -325,6 +325,14 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
LogSpawnsDetail(
|
||||
"[LoadSpawnGroupsByID] Loading spawn_group spawn_group_id [{}] name [{}] spawn_limit [{}] dist [{}]",
|
||||
row[0],
|
||||
row[1],
|
||||
row[2],
|
||||
row[3]
|
||||
);
|
||||
|
||||
auto new_spawn_group = new SpawnGroup(
|
||||
atoi(row[0]),
|
||||
row[1],
|
||||
@ -375,6 +383,15 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn
|
||||
(row[4] ? atoi(row[4]) : 0)
|
||||
);
|
||||
|
||||
LogSpawnsDetail(
|
||||
"[LoadSpawnGroupsByID] Loading spawn_entry spawn_group_id [{}] npc_id [{}] chance [{}] condition_value_filter [{}] spawn_limit [{}]",
|
||||
row[0],
|
||||
row[1],
|
||||
row[2],
|
||||
row[3],
|
||||
row[4]
|
||||
);
|
||||
|
||||
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||
if (!spawn_group) {
|
||||
safe_delete(new_spawn_entry);
|
||||
|
||||
@ -1272,8 +1272,6 @@ bool Zone::Process() {
|
||||
|
||||
EQEmu::InventoryProfile::CleanDirty();
|
||||
|
||||
LogSpawns("Running Zone::Process -> Spawn2::Process");
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
if (iterator.GetData()->Process()) {
|
||||
@ -1598,29 +1596,6 @@ void Zone::ClearNPCTypeCache(int id) {
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::RepopClose(const glm::vec4& client_position, uint32 repop_distance)
|
||||
{
|
||||
|
||||
if (!Depop())
|
||||
return;
|
||||
|
||||
LinkedListIterator<Spawn2*> iterator(spawn2_list);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
iterator.RemoveCurrent();
|
||||
}
|
||||
|
||||
quest_manager.ClearAllTimers();
|
||||
|
||||
if (!content_db.PopulateZoneSpawnListClose(zoneid, spawn2_list, GetInstanceVersion(), client_position, repop_distance))
|
||||
LogDebug("Error in Zone::Repop: database.PopulateZoneSpawnList failed");
|
||||
|
||||
initgrids_timer.Start();
|
||||
|
||||
mod_repop();
|
||||
}
|
||||
|
||||
void Zone::Repop(uint32 delay)
|
||||
{
|
||||
if (!Depop()) {
|
||||
@ -1640,8 +1615,19 @@ void Zone::Repop(uint32 delay)
|
||||
|
||||
quest_manager.ClearAllTimers();
|
||||
|
||||
if (!content_db.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay))
|
||||
LogInfo("Loading spawn groups");
|
||||
if (!content_db.LoadSpawnGroups(short_name, GetInstanceVersion(), &spawn_group_list)) {
|
||||
LogError("Loading spawn groups failed");
|
||||
}
|
||||
|
||||
LogInfo("Loading spawn conditions");
|
||||
if (!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) {
|
||||
LogError("Loading spawn conditions failed, continuing without them");
|
||||
}
|
||||
|
||||
if (!content_db.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay)) {
|
||||
LogDebug("Error in Zone::Repop: database.PopulateZoneSpawnList failed");
|
||||
}
|
||||
|
||||
LoadGrids();
|
||||
|
||||
@ -2522,3 +2508,8 @@ void Zone::LoadGrids()
|
||||
zone_grids = GridRepository::GetZoneGrids(GetZoneID());
|
||||
zone_grid_entries = GridEntriesRepository::GetZoneGridEntries(GetZoneID());
|
||||
}
|
||||
|
||||
Timer Zone::GetInitgridsTimer()
|
||||
{
|
||||
return initgrids_timer;
|
||||
}
|
||||
|
||||
@ -259,7 +259,6 @@ public:
|
||||
void RemoveAuth(const char *iCharName, const char *iLSKey);
|
||||
void RemoveAuth(uint32 lsid);
|
||||
void Repop(uint32 delay = 0);
|
||||
void RepopClose(const glm::vec4 &client_position, uint32 repop_distance);
|
||||
void RequestUCSServerStatus();
|
||||
void ResetAuth();
|
||||
void SetDate(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute);
|
||||
@ -285,6 +284,8 @@ public:
|
||||
ZonePoint *GetClosestZonePoint(const glm::vec3 &location, uint32 to, Client *client, float max_distance = 40000.0f);
|
||||
ZonePoint *GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f);
|
||||
|
||||
Timer GetInitgridsTimer();
|
||||
|
||||
/**
|
||||
* GMSay Callback for LogSys
|
||||
*
|
||||
@ -332,6 +333,7 @@ public:
|
||||
|
||||
double GetMaxMovementUpdateRange() const { return max_movement_update_range; }
|
||||
|
||||
|
||||
/**
|
||||
* Modding hooks
|
||||
*/
|
||||
@ -352,8 +354,6 @@ private:
|
||||
bool staticzone;
|
||||
bool zone_has_current_time;
|
||||
bool quest_hot_reload_queued;
|
||||
|
||||
private:
|
||||
double max_movement_update_range;
|
||||
char *long_name;
|
||||
char *map_name;
|
||||
@ -384,7 +384,7 @@ private:
|
||||
Timer autoshutdown_timer;
|
||||
Timer clientauth_timer;
|
||||
Timer hotzone_timer;
|
||||
Timer initgrids_timer; //delayed loading of initial grids.
|
||||
Timer initgrids_timer;
|
||||
Timer qglobal_purge_timer;
|
||||
ZoneSpellsBlocked *blocked_spells;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user