[Commands] Add additional #peqzone functionality. (#2085)

* [Commands] Add additional #peqzone functionality.
- Add #peqzone flagging capabilities so operators don't have to blanket allow #peqzone access to zones.
- Allows you to set a zone's `peqzone` column to `2` and disallow use of `#peqzone` until they have been given the appropriate flag.
- Add #peqzone_flags command to list your #peqzone flags similar to #flags command.
- Add `character_peqzone_flags` table to database and database_schema.h.
- Required SQL update to add the new table.
- Add client:ClearPEQZoneFlag(zone_id) to Lua.
- Add client:HasPEQZoneFlag(zone_id) to Lua.
- Add client:LoadPEQZoneFlags() to Lua.
- Add client:LoadZoneFlags() to Lua.
- Add client:SendPEQZoneFlagInfo(client) to Lua.
- Add client:SetPEQZoneFlag(zone_id) to Lua.
- Add $client->ClearPEQZoneFlag(zone_id) to Perl.
- Add $client->HasPEQZoneFlag(zone_id) to Perl.
- Add $client->LoadPEQZoneFlags() to Perl.
- Add $client->SendPEQZoneFlagInfo(client) to Perl.
- Add $client->SetPEQZoneFlag(zone_id) to Perl.

* Fixes.
This commit is contained in:
Kinglykrab 2022-05-01 19:39:52 -04:00 committed by GitHub
parent c7dbdfae58
commit d59dcb68ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 404 additions and 88 deletions

View File

@ -1143,21 +1143,21 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
return true;
}
uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version);
uint8 Database::GetPEQZone(uint32 zone_id, uint32 version){
std::string query = fmt::format(
"SELECT peqzone FROM zone WHERE zoneidnumber = {} AND (version = {} OR version = 0) ORDER BY version DESC LIMIT 1",
zone_id,
version
);
auto results = QueryDatabase(query);
if (!results.Success()) {
if (!results.Success() || !results.RowCount()) {
return 0;
}
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
return static_cast<uint8>(std::stoi(row[0]));
}
bool Database::CheckNameFilter(const char* name, bool surname)

View File

@ -254,7 +254,7 @@ public:
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
uint8 GetPEQZone(uint32 zoneID, uint32 version);
uint8 GetPEQZone(uint32 zone_id, uint32 version);
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
uint8 GetServerType();
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);

View File

