mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-05 12:33:51 +00:00
More work on getting remote calls up and running, added two remote calls list_zones and get_zone_info.
This commit is contained in:
parent
927580b983
commit
780789fbad
@ -91,7 +91,6 @@ SET(common_sources
|
||||
tinyxml/tinyxml.cpp
|
||||
tinyxml/tinyxmlerror.cpp
|
||||
tinyxml/tinyxmlparser.cpp
|
||||
web_interface_utils.cpp
|
||||
)
|
||||
|
||||
SET(common_headers
|
||||
@ -237,7 +236,6 @@ SET(common_headers
|
||||
StackWalker/StackWalker.h
|
||||
tinyxml/tinystr.h
|
||||
tinyxml/tinyxml.h
|
||||
web_interface_utils.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patches FILES
|
||||
|
||||
@ -186,9 +186,8 @@
|
||||
#define ServerOP_QSPlayerLogMoves 0x4014
|
||||
#define ServerOP_QSMerchantLogTransactions 0x4015
|
||||
|
||||
#define ServerOP_WIServGeneric 0x5001
|
||||
#define ServerOP_WIWorldResponse 0x5002
|
||||
#define ServerOP_WIClientRequest 0x5003
|
||||
#define ServerOP_WIRemoteCall 0x5001
|
||||
#define ServerOP_WIRemoteCallResponse 0x5002
|
||||
|
||||
enum { QSG_LFGuild = 0 };
|
||||
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
||||
@ -1233,17 +1232,6 @@ struct ReloadWorld_Struct{
|
||||
uint32 Option;
|
||||
};
|
||||
|
||||
struct WI_Client_Request_Struct{
|
||||
char Client_UUID[64];
|
||||
char JSON_Data[0];
|
||||
};
|
||||
|
||||
struct WI_Client_Response_Struct{
|
||||
char Client_UUID[64];
|
||||
char JSON_Data[0];
|
||||
};
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
@ -41,7 +41,9 @@ extern "C" {
|
||||
#include <stddef.h>
|
||||
#include <basetsd.h>
|
||||
|
||||
#ifndef strcasecmp
|
||||
#define strcasecmp stricmp
|
||||
#endif
|
||||
#define getdtablesize() 30000
|
||||
|
||||
#define LWS_VISIBLE
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(web_interface_sources
|
||||
call_handler.cpp
|
||||
method_handler.cpp
|
||||
remote_call.cpp
|
||||
web_interface.cpp
|
||||
worldserver.cpp
|
||||
)
|
||||
|
||||
SET(web_interface_headers
|
||||
call_handler.h
|
||||
method_handler.h
|
||||
remote_call.h
|
||||
worldserver.h
|
||||
)
|
||||
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
#include "web_interface.h"
|
||||
#include "call_handler.h"
|
||||
|
||||
extern std::map<std::string, CallHandler> authorized_calls;
|
||||
extern std::map<std::string, CallHandler> unauthorized_calls;
|
||||
|
||||
void register_authorized_calls()
|
||||
{
|
||||
}
|
||||
|
||||
void register_unauthorized_calls()
|
||||
{
|
||||
unauthorized_calls["token_auth"] = handle_call_token_auth;
|
||||
}
|
||||
|
||||
void register_calls()
|
||||
{
|
||||
register_authorized_calls();
|
||||
register_unauthorized_calls();
|
||||
}
|
||||
|
||||
void handle_call_token_auth(per_session_data_eqemu *session, rapidjson::Document &document)
|
||||
{
|
||||
if (!document.HasMember("token")) {
|
||||
WriteWebCallResponse(session, document, "token_missing");
|
||||
return;
|
||||
}
|
||||
|
||||
session->auth = document["token"].GetString();
|
||||
if (!CheckTokenAuthorization(session)) {
|
||||
WriteWebCallResponse(session, document, "unauthorized");
|
||||
} else {
|
||||
WriteWebCallResponse(session, document, "authorized");
|
||||
}
|
||||
}
|
||||
103
web_interface/method_handler.cpp
Normal file
103
web_interface/method_handler.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include "web_interface.h"
|
||||
#include "method_handler.h"
|
||||
#include "remote_call.h"
|
||||
|
||||
extern WorldServer *worldserver;
|
||||
extern std::map<std::string, std::pair<int, MethodHandler>> authorized_methods;
|
||||
extern std::map<std::string, MethodHandler> unauthorized_methods;
|
||||
|
||||
void register_authorized_methods()
|
||||
{
|
||||
authorized_methods["token_auth"] = std::make_pair(0, handle_method_token_auth);
|
||||
authorized_methods["list_zones"] = std::make_pair(10, handle_method_no_args);
|
||||
authorized_methods["get_zone_info"] = std::make_pair(10, handle_method_get_zone_info);
|
||||
authorized_methods["subscribe"] = std::make_pair(10, handle_method_subscribe);
|
||||
}
|
||||
|
||||
void register_unauthorized_methods()
|
||||
{
|
||||
unauthorized_methods["token_auth"] = handle_method_token_auth;
|
||||
}
|
||||
|
||||
void register_methods()
|
||||
{
|
||||
register_authorized_methods();
|
||||
register_unauthorized_methods();
|
||||
}
|
||||
|
||||
void handle_method_token_auth(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method)
|
||||
{
|
||||
if (!document.HasMember("token")) {
|
||||
WriteWebCallResponseString(session, document, "Auth token missing", true);
|
||||
return;
|
||||
}
|
||||
|
||||
session->auth = document["token"].GetString();
|
||||
if (!CheckTokenAuthorization(session)) {
|
||||
WriteWebCallResponseBoolean(session, document, "false", false);
|
||||
} else {
|
||||
WriteWebCallResponseBoolean(session, document, "true", false);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_method_no_args(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method)
|
||||
{
|
||||
CheckParams(0, "[]");
|
||||
VerifyID();
|
||||
uint32 sz = (uint32)(id.size() + session->uuid.size() + method.size() + 3 + 16);
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCall, sz);
|
||||
pack->WriteUInt32((uint32)id.size());
|
||||
pack->WriteString(id.c_str());
|
||||
pack->WriteUInt32((uint32)session->uuid.size());
|
||||
pack->WriteString(session->uuid.c_str());
|
||||
pack->WriteUInt32((uint32)method.size());
|
||||
pack->WriteString(method.c_str());
|
||||
pack->WriteUInt32(0);
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void handle_method_get_zone_info(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method)
|
||||
{
|
||||
CheckParams(1, "[zoneserver_id]");
|
||||
VerifyID();
|
||||
uint32 sz = (uint32)(id.size() + session->uuid.size() + method.size() + 3 + 16);
|
||||
auto ¶ms = document["params"];
|
||||
auto ¶m = params[(rapidjson::SizeType)0];
|
||||
if(param.IsNull()) {
|
||||
sz += 5;
|
||||
}
|
||||
else {
|
||||
sz += (uint32)strlen(param.GetString());
|
||||
sz += 5;
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCall, sz);
|
||||
pack->WriteUInt32((uint32)id.size());
|
||||
pack->WriteString(id.c_str());
|
||||
pack->WriteUInt32((uint32)session->uuid.size());
|
||||
pack->WriteString(session->uuid.c_str());
|
||||
pack->WriteUInt32((uint32)method.size());
|
||||
pack->WriteString(method.c_str());
|
||||
pack->WriteUInt32(1);
|
||||
pack->WriteUInt32((uint32)strlen(param.GetString()));
|
||||
pack->WriteString(param.GetString());
|
||||
worldserver->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void handle_method_subscribe(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method) {
|
||||
CheckParams(3, "[event, zone_id, instance_id]");
|
||||
VerifyID();
|
||||
uint32 sz = (uint32)(id.size() + session->uuid.size() + method.size() + 3 + 16);
|
||||
auto ¶ms = document["params"];
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
auto ¶m = params[i];
|
||||
if(param.IsNull()) {
|
||||
sz += 5;
|
||||
} else {
|
||||
sz += (uint32)strlen(param.GetString());
|
||||
sz += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
web_interface/method_handler.h
Normal file
51
web_interface/method_handler.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef WI_METHOD_HANDLER_H
|
||||
#define WI_METHOD_HANDLER_H
|
||||
|
||||
#define CheckParams(sz, msg) if (!document.HasMember("params")) { \
|
||||
WriteWebCallResponseString(session, document, "Missing parameters, expected: " + std::string(msg), true); \
|
||||
if (!document.HasMember("params") && sz > 0) { \
|
||||
WriteWebCallResponseString(session, document, "Missing parameters, expected: " + std::string(msg), true); \
|
||||
return; \
|
||||
} \
|
||||
auto ¶ms = document["params"]; \
|
||||
if(!params.IsArray()) { \
|
||||
WriteWebCallResponseString(session, document, "Missing parameters, expected: " + std::string(msg), true); \
|
||||
return; \
|
||||
} \
|
||||
if(params.Size() != sz) { \
|
||||
WriteWebCallResponseString(session, document, "Missing parameters, expected: " + std::string(msg), true); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define VerifyID() std::string id; \
|
||||
if (document.HasMember("id")) { \
|
||||
id = document["id"].GetString(); \
|
||||
} \
|
||||
|
||||
|
||||
void register_methods();
|
||||
void handle_method_token_auth(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method);
|
||||
void handle_method_no_args(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method);
|
||||
void handle_method_get_zone_info(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method);
|
||||
void handle_method_subscribe(per_session_data_eqemu *session, rapidjson::Document &document, std::string &method);
|
||||
|
||||
#endif
|
||||
|
||||
90
web_interface/remote_call.cpp
Normal file
90
web_interface/remote_call.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "web_interface.h"
|
||||
#include "remote_call.h"
|
||||
|
||||
void WriteWebCallResponseString(per_session_data_eqemu *session, rapidjson::Document &doc, std::string result, bool error, bool send_no_id) {
|
||||
if (doc.HasMember("id") || send_no_id) {
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
if (send_no_id) {
|
||||
writer.Null();
|
||||
}
|
||||
else {
|
||||
writer.String(doc["id"].GetString());
|
||||
}
|
||||
writer.String("result");
|
||||
writer.String(result.c_str());
|
||||
writer.String("error");
|
||||
if (error) {
|
||||
writer.Bool(true);
|
||||
}
|
||||
else {
|
||||
writer.Null();
|
||||
}
|
||||
writer.EndObject();
|
||||
session->send_queue->push_back(s.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
void WriteWebCallResponseInt(per_session_data_eqemu *session, rapidjson::Document &doc, int result, bool error, bool send_no_id) {
|
||||
if (doc.HasMember("id") || send_no_id) {
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
if (send_no_id) {
|
||||
writer.Null();
|
||||
}
|
||||
else {
|
||||
writer.String(doc["id"].GetString());
|
||||
}
|
||||
writer.String("result");
|
||||
writer.Int(result);
|
||||
writer.String("error");
|
||||
if (error) {
|
||||
writer.Bool(true);
|
||||
}
|
||||
else {
|
||||
writer.Null();
|
||||
}
|
||||
writer.EndObject();
|
||||
session->send_queue->push_back(s.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
void WriteWebCallResponseBoolean(per_session_data_eqemu *session, rapidjson::Document &doc, bool result, bool error, bool send_no_id) {
|
||||
if (doc.HasMember("id") || send_no_id) {
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
if (send_no_id) {
|
||||
writer.Null();
|
||||
}
|
||||
else {
|
||||
writer.String(doc["id"].GetString());
|
||||
}
|
||||
writer.String("result");
|
||||
writer.Bool(result);
|
||||
writer.String("error");
|
||||
if (error) {
|
||||
writer.Bool(true);
|
||||
}
|
||||
else {
|
||||
writer.Null();
|
||||
}
|
||||
writer.EndObject();
|
||||
session->send_queue->push_back(s.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
int CheckTokenAuthorization(per_session_data_eqemu *session) {
|
||||
//todo: actually check this against a table of tokens that is updated periodically
|
||||
//right now i have just one entry harded coded for testing purposes
|
||||
if (session->auth.compare("c5b80ec8-4174-4c4c-d332-dbf3c3a551fc") == 0) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -15,11 +15,13 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef WI_CALL_HANDLER_H
|
||||
#define WI_CALL_HANDLER_H
|
||||
#ifndef WI_RPC_H
|
||||
#define WI_RPC_H
|
||||
|
||||
void register_calls();
|
||||
void handle_call_token_auth(per_session_data_eqemu *session, rapidjson::Document &document);
|
||||
void WriteWebCallResponseString(per_session_data_eqemu *session, rapidjson::Document &doc, std::string result, bool error, bool send_no_id = false);
|
||||
void WriteWebCallResponseInt(per_session_data_eqemu *session, rapidjson::Document &doc, int result, bool error, bool send_no_id = false);
|
||||
void WriteWebCallResponseBoolean(per_session_data_eqemu *session, rapidjson::Document &doc, bool result, bool error, bool send_no_id = false);
|
||||
int CheckTokenAuthorization(per_session_data_eqemu*);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "web_interface.h"
|
||||
#include "call_handler.h"
|
||||
#include "method_handler.h"
|
||||
#include "remote_call.h"
|
||||
|
||||
volatile bool run = true;
|
||||
TimeoutManager timeout_manager;
|
||||
@ -7,8 +8,8 @@ const EQEmuConfig *config = nullptr;
|
||||
WorldServer *worldserver = nullptr;
|
||||
libwebsocket_context *context = nullptr;
|
||||
std::map<std::string, per_session_data_eqemu*> sessions;
|
||||
std::map<std::string, CallHandler> authorized_calls;
|
||||
std::map<std::string, CallHandler> unauthorized_calls;
|
||||
std::map<std::string, std::pair<int, MethodHandler>> authorized_methods;
|
||||
std::map<std::string, MethodHandler> unauthorized_methods;
|
||||
|
||||
void CatchSignal(int sig_num) {
|
||||
run = false;
|
||||
@ -49,39 +50,47 @@ int callback_eqemu(libwebsocket_context *context, libwebsocket *wsi, libwebsocke
|
||||
|
||||
rapidjson::Document document;
|
||||
if(document.Parse((const char*)in).HasParseError()) {
|
||||
WriteWebCallResponseString(session, document, "Malformed JSON data", true, true);
|
||||
break;
|
||||
}
|
||||
|
||||
std::string call;
|
||||
if(document.HasMember("call")) {
|
||||
call = document["call"].GetString();
|
||||
std::string method;
|
||||
if(document.HasMember("method")) {
|
||||
method = document["method"].GetString();
|
||||
}
|
||||
|
||||
if(call.length() == 0) {
|
||||
if(method.length() == 0) {
|
||||
//No function called, toss this message
|
||||
WriteWebCallResponse(session, document, "call_empty");
|
||||
WriteWebCallResponseString(session, document, "No method specified", true);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!CheckTokenAuthorization(session)) {
|
||||
int status = CheckTokenAuthorization(session);
|
||||
if (status == 0) {
|
||||
//check func call against functions that dont req auth
|
||||
if (unauthorized_calls.count(call) == 0) {
|
||||
WriteWebCallResponse(session, document, "unauthorized_call_not_found: " + call);
|
||||
if (unauthorized_methods.count(method) == 0) {
|
||||
WriteWebCallResponseString(session, document, "No suitable method found: " + method, true);
|
||||
break;
|
||||
}
|
||||
|
||||
auto call_func = unauthorized_calls[call];
|
||||
call_func(session, document);
|
||||
auto call_func = unauthorized_methods[method];
|
||||
call_func(session, document, method);
|
||||
}
|
||||
else {
|
||||
else if(status > 0) {
|
||||
//check func call against functions that req auth
|
||||
if (authorized_calls.count(call) == 0) {
|
||||
WriteWebCallResponse(session, document, "authorized_call_not_found: " + call);
|
||||
if (authorized_methods.count(method) == 0) {
|
||||
WriteWebCallResponseString(session, document, "No suitable method found: " + method, true);
|
||||
break;
|
||||
}
|
||||
|
||||
//check status level
|
||||
auto iter = authorized_methods.find(method);
|
||||
if(iter->second.first > status) {
|
||||
WriteWebCallResponseString(session, document, "Method " + method + " requires status " + std::to_string((long)iter->second.first), true);
|
||||
break;
|
||||
}
|
||||
|
||||
auto call_func = authorized_calls[call];
|
||||
call_func(session, document);
|
||||
auto call_func = iter->second.second;
|
||||
call_func(session, document, method);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -130,7 +139,7 @@ static struct libwebsocket_protocols protocols[] = {
|
||||
int main() {
|
||||
RegisterExecutablePlatform(ExePlatformWebInterface);
|
||||
set_exception_handler();
|
||||
register_calls();
|
||||
register_methods();
|
||||
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
||||
_log(WEB_INTERFACE__INIT, "Starting EQEmu Web Server.");
|
||||
|
||||
@ -189,27 +198,4 @@ int main() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WriteWebCallResponse(per_session_data_eqemu *session, rapidjson::Document &doc, std::string status) {
|
||||
if (doc.HasMember("id")) {
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
writer.String(doc["id"].GetString());
|
||||
writer.String("status");
|
||||
writer.String(status.c_str());
|
||||
writer.EndObject();
|
||||
session->send_queue->push_back(s.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckTokenAuthorization(per_session_data_eqemu *session) {
|
||||
//todo: actually check this against a table of tokens that is updated periodically
|
||||
//right now i have just one entry harded coded for testing purposes
|
||||
if(session->auth.compare("c5b80ec8-4174-4c4c-d332-dbf3c3a551fc") == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -46,8 +46,6 @@ struct per_session_data_eqemu {
|
||||
std::list<std::string> *send_queue;
|
||||
};
|
||||
|
||||
typedef void(*CallHandler)(per_session_data_eqemu*, rapidjson::Document&);
|
||||
void WriteWebCallResponse(per_session_data_eqemu *session, rapidjson::Document &doc, std::string status);
|
||||
bool CheckTokenAuthorization(per_session_data_eqemu*);
|
||||
typedef void(*MethodHandler)(per_session_data_eqemu*, rapidjson::Document&, std::string&);
|
||||
|
||||
#endif
|
||||
@ -30,14 +30,8 @@
|
||||
#include "../common/packet_functions.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/web_interface_utils.h"
|
||||
#include "worldserver.h"
|
||||
|
||||
struct per_session_data_eqemu {
|
||||
bool auth;
|
||||
std::string uuid;
|
||||
std::list<std::string> *send_queue;
|
||||
};
|
||||
#include "web_interface.h"
|
||||
|
||||
extern std::map<std::string, per_session_data_eqemu*> sessions;
|
||||
|
||||
@ -65,18 +59,74 @@ void WorldServer::Process(){
|
||||
switch(pack->opcode) {
|
||||
case 0: { break; }
|
||||
case ServerOP_KeepAlive: { break; }
|
||||
case ServerOP_WIWorldResponse: {
|
||||
/* Generic Response routine: web_interface server recieves packet from World -
|
||||
Relays data back to client
|
||||
*/
|
||||
_log(WEB_INTERFACE__ERROR, "WI Recieved packet from world 0x%04x, size %d", pack->opcode, pack->size);
|
||||
WI_Client_Request_Struct* WICR = (WI_Client_Request_Struct*)pack->pBuffer;
|
||||
std::string Data;
|
||||
Data.assign(WICR->JSON_Data, pack->size - 64);
|
||||
/* Check if Session is Valid before sending data back*/
|
||||
if (sessions[WICR->Client_UUID]){
|
||||
sessions[WICR->Client_UUID]->send_queue->push_back(Data.c_str());
|
||||
case ServerOP_WIRemoteCallResponse: {
|
||||
char *id = nullptr;
|
||||
char *session_id = nullptr;
|
||||
char *error = nullptr;
|
||||
|
||||
id = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(id);
|
||||
|
||||
session_id = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(session_id);
|
||||
|
||||
error = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(error);
|
||||
|
||||
uint32 param_count = pack->ReadUInt32();
|
||||
std::vector<std::string> params;
|
||||
for(uint32 i = 0; i < param_count; ++i) {
|
||||
char *p = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(p);
|
||||
params.push_back(p);
|
||||
safe_delete_array(p);
|
||||
}
|
||||
|
||||
//send the response to client...
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
if(strlen(id) == 0) {
|
||||
writer.Null();
|
||||
} else {
|
||||
writer.String(id);
|
||||
}
|
||||
|
||||
if(strlen(error) != 0) {
|
||||
writer.String("error");
|
||||
writer.Bool(true);
|
||||
|
||||
writer.String("result");
|
||||
writer.StartArray();
|
||||
if(params.size() > 0) {
|
||||
writer.String(params[0].c_str());
|
||||
} else {
|
||||
writer.String("");
|
||||
}
|
||||
writer.EndArray();
|
||||
} else {
|
||||
writer.String("error");
|
||||
writer.Null();
|
||||
writer.String("result");
|
||||
writer.StartArray();
|
||||
uint32 p_sz = (uint32)params.size();
|
||||
for(uint32 i = 0; i < p_sz; ++i) {
|
||||
writer.String(params[i].c_str());
|
||||
}
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
writer.EndObject();
|
||||
|
||||
if(sessions.count(session_id) != 0) {
|
||||
per_session_data_eqemu *session = sessions[session_id];
|
||||
session->send_queue->push_back(s.GetString());
|
||||
}
|
||||
|
||||
safe_delete_array(id);
|
||||
safe_delete_array(session_id);
|
||||
safe_delete_array(error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ SET(world_sources
|
||||
perl_EQW.cpp
|
||||
perl_HTTPRequest.cpp
|
||||
queryserv.cpp
|
||||
remote_call.cpp
|
||||
ucs.cpp
|
||||
web_interface.cpp
|
||||
wguild_mgr.cpp
|
||||
@ -54,6 +55,7 @@ SET(world_headers
|
||||
LoginServerList.h
|
||||
net.h
|
||||
queryserv.h
|
||||
remote_call.h
|
||||
SoFCharCreateData.h
|
||||
ucs.h
|
||||
web_interface.h
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
#include "ucs.h"
|
||||
#include "queryserv.h"
|
||||
#include "web_interface.h"
|
||||
#include "remote_call.h"
|
||||
|
||||
TimeoutManager timeout_manager;
|
||||
EQStreamFactory eqsf(WorldStream,9000);
|
||||
@ -107,7 +108,6 @@ uint32 numclients = 0;
|
||||
uint32 numzones = 0;
|
||||
bool holdzones = false;
|
||||
|
||||
|
||||
extern ConsoleList console_list;
|
||||
|
||||
void CatchSignal(int sig_num);
|
||||
@ -115,6 +115,7 @@ void CatchSignal(int sig_num);
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformWorld);
|
||||
set_exception_handler();
|
||||
register_remote_call_handlers();
|
||||
|
||||
// Load server configuration
|
||||
_log(WORLD__INIT, "Loading server configuration..");
|
||||
|
||||
88
world/remote_call.cpp
Normal file
88
world/remote_call.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "../common/debug.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "clientlist.h"
|
||||
#include "zonelist.h"
|
||||
#include "web_interface.h"
|
||||
#include "remote_call.h"
|
||||
#include "zoneserver.h"
|
||||
|
||||
extern ClientList client_list;
|
||||
extern ZSList zoneserver_list;
|
||||
extern WebInterfaceConnection WILink;
|
||||
std::map<std::string, RemoteCallHandler> remote_call_methods;
|
||||
|
||||
void RemoteCallResponse(const std::string &connection_id, const std::string &request_id, const std::vector<std::string> &res, const std::string &error) {
|
||||
uint32 sz = connection_id.size() + request_id.size() + error.size() + 3 + 16;
|
||||
uint32 res_sz = res.size();
|
||||
for(uint32 i = 0; i < res_sz; ++i) {
|
||||
sz += res[i].size() + 5;
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCallResponse, sz);
|
||||
pack->WriteUInt32((uint32)request_id.size());
|
||||
pack->WriteString(request_id.c_str());
|
||||
pack->WriteUInt32((uint32)connection_id.size());
|
||||
pack->WriteString(connection_id.c_str());
|
||||
pack->WriteUInt32((uint32)error.size());
|
||||
pack->WriteString(error.c_str());
|
||||
pack->WriteUInt32((uint32)res_sz);
|
||||
for (uint32 i = 0; i < res_sz; ++i) {
|
||||
auto &r = res[i];
|
||||
pack->WriteUInt32((uint32)r.size());
|
||||
pack->WriteString(r.c_str());
|
||||
}
|
||||
|
||||
WILink.SendPacket(pack);
|
||||
}
|
||||
|
||||
void register_remote_call_handlers() {
|
||||
remote_call_methods["list_zones"] = handle_rc_list_zones;
|
||||
remote_call_methods["get_zone_info"] = handle_rc_get_zone_info;
|
||||
}
|
||||
|
||||
void handle_rc_list_zones(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms) {
|
||||
std::vector<uint32> zones;
|
||||
zoneserver_list.GetZoneIDList(zones);
|
||||
|
||||
std::vector<std::string> res;
|
||||
uint32 sz = (uint32)zones.size();
|
||||
for(uint32 i = 0; i < sz; ++i) {
|
||||
res.push_back(itoa(zones[i]));
|
||||
}
|
||||
|
||||
std::string error;
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
}
|
||||
|
||||
void handle_rc_get_zone_info(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms) {
|
||||
std::string error;
|
||||
std::vector<std::string> res;
|
||||
if(params.size() != 1) {
|
||||
error = "Expected only one zone_id.";
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
return;
|
||||
}
|
||||
|
||||
ZoneServer *zs = zoneserver_list.FindByID(atoi(params[0].c_str()));
|
||||
if(zs == nullptr) {
|
||||
error = "Invalid zone";
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
return;
|
||||
}
|
||||
|
||||
res.push_back(zs->IsStaticZone() ? "static" : "dynamic");
|
||||
res.push_back(itoa(zs->GetZoneID()));
|
||||
res.push_back(itoa(zs->GetInstanceID()));
|
||||
res.push_back(zs->GetLaunchName());
|
||||
res.push_back(zs->GetLaunchedName());
|
||||
res.push_back(zs->GetZoneName());
|
||||
res.push_back(zs->GetZoneLongName());
|
||||
res.push_back(itoa(zs->GetCPort()));
|
||||
res.push_back(itoa(zs->NumPlayers()));
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
}
|
||||
34
world/remote_call.h
Normal file
34
world/remote_call.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef WORLD_REMOTE_CALL_H
|
||||
#define WORLD_REMOTE_CALL_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef void(*RemoteCallHandler)(const std::string&, const std::string&, const std::string&, const std::vector<std::string>&);
|
||||
|
||||
void RemoteCallResponse(const std::string &connection_id, const std::string &request_id, const std::vector<std::string> &res, const std::string &error);
|
||||
|
||||
void register_remote_call_handlers();
|
||||
void handle_rc_list_zones(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms);
|
||||
void handle_rc_get_zone_info(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms);
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "WorldConfig.h"
|
||||
#include "clientlist.h"
|
||||
#include "zonelist.h"
|
||||
#include "remote_call.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
#include "../common/md5.h"
|
||||
@ -11,6 +12,7 @@
|
||||
|
||||
extern ClientList client_list;
|
||||
extern ZSList zoneserver_list;
|
||||
extern std::map<std::string, RemoteCallHandler> remote_call_methods;
|
||||
|
||||
WebInterfaceConnection::WebInterfaceConnection()
|
||||
{
|
||||
@ -99,18 +101,38 @@ bool WebInterfaceConnection::Process()
|
||||
_log(WEB_INTERFACE__ERROR, "Got authentication from WebInterface when they are already authenticated.");
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIServGeneric:
|
||||
case ServerOP_WIRemoteCall:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack); // Send to all zones to test
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIClientRequest:
|
||||
{
|
||||
std::string Data;
|
||||
WI_Client_Request_Struct* WICR = (WI_Client_Request_Struct*)pack->pBuffer;
|
||||
Data.assign(WICR->JSON_Data, pack->size - 64);
|
||||
_log(WEB_INTERFACE__ERROR, "Recieved ServerOPcode from WebInterface 0x%04x \nSize %d\nData '%s' from client:\n%s\n", pack->opcode, pack->size, Data.c_str(), WICR->Client_UUID);
|
||||
zoneserver_list.SendPacket(pack); // Send to all zones to test
|
||||
char *id = nullptr;
|
||||
char *session_id = nullptr;
|
||||
char *method = nullptr;
|
||||
|
||||
id = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(id);
|
||||
|
||||
session_id = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(session_id);
|
||||
|
||||
method = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(method);
|
||||
|
||||
uint32 param_count = pack->ReadUInt32();
|
||||
std::vector<std::string> params;
|
||||
for(uint32 i = 0; i < param_count; ++i) {
|
||||
char *p = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(p);
|
||||
params.push_back(p);
|
||||
safe_delete_array(p);
|
||||
}
|
||||
|
||||
if (remote_call_methods.count(method) != 0) {
|
||||
auto f = remote_call_methods[method];
|
||||
f(method, session_id, id, params);
|
||||
}
|
||||
|
||||
safe_delete_array(id);
|
||||
safe_delete_array(session_id);
|
||||
safe_delete_array(method);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@ -1303,10 +1303,6 @@ bool ZoneServer::Process() {
|
||||
case ServerOP_CZSignalClientByName:
|
||||
case ServerOP_CZMessagePlayer:
|
||||
case ServerOP_CZSignalClient:
|
||||
{
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_DepopAllPlayersCorpses:
|
||||
case ServerOP_DepopPlayerCorpse:
|
||||
case ServerOP_ReloadTitles:
|
||||
@ -1318,12 +1314,6 @@ bool ZoneServer::Process() {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIWorldResponse:
|
||||
{
|
||||
_log(WEB_INTERFACE__ERROR, "ServerOP_WIWorldResponse for WebInterface 0x%04x, size %d", pack->opcode, pack->size);
|
||||
WILink.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
zlog(WORLD__ZONE_ERR,"Unknown ServerOPcode from zone 0x%04x, size %d",pack->opcode,pack->size);
|
||||
|
||||
28
zone/mob.cpp
28
zone/mob.cpp
@ -22,7 +22,6 @@
|
||||
#include "worldserver.h"
|
||||
#include "QuestParserCollection.h"
|
||||
#include "../common/StringUtil.h"
|
||||
#include "../common/web_interface_utils.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
@ -32,7 +31,6 @@ extern EntityList entity_list;
|
||||
|
||||
extern Zone* zone;
|
||||
extern WorldServer worldserver;
|
||||
extern std::string WS_Client_Connected;
|
||||
|
||||
Mob::Mob(const char* in_name,
|
||||
const char* in_lastname,
|
||||
@ -1215,19 +1213,19 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){
|
||||
spu->padding0014 =0x7f;
|
||||
spu->padding0018 =0x5df27;
|
||||
|
||||
/* Testing */
|
||||
if (IsNPC() && WS_Client_Connected.size() != 0){
|
||||
std::string str = MakeJSON("ResponseType:PositionUpdate,entity:" + std::to_string(GetID()) + ",name:" + GetName() + ",x:" + std::to_string(x_pos) + ",y:" + std::to_string(y_pos) + ",z:" + std::to_string(z_pos) + ",h:" + std::to_string(heading));
|
||||
char * writable = new char[str.size() + 1];
|
||||
std::copy(str.begin(), str.end(), writable);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_WIWorldResponse, sizeof(WI_Client_Response_Struct)+str.length() + 1);
|
||||
WI_Client_Response_Struct* WICR = (WI_Client_Response_Struct*)pack->pBuffer;
|
||||
strn0cpy(WICR->Client_UUID, WS_Client_Connected.c_str(), 64);
|
||||
strn0cpy(WICR->JSON_Data, str.c_str(), str.length() + 1);
|
||||
if (worldserver.Connected()) { worldserver.SendPacket(pack); }
|
||||
safe_delete(pack);
|
||||
delete[] writable;
|
||||
}
|
||||
///* Testing */
|
||||
//if (IsNPC() && WS_Client_Connected.size() != 0){
|
||||
// std::string str = MakeJSON("ResponseType:PositionUpdate,entity:" + std::to_string(GetID()) + ",name:" + GetName() + ",x:" + std::to_string(x_pos) + ",y:" + std::to_string(y_pos) + ",z:" + std::to_string(z_pos) + ",h:" + std::to_string(heading));
|
||||
// char * writable = new char[str.size() + 1];
|
||||
// std::copy(str.begin(), str.end(), writable);
|
||||
// ServerPacket* pack = new ServerPacket(ServerOP_WIWorldResponse, sizeof(WI_Client_Response_Struct)+str.length() + 1);
|
||||
// WI_Client_Response_Struct* WICR = (WI_Client_Response_Struct*)pack->pBuffer;
|
||||
// strn0cpy(WICR->Client_UUID, WS_Client_Connected.c_str(), 64);
|
||||
// strn0cpy(WICR->JSON_Data, str.c_str(), str.length() + 1);
|
||||
// if (worldserver.Connected()) { worldserver.SendPacket(pack); }
|
||||
// safe_delete(pack);
|
||||
// delete[] writable;
|
||||
//}
|
||||
}
|
||||
|
||||
// this is for SendPosUpdate()
|
||||
|
||||
@ -100,7 +100,6 @@ DBAsyncFinishedQueue MTdbafq;
|
||||
DBAsync *dbasync = nullptr;
|
||||
TaskManager *taskmanager = 0;
|
||||
QuestParserCollection *parse = 0;
|
||||
std::string WS_Client_Connected;
|
||||
|
||||
const SPDat_Spell_Struct* spells;
|
||||
void LoadSpells(EQEmu::MemoryMappedFile **mmf);
|
||||
|
||||
@ -62,7 +62,6 @@ extern NetConnection net;
|
||||
extern PetitionList petition_list;
|
||||
extern uint32 numclients;
|
||||
extern volatile bool RunLoops;
|
||||
extern std::string WS_Client_Connected;
|
||||
|
||||
WorldServer::WorldServer()
|
||||
: WorldConnection(EmuTCPConnection::packetModeZone)
|
||||
@ -1778,13 +1777,6 @@ void WorldServer::Process() {
|
||||
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIClientRequest:
|
||||
{
|
||||
WI_Client_Request_Struct* WICR = (WI_Client_Request_Struct*)pack->pBuffer;
|
||||
WS_Client_Connected = WICR->Client_UUID;
|
||||
_log(WEB_INTERFACE__ERROR, "Recieved packet from World, setting Client Connected to %s", WICR->Client_UUID);
|
||||
break;
|
||||
}
|
||||
case ServerOP_CZSignalClient:
|
||||
{
|
||||
CZClientSignal_Struct* CZCS = (CZClientSignal_Struct*) pack->pBuffer;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user