mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 03:11:28 +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 "world_content_service.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
#include "../database.h"
|
#include "../database.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../repositories/content_flags_repository.h"
|
#include "../repositories/instance_list_repository.h"
|
||||||
|
|
||||||
|
|
||||||
WorldContentService::WorldContentService()
|
WorldContentService::WorldContentService()
|
||||||
@ -200,6 +183,7 @@ void WorldContentService::ReloadContentFlags()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetContentFlags(set_content_flags);
|
SetContentFlags(set_content_flags);
|
||||||
|
SetContentZones(ZoneRepository::All(*m_content_database));
|
||||||
}
|
}
|
||||||
|
|
||||||
Database *WorldContentService::GetDatabase() const
|
Database *WorldContentService::GetDatabase() const
|
||||||
@ -214,6 +198,18 @@ WorldContentService *WorldContentService::SetDatabase(Database *database)
|
|||||||
return this;
|
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)
|
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
|
||||||
{
|
{
|
||||||
auto flags = ContentFlagsRepository::GetWhere(
|
auto flags = ContentFlagsRepository::GetWhere(
|
||||||
@ -238,3 +234,85 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
|||||||
|
|
||||||
ReloadContentFlags();
|
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
|
#ifndef EQEMU_WORLD_CONTENT_SERVICE_H
|
||||||
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../repositories/content_flags_repository.h"
|
#include "../repositories/content_flags_repository.h"
|
||||||
|
#include "../repositories/zone_repository.h"
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
@ -182,14 +163,23 @@ public:
|
|||||||
WorldContentService * SetDatabase(Database *database);
|
WorldContentService * SetDatabase(Database *database);
|
||||||
Database *GetDatabase() const;
|
Database *GetDatabase() const;
|
||||||
|
|
||||||
|
WorldContentService * SetContentDatabase(Database *database);
|
||||||
|
Database *GetContentDatabase() const;
|
||||||
|
|
||||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
||||||
|
|
||||||
|
void HandleZoneRoutingMiddleware(ZoneChange_Struct *zc);
|
||||||
|
WorldContentService * SetContentZones(const std::vector<ZoneRepository::Zone>& zones);
|
||||||
private:
|
private:
|
||||||
int current_expansion{};
|
int current_expansion{};
|
||||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||||
|
|
||||||
// reference to database
|
// reference to database
|
||||||
Database *m_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;
|
extern WorldContentService content_service;
|
||||||
|
|||||||
@ -5365,6 +5365,33 @@ ALTER TABLE `character_corpses` MODIFY COLUMN `time_of_death` datetime NOT NULL
|
|||||||
.sql = R"(
|
.sql = R"(
|
||||||
ALTER TABLE `object_contents` MODIFY COLUMN `droptime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
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
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
// ManifestEntry{
|
// ManifestEntry{
|
||||||
|
|||||||
@ -890,7 +890,7 @@ RULE_INT(Expansion, AutoGrantAAExpansion, -1, "Expansion to auto grant AAs up to
|
|||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Instances)
|
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_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_INT(Instances, GuildHallExpirationDays, 90, "Amount of days before a Guild Hall instance expires")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* 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
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9042
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -168,6 +168,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion));
|
content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion));
|
||||||
content_service.SetDatabase(&database)
|
content_service.SetDatabase(&database)
|
||||||
|
->SetContentDatabase(&content_db)
|
||||||
->SetExpansionContext()
|
->SetExpansionContext()
|
||||||
->ReloadContentFlags();
|
->ReloadContentFlags();
|
||||||
|
|
||||||
|
|||||||
@ -381,6 +381,7 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
|||||||
|
|
||||||
LogInfo("Initializing [WorldContentService]");
|
LogInfo("Initializing [WorldContentService]");
|
||||||
content_service.SetDatabase(&database)
|
content_service.SetDatabase(&database)
|
||||||
|
->SetContentDatabase(&content_db)
|
||||||
->SetExpansionContext()
|
->SetExpansionContext()
|
||||||
->ReloadContentFlags();
|
->ReloadContentFlags();
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,7 @@ extern volatile bool RunLoops;
|
|||||||
#include "../common/events/player_events.h"
|
#include "../common/events/player_events.h"
|
||||||
#include "../common/events/player_event_logs.h"
|
#include "../common/events/player_event_logs.h"
|
||||||
#include "dialogue_window.h"
|
#include "dialogue_window.h"
|
||||||
|
#include "../common/zone_store.h"
|
||||||
|
|
||||||
|
|
||||||
extern QueryServ* QServ;
|
extern QueryServ* QServ;
|
||||||
@ -9108,6 +9109,7 @@ void Client::ShowDevToolsMenu()
|
|||||||
*/
|
*/
|
||||||
menu_show += Saylink::Silent("#showzonepoints", "Zone Points");
|
menu_show += Saylink::Silent("#showzonepoints", "Zone Points");
|
||||||
menu_show += " | " + Saylink::Silent("#showzonegloballoot", "Zone Global Loot");
|
menu_show += " | " + Saylink::Silent("#showzonegloballoot", "Zone Global Loot");
|
||||||
|
menu_show += " | " + Saylink::Silent("#show content_flags", "Content Flags");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload
|
* Reload
|
||||||
@ -9165,14 +9167,6 @@ void Client::ShowDevToolsMenu()
|
|||||||
|
|
||||||
Message(Chat::White, "Developer Tools Menu");
|
Message(Chat::White, "Developer Tools Menu");
|
||||||
|
|
||||||
Message(
|
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
|
||||||
"Current Expansion | {}",
|
|
||||||
content_service.GetCurrentExpansionName()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
Message(
|
Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -9288,6 +9282,36 @@ void Client::ShowDevToolsMenu()
|
|||||||
);
|
);
|
||||||
|
|
||||||
SendChatLineBreak();
|
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) {
|
void Client::SendChatLineBreak(uint16 color) {
|
||||||
|
|||||||
@ -954,7 +954,6 @@ void Client::CompleteConnect()
|
|||||||
heroforge_wearchange_timer.Start(250);
|
heroforge_wearchange_timer.Start(250);
|
||||||
|
|
||||||
RecordStats();
|
RecordStats();
|
||||||
|
|
||||||
AutoGrantAAPoints();
|
AutoGrantAAPoints();
|
||||||
|
|
||||||
// enforce some rules..
|
// enforce some rules..
|
||||||
@ -17138,3 +17137,4 @@ void Client::Handle_OP_GuildTributeDonatePlat(const EQApplicationPacket *app)
|
|||||||
RequestGuildFavorAndTimer(GuildID());
|
RequestGuildFavorAndTimer(GuildID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "show/buffs.cpp"
|
#include "show/buffs.cpp"
|
||||||
#include "show/buried_corpse_count.cpp"
|
#include "show/buried_corpse_count.cpp"
|
||||||
#include "show/client_version_summary.cpp"
|
#include "show/client_version_summary.cpp"
|
||||||
|
#include "show/content_flags.cpp"
|
||||||
#include "show/currencies.cpp"
|
#include "show/currencies.cpp"
|
||||||
#include "show/distance.cpp"
|
#include "show/distance.cpp"
|
||||||
#include "show/emotes.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 = "buffs", .u = "buffs", .fn = ShowBuffs, .a = {"#showbuffs"}},
|
||||||
Cmd{.cmd = "buried_corpse_count", .u = "buried_corpse_count", .fn = ShowBuriedCorpseCount, .a = {"#getplayerburiedcorpsecount"}},
|
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 = "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 = "currencies", .u = "currencies", .fn = ShowCurrencies, .a = {"#viewcurrencies"}},
|
||||||
Cmd{.cmd = "distance", .u = "distance", .fn = ShowDistance, .a = {"#distance"}},
|
Cmd{.cmd = "distance", .u = "distance", .fn = ShowDistance, .a = {"#distance"}},
|
||||||
Cmd{.cmd = "emotes", .u = "emotes", .fn = ShowEmotes, .a = {"#emoteview"}},
|
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)
|
content_service.SetDatabase(&database)
|
||||||
|
->SetContentDatabase(&content_db)
|
||||||
|
->SetContentZones(zone_store.GetZones())
|
||||||
->SetExpansionContext()
|
->SetExpansionContext()
|
||||||
->ReloadContentFlags();
|
->ReloadContentFlags();
|
||||||
|
|
||||||
|
|||||||
@ -830,11 +830,21 @@ QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::strin
|
|||||||
zone->GetShortName()
|
zone->GetShortName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string& zone_versioned_path = fmt::format(
|
||||||
|
"{}/{}/v{}",
|
||||||
|
path.GetQuestsPath(),
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion()
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<std::string> file_names = {
|
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_id), // Local by NPC ID
|
||||||
fmt::format("{}/{}", zone_path, npc_name), // Local by NPC Name
|
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_id), // Global by NPC ID
|
||||||
fmt::format("{}/{}", global_path, npc_name), // 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", zone_path), // Zone Default
|
||||||
fmt::format("{}/default", global_path), // Global Default
|
fmt::format("{}/default", global_path), // Global Default
|
||||||
};
|
};
|
||||||
@ -877,7 +887,15 @@ QuestInterface* QuestParserCollection::GetQIByPlayerQuest(std::string& filename)
|
|||||||
zone->GetShortName()
|
zone->GetShortName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string& zone_versioned_path = fmt::format(
|
||||||
|
"{}/{}/v{}",
|
||||||
|
path.GetQuestsPath(),
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion()
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<std::string> file_names = {
|
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_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version
|
||||||
fmt::format("{}/player", zone_path), // Local
|
fmt::format("{}/player", zone_path), // Local
|
||||||
fmt::format("{}/player", global_path) // Global
|
fmt::format("{}/player", global_path) // Global
|
||||||
@ -969,7 +987,15 @@ QuestInterface* QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
|
|||||||
zone->GetShortName()
|
zone->GetShortName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string& zone_versioned_path = fmt::format(
|
||||||
|
"{}/{}/v{}/spells",
|
||||||
|
path.GetQuestsPath(),
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion()
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<std::string> file_names = {
|
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("{}/{}", zone_path, spell_id), // Local
|
||||||
fmt::format("{}/{}", global_path, spell_id), // Global
|
fmt::format("{}/{}", global_path, spell_id), // Global
|
||||||
fmt::format("{}/default", zone_path), // Local Default
|
fmt::format("{}/default", zone_path), // Local Default
|
||||||
@ -1013,7 +1039,15 @@ QuestInterface* QuestParserCollection::GetQIByItemQuest(std::string item_script,
|
|||||||
zone->GetShortName()
|
zone->GetShortName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string& zone_versioned_path = fmt::format(
|
||||||
|
"{}/{}/v{}/items",
|
||||||
|
path.GetQuestsPath(),
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion()
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<std::string> file_names = {
|
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("{}/{}", zone_path, item_script), // Local
|
||||||
fmt::format("{}/{}", global_path, item_script), // Global
|
fmt::format("{}/{}", global_path, item_script), // Global
|
||||||
fmt::format("{}/default", zone_path), // Local Default
|
fmt::format("{}/default", zone_path), // Local Default
|
||||||
@ -1057,7 +1091,15 @@ QuestInterface* QuestParserCollection::GetQIByEncounterQuest(std::string encount
|
|||||||
zone->GetShortName()
|
zone->GetShortName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string& zone_versioned_path = fmt::format(
|
||||||
|
"{}/{}/v{}/encounters",
|
||||||
|
path.GetQuestsPath(),
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion()
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<std::string> file_names = {
|
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("{}/{}", zone_path, encounter_name), // Local
|
||||||
fmt::format("{}/{}", global_path, encounter_name) // Global
|
fmt::format("{}/{}", global_path, encounter_name) // Global
|
||||||
};
|
};
|
||||||
@ -1099,7 +1141,15 @@ QuestInterface* QuestParserCollection::GetQIByBotQuest(std::string& filename)
|
|||||||
zone->GetShortName()
|
zone->GetShortName()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string& zone_versioned_path = fmt::format(
|
||||||
|
"{}/{}/v{}",
|
||||||
|
path.GetQuestsPath(),
|
||||||
|
zone->GetShortName(),
|
||||||
|
zone->GetInstanceVersion()
|
||||||
|
);
|
||||||
|
|
||||||
std::vector<std::string> file_names = {
|
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_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version
|
||||||
fmt::format("{}/bot", zone_path), // Local
|
fmt::format("{}/bot", zone_path), // Local
|
||||||
fmt::format("{}/bot", global_path) // Global
|
fmt::format("{}/bot", global_path) // Global
|
||||||
|
|||||||
@ -72,6 +72,8 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
|||||||
int(zone_mode)
|
int(zone_mode)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
content_service.HandleZoneRoutingMiddleware(zc);
|
||||||
|
|
||||||
uint16 target_zone_id = 0;
|
uint16 target_zone_id = 0;
|
||||||
auto target_instance_id = zc->instanceID;
|
auto target_instance_id = zc->instanceID;
|
||||||
ZonePoint* zone_point = nullptr;
|
ZonePoint* zone_point = nullptr;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user