mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 09:06:46 +00:00
Nats initial commit
This commit is contained in:
+4
-2
@@ -61,7 +61,7 @@ SET(zone_sources
|
||||
lua_raid.cpp
|
||||
lua_spawn.cpp
|
||||
lua_spell.cpp
|
||||
lua_stat_bonuses.cpp
|
||||
lua_stat_bonuses.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
entity.cpp
|
||||
@@ -80,6 +80,7 @@ SET(zone_sources
|
||||
mob.cpp
|
||||
mob_ai.cpp
|
||||
mod_functions.cpp
|
||||
nats_manager.cpp
|
||||
net.cpp
|
||||
npc.cpp
|
||||
npc_ai.cpp
|
||||
@@ -187,13 +188,14 @@ SET(zone_headers
|
||||
lua_raid.h
|
||||
lua_spawn.h
|
||||
lua_spell.h
|
||||
lua_stat_bonuses.h
|
||||
lua_stat_bonuses.h
|
||||
map.h
|
||||
masterentity.h
|
||||
maxskill.h
|
||||
message.h
|
||||
merc.h
|
||||
mob.h
|
||||
nats_manager.h
|
||||
net.h
|
||||
npc.h
|
||||
npc_ai.h
|
||||
|
||||
+5
-2
@@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "worldserver.h"
|
||||
#include "zone.h"
|
||||
#include "lua_parser.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@@ -52,6 +53,7 @@ extern WorldServer worldserver;
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
extern NatsManager nats;
|
||||
|
||||
EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon, EQEmu::skills::SkillType skillinuse)
|
||||
{
|
||||
@@ -2232,7 +2234,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
||||
entity_list.QueueClients(killer_mob, app, false);
|
||||
|
||||
safe_delete(app);
|
||||
|
||||
nats.OnDeathEvent(d);
|
||||
if (respawn2) {
|
||||
respawn2->DeathReset(1);
|
||||
}
|
||||
@@ -2816,6 +2818,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
cds->damage = DS;
|
||||
entity_list.QueueCloseClients(this, outapp);
|
||||
safe_delete(outapp);
|
||||
nats.OnDamageEvent(cds->source, cds);
|
||||
}
|
||||
else if (DS > 0 && !spell_ds) {
|
||||
//we are healing the attacker...
|
||||
@@ -3740,7 +3743,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
}
|
||||
|
||||
nats.OnDamageEvent(a->source, a);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
else {
|
||||
|
||||
+22
-2
@@ -59,6 +59,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "water_map.h"
|
||||
#include "worldserver.h"
|
||||
#include "zone.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#ifdef BOTS
|
||||
#include "bot.h"
|
||||
@@ -70,6 +71,8 @@ extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern PetitionList petition_list;
|
||||
extern EntityList entity_list;
|
||||
extern NatsManager nats;
|
||||
|
||||
typedef void (Client::*ClientPacketProc)(const EQApplicationPacket *app);
|
||||
|
||||
//Use a map for connecting opcodes since it dosent get used a lot and is sparse
|
||||
@@ -1262,6 +1265,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
struct in_addr ghost_addr;
|
||||
ghost_addr.s_addr = eqs->GetRemoteIP();
|
||||
|
||||
nats.SendAdminMessage(StringFormat("Ghosting client: Account ID:%i Name:%s Character:%s IP:%s",
|
||||
client->AccountID(), client->AccountName(), client->GetName(), inet_ntoa(ghost_addr)));
|
||||
Log(Logs::General, Logs::Error, "Ghosting client: Account ID:%i Name:%s Character:%s IP:%s",
|
||||
client->AccountID(), client->AccountName(), client->GetName(), inet_ntoa(ghost_addr));
|
||||
client->Save();
|
||||
@@ -2931,7 +2936,7 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nats.OnEntityEvent(OP_Assist, this->GetID(), eid->entity_id);
|
||||
FastQueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
@@ -3978,6 +3983,7 @@ void Client::Handle_OP_Camp(const EQApplicationPacket *app)
|
||||
if (IsLFP())
|
||||
worldserver.StopLFP(CharacterID());
|
||||
|
||||
nats.OnEntityEvent(OP_Camp, this->GetID(), 0);
|
||||
if (GetGM())
|
||||
{
|
||||
OnDisconnect(true);
|
||||
@@ -4203,7 +4209,7 @@ void Client::Handle_OP_ChannelMessage(const EQApplicationPacket *app)
|
||||
Message(13, "You try to speak but cant move your mouth!");
|
||||
return;
|
||||
}
|
||||
|
||||
nats.OnChannelMessageEvent(this->GetID(), cm);
|
||||
ChannelMessageReceived(cm->chan_num, cm->language, cm->skill_in_language, cm->message, cm->targetname);
|
||||
return;
|
||||
}
|
||||
@@ -5165,6 +5171,7 @@ void Client::Handle_OP_Damage(const EQApplicationPacket *app)
|
||||
CombatDamage_Struct* damage = (CombatDamage_Struct*)app->pBuffer;
|
||||
//dont send to originator of falling damage packets
|
||||
entity_list.QueueClients(this, app, (damage->type == DamageTypeFalling));
|
||||
nats.OnDamageEvent(damage->source, damage);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5913,6 +5920,7 @@ void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/becomenpc");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /becomenpc attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
if (app->size != sizeof(BecomeNPC_Struct)) {
|
||||
@@ -5944,6 +5952,7 @@ void Client::Handle_OP_GMDelCorpse(const EQApplicationPacket *app)
|
||||
if (this->Admin() < commandEditPlayerCorpses) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/delcorpse");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /delcorpse attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
GMDelCorpse_Struct* dc = (GMDelCorpse_Struct *)app->pBuffer;
|
||||
@@ -5965,6 +5974,7 @@ void Client::Handle_OP_GMEmoteZone(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/emote");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /emote attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
if (app->size != sizeof(GMEmoteZone_Struct)) {
|
||||
@@ -5998,6 +6008,7 @@ void Client::Handle_OP_GMFind(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/find");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /find attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
if (app->size != sizeof(GMSummon_Struct)) {
|
||||
@@ -6036,6 +6047,7 @@ void Client::Handle_OP_GMGoto(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/goto");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /goto attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
GMSummon_Struct* gmg = (GMSummon_Struct*)app->pBuffer;
|
||||
@@ -6063,6 +6075,7 @@ void Client::Handle_OP_GMHideMe(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/hideme");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /hideme attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
if (app->size != sizeof(SpawnAppearance_Struct)) {
|
||||
@@ -6083,6 +6096,7 @@ void Client::Handle_OP_GMKick(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToKick) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/kick");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /kick attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
GMKick_Struct* gmk = (GMKick_Struct *)app->pBuffer;
|
||||
@@ -6113,6 +6127,7 @@ void Client::Handle_OP_GMKill(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/kill");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /kill attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
if (app->size != sizeof(GMKill_Struct)) {
|
||||
@@ -6165,6 +6180,7 @@ void Client::Handle_OP_GMLastName(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(client->account_name, client->name, "/lastname");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /lastname attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -6190,6 +6206,7 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/name");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /name attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
Client* client = entity_list.GetClientByName(gmn->oldname);
|
||||
@@ -6334,6 +6351,7 @@ void Client::Handle_OP_GMToggle(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToUseGMCommands) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/toggle");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /toggle attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
GMToggle_Struct *ts = (GMToggle_Struct *)app->pBuffer;
|
||||
@@ -6385,6 +6403,7 @@ void Client::Handle_OP_GMZoneRequest(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToBeGM) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/zone");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /zone attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6433,6 +6452,7 @@ void Client::Handle_OP_GMZoneRequest2(const EQApplicationPacket *app)
|
||||
if (this->Admin() < minStatusToBeGM) {
|
||||
Message(13, "Your account has been reported for hacking.");
|
||||
database.SetHackerFlag(this->account_name, this->name, "/zone");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s /zone attempt.", GetCleanName()));
|
||||
return;
|
||||
}
|
||||
if (app->size < sizeof(uint32)) {
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "../common/string_util.h"
|
||||
#include "event_codes.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "nats_manager.h"
|
||||
#include "map.h"
|
||||
#include "petitions.h"
|
||||
#include "queryserv.h"
|
||||
@@ -60,6 +61,7 @@ extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern PetitionList petition_list;
|
||||
extern EntityList entity_list;
|
||||
extern NatsManager nats;
|
||||
|
||||
bool Client::Process() {
|
||||
bool ret = true;
|
||||
@@ -2199,7 +2201,7 @@ void Client::ClearHover()
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
||||
CastToClient()->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
nats.OnSpawnEvent(OP_ZoneEntry, this->GetID(), &sze->player.spawn);
|
||||
dead = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,10 +67,12 @@
|
||||
#include "titles.h"
|
||||
#include "water_map.h"
|
||||
#include "worldserver.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
extern QueryServ* QServ;
|
||||
extern WorldServer worldserver;
|
||||
extern TaskManager *taskmanager;
|
||||
extern NatsManager nats;
|
||||
void CatchSignal(int sig_num);
|
||||
|
||||
|
||||
@@ -563,6 +565,8 @@ int command_realdispatch(Client *c, const char *message)
|
||||
QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc);
|
||||
}
|
||||
|
||||
nats.SendAdminMessage(StringFormat("%s in %s issued command: %s", c->GetCleanName(), database.GetZoneName(zone->GetZoneID()), message));
|
||||
|
||||
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
|
||||
Log(Logs::General, Logs::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
|
||||
}
|
||||
|
||||
@@ -4879,3 +4879,16 @@ void EntityList::ReloadMerchants() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::map<uint16, NPC *> EntityList::ListNPCs()
|
||||
{
|
||||
std::map<uint16, NPC*> npcs;
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
NPC *n = it->second;
|
||||
npcs[n->id] = n;
|
||||
++it;
|
||||
}
|
||||
return npcs;
|
||||
}
|
||||
@@ -216,6 +216,7 @@ public:
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
std::map<uint16, NPC*> ListNPCs();
|
||||
Doors *GetDoorsByDoorID(uint32 id);
|
||||
Doors *GetDoorsByDBID(uint32 id);
|
||||
void RemoveAllCorpsesByCharID(uint32 charid);
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "worldserver.h"
|
||||
#include "zonedb.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern NatsManager nats;
|
||||
|
||||
// @merth: this needs to be touched up
|
||||
uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
@@ -626,6 +628,7 @@ void Client::DropItem(int16 slot_id, bool recurse)
|
||||
invalid_drop = nullptr;
|
||||
|
||||
database.SetHackerFlag(this->AccountName(), this->GetCleanName(), "Tried to drop an item on the ground that was nodrop!");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s: Tried to drop nodrop item on ground", GetCleanName()));
|
||||
GetInv().DeleteItem(slot_id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "mob.h"
|
||||
#include "npc.h"
|
||||
#include "zonedb.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
@@ -34,6 +35,8 @@
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
extern NatsManager nats;
|
||||
|
||||
// Queries the loottable: adds item & coin to the npc
|
||||
void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat) {
|
||||
const LootTable_Struct* lts = nullptr;
|
||||
@@ -242,6 +245,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch
|
||||
wc = (WearChange_Struct*)outapp->pBuffer;
|
||||
wc->spawn_id = GetID();
|
||||
wc->material=0;
|
||||
nats.OnWearChangeEvent(this->GetID(), wc);
|
||||
}
|
||||
|
||||
item->item_id = item2->ID;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// lua.hpp
|
||||
// Lua header files for C++
|
||||
// <<extern "C">> not supplied automatically because Lua also compiles as C++
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
+1023
-1021
File diff suppressed because it is too large
Load Diff
+26
-25
@@ -30,40 +30,41 @@
|
||||
#define BEST_Z_INVALID -99999
|
||||
|
||||
extern const ZoneConfig *Config;
|
||||
|
||||
class Map
|
||||
namespace EQEmu
|
||||
{
|
||||
public:
|
||||
Map();
|
||||
~Map();
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
Map();
|
||||
~Map();
|
||||
|
||||
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
float FindClosestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
float FindClosestZ(glm::vec3 &start, glm::vec3 *result) const;
|
||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
bool Load(std::string filename, bool force_mmf_overwrite = false);
|
||||
bool Load(std::string filename, bool force_mmf_overwrite = false);
|
||||
#else
|
||||
bool Load(std::string filename);
|
||||
bool Load(std::string filename);
|
||||
#endif
|
||||
|
||||
static Map *LoadMapFile(std::string file);
|
||||
private:
|
||||
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
||||
void ScaleVertex(glm::vec3 &v, float sx, float sy, float sz);
|
||||
void TranslateVertex(glm::vec3 &v, float tx, float ty, float tz);
|
||||
bool LoadV1(FILE *f);
|
||||
bool LoadV2(FILE *f);
|
||||
static Map *LoadMapFile(std::string file);
|
||||
private:
|
||||
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
||||
void ScaleVertex(glm::vec3 &v, float sx, float sy, float sz);
|
||||
void TranslateVertex(glm::vec3 &v, float tx, float ty, float tz);
|
||||
bool LoadV1(FILE *f);
|
||||
bool LoadV2(FILE *f);
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
bool LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||
bool SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||
bool LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||
bool SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
struct impl;
|
||||
impl *imp;
|
||||
};
|
||||
|
||||
struct impl;
|
||||
impl *imp;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
+16
-7
@@ -23,6 +23,7 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "string_ids.h"
|
||||
#include "worldserver.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
@@ -37,6 +38,7 @@ extern EntityList entity_list;
|
||||
|
||||
extern Zone* zone;
|
||||
extern WorldServer worldserver;
|
||||
extern NatsManager nats;
|
||||
|
||||
Mob::Mob(const char* in_name,
|
||||
const char* in_lastname,
|
||||
@@ -944,7 +946,7 @@ void Mob::CreateSpawnPacket(EQApplicationPacket* app, Mob* ForWho) {
|
||||
memset(app->pBuffer, 0, app->size);
|
||||
NewSpawn_Struct* ns = (NewSpawn_Struct*)app->pBuffer;
|
||||
FillSpawnStruct(ns, ForWho);
|
||||
|
||||
nats.OnSpawnEvent(OP_NewSpawn, ns->spawn.spawnId, &ns->spawn);
|
||||
if(RuleB(NPC, UseClassAsLastName) && strlen(ns->spawn.lastName) == 0)
|
||||
{
|
||||
switch(ns->spawn.class_)
|
||||
@@ -1260,6 +1262,7 @@ void Mob::CreateDespawnPacket(EQApplicationPacket* app, bool Decay)
|
||||
ds->spawn_id = GetID();
|
||||
// The next field only applies to corpses. If 0, they vanish instantly, otherwise they 'decay'
|
||||
ds->Decay = Decay ? 1 : 0;
|
||||
nats.OnDeleteSpawnEvent(this->GetID(), ds);
|
||||
}
|
||||
|
||||
void Mob::CreateHPPacket(EQApplicationPacket* app)
|
||||
@@ -1270,7 +1273,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
|
||||
app->pBuffer = new uchar[app->size];
|
||||
memset(app->pBuffer, 0, sizeof(SpawnHPUpdate_Struct2));
|
||||
SpawnHPUpdate_Struct2* ds = (SpawnHPUpdate_Struct2*)app->pBuffer;
|
||||
|
||||
nats.OnHPEvent(OP_MobHealth, this->GetID(), cur_hp, max_hp);
|
||||
ds->spawn_id = GetID();
|
||||
// they don't need to know the real hp
|
||||
ds->hp = (int)GetHPRatio();
|
||||
@@ -1304,7 +1307,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
|
||||
// sends hp update of this mob to people who might care
|
||||
void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/)
|
||||
{
|
||||
|
||||
nats.OnHPEvent(OP_HPUpdate, this->GetID(), cur_hp, max_hp);
|
||||
/* If our HP is different from last HP update call - let's update ourself */
|
||||
if (IsClient()) {
|
||||
if (cur_hp != last_hp || force_update_all) {
|
||||
@@ -1467,7 +1470,7 @@ void Mob::SendPosition() {
|
||||
else {
|
||||
entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false);
|
||||
}
|
||||
|
||||
nats.OnClientUpdateEvent(this->GetID(), spu);
|
||||
safe_delete(app);
|
||||
}
|
||||
|
||||
@@ -1481,7 +1484,7 @@ void Mob::SendPositionUpdateToClient(Client *client) {
|
||||
MakeSpawnUpdateNoDelta(spawn_update);
|
||||
|
||||
client->QueuePacket(app, false);
|
||||
|
||||
nats.OnClientUpdateEvent(this->GetID(), spawn_update);
|
||||
safe_delete(app);
|
||||
}
|
||||
|
||||
@@ -1504,6 +1507,7 @@ void Mob::SendPositionUpdate(uint8 iSendToSelf) {
|
||||
else {
|
||||
entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false);
|
||||
}
|
||||
nats.OnClientUpdateEvent(this->GetID(), spu);
|
||||
safe_delete(app);
|
||||
}
|
||||
|
||||
@@ -1622,7 +1626,7 @@ void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter)
|
||||
ackreq, /* Packet ACK */
|
||||
filter /* eqFilterType filter */
|
||||
);
|
||||
|
||||
nats.OnAnimationEvent(this->GetID(), anim);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@@ -2899,7 +2903,7 @@ void Mob::SendWearChange(uint8 material_slot, Client *one_client)
|
||||
{
|
||||
one_client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
|
||||
}
|
||||
|
||||
nats.OnWearChangeEvent(this->GetID(), wc);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@@ -2923,6 +2927,7 @@ void Mob::SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model, uin
|
||||
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
nats.OnWearChangeEvent(this->GetID(), wc);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@@ -2945,6 +2950,7 @@ void Mob::SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uin
|
||||
wc->wear_slot_id = material_slot;
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
nats.OnWearChangeEvent(this->GetID(), wc);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@@ -2962,6 +2968,7 @@ void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 h
|
||||
wc->wear_slot_id = material_slot;
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
nats.OnWearChangeEvent(this->GetID(), wc);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@@ -4688,7 +4695,9 @@ void Mob::DoKnockback(Mob *caster, uint32 pushback, uint32 pushup)
|
||||
outapp_push->priority = 6;
|
||||
entity_list.QueueClients(this, outapp_push, true);
|
||||
CastToClient()->FastQueuePacket(&outapp_push);
|
||||
nats.OnClientUpdateEvent(this->GetID(), spu);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Mob::TrySpellOnKill(uint8 level, uint16 spell_id)
|
||||
|
||||
@@ -0,0 +1,867 @@
|
||||
#include "entity.h"
|
||||
#include "mob.h"
|
||||
//#include "client.h" //map error
|
||||
#include "event_codes.h"
|
||||
#include "nats.h"
|
||||
#include "zone_config.h"
|
||||
#include "nats_manager.h"
|
||||
//#include "guild_mgr.h" //used for database, map error
|
||||
#include "npc.h"
|
||||
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/string_util.h"
|
||||
#ifndef PROTO_H
|
||||
#define PROTO_H
|
||||
#include "../common/proto/message.pb.h"
|
||||
#endif
|
||||
|
||||
const ZoneConfig *zoneConfig;
|
||||
|
||||
NatsManager::NatsManager()
|
||||
{
|
||||
//new timers, object initialization
|
||||
|
||||
zoneConfig = ZoneConfig::get();
|
||||
}
|
||||
|
||||
NatsManager::~NatsManager()
|
||||
{
|
||||
nats_timer.Disable();
|
||||
// Destroy all our objects to avoid report of memory leak
|
||||
natsConnection_Destroy(conn);
|
||||
natsOptions_Destroy(opts);
|
||||
|
||||
// To silence reports of memory still in used with valgrind
|
||||
nats_Close();
|
||||
}
|
||||
|
||||
void NatsManager::Process()
|
||||
{
|
||||
if (zoneSub == NULL) {
|
||||
return;
|
||||
}
|
||||
if (!connect()) return;
|
||||
natsMsg *msg = NULL;
|
||||
|
||||
s = NATS_OK;
|
||||
std::string pubMessage;
|
||||
for (int count = 0; (s == NATS_OK) && count < 100; count++)
|
||||
{
|
||||
s = natsSubscription_NextMsg(&msg, zoneSub, 1);
|
||||
if (s != NATS_OK) break;
|
||||
Log(Logs::General, Logs::NATS, "got message '%s'", natsMsg_GetData(msg));
|
||||
natsMsg_Destroy(msg);
|
||||
}
|
||||
|
||||
|
||||
s = NATS_OK;
|
||||
for (int count = 0; (s == NATS_OK) && count < 5; count++)
|
||||
{
|
||||
s = natsSubscription_NextMsg(&msg, commandMessageSub, 1);
|
||||
if (s != NATS_OK) break;
|
||||
Log(Logs::General, Logs::World_Server, "NATS Got Command Message '%s'", natsMsg_GetData(msg));
|
||||
eqproto::CommandMessage message;
|
||||
|
||||
if (!message.ParseFromString(natsMsg_GetData(msg))) {
|
||||
Log(Logs::General, Logs::World_Server, "Failed to marshal");
|
||||
natsMsg_Destroy(msg);
|
||||
continue;
|
||||
}
|
||||
if (message.command().compare("npctypespawn") == 0) {
|
||||
if (message.params_size() < 2) {
|
||||
message.set_result("Usage: !npctypespawn <npctypeid> <factionid> <x> <y> <z> <h>.");
|
||||
} else {
|
||||
|
||||
uint32 npctypeid = atoi(message.params(0).c_str());
|
||||
uint32 factionid = atoi(message.params(1).c_str());
|
||||
float x = atof(message.params(2).c_str());
|
||||
float y = atof(message.params(3).c_str());
|
||||
float z = atof(message.params(4).c_str());
|
||||
float h = atof(message.params(5).c_str());
|
||||
auto position = glm::vec4(x, y, z, h);
|
||||
const NPCType* tmp = 0;
|
||||
|
||||
/*if (!(tmp = database.LoadNPCTypesData(npctypeid))) {
|
||||
message.set_result(StringFormat("NPC Type %i not found", npctypeid));
|
||||
} else {
|
||||
//tmp->fixedZ = 1;
|
||||
|
||||
auto npc = new NPC(tmp, 0, position, FlyMode3);
|
||||
if (npc && factionid >0)
|
||||
npc->SetNPCFactionID(factionid);
|
||||
npc->AddLootTable();
|
||||
entity_list.AddNPC(npc);
|
||||
message.set_result("Created NPC successfully.");
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (message.command().compare("spawn") == 0) {
|
||||
if (message.params_size() < 5) {
|
||||
message.set_result("Usage: npctypespawn <x> <y> <z> <h> name race level material hp gender class priweapon secweapon merchantid bodytype.");
|
||||
}
|
||||
else {
|
||||
|
||||
float x = atof(message.params(0).c_str());
|
||||
float y = atof(message.params(1).c_str());
|
||||
float z = atof(message.params(2).c_str());
|
||||
float h = atof(message.params(3).c_str());
|
||||
auto position = glm::vec4(x, y, z, h);
|
||||
|
||||
std::string argumentString;
|
||||
for (int i = 4; i < message.params_size(); i++) {
|
||||
argumentString.append(StringFormat(" %s", message.params(i).c_str()));
|
||||
}
|
||||
|
||||
NPC* npc = NPC::SpawnNPC(argumentString.c_str(), position, NULL);
|
||||
if (!npc) {
|
||||
message.set_result("Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters.");
|
||||
}
|
||||
else {
|
||||
message.set_result(StringFormat("%u", npc->GetID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message.command().compare("moveto") == 0) {
|
||||
if (message.params_size() < 5) {
|
||||
message.set_result("Usage: moveto <entityid> <x> <y> <z> <h>.");
|
||||
}
|
||||
else {
|
||||
uint16 entityid = atoi(message.params(0).c_str());
|
||||
float x = atof(message.params(1).c_str());
|
||||
float y = atof(message.params(2).c_str());
|
||||
float z = atof(message.params(3).c_str());
|
||||
float h = atof(message.params(4).c_str());
|
||||
auto position = glm::vec4(x, y, z, h);
|
||||
|
||||
auto npc = entity_list.GetNPCByID(entityid);
|
||||
if (!npc) {
|
||||
message.set_result("Invalid entity ID passed, or not an npc, etc");
|
||||
}
|
||||
else {
|
||||
npc->MoveTo(position, true);
|
||||
message.set_result("OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message.command().compare("attack") == 0) {
|
||||
if (message.params_size() < 3) {
|
||||
message.set_result("Usage: attack <entityid> <targetentityid> <hateamount>.");
|
||||
}
|
||||
else {
|
||||
uint16 entityID = atoi(message.params(0).c_str());
|
||||
uint16 targetEntityID = atoi(message.params(1).c_str());
|
||||
uint32 hateAmount = atoi(message.params(2).c_str());
|
||||
|
||||
auto npc = entity_list.GetNPCByID(entityID);
|
||||
if (!npc) {
|
||||
message.set_result("Invalid entity ID passed, or not an npc, etc");
|
||||
}
|
||||
else {
|
||||
auto mob = entity_list.GetMobID(targetEntityID);
|
||||
if (!mob) {
|
||||
message.set_result("Invalid target entitiy ID passed, or not a mob, etc");
|
||||
}
|
||||
else {
|
||||
npc->AddToHateList(mob, hateAmount);
|
||||
message.set_result("OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message.command().compare("entitylist") == 0) {
|
||||
std::string entityPayload;
|
||||
if (message.params_size() < 1) {
|
||||
message.set_result("Usage: entitylist <typeid>.");
|
||||
}
|
||||
else {
|
||||
auto entities = eqproto::Entities();
|
||||
if (message.params(0).compare("npc") == 0) {
|
||||
auto npcs = entity_list.ListNPCs();
|
||||
auto it = npcs.begin();
|
||||
for (const auto &entry : npcs) {
|
||||
auto entity = entities.add_entities();
|
||||
entity->set_id(entry.second->GetID());
|
||||
entity->set_type(1);
|
||||
entity->set_name(entry.second->GetName());
|
||||
}
|
||||
|
||||
if (!entities.SerializeToString(&entityPayload)) {
|
||||
message.set_result("Failed to serialized entitiy result");
|
||||
}
|
||||
else {
|
||||
message.set_payload(entityPayload.c_str());
|
||||
}
|
||||
}
|
||||
/*else if (message.params(0).compare("client") == 0) {
|
||||
auto clients = entity_list.ListClients();
|
||||
auto it = clients.begin();
|
||||
for (const auto &entry : clients) {
|
||||
auto entity = entities.add_entities();
|
||||
entity->set_id(entry.second->GetID());
|
||||
entity->set_type(0);
|
||||
entity->set_name(entry.second->GetName());
|
||||
}
|
||||
|
||||
if (!entities.SerializeToString(&entityMessage)) {
|
||||
message.set_result("Failed to serialized entitiy result");
|
||||
}
|
||||
else {
|
||||
message.set_result(entityMessage.c_str());
|
||||
}
|
||||
}*/
|
||||
else {
|
||||
message.set_result("Usage: entitylist <typeid>.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (message.result().length() < 1) {
|
||||
message.set_result("Failed to parse command.");
|
||||
}
|
||||
|
||||
if (!message.SerializeToString(&pubMessage)) {
|
||||
Log(Logs::General, Logs::World_Server, "NATS Failed to serialize command message to string");
|
||||
return;
|
||||
}
|
||||
|
||||
s = natsConnection_PublishString(conn, natsMsg_GetReply(msg), pubMessage.c_str());
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::World_Server, "NATS Failed to send CommandMessageEvent");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Unregister is called when a zone is being put to sleep or being swapped
|
||||
void NatsManager::Unregister()
|
||||
{
|
||||
if (!connect()) return;
|
||||
if (commandMessageSub != NULL) {
|
||||
s = natsSubscription_Unsubscribe(commandMessageSub);
|
||||
commandMessageSub = NULL;
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from commandMessageSub failed: %s", nats_GetLastError(&s));
|
||||
}
|
||||
|
||||
if (zoneChannelMessageSub != NULL) {
|
||||
s = natsSubscription_Unsubscribe(zoneChannelMessageSub);
|
||||
zoneChannelMessageSub = NULL;
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from zoneChannelMessageSub failed: %s", nats_GetLastError(&s));
|
||||
}
|
||||
|
||||
if (zoneEntityEventSubscribeAllSub != NULL) {
|
||||
s = natsSubscription_Unsubscribe(zoneEntityEventSubscribeAllSub);
|
||||
zoneEntityEventSubscribeAllSub = NULL;
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from zoneEntityEventSubscribeAllSub failed: %s", nats_GetLastError(&s));
|
||||
}
|
||||
if (zoneEntityEventSubscribeSub != NULL) {
|
||||
s = natsSubscription_Unsubscribe(zoneEntityEventSubscribeSub);
|
||||
zoneEntityEventSubscribeSub = NULL;
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from zoneEntityEventSubscribeSub failed: %s", nats_GetLastError(&s));
|
||||
}
|
||||
|
||||
if (zoneEntityEventListSub != NULL) {
|
||||
s = natsSubscription_Unsubscribe(zoneEntityEventListSub);
|
||||
zoneEntityEventListSub = NULL;
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from zoneEntityEventListSub failed: %s", nats_GetLastError(&s));
|
||||
}
|
||||
|
||||
if (zoneEntityEventSub != NULL) {
|
||||
s = natsSubscription_Unsubscribe(zoneEntityEventSub);
|
||||
zoneEntityEventSub = NULL;
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from zoneEntityEventSub failed: %s", nats_GetLastError(&s));
|
||||
}
|
||||
|
||||
Log(Logs::General, Logs::NATS, "unsubscribed from %s", subscribedZonename.c_str());
|
||||
subscribedZonename.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
void NatsManager::ZoneSubscribe(const char* zonename) {
|
||||
if (strcmp(subscribedZonename.c_str(), zonename) == 0) return;
|
||||
if (!connect()) return;
|
||||
Unregister();
|
||||
|
||||
subscribedZonename = std::string(zonename);
|
||||
|
||||
s = natsConnection_SubscribeSync(&zoneChannelMessageSub, conn, StringFormat("zone.%s.channel_message", subscribedZonename.c_str()).c_str());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneChannelMessageSub %s", nats_GetLastError(&s));
|
||||
s = natsSubscription_SetPendingLimits(zoneChannelMessageSub, -1, -1);
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneChannelMessageSub %s", nats_GetLastError(&s));
|
||||
|
||||
s = natsConnection_SubscribeSync(&commandMessageSub, conn, StringFormat("zone.%s.command_message", subscribedZonename.c_str()).c_str());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to commandMessageSub %s", nats_GetLastError(&s));
|
||||
s = natsSubscription_SetPendingLimits(commandMessageSub, -1, -1);
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to commandMessageSub %s", nats_GetLastError(&s));
|
||||
|
||||
s = natsConnection_SubscribeSync(&zoneEntityEventSubscribeAllSub, conn, StringFormat("zone.%s.entity.event_subscribe.all", subscribedZonename.c_str()).c_str());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s));
|
||||
s = natsSubscription_SetPendingLimits(zoneEntityEventSubscribeAllSub, -1, -1);
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s));
|
||||
|
||||
s = natsConnection_SubscribeSync(&zoneEntityEventSubscribeAllSub, conn, StringFormat("zone.%s.entity.event_subscribe.all", subscribedZonename.c_str()).c_str());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s));
|
||||
s = natsSubscription_SetPendingLimits(zoneEntityEventSubscribeAllSub, -1, -1);
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s));
|
||||
|
||||
Log(Logs::General, Logs::NATS, "subscribed to %s", subscribedZonename.c_str());
|
||||
}
|
||||
|
||||
|
||||
void NatsManager::SendAdminMessage(std::string adminMessage) {
|
||||
if (!connect()) return;
|
||||
|
||||
eqproto::ChannelMessage message;
|
||||
message.set_message(adminMessage.c_str());
|
||||
std::string pubMessage;
|
||||
if (!message.SerializeToString(&pubMessage)) {
|
||||
Log(Logs::General, Logs::NATS, "Failed to serialize message to string");
|
||||
return;
|
||||
}
|
||||
s = natsConnection_PublishString(conn, "NATS AdminMessage", pubMessage.c_str());
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "Failed to SendAdminMessage");
|
||||
}
|
||||
Log(Logs::General, Logs::NATS, "AdminMessage: %s", adminMessage.c_str());
|
||||
}
|
||||
|
||||
|
||||
bool NatsManager::connect() {
|
||||
auto ncs = natsConnection_Status(conn);
|
||||
if (ncs == CONNECTED) return true;
|
||||
if (nats_timer.Enabled() && !nats_timer.Check()) return false;
|
||||
natsOptions *opts = NULL;
|
||||
natsOptions_Create(&opts);
|
||||
natsOptions_SetMaxReconnect(opts, 0);
|
||||
natsOptions_SetReconnectWait(opts, 0);
|
||||
natsOptions_SetAllowReconnect(opts, false);
|
||||
//The timeout is going to cause a 100ms delay on all connected clients every X seconds (20s)
|
||||
//since this blocks the connection. It can be set lower or higher delay,
|
||||
//but since NATS is a second priority I wanted server impact minimum.
|
||||
natsOptions_SetTimeout(opts, 100);
|
||||
std::string connection = StringFormat("nats://%s:%d", zoneConfig->NATSHost.c_str(), zoneConfig->NATSPort);
|
||||
if (zoneConfig->NATSHost.length() == 0) connection = "nats://localhost:4222";
|
||||
natsOptions_SetURL(opts, connection.c_str());
|
||||
s = natsConnection_Connect(&conn, opts);
|
||||
natsOptions_Destroy(opts);
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to connect to %s: %s, retrying in 20s", connection.c_str(), nats_GetLastError(&s));
|
||||
conn = NULL;
|
||||
nats_timer.Enable();
|
||||
nats_timer.SetTimer(20000);
|
||||
return false;
|
||||
}
|
||||
Log(Logs::General, Logs::NATS, "connected to %s", connection.c_str());
|
||||
nats_timer.Disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NatsManager::Load()
|
||||
{
|
||||
if (!connect()) return;
|
||||
|
||||
s = natsConnection_SubscribeSync(&zoneSub, conn, "zone");
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to subscribe to zone: %s", nats_GetLastError(&s));
|
||||
return;
|
||||
}
|
||||
s = natsSubscription_SetPendingLimits(zoneSub, -1, -1);
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to set pending limits while subscribed to zone %s", nats_GetLastError(&s));
|
||||
return;
|
||||
}
|
||||
|
||||
s = natsConnection_SubscribeSync(&commandMessageSub, conn, "zone.command_message");
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to subscribe to commandMessageSub: %s", nats_GetLastError(&s));
|
||||
return;
|
||||
}
|
||||
s = natsSubscription_SetPendingLimits(commandMessageSub, -1, -1);
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to set pending limits while subscribed to commandMessageSub: %s", nats_GetLastError(&s));
|
||||
return;
|
||||
}
|
||||
|
||||
s = natsConnection_SubscribeSync(&channelMessageSub, conn, "zone.channel_message");
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to subscribe to channel message: %s", nats_GetLastError(&s));
|
||||
return;
|
||||
}
|
||||
s = natsSubscription_SetPendingLimits(channelMessageSub, -1, -1);
|
||||
if (s != NATS_OK) {
|
||||
Log(Logs::General, Logs::NATS, "failed to set pending limits while subscribed to channel message: %s", nats_GetLastError(&s));
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NatsManager::DailyGain(int account_id, int character_id, const char* identity, int levels_gained, int experience_gained, int money_earned)
|
||||
{
|
||||
if (!connect()) return;
|
||||
eqproto::DailyGain daily;
|
||||
daily.set_account_id(account_id);
|
||||
daily.set_character_id(character_id);
|
||||
daily.set_identity(identity);
|
||||
daily.set_levels_gained(levels_gained);
|
||||
daily.set_experience_gained(experience_gained);
|
||||
daily.set_money_earned(money_earned);
|
||||
std::string pubMessage;
|
||||
if (!daily.SerializeToString(&pubMessage)) {
|
||||
Log(Logs::General, Logs::NATS, "failed to serialize dailygain to string");
|
||||
return;
|
||||
}
|
||||
|
||||
s = natsConnection_PublishString(conn, "DailyGain", pubMessage.c_str());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to send DailyGain: %s", nats_GetLastError(&s));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void NatsManager::OnEntityEvent(const EmuOpcode op, Entity *ent, Entity *target) {
|
||||
if (ent == NULL) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(ent->GetID())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!conn) {
|
||||
Log(Logs::General, Logs::NATS, "OnChannelMessage failed, no connection to NATS");
|
||||
return;
|
||||
}
|
||||
|
||||
eqproto::EntityEvent event;
|
||||
event.set_op(eqproto::OpCode(op));
|
||||
eqproto::Entity entity;
|
||||
entity.set_id(ent->GetID());
|
||||
entity.set_name(ent->GetName());
|
||||
|
||||
if (ent->IsClient()) {
|
||||
entity.set_type(1);
|
||||
}
|
||||
else if (ent->IsNPC()) {
|
||||
entity.set_type(2);
|
||||
}
|
||||
|
||||
auto position = eqproto::Position();
|
||||
if (ent->IsMob()) {
|
||||
auto mob = ent->CastToMob();
|
||||
entity.set_hp(mob->GetHP());
|
||||
entity.set_level(mob->GetLevel());
|
||||
entity.set_name(mob->GetName());
|
||||
position.set_x(mob->GetX());
|
||||
position.set_y(mob->GetY());
|
||||
position.set_z(mob->GetZ());
|
||||
position.set_h(mob->GetHeading());
|
||||
entity.set_race(mob->GetRace());
|
||||
entity.set_class_(mob->GetClass());
|
||||
}
|
||||
|
||||
auto targetEntity = eqproto::Entity();
|
||||
auto targetPosition = eqproto::Position();
|
||||
if (target != NULL && target->IsMob()) {
|
||||
if (target->IsClient()) {
|
||||
targetEntity.set_type(1);
|
||||
}
|
||||
else if (target->IsNPC()) {
|
||||
targetEntity.set_type(2);
|
||||
}
|
||||
auto mob = target->CastToMob();
|
||||
targetEntity.set_hp(mob->GetHP());
|
||||
targetEntity.set_level(mob->GetLevel());
|
||||
targetEntity.set_name(mob->GetName());
|
||||
targetPosition.set_x(mob->GetX());
|
||||
targetPosition.set_y(mob->GetY());
|
||||
targetPosition.set_z(mob->GetZ());
|
||||
targetPosition.set_h(mob->GetHeading());
|
||||
targetEntity.set_race(mob->GetRace());
|
||||
targetEntity.set_class_(mob->GetClass());
|
||||
}
|
||||
|
||||
entity.set_allocated_position(&position);
|
||||
targetEntity.set_allocated_position(&targetPosition);
|
||||
event.set_allocated_entity(&entity);
|
||||
event.set_allocated_target(&targetEntity);
|
||||
|
||||
|
||||
std::string pubMessage;
|
||||
bool isSerialized = event.SerializeToString(&pubMessage);
|
||||
if (!isSerialized) Log(Logs::General, Logs::NATS, "Failed to serialize message to string");
|
||||
Log(Logs::General, Logs::NATS, "Event: %d", op);
|
||||
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), ent->GetID()).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
entity.release_name();
|
||||
targetEntity.release_name();
|
||||
entity.release_position();
|
||||
targetEntity.release_position();
|
||||
event.release_entity();
|
||||
event.release_target();
|
||||
return;
|
||||
}*/
|
||||
|
||||
bool NatsManager::isEntitySubscribed(const uint16 ID) {
|
||||
if (!connect()) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void NatsManager::OnDeathEvent(Death_Struct* d) {
|
||||
if (!connect()) return;
|
||||
if (d == NULL) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(d->spawn_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::DeathEvent();
|
||||
|
||||
event.set_spawn_id(d->spawn_id);
|
||||
event.set_killer_id(d->killer_id);
|
||||
event.set_bind_zone_id(d->bindzoneid);
|
||||
event.set_spell_id(d->spell_id);
|
||||
event.set_attack_skill_id(d->attack_skill);
|
||||
event.set_damage(d->damage);
|
||||
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_Death);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), d->spawn_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
|
||||
void NatsManager::OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct* cm) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::ChannelMessageEvent();
|
||||
|
||||
event.set_target_name(cm->targetname);
|
||||
event.set_sender(cm->sender);
|
||||
event.set_language(cm->language);
|
||||
event.set_chan_num(cm->chan_num);
|
||||
event.set_cm_unknown4(*cm->cm_unknown4);
|
||||
event.set_skill_in_language(cm->skill_in_language);
|
||||
event.set_message(cm->message);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_ChannelMessage);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
void NatsManager::OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 target_id) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::EntityEvent();
|
||||
|
||||
event.set_entity_id(entity_id);
|
||||
event.set_target_id(target_id);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
if (op == OP_Camp) finalEvent.set_op(eqproto::OP_Camp);
|
||||
else if (op == OP_Assist) finalEvent.set_op(eqproto::OP_Assist);
|
||||
else { Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); return; }
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
|
||||
void NatsManager::OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struct *spawn) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::SpawnEvent();
|
||||
|
||||
event.set_unknown0000(spawn->unknown0000);
|
||||
event.set_gm(spawn->gm);
|
||||
event.set_unknown0003(spawn->unknown0003);
|
||||
event.set_aaitle(spawn->aaitle);
|
||||
event.set_unknown0004(spawn->unknown0004);
|
||||
event.set_anon(spawn->anon);
|
||||
event.set_face(spawn->face);
|
||||
event.set_name(spawn->name);
|
||||
event.set_deity(spawn->deity);
|
||||
event.set_unknown0073(spawn->unknown0073);
|
||||
event.set_size(spawn->size);
|
||||
event.set_unknown0079(spawn->unknown0079);
|
||||
event.set_npc(spawn->NPC);
|
||||
event.set_invis(spawn->invis);
|
||||
event.set_haircolor(spawn->haircolor);
|
||||
event.set_curhp(spawn->curHp);
|
||||
event.set_max_hp(spawn->max_hp);
|
||||
event.set_findable(spawn->findable);
|
||||
event.set_unknown0089(*spawn->unknown0089);
|
||||
event.set_deltaheading(spawn->deltaHeading);
|
||||
event.set_x(spawn->x);
|
||||
event.set_padding0054(spawn->padding0054);
|
||||
event.set_y(spawn->y);
|
||||
event.set_animation(spawn->animation);
|
||||
event.set_padding0058(spawn->padding0058);
|
||||
event.set_z(spawn->z);
|
||||
event.set_deltay(spawn->deltaY);
|
||||
event.set_deltax(spawn->deltaX);
|
||||
event.set_heading(spawn->heading);
|
||||
event.set_padding0066(spawn->padding0066);
|
||||
event.set_deltaz(spawn->deltaZ);
|
||||
event.set_padding0070(spawn->padding0070);
|
||||
event.set_eyecolor1(spawn->eyecolor1);
|
||||
event.set_unknown0115(*spawn->unknown0115);
|
||||
event.set_standstate(spawn->StandState);
|
||||
event.set_drakkin_heritage(spawn->drakkin_heritage);
|
||||
event.set_drakkin_tattoo(spawn->drakkin_tattoo);
|
||||
event.set_drakkin_details(spawn->drakkin_details);
|
||||
event.set_showhelm(spawn->showhelm);
|
||||
event.set_unknown0140(*spawn->unknown0140);
|
||||
event.set_is_npc(spawn->is_npc);
|
||||
event.set_hairstyle(spawn->hairstyle);
|
||||
event.set_beard(spawn->beard);
|
||||
event.set_unknown0147(*spawn->unknown0147);
|
||||
event.set_level(spawn->level);
|
||||
event.set_playerstate(spawn->PlayerState);
|
||||
event.set_beardcolor(spawn->beardcolor);
|
||||
event.set_suffix(spawn->suffix);
|
||||
event.set_petownerid(spawn->petOwnerId);
|
||||
event.set_guildrank(spawn->guildrank);
|
||||
event.set_unknown0194(*spawn->unknown0194);
|
||||
|
||||
/*auto texture = eqproto::Texture();
|
||||
texture.set_elitemodel(spawn->equipment.Arms.EliteModel);
|
||||
texture.set_herosforgemodel(spawn->equipment.Arms.HerosForgeModel);
|
||||
texture.set_material(spawn->equipment.Arms.Material);
|
||||
texture.set_unknown1(spawn->equipment.Arms.Unknown1);
|
||||
texture.set_unknown2(spawn->equipment.Arms.Unknown2);
|
||||
event.set_allocated_equipment(textureProfile);*/
|
||||
event.set_runspeed(spawn->runspeed);
|
||||
event.set_afk(spawn->afk);
|
||||
event.set_guildid(spawn->guildID);
|
||||
event.set_title(spawn->title);
|
||||
event.set_unknown0274(spawn->unknown0274);
|
||||
event.set_set_to_0xff(*spawn->set_to_0xFF);
|
||||
event.set_helm(spawn->helm);
|
||||
event.set_race(spawn->race);
|
||||
event.set_unknown0288(spawn->unknown0288);
|
||||
event.set_lastname(spawn->lastName);
|
||||
event.set_walkspeed(spawn->walkspeed);
|
||||
event.set_unknown0328(spawn->unknown0328);
|
||||
event.set_is_pet(spawn->is_pet);
|
||||
event.set_light(spawn->light);
|
||||
event.set_class_(spawn->class_);
|
||||
event.set_eyecolor2(spawn->eyecolor2);
|
||||
event.set_flymode(spawn->flymode);
|
||||
event.set_gender(spawn->gender);
|
||||
event.set_bodytype(spawn->bodytype);
|
||||
event.set_unknown0336(*spawn->unknown0336);
|
||||
event.set_equip_chest2(spawn->equip_chest2);
|
||||
event.set_mount_color(spawn->mount_color);
|
||||
event.set_spawnid(spawn->spawnId);
|
||||
event.set_unknown0344(*spawn->unknown0344);
|
||||
event.set_ismercenary(spawn->IsMercenary);
|
||||
//event.set_equipment_tint(spawn->equipment_tint);
|
||||
event.set_lfg(spawn->lfg);
|
||||
event.set_destructibleobject(spawn->DestructibleObject);
|
||||
event.set_destructiblemodel(spawn->DestructibleModel);
|
||||
event.set_destructiblename2(spawn->DestructibleName2);
|
||||
event.set_destructiblestring(spawn->DestructibleString);
|
||||
event.set_destructibleappearance(spawn->DestructibleAppearance);
|
||||
event.set_destructibleunk1(spawn->DestructibleUnk1);
|
||||
event.set_destructibleid1(spawn->DestructibleID1);
|
||||
event.set_destructibleid2(spawn->DestructibleID2);
|
||||
event.set_destructibleid3(spawn->DestructibleID3);
|
||||
event.set_destructibleid4(spawn->DestructibleID4);
|
||||
event.set_destructibleunk2(spawn->DestructibleUnk2);
|
||||
event.set_destructibleunk3(spawn->DestructibleUnk3);
|
||||
event.set_destructibleunk4(spawn->DestructibleUnk4);
|
||||
event.set_destructibleunk5(spawn->DestructibleUnk5);
|
||||
event.set_destructibleunk6(spawn->DestructibleUnk6);
|
||||
event.set_destructibleunk7(spawn->DestructibleUnk7);
|
||||
event.set_destructibleunk8(spawn->DestructibleUnk8);
|
||||
event.set_destructibleunk9(spawn->DestructibleUnk9);
|
||||
event.set_targetable_with_hotkey(spawn->targetable_with_hotkey);
|
||||
event.set_show_name(spawn->show_name);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
if (op == OP_ZoneEntry) finalEvent.set_op(eqproto::OP_ZoneEntry);
|
||||
else if (op == OP_NewSpawn) finalEvent.set_op(eqproto::OP_NewSpawn);
|
||||
else { Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); return; }
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
|
||||
void NatsManager::OnWearChangeEvent(uint32 entity_id, WearChange_Struct *wc) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::WearChangeEvent();
|
||||
|
||||
|
||||
event.set_spawn_id(wc->spawn_id);
|
||||
event.set_material(wc->material);
|
||||
event.set_unknown06(wc->unknown06);
|
||||
event.set_elite_material(wc->elite_material);
|
||||
event.set_hero_forge_model(wc->hero_forge_model);
|
||||
event.set_unknown18(wc->unknown18);
|
||||
//event.set_color(wc->color); //tint
|
||||
event.set_wear_slot_id(wc->wear_slot_id);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_WearChange);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
void NatsManager::OnDeleteSpawnEvent(uint32 entity_id, DeleteSpawn_Struct *ds) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::DeleteSpawnEvent();
|
||||
|
||||
|
||||
event.set_spawn_id(ds->spawn_id);
|
||||
event.set_decay(ds->Decay);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_DeleteSpawn);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
void NatsManager::OnHPEvent(const EmuOpcode op, uint32 entity_id, uint32 cur_hp, uint32 max_hp) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
if (cur_hp == max_hp) return;
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::HPEvent();
|
||||
|
||||
event.set_spawn_id(entity_id);
|
||||
event.set_cur_hp(cur_hp);
|
||||
event.set_max_hp(max_hp);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
if (op == OP_MobHealth) finalEvent.set_op(eqproto::OP_MobHealth);
|
||||
else if (op == OP_HPUpdate) finalEvent.set_op(eqproto::OP_HPUpdate);
|
||||
else { Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); return; }
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
void NatsManager::OnDamageEvent(uint32 entity_id, CombatDamage_Struct *cd) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::DamageEvent();
|
||||
|
||||
event.set_target(cd->target);
|
||||
event.set_source(cd->source);
|
||||
event.set_type(cd->type);
|
||||
event.set_spellid(cd->spellid);
|
||||
event.set_damage(cd->damage);
|
||||
event.set_force(cd->force);
|
||||
event.set_meleepush_xy(cd->meleepush_xy);
|
||||
event.set_meleepush_z(cd->meleepush_z);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_Damage);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
void NatsManager::OnClientUpdateEvent(uint32 entity_id, PlayerPositionUpdateServer_Struct * spu) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::PlayerPositionUpdateEvent();
|
||||
|
||||
event.set_spawn_id(spu->spawn_id);
|
||||
event.set_delta_heading(spu->delta_heading);
|
||||
event.set_x_pos(spu->x_pos);
|
||||
event.set_padding0002(spu->padding0002);
|
||||
event.set_y_pos(spu->y_pos);
|
||||
event.set_animation(spu->animation);
|
||||
event.set_padding0006(spu->padding0006);
|
||||
event.set_z_pos(spu->z_pos);
|
||||
event.set_delta_y(spu->delta_y);
|
||||
event.set_delta_x(spu->delta_x);
|
||||
event.set_heading(spu->heading);
|
||||
event.set_padding0014(spu->padding0014);
|
||||
event.set_delta_z(spu->delta_z);
|
||||
event.set_padding0018(spu->padding0018);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_ClientUpdate);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
|
||||
|
||||
void NatsManager::OnAnimationEvent(uint32 entity_id, Animation_Struct *anim) {
|
||||
if (!connect()) return;
|
||||
if (entity_id == 0) return;
|
||||
if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return;
|
||||
|
||||
std::string pubMessage;
|
||||
auto event = eqproto::AnimationEvent();
|
||||
|
||||
event.set_spawnid(anim->spawnid);
|
||||
event.set_speed(anim->speed);
|
||||
event.set_action(anim->action);
|
||||
|
||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
auto finalEvent = eqproto::Event();
|
||||
finalEvent.set_payload(pubMessage.c_str());
|
||||
finalEvent.set_op(eqproto::OP_Animation);
|
||||
if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||
s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length());
|
||||
if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent");
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef _NATS_H
|
||||
#define _NATS_H
|
||||
#include "nats.h"
|
||||
#include "event_codes.h"
|
||||
#include "entity.h";
|
||||
#include "mob.h";
|
||||
|
||||
#include "../common/opcodemgr.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/types.h"
|
||||
|
||||
class NatsManager
|
||||
{
|
||||
public:
|
||||
NatsManager();
|
||||
~NatsManager();
|
||||
void Process();
|
||||
void Unregister();
|
||||
void ZoneSubscribe(const char * zonename);
|
||||
void Load();
|
||||
void DailyGain(int account_id, int character_id, const char * identity, int levels_gained = 0, int experience_gained = 0, int money_earned = 0);
|
||||
void OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct * cm);
|
||||
void OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 target_id);
|
||||
void OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struct * spawn);
|
||||
void OnWearChangeEvent(uint32 entity_id, WearChange_Struct * wc);
|
||||
void OnDeleteSpawnEvent(uint32 entity_id, DeleteSpawn_Struct * ds);
|
||||
void OnHPEvent(const EmuOpcode op, uint32 entity_id, uint32 cur_hp, uint32 max_hp);
|
||||
void OnDamageEvent(uint32 entity_id, CombatDamage_Struct * cd);
|
||||
void OnClientUpdateEvent(uint32 entity_id, PlayerPositionUpdateServer_Struct * spu);
|
||||
void OnAnimationEvent(uint32 entity_id, Animation_Struct * anim);
|
||||
void OnDeathEvent(Death_Struct * d);
|
||||
void SendAdminMessage(std::string adminMessage);
|
||||
protected:
|
||||
bool connect();
|
||||
Timer nats_timer;
|
||||
bool isEntitySubscribed(const uint16 ID);
|
||||
bool isEntityEventAllEnabled = true;
|
||||
natsConnection *conn = NULL;
|
||||
natsStatus s;
|
||||
natsOptions *opts = NULL;
|
||||
std::string subscribedZonename;
|
||||
//global zone subscriptions
|
||||
natsSubscription *zoneSub = NULL;
|
||||
natsSubscription *channelMessageSub = NULL;
|
||||
natsSubscription *commandMessageSub = NULL;
|
||||
//zone specific subscriptions
|
||||
natsSubscription *zoneChannelMessageSub = NULL;
|
||||
natsSubscription *zoneCommandMessageSub = NULL;
|
||||
natsSubscription *zoneEntityEventSubscribeAllSub = NULL;
|
||||
natsSubscription *zoneEntityEventSubscribeSub = NULL;
|
||||
natsSubscription *zoneEntityEventListSub = NULL;
|
||||
natsSubscription *zoneEntityEventSub = NULL;
|
||||
};
|
||||
|
||||
#endif
|
||||
+13
-3
@@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "embparser.h"
|
||||
#include "lua_parser.h"
|
||||
#include "questmgr.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#include "../common/event/event_loop.h"
|
||||
#include "../common/event/timer.h"
|
||||
@@ -100,6 +101,8 @@ WorldServer worldserver;
|
||||
uint32 numclients = 0;
|
||||
char errorname[32];
|
||||
extern Zone* zone;
|
||||
NatsManager nats;
|
||||
|
||||
npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
||||
TitleManager title_manager;
|
||||
QueryServ *QServ = 0;
|
||||
@@ -131,7 +134,7 @@ int main(int argc, char** argv) {
|
||||
std::string filename = Config->MapDir;
|
||||
filename += mapfile;
|
||||
|
||||
auto m = new Map();
|
||||
auto m = new EQEmu::Map();
|
||||
auto success = m->Load(filename, true);
|
||||
delete m;
|
||||
std::cout << mapfile.c_str() << " conversion " << (success ? "succeeded" : "failed") << std::endl;
|
||||
@@ -148,6 +151,7 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
Config = ZoneConfig::get();
|
||||
nats.Load();
|
||||
|
||||
const char *zone_name;
|
||||
uint32 instance_id = 0;
|
||||
@@ -510,10 +514,14 @@ int main(int argc, char** argv) {
|
||||
entity_list.MobProcess();
|
||||
entity_list.BeaconProcess();
|
||||
entity_list.EncounterProcess();
|
||||
|
||||
if (zone->IsLoaded()) {
|
||||
nats.ZoneSubscribe(zone->GetShortName());
|
||||
nats.Process();
|
||||
}
|
||||
if (zone) {
|
||||
if (!zone->Process()) {
|
||||
Zone::Shutdown();
|
||||
nats.Unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,8 +579,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
safe_delete(Config);
|
||||
|
||||
if (zone != 0)
|
||||
if (zone != 0) {
|
||||
Zone::Shutdown(true);
|
||||
nats.Unregister();
|
||||
}
|
||||
//Fix for Linux world server problem.
|
||||
safe_delete(taskmanager);
|
||||
command_deinit();
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "quest_parser_collection.h"
|
||||
#include "string_ids.h"
|
||||
#include "worldserver.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -42,6 +43,7 @@
|
||||
extern Zone* zone;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern NatsManager nats;
|
||||
|
||||
|
||||
// the spell can still fail here, if the buff can't stack
|
||||
@@ -936,6 +938,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
Save();
|
||||
safe_delete(action_packet);
|
||||
safe_delete(message_packet);
|
||||
nats.OnDamageEvent(cd->source, cd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -987,6 +990,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
Save();
|
||||
safe_delete(action_packet);
|
||||
safe_delete(message_packet);
|
||||
nats.OnDamageEvent(cd->source, cd);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1025,6 +1029,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
Save();
|
||||
safe_delete(action_packet);
|
||||
safe_delete(message_packet);
|
||||
nats.OnDamageEvent(cd->source, cd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -81,6 +81,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
#include "quest_parser_collection.h"
|
||||
#include "string_ids.h"
|
||||
#include "worldserver.h"
|
||||
#include "nats_manager.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
@@ -104,6 +105,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
extern Zone* zone;
|
||||
extern volatile bool is_zone_loaded;
|
||||
extern WorldServer worldserver;
|
||||
extern NatsManager nats;
|
||||
|
||||
using EQEmu::CastingSlot;
|
||||
|
||||
@@ -252,6 +254,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
||||
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!",
|
||||
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
|
||||
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item with an invalid class");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s: Clicking equip-only item with an invalid class.", GetCleanName()));
|
||||
}
|
||||
else {
|
||||
Message_StringID(13, MUST_EQUIP_ITEM);
|
||||
@@ -264,6 +267,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
||||
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!",
|
||||
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
|
||||
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking race/class restricted item with an invalid class");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s: Clicking race/class restricted item with invalid class.", GetCleanName()));
|
||||
}
|
||||
else {
|
||||
if (CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
|
||||
@@ -284,6 +288,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
||||
// They are attempting to cast a must equip clicky without having it equipped
|
||||
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
|
||||
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s: Clicking equip-only item without equipping it.", GetCleanName()));
|
||||
}
|
||||
else {
|
||||
Message_StringID(13, MUST_EQUIP_ITEM);
|
||||
@@ -2727,7 +2732,7 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) {
|
||||
}
|
||||
safe_delete(message_packet);
|
||||
safe_delete(packet);
|
||||
|
||||
nats.OnDamageEvent(cd->source, cd);
|
||||
}
|
||||
//we are done...
|
||||
return;
|
||||
@@ -4047,7 +4052,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
||||
);
|
||||
}
|
||||
safe_delete(action_packet);
|
||||
safe_delete(message_packet);
|
||||
safe_delete(message_packet);
|
||||
nats.OnDamageEvent(cd->source, cd);
|
||||
|
||||
Log(Logs::Detail, Logs::Spells, "Cast of %d by %s on %s complete successfully.", spell_id, GetName(), spelltar->GetName());
|
||||
|
||||
|
||||
+3
-1
@@ -25,7 +25,7 @@
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
#include "mob.h"
|
||||
|
||||
#include "nats_manager.h"
|
||||
#include "quest_parser_collection.h"
|
||||
#include "string_ids.h"
|
||||
#include "worldserver.h"
|
||||
@@ -34,6 +34,7 @@ class QueryServ;
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern QueryServ* QServ;
|
||||
extern NatsManager nats;
|
||||
|
||||
// The maximum amount of a single bazaar/barter transaction expressed in copper.
|
||||
// Equivalent to 2 Million plat
|
||||
@@ -1658,6 +1659,7 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic
|
||||
|
||||
if(!TakeMoneyFromPP(TotalCost)) {
|
||||
database.SetHackerFlag(account_name, name, "Attempted to buy something in bazaar but did not have enough money.");
|
||||
nats.SendAdminMessage(StringFormat("Hacker %s: Attempted to buy something in bazaar but did not have enough money.", GetCleanName()));
|
||||
TradeRequestFailed(app);
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
#include "mob.h"
|
||||
#include "nats_manager.h"
|
||||
#include "trap.h"
|
||||
|
||||
extern NatsManager nats;
|
||||
/*
|
||||
|
||||
Schema:
|
||||
@@ -219,6 +221,7 @@ void Trap::Trigger(Mob* trigger)
|
||||
a->type = 253;
|
||||
trigger->CastToClient()->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
nats.OnDamageEvent(a->source, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -891,7 +891,7 @@ bool Zone::Init(bool iStaticZone) {
|
||||
}
|
||||
}
|
||||
|
||||
zone->zonemap = Map::LoadMapFile(zone->map_name);
|
||||
zone->zonemap = EQEmu::Map::LoadMapFile(zone->map_name);
|
||||
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
|
||||
zone->pathing = PathManager::LoadPathFile(zone->map_name);
|
||||
|
||||
|
||||
+1
-1
@@ -211,7 +211,7 @@ public:
|
||||
void ReloadWorld(uint32 Option);
|
||||
void ReloadMerchants();
|
||||
|
||||
Map* zonemap;
|
||||
EQEmu::Map* zonemap;
|
||||
WaterMap* watermap;
|
||||
PathManager *pathing;
|
||||
NewZone_Struct newzone_data;
|
||||
|
||||
Reference in New Issue
Block a user