diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Chat/Chat.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Chat/Chat.h | 6 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 12 | ||||
-rw-r--r-- | src/server/game/World/World.h | 16 | ||||
-rw-r--r-- | src/server/worldserver/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/server/worldserver/CommandLine/CliRunnable.cpp | 9 | ||||
-rw-r--r-- | src/server/worldserver/Master.cpp | 17 | ||||
-rw-r--r-- | src/server/worldserver/RemoteAccess/RASocket.cpp | 68 | ||||
-rw-r--r-- | src/server/worldserver/RemoteAccess/RASocket.h | 16 | ||||
-rw-r--r-- | src/server/worldserver/TCSoap/TCSoap.cpp | 175 | ||||
-rw-r--r-- | src/server/worldserver/TCSoap/TCSoap.h | 120 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 19 |
12 files changed, 394 insertions, 73 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 5efd4b4ef6a..d2f23434f2b 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -2402,8 +2402,8 @@ bool CliHandler::isAvailable(ChatCommand const& cmd) const void CliHandler::SendSysMessage(const char *str) { - m_print(str); - m_print("\r\n"); + m_print(m_callbackArg, str); + m_print(m_callbackArg, "\r\n"); } std::string CliHandler::GetNameLink() const diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 1a649c687d1..71bd82d29b0 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -76,6 +76,7 @@ class ChatHandler static ChatCommand* getCommandTable(); bool isValidChatMessage(const char* msg); + bool HasSentErrorMessage() { return sentErrorMessage;} void SendGlobalSysMessage(const char *str); protected: explicit ChatHandler() : m_session(NULL) {} // for CLI subclass @@ -652,8 +653,8 @@ class ChatHandler class CliHandler : public ChatHandler { public: - typedef void Print(char const*); - explicit CliHandler(Print* zprint) : m_print(zprint) {} + typedef void Print(void*, char const*); + explicit CliHandler(void* callbackArg, Print* zprint) : m_callbackArg(callbackArg), m_print(zprint) {} // overwrite functions const char *GetTrinityString(int32 entry) const; @@ -665,6 +666,7 @@ class CliHandler : public ChatHandler int GetSessionDbLocaleIndex() const; private: + void* m_callbackArg; Print* m_print; }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 915cfbb08b5..5eba5f44182 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2445,19 +2445,19 @@ void World::UpdateSessions(uint32 diff) void World::ProcessCliCommands() { CliCommandHolder::Print* zprint = NULL; - + void* callbackArg = NULL; CliCommandHolder* command; while (cliCmdQueue.next(command)) { sLog.outDebug("CLI command under processing..."); zprint = command->m_print; - CliHandler(zprint).ParseCommands(command->m_command); + callbackArg = command->m_callbackArg; + CliHandler handler(callbackArg, zprint); + handler.ParseCommands(command->m_command); + if(command->m_commandFinished) + command->m_commandFinished(callbackArg, !handler.HasSentErrorMessage()); delete command; } - - // print the console message here so it looks right - if (zprint) - zprint("TC> "); } void World::SendRNDBroadcast() diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index f3f06f6c821..aae4e3321a0 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -464,19 +464,23 @@ enum WorldStates /// Storage class for commands issued for delayed execution struct CliCommandHolder { - typedef void Print(const char*); - + typedef void Print(void*, const char*); + typedef void CommandFinished(void*, bool success); + + void* m_callbackArg; char *m_command; Print* m_print; - CliCommandHolder(const char *command, Print* zprint) - : m_print(zprint) + CommandFinished* m_commandFinished; + + CliCommandHolder(void* callbackArg, const char *command, Print* zprint, CommandFinished* commandFinished) + : m_callbackArg(callbackArg), m_print(zprint), m_commandFinished(commandFinished) { size_t len = strlen(command)+1; m_command = new char[len]; memcpy(m_command, command, len); } - + ~CliCommandHolder() { delete[] m_command; } }; @@ -657,7 +661,7 @@ class World static int32 GetVisibilityNotifyPeriodInBGArenas() { return m_visibility_notify_periodInBGArenas; } void ProcessCliCommands(); - void QueueCliCommand(CliCommandHolder::Print* zprintf, char const* input) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); } + void QueueCliCommand(CliCommandHolder* commandHolder) { cliCmdQueue.add(commandHolder); } void UpdateResultQueue(); void InitResultQueue(); diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index e86422e2ce1..69beb4e69ba 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -13,6 +13,7 @@ set(worldserver_SRCS CommandLine/CliRunnable.cpp RemoteAccess/RASocket.cpp + TCSoap/TCSoap.cpp WorldThread/WorldRunnable.cpp Main.cpp Master.cpp @@ -23,6 +24,7 @@ include_directories( ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/externals/gsoap ${CMAKE_SOURCE_DIR}/externals/sockets/include ${CMAKE_SOURCE_DIR}/externals/mersennetwister ${CMAKE_SOURCE_DIR}/dep/include @@ -112,6 +114,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/worldserver ${CMAKE_SOURCE_DIR}/src/server/worldserver/CommandLine ${CMAKE_SOURCE_DIR}/src/server/worldserver/RemoteAccess + ${CMAKE_SOURCE_DIR}/src/server/worldserver/TCSoap ${CMAKE_SOURCE_DIR}/src/server/worldserver/WorldThread ) @@ -154,6 +157,7 @@ if( WIN32 ) trinityconfig collision g3dlib + gsoap ${SCRIPT_LIB} ace ${MYSQL_LIBRARY} @@ -171,6 +175,7 @@ else() trinityconfig collision g3dlib + gsoap jemalloc ${SCRIPT_LIB} ${READLINE_LIBRARY} diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index 23a023972c9..294c512759f 100644 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -85,7 +85,7 @@ char ** cli_completion(const char * text, int start, int end) } #endif -void utf8print(const char* str) +void utf8print(void* arg, const char* str) { #if PLATFORM == PLATFORM_WINDOWS wchar_t wtemp_buf[6000]; @@ -106,6 +106,11 @@ void utf8print(const char* str) #endif } +void commandFinished(void*, bool sucess) +{ + printf("TC> "); + fflush(stdout); +} /// Delete a user account and all associated characters in this realm /// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account bool ChatHandler::HandleAccountDeleteCommand(const char* args) @@ -741,7 +746,7 @@ void CliRunnable::run() continue; } fflush(stdout); - sWorld.QueueCliCommand(&utf8print,command.c_str()); + sWorld.QueueCliCommand(new CliCommandHolder(NULL, command.c_str(), &utf8print, &commandFinished)); #if PLATFORM != WINDOWS add_history(command.c_str()); #endif diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index f6f4260e303..4a986893d78 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -38,6 +38,7 @@ #include "Log.h" #include "Master.h" #include "RASocket.h" +#include "TCSoap.h" #include "Timer.h" #include "Util.h" @@ -315,6 +316,15 @@ int Master::Run() } } #endif + //Start soap serving thread + ACE_Based::Thread* soap_thread = NULL; + + if(sConfig.GetBoolDefault("SOAP.Enabled", false)) + { + TCSoapRunnable *runnable = new TCSoapRunnable(); + runnable->setListenArguments(sConfig.GetStringDefault("SOAP.IP", "127.0.0.1"), sConfig.GetIntDefault("SOAP.Port", 7878)); + soap_thread = new ACE_Based::Thread(runnable); + } uint32 realCurrTime, realPrevTime; realCurrTime = realPrevTime = getMSTime(); @@ -341,6 +351,13 @@ int Master::Run() sWorldSocketMgr->Wait (); + if(soap_thread) + { + soap_thread->wait(); + soap_thread->destroy(); + delete soap_thread; + } + // set server offline LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID); diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp index 35c2514b377..98587c935d0 100644 --- a/src/server/worldserver/RemoteAccess/RASocket.cpp +++ b/src/server/worldserver/RemoteAccess/RASocket.cpp @@ -31,48 +31,28 @@ #include "Util.h" #include "World.h" -/// \todo Make this thread safe if in the future 2 admins should be able to log at the same time. -SOCKET r; - #define dropclient {Sendf("I'm busy right now, come back later."); \ SetCloseAndDelete(); \ return; \ } -uint32 iSession=0; ///< Session number (incremented each time a new connection is made) -unsigned int iUsers=0; ///< Number of active administrators - -typedef int(* pPrintf)(const char*,...); - -void ParseCommand(CliCommandHolder::Print*, char*command); - /// RASocket constructor RASocket::RASocket(ISocketHandler &h): TcpSocket(h) { - ///- Increment the session number - iSess =iSession++ ; - ///- Get the config parameters bSecure = sConfig.GetBoolDefault( "RA.Secure", true ); iMinLevel = sConfig.GetIntDefault( "RA.MinLevel", 3 ); ///- Initialize buffer and data iInputLength=0; - buff=new char[RA_BUFF_SIZE]; stage=NONE; } /// RASocket destructor RASocket::~RASocket() { - ///- Delete buffer and decrease active admins count - delete [] buff; - sLog.outRemote("Connection was closed.\n"); - - if(stage==OK) - iUsers--; } /// Accept an incoming connection @@ -80,12 +60,8 @@ void RASocket::OnAccept() { std::string ss=GetRemoteAddress(); sLog.outRemote("Incoming connection from %s.\n",ss.c_str()); - ///- If there is already an active admin, drop the connection - if(iUsers) - dropclient - - ///- Else print Motd - Sendf("%s\r\n",sWorld.GetMotd()); + ///- print Motd + Sendf("%s\r\n",sWorld.GetMotd()); } /// Read data from the network @@ -102,11 +78,7 @@ void RASocket::OnRead() return; } - ///- If there is already an active admin (other than you), drop the connection - if(stage!=OK && iUsers) - dropclient - - char *inp = new char [sz+1]; + char *inp = new char [sz+1]; ibuf.Read(inp,sz); /// \todo Can somebody explain this 'Linux bugfix'? @@ -209,9 +181,8 @@ void RASocket::OnRead() if(check) { - r=GetSocket(); + GetSocket(); stage=OK; - ++iUsers; Sendf("+Logged in.\r\n"); sLog.outRemote("User %s has logged in.\n",szLogin.c_str()); @@ -231,7 +202,10 @@ void RASocket::OnRead() if(strlen(buff)) { sLog.outRemote("Got '%s' cmd.\n",buff); - sWorld.QueueCliCommand(&RASocket::zprint , buff); + SetDeleteByHandler(false); + CliCommandHolder* cmd = new CliCommandHolder(this, buff, &RASocket::zprint, &RASocket::commandFinished); + sWorld.QueueCliCommand(cmd); + ++pendingCommands; } else Sendf("TC>"); @@ -243,23 +217,21 @@ void RASocket::OnRead() } /// Output function -void RASocket::zprint( const char * szText ) +void RASocket::zprint(void* callbackArg, const char * szText ) { if( !szText ) return; - #ifdef RA_CRYPT - - char *megabuffer=strdup(szText); - unsigned int sz=strlen(megabuffer); - Encrypt(megabuffer,sz); - send(r,megabuffer,sz,0); - free(megabuffer); - - #else - unsigned int sz=strlen(szText); - send(r,szText,sz,0); - - #endif + send(((RASocket*)callbackArg)->GetSocket(), szText, sz, 0); } + +void RASocket::commandFinished(void* callbackArg, bool success) +{ + RASocket* raSocket = (RASocket*)callbackArg; + raSocket->Sendf("TC>"); + uint64 remainingCommands = --raSocket->pendingCommands; + + if(remainingCommands == 0) + raSocket->SetDeleteByHandler(true); + } diff --git a/src/server/worldserver/RemoteAccess/RASocket.h b/src/server/worldserver/RemoteAccess/RASocket.h index 25a21d52044..4d491e5a436 100644 --- a/src/server/worldserver/RemoteAccess/RASocket.h +++ b/src/server/worldserver/RemoteAccess/RASocket.h @@ -28,11 +28,14 @@ #include "TcpSocket.h" #include "Common.h" +#include <ace/Synch_Traits.h> #define RA_BUFF_SIZE 1024 class ISocketHandler; +typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, uint64> AtomicInt; + /// Remote Administration socket class RASocket: public TcpSocket { @@ -44,14 +47,14 @@ class RASocket: public TcpSocket void OnAccept(); void OnRead(); - private: + AtomicInt pendingCommands; - char * buff; + private: + char buff[RA_BUFF_SIZE]; std::string szLogin; - uint32 iSess; + unsigned int iInputLength; - bool bLog; - bool bSecure; //kick on wrong pass, non exist. user, user with no priv + bool bSecure; //will protect from DOS, bruteforce attacks //some 'smart' protection must be added for more security uint8 iMinLevel; @@ -62,7 +65,8 @@ class RASocket: public TcpSocket OK, //both login and pass were given, and they are correct and user have enough priv. }stage; - static void zprint( const char * szText ); + static void zprint(void* callbackArg, const char * szText ); + static void commandFinished(void* callbackArg, bool success); }; #endif /// @} diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp new file mode 100644 index 00000000000..cf2c55146a4 --- /dev/null +++ b/src/server/worldserver/TCSoap/TCSoap.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2005-2010 TrinityCore2 <http://trinitycore.com/> + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; 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 "TCSoap.h" +#include "soapH.h" +#include "soapStub.h" + +#define POOL_SIZE 5 + +void TCSoapRunnable::run() +{ + // create pool + SOAPWorkingThread pool; + pool.activate (THR_NEW_LWP | THR_JOINABLE, POOL_SIZE); + + struct soap soap; + int m, s; + soap_init(&soap); + soap_set_imode(&soap, SOAP_C_UTFSTRING); + soap_set_omode(&soap, SOAP_C_UTFSTRING); + m = soap_bind(&soap, m_host.c_str(), m_port, 100); + + // check every 3 seconds if world ended + soap.accept_timeout = 3; + + soap.recv_timeout = 5; + soap.send_timeout = 5; + if (m < 0) + { + sLog.outError("TCSoap: couldn't bind to %s:%d", m_host.c_str(), m_port); + exit(-1); + } + + sLog.outString("TCSoap: bound to http://%s:%d", m_host.c_str(), m_port); + + while(!World::IsStopped()) + { + s = soap_accept(&soap); + + if (s < 0) + { + // ran into an accept timeout + continue; + } + + sLog.outDebug("TCSoap: accepted connection from IP=%d.%d.%d.%d", (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF); + struct soap* thread_soap = soap_copy(&soap);// make a safe copy + + ACE_Message_Block *mb = new ACE_Message_Block(sizeof(struct soap*)); + ACE_OS::memcpy (mb->wr_ptr (), &thread_soap, sizeof(struct soap*)); + pool.putq(mb); + } + pool.msg_queue ()->deactivate (); + pool.wait (); + + soap_done(&soap); +} + +void SOAPWorkingThread::process_message (ACE_Message_Block *mb) +{ + ACE_TRACE (ACE_TEXT ("SOAPWorkingThread::process_message")); + + struct soap* soap; + ACE_OS::memcpy (&soap, mb->rd_ptr (), sizeof(struct soap*)); + mb->release (); + + soap_serve(soap); + soap_destroy(soap); // dealloc C++ data + soap_end(soap); // dealloc data and clean up + soap_done(soap); // detach soap struct + free(soap); +} +/* +Code used for generating stubs: + +int ns1__executeCommand(char* command, char** result); +*/ +int ns1__executeCommand(soap* soap, char* command, char** result) +{ + // security check + if (!soap->userid || !soap->passwd) + { + sLog.outDebug("TCSoap: Client didn't provide login information"); + return 401; + } + + uint32 accountId = accmgr.GetId(soap->userid); + if(!accountId) + { + sLog.outDebug("TCSoap: Client used invalid username '%s'", soap->userid); + return 401; + } + + if(!accmgr.CheckPassword(accountId, soap->passwd)) + { + sLog.outDebug("TCSoap: invalid password for account '%s'", soap->userid); + return 401; + } + + if(accmgr.GetSecurity(accountId) < SEC_ADMINISTRATOR) + { + sLog.outDebug("TCSoap: %s's gmlevel is too low", soap->userid); + return 403; + } + + if(!command || !*command) + return soap_sender_fault(soap, "Command mustn't be empty", "The supplied command was an empty string"); + + sLog.outDebug("TCSoap: got command '%s'", command); + SOAPCommand connection; + + // commands are executed in the world thread. We have to wait for them to be completed + { + // CliCommandHolder will be deleted from world, accessing after queueing is NOT save + CliCommandHolder* cmd = new CliCommandHolder(&connection, command, &SOAPCommand::print, &SOAPCommand::commandFinished); + sWorld.QueueCliCommand(cmd); + } + + // wait for callback to complete command + + int acc = connection.pendingCommands.acquire(); + if(acc) + { + sLog.outError("TCSoap: Error while acquiring lock, acc = %i, errno = %u", acc, errno); + } + + // alright, command finished + + char* printBuffer = soap_strdup(soap, connection.m_printBuffer.c_str()); + if(connection.hasCommandSucceeded()) + { + *result = printBuffer; + return SOAP_OK; + } + else + return soap_sender_fault(soap, printBuffer, printBuffer); +} + + +void SOAPCommand::commandFinished(void* soapconnection, bool success) +{ + SOAPCommand* con = (SOAPCommand*)soapconnection; + con->setCommandSuccess(success); + con->pendingCommands.release(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Namespace Definition Table +// +//////////////////////////////////////////////////////////////////////////////// + +struct Namespace namespaces[] = + { { "SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/" }, // must be first + { "SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/" }, // must be second + { "xsi", "http://www.w3.org/1999/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance" }, + { "xsd", "http://www.w3.org/1999/XMLSchema", "http://www.w3.org/*/XMLSchema" }, + { "ns1", "urn:TC" }, // "ns1" namespace prefix + { NULL, NULL } + }; diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h new file mode 100644 index 00000000000..87e80e69a34 --- /dev/null +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2005-2010 TrinityCore2 <http://trinitycore.com/> + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; 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 _TCSOAP_H +#define _TCSOAP_H + +#include "Common.h" +#include "World.h" +#include "AccountMgr.h" +#include "Log.h" + +#include "soapH.h" +#include "soapStub.h" +#include "stdsoap2.h" + +#include <ace/SV_Semaphore_Simple.h> +#include <ace/Task.h> + + +class TCSoapRunnable: public ACE_Based::Runnable +{ + public: + TCSoapRunnable() { } + void run(); + void setListenArguments(std::string host, uint16 port) + { + m_host = host; + m_port = port; + } + private: + std::string m_host; + uint16 m_port; +}; + +class SOAPWorkingThread : public ACE_Task<ACE_MT_SYNCH> +{ + public: + SOAPWorkingThread () + { } + + virtual int svc (void) + { + while (1) + { + ACE_Message_Block *mb = 0; + if (this->getq (mb) == -1) + { + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%t) Shutting down\n"))); + break; + } + + // Process the message. + process_message (mb); + } + + return 0; + } + private: + void process_message (ACE_Message_Block *mb); +}; + + +class SOAPCommand +{ + public: + SOAPCommand() + { + ACE_ASSERT (pendingCommands.open("pendingCommands", + ACE_SV_Semaphore_Simple::ACE_CREATE, + 0) != -1); + + } + ~SOAPCommand() + { + } + + void appendToPrintBuffer(const char* msg) + { + m_printBuffer += msg; + } + + ACE_SV_Semaphore_Simple pendingCommands; + + void setCommandSuccess(bool val) + { + m_success = val; + } + bool hasCommandSucceeded() + { + return m_success; + } + + static void print(void* callbackArg, const char* msg) + { + ((SOAPCommand*)callbackArg)->appendToPrintBuffer(msg); + } + + static void commandFinished(void* callbackArg, bool success); + + bool m_success; + std::string m_printBuffer; +}; + +#endif diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index ac6dd718230..ef311e8ea7a 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2084,7 +2084,20 @@ AuctionHouseBot.DisableTGsAboveReqSkillRank = 0 # Ra.Secure # Kick client on wrong pass # -############################################################################### +# SOAP.Enable +# Enable soap service +# Default: 0 - off +# 1 - on +# +# SOAP.IP +# Bound SOAP service ip address, use 0.0.0.0 to access from everywhere +# Default: 127.0.0.1 +# +# SOAP.Port +# SOAP port +# Default: 7878 +# +################################################################################################################### Console.Enable = 1 Ra.Enable = 0 @@ -2093,6 +2106,10 @@ Ra.Port = 3443 Ra.MinLevel = 3 Ra.Secure = 1 +SOAP.Enabled = 0 +SOAP.IP = 127.0.0.1 +SOAP.Port = 7878 + ################################################################################################################### # CharDelete.Method # Character deletion behavior |