mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Expansions] Zone Expansion Version Routing (#4084)
* Expansion version routing * CheckForImproperContentFiles rule * Update world_content_service.cpp * Update client.cpp * Update client.cpp * Update CheckForImproperContentFiles * Remove nek pok check * Remove file checking * Remove * Command and dev tools menu tweaks * Update world_content_service.cpp * Update world_content_service.cpp * Update version path * Update content_filter_criteria.h * Update content_filter_criteria.h * Update quest_parser_collection.cpp * Update comments * PR feedback * Update client_packet.cpp * Remove notes column for display cleanliness
This commit is contained in:
parent
5a89fcfb78
commit
d182fc3613
@ -1,28 +1,11 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "world_content_service.h"
|
||||
|
||||
#include <utility>
|
||||
#include <glm/vec3.hpp>
|
||||
#include "../database.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
|
||||
|
||||
WorldContentService::WorldContentService()
|
||||
@ -119,7 +102,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
||||
/**
|
||||
* @param content_flags
|
||||
*/
|
||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags)
|
||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags> &content_flags)
|
||||
{
|
||||
WorldContentService::content_flags = content_flags;
|
||||
}
|
||||
@ -167,14 +150,14 @@ bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
|
||||
}
|
||||
|
||||
// if we don't have any enabled flag in enabled flags, we fail
|
||||
for (const auto& flag: Strings::Split(f.content_flags)) {
|
||||
for (const auto &flag: Strings::Split(f.content_flags)) {
|
||||
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have any disabled flag in disabled flags, we fail
|
||||
for (const auto& flag: Strings::Split(f.content_flags_disabled)) {
|
||||
for (const auto &flag: Strings::Split(f.content_flags_disabled)) {
|
||||
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
@ -200,6 +183,7 @@ void WorldContentService::ReloadContentFlags()
|
||||
}
|
||||
|
||||
SetContentFlags(set_content_flags);
|
||||
SetContentZones(ZoneRepository::All(*m_content_database));
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetDatabase() const
|
||||
@ -214,6 +198,18 @@ WorldContentService *WorldContentService::SetDatabase(Database *database)
|
||||
return this;
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetContentDatabase() const
|
||||
{
|
||||
return m_content_database;
|
||||
}
|
||||
|
||||
WorldContentService *WorldContentService::SetContentDatabase(Database *database)
|
||||
{
|
||||
WorldContentService::m_content_database = database;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
|
||||
{
|
||||
auto flags = ContentFlagsRepository::GetWhere(
|
||||
@ -238,3 +234,85 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
||||
|
||||
ReloadContentFlags();
|
||||
}
|
||||
|
||||
// SetZones sets the zones for the world content service
|
||||
// this is used for zone routing middleware
|
||||
// we pull the zone list from the zone repository and feed from the zone store for now
|
||||
// we're holding a copy in the content service - but we're talking 250kb of data in memory to handle routing of zoning
|
||||
WorldContentService *WorldContentService::SetContentZones(const std::vector<BaseZoneRepository::Zone>& zones)
|
||||
{
|
||||
m_zones = zones;
|
||||
|
||||
LogInfo("Loaded [{}] zones", m_zones.size());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// HandleZoneRoutingMiddleware is meant to handle content and context aware zone routing
|
||||
//
|
||||
// example # 1
|
||||
// lavastorm (pre-don) version 0 (classic)
|
||||
// lavastorm (don) version 1
|
||||
// we want to route players to the correct version of lavastorm based on the current server side expansion
|
||||
// in order to do that the simplest and cleanest way we intercept the zoning process and route players to an "instance" of the zone
|
||||
// the reason why we're doing this is because all of the zoning logic already is handled by two keys "zone_id" and "instance_id"
|
||||
// we can leverage static, never expires instances to handle this but to the client they don't see it any other way than a public normal zone
|
||||
// scripts handle all the same way, you don't have to think about instances, the middleware will handle the magic
|
||||
// the versions of zones are represented by two zone entries that have potentially different min/max expansion and/or different content flags
|
||||
// we decide to route the client to the correct version of the zone based on the current server side expansion
|
||||
// example # 2
|
||||
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
||||
{
|
||||
// if we're already in an instance, we don't want to route the player to another instance
|
||||
if (zc->instanceID > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &z: m_zones) {
|
||||
if (z.zoneidnumber == zc->zoneID) {
|
||||
auto f = ContentFlags{
|
||||
.min_expansion = z.min_expansion,
|
||||
.max_expansion = z.max_expansion,
|
||||
.content_flags = z.content_flags,
|
||||
.content_flags_disabled = z.content_flags_disabled
|
||||
};
|
||||
|
||||
if (DoesPassContentFiltering(f)) {
|
||||
LogInfo(
|
||||
"Attempting to route player to zone [{}] ({}) version [{}] long_name [{}]",
|
||||
z.short_name,
|
||||
z.zoneidnumber,
|
||||
z.version,
|
||||
z.long_name
|
||||
);
|
||||
|
||||
auto instances = InstanceListRepository::GetWhere(
|
||||
*GetDatabase(),
|
||||
fmt::format(
|
||||
"zone = {} AND version = {} AND never_expires = 1 AND is_global = 1",
|
||||
z.zoneidnumber,
|
||||
z.version
|
||||
)
|
||||
);
|
||||
|
||||
if (!instances.empty()) {
|
||||
auto instance = instances.front();
|
||||
zc->instanceID = instance.id;
|
||||
|
||||
LogInfo(
|
||||
"Routed player to instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
||||
instance.id,
|
||||
z.short_name,
|
||||
z.zoneidnumber,
|
||||
z.version,
|
||||
z.long_name,
|
||||
instance.notes
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,29 +1,10 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 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_WORLD_CONTENT_SERVICE_H
|
||||
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
#include "../repositories/zone_repository.h"
|
||||
|
||||
class Database;
|
||||
|
||||
@ -182,14 +163,23 @@ public:
|
||||
WorldContentService * SetDatabase(Database *database);
|
||||
Database *GetDatabase() const;
|
||||
|
||||
WorldContentService * SetContentDatabase(Database *database);
|
||||
Database *GetContentDatabase() const;
|
||||
|
||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
||||
|
||||
void HandleZoneRoutingMiddleware(ZoneChange_Struct *zc);
|
||||
WorldContentService * SetContentZones(const std::vector<ZoneRepository::Zone>& zones);
|
||||
private:
|
||||
int current_expansion{};
|
||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||
|
||||
// reference to database
|
||||
Database *m_database;
|
||||
Database *m_content_database;
|
||||
|
||||
// holds a record of the zone table from the database
|
||||
std::vector<ZoneRepository::Zone> m_zones = {};
|
||||
};
|
||||
|
||||
extern WorldContentService content_service;
|
||||
|
||||
@ -5365,6 +5365,33 @@ ALTER TABLE `character_corpses` MODIFY COLUMN `time_of_death` datetime NOT NULL
|
||||
.sql = R"(
|
||||
ALTER TABLE `object_contents` MODIFY COLUMN `droptime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9263,
|
||||
.description = "2024_02_16_rearrange_zone_columns.sql",
|
||||
.check = "show columns from zone like 'note'",
|
||||
.condition = "missing",
|
||||
.match = "varchar(200)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `zone`
|
||||
MODIFY COLUMN `id` int(10) NOT NULL AUTO_INCREMENT FIRST,
|
||||
MODIFY COLUMN `zoneidnumber` int(4) NOT NULL DEFAULT 0 AFTER `id`,
|
||||
MODIFY COLUMN `version` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `zoneidnumber`,
|
||||
MODIFY COLUMN `short_name` varchar(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `version`,
|
||||
MODIFY COLUMN `long_name` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL AFTER `short_name`,
|
||||
MODIFY COLUMN `min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `long_name`,
|
||||
MODIFY COLUMN `note` varchar(200) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `map_file_name`,
|
||||
MODIFY COLUMN `min_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `note`,
|
||||
MODIFY COLUMN `max_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `min_expansion`,
|
||||
MODIFY COLUMN `content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `max_expansion`,
|
||||
MODIFY COLUMN `content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `content_flags`,
|
||||
MODIFY COLUMN `expansion` tinyint(3) NOT NULL DEFAULT 0 AFTER `content_flags_disabled`,
|
||||
MODIFY COLUMN `file_name` varchar(16) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `expansion`,
|
||||
MODIFY COLUMN `safe_x` float NOT NULL DEFAULT 0 AFTER `file_name`,
|
||||
MODIFY COLUMN `safe_y` float NOT NULL DEFAULT 0 AFTER `safe_x`,
|
||||
MODIFY COLUMN `safe_z` float NOT NULL DEFAULT 0 AFTER `safe_y`,
|
||||
MODIFY COLUMN `safe_heading` float NOT NULL DEFAULT 0 AFTER `safe_z`;
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
|
||||
@ -890,7 +890,7 @@ RULE_INT(Expansion, AutoGrantAAExpansion, -1, "Expansion to auto grant AAs up to
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Instances)
|
||||
RULE_INT(Instances, ReservedInstances, 30, "Number of instance IDs which are reserved for globals. This value should not be changed while a server is running")
|
||||
RULE_INT(Instances, ReservedInstances, 100, "Number of instance IDs which are reserved for globals. This value should not be changed while a server is running")
|
||||
RULE_BOOL(Instances, RecycleInstanceIds, true, "Setting whether free instance IDs should be recycled to prevent them from gradually running out at 32k")
|
||||
RULE_INT(Instances, GuildHallExpirationDays, 90, "Amount of days before a Guild Hall instance expires")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9262
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9263
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9042
|
||||
|
||||
#endif
|
||||
|
||||
@ -168,6 +168,7 @@ int main(int argc, char **argv)
|
||||
|
||||
content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion));
|
||||
content_service.SetDatabase(&database)
|
||||
->SetContentDatabase(&content_db)
|
||||
->SetExpansionContext()
|
||||
->ReloadContentFlags();
|
||||
|
||||
|
||||
@ -381,6 +381,7 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
||||
|
||||
LogInfo("Initializing [WorldContentService]");
|
||||
content_service.SetDatabase(&database)
|
||||
->SetContentDatabase(&content_db)
|
||||
->SetExpansionContext()
|
||||
->ReloadContentFlags();
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@ extern volatile bool RunLoops;
|
||||
#include "../common/events/player_events.h"
|
||||
#include "../common/events/player_event_logs.h"
|
||||
#include "dialogue_window.h"
|
||||
#include "../common/zone_store.h"
|
||||
|
||||
|
||||
extern QueryServ* QServ;
|
||||
@ -9108,6 +9109,7 @@ void Client::ShowDevToolsMenu()
|
||||
*/
|
||||
menu_show += Saylink::Silent("#showzonepoints", "Zone Points");
|
||||
menu_show += " | " + Saylink::Silent("#showzonegloballoot", "Zone Global Loot");
|
||||
menu_show += " | " + Saylink::Silent("#show content_flags", "Content Flags");
|
||||
|
||||
/**
|
||||
* Reload
|
||||
@ -9165,14 +9167,6 @@ void Client::ShowDevToolsMenu()
|
||||
|
||||
Message(Chat::White, "Developer Tools Menu");
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Current Expansion | {}",
|
||||
content_service.GetCurrentExpansionName()
|
||||
).c_str()
|
||||
);
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
@ -9288,6 +9282,36 @@ void Client::ShowDevToolsMenu()
|
||||
);
|
||||
|
||||
SendChatLineBreak();
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Current Expansion | {} ({})",
|
||||
content_service.GetCurrentExpansionName(),
|
||||
content_service.GetCurrentExpansion()
|
||||
).c_str()
|
||||
);
|
||||
|
||||
|
||||
auto z = GetZoneVersionWithFallback(zone->GetZoneID(), zone->GetInstanceVersion());
|
||||
|
||||
if (z) {
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Current Zone | [{}] ({}) version [{}] instance_id [{}] min/max expansion ({}/{}) content_flags [{}]",
|
||||
z->short_name,
|
||||
z->long_name,
|
||||
z->version,
|
||||
zone->GetInstanceID(),
|
||||
z->min_expansion,
|
||||
z->max_expansion,
|
||||
z->content_flags
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
SendChatLineBreak();
|
||||
}
|
||||
|
||||
void Client::SendChatLineBreak(uint16 color) {
|
||||
|
||||
@ -954,7 +954,6 @@ void Client::CompleteConnect()
|
||||
heroforge_wearchange_timer.Start(250);
|
||||
|
||||
RecordStats();
|
||||
|
||||
AutoGrantAAPoints();
|
||||
|
||||
// enforce some rules..
|
||||
@ -17138,3 +17137,4 @@ void Client::Handle_OP_GuildTributeDonatePlat(const EQApplicationPacket *app)
|
||||
RequestGuildFavorAndTimer(GuildID());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1072,7 +1072,7 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I
|
||||
SetMana(GetMaxMana() / 20);
|
||||
SetEndurance(GetMaxEndurance() / 20);
|
||||
}
|
||||
|
||||
|
||||
if(spells[SpellID].base_value[0] < 100 && spells[SpellID].base_value[0] > 0 && PendingRezzXP > 0) {
|
||||
SetEXP(((int)(GetEXP()+((float)((PendingRezzXP / 100) * spells[SpellID].base_value[0])))),
|
||||
GetAAXP(),true);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "show/buffs.cpp"
|
||||
#include "show/buried_corpse_count.cpp"
|
||||
#include "show/client_version_summary.cpp"
|
||||
#include "show/content_flags.cpp"
|
||||
#include "show/currencies.cpp"
|
||||
#include "show/distance.cpp"
|
||||
#include "show/emotes.cpp"
|
||||
@ -64,6 +65,7 @@ void command_show(Client *c, const Seperator *sep)
|
||||
Cmd{.cmd = "buffs", .u = "buffs", .fn = ShowBuffs, .a = {"#showbuffs"}},
|
||||
Cmd{.cmd = "buried_corpse_count", .u = "buried_corpse_count", .fn = ShowBuriedCorpseCount, .a = {"#getplayerburiedcorpsecount"}},
|
||||
Cmd{.cmd = "client_version_summary", .u = "client_version_summary", .fn = ShowClientVersionSummary, .a = {"#cvs"}},
|
||||
Cmd{.cmd = "content_flags", .u = "content_flags", .fn = ShowContentFlags, .a = {"#showcontentflags"}},
|
||||
Cmd{.cmd = "currencies", .u = "currencies", .fn = ShowCurrencies, .a = {"#viewcurrencies"}},
|
||||
Cmd{.cmd = "distance", .u = "distance", .fn = ShowDistance, .a = {"#distance"}},
|
||||
Cmd{.cmd = "emotes", .u = "emotes", .fn = ShowEmotes, .a = {"#emoteview"}},
|
||||
|
||||
30
zone/gm_commands/show/content_flags.cpp
Normal file
30
zone/gm_commands/show/content_flags.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "../../client.h"
|
||||
#include "../../dialogue_window.h"
|
||||
|
||||
void ShowContentFlags(Client *c, const Seperator *sep)
|
||||
{
|
||||
Client *t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
std::string flags = DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("id") +
|
||||
DialogueWindow::TableCell("flag_name") +
|
||||
DialogueWindow::TableCell("enabled")
|
||||
);
|
||||
|
||||
for (auto &f: ContentFlagsRepository::All(database)) {
|
||||
flags += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell(std::to_string(f.id)) +
|
||||
DialogueWindow::TableCell(f.flag_name) +
|
||||
DialogueWindow::TableCell(
|
||||
f.enabled ?
|
||||
DialogueWindow::ColorMessage("forest_green", "yes") :
|
||||
DialogueWindow::ColorMessage("red", "no")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
c->SendPopupToClient("Server Content Flag Settings", DialogueWindow::Table(flags).c_str());
|
||||
}
|
||||
@ -402,6 +402,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
content_service.SetDatabase(&database)
|
||||
->SetContentDatabase(&content_db)
|
||||
->SetContentZones(zone_store.GetZones())
|
||||
->SetExpansionContext()
|
||||
->ReloadContentFlags();
|
||||
|
||||
|
||||
@ -830,11 +830,21 @@ QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::strin
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}",
|
||||
path.GetQuestsPath(),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/{}", zone_versioned_path, npc_id), // Local versioned by NPC ID ./quests/zone/v0/10.ext
|
||||
fmt::format("{}/{}", zone_versioned_path, npc_name), // Local versioned by NPC Name ./quests/zone/v0/npc.ext
|
||||
fmt::format("{}/{}", zone_path, npc_id), // Local by NPC ID
|
||||
fmt::format("{}/{}", zone_path, npc_name), // Local by NPC Name
|
||||
fmt::format("{}/{}", global_path, npc_id), // Global by NPC ID
|
||||
fmt::format("{}/{}", global_path, npc_name), // Global by NPC ID
|
||||
fmt::format("{}/default", zone_versioned_path), // Zone Default ./quests/zone/v0/default.ext
|
||||
fmt::format("{}/default", zone_path), // Zone Default
|
||||
fmt::format("{}/default", global_path), // Global Default
|
||||
};
|
||||
@ -877,7 +887,15 @@ QuestInterface* QuestParserCollection::GetQIByPlayerQuest(std::string& filename)
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}",
|
||||
path.GetQuestsPath(),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/player", zone_versioned_path), // Local by Instance Version ./quests/zone/v0/player.ext
|
||||
fmt::format("{}/player_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version
|
||||
fmt::format("{}/player", zone_path), // Local
|
||||
fmt::format("{}/player", global_path) // Global
|
||||
@ -969,7 +987,15 @@ QuestInterface* QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}/spells",
|
||||
path.GetQuestsPath(),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/{}", zone_versioned_path, spell_id), // Local versioned by Spell ID ./quests/zone/v0/spells/10.ext
|
||||
fmt::format("{}/{}", zone_path, spell_id), // Local
|
||||
fmt::format("{}/{}", global_path, spell_id), // Global
|
||||
fmt::format("{}/default", zone_path), // Local Default
|
||||
@ -1013,7 +1039,15 @@ QuestInterface* QuestParserCollection::GetQIByItemQuest(std::string item_script,
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}/items",
|
||||
path.GetQuestsPath(),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/{}", zone_versioned_path, item_script), // Local versioned by Item Script ./quests/zone/v0/items/10.ext
|
||||
fmt::format("{}/{}", zone_path, item_script), // Local
|
||||
fmt::format("{}/{}", global_path, item_script), // Global
|
||||
fmt::format("{}/default", zone_path), // Local Default
|
||||
@ -1057,7 +1091,15 @@ QuestInterface* QuestParserCollection::GetQIByEncounterQuest(std::string encount
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}/encounters",
|
||||
path.GetQuestsPath(),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/{}", zone_versioned_path, encounter_name), // Local versioned ./quests/zone/v0/encounters/name.ext
|
||||
fmt::format("{}/{}", zone_path, encounter_name), // Local
|
||||
fmt::format("{}/{}", global_path, encounter_name) // Global
|
||||
};
|
||||
@ -1099,7 +1141,15 @@ QuestInterface* QuestParserCollection::GetQIByBotQuest(std::string& filename)
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}",
|
||||
path.GetQuestsPath(),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/bot", zone_versioned_path), // Local versioned by Instance Version ./quests/zone/v0/bot.ext
|
||||
fmt::format("{}/bot_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version
|
||||
fmt::format("{}/bot", zone_path), // Local
|
||||
fmt::format("{}/bot", global_path) // Global
|
||||
|
||||
@ -72,6 +72,8 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
||||
int(zone_mode)
|
||||
);
|
||||
|
||||
content_service.HandleZoneRoutingMiddleware(zc);
|
||||
|
||||
uint16 target_zone_id = 0;
|
||||
auto target_instance_id = zc->instanceID;
|
||||
ZonePoint* zone_point = nullptr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user