mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
TCP cleanup, added basis of web interface
This commit is contained in:
+4
-14
@@ -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
|
||||
)
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_*/
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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));
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
class WebInterface;
|
||||
|
||||
void RegisterEQW(WebInterface *i);
|
||||
+1
-2
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user