@ -62,6 +62,7 @@ namespace DatabaseSchema {
{"character_pet_buffs", "char_id"},
{"character_pet_info", "char_id"},
{"character_pet_inventory", "char_id"},
{"character_peqzone_flags", "id"},
{"character_potionbelt", "id"},
{"character_skills", "id"},
{"character_spells", "id"},
@ -129,6 +130,7 @@ namespace DatabaseSchema {
"character_pet_buffs",
"character_pet_info",
"character_pet_inventory",
"character_peqzone_flags",
"character_potionbelt",
"character_skills",
"character_spells",

View File

@ -34,7 +34,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9179
#define CURRENT_BINARY_DATABASE_VERSION 9180
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9028

View File

@ -433,6 +433,7 @@
9177|2022_03_06_table_structure_changes.sql|SHOW COLUMNS FROM `pets` LIKE 'id'|empty|
9178|2022_03_07_saylink_collation.sql|SELECT * FROM db_version WHERE version >= 9178|empty|
9179|2022_04_30_hp_regen_per_second.sql|SHOW COLUMNS FROM `npc_types` LIKE 'hp_regen_per_second'|empty|
9180|2022_05_01_character_peqzone_flags.sql|SHOW TABLES LIKE 'character_peqzone_flags'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -1 +1 @@
ALTER TABLE npc_types ADD COLUMN hp_regen_per_second bigint(11) DEFAULT 0 AFTER hp_regen_rate;
ALTER TABLE npc_types ADD COLUMN hp_regen_per_second bigint(11) DEFAULT 0 AFTER hp_regen_rate;

View File

@ -0,0 +1,14 @@
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for character_peqzone_flags
-- ----------------------------
DROP TABLE IF EXISTS `character_peqzone_flags`;
CREATE TABLE `character_peqzone_flags` (
`id` int NOT NULL DEFAULT 0,
`zone_id` int NOT NULL DEFAULT 0,
PRIMARY KEY (`id`, `zone_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -287,7 +287,6 @@ SET(zone_headers
zone_store.h
)
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)

View File

@ -992,11 +992,17 @@ public:
virtual void ThrowingAttack(Mob* other, bool CanDoubleAttack = false);
void DoClassAttacks(Mob *ca_target, uint16 skill = -1, bool IsRiposte=false);
void SetZoneFlag(uint32 zone_id);
void ClearZoneFlag(uint32 zone_id);
bool HasZoneFlag(uint32 zone_id) const;
void SendZoneFlagInfo(Client *to) const;
void LoadZoneFlags();
void SendZoneFlagInfo(Client *to) const;
void SetZoneFlag(uint32 zone_id);
void ClearPEQZoneFlag(uint32 zone_id);
bool HasPEQZoneFlag(uint32 zone_id) const;
void LoadPEQZoneFlags();
void SendPEQZoneFlagInfo(Client *to) const;
void SetPEQZoneFlag(uint32 zone_id);
bool CanFish();
void GoFish();
@ -1917,6 +1923,7 @@ private:
float AreaEndRegen;
std::set<uint32> zone_flags;
std::set<uint32> peqzone_flags;
ClientTaskState *task_state;
int TotalSecondsPlayed;

View File

@ -536,6 +536,7 @@ void Client::CompleteConnect()
SetDueling(false);
EnteringMessages(this);
LoadPEQZoneFlags();
LoadZoneFlags();
/* Sets GM Flag if needed & Sends Petition Queue */

View File

@ -184,7 +184,7 @@ int command_init(void)
command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", AccountStatus::QuestTroupe, command_fixmob) ||
command_add("flag", "[status] [acctname] - Refresh your admin status, or set an account's admin status if arguments provided", AccountStatus::Player, command_flag) ||
command_add("flagedit", "- Edit zone flags on your target. Use #flagedit help for more info.", AccountStatus::GMAdmin, command_flagedit) ||
command_add("flags", "- displays the flags of you or your target", AccountStatus::Player, command_flags) ||
command_add("flags", "- displays the Zone Flags of you or your target", AccountStatus::Player, command_flags) ||
command_add("flymode", "[0/1/2/3/4/5] - Set your or your player target's flymode to ground/flying/levitate/water/floating/levitate_running", AccountStatus::Guide, command_flymode) ||
command_add("fov", "- Check wether you're behind or in your target's field of view", AccountStatus::QuestTroupe, command_fov) ||
command_add("freeze", "- Freeze your target", AccountStatus::QuestTroupe, command_freeze) ||
@ -276,6 +276,7 @@ int command_init(void)
command_add("path", "- view and edit pathing", AccountStatus::GMMgmt, command_path) ||
command_add("peekinv", "[equip/gen/cursor/poss/limbo/curlim/trib/bank/shbank/allbank/trade/world/all] - Print out contents of your player target's inventory", AccountStatus::GMAdmin, command_peekinv) ||
command_add("peqzone", "[Zone ID|Zone Short Name] - Teleports you to the specified zone if you meet the requirements.", AccountStatus::Player, command_peqzone) ||
command_add("peqzone_flags", "- displays the PEQZone Flags of you or your target", AccountStatus::Player, command_peqzone_flags) ||
command_add("permaclass", "[Class ID] - Change your or your player target's class, changed client is disconnected", AccountStatus::QuestTroupe, command_permaclass) ||
command_add("permagender", "[Gender ID] - Change your or your player target's gender", AccountStatus::QuestTroupe, command_permagender) ||
command_add("permarace", "[Race ID] - Change your or your player target's race", AccountStatus::QuestTroupe, command_permarace) ||
@ -1331,6 +1332,7 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/path.cpp"
#include "gm_commands/peekinv.cpp"
#include "gm_commands/peqzone.cpp"
#include "gm_commands/peqzone_flags.cpp"
#include "gm_commands/permaclass.cpp"
#include "gm_commands/permagender.cpp"
#include "gm_commands/permarace.cpp"

View File

@ -192,6 +192,7 @@ void command_packetprofile(Client *c, const Seperator *sep);
void command_path(Client *c, const Seperator *sep);
void command_peekinv(Client *c, const Seperator *sep);
void command_peqzone(Client *c, const Seperator *sep);
void command_peqzone_flags(Client *c, const Seperator *sep);
void command_permaclass(Client *c, const Seperator *sep);
void command_permagender(Client *c, const Seperator *sep);
void command_permarace(Client *c, const Seperator *sep);

View File

@ -68,12 +68,8 @@ void command_peqzone(Client *c, const Seperator *sep)
return;
}
bool allows_peqzone = (
content_db.GetPEQZone(zone_id, 0) ?
true :
false
);
if (!allows_peqzone) {
uint8 peqzone_flag = content_db.GetPEQZone(zone_id, 0);
if (peqzone_flag == 0) {
c->Message(
Chat::White,
fmt::format(
@ -83,6 +79,16 @@ void command_peqzone(Client *c, const Seperator *sep)
).c_str()
);
return;
} else if (peqzone_flag == 2 && !c->HasPEQZoneFlag(zone_id)) {
c->Message(
Chat::White,
fmt::format(
"You do not have the required PEQZone flag to use this command to enter {} ({}).",
zone_long_name,
zone_short_name
).c_str()
);
return;
}
if (zone_id == zone->GetZoneID()) {

View File

@ -0,0 +1,17 @@
#include "../client.h"
void command_peqzone_flags(Client *c, const Seperator *sep)
{
Client *target = c;
if (
c->GetTarget() &&
c->GetTarget()->IsClient() &&
c->Admin() >= minStatusToSeeOthersZoneFlags
) {
target = c->GetTarget()->CastToClient();
}
target->SendPEQZoneFlagInfo(c);
}

View File

@ -1100,17 +1100,17 @@ int Lua_Client::GetCharacterFactionLevel(int faction_id) {
return self->GetCharacterFactionLevel(faction_id);
}
void Lua_Client::SetZoneFlag(int zone_id) {
void Lua_Client::SetZoneFlag(uint32 zone_id) {
Lua_Safe_Call_Void();
self->SetZoneFlag(zone_id);
}
void Lua_Client::ClearZoneFlag(int zone_id) {
void Lua_Client::ClearZoneFlag(uint32 zone_id) {
Lua_Safe_Call_Void();
self->ClearZoneFlag(zone_id);
}
bool Lua_Client::HasZoneFlag(int zone_id) {
bool Lua_Client::HasZoneFlag(uint32 zone_id) {
Lua_Safe_Call_Bool();
return self->HasZoneFlag(zone_id);
}
@ -2446,6 +2446,36 @@ bool Lua_Client::TakePlatinum(uint32 platinum, bool update_client) {
return self->TakePlatinum(platinum, update_client);
}
void Lua_Client::LoadZoneFlags() {
Lua_Safe_Call_Void();
self->LoadZoneFlags();
}
void Lua_Client::ClearPEQZoneFlag(uint32 zone_id) {
Lua_Safe_Call_Void();
self->ClearPEQZoneFlag(zone_id);
}
bool Lua_Client::HasPEQZoneFlag(uint32 zone_id) {
Lua_Safe_Call_Bool();
return self->HasPEQZoneFlag(zone_id);
}
void Lua_Client::LoadPEQZoneFlags() {
Lua_Safe_Call_Void();
self->LoadPEQZoneFlags();
}
void Lua_Client::SendPEQZoneFlagInfo(Lua_Client to) {
Lua_Safe_Call_Void();
self->SendPEQZoneFlagInfo(to);
}
void Lua_Client::SetPEQZoneFlag(uint32 zone_id) {
Lua_Safe_Call_Void();
self->SetPEQZoneFlag(zone_id);
}
luabind::scope lua_register_client() {
return luabind::class_<Lua_Client, Lua_Mob>("Client")
.def(luabind::constructor<>())
@ -2489,7 +2519,8 @@ luabind::scope lua_register_client() {
.def("CheckIncreaseSkill", (void(Lua_Client::*)(int,Lua_Mob,int))&Lua_Client::CheckIncreaseSkill)
.def("CheckSpecializeIncrease", (void(Lua_Client::*)(int))&Lua_Client::CheckSpecializeIncrease)
.def("ClearCompassMark",(void(Lua_Client::*)(void))&Lua_Client::ClearCompassMark)
.def("ClearZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::ClearZoneFlag)
.def("ClearPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::ClearPEQZoneFlag)
.def("ClearZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::ClearZoneFlag)
.def("Connected", (bool(Lua_Client::*)(void))&Lua_Client::Connected)
.def("CountAugmentEquippedByID", (int(Lua_Client::*)(uint32))&Lua_Client::CountAugmentEquippedByID)
.def("CountItem", (int(Lua_Client::*)(uint32))&Lua_Client::CountItem)
@ -2646,9 +2677,10 @@ luabind::scope lua_register_client() {
.def("HasDisciplineLearned", (bool(Lua_Client::*)(uint16))&Lua_Client::HasDisciplineLearned)
.def("HasExpeditionLockout", (bool(Lua_Client::*)(std::string, std::string))&Lua_Client::HasExpeditionLockout)
.def("HasItemEquippedByID", (bool(Lua_Client::*)(uint32))&Lua_Client::HasItemEquippedByID)
.def("HasPEQZoneFlag", (bool(Lua_Client::*)(uint32))&Lua_Client::HasPEQZoneFlag)
.def("HasSkill", (bool(Lua_Client::*)(int))&Lua_Client::HasSkill)
.def("HasSpellScribed", (bool(Lua_Client::*)(int))&Lua_Client::HasSpellScribed)
.def("HasZoneFlag", (bool(Lua_Client::*)(int))&Lua_Client::HasZoneFlag)
.def("HasZoneFlag", (bool(Lua_Client::*)(uint32))&Lua_Client::HasZoneFlag)
.def("Hungry", (bool(Lua_Client::*)(void))&Lua_Client::Hungry)
.def("InZone", (bool(Lua_Client::*)(void))&Lua_Client::InZone)
.def("IncStats", (void(Lua_Client::*)(int,int))&Lua_Client::IncStats)
@ -2675,6 +2707,8 @@ luabind::scope lua_register_client() {
.def("LearnDisciplines", (uint16(Lua_Client::*)(uint8,uint8))&Lua_Client::LearnDisciplines)
.def("LearnRecipe", (void(Lua_Client::*)(uint32))&Lua_Client::LearnRecipe)
.def("LeaveGroup", (void(Lua_Client::*)(void))&Lua_Client::LeaveGroup)
.def("LoadPEQZoneFlags", (void(Lua_Client::*)(void))&Lua_Client::LoadPEQZoneFlags)
.def("LoadZoneFlags", (void(Lua_Client::*)(void))&Lua_Client::LoadZoneFlags)
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float))&Lua_Client::MarkSingleCompassLoc)
.def("MarkSingleCompassLoc", (void(Lua_Client::*)(float,float,float,int))&Lua_Client::MarkSingleCompassLoc)
.def("MaxSkill", (int(Lua_Client::*)(int))&Lua_Client::MaxSkill)
@ -2749,6 +2783,7 @@ luabind::scope lua_register_client() {
.def("SendItemScale", (void(Lua_Client::*)(Lua_ItemInst))&Lua_Client::SendItemScale)
.def("SendMarqueeMessage", (void(Lua_Client::*)(uint32, uint32, uint32, uint32, uint32, std::string))&Lua_Client::SendMarqueeMessage)
.def("SendOPTranslocateConfirm", (void(Lua_Client::*)(Lua_Mob,int))&Lua_Client::SendOPTranslocateConfirm)
.def("SendPEQZoneFlagInfo", (void(Lua_Client::*)(Lua_Client))&Lua_Client::SendPEQZoneFlagInfo)
.def("SendSound", (void(Lua_Client::*)(void))&Lua_Client::SendSound)
.def("SendToGuildHall", (void(Lua_Client::*)(void))&Lua_Client::SendToGuildHall)
.def("SendToInstance", (void(Lua_Client::*)(std::string,std::string,uint32,float,float,float,float,std::string,uint32))&Lua_Client::SendToInstance)
@ -2795,6 +2830,7 @@ luabind::scope lua_register_client() {
.def("SetIPExemption", (void(Lua_Client::*)(int))&Lua_Client::SetIPExemption)
.def("SetLanguageSkill", (void(Lua_Client::*)(int,int))&Lua_Client::SetLanguageSkill)
.def("SetMaterial", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetMaterial)
.def("SetPEQZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetPEQZoneFlag)
.def("SetPVP", (void(Lua_Client::*)(bool))&Lua_Client::SetPVP)
.def("SetPrimaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetPrimaryWeaponOrnamentation)
.def("SetRadiantCrystals", (void(Lua_Client::*)(uint32))&Lua_Client::SetRadiantCrystals)
@ -2809,7 +2845,7 @@ luabind::scope lua_register_client() {
.def("SetThirst", (void(Lua_Client::*)(int))&Lua_Client::SetThirst)
.def("SetTint", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetTint)
.def("SetTitleSuffix", (void(Lua_Client::*)(const char *))&Lua_Client::SetTitleSuffix)
.def("SetZoneFlag", (void(Lua_Client::*)(int))&Lua_Client::SetZoneFlag)
.def("SetZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetZoneFlag)
.def("Signal", (void(Lua_Client::*)(uint32))&Lua_Client::Signal)
.def("Sit", (void(Lua_Client::*)(void))&Lua_Client::Sit)
.def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand)

View File

@ -255,10 +255,16 @@ public:
bool UseDiscipline(int spell_id, int target_id);
bool HasDisciplineLearned(uint16 spell_id);
int GetCharacterFactionLevel(int faction_id);
void SetZoneFlag(int zone_id);
void ClearZoneFlag(int zone_id);
bool HasZoneFlag(int zone_id);
void ClearZoneFlag(uint32 zone_id);
bool HasZoneFlag(uint32 zone_id);
void LoadZoneFlags();
void SendZoneFlagInfo(Lua_Client to);
void SetZoneFlag(uint32 zone_id);
void ClearPEQZoneFlag(uint32 zone_id);
bool HasPEQZoneFlag(uint32 zone_id);
void LoadPEQZoneFlags();
void SendPEQZoneFlagInfo(Lua_Client to);
void SetPEQZoneFlag(uint32 zone_id);
void SetAATitle(const char *title);
int GetClientVersion();
uint32 GetClientVersionBit();

View File

@ -6252,6 +6252,86 @@ XS(XS_Client_TakePlatinum) {
XSRETURN(1);
}
XS(XS_Client_ClearPEQZoneFlag); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_ClearPEQZoneFlag) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::ClearPEQZoneFlag(THIS, uint32 zone_id)"); // @categories Script Utility
{
Client *THIS;
uint32 zone_id = (uint32) SvUV(ST(1));
VALIDATE_THIS_IS_CLIENT;
THIS->ClearPEQZoneFlag(zone_id);
}
XSRETURN_EMPTY;
}
XS(XS_Client_HasPEQZoneFlag); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_HasPEQZoneFlag) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::HasPEQZoneFlag(THIS, uint32 zone_id)"); // @categories Account and Character
{
Client *THIS;
bool RETVAL;
uint32 zone_id = (uint32) SvUV(ST(1));
VALIDATE_THIS_IS_CLIENT;
RETVAL = THIS->HasPEQZoneFlag(zone_id);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_Client_LoadPEQZoneFlags); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_LoadPEQZoneFlags) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Client::LoadPEQZoneFlags(THIS)"); // @categories Zones
{
Client *THIS;
VALIDATE_THIS_IS_CLIENT;
THIS->LoadPEQZoneFlags();
}
XSRETURN_EMPTY;
}
XS(XS_Client_SendPEQZoneFlagInfo); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_SendPEQZoneFlagInfo) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::SendPEQZoneFlagInfo(THIS, Client* to)"); // @categories Account and Character, Zones
{
Client *THIS;
Client *to;
VALIDATE_THIS_IS_CLIENT;
if (sv_derived_from(ST(1), "Client")) {
IV tmp = SvIV((SV *) SvRV(ST(1)));
to = INT2PTR(Client *, tmp);
} else
Perl_croak(aTHX_ "to is not of type Client");
if (to == nullptr)
Perl_croak(aTHX_ "to is nullptr, avoiding crash.");
THIS->SendPEQZoneFlagInfo(to);
}
XSRETURN_EMPTY;
}
XS(XS_Client_SetPEQZoneFlag); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_SetPEQZoneFlag) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Client::SetPEQZoneFlag(THIS, uint32 zone_id)"); // @categories Account and Character, PEQZones
{
Client *THIS;
uint32 zone_id = (uint32) SvUV(ST(1));
VALIDATE_THIS_IS_CLIENT;
THIS->SetPEQZoneFlag(zone_id);
}
XSRETURN_EMPTY;
}
#ifdef __cplusplus
extern "C"
#endif
@ -6298,6 +6378,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "CheckIncreaseSkill"), XS_Client_CheckIncreaseSkill, file, "$$;$");
newXSproto(strcpy(buf, "CheckSpecializeIncrease"), XS_Client_CheckSpecializeIncrease, file, "$$");
newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$");
newXSproto(strcpy(buf, "ClearPEQZoneFlag"), XS_Client_ClearPEQZoneFlag, file, "$$");
newXSproto(strcpy(buf, "ClearZoneFlag"), XS_Client_ClearZoneFlag, file, "$$");
newXSproto(strcpy(buf, "Connected"), XS_Client_Connected, file, "$");
newXSproto(strcpy(buf, "CountAugmentEquippedByID"), XS_Client_CountAugmentEquippedByID, file, "$$");
@ -6436,6 +6517,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "HasDisciplineLearned"), XS_Client_HasDisciplineLearned, file, "$$");
newXSproto(strcpy(buf, "HasExpeditionLockout"), XS_Client_HasExpeditionLockout, file, "$$$");
newXSproto(strcpy(buf, "HasItemEquippedByID"), XS_Client_HasItemEquippedByID, file, "$$");
newXSproto(strcpy(buf, "HasPEQZoneFlag"), XS_Client_HasPEQZoneFlag, file, "$$");
newXSproto(strcpy(buf, "HasSkill"), XS_Client_HasSkill, file, "$$");
newXSproto(strcpy(buf, "HasSpellScribed"), XS_Client_HasSkill, file, "$$");
newXSproto(strcpy(buf, "HasZoneFlag"), XS_Client_HasZoneFlag, file, "$$");
@ -6463,6 +6545,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "LearnDisciplines"), XS_Client_LearnDisciplines, file, "$$$");
newXSproto(strcpy(buf, "LearnRecipe"), XS_Client_LearnRecipe, file, "$$");
newXSproto(strcpy(buf, "LeaveGroup"), XS_Client_LeaveGroup, file, "$");
newXSproto(strcpy(buf, "LoadPEQZoneFlags"), XS_Client_LoadPEQZoneFlags, file, "$");
newXSproto(strcpy(buf, "LoadZoneFlags"), XS_Client_LoadZoneFlags, file, "$");
newXSproto(strcpy(buf, "MarkCompassLoc"), XS_Client_MarkCompassLoc, file, "$$$$");
newXSproto(strcpy(buf, "MaxSkill"), XS_Client_MaxSkill, file, "$$;$$");
@ -6507,6 +6590,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "SendColoredText"), XS_Client_SendColoredText, file, "$$$");
newXSproto(strcpy(buf, "SendMarqueeMessage"), XS_Client_SendMarqueeMessage, file, "$$$$$$$");
newXSproto(strcpy(buf, "SendOPTranslocateConfirm"), XS_Client_SendOPTranslocateConfirm, file, "$$$");
newXSproto(strcpy(buf, "SendPEQZoneFlagInfo"), XS_Client_SendPEQZoneFlagInfo, file, "$$");
newXSproto(strcpy(buf, "SendSound"), XS_Client_SendSound, file, "$");
newXSproto(strcpy(buf, "SendSpellAnim"), XS_Client_SendSpellAnim, file, "$$$");
newXSproto(strcpy(buf, "SendTargetCommand"), XS_Client_SendTargetCommand, file, "$$");
@ -6550,6 +6634,7 @@ XS(boot_Client) {
newXSproto(strcpy(buf, "SetInvulnerableEnvironmentDamage"), XS_Client_SetInvulnerableEnvironmentDamage, file, "$$");
newXSproto(strcpy(buf, "SetLanguageSkill"), XS_Client_SetLanguageSkill, file, "$$$");
newXSproto(strcpy(buf, "SetMaterial"), XS_Client_SetMaterial, file, "$$$");
newXSproto(strcpy(buf, "SetPEQZoneFlag"), XS_Client_SetPEQZoneFlag, file, "$$");
newXSproto(strcpy(buf, "SetPVP"), XS_Client_SetPVP, file, "$$");
newXSproto(strcpy(buf, "SetPrimaryWeaponOrnamentation"), XS_Client_SetPrimaryWeaponOrnamentation, file, "$$");
newXSproto(strcpy(buf, "SetRadiantCrystals"), XS_Client_SetRadiantCrystals, file, "$$");

View File

@ -980,53 +980,50 @@ void Client::GoToDeath() {
MovePC(m_pp.binds[0].zone_id, m_pp.binds[0].instance_id, 0.0f, 0.0f, 0.0f, 0.0f, 1, ZoneToBindPoint);
}
void Client::SetZoneFlag(uint32 zone_id) {
if(HasZoneFlag(zone_id))
return;
zone_flags.insert(zone_id);
// Retrieve all waypoints for this grid
std::string query = StringFormat("INSERT INTO zone_flags (charID,zoneID) VALUES(%d,%d)", CharacterID(), zone_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogError("MySQL Error while trying to set zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
}
void Client::ClearZoneFlag(uint32 zone_id) {
if(!HasZoneFlag(zone_id))
if (!HasZoneFlag(zone_id)) {
return;
}
zone_flags.erase(zone_id);
// Retrieve all waypoints for this grid
std::string query = StringFormat("DELETE FROM zone_flags WHERE charID=%d AND zoneID=%d", CharacterID(), zone_id);
std::string query = fmt::format(
"DELETE FROM zone_flags WHERE charID = {} AND zoneID = {}",
CharacterID(),
zone_id
);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogError("MySQL Error while trying to clear zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
if (!results.Success()) {
LogError("MySQL Error while trying to clear zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
}
}
bool Client::HasZoneFlag(uint32 zone_id) const {
return zone_flags.find(zone_id) != zone_flags.end();
}
void Client::LoadZoneFlags() {
// Retrieve all waypoints for this grid
std::string query = StringFormat("SELECT zoneID from zone_flags WHERE charID=%d", CharacterID());
std::string query = fmt::format(
"SELECT zoneID from zone_flags WHERE charID = {}",
CharacterID()
);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogError("MySQL Error while trying to load zone flags for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
return;
}
for(auto row = results.begin(); row != results.end(); ++row)
zone_flags.insert(atoi(row[0]));
}
zone_flags.clear();
bool Client::HasZoneFlag(uint32 zone_id) const {
return(zone_flags.find(zone_id) != zone_flags.end());
for (auto row : results) {
zone_flags.insert(std::stoul(row[0]));
}
}
void Client::SendZoneFlagInfo(Client *to) const {
if(zone_flags.empty()) {
if (zone_flags.empty()) {
to->Message(
Chat::White,
fmt::format(
@ -1041,7 +1038,7 @@ void Client::SendZoneFlagInfo(Client *to) const {
to->Message(
Chat::White,
fmt::format(
"{} {} the following Flags:",
"{} {} the following Zone Flags:",
to == this ? "You" : GetName(),
to == this ? "have" : "has"
).c_str()
@ -1050,38 +1047,47 @@ void Client::SendZoneFlagInfo(Client *to) const {
int flag_count = 0;
for (const auto& zone_id : zone_flags) {
int flag_number = (flag_count + 1);
const char* zone_short_name = ZoneName(zone_id);
std::string zone_long_name = ZoneLongName(zone_id);
float safe_x, safe_y, safe_z, safe_heading;
int16 min_status = AccountStatus::Player;
uint8 min_level = 0;
char flag_name[128];
if(!content_db.GetSafePoints(
zone_short_name,
0,
&safe_x,
&safe_y,
&safe_z,
&safe_heading,
&min_status,
&min_level,
flag_name
)) {
strcpy(flag_name, "ERROR");
}
to->Message(
Chat::White,
fmt::format(
"Zone Flag {} | Zone ID: {} Zone Name: {} ({}) Flag Name: {}",
flag_number,
zone_id,
zone_long_name,
const char* zone_short_name = ZoneName(zone_id, true);
if (zone_short_name != "UNKNOWN") {
std::string zone_long_name = ZoneLongName(zone_id);
float safe_x, safe_y, safe_z, safe_heading;
int16 min_status = AccountStatus::Player;
uint8 min_level = 0;
char flag_name[128];
if (!content_db.GetSafePoints(
zone_short_name,
0,
&safe_x,
&safe_y,
&safe_z,
&safe_heading,
&min_status,
&min_level,
flag_name
).c_str()
);
flag_count++;
)) {
strcpy(flag_name, "ERROR");
}
to->Message(
Chat::White,
fmt::format(
"Flag {} | Zone ID: {} Zone Name: {} ({}){}",
flag_number,
zone_id,
zone_long_name,
zone_short_name,
(
flag_name != "" ?
fmt::format(
" Flag Required: {}",
flag_name
) :
""
)
).c_str()
);
flag_count++;
}
}
to->Message(
@ -1095,6 +1101,139 @@ void Client::SendZoneFlagInfo(Client *to) const {
);
}
void Client::SetZoneFlag(uint32 zone_id) {
if (HasZoneFlag(zone_id)) {
return;
}
zone_flags.insert(zone_id);
std::string query = fmt::format(
"INSERT INTO zone_flags (charID, zoneID) VALUES ({}, {})",
CharacterID(),
zone_id
);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogError("MySQL Error while trying to set zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
}
}
void Client::ClearPEQZoneFlag(uint32 zone_id) {
if (!HasPEQZoneFlag(zone_id)) {
return;
}
peqzone_flags.erase(zone_id);
auto query = fmt::format(
"DELETE FROM character_peqzone_flags WHERE id = {} AND zone_id = {}",
CharacterID(),
zone_id
);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogError("MySQL Error while trying to clear zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
}
}
bool Client::HasPEQZoneFlag(uint32 zone_id) const {
return peqzone_flags.find(zone_id) != peqzone_flags.end();
}
void Client::LoadPEQZoneFlags() {
std::string query = fmt::format(
"SELECT zone_id from character_peqzone_flags WHERE id = {}",
CharacterID()
);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogError("MySQL Error while trying to load zone flags for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
return;
}
peqzone_flags.clear();
for (auto row : results) {
peqzone_flags.insert(std::stoul(row[0]));
}
}
void Client::SendPEQZoneFlagInfo(Client *to) const {
if (peqzone_flags.empty()) {
to->Message(
Chat::White,
fmt::format(
"{} {} no PEQZone Flags.",
to == this ? "You" : GetName(),
to == this ? "have" : "has"
).c_str()
);
return;
}
to->Message(
Chat::White,
fmt::format(
"{} {} the following PEQZone Flags:",
to == this ? "You" : GetName(),
to == this ? "have" : "has"
).c_str()
);
int flag_count = 0;
for (const auto& zone_id : peqzone_flags) {
int flag_number = (flag_count + 1);
std::string zone_short_name = ZoneName(zone_id, true);
if (zone_short_name != "UNKNOWN") {
std::string zone_long_name = ZoneLongName(zone_id);
to->Message(
Chat::White,
fmt::format(
"Flag {} | Zone ID: {} Zone Name: {} ({})",
flag_number,
zone_id,
zone_long_name,
zone_short_name
).c_str()
);
flag_count++;
}
}
to->Message(
Chat::White,
fmt::format(
"{} {} {} PEQZone Flags.",
to == this ? "You" : GetName(),
to == this ? "have" : "has",
flag_count
).c_str()
);
}
void Client::SetPEQZoneFlag(uint32 zone_id) {
if (HasPEQZoneFlag(zone_id)) {
return;
}
peqzone_flags.insert(zone_id);
auto query = fmt::format(
"INSERT INTO character_peqzone_flags (id, zone_id) VALUES ({}, {})",
CharacterID(),
zone_id
);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogError("MySQL Error while trying to set zone flag for [{}]: [{}]", GetName(), results.ErrorMessage().c_str());
}
}
bool Client::CanBeInZone() {
//check some critial rules to see if this char needs to be booted from the zone
//only enforce rules here which are serious enough to warrant being kicked from