TCP cleanup, added basis of web interface

This commit is contained in:
KimLS
2017-01-08 19:00:39 -08:00
parent 08e72bbbdd
commit 124728e0c7
43 changed files with 690 additions and 6442 deletions
+4 -14
View File
@@ -6,23 +6,17 @@ SET(world_sources
client.cpp
cliententry.cpp
clientlist.cpp
CMakeLists.txt
eql_config.cpp
eqw.cpp
eqw_http_handler.cpp
eqw_parser.cpp
http_request.cpp
launcher_link.cpp
launcher_list.cpp
lfplist.cpp
login_server.cpp
login_server_list.cpp
net.cpp
perl_eql_config.cpp
perl_eqw.cpp
perl_http_request.cpp
queryserv.cpp
ucs.cpp
web_interface.cpp
web_interface_eqw.cpp
wguild_mgr.cpp
world_config.cpp
worlddb.cpp
@@ -37,12 +31,7 @@ SET(world_headers
client.h
cliententry.h
clientlist.h
CMakeLists.txt
eql_config.h
eqw.h
eqw_http_handler.h
eqw_parser.h
http_request.h
launcher_link.h
launcher_list.h
lfplist.h
@@ -52,10 +41,11 @@ SET(world_headers
queryserv.h
sof_char_create_data.h
ucs.h
web_interface.h
web_interface_eqw.h
wguild_mgr.h
world_config.h
worlddb.h
world_tcp_connection.h
zonelist.h
zoneserver.h
)
+2 -2
View File
@@ -21,15 +21,15 @@
#include "zoneserver.h"
#include "zonelist.h"
#include "client.h"
#include "console.h"
#include "worlddb.h"
#include "../common/string_util.h"
#include "../common/guilds.h"
#include "../common/races.h"
#include "../common/classes.h"
#include "../common/packet_dump.h"
#include "wguild_mgr.h"
#include "../common/misc.h"
#include "../common/misc_functions.h"
#include "wguild_mgr.h"
#include <set>
-854
View File
@@ -1,854 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
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/global_define.h"
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include "../common/version.h"
#include "console.h"
#include "zoneserver.h"
#include "worlddb.h"
#include "../common/packet_dump.h"
#include "../common/seperator.h"
#include "../common/eq_packet_structs.h"
#include "../common/eq_packet.h"
#include "login_server.h"
#include "login_server_list.h"
#include "../common/serverinfo.h"
#include "../common/md5.h"
#include "../common/opcodemgr.h"
#include "../common/rulesys.h"
#include "../common/ruletypes.h"
#include "../common/string_util.h"
#include "world_config.h"
#include "zoneserver.h"
#include "zonelist.h"
#include "clientlist.h"
#include "launcher_list.h"
#include "ucs.h"
#include "queryserv.h"
#ifdef _WINDOWS
#define snprintf _snprintf
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#endif
extern ZSList zoneserver_list;
extern uint32 numzones;
extern LoginServerList loginserverlist;
extern ClientList client_list;
extern LauncherList launcher_list;
extern UCSConnection UCSLink;
extern QueryServConnection QSLink;
extern volatile bool RunLoops;
ConsoleList console_list;
void CatchSignal(int sig_num);
Console::Console(EmuTCPConnection* itcpc)
: WorldTCPConnection(),
timeout_timer(RuleI(Console, SessionTimeOut)),
prompt_timer(1000)
{
tcpc = itcpc;
tcpc->SetEcho(true);
state = 0;
paccountid = 0;
memset(paccountname, 0, sizeof(paccountname));
admin = 0;
pAcceptMessages = false;
}
Console::~Console() {
if (tcpc)
tcpc->Free();
}
void Console::Die() {
state = CONSOLE_STATE_CLOSED;
struct in_addr in;
in.s_addr = GetIP();
Log.Out(Logs::Detail, Logs::World_Server,"Removing console from %s:%d",inet_ntoa(in),GetPort());
tcpc->Disconnect();
}
bool Console::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
if (!pAcceptMessages)
return false;
switch (scm->chan_num) {
if(RuleB(Chat, ServerWideAuction)){
case 4: {
SendMessage(1, "%s auctions, '%s'", scm->from, scm->message);
break;
}
}
if(RuleB(Chat, ServerWideOOC)){
case 5: {
SendMessage(1, "%s says ooc, '%s'", scm->from, scm->message);
break;
}
}
case 6: {
SendMessage(1, "%s BROADCASTS, '%s'", scm->from, scm->message);
break;
}
case 7: {
SendMessage(1, "[%s] tells you, '%s'", scm->from, scm->message);
auto pack = new ServerPacket(ServerOP_ChannelMessage,
sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
memcpy(pack->pBuffer, scm, pack->size);
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*) pack->pBuffer;
strcpy(scm2->deliverto, scm2->from);
scm2->noreply = true;
client_list.SendPacket(scm->from, pack);
safe_delete(pack);
break;
}
case 11: {
SendMessage(1, "%s GMSAYS, '%s'", scm->from, scm->message);
break;
}
default: {
return false;
}
}
return true;
}
bool Console::SendEmoteMessage(uint32 type, const char* message, ...) {
if (!message)
return false;
if (!pAcceptMessages)
return false;
va_list argptr;
char buffer[1024];
va_start(argptr, message);
vsnprintf(buffer, sizeof(buffer), message, argptr);
va_end(argptr);
SendMessage(1, message);
return true;
}
bool Console::SendEmoteMessageRaw(uint32 type, const char* message) {
if (!message)
return false;
if (!pAcceptMessages)
return false;
SendMessage(1, message);
return true;
}
void Console::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) {
if (!message)
return;
if (to_guilddbid != 0 || to_minstatus > Admin())
return;
va_list argptr;
char buffer[1024];
va_start(argptr, message);
vsnprintf(buffer, sizeof(buffer), message, argptr);
va_end(argptr);
SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, buffer);
}
void Console::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message) {
if (!message)
return;
if (to_guilddbid != 0 || to_minstatus > Admin())
return;
SendMessage(1, message);
}
void Console::SendMessage(uint8 newline, const char* message, ...) {
if (!message)
return;
char* buffer = 0;
uint32 bufsize = 1500;
if (message)
bufsize += strlen(message);
buffer = new char[bufsize];
memset(buffer, 0, bufsize);
if (message != 0) {
va_list argptr;
va_start(argptr, message);
vsnprintf(buffer, bufsize - 512, message, argptr);
va_end(argptr);
}
if (newline) {
char outbuf[3];
outbuf[0] = 13;
outbuf[1] = 10;
outbuf[2] = 0;
for (int i=0; i < newline; i++)
strcat(buffer, outbuf);
}
tcpc->Send((uchar*) buffer, strlen(buffer));
safe_delete_array(buffer);
}
bool Console::Process() {
if (state == CONSOLE_STATE_CLOSED)
return false;
if (!tcpc->Connected()) {
struct in_addr in;
in.s_addr = GetIP();
Log.Out(Logs::Detail, Logs::World_Server,"Removing console (!tcpc->Connected) from %s:%d",inet_ntoa(in),GetPort());
return false;
}
//if we have not gotten the special markers after this timer, send login prompt
if(prompt_timer.Check()) {
prompt_timer.Disable();
if(tcpc->GetMode() == EmuTCPConnection::modeConsole)
tcpc->Send((const uchar*) "Username: ", strlen("Username: "));
}
if (timeout_timer.Check()) {
SendMessage(1, 0);
SendMessage(1, "Timeout, disconnecting...");
struct in_addr in;
in.s_addr = GetIP();
Log.Out(Logs::Detail, Logs::World_Server,"TCP connection timeout from %s:%d",inet_ntoa(in),GetPort());
return false;
}
if (tcpc->GetMode() == EmuTCPConnection::modePacket) {
struct in_addr in;
in.s_addr = GetIP();
//if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) {
// auto zs = new ZoneServer(tcpc);
// Log.Out(Logs::Detail, Logs::World_Server,"New zoneserver #%d from %s:%d", zs->GetID(), inet_ntoa(in), GetPort());
// zoneserver_list.Add(zs);
// numzones++;
// tcpc = 0;
//} else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) {
// Log.Out(Logs::Detail, Logs::World_Server,"New launcher from %s:%d", inet_ntoa(in), GetPort());
// launcher_list.Add(tcpc);
// tcpc = 0;
//}
//else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS)
//{
// Log.Out(Logs::Detail, Logs::World_Server,"New UCS Connection from %s:%d", inet_ntoa(in), GetPort());
// UCSLink.SetConnection(tcpc);
// tcpc = 0;
//}
//else {
// Log.Out(Logs::Detail, Logs::World_Server,"Unsupported packet mode from %s:%d", inet_ntoa(in), GetPort());
//}
return false;
}
char* command = 0;
while ((command = tcpc->PopLine())) {
timeout_timer.Start();
ProcessCommand(command);
delete command;
}
return true;
}
void ConsoleList::Add(Console* con) {
list.Insert(con);
}
void ConsoleList::Process() {
LinkedListIterator<Console*> iterator(list);
iterator.Reset();
while(iterator.MoreElements()) {
if (!iterator.GetData()->Process())
iterator.RemoveCurrent();
else
iterator.Advance();
}
}
void ConsoleList::KillAll() {
LinkedListIterator<Console*> iterator(list);
iterator.Reset();
while(iterator.MoreElements()) {
iterator.GetData()->Die();
iterator.RemoveCurrent();
}
}
void ConsoleList::SendConsoleWho(WorldTCPConnection* connection, const char* to, int16 admin, char** output, uint32* outsize, uint32* outlen) {
LinkedListIterator<Console*> iterator(list);
iterator.Reset();
struct in_addr in;
int x = 0;
while(iterator.MoreElements()) {
in.s_addr = iterator.GetData()->GetIP();
if (admin >= iterator.GetData()->Admin())
AppendAnyLenString(output, outsize, outlen, " Console: %s:%i AccID: %i AccName: %s", inet_ntoa(in), iterator.GetData()->GetPort(), iterator.GetData()->AccountID(), iterator.GetData()->AccountName());
else
AppendAnyLenString(output, outsize, outlen, " Console: AccID: %i AccName: %s", iterator.GetData()->AccountID(), iterator.GetData()->AccountName());
if (*outlen >= 3584) {
connection->SendEmoteMessageRaw(to, 0, 0, 10, *output);
safe_delete(*output);
*outsize = 0;
*outlen = 0;
}
else {
if (connection->IsConsole())
AppendAnyLenString(output, outsize, outlen, "\r\n");
else
AppendAnyLenString(output, outsize, outlen, "\n");
}
x++;
iterator.Advance();
}
AppendAnyLenString(output, outsize, outlen, "%i consoles connected", x);
}
void ConsoleList::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
LinkedListIterator<Console*> iterator(list);
iterator.Reset();
while(iterator.MoreElements()) {
iterator.GetData()->SendChannelMessage(scm);
iterator.Advance();
}
}
void ConsoleList::SendEmoteMessage(uint32 type, const char* message, ...) {
va_list argptr;
char buffer[1024];
va_start(argptr, message);
vsnprintf(buffer, sizeof(buffer), message, argptr);
va_end(argptr);
SendEmoteMessageRaw(type, buffer);
}
void ConsoleList::SendEmoteMessageRaw(uint32 type, const char* message) {
LinkedListIterator<Console*> iterator(list);
iterator.Reset();
while(iterator.MoreElements()) {
iterator.GetData()->SendEmoteMessageRaw(type, message);
iterator.Advance();
}
}
Console* ConsoleList::FindByAccountName(const char* accname) {
LinkedListIterator<Console*> iterator(list);
iterator.Reset();
while(iterator.MoreElements()) {
if (strcasecmp(iterator.GetData()->AccountName(), accname) == 0)
return iterator.GetData();
iterator.Advance();
}
return 0;
}
void Console::ProcessCommand(const char* command) {
switch(state)
{
case CONSOLE_STATE_USERNAME:
{
if (strlen(command) >= 16) {
SendMessage(1, 0);
SendMessage(2, "Username buffer overflow.");
SendMessage(1, "Bye Bye.");
state = CONSOLE_STATE_CLOSED;
return;
}
strcpy(paccountname, command);
state = CONSOLE_STATE_PASSWORD;
SendMessage(0, "Password: ");
tcpc->SetEcho(false);
break;
}
case CONSOLE_STATE_PASSWORD:
{
if (strlen(command) >= 16) {
SendMessage(1, 0);
SendMessage(2, "Password buffer overflow.");
SendMessage(1, "Bye Bye.");
state = CONSOLE_STATE_CLOSED;
return;
}
paccountid = database.CheckLogin(paccountname ,command);
if (paccountid == 0) {
SendMessage(1, 0);
SendMessage(2, "Login failed.");
SendMessage(1, "Bye Bye.");
state = CONSOLE_STATE_CLOSED;
return;
}
database.GetAccountName(paccountid, paccountname); // fixes case and stuff
admin = database.CheckStatus(paccountid);
if (!(admin >= consoleLoginStatus)) {
SendMessage(1, 0);
SendMessage(2, "Access denied.");
SendMessage(1, "Bye Bye.");
state = CONSOLE_STATE_CLOSED;
return;
}
Log.Out(Logs::Detail, Logs::World_Server,"TCP console authenticated: Username=%s, Admin=%d",paccountname,admin);
SendMessage(1, 0);
SendMessage(2, "Login accepted.");
state = CONSOLE_STATE_CONNECTED;
tcpc->SetEcho(true);
SendPrompt();
break;
}
case CONSOLE_STATE_CONNECTED: {
Log.Out(Logs::Detail, Logs::World_Server,"TCP command: %s: \"%s\"",paccountname ,command);
Seperator sep(command);
if (strcasecmp(sep.arg[0], "help") == 0 || strcmp(sep.arg[0], "?") == 0) {
SendMessage(1, " whoami");
SendMessage(1, " who");
SendMessage(1, " zonestatus");
SendMessage(1, " uptime [zoneID#]");
SendMessage(1, " emote [zonename or charname or world] [type] [message]");
SendMessage(1, " echo [on/off]");
SendMessage(1, " acceptmessages [on/off]");
SendMessage(1, " tell [name] [message]");
SendMessage(1, " broadcast [message]");
SendMessage(1, " gmsay [message]");
SendMessage(1, " ooc [message]");
SendMessage(1, " auction [message]");
if (admin >= consoleKickStatus)
SendMessage(1, " kick [charname]");
if (admin >= consoleLockStatus)
SendMessage(1, " lock/unlock");
if (admin >= consoleZoneStatus) {
SendMessage(1, " zoneshutdown [zonename or ZoneServerID]");
SendMessage(1, " zonebootup [ZoneServerID] [zonename]");
SendMessage(1, " zonelock [list|lock|unlock] [zonename]");
}
if (admin >= consoleFlagStatus)
SendMessage(1, " flag [status] [accountname]");
if (admin >= consolePassStatus)
SendMessage(1, " setpass [accountname] [newpass]");
if (admin >= consoleWorldStatus) {
SendMessage(1, " version");
SendMessage(1, " worldshutdown");
}
if (admin >= 201) {
SendMessage(1, " IPLookup [name]");
}
if (admin >= 100) {
SendMessage(1, " signalcharbyname charname ID");
SendMessage(1, " reloadworld");
}
}
else if (strcasecmp(sep.arg[0], "ping") == 0) {
// do nothing
}
else if (strcasecmp(sep.arg[0], "signalcharbyname") == 0) {
SendMessage(1, "Signal Sent to %s with ID %i", (char*) sep.arg[1], atoi(sep.arg[2]));
uint32 message_len = strlen((char*) sep.arg[1]) + 1;
auto pack = new ServerPacket(ServerOP_CZSignalClientByName,
sizeof(CZClientSignalByName_Struct) + message_len);
CZClientSignalByName_Struct* CZSC = (CZClientSignalByName_Struct*) pack->pBuffer;
strn0cpy(CZSC->Name, (char*) sep.arg[1], 64);
CZSC->data = atoi(sep.arg[2]);
zoneserver_list.SendPacket(pack);
safe_delete(pack);
}
else if (strcasecmp(sep.arg[0], "setpass") == 0 && admin >= consolePassStatus) {
if (sep.argnum != 2)
SendMessage(1, "Format: setpass accountname password");
else {
int16 tmpstatus = 0;
uint32 tmpid = database.GetAccountIDByName(sep.arg[1], &tmpstatus);
if (!tmpid)
SendMessage(1, "Error: Account not found");
else if (tmpstatus > admin)
SendMessage(1, "Cannot change password: Account's status is higher than yours");
else if (database.SetLocalPassword(tmpid, sep.arg[2]))
SendMessage(1, "Password changed.");
else
SendMessage(1, "Error changing password.");
}
}
else if (strcasecmp(sep.arg[0], "uptime") == 0) {
if (sep.IsNumber(1) && atoi(sep.arg[1]) > 0) {
auto pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct));
ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer;
snprintf(sus->adminname, sizeof(sus->adminname), "*%s", this->GetName());
sus->zoneserverid = atoi(sep.arg[1]);
ZoneServer* zs = zoneserver_list.FindByID(sus->zoneserverid);
if (zs)
zs->SendPacket(pack);
else
SendMessage(1, "Zoneserver not found.");
delete pack;
}
else {
ZSList::ShowUpTime(this);
}
}
else if (strcasecmp(sep.arg[0], "md5") == 0) {
uint8 md5[16];
MD5::Generate((const uchar*) sep.argplus[1], strlen(sep.argplus[1]), md5);
SendMessage(1, "MD5: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);
}
else if (strcasecmp(sep.arg[0], "whoami") == 0) {
SendMessage(1, "You are logged in as '%s'", this->AccountName());
SendMessage(1, "You are known as '*%s'", this->AccountName());
SendMessage(1, "AccessLevel: %d", this->Admin());
}
else if (strcasecmp(sep.arg[0], "echo") == 0) {
if (strcasecmp(sep.arg[1], "on") == 0)
tcpc->SetEcho(true);
else if (strcasecmp(sep.arg[1], "off") == 0) {
if (pAcceptMessages)
SendMessage(1, "Echo can not be turned off while acceptmessages is on");
else
tcpc->SetEcho(false);
}
else
SendMessage(1, "Usage: echo [on/off]");
}
else if (strcasecmp(sep.arg[0], "acceptmessages") == 0) {
if (strcasecmp(sep.arg[1], "on") == 0)
if (tcpc->GetEcho())
SendMessage(1, "AcceptMessages can not be turned on while echo is on");
else
pAcceptMessages = true;
else if (strcasecmp(sep.arg[1], "off") == 0)
pAcceptMessages = false;
else
SendMessage(1, "Usage: acceptmessages [on/off]");
}
else if (strcasecmp(sep.arg[0], "tell") == 0) {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
zoneserver_list.SendChannelMessage(tmpname, sep.arg[1], 7, 0, sep.argplus[2]);
}
else if (strcasecmp(sep.arg[0], "broadcast") == 0) {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
zoneserver_list.SendChannelMessage(tmpname, 0, 6, 0, sep.argplus[1]);
}
else if (strcasecmp(sep.arg[0], "ooc") == 0) {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
zoneserver_list.SendChannelMessage(tmpname, 0, 5, 0, sep.argplus[1]);
}
else if (strcasecmp(sep.arg[0], "auction") == 0) {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
zoneserver_list.SendChannelMessage(tmpname, 0, 4, 0, sep.argplus[1]);
}
else if (strcasecmp(sep.arg[0], "gmsay") == 0 || strcasecmp(sep.arg[0], "pr") == 0) {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
zoneserver_list.SendChannelMessage(tmpname, 0, 11, 0, sep.argplus[1]);
}
else if (strcasecmp(sep.arg[0], "emote") == 0) {
if (strcasecmp(sep.arg[1], "world") == 0)
zoneserver_list.SendEmoteMessageRaw(0, 0, 0, atoi(sep.arg[2]), sep.argplus[3]);
else {
ZoneServer* zs = zoneserver_list.FindByName(sep.arg[1]);
if (zs != 0)
zs->SendEmoteMessageRaw(0, 0, 0, atoi(sep.arg[2]), sep.argplus[3]);
else
zoneserver_list.SendEmoteMessageRaw(sep.arg[1], 0, 0, atoi(sep.arg[2]), sep.argplus[3]);
}
}
else if (strcasecmp(sep.arg[0], "movechar") == 0) {
if(sep.arg[1][0]==0 || sep.arg[2][0] == 0)
SendMessage(1, "Usage: movechar [charactername] [zonename]");
else {
if (!database.GetZoneID(sep.arg[2]))
SendMessage(1, "Error: Zone '%s' not found", sep.arg[2]);
else if (!database.CheckUsedName((char*) sep.arg[1])) {
if (!database.MoveCharacterToZone((char*) sep.arg[1], (char*) sep.arg[2]))
SendMessage(1, "Character Move Failed!");
else
SendMessage(1, "Character has been moved.");
}
else
SendMessage(1, "Character Does Not Exist");
}
}
else if (strcasecmp(sep.arg[0], "flag") == 0 && this->Admin() >= consoleFlagStatus) {
// SCORPIOUS2K - reversed parameter order for flag
if(sep.arg[2][0]==0 || !sep.IsNumber(1))
SendMessage(1, "Usage: flag [status] [accountname]");
else
{
if (atoi(sep.arg[1]) > this->Admin())
SendMessage(1, "You cannot set people's status to higher than your own");
else if (atoi(sep.arg[1]) < 0 && this->Admin() < consoleFlagStatus)
SendMessage(1, "You have too low of status to change flags");
else if (!database.SetAccountStatus(sep.arg[2], atoi(sep.arg[1])))
SendMessage(1, "Unable to flag account!");
else
SendMessage(1, "Account Flaged");
}
}
else if (strcasecmp(sep.arg[0], "kick") == 0 && admin >= consoleKickStatus) {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
auto pack = new ServerPacket;
pack->opcode = ServerOP_KickPlayer;
pack->size = sizeof(ServerKickPlayer_Struct);
pack->pBuffer = new uchar[pack->size];
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
strcpy(skp->adminname, tmpname);
strcpy(skp->name, sep.arg[1]);
skp->adminrank = this->Admin();
zoneserver_list.SendPacket(pack);
delete pack;
}
else if (strcasecmp(sep.arg[0], "who") == 0) {
auto whom = new Who_All_Struct;
memset(whom, 0, sizeof(Who_All_Struct));
whom->lvllow = 0xFFFF;
whom->lvlhigh = 0xFFFF;
whom->wclass = 0xFFFF;
whom->wrace = 0xFFFF;
whom->gmlookup = 0xFFFF;
for (int i=1; i<=sep.argnum; i++) {
if (strcasecmp(sep.arg[i], "gm") == 0)
whom->gmlookup = 1;
else if (sep.IsNumber(i)) {
if (whom->lvllow == 0xFFFF) {
whom->lvllow = atoi(sep.arg[i]);
whom->lvlhigh = whom->lvllow;
}
else if (atoi(sep.arg[i]) > int(whom->lvllow))
whom->lvlhigh = atoi(sep.arg[i]);
else
whom->lvllow = atoi(sep.arg[i]);
}
else
strn0cpy(whom->whom, sep.arg[i], sizeof(whom->whom));
}
client_list.ConsoleSendWhoAll(0, admin, whom, this);
delete whom;
}
else if (strcasecmp(sep.arg[0], "zonestatus") == 0) {
zoneserver_list.SendZoneStatus(0, admin, this);
}
else if (strcasecmp(sep.arg[0], "exit") == 0 || strcasecmp(sep.arg[0], "quit") == 0) {
SendMessage(1, "Bye Bye.");
state = CONSOLE_STATE_CLOSED;
}
else if (strcasecmp(sep.arg[0], "zoneshutdown") == 0 && admin >= consoleZoneStatus) {
if (sep.arg[1][0] == 0) {
SendMessage(1, "Usage: zoneshutdown zoneshortname");
} else {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
auto pack = new ServerPacket;
pack->size = sizeof(ServerZoneStateChange_struct);
pack->pBuffer = new uchar[pack->size];
memset(pack->pBuffer, 0, sizeof(ServerZoneStateChange_struct));
ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer;
pack->opcode = ServerOP_ZoneShutdown;
strcpy(s->adminname, tmpname);
if (sep.arg[1][0] >= '0' && sep.arg[1][0] <= '9')
s->ZoneServerID = atoi(sep.arg[1]);
else
s->zoneid = database.GetZoneID(sep.arg[1]);
ZoneServer* zs = 0;
if (s->ZoneServerID != 0)
zs = zoneserver_list.FindByID(s->ZoneServerID);
else if (s->zoneid != 0)
zs = zoneserver_list.FindByName(database.GetZoneName(s->zoneid));
else
SendMessage(1, "Error: ZoneShutdown: neither ID nor name specified");
if (zs == 0)
SendMessage(1, "Error: ZoneShutdown: zoneserver not found");
else
zs->SendPacket(pack);
delete pack;
}
}
else if (strcasecmp(sep.arg[0], "zonebootup") == 0 && admin >= consoleZoneStatus) {
if (sep.arg[2][0] == 0 || !sep.IsNumber(1)) {
SendMessage(1, "Usage: zonebootup ZoneServerID# zoneshortname");
} else {
char tmpname[64];
tmpname[0] = '*';
strcpy(&tmpname[1], paccountname);
Log.Out(Logs::Detail, Logs::World_Server,"Console ZoneBootup: %s, %s, %s",tmpname,sep.arg[2],sep.arg[1]);
zoneserver_list.SOPZoneBootup(tmpname, atoi(sep.arg[1]), sep.arg[2], (bool) (strcasecmp(sep.arg[3], "static") == 0));
}
}
else if (strcasecmp(sep.arg[0], "worldshutdown") == 0 && admin >= consoleWorldStatus) {
int32 time, interval;
if(sep.IsNumber(1) && sep.IsNumber(2) && ((time=atoi(sep.arg[1]))>0) && ((interval=atoi(sep.arg[2]))>0)) {
zoneserver_list.WorldShutDown(time, interval);
}
else if(strcasecmp(sep.arg[1], "now") == 0) {
zoneserver_list.WorldShutDown(0, 0);
}
else if(strcasecmp(sep.arg[1], "disable") == 0) {
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World shutdown aborted.");
zoneserver_list.SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World shutdown aborted.");
zoneserver_list.shutdowntimer->Disable();
zoneserver_list.reminder->Disable();
}
else {
SendMessage(1, "Usage: worldshutdown [now] [disable] ([time] [interval])");
//Go ahead and shut down since that's what this used to do when invoked this way.
zoneserver_list.WorldShutDown(0, 0);
}
}
else if (strcasecmp(sep.arg[0], "lock") == 0 && admin >= consoleLockStatus) {
WorldConfig::LockWorld();
if (loginserverlist.Connected()) {
loginserverlist.SendStatus();
SendMessage(1, "World locked.");
}
else {
SendMessage(1, "World locked, but login server not connected.");
}
}
else if (strcasecmp(sep.arg[0], "unlock") == 0 && admin >= consoleLockStatus) {
WorldConfig::UnlockWorld();
if (loginserverlist.Connected()) {
loginserverlist.SendStatus();
SendMessage(1, "World unlocked.");
}
else {
SendMessage(1, "World unlocked, but login server not connected.");
}
}
else if (strcasecmp(sep.arg[0], "version") == 0 && admin >= consoleWorldStatus) {
SendMessage(1, "Current version information.");
SendMessage(1, " %s", CURRENT_VERSION);
SendMessage(1, " Compiled on: %s at %s", COMPILE_DATE, COMPILE_TIME);
SendMessage(1, " Last modified on: %s", LAST_MODIFIED);
}
else if (strcasecmp(sep.arg[0], "serverinfo") == 0 && admin >= 200) {
if (strcasecmp(sep.arg[1], "os") == 0) {
#ifdef _WINDOWS
GetOS();
char intbuffer [sizeof(unsigned long)];
SendMessage(1, "Operating system information.");
SendMessage(1, " %s", Ver_name);
SendMessage(1, " Build number: %s", ultoa(Ver_build, intbuffer, 10));
SendMessage(1, " Minor version: %s", ultoa(Ver_min, intbuffer, 10));
SendMessage(1, " Major version: %s", ultoa(Ver_maj, intbuffer, 10));
SendMessage(1, " Platform Id: %s", ultoa(Ver_pid, intbuffer, 10));
#else
char os_string[100];
SendMessage(1, "Operating system information.");
SendMessage(1, " %s", GetOS(os_string));
#endif
}
else {
SendMessage(1, "Usage: Serverinfo [type]");
SendMessage(1, " OS - Operating system version information.");
}
}
else if (strcasecmp(sep.arg[0], "IPLookup") == 0 && admin >= 201) {
client_list.SendCLEList(admin, 0, this, sep.argplus[1]);
}
else if (strcasecmp(sep.arg[0], "zonelock") == 0 && admin >= consoleZoneStatus) {
if (strcasecmp(sep.arg[1], "list") == 0) {
zoneserver_list.ListLockedZones(0, this);
}
else if (strcasecmp(sep.arg[1], "lock") == 0 && admin >= 101) {
uint16 tmp = database.GetZoneID(sep.arg[2]);
if (tmp) {
if (zoneserver_list.SetLockedZone(tmp, true))
zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone locked: %s", database.GetZoneName(tmp));
else
SendMessage(1, "Failed to change lock");
}
else
SendMessage(1, "Usage: #zonelock lock [zonename]");
}
else if (strcasecmp(sep.arg[1], "unlock") == 0 && admin >= 101) {
uint16 tmp = database.GetZoneID(sep.arg[2]);
if (tmp) {
if (zoneserver_list.SetLockedZone(tmp, false))
zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone unlocked: %s", database.GetZoneName(tmp));
else
SendMessage(1, "Failed to change lock");
}
else
SendMessage(1, "Usage: #zonelock unlock [zonename]");
}
else {
SendMessage(1, "#zonelock sub-commands");
SendMessage(1, " list");
if (admin >= 101) {
SendMessage(1, " lock [zonename]");
SendMessage(1, " unlock [zonename]");
}
}
}
else if (strcasecmp(sep.arg[0], "reloadworld") == 0 && admin > 101)
{
SendEmoteMessage(0,0,0,15,"Reloading World...");
auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct));
ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer;
RW->Option = 1;
zoneserver_list.SendPacket(pack);
safe_delete(pack);
}
else if (strcasecmp(sep.arg[0], "") == 0){
/* Hit Enter with no command */
}
else {
SendMessage(1, "Command unknown.");
}
if (state == CONSOLE_STATE_CONNECTED)
SendPrompt();
break;
}
default: {
break;
}
}
}
void Console::SendPrompt() {
if (tcpc->GetEcho())
SendMessage(0, "%s> ", paccountname);
}
-109
View File
@@ -1,109 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
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 CONSOLE_H
#define CONSOLE_H
enum {
consoleLoginStatus = 50, //ability to log in, basic commands.
httpLoginStatus = 100, //can log into the HTTP interface
consoleFlagStatus = 200, //flag
consoleKickStatus = 150, //kick
consoleLockStatus = 150, //world lock/unlock
consoleZoneStatus = 150, //zone up/down/lock
consolePassStatus = 200, //change password
consoleWorldStatus = 200, //world shutdown
consoleOpcodesStatus = 250
};
#define CONSOLE_STATE_USERNAME 0
#define CONSOLE_STATE_PASSWORD 1
#define CONSOLE_STATE_CONNECTED 2
#define CONSOLE_STATE_CLOSED 3
#include "../common/linked_list.h"
#include "../common/timer.h"
#include "../common/queue.h"
#include "../common/emu_tcp_connection.h"
#include "world_tcp_connection.h"
#include "../common/mutex.h"
struct ServerChannelMessage_Struct;
class Console : public WorldTCPConnection {
public:
Console(EmuTCPConnection* itcpc);
virtual ~Console();
virtual inline bool IsConsole() { return true; }
bool Process();
void Send(const char* message);
int16 Admin() { return admin; }
uint32 GetIP() { return tcpc->GetrIP(); }
uint16 GetPort() { return tcpc->GetrPort(); }
void ProcessCommand(const char* command);
void Die();
bool SendChannelMessage(const ServerChannelMessage_Struct* scm);
bool SendEmoteMessage(uint32 type, const char* message, ...);
bool SendEmoteMessageRaw(uint32 type, const char* message);
void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...);
void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message);
void SendMessage(uint8 newline, const char* message, ...);
const char* GetName() { return paccountname; }
const char* AccountName() { return paccountname; }
uint32 AccountID() { return paccountid; }
private:
EmuTCPConnection* tcpc;
Timer timeout_timer;
Timer prompt_timer;
void SendPrompt();
uint32 paccountid;
char paccountname[30];
bool pAcceptMessages;
uint8 state;
int16 admin;
uchar textbuf[1024];
int bufindex;
};
class ConsoleList
{
public:
ConsoleList() {}
~ConsoleList() {}
void Add(Console* con);
void Process();
void KillAll();
void SendChannelMessage(const ServerChannelMessage_Struct* scm);
void SendConsoleWho(WorldTCPConnection* connection, const char* to, int16 admin, char** output, uint32* outsize, uint32* outlen);
void SendEmoteMessage(uint32 type, const char* message, ...);
void SendEmoteMessageRaw(uint32 type, const char* message);
Console* FindByAccountName(const char* accname);
private:
LinkedList<Console*> list;
};
#endif
-335
View File
@@ -1,335 +0,0 @@
/* 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/global_define.h"
#include "eqw_http_handler.h"
#include "../common/SocketLib/Base64.h"
#include "eqw_parser.h"
#include "eqw.h"
#include "http_request.h"
#include "worlddb.h"
#include "console.h"
Mime EQWHTTPHandler::s_mime;
#ifdef EMBPERL
EQWParser *EQWHTTPHandler::s_parser = nullptr;
#endif
const int EQWHTTPHandler::READ_BUFFER_LEN = 1024; //for page IO, was a static const member, but VC6 got mad.
EQWHTTPHandler::EQWHTTPHandler(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort)
: HttpdSocket(ID,in_socket,irIP,irPort),
m_closeOnFinish(false)
{
}
EQWHTTPHandler::~EQWHTTPHandler() {
}
#ifdef EMBPERL
EQWParser *EQWHTTPHandler::GetParser() {
if(s_parser == nullptr) {
EQW::Singleton()->ClearOutput();
s_parser = new EQWParser();
const std::string &res = EQW::Singleton()->GetOutput();
if(!res.empty()) {
printf("EQWParser Init output:\n%s\n\n", res.c_str());
EQW::Singleton()->ClearOutput();
}
}
return(s_parser);
}
#endif
/*void EQWHTTPHandler::OnWrite() {
HttpdSocket::OnWrite();
if(m_closeOnFinish && GetOutputLength() == 0) {
// printf("CLOSING\n");
Close();
}
}*/
void EQWHTTPHandler::Exec() {
m_sentHeaders = false;
m_responseCode = "200";
// printf("Request: %s, %s, %s, %s.\n", GetMethod().c_str(), GetUrl().c_str(), GetUri().c_str(), GetQueryString().c_str());
SetHttpVersion("HTTP/1.0");
AddResponseHeader("Connection", "close");
if(GetUri().find("..") != std::string::npos) {
SendResponse("403", "Forbidden");
printf("%s is forbidden.\n", GetUri().c_str());
return;
}
if(!CheckAuth()) {
AddResponseHeader("Content-type", "text/plain");
AddResponseHeader("WWW-Authenticate", "Basic realm=\"EQEmulator\"");
SendResponse("401", "Authorization Required");
SendString("Gotta Authenticate.");
} else {
std::string::size_type start = GetUri().find_first_not_of('/');
std::string page;
if(start != std::string::npos)
page = GetUri().substr(start);
else
page = "index.html";
SendPage(page);
}
/* if (!Detach()) {
printf("Unable to detach...\n");
}
if(GetOutputLength() > 0) {
//we cannot close yet
m_closeOnFinish = true;
} else {
Close();
}*/
Free(); //the "app" side (us) is done with this connection too...
Disconnect();
}
void EQWHTTPHandler::OnHeader(const std::string& key,const std::string& value) {
HttpdSocket::OnHeader(key, value);
if (!strcasecmp(key.c_str(),"Authorization")) {
if(strncasecmp(value.c_str(), "Basic ", 6)) {
printf("Invalid auth type. Expected Basic: %s\n", value.c_str());
return;
}
std::string dec;
Base64::decode(value.c_str() + 6, dec);
std::string::size_type cpos;
cpos = dec.find_first_of(':');
if(cpos == std::string::npos) {
printf("Invalid auth string: %s\n", dec.c_str());
return;
}
m_username = dec.substr(0, cpos);
m_password = dec.substr(cpos+1);
}
}
//we should prolly cache login info here... if we load a fresh page, we could be checking
//their auth dozens of times rather quickly...
bool EQWHTTPHandler::CheckAuth() const {
if(m_username.length() < 1)
return(false);
int16 status = 0;
uint32 acctid = database.CheckLogin(m_username.c_str(), m_password.c_str(), &status);
if(acctid == 0) {
Log.Out(Logs::Detail, Logs::World_Server, "Login autentication failed for %s with '%s'", m_username.c_str(), m_password.c_str());
return(false);
}
if(status < httpLoginStatus) {
Log.Out(Logs::Detail, Logs::World_Server, "Login of %s failed: status too low.", m_username.c_str());
return(false);
}
return(true);
}
void EQWHTTPHandler::SendPage(const std::string &file) {
std::string path = "templates/";
path += file;
FILE *f = fopen(path.c_str(), "rb");
if(f == nullptr) {
SendResponse("404", "Not Found");
SendString("Not found.");
printf("%s not found.\n", file.c_str());
return;
}
std::string type = s_mime.GetMimeFromFilename(file);
AddResponseHeader("Content-type", type);
bool process = false;
#ifdef EMBPERL
if(type == "text/html")
process = true;
else {
//not processing, send headers right away
#endif
SendResponse("200", "OK");
#ifdef EMBPERL
}
#endif
auto buffer = new char[READ_BUFFER_LEN + 1];
size_t len;
std::string to_process;
while((len = fread(buffer, 1, READ_BUFFER_LEN, f)) > 0) {
buffer[len] = '\0';
if(process)
to_process += buffer;
else
SendBuf(buffer, len);
}
delete[] buffer;
fclose(f);
#ifdef EMBPERL
if(process) {
//convert the base form into a useful perl exportable form
HTTPRequest req(this, GetHttpForm());
GetParser()->SetHTTPRequest("testing", &req);
//parse out the page and potentially pass some stuff on to perl.
ProcessAndSend(to_process);
//clear out the form, just in case (since it gets destroyed next)
GetParser()->SetHTTPRequest("testing", nullptr);
}
#endif
}
bool EQWHTTPHandler::LoadMimeTypes(const char *filename) {
return(s_mime.LoadMimeFile(filename));
}
#ifdef EMBPERL
void EQWHTTPHandler::ProcessAndSend(const std::string &str) {
std::string::size_type len = str.length();
std::string::size_type start = 0;
std::string::size_type pos, end;
while((pos = str.find("<?", start)) != std::string::npos) {
//send all the crap leading up to the script block
if(pos != start) {
ProcessText(str.c_str() + start, pos-start);
}
//look for the end of this script block...
end = str.find("?>", pos+2);
if(end == std::string::npos) {
//terminal ?> not found... should issue a warning or something...
std::string scriptBody = str.substr(pos+2);
ProcessScript(scriptBody);
start = len;
break;
} else {
//script only consumes some of this buffer...
std::string scriptBody = str.substr(pos+2, end-pos-2);
ProcessScript(scriptBody);
start = end + 2;
}
}
//send whatever is left over
if(start != len)
ProcessText(str.c_str() + start, len-start);
}
void EQWHTTPHandler::ProcessScript(const std::string &script_body) {
const char *script = script_body.c_str();
if(strcmp("perl", script) == 0)
script += 4; //allow <?perl
// printf("Script: ''''%s''''\n\n", script_body.c_str());
GetParser()->EQW_eval("testing", script_body.c_str());
const std::string &res = EQW::Singleton()->GetOutput();
if(!res.empty()) {
ProcessText(res.c_str(), res.length());
EQW::Singleton()->ClearOutput();
}
}
void EQWHTTPHandler::ProcessText(const char *txt, int len) {
if(!m_sentHeaders) {
SendResponse(m_responseCode, "OK");
m_sentHeaders = true;
}
SendBuf(txt, len);
}
#endif
EQWHTTPServer::EQWHTTPServer()
: m_port(0)
{
}
void EQWHTTPServer::CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort) {
auto conn = new EQWHTTPHandler(ID, in_socket, irIP, irPort);
AddConnection(conn);
}
void EQWHTTPServer::Stop() {
Log.Out(Logs::Detail, Logs::World_Server, "Requesting that HTTP Service stop.");
m_running = false;
Close();
}
bool EQWHTTPServer::Start(uint16 port, const char *mime_file) {
if(m_running) {
Log.Out(Logs::Detail, Logs::World_Server, "HTTP Service is already running on port %d", m_port);
return(false);
}
//load up our nice mime types
if(!EQWHTTPHandler::LoadMimeTypes(mime_file)) {
Log.Out(Logs::Detail, Logs::World_Server, "Failed to load mime types from '%s'", mime_file);
return(false);
} else {
Log.Out(Logs::Detail, Logs::World_Server, "Loaded mime types from %s", mime_file);
}
//fire up the server thread
char errbuf[TCPServer_ErrorBufferSize];
if(!Open(port, errbuf)) {
Log.Out(Logs::Detail, Logs::World_Server, "Unable to bind to port %d for HTTP service: %s", port, errbuf);
return(false);
}
m_running = true;
m_port = port;
/*
#ifdef _WINDOWS
_beginthread(ThreadProc, 0, this);
#else
pthread_create(&m_thread, nullptr, ThreadProc, this);
#endif*/
return(true);
}
/*
void EQWHTTPServer::Run() {
Log.LogDebugType(Logs::Detail, Logs::World_Server, "HTTP Processing thread started on port %d", m_port);
do {
#warning DELETE THIS IF YOU DONT USE IT
Sleep(10);
} while(m_running);
Log.LogDebugType(Logs::Detail, Logs::World_Server, "HTTP Processing thread terminating on port %d", m_port);
}
ThreadReturnType EQWHTTPServer::ThreadProc(void *data) {
((EQWHTTPServer *) data)->Run();
THREAD_RETURN(nullptr);
}*/
-98
View File
@@ -1,98 +0,0 @@
/* 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
*/
#ifndef EQWHTTPHandler_H
#define EQWHTTPHandler_H
#include "../common/tcp_server.h"
#include "../common/tcp_connection.h"
#include "../common/SocketLib/HttpdSocket.h"
#include "../common/SocketLib/Mime.h"
#include "../common/types.h"
class EQWParser;
class EQWHTTPHandler : public HttpdSocket {
static const int READ_BUFFER_LEN;
public:
EQWHTTPHandler(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort);
virtual ~EQWHTTPHandler();
void SetResponseCode(const char *code) { m_responseCode = code; }
//HttpdSocket interface:
virtual void Exec();
virtual void OnHeader(const std::string& key,const std::string& value);
static bool LoadMimeTypes(const char *filename);
protected:
bool CheckAuth() const;
void SendPage(const std::string &file);
//credentials
std::string m_username;
std::string m_password;
bool m_closeOnFinish;
std::string m_responseCode;
bool m_sentHeaders;
//our mime type manager
static Mime s_mime;
#ifdef EMBPERL
void ProcessAndSend(const std::string &entire_html_page);
void ProcessScript(const std::string &script_body);
void ProcessText(const char *txt, int len);
static EQWParser *GetParser();
private:
static EQWParser *s_parser;
#endif
};
class EQWHTTPServer : protected TCPServer<EQWHTTPHandler> {
public:
EQWHTTPServer();
bool Start(uint16 port, const char *mime_file);
void Stop();
protected:
volatile bool m_running;
uint16 m_port;
virtual void CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort);
/* //I decided to put this into its own thread so that the HTTP pages
//cannot block the main world server's operation.
static ThreadReturnType ThreadProc(void* tmp);
void Run();
#ifndef WIN32
pthread_t m_thread;
#endif*/
};
#endif
-346
View File
@@ -1,346 +0,0 @@
/* 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
*/
//a lot of this is copied from embperl.cpp, but I didnt feel like factoring the common stuff out
#ifdef EMBPERL
#include "../common/global_define.h"
#include "eqw_parser.h"
#include "eqw.h"
#include "../common/eqdb.h"
#include "worlddb.h"
#ifndef GvCV_set
#define GvCV_set(gv,cv) (GvCV(gv) = (cv))
#endif
XS(XS_EQWIO_PRINT);
//so embedded scripts can use xs extensions (ala 'use socket;')
EXTERN_C void boot_DynaLoader(pTHX_ CV* cv);
EXTERN_C XS(boot_EQW);
EXTERN_C XS(boot_EQDB);
EXTERN_C XS(boot_EQDBRes);
EXTERN_C XS(boot_HTTPRequest);
EXTERN_C XS(boot_EQLConfig);
EXTERN_C void xs_init(pTHX)
{
char file[256];
strncpy(file, __FILE__, 256);
file[255] = '\0';
char buf[128]; //shouldent have any function names longer than this.
//add the strcpy stuff to get rid of const warnings....
newXS(strcpy(buf, "DynaLoader::boot_DynaLoader"), boot_DynaLoader, file);
newXS(strcpy(buf, "EQW::boot_EQW"), boot_EQW, file);
newXS(strcpy(buf, "EQDB::boot_EQDB"), boot_EQDB, file);
newXS(strcpy(buf, "EQDBRes::boot_EQDBRes"), boot_EQDBRes, file);
newXS(strcpy(buf, "HTTPRequest::boot_HTTPRequest"), boot_HTTPRequest, file);
newXS(strcpy(buf, "EQLConfig::boot_EQLConfig"), boot_EQLConfig, file);
newXS(strcpy(buf, "EQWIO::PRINT"), XS_EQWIO_PRINT, file);
}
EQWParser::EQWParser() {
//setup perl...
my_perl = perl_alloc();
_empty_sv = newSV(0);
if(!my_perl)
Log.Out(Logs::Detail, Logs::World_Server, "Error: perl_alloc failed!");
else
DoInit();
}
void EQWParser::DoInit() {
const char *argv_eqemu[] = { "",
"-w", "-W",
"-e", "0;", nullptr };
int argc = 5;
char **argv = (char **)argv_eqemu;
char **env = { nullptr };
PL_perl_destruct_level = 1;
perl_construct(my_perl);
PERL_SYS_INIT3(&argc, &argv, &env);
perl_parse(my_perl, xs_init, argc, argv, env);
perl_run(my_perl);
//a little routine we use a lot.
eval_pv("sub my_eval {eval $_[0];}", TRUE); //dies on error
//ruin the perl exit and command:
eval_pv("sub my_exit {}",TRUE);
eval_pv("sub my_sleep {}",TRUE);
if(gv_stashpv("CORE::GLOBAL", FALSE)) {
GV *exitgp = gv_fetchpv("CORE::GLOBAL::exit", TRUE, SVt_PVCV);
GvCV_set(exitgp, perl_get_cv("my_exit", TRUE)); //dies on error
GvIMPORTED_CV_on(exitgp);
GV *sleepgp = gv_fetchpv("CORE::GLOBAL::sleep", TRUE, SVt_PVCV);
GvCV_set(sleepgp, perl_get_cv("my_sleep", TRUE)); //dies on error
GvIMPORTED_CV_on(sleepgp);
}
//setup eval_file
eval_pv(
"our %Cache;"
"use Symbol qw(delete_package);"
"sub eval_file {"
"my($package, $filename) = @_;"
"$filename=~s/\'//g;"
"if(! -r $filename) { print \"Unable to read perl file '$filename'\\n\"; return; }"
"my $mtime = -M $filename;"
"if(defined $Cache{$package}{mtime}&&$Cache{$package}{mtime} <= $mtime && !($package eq 'plugin')){"
" return;"
"} else {"
//we 'my' $filename,$mtime,$package,$sub to prevent them from changing our state up here.
" eval(\"package $package; my(\\$filename,\\$mtime,\\$package,\\$sub); \\$isloaded = 1; require '$filename'; \");"
"}"
"}"
,FALSE);
//make a tie-able class to capture IO and get it where it needs to go
eval_pv(
"package EQWIO; "
// "&boot_EQEmuIO;"
"sub TIEHANDLE { my $me = bless {}, $_[0]; $me->PRINT('Creating '.$me); return($me); } "
"sub WRITE { } "
"sub PRINTF { my $me = shift; my $fmt = shift; $me->PRINT(sprintf($fmt, @_)); } "
"sub CLOSE { my $me = shift; $me->PRINT('Closing '.$me); } "
"sub DESTROY { my $me = shift; $me->PRINT('Destroying '.$me); } "
//this ties us for all packages
"package MAIN;"
" if(tied *STDOUT) { untie(*STDOUT); }"
" if(tied *STDERR) { untie(*STDERR); }"
" tie *STDOUT, 'EQWIO';"
" tie *STDERR, 'EQWIO';"
,FALSE);
eval_pv(
"package world; "
,FALSE
);
//make sure the EQW pointer is set up in this package
EQW *curc = EQW::Singleton();
SV *l = get_sv("world::EQW", true);
if(curc != nullptr) {
sv_setref_pv(l, "EQW", curc);
} else {
//clear out the value, mainly to get rid of blessedness
sv_setsv(l, _empty_sv);
}
//make sure the EQDB pointer is set up in this package
EQDB::SetMySQL(database.getMySQL());
EQDB *curc_db = EQDB::Singleton();
SV *l_db = get_sv("world::EQDB", true);
if(curc_db != nullptr) {
sv_setref_pv(l_db, "EQDB", curc_db);
} else {
//clear out the value, mainly to get rid of blessedness
sv_setsv(l_db, _empty_sv);
}
//load up EQW
eval_pv(
"package EQW;"
"&boot_EQW;" //load our EQW XS
"package EQDB;"
"&boot_EQDB;" //load our EQW XS
"package EQDBRes;"
"&boot_EQDBRes;" //load our EQW XS
"package HTTPRequest;"
"&boot_HTTPRequest;" //load our HTTPRequest XS
"package EQLConfig;"
"&boot_EQLConfig;" //load our EQLConfig XS
, FALSE );
#ifdef EMBPERL_PLUGIN
Log.Out(Logs::Detail, Logs::World_Server, "Loading worldui perl plugins.");
std::string err;
if(!eval_file("world", "worldui.pl", err)) {
Log.Out(Logs::Detail, Logs::World_Server, "Warning - world.pl: %s", err.c_str());
}
eval_pv(
"package world; "
"if(opendir(D,'worldui')) { "
" my @d = readdir(D);"
" closedir(D);"
" foreach(@d){ "
" next unless(/\\.pl$); "
" require 'templates/'.$_;"
" }"
"}"
,FALSE);
#endif //EMBPERL_PLUGIN
}
EQWParser::~EQWParser() {
//removed to try to stop perl from exploding on reload, we'll see
/* eval_pv(
"package quest;"
" untie *STDOUT;"
" untie *STDERR;"
,FALSE);
*/
perl_free(my_perl);
}
bool EQWParser::eval_file(const char * packagename, const char * filename, std::string &error)
{
std::vector<std::string> args;
args.push_back(packagename);
args.push_back(filename);
return(dosub("eval_file", args, error));
}
bool EQWParser::dosub(const char * subname, const std::vector<std::string> &args, std::string &error, int mode) {
bool err = false;
dSP; // initialize stack pointer
ENTER; // everything created after here
SAVETMPS; // ...is a temporary variable
PUSHMARK(SP); // remember the stack pointer
if(!args.empty())
{
for (auto i = args.begin(); i != args.end(); ++i) { /* push the arguments onto the perl stack */
XPUSHs(sv_2mortal(newSVpv(i->c_str(), i->length())));
}
}
PUTBACK; // make local stack pointer global
call_pv(subname, mode); /*eval our code*/
SPAGAIN; // refresh stack pointer
if(SvTRUE(ERRSV)) {
err = true;
}
FREETMPS; // free temp values
LEAVE; // ...and the XPUSHed "mortal" args.
if(err) {
error = "Perl runtime error: ";
error += SvPVX(ERRSV);
return(false);
}
return(true);
}
bool EQWParser::eval(const char * code, std::string &error) {
std::vector<std::string> arg;
arg.push_back(code);
return(dosub("my_eval", arg, error, G_SCALAR|G_DISCARD|G_EVAL|G_KEEPERR));
}
void EQWParser::EQW_eval(const char *pkg, const char *code) {
char namebuf[64];
snprintf(namebuf, 64, "package %s;", pkg);
eval_pv(namebuf, FALSE);
//make sure the EQW pointer is set up
EQW *curc = EQW::Singleton();
snprintf(namebuf, 64, "EQW");
// snprintf(namebuf, 64, "%s::EQW", pkg);
SV *l = get_sv(namebuf, true);
if(curc != nullptr) {
sv_setref_pv(l, "EQW", curc);
} else {
//clear out the value, mainly to get rid of blessedness
sv_setsv(l, _empty_sv);
}
//make sure the EQDB pointer is set up
EQDB *curc_db = EQDB::Singleton();
snprintf(namebuf, 64, "EQDB");
// snprintf(namebuf, 64, "%s::EQW", pkg);
SV *l_db = get_sv(namebuf, true);
if(curc_db != nullptr) {
sv_setref_pv(l_db, "EQDB", curc_db);
} else {
//clear out the value, mainly to get rid of blessedness
sv_setsv(l_db, _empty_sv);
}
std::string err;
if(!eval(code, err)) {
EQW::Singleton()->AppendOutput(err.c_str());
}
}
void EQWParser::SetHTTPRequest(const char *pkg, HTTPRequest *it) {
char namebuf[64];
snprintf(namebuf, 64, "package %s;", pkg);
eval_pv(namebuf, FALSE);
snprintf(namebuf, 64, "request");
// snprintf(namebuf, 64, "%s::EQW", pkg);
SV *l = get_sv(namebuf, true);
if(it != nullptr) {
sv_setref_pv(l, "HTTPRequest", it);
} else {
//clear out the value, mainly to get rid of blessedness
sv_setsv(l, _empty_sv);
}
}
/*
$editors = array();
$editors["merchant"] = new MerchantEditor();
#... for other editors
if(defined($editors[$editor])) {
$edit = $editors[$editor];
$edit->dispatch($action);
}
class MerchantEditor extends BaseEditor {
MerchantEditor() {
$this->RegisterAction(0, "get_merchantlist", "merchant/merchant.tmpl.php", "no");
$this->RegisterAction(1, "get_merchantlist", "merchant/merchant.edit.tmpl.php", "no");
}
}
function dispatch() {
my $dispatcher = $this->_dispatchers[$action];
$body = new Template($dispatcher["template"]);
my $proc = $dispatcher["proc"];
$vars = $this->$proc();
if($dispatcher["guestmode"] == "no") {
check_authorization();
}
if ($vars) {
foreach ($vars as $key=>$value) {
$body->set($key, $value);
}
}
}
*/
#endif //EMBPERL
-72
View File
@@ -1,72 +0,0 @@
/* 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
*/
#ifndef EQWPARSER_H_
#define EQWPARSER_H_
#ifdef EMBPERL
#include <string>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <string>
#include "../common/useperl.h"
class HTTPRequest;
class EQWParser {
public:
EQWParser();
~EQWParser();
void EQW_eval(const char *pkg, const char *code);
void SetHTTPRequest(const char *pkg, HTTPRequest *it);
//put an integer into a perl varable
void seti(const char *varname, int val) const {
SV *t = get_sv(varname, true);
sv_setiv(t, val);
}
//put a real into a perl varable
void setd(const char *varname, float val) const {
SV *t = get_sv(varname, true);
sv_setnv(t, val);
}
//put a string into a perl varable
void setstr(const char *varname, const char *val) const {
SV *t = get_sv(varname, true);
sv_setpv(t, val);
}
protected:
void DoInit();
bool eval(const char * code, std::string &error);
bool dosub(const char * subname, const std::vector<std::string> &args, std::string &error, int mode = G_SCALAR|G_DISCARD|G_EVAL);
bool eval_file(const char * packagename, const char * filename, std::string &error);
//the embedded interpreter
PerlInterpreter * my_perl;
SV *_empty_sv;
};
#endif //EMBPERL
#endif /*EQWPARSER_H_*/
+1 -1
View File
@@ -24,8 +24,8 @@
#include "../common/md5.h"
#include "../common/packet_dump.h"
#include "../common/servertalk.h"
#include "../common/emu_tcp_connection.h"
#include "../common/string_util.h"
#include "../common/misc_functions.h"
#include "worlddb.h"
#include "eql_config.h"
+2 -1
View File
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include "../common/version.h"
#include "../common/servertalk.h"
#include "../common/misc_functions.h"
#include "login_server.h"
#include "login_server_list.h"
#include "../common/eq_packet_structs.h"
@@ -166,7 +167,7 @@ bool LoginServer::Connect() {
return false;
}
char errbuf[TCPConnection_ErrorBufferSize];
char errbuf[1024];
if ((LoginServerIP = ResolveIP(LoginServerAddress, errbuf)) == 0) {
Log.Out(Logs::Detail, Logs::World_Server, "Unable to resolve '%s' to an IP.",LoginServerAddress);
return false;
-1
View File
@@ -7,7 +7,6 @@
#include "../common/queue.h"
#include "../common/eq_packet_structs.h"
#include "../common/mutex.h"
#include "../common/emu_tcp_connection.h"
class LoginServer;
+21 -22
View File
@@ -21,10 +21,8 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "../common/global_define.h"
#include "../common/eqemu_logsys.h"
#include "../common/queue.h"
#include "../common/timer.h"
@@ -67,14 +65,11 @@
#endif
#include "../common/emu_tcp_server.h"
#include "../common/patches/patches.h"
#include "../common/random.h"
#include "zoneserver.h"
#include "console.h"
#include "login_server.h"
#include "login_server_list.h"
#include "eqw_http_handler.h"
#include "world_config.h"
#include "zoneserver.h"
#include "zonelist.h"
@@ -85,16 +80,15 @@
#include "adventure_manager.h"
#include "ucs.h"
#include "queryserv.h"
#include "web_interface.h"
#include "../common/net/tcp_server.h"
#include "../common/net/servertalk_server.h"
EmuTCPServer tcps;
ClientList client_list;
GroupLFPList LFPGroupList;
ZSList zoneserver_list;
LoginServerList loginserverlist;
EQWHTTPServer http_server;
UCSConnection UCSLink;
QueryServConnection QSLink;
LauncherList launcher_list;
@@ -106,6 +100,7 @@ uint32 numzones = 0;
bool holdzones = false;
const WorldConfig *Config;
EQEmuLogSys Log;
WebInterfaceList web_interface;
void CatchSignal(int sig_num);
@@ -130,22 +125,21 @@ int main(int argc, char** argv) {
Log.Out(Logs::General, Logs::World_Server, "Loading server configuration failed.");
return 1;
}
Config=WorldConfig::get();
Config = WorldConfig::get();
Log.Out(Logs::General, Logs::World_Server, "CURRENT_VERSION: %s", CURRENT_VERSION);
#ifdef _DEBUG
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
Log.Out(Logs::General, Logs::World_Server, "Could not set signal handler");
return 1;
}
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
Log.Out(Logs::General, Logs::World_Server, "Could not set signal handler");
return 1;
}
#ifndef WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
Log.Out(Logs::General, Logs::World_Server, "Could not set signal handler");
@@ -281,13 +275,6 @@ int main(int argc, char** argv) {
}
}
if(Config->WorldHTTPEnabled) {
Log.Out(Logs::General, Logs::World_Server, "Starting HTTP world service...");
http_server.Start(Config->WorldHTTPPort, Config->WorldHTTPMimeFile.c_str());
} else {
Log.Out(Logs::General, Logs::World_Server, "HTTP world service disabled.");
}
if(!ignore_db) {
Log.Out(Logs::General, Logs::World_Server, "Checking Database Conversions..");
database.CheckDatabaseConversions();
@@ -445,12 +432,26 @@ int main(int argc, char** argv) {
});
server_connection->OnConnectionRemoved("UCS", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
Log.OutF(Logs::General, Logs::World_Server, "UCS Query Server connection from {0}",
Log.OutF(Logs::General, Logs::World_Server, "Removed Query Server connection from {0}",
connection->GetUUID());
UCSLink.SetConnection(nullptr);
});
server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
Log.OutF(Logs::General, Logs::World_Server, "New WebInterface Server connection from {2} at {0}:{1}",
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
web_interface.AddConnection(connection);
});
server_connection->OnConnectionRemoved("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
Log.OutF(Logs::General, Logs::World_Server, "Removed WebInterface Server connection from {0}",
connection->GetUUID());
web_interface.RemoveConnection(connection);
});
EQ::Net::EQStreamManagerOptions opts(9000, false, false);
EQ::Net::EQStreamManager eqsm(opts);
@@ -538,9 +539,7 @@ int main(int argc, char** argv) {
Log.Out(Logs::General, Logs::World_Server, "Shutting down zone connections (if any).");
zoneserver_list.KillAll();
Log.Out(Logs::General, Logs::World_Server, "Zone (TCP) listener stopped.");
//tcps.Close();
Log.Out(Logs::General, Logs::World_Server, "Signaling HTTP service to stop...");
http_server.Stop();
Log.CloseFileLogs();
return 0;
-477
View File
@@ -1,477 +0,0 @@
/*
* This file was generated automatically by xsubpp version 1.9508 from the
* contents of tmp. Do not edit this file, edit tmp instead.
*
* ANY CHANGES MADE HERE WILL BE LOST!
*
*/
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2004 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
*/
typedef const char Const_char;
#ifdef EMBPERL
#include "../common/global_define.h"
#include "eqw_parser.h"
#include "eql_config.h"
#ifdef seed
#undef seed
#endif
#ifdef THIS /* this macro seems to leak out on some systems */
#undef THIS
#endif
XS(XS_EQLConfig_GetName); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_GetName)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EQLConfig::GetName(THIS)");
{
EQLConfig * THIS;
Const_char * RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetName();
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
}
XSRETURN(1);
}
XS(XS_EQLConfig_GetStaticCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_GetStaticCount)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EQLConfig::GetStaticCount(THIS)");
{
EQLConfig * THIS;
int RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetStaticCount();
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}
XS(XS_EQLConfig_IsConnected); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_IsConnected)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EQLConfig::IsConnected(THIS)");
{
EQLConfig * THIS;
bool RETVAL;
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->IsConnected();
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_EQLConfig_DeleteLauncher); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_DeleteLauncher)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EQLConfig::DeleteLauncher(THIS)");
{
EQLConfig * THIS;
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->DeleteLauncher();
}
XSRETURN_EMPTY;
}
XS(XS_EQLConfig_RestartZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_RestartZone)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: EQLConfig::RestartZone(THIS, zone_ref)");
{
EQLConfig * THIS;
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->RestartZone(zone_ref);
}
XSRETURN_EMPTY;
}
XS(XS_EQLConfig_StopZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_StopZone)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: EQLConfig::StopZone(THIS, zone_ref)");
{
EQLConfig * THIS;
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->StopZone(zone_ref);
}
XSRETURN_EMPTY;
}
XS(XS_EQLConfig_StartZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_StartZone)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: EQLConfig::StartZone(THIS, zone_ref)");
{
EQLConfig * THIS;
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->StartZone(zone_ref);
}
XSRETURN_EMPTY;
}
XS(XS_EQLConfig_BootStaticZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_BootStaticZone)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: EQLConfig::BootStaticZone(THIS, short_name, port)");
{
EQLConfig * THIS;
bool RETVAL;
Const_char * short_name = (Const_char *)SvPV_nolen(ST(1));
uint16 port = (uint16)SvUV(ST(2));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->BootStaticZone(short_name, port);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_EQLConfig_ChangeStaticZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_ChangeStaticZone)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: EQLConfig::ChangeStaticZone(THIS, short_name, port)");
{
EQLConfig * THIS;
bool RETVAL;
Const_char * short_name = (Const_char *)SvPV_nolen(ST(1));
uint16 port = (uint16)SvUV(ST(2));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->ChangeStaticZone(short_name, port);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_EQLConfig_DeleteStaticZone); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_DeleteStaticZone)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: EQLConfig::DeleteStaticZone(THIS, short_name)");
{
EQLConfig * THIS;
bool RETVAL;
Const_char * short_name = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->DeleteStaticZone(short_name);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_EQLConfig_SetDynamicCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_SetDynamicCount)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: EQLConfig::SetDynamicCount(THIS, count)");
{
EQLConfig * THIS;
bool RETVAL;
int count = (int)SvIV(ST(1));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->SetDynamicCount(count);
ST(0) = boolSV(RETVAL);
sv_2mortal(ST(0));
}
XSRETURN(1);
}
XS(XS_EQLConfig_GetDynamicCount); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_GetDynamicCount)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EQLConfig::GetDynamicCount(THIS)");
{
EQLConfig * THIS;
int RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetDynamicCount();
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}
XS(XS_EQLConfig_ListZones); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_ListZones)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EQLConfig::ListZones(THIS)");
{
EQLConfig * THIS;
std::vector<std::string> RETVAL;
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->ListZones();
ST(0) = sv_newmortal();
{
U32 ix_RETVAL;
/* pop crap off the stack we dont really want */
POPs;
POPs;
/* grow the stack to the number of elements being returned */
EXTEND(SP, RETVAL.size());
for (ix_RETVAL = 0; ix_RETVAL < RETVAL.size(); ix_RETVAL++) {
const std::string &it = RETVAL[ix_RETVAL];
ST(ix_RETVAL) = sv_newmortal();
sv_setpvn(ST(ix_RETVAL), it.c_str(), it.length());
}
/* hackish, but im over it. The normal xsubpp return will be right below this */
XSRETURN(RETVAL.size());
}
}
XSRETURN(1);
}
XS(XS_EQLConfig_GetZoneDetails); /* prototype to pass -Wmissing-prototypes */
XS(XS_EQLConfig_GetZoneDetails)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: EQLConfig::GetZoneDetails(THIS, zone_ref)");
{
EQLConfig * THIS;
std::map<std::string,std::string> RETVAL;
Const_char * zone_ref = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "EQLConfig")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(EQLConfig *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type EQLConfig");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetZoneDetails(zone_ref);
ST(0) = sv_newmortal();
if (RETVAL.begin()!=RETVAL.end())
{
//NOTE: we are leaking the original ST(0) right now
HV *hv = newHV();
sv_2mortal((SV*)hv);
ST(0) = newRV((SV*)hv);
std::map<std::string,std::string>::const_iterator cur, end;
cur = RETVAL.begin();
end = RETVAL.end();
for(; cur != end; cur++) {
/* get the element from the hash, creating if needed (will be needed) */
SV**ele = hv_fetch(hv, cur->first.c_str(), cur->first.length(), TRUE);
if(ele == nullptr) {
Perl_croak(aTHX_ "Unable to create a hash element for RETVAL");
break;
}
/* put our string in the SV associated with this element in the hash */
sv_setpvn(*ele, cur->second.c_str(), cur->second.length());
}
}
}
XSRETURN(1);
}
#ifdef __cplusplus
extern "C"
#endif
XS(boot_EQLConfig); /* prototype to pass -Wmissing-prototypes */
XS(boot_EQLConfig)
{
dXSARGS;
char file[256];
strncpy(file, __FILE__, 256);
file[255] = 0;
if(items != 1)
fprintf(stderr, "boot_quest does not take any arguments.");
char buf[128];
//add the strcpy stuff to get rid of const warnings....
XS_VERSION_BOOTCHECK ;
newXSproto(strcpy(buf, "GetName"), XS_EQLConfig_GetName, file, "$");
newXSproto(strcpy(buf, "GetStaticCount"), XS_EQLConfig_GetStaticCount, file, "$");
newXSproto(strcpy(buf, "IsConnected"), XS_EQLConfig_IsConnected, file, "$");
newXSproto(strcpy(buf, "DeleteLauncher"), XS_EQLConfig_DeleteLauncher, file, "$");
newXSproto(strcpy(buf, "RestartZone"), XS_EQLConfig_RestartZone, file, "$$");
newXSproto(strcpy(buf, "StopZone"), XS_EQLConfig_StopZone, file, "$$");
newXSproto(strcpy(buf, "StartZone"), XS_EQLConfig_StartZone, file, "$$");
newXSproto(strcpy(buf, "BootStaticZone"), XS_EQLConfig_BootStaticZone, file, "$$$");
newXSproto(strcpy(buf, "ChangeStaticZone"), XS_EQLConfig_ChangeStaticZone, file, "$$$");
newXSproto(strcpy(buf, "DeleteStaticZone"), XS_EQLConfig_DeleteStaticZone, file, "$$");
newXSproto(strcpy(buf, "SetDynamicCount"), XS_EQLConfig_SetDynamicCount, file, "$$");
newXSproto(strcpy(buf, "GetDynamicCount"), XS_EQLConfig_GetDynamicCount, file, "$");
newXSproto(strcpy(buf, "ListZones"), XS_EQLConfig_ListZones, file, "$");
newXSproto(strcpy(buf, "GetZoneDetails"), XS_EQLConfig_GetZoneDetails, file, "$$");
XSRETURN_YES;
}
#endif //EMBPERL_XS_CLASSES
-1020
View File
File diff suppressed because it is too large Load Diff
-330
View File
@@ -1,330 +0,0 @@
/*
* This file was generated automatically by xsubpp version 1.9508 from the
* contents of tmp. Do not edit this file, edit tmp instead.
*
* ANY CHANGES MADE HERE WILL BE LOST!
*
*/
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2004 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
*/
typedef const char Const_char;
#ifdef EMBPERL
#include "../common/global_define.h"
#include "eqw_parser.h"
#include "http_request.h"
#ifdef seed
#undef seed
#endif
#ifdef THIS /* this macro seems to leak out on some systems */
#undef THIS
#endif
XS(XS_HTTPRequest_get); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_get)
{
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: HTTPRequest::get(THIS, name, default_value= \"\")");
{
HTTPRequest * THIS;
Const_char * RETVAL;
dXSTARG;
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
Const_char * default_value;
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
if (items < 3)
default_value = "";
else {
default_value = (Const_char *)SvPV_nolen(ST(2));
}
RETVAL = THIS->get(name, default_value);
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
}
XSRETURN(1);
}
XS(XS_HTTPRequest_getInt); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_getInt)
{
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: HTTPRequest::getInt(THIS, name, default_value= 0)");
{
HTTPRequest * THIS;
int RETVAL;
dXSTARG;
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
int default_value;
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
if (items < 3)
default_value = 0;
else {
default_value = (int)SvIV(ST(2));
}
RETVAL = THIS->getInt(name, default_value);
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}
XS(XS_HTTPRequest_getFloat); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_getFloat)
{
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: HTTPRequest::getFloat(THIS, name, default_value= 0.0)");
{
HTTPRequest * THIS;
float RETVAL;
dXSTARG;
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
float default_value;
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
if (items < 3)
default_value = 0.0;
else {
default_value = (float)SvNV(ST(2));
}
RETVAL = THIS->getFloat(name, default_value);
XSprePUSH; PUSHn((double)RETVAL);
}
XSRETURN(1);
}
XS(XS_HTTPRequest_getEscaped); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_getEscaped)
{
dXSARGS;
if (items < 2 || items > 3)
Perl_croak(aTHX_ "Usage: HTTPRequest::getEscaped(THIS, name, default_value= \"\")");
{
HTTPRequest * THIS;
Const_char * RETVAL;
dXSTARG;
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
Const_char * default_value;
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
if (items < 3)
default_value = "";
else {
default_value = (Const_char *)SvPV_nolen(ST(2));
}
RETVAL = THIS->getEscaped(name, default_value);
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
}
XSRETURN(1);
}
XS(XS_HTTPRequest_get_all); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_get_all)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: HTTPRequest::get_all(THIS)");
{
HTTPRequest * THIS;
std::map<std::string,std::string> RETVAL;
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->get_all();
ST(0) = sv_newmortal();
if (RETVAL.begin()!=RETVAL.end())
{
//NOTE: we are leaking the original ST(0) right now
HV *hv = newHV();
sv_2mortal((SV*)hv);
ST(0) = newRV((SV*)hv);
std::map<std::string,std::string>::const_iterator cur, end;
cur = RETVAL.begin();
end = RETVAL.end();
for(; cur != end; cur++) {
/* get the element from the hash, creating if needed (will be needed) */
SV**ele = hv_fetch(hv, cur->first.c_str(), cur->first.length(), TRUE);
if(ele == nullptr) {
Perl_croak(aTHX_ "Unable to create a hash element for RETVAL");
break;
}
/* put our string in the SV associated with this element in the hash */
sv_setpvn(*ele, cur->second.c_str(), cur->second.length());
}
}
}
XSRETURN(1);
}
XS(XS_HTTPRequest_redirect); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_redirect)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: HTTPRequest::redirect(THIS, URL)");
{
HTTPRequest * THIS;
Const_char * URL = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->redirect(URL);
}
XSRETURN_EMPTY;
}
XS(XS_HTTPRequest_SetResponseCode); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_SetResponseCode)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: HTTPRequest::SetResponseCode(THIS, code)");
{
HTTPRequest * THIS;
Const_char * code = (Const_char *)SvPV_nolen(ST(1));
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->SetResponseCode(code);
}
XSRETURN_EMPTY;
}
XS(XS_HTTPRequest_header); /* prototype to pass -Wmissing-prototypes */
XS(XS_HTTPRequest_header)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: HTTPRequest::header(THIS, name, value)");
{
HTTPRequest * THIS;
Const_char * name = (Const_char *)SvPV_nolen(ST(1));
Const_char * value = (Const_char *)SvPV_nolen(ST(2));
if (sv_derived_from(ST(0), "HTTPRequest")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(HTTPRequest *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type HTTPRequest");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->header(name, value);
}
XSRETURN_EMPTY;
}
#ifdef __cplusplus
extern "C"
#endif
XS(boot_HTTPRequest); /* prototype to pass -Wmissing-prototypes */
XS(boot_HTTPRequest)
{
dXSARGS;
char file[256];
strncpy(file, __FILE__, 256);
file[255] = 0;
if(items != 1)
fprintf(stderr, "boot_quest does not take any arguments.");
char buf[128];
//add the strcpy stuff to get rid of const warnings....
XS_VERSION_BOOTCHECK ;
newXSproto(strcpy(buf, "get"), XS_HTTPRequest_get, file, "$$;$");
newXSproto(strcpy(buf, "getInt"), XS_HTTPRequest_getInt, file, "$$;$");
newXSproto(strcpy(buf, "getFloat"), XS_HTTPRequest_getFloat, file, "$$;$");
newXSproto(strcpy(buf, "getEscaped"), XS_HTTPRequest_getEscaped, file, "$$;$");
newXSproto(strcpy(buf, "get_all"), XS_HTTPRequest_get_all, file, "$");
newXSproto(strcpy(buf, "redirect"), XS_HTTPRequest_redirect, file, "$$");
newXSproto(strcpy(buf, "SetResponseCode"), XS_HTTPRequest_SetResponseCode, file, "$$");
newXSproto(strcpy(buf, "header"), XS_HTTPRequest_header, file, "$$$");
XSRETURN_YES;
}
#endif //EMBPERL_XS_CLASSES
-1
View File
@@ -7,7 +7,6 @@
#include "../common/md5.h"
#include "../common/emu_tcp_connection.h"
#include "../common/packet_dump.h"
extern ClientList client_list;
+1 -2
View File
@@ -3,9 +3,8 @@
#include "ucs.h"
#include "world_config.h"
#include "../common/misc_functions.h"
#include "../common/md5.h"
#include "../common/emu_tcp_connection.h"
#include "../common/packet_dump.h"
UCSConnection::UCSConnection()
+164
View File
@@ -0,0 +1,164 @@
#include "web_interface.h"
#include "../common/json/json.h"
#include "web_interface_eqw.h"
#include <sstream>
WebInterface::WebInterface(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection)
{
m_connection = connection;
m_connection->OnMessage(ServerOP_WebInterfaceCall, std::bind(&WebInterface::OnCall, this, std::placeholders::_1, std::placeholders::_2));
RegisterEQW(this);
}
WebInterface::~WebInterface()
{
}
void WebInterface::OnCall(uint16 opcode, EQ::Net::Packet &p)
{
Json::Value root;
try {
auto json_str = p.GetCString(0);
std::stringstream ss(json_str);
ss >> root;
}
catch (std::exception) {
SendError("Could not parse request");
return;
}
std::string method;
Json::Value params;
std::string id;
try {
method = root["method"].asString();
if (method.length() == 0) {
SendError("Invalid request: method not supplied");
return;
}
}
catch (std::exception) {
SendError("Invalid request: method not supplied");
return;
}
//optional "params" -> Json::Value
try {
params = root["params"];
}
catch (std::exception) {
params = nullptr;
}
//optional "id" needs to be string
try {
id = root["id"].asString();
}
catch (std::exception) {
id = "";
}
//check for registered method
auto iter = m_calls.find(method);
if (iter == m_calls.end()) {
//if not exist then error
SendError("Invalid request: method not found");
return;
}
iter->second(this, method, id, params);
}
void WebInterface::Send(const Json::Value &value)
{
try {
std::stringstream ss;
ss << value;
EQ::Net::DynamicPacket p;
p.PutString(0, ss.str());
m_connection->Send(ServerOP_WebInterfaceCall, p);
}
catch (std::exception) {
//Log error
}
}
void WebInterface::SendError(const std::string &message)
{
Json::Value error;
error["error"] = Json::Value();
error["error"]["message"] = message;
Send(error);
}
void WebInterface::SendError(const std::string &message, const std::string &id)
{
Json::Value error;
error["error"] = Json::Value();
error["error"]["message"] = message;
Send(error);
}
void WebInterface::AddCall(const std::string &method, WebInterfaceCall call)
{
m_calls.insert(std::make_pair(method, call));
}
void WebInterface::SendResponse(const std::string &id, const Json::Value &response)
{
Json::Value out;
if(!id.empty())
out["id"] = id;
out["response"] = response;
Send(out);
}
WebInterfaceList::WebInterfaceList()
{
}
WebInterfaceList::~WebInterfaceList()
{
}
void WebInterfaceList::AddConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection)
{
m_interfaces.insert(std::make_pair(connection->GetUUID(), std::unique_ptr<WebInterface>(new WebInterface(connection))));
}
void WebInterfaceList::RemoveConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection)
{
auto iter = m_interfaces.find(connection->GetUUID());
if (iter != m_interfaces.end()) {
m_interfaces.erase(iter);
return;
}
}
void WebInterfaceList::SendResponse(const std::string &uuid, std::string &id, const Json::Value &response) {
auto iter = m_interfaces.find(uuid);
if (iter != m_interfaces.end()) {
iter->second->SendResponse(id, response);
}
}
void WebInterfaceList::SendError(const std::string &uuid, const std::string &message) {
auto iter = m_interfaces.find(uuid);
if (iter != m_interfaces.end()) {
iter->second->SendError(message);
}
}
void WebInterfaceList::SendError(const std::string &uuid, const std::string &message, const std::string &id) {
auto iter = m_interfaces.find(uuid);
if (iter != m_interfaces.end()) {
iter->second->SendError(message, id);
}
}
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include "../common/net/servertalk_server_connection.h"
#include "../common/json/json.h"
#include <map>
#include <string>
#include <functional>
class WebInterface
{
public:
typedef std::function<void(WebInterface *, const std::string&, const std::string&, const Json::Value&)> WebInterfaceCall;
WebInterface(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection);
~WebInterface();
std::string GetUUID() const { return m_connection->GetUUID(); }
void SendResponse(const std::string &id, const Json::Value &response);
void SendError(const std::string &message);
void SendError(const std::string &message, const std::string &id);
void AddCall(const std::string &method, WebInterfaceCall call);
private:
void OnCall(uint16 opcode, EQ::Net::Packet &p);
void Send(const Json::Value &value);
std::shared_ptr<EQ::Net::ServertalkServerConnection> m_connection;
std::map<std::string, WebInterfaceCall> m_calls;
};
class WebInterfaceList
{
public:
WebInterfaceList();
~WebInterfaceList();
void AddConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection);
void RemoveConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection);
void SendResponse(const std::string &uuid, std::string &id, const Json::Value &response);
void SendError(const std::string &uuid, const std::string &message);
void SendError(const std::string &uuid, const std::string &message, const std::string &id);
private:
std::map<std::string, std::unique_ptr<WebInterface>> m_interfaces;
};
+40
View File
@@ -0,0 +1,40 @@
#include "web_interface_eqw.h"
#include "web_interface.h"
#include "world_config.h"
#include "login_server_list.h"
extern LoginServerList loginserverlist;
void EQW__IsLocked(WebInterface *i, const std::string& method, const std::string& id, const Json::Value& params) {
Json::Value ret = WorldConfig::get()->Locked;
i->SendResponse(id, ret);
}
void EQW__Lock(WebInterface *i, const std::string& method, const std::string& id, const Json::Value& params) {
WorldConfig::LockWorld();
if (loginserverlist.Connected()) {
loginserverlist.SendStatus();
}
Json::Value ret;
ret["status"] = "complete";
i->SendResponse(id, ret);
}
void EQW__Unlock(WebInterface *i, const std::string& method, const std::string& id, const Json::Value& params) {
WorldConfig::UnlockWorld();
if (loginserverlist.Connected()) {
loginserverlist.SendStatus();
}
Json::Value ret;
ret["status"] = "complete";
i->SendResponse(id, ret);
}
void RegisterEQW(WebInterface *i)
{
i->AddCall("IsLocked", std::bind(EQW__IsLocked, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
i->AddCall("Lock", std::bind(EQW__Lock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
i->AddCall("Unlock", std::bind(EQW__Unlock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
class WebInterface;
void RegisterEQW(WebInterface *i);
+1 -2
View File
@@ -18,10 +18,9 @@
#include "../common/global_define.h"
#include "zonelist.h"
#include "zoneserver.h"
#include "world_tcp_connection.h"
#include "worlddb.h"
#include "console.h"
#include "world_config.h"
#include "../common/misc_functions.h"
#include "../common/servertalk.h"
#include "../common/string_util.h"
#include "../common/random.h"
-1
View File
@@ -22,7 +22,6 @@
#include "login_server_list.h"
#include "zonelist.h"
#include "worlddb.h"
#include "console.h"
#include "client.h"
#include "../common/md5.h"
#include "world_config.h"