From eb039d176c99f31aaaba3037eb4801f6c739a51c Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Jun 2020 15:49:24 -0400 Subject: [PATCH 01/11] Add GetDisplayAC() to Perl/Lua. --- zone/attack.cpp | 8 ++++---- zone/lua_mob.cpp | 6 ++++++ zone/lua_mob.h | 1 + zone/mob.h | 3 ++- zone/perl_mob.cpp | 26 ++++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 4ac29fdc0..39fceb568 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -780,7 +780,7 @@ int Mob::GetClassRaceACBonus() return ac_bonus; } -int Mob::ACSum() +int Mob::ACSum(bool skip_caps) { int ac = 0; // this should be base AC whenever shrouds come around ac += itembonuses.AC; // items + food + tribute @@ -799,7 +799,7 @@ int Mob::ACSum() // EQ math ac = (ac * 4) / 3; // anti-twink - if (IsClient() && GetLevel() < RuleI(Combat, LevelToStopACTwinkControl)) + if (!skip_caps && IsClient() && GetLevel() < RuleI(Combat, LevelToStopACTwinkControl)) ac = std::min(ac, 25 + 6 * GetLevel()); ac = std::max(0, ac + GetClassRaceACBonus()); if (IsNPC()) { @@ -835,11 +835,11 @@ int Mob::ACSum() if (ac < 0) ac = 0; - if (IsClient() + if (!skip_caps && (IsClient() #ifdef BOTS || IsBot() #endif - ) { + )) { auto softcap = GetACSoftcap(); auto returns = GetSoftcapReturns(); int total_aclimitmod = aabonuses.CombatStability + itembonuses.CombatStability + spellbonuses.CombatStability; diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 69742c655..53658e63d 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -532,6 +532,11 @@ int Lua_Mob::GetAC() { return self->GetAC(); } +int Lua_Mob::GetDisplayAC() { + Lua_Safe_Call_Int(); + return self->GetDisplayAC(); +} + int Lua_Mob::GetATK() { Lua_Safe_Call_Int(); return self->GetATK(); @@ -2344,6 +2349,7 @@ luabind::scope lua_register_mob() { .def("SetMana", &Lua_Mob::SetMana) .def("GetManaRatio", &Lua_Mob::GetManaRatio) .def("GetAC", &Lua_Mob::GetAC) + .def("GetDisplayAC", &Lua_Mob::GetDisplayAC) .def("GetATK", &Lua_Mob::GetATK) .def("GetSTR", &Lua_Mob::GetSTR) .def("GetSTA", &Lua_Mob::GetSTA) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 592ac6243..e2dbf9e24 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -124,6 +124,7 @@ public: int SetMana(int mana); double GetManaRatio(); int GetAC(); + int GetDisplayAC(); int GetATK(); int GetSTR(); int GetSTA(); diff --git a/zone/mob.h b/zone/mob.h index efdf68012..b07f51ceb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -211,7 +211,8 @@ public: int TryAssassinate(Mob* defender, EQ::skills::SkillType skillInUse); virtual void DoRiposte(Mob* defender); void ApplyMeleeDamageMods(uint16 skill, int &damage, Mob * defender = nullptr, ExtraAttackOptions *opts = nullptr); - int ACSum(); + int ACSum(bool skip_caps = false); + inline int GetDisplayAC() { return 1000 * (ACSum(true) + compute_defense()) / 847; } int offense(EQ::skills::SkillType skill); int GetBestMeleeSkill(); void CalcAC() { mitigation_ac = ACSum(); } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 12f3b1886..f90435887 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -2506,6 +2506,31 @@ XS(XS_Mob_GetAC) { XSRETURN(1); } +XS(XS_Mob_GetDisplayAC); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_GetDisplayAC) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Mob::GetDisplayAC(THIS)"); + { + Mob *THIS; + uint32 RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Mob")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Mob *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Mob"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetDisplayAC(); + XSprePUSH; + PUSHu((UV) RETVAL); + } + XSRETURN(1); +} + XS(XS_Mob_GetATK); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_GetATK) { dXSARGS; @@ -8676,6 +8701,7 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "SetMana"), XS_Mob_SetMana, file, "$$"); newXSproto(strcpy(buf, "GetManaRatio"), XS_Mob_GetManaRatio, file, "$"); newXSproto(strcpy(buf, "GetAC"), XS_Mob_GetAC, file, "$"); + newXSproto(strcpy(buf, "GetDisplayAC"), XS_Mob_GetDisplayAC, file, "$"); newXSproto(strcpy(buf, "GetATK"), XS_Mob_GetATK, file, "$"); newXSproto(strcpy(buf, "GetSTR"), XS_Mob_GetSTR, file, "$"); newXSproto(strcpy(buf, "GetSTA"), XS_Mob_GetSTA, file, "$"); From f514dd5b5563643359802ce03a8660aa7a941ea0 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Jun 2020 15:18:32 -0400 Subject: [PATCH 02/11] Optimize cross-zone utilities and add cross-zone player move utilities to Perl/Lua. --- common/servertalk.h | 24 ++++++++ world/zoneserver.cpp | 4 ++ zone/embparser_api.cpp | 68 ++++++++++++++++++++ zone/lua_general.cpp | 20 ++++++ zone/questmgr.cpp | 40 ++++++++++++ zone/questmgr.h | 4 ++ zone/worldserver.cpp | 137 +++++++++++++++++++++++++++++++---------- 7 files changed, 264 insertions(+), 33 deletions(-) diff --git a/common/servertalk.h b/common/servertalk.h index 3e947a281..a487c84ca 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -211,6 +211,10 @@ #define ServerOP_CZTaskAssignGroup 0x4026 #define ServerOP_CZTaskAssignRaid 0x4027 #define ServerOP_CZTaskAssignGuild 0x4028 +#define ServerOP_CZMovePlayer 0x4029 +#define ServerOP_CZMoveGroup 0x4030 +#define ServerOP_CZMoveRaid 0x4031 +#define ServerOP_CZMoveGuild 0x4032 /** * QueryServer @@ -1408,6 +1412,26 @@ struct CZMessageGuild_Struct { char Message[512]; }; +struct CZMovePlayer_Struct { + int character_id; + char zone_short_name[32]; +}; + +struct CZMoveGroup_Struct { + int group_id; + char zone_short_name[32]; +}; + +struct CZMoveRaid_Struct { + int raid_id; + char zone_short_name[32]; +}; + +struct CZMoveGuild_Struct { + int guild_id; + char zone_short_name[32]; +}; + struct WWMarquee_Struct { uint32 Type; uint32 Priority; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 9ccd1de81..74a17d43a 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1255,6 +1255,10 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_CZTaskAssignGroup: case ServerOP_CZTaskAssignRaid: case ServerOP_CZTaskAssignGuild: + case ServerOP_CZMovePlayer: + case ServerOP_CZMoveGroup: + case ServerOP_CZMoveRaid: + case ServerOP_CZMoveGuild: case ServerOP_WWMarquee: case ServerOP_DepopAllPlayersCorpses: case ServerOP_DepopPlayerCorpse: diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 4687e8f29..338e5a1a1 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3976,6 +3976,70 @@ XS(XS__crosszonemessageplayerbyguildid) { XSRETURN_EMPTY; } +XS(XS__crosszonemoveplayerbycharid); +XS(XS__crosszonemoveplayerbycharid) { + dXSARGS; + + if (items != 2) + Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbycharid(int character_id, string zone_short_name)"); + + if (items == 2) { + int character_id = (int) SvIV(ST(0)); + char *zone_short_name = (char *) SvPV_nolen(ST(1)); + quest_manager.CrossZoneMovePlayerByCharID(character_id, zone_short_name); + } + + XSRETURN_EMPTY; +} + +XS(XS__crosszonemoveplayerbygroupid); +XS(XS__crosszonemoveplayerbygroupid) { + dXSARGS; + + if (items != 2) + Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbygroupid(int group_id, string zone_short_name)"); + + if (items == 2) { + int group_id = (int) SvIV(ST(0)); + char *zone_short_name = (char *) SvPV_nolen(ST(1)); + quest_manager.CrossZoneMovePlayerByGroupID(group_id, zone_short_name); + } + + XSRETURN_EMPTY; +} + +XS(XS__crosszonemoveplayerbyraidid); +XS(XS__crosszonemoveplayerbyraidid) { + dXSARGS; + + if (items != 2) + Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbyraidid(int raid_id, string zone_short_name)"); + + if (items == 2) { + int raid_id = (int) SvIV(ST(0)); + char *zone_short_name = (char *) SvPV_nolen(ST(1)); + quest_manager.CrossZoneMovePlayerByRaidID(raid_id, zone_short_name); + } + + XSRETURN_EMPTY; +} + +XS(XS__crosszonemoveplayerbyguildid); +XS(XS__crosszonemoveplayerbyguildid) { + dXSARGS; + + if (items != 2) + Perl_croak(aTHX_ "Usage: quest::crosszonemoveplayerbyguildid(int guild_id, string zone_short_name)"); + + if (items == 2) { + int guild_id = (int) SvIV(ST(0)); + char *zone_short_name = (char *) SvPV_nolen(ST(1)); + quest_manager.CrossZoneMovePlayerByGuildID(guild_id, zone_short_name); + } + + XSRETURN_EMPTY; +} + XS(XS__enablerecipe); XS(XS__enablerecipe) { dXSARGS; @@ -4450,6 +4514,10 @@ EXTERN_C XS(boot_quest) { newXS(strcpy(buf, "crosszonemessageplayerbygroupid"), XS__crosszonemessageplayerbygroupid, file); newXS(strcpy(buf, "crosszonemessageplayerbyraidid"), XS__crosszonemessageplayerbyraidid, file); newXS(strcpy(buf, "crosszonemessageplayerbyguildid"), XS__crosszonemessageplayerbyguildid, file); + newXS(strcpy(buf, "crosszonemoveplayerbycharid"), XS__crosszonemoveplayerbycharid, file); + newXS(strcpy(buf, "crosszonemoveplayerbygroupid"), XS__crosszonemoveplayerbygroupid, file); + newXS(strcpy(buf, "crosszonemoveplayerbyraidid"), XS__crosszonemoveplayerbyraidid, file); + newXS(strcpy(buf, "crosszonemoveplayerbyguildid"), XS__crosszonemoveplayerbyguildid, file); newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file); newXS(strcpy(buf, "crosszonesetentityvariablebyclientname"), XS__crosszonesetentityvariablebyclientname, file); newXS(strcpy(buf, "crosszonesetentityvariablebygroupid"), XS__crosszonesetentityvariablebygroupid, file); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 990c9f1ca..71798ecf0 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1090,6 +1090,22 @@ void lua_cross_zone_message_player_by_guild_id(uint32 type, int guild_id, const quest_manager.CrossZoneMessagePlayerByGuildID(type, guild_id, message); } +void lua_cross_zone_move_player_by_char_id(int character_id, const char *zone_short_name) { + quest_manager.CrossZoneMovePlayerByCharID(character_id, zone_short_name); +} + +void lua_cross_zone_move_player_by_group_id(int group_id, const char *zone_short_name) { + quest_manager.CrossZoneMovePlayerByGroupID(group_id, zone_short_name); +} + +void lua_cross_zone_move_player_by_raid_id(int raid_id, const char *zone_short_name) { + quest_manager.CrossZoneMovePlayerByRaidID(raid_id, zone_short_name); +} + +void lua_cross_zone_move_player_by_guild_id(int guild_id, const char *zone_short_name) { + quest_manager.CrossZoneMovePlayerByGuildID(guild_id, zone_short_name); +} + void lua_cross_zone_set_entity_variable_by_client_name(const char *player, const char *id, const char *m_var) { quest_manager.CrossZoneSetEntityVariableByClientName(player, id, m_var); } @@ -1935,6 +1951,10 @@ luabind::scope lua_register_general() { luabind::def("cross_zone_message_player_by_group_id", &lua_cross_zone_message_player_by_group_id), luabind::def("cross_zone_message_player_by_raid_id", &lua_cross_zone_message_player_by_raid_id), luabind::def("cross_zone_message_player_by_guild_id", &lua_cross_zone_message_player_by_guild_id), + luabind::def("cross_zone_move_player_by_char_id", &lua_cross_zone_move_player_by_char_id), + luabind::def("cross_zone_move_player_by_group_id", &lua_cross_zone_move_player_by_group_id), + luabind::def("cross_zone_move_player_by_raid_id", &lua_cross_zone_move_player_by_raid_id), + luabind::def("cross_zone_move_player_by_guild_id", &lua_cross_zone_move_player_by_guild_id), luabind::def("cross_zone_set_entity_variable_by_client_name", &lua_cross_zone_set_entity_variable_by_client_name), luabind::def("cross_zone_set_entity_variable_by_group_id", &lua_cross_zone_set_entity_variable_by_group_id), luabind::def("cross_zone_set_entity_variable_by_raid_id", &lua_cross_zone_set_entity_variable_by_raid_id), diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index a38553c39..09423b49b 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -3428,6 +3428,46 @@ void QuestManager::CrossZoneMessagePlayerByGuildID(uint32 Type, int GuildID, con safe_delete(pack); } +void QuestManager::CrossZoneMovePlayerByCharID(int character_id, const char *zone_short_name){ + uint32 message_len = strlen(zone_short_name) + 1; + auto pack = new ServerPacket(ServerOP_CZMovePlayer, sizeof(CZMovePlayer_Struct) + message_len); + CZMovePlayer_Struct* CZGM = (CZMovePlayer_Struct*) pack->pBuffer; + CZGM->character_id = character_id; + strn0cpy(CZGM->zone_short_name, zone_short_name, 32); + worldserver.SendPacket(pack); + safe_delete(pack); +} + +void QuestManager::CrossZoneMovePlayerByGroupID(int group_id, const char *zone_short_name){ + uint32 message_len = strlen(zone_short_name) + 1; + auto pack = new ServerPacket(ServerOP_CZMoveGroup, sizeof(CZMoveGroup_Struct) + message_len); + CZMoveGroup_Struct* CZGM = (CZMoveGroup_Struct*) pack->pBuffer; + CZGM->group_id = group_id; + strn0cpy(CZGM->zone_short_name, zone_short_name, 32); + worldserver.SendPacket(pack); + safe_delete(pack); +} + +void QuestManager::CrossZoneMovePlayerByRaidID(int raid_id, const char *zone_short_name){ + uint32 message_len = strlen(zone_short_name) + 1; + auto pack = new ServerPacket(ServerOP_CZMoveRaid, sizeof(CZMoveRaid_Struct) + message_len); + CZMoveRaid_Struct* CZRM = (CZMoveRaid_Struct*) pack->pBuffer; + CZRM->raid_id = raid_id; + strn0cpy(CZRM->zone_short_name, zone_short_name, 32); + worldserver.SendPacket(pack); + safe_delete(pack); +} + +void QuestManager::CrossZoneMovePlayerByGuildID(int guild_id, const char *zone_short_name){ + uint32 message_len = strlen(zone_short_name) + 1; + auto pack = new ServerPacket(ServerOP_CZMoveGuild, sizeof(CZMoveGuild_Struct) + message_len); + CZMoveGuild_Struct* CZGM = (CZMoveGuild_Struct*) pack->pBuffer; + CZGM->guild_id = guild_id; + strn0cpy(CZGM->zone_short_name, zone_short_name, 32); + worldserver.SendPacket(pack); + safe_delete(pack); +} + void QuestManager::CrossZoneSetEntityVariableByClientName(const char *CharName, const char *id, const char *m_var){ uint32 message_len = strlen(id) + 1; uint32 message_len2 = strlen(m_var) + 1; diff --git a/zone/questmgr.h b/zone/questmgr.h index ab0701b39..14f4678be 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -299,6 +299,10 @@ public: void CrossZoneMessagePlayerByGroupID(uint32 Type, int GroupID, const char *Message); void CrossZoneMessagePlayerByRaidID(uint32 Type, int RaidID, const char *Message); void CrossZoneMessagePlayerByGuildID(uint32 Type, int GuildID, const char *Message); + void CrossZoneMovePlayerByCharID(int character_id, const char *zone_short_name); + void CrossZoneMovePlayerByGroupID(int group_id, const char *zone_short_name); + void CrossZoneMovePlayerByRaidID(int raid_id, const char *zone_short_name); + void CrossZoneMovePlayerByGuildID(int guild_id, const char *zone_short_name); void WorldWideMarquee(uint32 Type, uint32 Priority, uint32 FadeIn, uint32 FadeOut, uint32 Duration, const char *Message); bool EnableRecipe(uint32 recipe_id); bool DisableRecipe(uint32 recipe_id); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 24d1bb7fb..c4a544357 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1918,10 +1918,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZSignalGroup: { CZGroupSignal_Struct* CZGS = (CZGroupSignal_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZGS->group_id) { - client.second->Signal(CZGS->data); + auto client_group = entity_list.GetGroupByID(CZGS->group_id); + if (client_group) { + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->Signal(CZGS->data); + } } } break; @@ -1929,10 +1932,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZSignalRaid: { CZRaidSignal_Struct* CZRS = (CZRaidSignal_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZRS->raid_id) { - client.second->Signal(CZRS->data); + auto client_raid = entity_list.GetRaidByID(CZRS->raid_id); + if (client_raid) { + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->Signal(CZRS->data); + } } } break; @@ -1969,10 +1975,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZMessageGroup: { CZMessageGroup_Struct* CZGM = (CZMessageGroup_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZGM->GroupID) { - client.second->Message(CZGM->Type, CZGM->Message); + auto client_group = entity_list.GetGroupByID(CZGM->GroupID); + if (client_group) { + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->Message(CZGM->Type, CZGM->Message); + } } } break; @@ -1980,10 +1989,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZMessageRaid: { CZMessageRaid_Struct* CZRM = (CZMessageRaid_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZRM->RaidID) { - client.second->Message(CZRM->Type, CZRM->Message); + auto client_raid = entity_list.GetRaidByID(CZRM->RaidID); + if (client_raid) { + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->Message(CZRM->Type, CZRM->Message); + } } } break; @@ -2011,10 +2023,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZSetEntityVariableByGroupID: { CZSetEntVarByGroupID_Struct* CZCS = (CZSetEntVarByGroupID_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZCS->group_id) { - client.second->SetEntityVariable(CZCS->id, CZCS->m_var); + auto client_group = entity_list.GetGroupByID(CZCS->group_id); + if (client_group) { + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->SetEntityVariable(CZCS->id, CZCS->m_var); + } } } break; @@ -2022,10 +2037,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZSetEntityVariableByRaidID: { CZSetEntVarByRaidID_Struct* CZCS = (CZSetEntVarByRaidID_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZCS->raid_id) { - client.second->SetEntityVariable(CZCS->id, CZCS->m_var); + auto client_raid = entity_list.GetRaidByID(CZCS->raid_id); + if (client_raid) { + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->SetEntityVariable(CZCS->id, CZCS->m_var); + } } } break; @@ -2044,7 +2062,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZTaskAssign: { CZTaskAssign_Struct* CZTA = (CZTaskAssign_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); Client* client = entity_list.GetClientByCharID(CZTA->character_id); if (client != 0) { client->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); @@ -2054,10 +2071,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZTaskAssignGroup: { CZTaskAssignGroup_Struct* CZTA = (CZTaskAssignGroup_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZTA->group_id) { - client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + auto client_group = entity_list.GetGroupByID(CZTA->group_id); + if (client_group) { + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + } } } break; @@ -2065,10 +2085,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) case ServerOP_CZTaskAssignRaid: { CZTaskAssignRaid_Struct* CZTA = (CZTaskAssignRaid_Struct*)pack->pBuffer; - auto client_list = entity_list.GetClientList(); - for (auto client : client_list) { - if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZTA->raid_id) { - client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + auto client_raid = entity_list.GetRaidByID(CZTA->raid_id); + if (client_raid) { + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + } } } break; @@ -2084,6 +2107,54 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } break; } + case ServerOP_CZMovePlayer: + { + CZMovePlayer_Struct* CZMP = (CZMovePlayer_Struct*)pack->pBuffer; + Client* client = entity_list.GetClientByCharID(CZMP->character_id); + if (client != 0) { + client->MoveZone(CZMP->zone_short_name); + } + break; + } + case ServerOP_CZMoveGroup: + { + CZMoveGroup_Struct* CZMG = (CZMoveGroup_Struct*)pack->pBuffer; + auto client_group = entity_list.GetGroupByID(CZMG->group_id); + if (client_group) { + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->MoveZone(CZMG->zone_short_name); + } + } + } + break; + } + case ServerOP_CZMoveRaid: + { + CZMoveRaid_Struct* CZMR = (CZMoveRaid_Struct*)pack->pBuffer; + auto client_raid = entity_list.GetRaidByID(CZMR->raid_id); + if (client_raid) { + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->MoveZone(CZMR->zone_short_name); + } + } + } + break; + } + case ServerOP_CZMoveGuild: + { + CZMoveGuild_Struct* CZMG = (CZMoveGuild_Struct*)pack->pBuffer; + auto client_list = entity_list.GetClientList(); + for (auto client : client_list) { + if (client.second->GuildID() > 0 && client.second->GuildID() == CZMG->guild_id) { + client.second->MoveZone(CZMG->zone_short_name); + } + } + break; + } case ServerOP_WWMarquee: { WWMarquee_Struct* WWMS = (WWMarquee_Struct*)pack->pBuffer; From 1b2c2a1dd0fca14d31a9226ac1be8568e8ee9824 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Jun 2020 19:24:14 -0400 Subject: [PATCH 03/11] Add MoveZoneInstance methods to Perl/Lua. --- zone/client.h | 3 + zone/lua_client.cpp | 18 ++++++ zone/lua_client.h | 3 + zone/perl_client.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++ zone/zoning.cpp | 47 ++++++++++++++++ 5 files changed, 200 insertions(+) diff --git a/zone/client.h b/zone/client.h index 91319b04a..8b9d32bbc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -636,6 +636,9 @@ public: void MoveZone(const char *zone_short_name); void MoveZoneGroup(const char *zone_short_name); void MoveZoneRaid(const char *zone_short_name); + void MoveZoneInstance(uint16 instance_id); + void MoveZoneInstanceGroup(uint16 instance_id); + void MoveZoneInstanceRaid(uint16 instance_id); void SendToGuildHall(); void AssignToInstance(uint16 instance_id); void RemoveFromInstance(uint16 instance_id); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 88d085f41..ffe643e79 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -340,6 +340,21 @@ void Lua_Client::MoveZoneRaid(const char *zone_short_name) { self->MoveZoneRaid(zone_short_name); } +void Lua_Client::MoveZoneInstance(uint16 instance_id) { + Lua_Safe_Call_Void(); + self->MoveZoneInstance(instance_id); +} + +void Lua_Client::MoveZoneInstanceGroup(uint16 instance_id) { + Lua_Safe_Call_Void(); + self->MoveZoneInstanceGroup(instance_id); +} + +void Lua_Client::MoveZoneInstanceRaid(uint16 instance_id) { + Lua_Safe_Call_Void(); + self->MoveZoneInstanceRaid(instance_id); +} + void Lua_Client::ChangeLastName(const char *in) { Lua_Safe_Call_Void(); self->ChangeLastName(in); @@ -1676,6 +1691,9 @@ luabind::scope lua_register_client() { .def("MoveZone", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZone) .def("MoveZoneGroup", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZoneGroup) .def("MoveZoneRaid", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZoneRaid) + .def("MoveZoneInstance", (void(Lua_Client::*)(uint16))&Lua_Client::MoveZoneInstance) + .def("MoveZoneInstanceGroup", (void(Lua_Client::*)(uint16))&Lua_Client::MoveZoneInstanceGroup) + .def("MoveZoneInstanceRaid", (void(Lua_Client::*)(uint16))&Lua_Client::MoveZoneInstanceRaid) .def("ChangeLastName", (void(Lua_Client::*)(const char *in))&Lua_Client::ChangeLastName) .def("GetFactionLevel", (int(Lua_Client::*)(uint32,uint32,uint32,uint32,uint32,uint32,Lua_NPC))&Lua_Client::GetFactionLevel) .def("SetFactionLevel", (void(Lua_Client::*)(uint32,uint32,int,int,int))&Lua_Client::SetFactionLevel) diff --git a/zone/lua_client.h b/zone/lua_client.h index 1453c46e9..e0f4745f5 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -94,6 +94,9 @@ public: void MoveZone(const char *zone_short_name); void MoveZoneGroup(const char *zone_short_name); void MoveZoneRaid(const char *zone_short_name); + void MoveZoneInstance(uint16 instance_id); + void MoveZoneInstanceGroup(uint16 instance_id); + void MoveZoneInstanceRaid(uint16 instance_id); void ChangeLastName(const char *in); int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc); void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 393f8ea28..c8a070fd4 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1445,6 +1445,132 @@ XS(XS_Client_MoveZoneRaid) { XSRETURN_EMPTY; } +XS(XS_Client_MoveZoneInstance); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_MoveZoneInstance) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::MoveZoneInstance(THIS, uint16 instance_id)"); + { + Client *THIS; + uint16 instance_id = (uint16) SvUV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + if (THIS->IsClient()) { + THIS->MoveZoneInstance(instance_id); + } else { + if (THIS->IsMerc()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process a type Merc reference"); + } +#ifdef BOTS + else if (THIS->IsBot()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process a type Bot reference"); + } +#endif + else if (THIS->IsNPC()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process a type NPC reference"); + } + else { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstance) attempted to process an Unknown type reference"); + } + + Perl_croak(aTHX_ "THIS is not of type Client"); + } + + } + XSRETURN_EMPTY; +} + +XS(XS_Client_MoveZoneInstanceGroup); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_MoveZoneInstanceGroup) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::MoveZoneInstanceGroup(THIS, uint16 instance_id)"); + { + Client *THIS; + uint16 instance_id = (uint16) SvUV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + if (THIS->IsClient()) { + THIS->MoveZoneInstanceGroup(instance_id); + } else { + if (THIS->IsMerc()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process a type Merc reference"); + } +#ifdef BOTS + else if (THIS->IsBot()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process a type Bot reference"); + } +#endif + else if (THIS->IsNPC()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process a type NPC reference"); + } + else { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceGroup) attempted to process an Unknown type reference"); + } + + Perl_croak(aTHX_ "THIS is not of type Client"); + } + + } + XSRETURN_EMPTY; +} + +XS(XS_Client_MoveZoneInstanceRaid); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_MoveZoneInstanceRaid) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::MoveZoneInstanceRaid(THIS, uint16 instance_id)"); + { + Client *THIS; + uint16 instance_id = (uint16) SvUV(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + if (THIS->IsClient()) { + THIS->MoveZoneInstanceRaid(instance_id); + } else { + if (THIS->IsMerc()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process a type Merc reference"); + } +#ifdef BOTS + else if (THIS->IsBot()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process a type Bot reference"); + } +#endif + else if (THIS->IsNPC()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process a type NPC reference"); + } + else { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneInstanceRaid) attempted to process an Unknown type reference"); + } + + Perl_croak(aTHX_ "THIS is not of type Client"); + } + + } + XSRETURN_EMPTY; +} + XS(XS_Client_ChangeLastName); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_ChangeLastName) { dXSARGS; @@ -6715,6 +6841,9 @@ XS(boot_Client) { newXSproto(strcpy(buf, "MoveZone"), XS_Client_MoveZone, file, "$$"); newXSproto(strcpy(buf, "MoveZoneGroup"), XS_Client_MoveZoneGroup, file, "$$"); newXSproto(strcpy(buf, "MoveZoneRaid"), XS_Client_MoveZoneRaid, file, "$$"); + newXSproto(strcpy(buf, "MoveZoneInstance"), XS_Client_MoveZoneInstance, file, "$$"); + newXSproto(strcpy(buf, "MoveZoneInstanceGroup"), XS_Client_MoveZoneInstanceGroup, file, "$$"); + newXSproto(strcpy(buf, "MoveZoneInstanceRaid"), XS_Client_MoveZoneInstanceRaid, file, "$$"); newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index a22d5e250..785573bef 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -461,6 +461,53 @@ void Client::MoveZoneRaid(const char *zone_short_name) { } } +void Client::MoveZoneInstance(uint16 instance_id) { + if (!database.CharacterInInstanceGroup(instance_id, CharacterID())) { + database.AddClientToInstance(instance_id, CharacterID()); + } + auto pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct)); + ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; + ztz->response = 0; + ztz->current_zone_id = zone->GetZoneID(); + ztz->current_instance_id = zone->GetInstanceID(); + ztz->requested_zone_id = database.ZoneIDFromInstanceID(instance_id); + ztz->requested_instance_id = instance_id; + ztz->admin = Admin(); + strcpy(ztz->name, GetName()); + ztz->guild_id = GuildID(); + ztz->ignorerestrictions = 3; + worldserver.SendPacket(pack); + safe_delete(pack); +} + +void Client::MoveZoneInstanceGroup(uint16 instance_id) { + if (!GetGroup()) { + MoveZoneInstance(instance_id); + } else { + auto client_group = GetGroup(); + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->MoveZoneInstance(instance_id); + } + } + } +} + +void Client::MoveZoneInstanceRaid(uint16 instance_id) { + if (!GetRaid()) { + MoveZoneInstance(instance_id); + } else { + auto client_raid = GetRaid(); + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->MoveZoneInstance(instance_id); + } + } + } +} + void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) { // From what I have read, dragged corpses should stay with the player for Intra-zone summons etc, but we can implement that later. From eed1fd8a4320d85c534ea59e216f139ad6de7e8d Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Jun 2020 20:54:48 -0400 Subject: [PATCH 04/11] Add DyeArmorBySlot(slot, red, green, blue, use_tint) to Perl/Lua. --- zone/client.h | 1 + zone/inventory.cpp | 16 ++++++++++++++++ zone/lua_client.cpp | 12 ++++++++++++ zone/lua_client.h | 2 ++ zone/perl_client.cpp | 29 +++++++++++++++++++++++++++++ 5 files changed, 60 insertions(+) diff --git a/zone/client.h b/zone/client.h index 91319b04a..20ae0795b 100644 --- a/zone/client.h +++ b/zone/client.h @@ -276,6 +276,7 @@ public: GetItems_Struct* GetTraderItems(); void SendBazaarWelcome(); void DyeArmor(EQ::TintProfile* dye); + void DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint = 0x00); uint8 SlotConvert(uint8 slot,bool bracer=false); void MessageString(uint32 type, uint32 string_id, uint32 distance = 0); void MessageString(uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 993cdac8a..54ae07b7d 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2228,6 +2228,22 @@ void Client::DyeArmor(EQ::TintProfile* dye){ } +void Client::DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint) { + uint8 item_slot = SlotConvert(slot); + EQ::ItemInstance* item_instance = this->m_inv.GetItem(item_slot); + if (item_instance) { + uint32 armor_color = ((uint32)red << 16) | ((uint32)green << 8) | ((uint32)blue); + item_instance->SetColor(armor_color); + database.SaveCharacterMaterialColor(this->CharacterID(), slot, armor_color); + database.SaveInventory(CharacterID(), item_instance, item_slot); + m_pp.item_tint.Slot[slot].UseTint = (use_tint ? 0xFF : 0x00); + } + m_pp.item_tint.Slot[slot].Red = red; + m_pp.item_tint.Slot[slot].Green = green; + m_pp.item_tint.Slot[slot].Blue = blue; + SendWearChange(slot); +} + #if 0 bool Client::DecreaseByItemType(uint32 type, uint8 amt) { const ItemData* TempItem = 0; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 88d085f41..70adce43f 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -75,6 +75,16 @@ void Lua_Client::Duck() { self->Duck(); } +void Lua_Client::DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue) { + Lua_Safe_Call_Void(); + self->DyeArmorBySlot(slot, red, green, blue); +} + +void Lua_Client::DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint) { + Lua_Safe_Call_Void(); + self->DyeArmorBySlot(slot, red, green, blue, use_tint); +} + void Lua_Client::Stand() { Lua_Safe_Call_Void(); self->Stand(); @@ -1622,6 +1632,8 @@ luabind::scope lua_register_client() { .def("SendToGuildHall", (void(Lua_Client::*)(void))&Lua_Client::SendToGuildHall) .def("GetAnon", (bool(Lua_Client::*)(void))&Lua_Client::GetAnon) .def("Duck", (void(Lua_Client::*)(void))&Lua_Client::Duck) + .def("DyeArmorBySlot", (void(Lua_Client::*)(uint8,uint8,uint8,uint8))&Lua_Client::DyeArmorBySlot) + .def("DyeArmorBySlot", (void(Lua_Client::*)(uint8,uint8,uint8,uint8,uint8))&Lua_Client::DyeArmorBySlot) .def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand) .def("SetGM", (void(Lua_Client::*)(bool))&Lua_Client::SetGM) .def("SetPVP", (void(Lua_Client::*)(bool))&Lua_Client::SetPVP) diff --git a/zone/lua_client.h b/zone/lua_client.h index 1453c46e9..45eeb27a4 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -42,6 +42,8 @@ public: void SendToGuildHall(); bool GetAnon(); void Duck(); + void DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue); + void DyeArmorBySlot(uint8 slot, uint8 red, uint8 green, uint8 blue, uint8 use_tint); void Stand(); void SetGM(bool v); void SetPVP(bool v); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 393f8ea28..8a13df9d3 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -312,6 +312,34 @@ XS(XS_Client_Duck) { XSRETURN_EMPTY; } +XS(XS_Client_DyeArmorBySlot); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_DyeArmorBySlot) { + dXSARGS; + if (items != 5 && items != 6) + Perl_croak(aTHX_ "Usage: Client::DyeArmorBySlot(THIS, uint8 slot, uint8 red, uint8 green, uint8 blue, [uint8 use_tint = 0x00])"); + { + Client *THIS; + uint8 slot = (uint8) SvUV(ST(1)); + uint8 red = (uint8) SvUV(ST(2)); + uint8 green = (uint8) SvUV(ST(3)); + uint8 blue = (uint8) SvUV(ST(4)); + uint8 use_tint = 0x00; + if (items == 6) { + use_tint = (uint8) SvUV(ST(5)); + } + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->DyeArmorBySlot(slot, red, green, blue, use_tint); + } + XSRETURN_EMPTY; +} + XS(XS_Client_Stand); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_Stand) { dXSARGS; @@ -6585,6 +6613,7 @@ XS(boot_Client) { newXSproto(strcpy(buf, "Disconnect"), XS_Client_Disconnect, file, "$"); newXSproto(strcpy(buf, "DropItem"), XS_Client_DropItem, file, "$$"); newXSproto(strcpy(buf, "Duck"), XS_Client_Duck, file, "$"); + newXSproto(strcpy(buf, "DyeArmorBySlot"), XS_Client_DyeArmorBySlot, file, "$$$$$;$"); newXSproto(strcpy(buf, "Escape"), XS_Client_Escape, file, "$"); newXSproto(strcpy(buf, "ExpeditionMessage"), XS_Client_ExpeditionMessage, file, "$$$"); newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$"); From 12a0e3e2266c2208236745ba12a999a4f989cb45 Mon Sep 17 00:00:00 2001 From: Erick Christgau Date: Thu, 2 Jul 2020 10:16:04 -0500 Subject: [PATCH 05/11] Issue 743 - WorldDatabase::GetStartZone now checks isTitanium when creating the SQL --- world/worlddb.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/world/worlddb.cpp b/world/worlddb.cpp index f42c04964..bfdc40fd4 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -405,10 +405,24 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0; + // see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids - std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i " - "AND player_class = %i AND player_deity = %i AND player_race = %i", - in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); + std::string query; + + if (isTitanium) { + // Titanium sends player choice (starting city) instead of a zone id + query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE player_choice = %i " + "AND player_class = %i AND player_deity = %i AND player_race = %i", + in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); + LogInfo("Titanium Start zone query: [{}]\n", query.c_str()); + } + else { + query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i " + "AND player_class = %i AND player_deity = %i AND player_race = %i", + in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); + LogInfo("SoF Start zone query: [{}]\n", query.c_str()); + } + auto results = QueryDatabase(query); if(!results.Success()) { return false; From 36e064a7b32ad0f2c86c946dce62559e777a194c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 2 Jul 2020 21:31:50 -0500 Subject: [PATCH 06/11] Fix issue where #hotfix doesn't work properly in new Windows installations --- zone/command.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/zone/command.cpp b/zone/command.cpp index 3cb8b6558..1e1b4475e 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -206,7 +206,7 @@ int command_init(void) command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", 80, command_faction) || command_add("findaliases", "[search criteria]- Searches for available command aliases, by alias or command", 0, command_findaliases) || command_add("findnpctype", "[search criteria] - Search database NPC types", 100, command_findnpctype) || - command_add("findrace", "[search criteria] - Search for a race", 50, command_findrace) || + command_add("findrace", "[search criteria] - Search for a race", 50, command_findrace) || command_add("findspell", "[search criteria] - Search for a spell", 50, command_findspell) || command_add("findzone", "[search criteria] - Search database zones", 100, command_findzone) || command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", 80, command_fixmob) || @@ -2478,8 +2478,8 @@ void command_grid(Client *c, const Seperator *sep) glm::vec4 node_position = glm::vec4(atof(row[0]), atof(row[1]), atof(row[2]), atof(row[3])); std::vector node_loc { - node_position.x, - node_position.y, + node_position.x, + node_position.y, node_position.z }; @@ -4180,7 +4180,7 @@ void command_findzone(Client *c, const Seperator *sep) if (id == 0) { query = fmt::format( "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE long_name LIKE '%{}%' OR `short_name` LIKE '%{}%'", - EscapeString(sep->arg[1]), + EscapeString(sep->arg[1]), EscapeString(sep->arg[1]) ); } @@ -12822,15 +12822,23 @@ void command_hotfix(Client *c, const Seperator *sep) c->Message(Chat::White, "Creating and applying hotfix"); std::thread t1( [c, hotfix_name]() { + + std::string shared_memory_path; + #ifdef WIN32 - if(hotfix_name.length() > 0) { - if(system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str())); - } else { - if(system(StringFormat("shared_memory").c_str())); + shared_memory_path = "shared_memory"; + if (file_exists("bin/shared_memory")) { + shared_memory_path = "bin/shared_memory"; + } + + if (hotfix_name.length() > 0) { + if (system(StringFormat("%s -hotfix=%s", shared_memory_path.c_str(), hotfix_name.c_str()).c_str())) {} + } + else { + if (system(StringFormat("%s", shared_memory_path.c_str()).c_str())) {} } #else - - std::string shared_memory_path = "./shared_memory"; + shared_memory_path = "./shared_memory"; if (file_exists("./bin/shared_memory")) { shared_memory_path = "./bin/shared_memory"; } From 6aad062e9a3e751c7430a6134353f53e3c7eb399 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 4 Jul 2020 01:50:29 -0500 Subject: [PATCH 07/11] Add logging [skip ci] --- common/shareddb.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 789b739a8..6507eaebc 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -917,6 +917,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) { EQ::IPCMutex mutex("items"); mutex.Lock(); std::string file_name = Config->SharedMemDir + prefix + std::string("items"); + LogInfo("[Shared Memory] Attempting to load file [{}]", file_name); items_mmf = std::unique_ptr(new EQ::MemoryMappedFile(file_name)); items_hash = std::unique_ptr>(new EQ::FixedMemoryHashSet(reinterpret_cast(items_mmf->Get()), items_mmf->Size())); mutex.Unlock(); @@ -1341,6 +1342,7 @@ bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) { EQ::IPCMutex mutex("faction"); mutex.Lock(); std::string file_name = Config->SharedMemDir + prefix + std::string("faction"); + LogInfo("[Shared Memory] Attempting to load file [{}]", file_name); faction_mmf = std::unique_ptr(new EQ::MemoryMappedFile(file_name)); faction_hash = std::unique_ptr>(new EQ::FixedMemoryHashSet(reinterpret_cast(faction_mmf->Get()), faction_mmf->Size())); mutex.Unlock(); @@ -1542,6 +1544,7 @@ bool SharedDatabase::LoadSkillCaps(const std::string &prefix) { EQ::IPCMutex mutex("skill_caps"); mutex.Lock(); std::string file_name = Config->SharedMemDir + prefix + std::string("skill_caps"); + LogInfo("[Shared Memory] Attempting to load file [{}]", file_name); skill_caps_mmf = std::unique_ptr(new EQ::MemoryMappedFile(file_name)); mutex.Unlock(); } catch(std::exception &ex) { @@ -1700,6 +1703,7 @@ bool SharedDatabase::LoadSpells(const std::string &prefix, int32 *records, const std::string file_name = Config->SharedMemDir + prefix + std::string("spells"); spells_mmf = std::unique_ptr(new EQ::MemoryMappedFile(file_name)); + LogInfo("[Shared Memory] Attempting to load file [{}]", file_name); *records = *reinterpret_cast(spells_mmf->Get()); *sp = reinterpret_cast((char*)spells_mmf->Get() + 4); mutex.Unlock(); From 8e96232690eaca15302be8b75b918b731012c1b5 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 4 Jul 2020 01:58:02 -0500 Subject: [PATCH 08/11] Add explicit file extension to file check [skip ci] --- zone/command.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/command.cpp b/zone/command.cpp index 1e1b4475e..6dd380975 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -12827,7 +12827,7 @@ void command_hotfix(Client *c, const Seperator *sep) #ifdef WIN32 shared_memory_path = "shared_memory"; - if (file_exists("bin/shared_memory")) { + if (file_exists("bin/shared_memory.exe")) { shared_memory_path = "bin/shared_memory"; } From 9e960b90bdea5a16b560d917d679c45556157cf6 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 4 Jul 2020 02:01:35 -0500 Subject: [PATCH 09/11] Adjust path quote [skip ci] --- zone/command.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zone/command.cpp b/zone/command.cpp index 6dd380975..58cf8e876 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -12832,10 +12832,10 @@ void command_hotfix(Client *c, const Seperator *sep) } if (hotfix_name.length() > 0) { - if (system(StringFormat("%s -hotfix=%s", shared_memory_path.c_str(), hotfix_name.c_str()).c_str())) {} + if (system(StringFormat("\"%s\" -hotfix=%s", shared_memory_path.c_str(), hotfix_name.c_str()).c_str())) {} } else { - if (system(StringFormat("%s", shared_memory_path.c_str()).c_str())) {} + if (system(StringFormat("\"%s\"", shared_memory_path.c_str()).c_str())) {} } #else shared_memory_path = "./shared_memory"; From 15a70c7aa9e3cb3c1b0ec7cc4cb89c2a0c6e572c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 4 Jul 2020 02:24:53 -0500 Subject: [PATCH 10/11] Fix for windows hotfix [skip ci] --- zone/command.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/zone/command.cpp b/zone/command.cpp index 58cf8e876..f60490b88 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -12828,15 +12828,19 @@ void command_hotfix(Client *c, const Seperator *sep) #ifdef WIN32 shared_memory_path = "shared_memory"; if (file_exists("bin/shared_memory.exe")) { - shared_memory_path = "bin/shared_memory"; + shared_memory_path = "bin\\shared_memory.exe"; } + std::string hotfix_command; if (hotfix_name.length() > 0) { - if (system(StringFormat("\"%s\" -hotfix=%s", shared_memory_path.c_str(), hotfix_name.c_str()).c_str())) {} + hotfix_command = fmt::format("\"{}\" -hotfix={}", shared_memory_path, hotfix_name); } else { - if (system(StringFormat("\"%s\"", shared_memory_path.c_str()).c_str())) {} + hotfix_command = fmt::format("\"{}\"", shared_memory_path, hotfix_name); } + + LogInfo("Running hotfix command [{}]", hotfix_command); + if (system(hotfix_command.c_str())) {} #else shared_memory_path = "./shared_memory"; if (file_exists("./bin/shared_memory")) { From 4e6c3b524f2df01278c23c2d519b65773d0a6ad9 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 7 Jul 2020 01:19:02 -0500 Subject: [PATCH 11/11] Add fix for scenario where a client traveled far distance quickly and mob scanning is too slow; this takes care of all scenarios --- zone/client_process.cpp | 10 +++++----- zone/entity.cpp | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 29a826f0e..ff51fcfb7 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -256,9 +256,9 @@ bool Client::Process() { * Used in aggro checks */ if (mob_close_scan_timer.Check()) { - entity_list.ScanCloseMobs(close_mobs, this); + entity_list.ScanCloseMobs(close_mobs, this, true); } - + bool may_use_attacks = false; /* Things which prevent us from attacking: @@ -757,7 +757,7 @@ void Client::BulkSendInventoryItems() if (ob.tellp() == last_pos) LogInventory("Serialization failed on item slot [{}] during BulkSendInventoryItems. Item skipped", slot_id); - + last_pos = ob.tellp(); } @@ -836,7 +836,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { else { cur_fac_level = GetModCharacterFactionLevel(fac); } - + if (cur_fac_level < ml.faction_required) continue; @@ -1170,7 +1170,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) { return; } - + // could just do a range, but this is clearer and explicit if ( diff --git a/zone/entity.cpp b/zone/entity.cpp index 5637777d6..b00735e4a 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -2716,18 +2716,22 @@ void EntityList::ScanCloseMobs( } float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition()); - if (distance <= scan_range) { + if (distance <= scan_range || mob->GetAggroRange() >= scan_range) { close_mobs.insert(std::pair(mob->GetID(), mob)); if (add_self_to_other_lists) { - mob->close_mobs.insert(std::pair(scanning_mob->GetID(), scanning_mob)); - } - } - else if (mob->GetAggroRange() >= scan_range) { - close_mobs.insert(std::pair(mob->GetID(), mob)); + bool has_mob = false; - if (add_self_to_other_lists) { - mob->close_mobs.insert(std::pair(scanning_mob->GetID(), scanning_mob)); + for (auto &cm: mob->close_mobs) { + if (scanning_mob->GetID() == cm.first) { + has_mob = true; + break; + } + } + + if (!has_mob) { + mob->close_mobs.insert(std::pair(scanning_mob->GetID(), scanning_mob)); + } } } }