Added lua/perl support for nats AdminMessage, added more response fields

This commit is contained in:
Xackery 2018-03-17 18:45:31 -07:00
parent 825dbc9e9a
commit 6a25f30441
7 changed files with 273 additions and 128 deletions

View File

@ -16,22 +16,28 @@ message ChannelMessage {
int32 minstatus = 9;
int32 fromadmin = 10;
bool noreply = 11;
bool is_emote = 12;
//0 not queued, 1 queued, 2 queue full, 3 offline
int32 queued = 13;
string result = 15; //Result of channel request. 1 = Success, Non-numeric = error
bool is_emote = 12; //Is message considered an emote?
int32 queued = 13; //only used on channel_message.out events. (*.in uses response_message): 0 not queued, 1 queued, 2 queue full, 3 offline
int32 from_entity_id = 16; //(Only in zone requests) Entity to send message from
EntityType from_entity_type = 17; //(Only in zone requests) Entity type the message is from
float distance = 18; //(optional, only in zone requests) how far should the message travel? (e.g. say)
bool skip_sender = 19; //(optional, only in zone requests) should we skip sender?
string response_message = 20; //Human-readable response message of request.
int32 response_value = 21; //Response value. In cases where a single value is returned, this is utilized (like an entity id)
ErrorType response_error = 22; //error (if any), ERR_OK (0) is default
string response_type = 23; //defines what message type the response_payload is
bytes response_payload = 24; //binary payload to be parsed using response_type
}
message CommandMessage {
string author = 1; //Author of command. This can typically be ignored
string command = 2; //command to request
repeated string params = 3; //Parameters are an array of strings.
string result = 4; //Result of command request. If non-numeric, it is an error message. If it's an integer, and greater than 0, it is a success (1 is default. Some commands return entity id)
bytes payload = 5; //Raw Payload to be parsed
repeated string params = 3; //Parameters are an array of strings.
string response_message = 4; //Human-readable response message of request.
int32 response_value = 5; //Response value. In cases where a single value is returned, this is utilized (like an entity id)
ErrorType response_error = 6; //error (if any), ERR_OK (0) is default
string response_type = 7; //defines what message type the response_payload is
bytes response_payload = 8; //binary payload to be parsed using response_type
}
//Entity is full of entity data.
@ -447,6 +453,14 @@ message UseAAEvent {
uint32 exp_value = 6;
}
enum ErrorType {
ERR_OK = 0; //OK, No error provided
ERR_Request = 1; //Request data has something wrong. See response_message for more details.
ERR_Internal = 2; //Internal server error. See response message for mode details
ERR_Failed = 3; //Failed request. This is when the request succeeds, there are no internal server errors, but the response is a failure.
}
//EntityType will attempt to identify an entity to it's upper-most type by default
enum EntityType {
NPC = 0; //Inherits mob
@ -514,7 +528,8 @@ enum MessageType {
BrightBlue = 3; // FF|0040FF
Magenta = 5; // FF|F000F0
Gray = 6; // FF|808080
LightGray = 7; // FF|E0E0E0
LightGray = 7; // FF|E0E0E0 , also tell?
SayLocal = 8; //Say when you say it?
WhiteSmoke2 = 10; // FF|F0F0F0
DarkGray = 12; // FF|A0A0A0
Red= 13; // FF|F00000

View File

@ -4,12 +4,12 @@ package main
import (
"fmt"
"log"
"strconv"
"time"
"github.com/eqemu/server/protobuf/go/eqproto"
"github.com/golang/protobuf/proto"
"github.com/nats-io/go-nats"
"github.com/pkg/errors"
)
var (
@ -28,7 +28,9 @@ func main() {
zone := "ecommons"
instance := int64(0)
entities = zoneEntityList(zone, 0)
if len(entities) == 0 {
return
}
fmt.Println(len(entities), "entities known")
//fmt.Println(entities)
@ -45,35 +47,82 @@ func main() {
}
go asyncChannelMessageSubscriber(nc) //async is recommended
go entityEventSubscriber(zone, instance, entityID)
zoneChannel(zone, instance, entityID, eqproto.EntityType_Client, eqproto.MessageType_Say, "Hello, World!")
err := zoneChannelMessage(zone, instance, entityID, eqproto.EntityType_Client, eqproto.MessageType_Say, "Hello, World!")
//err := tell("shin", "Testing tell")
if err != nil {
fmt.Println("Failed to send channel message:", err.Error())
return
}
time.Sleep(1000 * time.Second)
}
func zoneChannel(zone string, instance int64, fromEntityID int32, fromEntityType eqproto.EntityType, chanNumber eqproto.MessageType, message string) {
func tell(to string, message string) (err error) {
msg := &eqproto.ChannelMessage{
Message: message,
Number: chanNumber,
FromEntityId: fromEntityID,
FromEntityType: fromEntityType,
Distance: 500,
SkipSender: true,
Message: message,
From: "go",
To: to,
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
channel := fmt.Sprintf("zone.%s.channel_message.in", zone)
log.Println(channel, "sending channel request", msg)
channel := fmt.Sprintf("world.channel_message.in")
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
log.Println("Failed to get request response on zone channel:", err.Error())
err = errors.Wrap(err, "Failed to get request response on zone channel")
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
err = errors.Wrap(err, "failed to unmarshal")
return
}
if msg.ResponseError > 0 {
err = errors.New(msg.ResponseMessage)
return
}
fmt.Println("Response:", msg)
return
}
func zoneChannelMessage(zone string, instance int64, fromEntityID int32, fromEntityType eqproto.EntityType, chanNumber eqproto.MessageType, message string) (err error) {
msg := &eqproto.ChannelMessage{
Message: message,
Number: eqproto.MessageType_SayLocal, //chanNumber,
FromEntityId: fromEntityID,
FromEntityType: fromEntityType,
From: "go",
Distance: 500,
SkipSender: false,
//To: "shin",
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
channel := fmt.Sprintf("zone.%s.%d.channel_message.in", zone, instance)
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
err = errors.Wrap(err, "Failed to get request response on zone channel")
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
err = errors.Wrap(err, "failed to unmarshal")
return
}
if msg.ResponseError > 0 {
err = errors.New(msg.ResponseMessage)
return
}
fmt.Println("Response:", msg)
@ -107,7 +156,7 @@ func zoneEntityList(zone string, instanceID int) (entities []*eqproto.Entity) {
channel := fmt.Sprintf("zone.%s.command_message.in", zone)
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
log.Println("Failed to get response on", channel, "", err.Error())
log.Println("Failed to get response on", channel, err.Error())
return
}
@ -116,15 +165,14 @@ func zoneEntityList(zone string, instanceID int) (entities []*eqproto.Entity) {
fmt.Println("Failed to unmarshal", err.Error())
return
}
if msg.Result != "1" {
fmt.Println("Failed response: ", msg.Result)
if msg.ResponseError > 0 {
fmt.Println("Failed to get entity list:", msg.ResponseError, msg.ResponseMessage)
return
}
//fmt.Println("reply", len(msg.Payload), string(msg.Payload))
rootEntities := &eqproto.Entities{}
err = proto.Unmarshal([]byte(msg.Payload), rootEntities)
err = proto.Unmarshal([]byte(msg.ResponsePayload), rootEntities)
if err != nil {
fmt.Println("failed to unmarshal entities", err.Error(), msg)
return
@ -133,7 +181,7 @@ func zoneEntityList(zone string, instanceID int) (entities []*eqproto.Entity) {
return
}
func zoneCommandEntity(zone string, command string, params []string) (entityID int64) {
func zoneCommandEntity(zone string, command string, params []string) (entityID int32) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: command,
@ -154,12 +202,13 @@ func zoneCommandEntity(zone string, command string, params []string) (entityID i
fmt.Println("Failed to unmarshal", err.Error())
return
}
fmt.Println("Response:", msg)
entityID, err = strconv.ParseInt(msg.Result, 10, 64)
if err != nil {
fmt.Println("Failed to parse response", err.Error(), msg.Result)
//fmt.Println("Response:", msg)
if msg.ResponseError > 0 {
fmt.Println("Failed to get response:", msg.ResponseError, msg.ResponseMessage)
return
}
entityID = msg.ResponseValue
return
}
@ -190,20 +239,6 @@ func zoneCommand(zone string, command string, params []string) {
func entityEventSubscriber(zone string, instance int64, entityID int32) {
/*event := &eqproto.EntityEvent{
Entity: &eqproto.Entity{
Id: 1,
},
}
d, err := proto.Marshal(event)
if err != nil {
log.Fatal(err)
}
if err = nc.Publish(fmt.Sprintf("zone.%s.entity.event_subscribe.all", zone), d); err != nil {
log.Println("Failed to publish event subscribe:", err.Error())
return
}*/
var index int
channel := fmt.Sprintf("zone.%s.%d.entity.%d.event.out", zone, instance, entityID)
@ -212,6 +247,7 @@ func entityEventSubscriber(zone string, instance int64, entityID int32) {
err = proto.Unmarshal(m.Data, event)
if err != nil {
fmt.Println("invalid event data passed", m.Data)
return
}
var eventPayload proto.Message

View File

@ -3,6 +3,7 @@
#include "zonelist.h"
#include "login_server_list.h"
#include "clientlist.h"
#include "cliententry.h"
#include "worlddb.h"
#include <google/protobuf/arena.h>
@ -98,7 +99,7 @@ void NatsManager::Process()
break;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
if (!message->ParseFromString(natsMsg_GetData(msg))) {
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "world.channel_message.in: failed to parse");
natsMsg_Destroy(msg);
continue;
@ -115,11 +116,11 @@ void NatsManager::Process()
break;
eqproto::CommandMessage* message = google::protobuf::Arena::CreateMessage<eqproto::CommandMessage>(&the_arena);
if (!message->ParseFromString(natsMsg_GetData(msg))) {
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "world.command_message.in: failed to parse");
natsMsg_Destroy(msg);
continue;
}
}
GetCommandMessage(message, natsMsg_GetReply(msg));
}
}
@ -191,10 +192,6 @@ void NatsManager::SendCommandMessage(eqproto::CommandMessage* message, const cha
if (!connect())
return;
if (message->result().length() <= 1)
message->set_result("Failed to parse command.");
size_t event_size = message->ByteSizeLong();
void *event_buffer = malloc(event_size);
if (!message->SerializeToArray(event_buffer, event_size)) {
@ -209,11 +206,11 @@ void NatsManager::SendCommandMessage(eqproto::CommandMessage* message, const cha
s = natsConnection_Publish(conn, "world.command_message.out", event_buffer, event_size);
if (s != NATS_OK) {
Log(Logs::General, Logs::NATS, "world.command_message.out failed: %s");
Log(Logs::General, Logs::NATS, "world.command_message.out failed: %s", nats_GetLastError(&s));
return;
}
Log(Logs::General, Logs::NATS, "world.command_message.in: %s (%s)", message->command().c_str(), message->result().c_str());
Log(Logs::General, Logs::NATS, "world.command_message.in: %s (%d: %s)", message->command().c_str(), message->response_error(), message->response_message().c_str());
}
// GetCommandMessage is used to process a command message
@ -222,7 +219,7 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
return;
if (message->command().compare("who") == 0) {
message->set_result(client_list.GetWhoAll());
message->set_response_message(client_list.GetWhoAll());
SendCommandMessage(message, reply);
return;
}
@ -231,7 +228,7 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
WorldConfig::UnlockWorld();
if (loginserverlist.Connected())
loginserverlist.SendStatus();
message->set_result("Server is now unlocked.");
message->set_response_message("Server is now unlocked.");
SendCommandMessage(message, reply);
return;
}
@ -240,7 +237,7 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
WorldConfig::LockWorld();
if (loginserverlist.Connected())
loginserverlist.SendStatus();
message->set_result("Server is now locked.");
message->set_response_message("Server is now locked.");
SendCommandMessage(message, reply);
return;
}
@ -250,26 +247,27 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
uint32 interval=0;
if(message->params_size() == 2 && ((time=atoi(message->params(0).c_str()))>0) && ((interval=atoi(message->params(1).c_str()))>0)) {
message->set_result(StringFormat("Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval));
message->set_response_message(StringFormat("Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval));
zoneserver_list.WorldShutDown(time, interval);
SendCommandMessage(message, reply);
return;
}
else if(strcasecmp(message->params(0).c_str(), "now") == 0){
message->set_result("Sending shutdown packet now");
message->set_response_message("Sending shutdown packet now");
zoneserver_list.WorldShutDown(0, 0);
SendCommandMessage(message, reply);
return;
}
else if(strcasecmp(message->params(0).c_str(), "disable") == 0){
message->set_result("Shutdown prevented, next time I may not be so forgiving...");
message->set_response_message("Shutdown prevented, next time I may not be so forgiving...");
zoneserver_list.SendEmoteMessage(0, 0, 0, 15, "<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World shutdown aborted.");
zoneserver_list.shutdowntimer->Disable();
zoneserver_list.reminder->Disable();
SendCommandMessage(message, reply);
return;
}
message->set_result("worldshutdown - Shuts down the server and all zones.\n \
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("worldshutdown - Shuts down the server and all zones.\n \
Usage: worldshutdown now - Shuts down the server and all zones immediately.\n \
Usage: worldshutdown disable - Stops the server from a previously scheduled shut down.\n \
Usage: worldshutdown [timer] [interval] - Shuts down the server and all zones after [timer] seconds and sends warning every [interval] seconds\n");
@ -277,7 +275,8 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
return;
}
message->set_result("unknown command sent");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Unknown command");
SendCommandMessage(message, reply);
return;
}
@ -289,21 +288,60 @@ void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char
if (message->is_emote()) { //emote message
zoneserver_list.SendEmoteMessage(message->to().c_str(), message->guilddbid(), message->minstatus(), message->type(), message->message().c_str());
message->set_result("Sent message");
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
//normal broadcast
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], message->from().c_str());
//TODO: add To support on tells
char from[64];
from[0] = '*';
strcpy(&from[1], message->from().c_str());
int channel = message->number();
if (channel < 1)
if (channel < 1) {
channel = MT_OOC; //default to ooc
zoneserver_list.SendChannelMessage(tmpname, 0, channel, message->language(), message->message().c_str());
message->set_result("1");
message->set_number(eqproto::OOC);
}
if (message->to().length() == 0) { //Send a world message
zoneserver_list.SendChannelMessage(from, 0, channel, message->language(), message->message().c_str());
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
//Send a tell
channel = 7; //tells are always echo
message->set_number(static_cast<eqproto::MessageType>(7));
ClientListEntry* cle = client_list.FindCharacter(message->to().c_str());
if (cle == 0 || cle->Online() < CLE_Status_Zoning ||
(cle->TellsOff() && ((cle->Anon() == 1 && message->fromadmin() < cle->Admin()) || message->fromadmin() < 80))) {
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("Player is offline");
SendChannelMessage(message, reply);
return;
}
if (cle->Online() == CLE_Status_Zoning) {
if (cle->TellQueueFull()) {
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("Queue is full");
SendChannelMessage(message, reply);
return;
}
//This should succeed in going into a tell queue, since it doesn't return we have to detect above
zoneserver_list.SendChannelMessage(from, message->to().c_str(), channel, message->language(), message->message().c_str());
message->set_response_message("Player is zoning, tell is queued");
SendChannelMessage(message, reply);
return;
}
zoneserver_list.SendChannelMessage(from, message->to().c_str(), channel, message->language(), message->message().c_str());
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
@ -334,7 +372,7 @@ void NatsManager::SendChannelMessage(eqproto::ChannelMessage* message, const cha
}
if (reply)
Log(Logs::General, Logs::NATS, "world.channel_message.in: %s (%s)", message->message().c_str(), message->result().c_str());
Log(Logs::General, Logs::NATS, "world.channel_message.in: %s (%d: %s)", message->message().c_str(), message->response_error(), message->response_message().c_str());
else
Log(Logs::General, Logs::NATS, "world.channel_message.out: %s", message->message().c_str());
}

View File

@ -31,9 +31,11 @@
#include "queryserv.h"
#include "questmgr.h"
#include "zone.h"
#include "nats_manager.h"
extern Zone* zone;
extern QueryServ* QServ;
extern NatsManager nats;
/*
@ -2882,6 +2884,21 @@ XS(XS__varlink) {
XSRETURN(1);
}
XS(XS__adminmessage); // prototype to pass -Wmissing-prototypes
XS(XS__adminmessage) {
dXSARGS;
if (items == 1)
nats.SendAdminMessage(SvPV_nolen(ST(0)));
else if (items == 2)
nats.SendAdminMessage(SvPV_nolen(ST(0)), (int)SvIV(ST(1)));
else
Perl_croak(aTHX_ "Usage: adminmessage(message [, min_status])");
XSRETURN_EMPTY;
}
XS(XS__CreateInstance);
XS(XS__CreateInstance) {
dXSARGS;
@ -3766,6 +3783,7 @@ EXTERN_C XS(boot_quest)
newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file);
newXS(strcpy(buf, "addloot"), XS__addloot, file);
newXS(strcpy(buf, "addskill"), XS__addskill, file);
newXS(strcpy(buf, "adminmessage"), XS__adminmessage, file);
newXS(strcpy(buf, "assigntask"), XS__assigntask, file);
newXS(strcpy(buf, "attack"), XS__attack, file);
newXS(strcpy(buf, "attacknpc"), XS__attacknpc, file);

View File

@ -22,6 +22,7 @@
#include "qglobals.h"
#include "encounter.h"
#include "lua_encounter.h"
#include "nats_manager.h"
struct Events { };
struct Factions { };
@ -45,6 +46,7 @@ struct lua_registered_event {
extern std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
extern std::map<std::string, bool> lua_encounters_loaded;
extern std::map<std::string, Encounter *> lua_encounters;
extern NatsManager nats;
extern void MapOpcodes();
extern void ClearMappedOpcode(EmuOpcode op);
@ -1320,6 +1322,10 @@ void lua_debug(std::string message, int level) {
Log(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
}
void lua_adminmessage(std::string message) {
nats.SendAdminMessage(message);
}
void lua_update_zone_header(std::string type, std::string value) {
quest_manager.UpdateZoneHeader(type, value);
}
@ -1698,8 +1704,9 @@ luabind::scope lua_register_general() {
luabind::def("reloadzonestaticdata", &lua_reloadzonestaticdata),
luabind::def("clock", &lua_clock),
luabind::def("create_npc", &lua_create_npc),
luabind::def("debug", (void(*)(std::string))&lua_debug),
luabind::def("debug", (void(*)(std::string, int))&lua_debug)
luabind::def("debug", (void(*)(std::string))&lua_debug),
luabind::def("debug", (void(*)(std::string, int))&lua_debug),
luabind::def("adminmessage", &lua_adminmessage)
];
}

View File

@ -58,7 +58,7 @@ void NatsManager::Process()
break;
eqproto::CommandMessage* message = google::protobuf::Arena::CreateMessage<eqproto::CommandMessage>(&the_arena);
if (!message->ParseFromString(natsMsg_GetData(msg))) {
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "zone.%s.command_message.in: failed to parse", subscribedZoneName.c_str());
natsMsg_Destroy(msg);
continue;
@ -75,7 +75,7 @@ void NatsManager::Process()
break;
eqproto::CommandMessage* message = google::protobuf::Arena::CreateMessage<eqproto::CommandMessage>(&the_arena);
if (!message->ParseFromString(natsMsg_GetData(msg))) {
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "zone.%s.%dcommand_message.in: failed to parse", subscribedZoneName.c_str(), subscribedZoneInstance);
natsMsg_Destroy(msg);
continue;
@ -92,7 +92,7 @@ void NatsManager::Process()
break;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
if (!message->ParseFromString(natsMsg_GetData(msg))) {
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "zone.%s.channel_message.in: failed to parse", subscribedZoneName.c_str());
natsMsg_Destroy(msg);
continue;
@ -109,7 +109,7 @@ void NatsManager::Process()
break;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
if (!message->ParseFromString(natsMsg_GetData(msg))) {
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message.in: failed to parse", subscribedZoneName.c_str(), subscribedZoneInstance);
natsMsg_Destroy(msg);
continue;
@ -125,7 +125,8 @@ void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char
return;
if (message->from_entity_id() < 1) {
message->set_result("from_entity_id must be set to send zone channel messages.");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("from_entity_id must be set to send zone channel messages.");
SendChannelMessage(message, reply);
return;
}
@ -133,7 +134,8 @@ void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char
auto mob = entity_list.GetMobID(message->from_entity_id());
if (!mob) {
message->set_result("from_entity_id not found");
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("mob from_entity_id not found");
SendChannelMessage(message, reply);
return;
}
@ -143,7 +145,8 @@ void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char
else
mob->Message(message->number(), message->message().c_str());
message->set_result("1");
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
@ -173,7 +176,7 @@ void NatsManager::SendChannelMessage(eqproto::ChannelMessage* message, const cha
}
if (reply)
Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message.in: %s (%s)", subscribedZoneName.c_str(), subscribedZoneInstance, message->message().c_str(), message->result().c_str());
Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message.in: %s (%d: %s)", subscribedZoneName.c_str(), subscribedZoneInstance, message->message().c_str(), message->response_error(), message->response_message().c_str());
else
Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message.out: %s", subscribedZoneName.c_str(), subscribedZoneInstance, message->message().c_str());
}
@ -186,7 +189,8 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
if (message->command().compare("npctypespawn") == 0) {
if (message->params_size() < 2) {
message->set_result("Format: npctypespawn <x> <y> <z> <h> <npctypeid> <factionid>");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Format: npctypespawn <x> <y> <z> <h> <npctypeid> <factionid>");
SendCommandMessage(message, reply);
return;
}
@ -201,7 +205,8 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
uint32 factionid = atoi(message->params(5).c_str());
const NPCType* tmp = 0;
if (!(tmp = database.LoadNPCTypesData(npctypeid))) {
message->set_result(StringFormat("NPC Type %i not found", npctypeid));
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message(StringFormat("NPC of typied %i not found", npctypeid));
SendCommandMessage(message, reply);
return;
}
@ -210,7 +215,8 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
auto npc = new NPC(tmp, 0, position, FlyMode3);
if (!npc) {
message->set_result("failed to instantiate npc");
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("Failed to create npc");
SendCommandMessage(message, reply);
return;
}
@ -219,14 +225,16 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
npc->SetNPCFactionID(factionid);
npc->AddLootTable();
entity_list.AddNPC(npc);
message->set_result(StringFormat("%u", npc->GetID()));
message->set_response_message("Success");
message->set_response_value(npc->GetID());
SendCommandMessage(message, reply);
return;
}
if (message->command().compare("spawn") == 0) {
if (message->params_size() < 5) {
message->set_result("Format: spawn <x> <y> <z> <h> <name> <race> <level> <material> <hp> <gender> <class> <priweapon> <secweapon> <merchantid> <bodytype> - spawns a npc those parameters.");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Requires minimum 5 arguments. Format: spawn <x> <y> <z> <h> <name> <race> <level> <material> <hp> <gender> <class> <priweapon> <secweapon> <merchantid> <bodytype> - spawns a npc those parameters.");
SendCommandMessage(message, reply);
return;
}
@ -244,19 +252,22 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
NPC* npc = NPC::SpawnNPC(argumentString.c_str(), position, NULL);
if (!npc) {
message->set_result("Format: spawn <x> <y> <z> <h> <name> <race> <level> <material> <hp> <gender> <class> <priweapon> <secweapon> <merchantid> <bodytype> - spawns a npc those parameters.");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Failed to spawn npc with provided arguments.");
SendCommandMessage(message, reply);
return;
}
message->set_result(StringFormat("%u", npc->GetID()));
message->set_response_message("Success");
message->set_response_value(npc->GetID());
SendCommandMessage(message, reply);
return;
}
if (message->command().compare("moveto") == 0) {
if (message->params_size() < 5) {
message->set_result("Usage: moveto <entityid> <x> <y> <z> <h>.");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Usage: moveto <npcid> <x> <y> <z> <h>.");
SendCommandMessage(message, reply);
return;
}
@ -270,20 +281,22 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
auto npc = entity_list.GetNPCByID(entityid);
if (!npc) {
message->set_result("Invalid entity ID passed, or not an npc, etc");
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("Could not find npcid");
SendCommandMessage(message, reply);
return;
}
npc->MoveTo(position, true);
message->set_result("1");
npc->MoveTo(position, true);
message->set_response_message("Success");
SendCommandMessage(message, reply);
return;
}
if (message->command().compare("attack") == 0) {
if (message->params_size() < 3) {
message->set_result("Usage: attack <entityid> <targetentityid> <hateamount>.");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Usage: attack <entityid> <targetentityid> <hateamount>.");
SendCommandMessage(message, reply);
return;
}
@ -293,19 +306,22 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
auto npc = entity_list.GetNPCByID(entityID);
if (!npc) {
message->set_result("Invalid entity ID passed, or not an npc, etc");
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("npc ID not found");
SendCommandMessage(message, reply);
return;
}
auto mob = entity_list.GetMobID(targetEntityID);
if (!mob) {
message->set_result("Invalid target entitiy ID passed, or not a mob, etc");
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("target mob ID not found");
SendCommandMessage(message, reply);
return;
}
npc->AddToHateList(mob, hateAmount);
message->set_result("1");
message->set_response_message("Success");
message->set_response_type("CommandMessage");
SendCommandMessage(message, reply);
return;
}
@ -313,7 +329,8 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
if (message->command().compare("entitylist") == 0) {
std::string entityPayload;
if (message->params_size() < 1) {
message->set_result("Usage: entitylist <type>. Types: npc, client, mob, mercenary, corpse, door, object");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Usage: entitylist <type>. Types: npc, client, mob, mercenary, corpse, door, object");
SendCommandMessage(message, reply);
return;
}
@ -334,12 +351,14 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
@ -357,12 +376,14 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
@ -380,12 +401,14 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
@ -403,12 +426,14 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
@ -426,12 +451,14 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
@ -450,12 +477,14 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
@ -473,21 +502,25 @@ void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char
size_t size = entities->ByteSizeLong();
void *buffer = malloc(size);
if (!entities->SerializeToArray(buffer, size)) {
message->set_result("Failed to serialize entitiy result");
message->set_response_message("Failed to serialize entity result");
message->set_response_error(eqproto::ERR_Internal);
SendCommandMessage(message, reply);
return;
}
message->set_result("1");
message->set_payload(buffer, size);
message->set_response_message("Success");
message->set_response_type("CommandMessage");
message->set_response_payload(buffer, size);
SendCommandMessage(message, reply);
return;
}
message->set_result("Usage: entitylist <type>. Types: npc, client, mob, mercenary, corpse, door, object");
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Usage: entitylist <type>. Types: npc, client, mob, mercenary, corpse, door, object");
SendCommandMessage(message, reply);
return;
}
message->set_result("Failed to parse command.");
message->set_response_message("Failed to parse command.");
message->set_response_error(eqproto::ERR_Request);
SendCommandMessage(message, reply);
return;
}
@ -498,9 +531,6 @@ void NatsManager::SendCommandMessage(eqproto::CommandMessage* message, const cha
if (!connect())
return;
if (message->result().length() == 0)
message->set_result("Failed to parse command.");
size_t size = message->ByteSizeLong();
void *buffer = malloc(size);
@ -521,7 +551,7 @@ void NatsManager::SendCommandMessage(eqproto::CommandMessage* message, const cha
return;
}
Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message.in: %s (%s)", subscribedZoneName.c_str(), subscribedZoneInstance, message->command().c_str(), message->result().c_str());
Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message.in: %s (%d: %s)", subscribedZoneName.c_str(), subscribedZoneInstance, message->command().c_str(), message->response_error(), message->response_message().c_str());
}
//Unregister is called when a zone is being put to sleep or being swapped
@ -570,6 +600,7 @@ void NatsManager::Unregister()
void NatsManager::SendEvent(eqproto::OpCode op, uint32 entity_id, void * buffer, size_t size) {
eqproto::Event* event = google::protobuf::Arena::CreateMessage<eqproto::Event>(&the_arena);
event->set_payload(buffer, size);
event->set_op(op);
event->set_entity_id(entity_id);
@ -638,13 +669,13 @@ void NatsManager::ZoneSubscribe(const char* zonename, uint32 instance) {
}
void NatsManager::SendAdminMessage(std::string adminMessage) {
void NatsManager::SendAdminMessage(std::string adminMessage, int min_status) {
if (!connect())
return;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
message->set_message(adminMessage.c_str());
message->set_minstatus(min_status);
size_t size = message->ByteSizeLong();
void *buffer = malloc(size);

View File

@ -28,7 +28,7 @@ public:
void SendChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr);
void GetCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr);
void SendCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr);
void SendAdminMessage(std::string adminMessage);
void SendAdminMessage(std::string adminMessage, int min_status = 200);
void SendEvent(eqproto::OpCode op, uint32 entity_id, void * buffer, size_t size);
void OnAlternateAdvancementStats(uint32 entity_id, AltAdvStats_Struct * aas);