mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 15:41:30 +00:00
More work on subscription events, and relaying through world.
This commit is contained in:
parent
002f5e3bcc
commit
40b555a55b
@ -188,7 +188,9 @@
|
||||
|
||||
#define ServerOP_WIRemoteCall 0x5001
|
||||
#define ServerOP_WIRemoteCallResponse 0x5002
|
||||
#define ServerOP_WIClientSession 0x5003
|
||||
#define ServerOP_WIRemoteCallToClient 0x5003
|
||||
#define ServerOP_WIClientSession 0x5004
|
||||
#define ServerOP_WIClientSessionResponse 0x5005
|
||||
|
||||
enum { QSG_LFGuild = 0 };
|
||||
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
||||
|
||||
@ -8,15 +8,16 @@ 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);
|
||||
authorized_methods["WebInterface::Authorize"] = std::make_pair(0, handle_method_token_auth);
|
||||
authorized_methods["World::ListZones"] = std::make_pair(10, handle_method_no_args);
|
||||
authorized_methods["World::GetZoneDetails"] = std::make_pair(10, handle_method_get_zone_info);
|
||||
authorized_methods["Zone::Subscribe"] = std::make_pair(10, handle_method_subscribe);
|
||||
authorized_methods["Zone::Unsubscribe"] = std::make_pair(10, handle_method_subscribe);
|
||||
}
|
||||
|
||||
void register_unauthorized_methods()
|
||||
{
|
||||
unauthorized_methods["token_auth"] = handle_method_token_auth;
|
||||
unauthorized_methods["WebInterface::Authorize"] = handle_method_token_auth;
|
||||
}
|
||||
|
||||
void register_methods()
|
||||
|
||||
@ -13,8 +13,13 @@ void WriteWebCallResponseString(per_session_data_eqemu *session, rapidjson::Docu
|
||||
else {
|
||||
writer.String(doc["id"].GetString());
|
||||
}
|
||||
|
||||
writer.String("result");
|
||||
writer.StartObject();
|
||||
writer.String("value");
|
||||
writer.String(result.c_str());
|
||||
writer.EndObject();
|
||||
|
||||
writer.String("error");
|
||||
if (error) {
|
||||
writer.Bool(true);
|
||||
@ -39,8 +44,13 @@ void WriteWebCallResponseInt(per_session_data_eqemu *session, rapidjson::Documen
|
||||
else {
|
||||
writer.String(doc["id"].GetString());
|
||||
}
|
||||
|
||||
writer.String("result");
|
||||
writer.StartObject();
|
||||
writer.String("value");
|
||||
writer.Int(result);
|
||||
writer.EndObject();
|
||||
|
||||
writer.String("error");
|
||||
if (error) {
|
||||
writer.Bool(true);
|
||||
@ -65,8 +75,13 @@ void WriteWebCallResponseBoolean(per_session_data_eqemu *session, rapidjson::Doc
|
||||
else {
|
||||
writer.String(doc["id"].GetString());
|
||||
}
|
||||
|
||||
writer.String("result");
|
||||
writer.StartObject();
|
||||
writer.String("value");
|
||||
writer.Bool(result);
|
||||
writer.EndObject();
|
||||
|
||||
writer.String("error");
|
||||
if (error) {
|
||||
writer.Bool(true);
|
||||
|
||||
@ -74,17 +74,24 @@ void WorldServer::Process(){
|
||||
pack->ReadString(error);
|
||||
|
||||
uint32 param_count = pack->ReadUInt32();
|
||||
std::vector<std::string> params;
|
||||
std::map<std::string, 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);
|
||||
char *first = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(first);
|
||||
|
||||
char *second = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(second);
|
||||
|
||||
params[first] = second;
|
||||
|
||||
safe_delete_array(first);
|
||||
safe_delete_array(second);
|
||||
}
|
||||
|
||||
//send the response to client...
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
if(strlen(id) == 0) {
|
||||
@ -103,14 +110,15 @@ void WorldServer::Process(){
|
||||
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.StartObject();
|
||||
auto iter = params.begin();
|
||||
while(iter != params.end()) {
|
||||
writer.String(iter->first.c_str());
|
||||
writer.String(iter->second.c_str());
|
||||
++iter;
|
||||
}
|
||||
writer.EndArray();
|
||||
writer.EndObject();
|
||||
}
|
||||
|
||||
writer.EndObject();
|
||||
|
||||
if(sessions.count(session_id) != 0) {
|
||||
@ -123,6 +131,101 @@ void WorldServer::Process(){
|
||||
safe_delete_array(error);
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_WIRemoteCallToClient:
|
||||
{
|
||||
char *session_id = nullptr;
|
||||
char *method = nullptr;
|
||||
|
||||
DumpPacket(pack);
|
||||
|
||||
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(param_count);
|
||||
for(uint32 i = 0; i < param_count; ++i) {
|
||||
char *p = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(p);
|
||||
params[i] = p;
|
||||
|
||||
safe_delete_array(p);
|
||||
}
|
||||
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
|
||||
writer.StartObject();
|
||||
writer.String("id");
|
||||
writer.Null();
|
||||
|
||||
writer.String("method");
|
||||
writer.String(method);
|
||||
|
||||
writer.String("params");
|
||||
writer.StartArray();
|
||||
|
||||
for(uint32 i = 0; i < param_count; ++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(session_id);
|
||||
safe_delete_array(method);
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_WIClientSession:
|
||||
{
|
||||
std::vector<std::string> invalidate;
|
||||
uint32 zone_id = pack->ReadUInt32();
|
||||
uint32 instance_id = pack->ReadUInt32();
|
||||
uint32 count = pack->ReadUInt32();
|
||||
for(uint32 i = 0; i < count; ++i) {
|
||||
char *p = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(p);
|
||||
|
||||
if(sessions.count(p) == 0) {
|
||||
invalidate.push_back(p);
|
||||
}
|
||||
|
||||
safe_delete_array(p);
|
||||
}
|
||||
|
||||
if(invalidate.size() != 0) {
|
||||
uint32 sz = 12;
|
||||
size_t isz = invalidate.size();
|
||||
for(size_t i = 0; i < isz; ++i) {
|
||||
sz += invalidate[i].size();
|
||||
sz += 5;
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIClientSessionResponse, sz);
|
||||
pack->WriteUInt32((uint32)zone_id);
|
||||
pack->WriteUInt32((uint32)instance_id);
|
||||
pack->WriteUInt32((uint32)invalidate.size());
|
||||
for(size_t i = 0; i < isz; ++i) {
|
||||
pack->WriteUInt32((uint32)invalidate[i].size());
|
||||
pack->WriteString(invalidate[i].c_str());
|
||||
}
|
||||
|
||||
SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,11 +16,12 @@ 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) {
|
||||
void RemoteCallResponse(const std::string &connection_id, const std::string &request_id, const std::map<std::string, std::string> &res, const std::string &error) {
|
||||
uint32 sz = (uint32)(connection_id.size() + request_id.size() + error.size() + 3 + 16);
|
||||
uint32 res_sz = (uint32)res.size();
|
||||
for(uint32 i = 0; i < res_sz; ++i) {
|
||||
sz += (uint32)res[i].size() + 5;
|
||||
auto iter = res.begin();
|
||||
while(iter != res.end()) {
|
||||
sz += (uint32)iter->first.size() + (uint32)iter->second.size() + 10;
|
||||
++iter;
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCallResponse, sz);
|
||||
@ -30,30 +31,35 @@ void RemoteCallResponse(const std::string &connection_id, const std::string &req
|
||||
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());
|
||||
pack->WriteUInt32((uint32)res.size());
|
||||
iter = res.begin();
|
||||
while(iter != res.end()) {
|
||||
pack->WriteUInt32((uint32)iter->first.size());
|
||||
pack->WriteString(iter->first.c_str());
|
||||
pack->WriteUInt32((uint32)iter->second.size());
|
||||
pack->WriteString(iter->second.c_str());
|
||||
++iter;
|
||||
}
|
||||
|
||||
WILink.SendPacket(pack);
|
||||
safe_delete(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;
|
||||
remote_call_methods["subscribe"] = handle_rc_relay;
|
||||
remote_call_methods["World::ListZones"] = handle_rc_list_zones;
|
||||
remote_call_methods["World::GetZoneDetails"] = handle_rc_get_zone_info;
|
||||
remote_call_methods["Zone::Subscribe"] = handle_rc_relay;
|
||||
remote_call_methods["Zone::Unsubscribe"] = handle_rc_relay;
|
||||
}
|
||||
|
||||
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;
|
||||
std::map<std::string, std::string> res;
|
||||
uint32 sz = (uint32)zones.size();
|
||||
for(uint32 i = 0; i < sz; ++i) {
|
||||
res.push_back(itoa(zones[i]));
|
||||
res[itoa(i)] = (itoa(zones[i]));
|
||||
}
|
||||
|
||||
std::string error;
|
||||
@ -62,7 +68,7 @@ void handle_rc_list_zones(const std::string &method, const std::string &connecti
|
||||
|
||||
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;
|
||||
std::map<std::string, std::string> res;
|
||||
if(params.size() != 1) {
|
||||
error = "Expected only one zone_id.";
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
@ -76,21 +82,21 @@ void handle_rc_get_zone_info(const std::string &method, const std::string &conne
|
||||
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()));
|
||||
res["type"] = zs->IsStaticZone() ? "static" : "dynamic";
|
||||
res["zone_id"] = itoa(zs->GetZoneID());
|
||||
res["instance_id"] = itoa(zs->GetInstanceID());
|
||||
res["launch_name"] = zs->GetLaunchName();
|
||||
res["launched_name"] = zs->GetLaunchedName();
|
||||
res["short_name"] = zs->GetZoneName();
|
||||
res["long_name"] = zs->GetZoneLongName();
|
||||
res["port"] = itoa(zs->GetCPort());
|
||||
res["num_players"] = itoa(zs->NumPlayers());
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
}
|
||||
|
||||
void handle_rc_relay(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;
|
||||
std::map<std::string, std::string> res;
|
||||
uint32 zone_id = 0;
|
||||
uint32 instance_id = 0;
|
||||
ZoneServer *zs = nullptr;
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
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 RemoteCallResponse(const std::string &connection_id, const std::string &request_id, const std::map<std::string, 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);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "WorldConfig.h"
|
||||
#include "clientlist.h"
|
||||
#include "zonelist.h"
|
||||
#include "zoneserver.h"
|
||||
#include "remote_call.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
@ -135,6 +136,27 @@ bool WebInterfaceConnection::Process()
|
||||
safe_delete_array(method);
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIClientSessionResponse: {
|
||||
uint32 zone_id = pack->ReadUInt32();
|
||||
uint32 instance_id = pack->ReadUInt32();
|
||||
|
||||
ZoneServer *zs = nullptr;
|
||||
if(instance_id != 0) {
|
||||
zs = zoneserver_list.FindByInstanceID(instance_id);
|
||||
} else {
|
||||
zs = zoneserver_list.FindByZoneID(zone_id);
|
||||
}
|
||||
|
||||
if(zs) {
|
||||
ServerPacket *npack = new ServerPacket(ServerOP_WIClientSessionResponse, pack->size - 8);
|
||||
memcpy(npack->pBuffer, pack->pBuffer + 8, pack->size - 8);
|
||||
|
||||
zs->SendPacket(npack);
|
||||
safe_delete(npack);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log(WEB_INTERFACE__ERROR, "Unknown ServerOPcode from WebInterface 0x%04x, size %d", pack->opcode, pack->size);
|
||||
|
||||
@ -1300,6 +1300,13 @@ bool ZoneServer::Process() {
|
||||
QSLink.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIRemoteCallResponse:
|
||||
case ServerOP_WIClientSession:
|
||||
case ServerOP_WIRemoteCallToClient:
|
||||
{
|
||||
WILink.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_CZSignalClientByName:
|
||||
case ServerOP_CZMessagePlayer:
|
||||
case ServerOP_CZSignalClient:
|
||||
|
||||
@ -97,6 +97,8 @@ SET(zone_sources
|
||||
QuestParserCollection.cpp
|
||||
raids.cpp
|
||||
RaycastMesh.cpp
|
||||
remote_call.cpp
|
||||
remote_call_subscribe.cpp
|
||||
spawn2.cpp
|
||||
spawn2.h
|
||||
spawngroup.cpp
|
||||
@ -189,6 +191,8 @@ SET(zone_headers
|
||||
raid.h
|
||||
raids.h
|
||||
RaycastMesh.h
|
||||
remote_call.h
|
||||
remote_call_subscribe.h
|
||||
skills.h
|
||||
spawn2.cpp
|
||||
spawn2.h
|
||||
|
||||
@ -40,12 +40,10 @@ void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
|
||||
end = entries[id].end();
|
||||
for(; cur != end; ++cur) {
|
||||
if(*cur == c) {
|
||||
printf("%s was allready subscribed to %d\n", c->GetName(), id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s has been subscribed to %d\n", c->GetName(), id);
|
||||
entries[id].push_back(c);
|
||||
}
|
||||
|
||||
|
||||
47
zone/mob.cpp
47
zone/mob.cpp
@ -18,10 +18,12 @@
|
||||
#include "../common/debug.h"
|
||||
#include "masterentity.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/StringUtil.h"
|
||||
#include "StringIDs.h"
|
||||
#include "worldserver.h"
|
||||
#include "QuestParserCollection.h"
|
||||
#include "../common/StringUtil.h"
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
@ -1213,19 +1215,34 @@ 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;
|
||||
//}
|
||||
if(IsNPC()) {
|
||||
//zone_id
|
||||
//instance_id
|
||||
//entity_id
|
||||
//x
|
||||
//y
|
||||
//z
|
||||
//h
|
||||
const auto &conns = RemoteCallSubscriptionHandler::Instance()->GetSubscribers("NPC::MakeSpawnUpdateNoDelta");
|
||||
if(conns.size() > 0) {
|
||||
std::string method = "NPC::MakeSpawnUpdateNoDelta";
|
||||
std::vector<std::string> params;
|
||||
params.push_back(std::to_string((long)zone->GetZoneID()));
|
||||
params.push_back(std::to_string((long)zone->GetInstanceID()));
|
||||
params.push_back(std::to_string((long)GetID()));
|
||||
params.push_back(GetName());
|
||||
params.push_back(std::to_string((double)x_pos));
|
||||
params.push_back(std::to_string((double)y_pos));
|
||||
params.push_back(std::to_string((double)z_pos));
|
||||
params.push_back(std::to_string((double)heading));
|
||||
|
||||
auto &iter = conns.begin();
|
||||
while(iter != conns.end()) {
|
||||
RemoteCall((*iter), method, params);
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is for SendPosUpdate()
|
||||
@ -1245,7 +1262,7 @@ void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) {
|
||||
if(this->IsClient())
|
||||
spu->animation = animation;
|
||||
else
|
||||
spu->animation = pRunAnimSpeed;//animation;
|
||||
spu->animation = pRunAnimSpeed;
|
||||
spu->delta_heading = NewFloatToEQ13(static_cast<float>(delta_heading));
|
||||
}
|
||||
|
||||
|
||||
@ -53,12 +53,13 @@
|
||||
#include "titles.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "tasks.h"
|
||||
|
||||
#include "QuestParserCollection.h"
|
||||
#include "embparser.h"
|
||||
#include "lua_parser.h"
|
||||
#include "client_logs.h"
|
||||
#include "questmgr.h"
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -111,6 +112,7 @@ extern void MapOpcodes();
|
||||
int main(int argc, char** argv) {
|
||||
RegisterExecutablePlatform(ExePlatformZone);
|
||||
set_exception_handler();
|
||||
register_remote_call_handlers();
|
||||
|
||||
const char *zone_name;
|
||||
|
||||
@ -310,6 +312,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect
|
||||
Timer RemoteCallProcessTimer(5000);
|
||||
#ifdef EQPROFILE
|
||||
#ifdef PROFILE_DUMP_TIME
|
||||
Timer profile_dump_timer(PROFILE_DUMP_TIME*1000);
|
||||
@ -403,6 +406,10 @@ int main(int argc, char** argv) {
|
||||
worldwasconnected = false;
|
||||
}
|
||||
|
||||
if(RemoteCallProcessTimer.Check()) {
|
||||
RemoteCallSubscriptionHandler::Instance()->Process();
|
||||
}
|
||||
|
||||
if (ZoneLoaded && zoneupdate_timer.Check()) {
|
||||
{
|
||||
if(net.group_timer.Enabled() && net.group_timer.Check())
|
||||
|
||||
112
zone/remote_call.cpp
Normal file
112
zone/remote_call.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "../common/debug.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/packet_functions.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
#include "worldserver.h"
|
||||
|
||||
std::map<std::string, RemoteCallHandler> remote_call_methods;
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void RemoteCallResponse(const std::string &connection_id, const std::string &request_id, const std::map<std::string, std::string> &res, const std::string &error) {
|
||||
uint32 sz = (uint32)(connection_id.size() + request_id.size() + error.size() + 3 + 16);
|
||||
auto iter = res.begin();
|
||||
while(iter != res.end()) {
|
||||
sz += (uint32)iter->first.size() + (uint32)iter->second.size() + 10;
|
||||
++iter;
|
||||
}
|
||||
|
||||
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.size());
|
||||
iter = res.begin();
|
||||
while(iter != res.end()) {
|
||||
pack->WriteUInt32((uint32)iter->first.size());
|
||||
pack->WriteString(iter->first.c_str());
|
||||
pack->WriteUInt32((uint32)iter->second.size());
|
||||
pack->WriteString(iter->second.c_str());
|
||||
++iter;
|
||||
}
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void RemoteCall(const std::string &connection_id, const std::string &method, const std::vector<std::string> ¶ms) {
|
||||
uint32 sz = (uint32)(connection_id.size() + method.size() + 14);
|
||||
auto iter = params.begin();
|
||||
while(iter != params.end()) {
|
||||
sz += (uint32)iter->size() + 5;
|
||||
++iter;
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIRemoteCallToClient, sz);
|
||||
pack->WriteUInt32((uint32)connection_id.size());
|
||||
pack->WriteString(connection_id.c_str());
|
||||
pack->WriteUInt32((uint32)method.size());
|
||||
pack->WriteString(method.c_str());
|
||||
pack->WriteUInt32((uint32)params.size());
|
||||
iter = params.begin();
|
||||
while(iter != params.end()) {
|
||||
pack->WriteUInt32((uint32)iter->size());
|
||||
pack->WriteString(iter->c_str());
|
||||
++iter;
|
||||
}
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
void register_remote_call_handlers() {
|
||||
remote_call_methods["Zone::Subscribe"] = handle_rc_subscribe;
|
||||
remote_call_methods["Zone::Unsubscribe"] = handle_rc_unsubscribe;
|
||||
}
|
||||
|
||||
void handle_rc_subscribe(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms) {
|
||||
std::string error;
|
||||
std::map<std::string, std::string> res;
|
||||
|
||||
if(params.size() != 1) {
|
||||
error = "Missing event to subscribe to";
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if(RemoteCallSubscriptionHandler::Instance()->Subscribe(connection_id, params[0])) {
|
||||
res["status"] = "subscribed";
|
||||
} else {
|
||||
res["status"] = "failed to subscribe";
|
||||
}
|
||||
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
}
|
||||
|
||||
void handle_rc_unsubscribe(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms) {
|
||||
std::string error;
|
||||
std::map<std::string, std::string> res;
|
||||
|
||||
if(params.size() != 1) {
|
||||
error = "Missing event to unsubscribe from";
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if(RemoteCallSubscriptionHandler::Instance()->Subscribe(connection_id, params[0])) {
|
||||
res["status"] = "unsubscribed";
|
||||
}
|
||||
else {
|
||||
res["status"] = "failed to unsubscribe";
|
||||
}
|
||||
|
||||
RemoteCallResponse(connection_id, request_id, res, error);
|
||||
}
|
||||
36
zone/remote_call.h
Normal file
36
zone/remote_call.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* 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 ZONE_REMOTE_CALL_H
|
||||
#define ZONE_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::map<std::string, std::string> &res, const std::string &error);
|
||||
void RemoteCall(const std::string &connection_id, const std::string &method, const std::vector<std::string> ¶ms);
|
||||
|
||||
void register_remote_call_handlers();
|
||||
|
||||
void handle_rc_subscribe(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms);
|
||||
void handle_rc_unsubscribe(const std::string &method, const std::string &connection_id, const std::string &request_id, const std::vector<std::string> ¶ms);
|
||||
|
||||
#endif
|
||||
|
||||
159
zone/remote_call_subscribe.cpp
Normal file
159
zone/remote_call_subscribe.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
#include "../common/debug.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/logtypes.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "../common/packet_functions.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
#include "worldserver.h"
|
||||
#include "zone.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern Zone* zone;
|
||||
|
||||
RemoteCallSubscriptionHandler* RemoteCallSubscriptionHandler::_instance = nullptr;
|
||||
|
||||
RemoteCallSubscriptionHandler::RemoteCallSubscriptionHandler() {
|
||||
}
|
||||
|
||||
RemoteCallSubscriptionHandler::~RemoteCallSubscriptionHandler() {
|
||||
}
|
||||
|
||||
RemoteCallSubscriptionHandler *RemoteCallSubscriptionHandler::Instance()
|
||||
{
|
||||
if(!_instance) {
|
||||
_instance = new RemoteCallSubscriptionHandler();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
bool RemoteCallSubscriptionHandler::Subscribe(std::string connection_id, std::string event_name) {
|
||||
if(registered_events.count(event_name) == 0) {
|
||||
std::vector<std::string> r;
|
||||
r.push_back(connection_id);
|
||||
registered_events[event_name] = r;
|
||||
|
||||
if(connection_ids.count(connection_id) == 0) {
|
||||
connection_ids[connection_id] = 1;
|
||||
} else {
|
||||
int count = connection_ids[connection_id];
|
||||
connection_ids[connection_id] = count + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
std::vector<std::string>& r = registered_events[event_name];
|
||||
|
||||
size_t sz = r.size();
|
||||
for(size_t i = 0; i < sz; ++i) {
|
||||
if(connection_id.compare(r[i]) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
r.push_back(connection_id);
|
||||
registered_events[event_name] = r;
|
||||
|
||||
if(connection_ids.count(connection_id) == 0) {
|
||||
connection_ids[connection_id] = 1;
|
||||
}
|
||||
else {
|
||||
int count = connection_ids[connection_id];
|
||||
connection_ids[connection_id] = count + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteCallSubscriptionHandler::Unsubscribe(std::string connection_id, std::string event_name) {
|
||||
if(registered_events.count(event_name) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string>& r = registered_events[event_name];
|
||||
auto iter = r.begin();
|
||||
while(iter != r.end()) {
|
||||
if(iter->compare(connection_id) == 0) {
|
||||
r.erase(iter);
|
||||
registered_events[event_name] = r;
|
||||
|
||||
int count = connection_ids[connection_id];
|
||||
connection_ids[connection_id] = count - 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoteCallSubscriptionHandler::Process() {
|
||||
//create a check for all these connection ids packet
|
||||
uint32 sz = 12;
|
||||
auto iter = connection_ids.begin();
|
||||
while(iter != connection_ids.end()) {
|
||||
sz += iter->first.size();
|
||||
sz += 5;
|
||||
++iter;
|
||||
}
|
||||
|
||||
ServerPacket *pack = new ServerPacket(ServerOP_WIClientSession, sz);
|
||||
pack->WriteUInt32((uint32)zone->GetZoneID());
|
||||
pack->WriteUInt32((uint32)zone->GetInstanceID());
|
||||
pack->WriteUInt32((uint32)connection_ids.size());
|
||||
|
||||
iter = connection_ids.begin();
|
||||
while(iter != connection_ids.end()) {
|
||||
pack->WriteUInt32((uint32)iter->first.size());
|
||||
pack->WriteString(iter->first.c_str());
|
||||
++iter;
|
||||
}
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
const std::vector<std::string> &RemoteCallSubscriptionHandler::GetSubscribers(std::string event_name) {
|
||||
if(registered_events.count(event_name) == 0) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
std::vector<std::string> &r = registered_events[event_name];
|
||||
return r;
|
||||
}
|
||||
|
||||
void RemoteCallSubscriptionHandler::ClearConnection(std::string connection_id) {
|
||||
if(connection_ids.count(connection_id) != 0) {
|
||||
connection_ids.erase(connection_id);
|
||||
}
|
||||
|
||||
auto iter = registered_events.begin();
|
||||
while(iter != registered_events.end()) {
|
||||
auto &conns = iter->second;
|
||||
auto conn_iter = conns.begin();
|
||||
while(conn_iter != conns.end()) {
|
||||
if(conn_iter->compare(connection_id) == 0) {
|
||||
conns.erase(conn_iter);
|
||||
registered_events[iter->first] = conns;
|
||||
printf("Removing connection: %s from event %s\n", connection_id.c_str(), iter->first.c_str());
|
||||
break;
|
||||
}
|
||||
++conn_iter;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteCallSubscriptionHandler::ClearAllConnections() {
|
||||
//
|
||||
//std::map<std::string, std::vector<std::string>> registered_events;
|
||||
//std::map<std::string, int> connection_ids;
|
||||
|
||||
registered_events.clear();
|
||||
connection_ids.clear();
|
||||
|
||||
}
|
||||
51
zone/remote_call_subscribe.h
Normal file
51
zone/remote_call_subscribe.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 ZONE_REMOTE_CALL_SUBSCRIBE_H
|
||||
#define ZONE_REMOTE_CALL_SUBSCRIBE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class RemoteCallSubscriptionHandler
|
||||
{
|
||||
public:
|
||||
~RemoteCallSubscriptionHandler();
|
||||
|
||||
static RemoteCallSubscriptionHandler *Instance();
|
||||
bool Subscribe(std::string connection_id, std::string event_name);
|
||||
bool Unsubscribe(std::string connection_id, std::string event_name);
|
||||
const std::vector<std::string> &GetSubscribers(std::string event_name);
|
||||
|
||||
void Process();
|
||||
void ClearConnection(std::string connection_id);
|
||||
void ClearAllConnections();
|
||||
|
||||
private:
|
||||
RemoteCallSubscriptionHandler();
|
||||
RemoteCallSubscriptionHandler(RemoteCallSubscriptionHandler const&);
|
||||
RemoteCallSubscriptionHandler& operator=(RemoteCallSubscriptionHandler const&);
|
||||
|
||||
static RemoteCallSubscriptionHandler *_instance;
|
||||
|
||||
std::map<std::string, std::vector<std::string>> registered_events;
|
||||
std::map<std::string, int> connection_ids;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -51,7 +51,8 @@
|
||||
#include "../common/rulesys.h"
|
||||
#include "titles.h"
|
||||
#include "QGlobals.h"
|
||||
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
@ -62,6 +63,7 @@ extern NetConnection net;
|
||||
extern PetitionList petition_list;
|
||||
extern uint32 numclients;
|
||||
extern volatile bool RunLoops;
|
||||
extern std::map<std::string, RemoteCallHandler> remote_call_methods;
|
||||
|
||||
WorldServer::WorldServer()
|
||||
: WorldConnection(EmuTCPConnection::packetModeZone)
|
||||
@ -1812,10 +1814,50 @@ void WorldServer::Process() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_WIRemoteCall:
|
||||
printf("Recv remote call from WI but atm doing anything with it is not yet implemented (BUT SOON)\n");
|
||||
DumpPacket(pack);
|
||||
case ServerOP_WIRemoteCall: {
|
||||
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;
|
||||
}
|
||||
case ServerOP_WIClientSessionResponse: {
|
||||
uint32 count = pack->ReadUInt32();
|
||||
for(uint32 i = 0; i < count; ++i) {
|
||||
char *p = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(p);
|
||||
RemoteCallSubscriptionHandler::Instance()->ClearConnection(p);
|
||||
safe_delete_array(p);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
std::cout << " Unknown ZSopcode:" << (int)pack->opcode;
|
||||
std::cout << " size:" << pack->size << std::endl;
|
||||
|
||||
@ -58,6 +58,8 @@
|
||||
#include "../common/rulesys.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "QuestParserCollection.h"
|
||||
#include "remote_call.h"
|
||||
#include "remote_call_subscribe.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
@ -790,6 +792,7 @@ void Zone::Shutdown(bool quite)
|
||||
LogFile->write(EQEMuLog::Normal, "Zone shutdown: going to sleep");
|
||||
ZoneLoaded = false;
|
||||
|
||||
RemoteCallSubscriptionHandler::Instance()->ClearAllConnections();
|
||||
zone->ResetAuth();
|
||||
safe_delete(zone);
|
||||
dbasync->CommitWrites();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user