mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-16 13:58:22 +00:00
svn -> git Migration
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2006 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
|
||||
*/
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "LauncherLink.h"
|
||||
#include "LauncherList.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "../common/logsys.h"
|
||||
#include "../common/md5.h"
|
||||
#include "../common/packet_dump.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/EmuTCPConnection.h"
|
||||
#include "worlddb.h"
|
||||
#include "EQLConfig.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
extern LauncherList launcher_list;
|
||||
|
||||
|
||||
LauncherLink::LauncherLink(int id, EmuTCPConnection *c)
|
||||
: ID(id),
|
||||
tcpc(c),
|
||||
authenticated(false),
|
||||
m_name(""),
|
||||
m_bootTimer(2000)
|
||||
{
|
||||
m_dynamicCount = 0;
|
||||
m_bootTimer.Disable();
|
||||
}
|
||||
|
||||
LauncherLink::~LauncherLink() {
|
||||
tcpc->Free();
|
||||
}
|
||||
|
||||
bool LauncherLink::Process() {
|
||||
if (!tcpc->Connected())
|
||||
return false;
|
||||
|
||||
if(m_bootTimer.Check(false)) {
|
||||
//force a boot on any zone which isnt running.
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(!cur->second.up) {
|
||||
StartZone(cur->first.c_str());
|
||||
}
|
||||
}
|
||||
m_bootTimer.Disable();
|
||||
}
|
||||
|
||||
ServerPacket *pack = 0;
|
||||
while((pack = tcpc->PopPacket())) {
|
||||
_hex(WORLD__ZONE_TRACE,pack->pBuffer,pack->size);
|
||||
if (!authenticated) {
|
||||
if (WorldConfig::get()->SharedKey.length() > 0) {
|
||||
if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) {
|
||||
uint8 tmppass[16];
|
||||
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(WORLD__LAUNCH_ERR, "Launcher authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
_log(WORLD__LAUNCH_ERR, "Launcher authorization failed.");
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log(WORLD__LAUNCH,"**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:
|
||||
break;
|
||||
case ServerOP_KeepAlive: {
|
||||
// ignore this
|
||||
break;
|
||||
}
|
||||
case ServerOP_ZAAuth: {
|
||||
_log(WORLD__LAUNCH, "Got authentication from %s when they are already authenticated.", m_name.c_str());
|
||||
break;
|
||||
}
|
||||
case ServerOP_LauncherConnectInfo: {
|
||||
const LauncherConnectInfo *it = (const LauncherConnectInfo *) pack->pBuffer;
|
||||
if(HasName()) {
|
||||
_log(WORLD__LAUNCH_ERR, "Launcher '%s' received an additional connect packet with name '%s'. Ignoring.", m_name.c_str(), it->name);
|
||||
break;
|
||||
}
|
||||
m_name = it->name;
|
||||
|
||||
EQLConfig *config = launcher_list.GetConfig(m_name.c_str());
|
||||
if(config == NULL) {
|
||||
_log(WORLD__LAUNCH, "Unknown launcher '%s' connected. Disconnecting.", it->name);
|
||||
Disconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
_log(WORLD__LAUNCH, "Launcher Identified itself as '%s'. Loading zone list.", it->name);
|
||||
|
||||
std::vector<LauncherZone> result;
|
||||
//database.GetLauncherZones(it->name, result);
|
||||
config->GetZones(result);
|
||||
|
||||
std::vector<LauncherZone>::iterator cur, end;
|
||||
cur = result.begin();
|
||||
end = result.end();
|
||||
ZoneState zs;
|
||||
for(; cur != end; cur++) {
|
||||
zs.port = cur->port;
|
||||
zs.up = false;
|
||||
zs.starts = 0;
|
||||
_log(WORLD__LAUNCH_TRACE, "%s: Loaded zone '%s' on port %d", m_name.c_str(), cur->name.c_str(), zs.port);
|
||||
m_states[cur->name] = zs;
|
||||
}
|
||||
|
||||
//now we add all the dynamics.
|
||||
BootDynamics(config->GetDynamicCount());
|
||||
|
||||
m_bootTimer.Start();
|
||||
|
||||
break;
|
||||
}
|
||||
case ServerOP_LauncherZoneStatus: {
|
||||
const LauncherZoneStatus *it = (const LauncherZoneStatus *) pack->pBuffer;
|
||||
std::map<std::string, ZoneState>::iterator res;
|
||||
res = m_states.find(it->short_name);
|
||||
if(res == m_states.end()) {
|
||||
_log(WORLD__LAUNCH_ERR, "%s: reported state for zone %s which it does not have.", m_name.c_str(), it->short_name);
|
||||
break;
|
||||
}
|
||||
_log(WORLD__LAUNCH, "%s: %s reported state %s (%d starts)", m_name.c_str(), it->short_name, it->running?"STARTED":"STOPPED", it->start_count);
|
||||
res->second.up = it->running;
|
||||
res->second.starts = it->start_count;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_log(WORLD__LAUNCH_ERR, "Unknown ServerOPcode from launcher 0x%04x, size %d",pack->opcode,pack->size);
|
||||
DumpPacket(pack->pBuffer, pack->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete pack;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool LauncherLink::ContainsZone(const char *short_name) const {
|
||||
return(m_states.find(short_name) != m_states.end());
|
||||
|
||||
/*
|
||||
* std::map<std::string, bool>::const_iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(
|
||||
}*/
|
||||
}
|
||||
|
||||
void LauncherLink::BootZone(const char *short_name, uint16 port) {
|
||||
ZoneState zs;
|
||||
zs.port = port;
|
||||
zs.up = false;
|
||||
zs.starts = 0;
|
||||
_log(WORLD__LAUNCH_TRACE, "%s: Loaded zone '%s' on port %d", m_name.c_str(), short_name, zs.port);
|
||||
m_states[short_name] = zs;
|
||||
|
||||
StartZone(short_name);
|
||||
}
|
||||
|
||||
void LauncherLink::StartZone(const char *short_name) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Start;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LauncherLink::RestartZone(const char *short_name) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Restart;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LauncherLink::StopZone(const char *short_name) {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_LauncherZoneRequest, sizeof(LauncherZoneRequest));
|
||||
LauncherZoneRequest* s = (LauncherZoneRequest *) pack->pBuffer;
|
||||
|
||||
strn0cpy(s->short_name, short_name, 32);
|
||||
s->command = ZR_Stop;
|
||||
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
void LauncherLink::BootDynamics(uint8 new_count) {
|
||||
if(m_dynamicCount == new_count)
|
||||
return;
|
||||
|
||||
ZoneState zs;
|
||||
if(m_dynamicCount < new_count) {
|
||||
//we are booting more dynamics.
|
||||
|
||||
zs.port = 0;
|
||||
zs.up = false;
|
||||
zs.starts = 0;
|
||||
|
||||
int r;
|
||||
char nbuf[20];
|
||||
uint8 index;
|
||||
//"for each zone we need to boot"
|
||||
for(r = m_dynamicCount; r < new_count; r++) {
|
||||
//find an idle ID
|
||||
for(index = m_dynamicCount+1; index < 255; index++) {
|
||||
sprintf(nbuf, "dynamic_%02d", index);
|
||||
if(m_states.find(nbuf) != m_states.end())
|
||||
continue;
|
||||
m_states[nbuf] = zs;
|
||||
StartZone(nbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_dynamicCount = new_count;
|
||||
} else if(new_count == 0) {
|
||||
//kill all zones...
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
StopZone(cur->first.c_str());
|
||||
}
|
||||
} else {
|
||||
//need to get rid of some zones...
|
||||
|
||||
//quick and dirty way to do this.. should do better (like looking for idle zones)
|
||||
int found = 0;
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
if(cur->first.find("dynamic_") == 0) {
|
||||
if(found >= new_count) {
|
||||
//this zone exceeds the number of allowed booted zones.
|
||||
StopZone(cur->first.c_str());
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_dynamicCount = new_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LauncherLink::GetZoneList(std::vector<std::string> &l) {
|
||||
std::map<std::string, ZoneState>::iterator cur, end;
|
||||
cur = m_states.begin();
|
||||
end = m_states.end();
|
||||
for(; cur != end; cur++) {
|
||||
l.push_back(cur->first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherLink::GetZoneDetails(const char *short_name, std::map<std::string,std::string> &res) {
|
||||
res.clear();
|
||||
|
||||
std::map<std::string, ZoneState>::iterator r;
|
||||
r = m_states.find(short_name);
|
||||
if(r == m_states.end()) {
|
||||
res["error"] = "Zone Not Found";
|
||||
res["name"] = short_name;
|
||||
res["up"] = "0";
|
||||
res["starts"] = "0";
|
||||
res["port"] = "0";
|
||||
} else {
|
||||
res["name"] = r->first;
|
||||
res["up"] = r->second.up?"1":"0";
|
||||
res["starts"] = itoa(r->second.starts);
|
||||
res["port"] = itoa(r->second.port);
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherLink::Shutdown() {
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ShutdownAll);
|
||||
SendPacket(pack);
|
||||
delete pack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user