Launcher support added. Still missing UCS but thinking about maybe rewriting it completely

This commit is contained in:
KimLS 2017-01-05 22:25:01 -08:00
parent f6ca59fbc6
commit b7c5de144a
9 changed files with 209 additions and 298 deletions

View File

@ -9,7 +9,7 @@ namespace EQ
namespace Net namespace Net
{ {
inline bool IsLittleEndian() { inline bool IsLittleEndian() {
static int32_t v = 1; const int32_t v = 1;
return 1 == *(int8_t*)&v; return 1 == *(int8_t*)&v;
} }

View File

@ -91,9 +91,6 @@ int main(int argc, char *argv[]) {
std::map<std::string, ZoneLaunch *> zones; std::map<std::string, ZoneLaunch *> zones;
WorldServer world(zones, launcher_name.c_str(), Config); WorldServer world(zones, launcher_name.c_str(), Config);
if (!world.Connect()) {
Log.Out(Logs::Detail, Logs::Launcher, "worldserver.Connect() FAILED! Will retry.");
}
std::map<std::string, ZoneLaunch *>::iterator zone, zend; std::map<std::string, ZoneLaunch *>::iterator zone, zend;
std::set<std::string> to_remove; std::set<std::string> to_remove;
@ -108,11 +105,6 @@ int main(int argc, char *argv[]) {
//Advance the timer to our current point in time //Advance the timer to our current point in time
Timer::SetCurrentTime(); Timer::SetCurrentTime();
/*
* Process the world connection
*/
world.Process();
/* /*
* Let the process manager look for dead children * Let the process manager look for dead children
*/ */
@ -143,19 +135,8 @@ int main(int argc, char *argv[]) {
zones.erase(rem); zones.erase(rem);
} }
EQ::EventLoop::Get().Process();
if (InterserverTimer.Check()) { Sleep(1);
if (world.TryReconnect() && (!world.Connected()))
world.AsyncConnect();
}
/*
* Take a nice nap until next cycle
*/
if(zones.empty())
Sleep(5000);
else
Sleep(2000);
} }
//try to be semi-nice about this... without waiting too long //try to be semi-nice about this... without waiting too long

View File

@ -25,25 +25,27 @@
#include "zone_launch.h" #include "zone_launch.h"
WorldServer::WorldServer(std::map<std::string, ZoneLaunch *> &zones, const char *name, const EQEmuConfig *config) WorldServer::WorldServer(std::map<std::string, ZoneLaunch *> &zones, const char *name, const EQEmuConfig *config)
: WorldConnection(EmuTCPConnection::packetModeLauncher, config->SharedKey.c_str()), : m_name(name),
m_name(name),
m_config(config), m_config(config),
m_zones(zones) m_zones(zones)
{ {
m_connection.reset(new EQ::Net::ServertalkClient(config->WorldIP, config->WorldTCPPort, false, "Launcher", config->SharedKey));
m_connection->OnConnect([this](EQ::Net::ServertalkClient *client) {
OnConnected();
});
m_connection->OnMessage(std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2));
} }
WorldServer::~WorldServer() { WorldServer::~WorldServer() {
} }
void WorldServer::OnConnected() { void WorldServer::OnConnected() {
WorldConnection::OnConnected();
auto pack = new ServerPacket(ServerOP_LauncherConnectInfo, sizeof(LauncherConnectInfo)); auto pack = new ServerPacket(ServerOP_LauncherConnectInfo, sizeof(LauncherConnectInfo));
LauncherConnectInfo* sci = (LauncherConnectInfo*) pack->pBuffer; LauncherConnectInfo* sci = (LauncherConnectInfo*) pack->pBuffer;
strn0cpy(sci->name, m_name, sizeof(sci->name)); strn0cpy(sci->name, m_name, sizeof(sci->name));
// sci->port = net.GetZonePort(); m_connection->SendPacket(pack);
// strcpy(sci->address, net.GetZoneAddress());
SendPacket(pack);
safe_delete(pack); safe_delete(pack);
//send status for all zones... //send status for all zones...
@ -55,16 +57,11 @@ void WorldServer::OnConnected() {
} }
} }
void WorldServer::Process() { void WorldServer::HandleMessage(uint16 opcode, EQ::Net::Packet &p) {
ServerPacket tpack(opcode, p);
ServerPacket *pack = &tpack;
WorldConnection::Process(); switch(opcode) {
if (!Connected())
return;
ServerPacket *pack = 0;
while((pack = tcpc.PopPacket())) {
switch(pack->opcode) {
case 0: { case 0: {
break; break;
} }
@ -73,12 +70,6 @@ void WorldServer::Process() {
// ignore this // ignore this
break; break;
} }
case ServerOP_ZAAuthFailed: {
Log.Out(Logs::Detail, Logs::Launcher, "World server responded 'Not Authorized', disabling reconnect");
pTryReconnect = false;
Disconnect();
break;
}
case ServerOP_LauncherZoneRequest: { case ServerOP_LauncherZoneRequest: {
if(pack->size != sizeof(LauncherZoneRequest)) { if(pack->size != sizeof(LauncherZoneRequest)) {
Log.Out(Logs::Detail, Logs::Launcher, "Invalid size of LauncherZoneRequest: %d", pack->size); Log.Out(Logs::Detail, Logs::Launcher, "Invalid size of LauncherZoneRequest: %d", pack->size);
@ -130,8 +121,6 @@ void WorldServer::Process() {
break; break;
} }
} }
safe_delete(pack);
}
} }
@ -144,12 +133,6 @@ void WorldServer::SendStatus(const char *short_name, uint32 start_count, bool ru
it->start_count = start_count; it->start_count = start_count;
it->running = running?1:0; it->running = running?1:0;
SendPacket(pack); m_connection->SendPacket(pack);
safe_delete(pack); safe_delete(pack);
} }

View File

@ -18,7 +18,8 @@
#ifndef WORLDSERVER_H #ifndef WORLDSERVER_H
#define WORLDSERVER_H #define WORLDSERVER_H
#include "../common/worldconn.h" #include "../common/net/servertalk_client_connection.h"
#include <memory>
#include <string> #include <string>
#include <queue> #include <queue>
#include <map> #include <map>
@ -26,18 +27,19 @@
class ZoneLaunch; class ZoneLaunch;
class EQEmuConfig; class EQEmuConfig;
class WorldServer : public WorldConnection { class WorldServer {
public: public:
WorldServer(std::map<std::string, ZoneLaunch *> &zones, const char *name, const EQEmuConfig *config); WorldServer(std::map<std::string, ZoneLaunch *> &zones, const char *name, const EQEmuConfig *config);
virtual ~WorldServer(); ~WorldServer();
virtual void Process(); void HandleMessage(uint16 opcode, EQ::Net::Packet &p);
void SendStatus(const char *short_name, uint32 start_count, bool running); void SendStatus(const char *short_name, uint32 start_count, bool running);
private: private:
virtual void OnConnected(); virtual void OnConnected();
std::unique_ptr<EQ::Net::ServertalkClient> m_connection;
const char *const m_name; const char *const m_name;
const EQEmuConfig *const m_config; const EQEmuConfig *const m_config;
std::map<std::string, ZoneLaunch *> &m_zones; std::map<std::string, ZoneLaunch *> &m_zones;

View File

@ -34,7 +34,7 @@
extern LauncherList launcher_list; extern LauncherList launcher_list;
LauncherLink::LauncherLink(int id, EmuTCPConnection *c) LauncherLink::LauncherLink(int id, std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
: ID(id), : ID(id),
tcpc(c), tcpc(c),
authenticated(false), authenticated(false),
@ -43,69 +43,35 @@ LauncherLink::LauncherLink(int id, EmuTCPConnection *c)
{ {
m_dynamicCount = 0; m_dynamicCount = 0;
m_bootTimer.Disable(); m_bootTimer.Disable();
tcpc->OnMessage(std::bind(&LauncherLink::ProcessMessage, this, std::placeholders::_1, std::placeholders::_2));
m_process_timer.reset(new EQ::Timer(100, true, std::bind(&LauncherLink::Process, this, std::placeholders::_1)));
} }
LauncherLink::~LauncherLink() { LauncherLink::~LauncherLink() {
tcpc->Free();
} }
bool LauncherLink::Process() { void LauncherLink::Process(EQ::Timer *t) {
if (!tcpc->Connected()) if (m_bootTimer.Check(false)) {
return false;
if(m_bootTimer.Check(false)) {
//force a boot on any zone which isnt running. //force a boot on any zone which isnt running.
std::map<std::string, ZoneState>::iterator cur, end; std::map<std::string, ZoneState>::iterator cur, end;
cur = m_states.begin(); cur = m_states.begin();
end = m_states.end(); end = m_states.end();
for(; cur != end; ++cur) { for (; cur != end; ++cur) {
if(!cur->second.up) { if (!cur->second.up) {
StartZone(cur->first.c_str(), cur->second.port); StartZone(cur->first.c_str(), cur->second.port);
} }
} }
m_bootTimer.Disable(); m_bootTimer.Disable();
} }
}
ServerPacket *pack = 0; void LauncherLink::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
while((pack = tcpc->PopPacket())) { {
if (!authenticated) { ServerPacket tpack(opcode, p);
if (WorldConfig::get()->SharedKey.length() > 0) { ServerPacket *pack = &tpack;
if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) {
uint8 tmppass[16]; switch(opcode) {
MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass);
if (memcmp(pack->pBuffer, tmppass, 16) == 0)
authenticated = true;
else {
struct in_addr in;
in.s_addr = GetIP();
Log.Out(Logs::Detail, Logs::World_Server, "Launcher authorization failed.");
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
SendPacket(pack);
delete pack;
Disconnect();
return false;
}
}
else {
struct in_addr in;
in.s_addr = GetIP();
Log.Out(Logs::Detail, Logs::World_Server, "Launcher authorization failed.");
auto pack = new ServerPacket(ServerOP_ZAAuthFailed);
SendPacket(pack);
delete pack;
Disconnect();
return false;
}
}
else
{
Log.Out(Logs::Detail, Logs::World_Server,"**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthroized zone access.");
authenticated = true;
}
delete pack;
continue;
}
switch(pack->opcode) {
case 0: case 0:
break; break;
case ServerOP_KeepAlive: { case ServerOP_KeepAlive: {
@ -176,10 +142,6 @@ bool LauncherLink::Process() {
break; break;
} }
} }
delete pack;
}
return(true);
} }
bool LauncherLink::ContainsZone(const char *short_name) const { bool LauncherLink::ContainsZone(const char *short_name) const {

View File

@ -18,8 +18,10 @@
#ifndef LAUNCHERLINK_H_ #ifndef LAUNCHERLINK_H_
#define LAUNCHERLINK_H_ #define LAUNCHERLINK_H_
#include "../common/emu_tcp_connection.h"
#include "../common/timer.h" #include "../common/timer.h"
#include "../net/servertalk_server_connection.h"
#include "../event/timer.h"
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
@ -28,19 +30,20 @@ class ServerPacket;
class LauncherLink { class LauncherLink {
public: public:
LauncherLink(int id, EmuTCPConnection *tcpc); LauncherLink(int id, std::shared_ptr<EQ::Net::ServertalkServerConnection> tcpc);
~LauncherLink(); ~LauncherLink();
bool Process(); void Process(EQ::Timer *t);
bool SendPacket(ServerPacket* pack) { return tcpc->SendPacket(pack); } void ProcessMessage(uint16 opcode, EQ::Net::Packet &p);
// bool SendPacket(TCPConnection::TCPNetPacket_Struct* tnps) { return tcpc->SendPacket(tnps); } void SendPacket(ServerPacket* pack) { tcpc->SendPacket(pack); }
int GetID() const { return(ID); } int GetID() const { return(ID); }
void Disconnect() { tcpc->Disconnect(); } void Disconnect() { if (tcpc->Handle()) { tcpc->Handle()->Disconnect(); } }
inline bool HasName() const { return(m_name.length() > 0); } inline bool HasName() const { return(m_name.length() > 0); }
inline uint32 GetIP() const { return tcpc->GetrIP(); } inline std::string GetIP() const { return tcpc->Handle() ? tcpc->Handle()->RemoteIP() : 0; }
inline uint16 GetPort() const { return tcpc->GetrPort(); } inline uint16 GetPort() const { return tcpc->Handle() ? tcpc->Handle()->RemotePort() : 0; }
inline std::string GetUUID() const { return tcpc->GetUUID(); }
inline const char * GetName() const { return(m_name.c_str()); } inline const char * GetName() const { return(m_name.c_str()); }
inline int CountZones() const { return(m_states.size()); } inline int CountZones() const { return(m_states.size()); }
@ -60,7 +63,8 @@ public:
protected: protected:
const int ID; const int ID;
EmuTCPConnection*const tcpc; std::shared_ptr<EQ::Net::ServertalkServerConnection> tcpc;
std::unique_ptr<EQ::Timer> m_process_timer;
bool authenticated; bool authenticated;
std::string m_name; std::string m_name;
Timer m_bootTimer; Timer m_bootTimer;

View File

@ -52,17 +52,11 @@ LauncherList::~LauncherList() {
} }
void LauncherList::Process() { void LauncherList::Process() {
//process pending launchers..
std::vector<LauncherLink *>::iterator cur; std::vector<LauncherLink *>::iterator cur;
cur = m_pendingLaunchers.begin(); cur = m_pendingLaunchers.begin();
while(cur != m_pendingLaunchers.end()) { while(cur != m_pendingLaunchers.end()) {
LauncherLink *l = *cur; LauncherLink *l = *cur;
if(!l->Process()) { if(l->HasName()) {
//launcher has died before it identified itself.
Log.Out(Logs::Detail, Logs::World_Server, "Removing pending launcher %d", l->GetID());
cur = m_pendingLaunchers.erase(cur);
delete l;
} else if(l->HasName()) {
//launcher has identified itself now. //launcher has identified itself now.
//remove ourself from the pending list //remove ourself from the pending list
cur = m_pendingLaunchers.erase(cur); cur = m_pendingLaunchers.erase(cur);
@ -81,21 +75,6 @@ void LauncherList::Process() {
++cur; ++cur;
} }
} }
//process active launchers.
std::map<std::string, LauncherLink *>::iterator curl;
curl = m_launchers.begin();
while(curl != m_launchers.end()) {
LauncherLink *l = curl->second;
if(!l->Process()) {
//launcher has died before it identified itself.
Log.Out(Logs::Detail, Logs::World_Server, "Removing launcher %s (%d)", l->GetName(), l->GetID());
curl = m_launchers.erase(curl);
delete l;
} else {
++curl;
}
}
} }
LauncherLink *LauncherList::Get(const char *name) { LauncherLink *LauncherList::Get(const char *name) {
@ -104,16 +83,6 @@ LauncherLink *LauncherList::Get(const char *name) {
if(res == m_launchers.end()) if(res == m_launchers.end())
return(nullptr); return(nullptr);
return(res->second); return(res->second);
/* std::string goal(name);
std::vector<LauncherLink *>::iterator cur, end;
cur = m_launchers.begin();
end = m_launchers.end();
for(; cur != end; cur++) {
if(goal == (*cur)->GetName())
return(*cur);
}
return(nullptr);*/
} }
LauncherLink *LauncherList::FindByZone(const char *short_name) { LauncherLink *LauncherList::FindByZone(const char *short_name) {
@ -127,12 +96,33 @@ LauncherLink *LauncherList::FindByZone(const char *short_name) {
return(nullptr); return(nullptr);
} }
void LauncherList::Add(EmuTCPConnection *conn) { void LauncherList::Add(std::shared_ptr<EQ::Net::ServertalkServerConnection> conn) {
auto it = new LauncherLink(nextID++, conn); auto it = new LauncherLink(nextID++, conn);
Log.Out(Logs::Detail, Logs::World_Server, "Adding pending launcher %d", it->GetID()); Log.Out(Logs::Detail, Logs::World_Server, "Adding pending launcher %d", it->GetID());
m_pendingLaunchers.push_back(it); m_pendingLaunchers.push_back(it);
} }
void LauncherList::Remove(std::shared_ptr<EQ::Net::ServertalkServerConnection> conn)
{
auto pendingLauncherIter = m_pendingLaunchers.begin();
while (pendingLauncherIter != m_pendingLaunchers.end()) {
if ((*pendingLauncherIter)->GetUUID() == conn->GetUUID()) {
m_pendingLaunchers.erase(pendingLauncherIter);
break;
}
++pendingLauncherIter;
}
auto launcherIter = m_launchers.begin();
while (launcherIter != m_launchers.end()) {
if (launcherIter->second->GetUUID() == conn->GetUUID()) {
m_launchers.erase(launcherIter);
break;
}
++launcherIter;
}
}
int LauncherList::GetLauncherCount() { int LauncherList::GetLauncherCount() {
return(m_launchers.size()); return(m_launchers.size());

View File

@ -19,12 +19,13 @@
#define LAUNCHERLIST_H_ #define LAUNCHERLIST_H_
#include "../common/types.h" #include "../common/types.h"
#include "../net/servertalk_server_connection.h"
#include <map> #include <map>
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory>
class LauncherLink; class LauncherLink;
class EmuTCPConnection;
class EQLConfig; class EQLConfig;
class LauncherList { class LauncherList {
@ -39,7 +40,8 @@ public:
void CreateLauncher(const char *name, uint8 dynamic_count); void CreateLauncher(const char *name, uint8 dynamic_count);
void Remove(const char *name); void Remove(const char *name);
void Add(EmuTCPConnection *conn); void Add(std::shared_ptr<EQ::Net::ServertalkServerConnection> conn);
void Remove(std::shared_ptr<EQ::Net::ServertalkServerConnection> conn);
LauncherLink *Get(const char *name); LauncherLink *Get(const char *name);
LauncherLink *FindByZone(const char *short_name); LauncherLink *FindByZone(const char *short_name);
@ -49,7 +51,6 @@ public:
protected: protected:
std::map<std::string, EQLConfig *> m_configs; //we own these objects std::map<std::string, EQLConfig *> m_configs; //we own these objects
std::map<std::string, LauncherLink *> m_launchers; //we own these objects std::map<std::string, LauncherLink *> m_launchers; //we own these objects
// std::map<std::string, EQLConfig *> m_configs; //we own these objects
std::vector<LauncherLink *> m_pendingLaunchers; //we own these objects, have not yet identified themself std::vector<LauncherLink *> m_pendingLaunchers; //we own these objects, have not yet identified themself
int nextID; int nextID;
}; };

View File

@ -409,6 +409,20 @@ int main(int argc, char** argv) {
zoneserver_list.Remove(connection->GetUUID()); zoneserver_list.Remove(connection->GetUUID());
}); });
server_connection->OnConnectionIdentified("Launcher", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
Log.OutF(Logs::General, Logs::World_Server, "New Launcher connection from {2} at {0}:{1}",
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
launcher_list.Add(connection);
});
server_connection->OnConnectionRemoved("Launcher", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
Log.OutF(Logs::General, Logs::World_Server, "Removed Launcher connection from {0}",
connection->GetUUID());
launcher_list.Remove(connection);
});
server_connection->OnConnectionIdentified("QueryServ", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) { server_connection->OnConnectionIdentified("QueryServ", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
Log.OutF(Logs::General, Logs::World_Server, "New Query Server connection from {2} at {0}:{1}", Log.OutF(Logs::General, Logs::World_Server, "New Query Server connection from {2} at {0}:{1}",
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
@ -479,32 +493,6 @@ int main(int argc, char** argv) {
client_list.Process(); client_list.Process();
//while ((tcpc = tcps.NewQueuePop())) {
// struct in_addr in;
// in.s_addr = tcpc->GetrIP();
//
// /* World - Tell what is being connected */
// if (tcpc->GetMode() == EmuTCPConnection::modePacket) {
// if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) {
// Log.Out(Logs::General, Logs::World_Server, "New Zone Server from %s:%d", inet_ntoa(in), tcpc->GetrPort());
// }
// else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) {
// Log.Out(Logs::General, Logs::World_Server, "New Launcher from %s:%d", inet_ntoa(in), tcpc->GetrPort());
// }
// else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS) {
// Log.Out(Logs::General, Logs::World_Server, "New UCS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort());
// }
// else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeQueryServ) {
// Log.Out(Logs::General, Logs::World_Server, "New QS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort());
// }
// else {
// Log.Out(Logs::General, Logs::World_Server, "Unsupported packet mode from %s:%d", inet_ntoa(in), tcpc->GetrPort());
// }
// }
//
// console_list.Add(new Console(tcpc));
//}
if(PurgeInstanceTimer.Check()) if(PurgeInstanceTimer.Check())
{ {
database.PurgeExpiredInstances(); database.PurgeExpiredInstances();