From fd28bc6aff6fe356262b5ac20e152c6ec8569c43 Mon Sep 17 00:00:00 2001 From: click Date: Sat, 5 Jun 2010 22:44:53 +0200 Subject: rename world server directory (trinitycore) to worldserver, rename authserver directory (trinityrealm) to authserver to reflect their real purposes --HG-- branch : trunk rename : src/server/trinityrealm/AuthCodes.cpp => src/server/authserver/AuthCodes.cpp rename : src/server/trinityrealm/AuthCodes.h => src/server/authserver/AuthCodes.h rename : src/server/trinityrealm/AuthSocket.cpp => src/server/authserver/AuthSocket.cpp rename : src/server/trinityrealm/AuthSocket.h => src/server/authserver/AuthSocket.h rename : src/server/trinityrealm/CMakeLists.txt => src/server/authserver/CMakeLists.txt rename : src/server/trinityrealm/Main.cpp => src/server/authserver/Main.cpp rename : src/server/trinityrealm/RealmAcceptor.h => src/server/authserver/RealmAcceptor.h rename : src/server/trinityrealm/RealmList.cpp => src/server/authserver/RealmList.cpp rename : src/server/trinityrealm/RealmList.h => src/server/authserver/RealmList.h rename : src/server/trinityrealm/RealmSocket.cpp => src/server/authserver/RealmSocket.cpp rename : src/server/trinityrealm/RealmSocket.h => src/server/authserver/RealmSocket.h rename : src/server/trinityrealm/TrinityRealm.ico => src/server/authserver/TrinityRealm.ico rename : src/server/trinityrealm/TrinityRealm.rc => src/server/authserver/TrinityRealm.rc rename : src/server/trinityrealm/resource.h => src/server/authserver/resource.h rename : src/server/trinityrealm/trinityrealm.conf.dist => src/server/authserver/trinityrealm.conf.dist rename : src/server/trinitycore/CMakeLists.txt => src/server/worldserver/CMakeLists.txt rename : src/server/trinitycore/CliRunnable.cpp => src/server/worldserver/CliRunnable.cpp rename : src/server/trinitycore/CliRunnable.h => src/server/worldserver/CliRunnable.h rename : src/server/trinitycore/Main.cpp => src/server/worldserver/Main.cpp rename : src/server/trinitycore/Master.cpp => src/server/worldserver/Master.cpp rename : src/server/trinitycore/Master.h => src/server/worldserver/Master.h rename : src/server/trinitycore/RASocket.cpp => src/server/worldserver/RASocket.cpp rename : src/server/trinitycore/RASocket.h => src/server/worldserver/RASocket.h rename : src/server/trinitycore/TrinityCore.ico => src/server/worldserver/TrinityCore.ico rename : src/server/trinitycore/TrinityCore.rc => src/server/worldserver/TrinityCore.rc rename : src/server/trinitycore/WorldRunnable.cpp => src/server/worldserver/WorldRunnable.cpp rename : src/server/trinitycore/WorldRunnable.h => src/server/worldserver/WorldRunnable.h rename : src/server/trinitycore/resource.h => src/server/worldserver/resource.h rename : src/server/trinitycore/trinitycore.conf.dist => src/server/worldserver/trinitycore.conf.dist --- src/server/authserver/AuthCodes.cpp | 37 + src/server/authserver/AuthCodes.h | 97 ++ src/server/authserver/AuthSocket.cpp | 1069 ++++++++++++ src/server/authserver/AuthSocket.h | 97 ++ src/server/authserver/CMakeLists.txt | 60 + src/server/authserver/Main.cpp | 352 ++++ src/server/authserver/RealmAcceptor.h | 52 + src/server/authserver/RealmList.cpp | 100 ++ src/server/authserver/RealmList.h | 79 + src/server/authserver/RealmSocket.cpp | 324 ++++ src/server/authserver/RealmSocket.h | 85 + src/server/authserver/TrinityRealm.ico | Bin 0 -> 136606 bytes src/server/authserver/TrinityRealm.rc | 86 + src/server/authserver/resource.h | 15 + src/server/authserver/trinityrealm.conf.dist | 146 ++ src/server/trinitycore/CMakeLists.txt | 79 - src/server/trinitycore/CliRunnable.cpp | 445 ----- src/server/trinitycore/CliRunnable.h | 35 - src/server/trinitycore/Main.cpp | 154 -- src/server/trinitycore/Master.cpp | 536 ------ src/server/trinitycore/Master.h | 48 - src/server/trinitycore/RASocket.cpp | 265 --- src/server/trinitycore/RASocket.h | 68 - src/server/trinitycore/TrinityCore.ico | Bin 136606 -> 0 bytes src/server/trinitycore/TrinityCore.rc | 86 - src/server/trinitycore/WorldRunnable.cpp | 97 -- src/server/trinitycore/WorldRunnable.h | 35 - src/server/trinitycore/resource.h | 15 - src/server/trinitycore/trinitycore.conf.dist | 2212 ------------------------ src/server/trinityrealm/AuthCodes.cpp | 37 - src/server/trinityrealm/AuthCodes.h | 97 -- src/server/trinityrealm/AuthSocket.cpp | 1069 ------------ src/server/trinityrealm/AuthSocket.h | 97 -- src/server/trinityrealm/CMakeLists.txt | 60 - src/server/trinityrealm/Main.cpp | 352 ---- src/server/trinityrealm/RealmAcceptor.h | 52 - src/server/trinityrealm/RealmList.cpp | 100 -- src/server/trinityrealm/RealmList.h | 79 - src/server/trinityrealm/RealmSocket.cpp | 324 ---- src/server/trinityrealm/RealmSocket.h | 85 - src/server/trinityrealm/TrinityRealm.ico | Bin 136606 -> 0 bytes src/server/trinityrealm/TrinityRealm.rc | 86 - src/server/trinityrealm/resource.h | 15 - src/server/trinityrealm/trinityrealm.conf.dist | 146 -- src/server/worldserver/CMakeLists.txt | 79 + src/server/worldserver/CliRunnable.cpp | 445 +++++ src/server/worldserver/CliRunnable.h | 35 + src/server/worldserver/Main.cpp | 154 ++ src/server/worldserver/Master.cpp | 536 ++++++ src/server/worldserver/Master.h | 48 + src/server/worldserver/RASocket.cpp | 265 +++ src/server/worldserver/RASocket.h | 68 + src/server/worldserver/TrinityCore.ico | Bin 0 -> 136606 bytes src/server/worldserver/TrinityCore.rc | 86 + src/server/worldserver/WorldRunnable.cpp | 97 ++ src/server/worldserver/WorldRunnable.h | 35 + src/server/worldserver/resource.h | 15 + src/server/worldserver/trinitycore.conf.dist | 2212 ++++++++++++++++++++++++ 58 files changed, 6674 insertions(+), 6674 deletions(-) create mode 100644 src/server/authserver/AuthCodes.cpp create mode 100644 src/server/authserver/AuthCodes.h create mode 100644 src/server/authserver/AuthSocket.cpp create mode 100644 src/server/authserver/AuthSocket.h create mode 100644 src/server/authserver/CMakeLists.txt create mode 100644 src/server/authserver/Main.cpp create mode 100644 src/server/authserver/RealmAcceptor.h create mode 100644 src/server/authserver/RealmList.cpp create mode 100644 src/server/authserver/RealmList.h create mode 100644 src/server/authserver/RealmSocket.cpp create mode 100644 src/server/authserver/RealmSocket.h create mode 100644 src/server/authserver/TrinityRealm.ico create mode 100644 src/server/authserver/TrinityRealm.rc create mode 100644 src/server/authserver/resource.h create mode 100644 src/server/authserver/trinityrealm.conf.dist delete mode 100644 src/server/trinitycore/CMakeLists.txt delete mode 100644 src/server/trinitycore/CliRunnable.cpp delete mode 100644 src/server/trinitycore/CliRunnable.h delete mode 100644 src/server/trinitycore/Main.cpp delete mode 100644 src/server/trinitycore/Master.cpp delete mode 100644 src/server/trinitycore/Master.h delete mode 100644 src/server/trinitycore/RASocket.cpp delete mode 100644 src/server/trinitycore/RASocket.h delete mode 100644 src/server/trinitycore/TrinityCore.ico delete mode 100644 src/server/trinitycore/TrinityCore.rc delete mode 100644 src/server/trinitycore/WorldRunnable.cpp delete mode 100644 src/server/trinitycore/WorldRunnable.h delete mode 100644 src/server/trinitycore/resource.h delete mode 100644 src/server/trinitycore/trinitycore.conf.dist delete mode 100644 src/server/trinityrealm/AuthCodes.cpp delete mode 100644 src/server/trinityrealm/AuthCodes.h delete mode 100644 src/server/trinityrealm/AuthSocket.cpp delete mode 100644 src/server/trinityrealm/AuthSocket.h delete mode 100644 src/server/trinityrealm/CMakeLists.txt delete mode 100644 src/server/trinityrealm/Main.cpp delete mode 100644 src/server/trinityrealm/RealmAcceptor.h delete mode 100644 src/server/trinityrealm/RealmList.cpp delete mode 100644 src/server/trinityrealm/RealmList.h delete mode 100644 src/server/trinityrealm/RealmSocket.cpp delete mode 100644 src/server/trinityrealm/RealmSocket.h delete mode 100644 src/server/trinityrealm/TrinityRealm.ico delete mode 100644 src/server/trinityrealm/TrinityRealm.rc delete mode 100644 src/server/trinityrealm/resource.h delete mode 100644 src/server/trinityrealm/trinityrealm.conf.dist create mode 100644 src/server/worldserver/CMakeLists.txt create mode 100644 src/server/worldserver/CliRunnable.cpp create mode 100644 src/server/worldserver/CliRunnable.h create mode 100644 src/server/worldserver/Main.cpp create mode 100644 src/server/worldserver/Master.cpp create mode 100644 src/server/worldserver/Master.h create mode 100644 src/server/worldserver/RASocket.cpp create mode 100644 src/server/worldserver/RASocket.h create mode 100644 src/server/worldserver/TrinityCore.ico create mode 100644 src/server/worldserver/TrinityCore.rc create mode 100644 src/server/worldserver/WorldRunnable.cpp create mode 100644 src/server/worldserver/WorldRunnable.h create mode 100644 src/server/worldserver/resource.h create mode 100644 src/server/worldserver/trinitycore.conf.dist (limited to 'src/server') diff --git a/src/server/authserver/AuthCodes.cpp b/src/server/authserver/AuthCodes.cpp new file mode 100644 index 00000000000..812949e0823 --- /dev/null +++ b/src/server/authserver/AuthCodes.cpp @@ -0,0 +1,37 @@ +#include "AuthCodes.h" + +namespace AuthHelper +{ + +bool IsPreBCAcceptedClientBuild(int build) +{ + int accepted_versions[] = PRE_BC_ACCEPTED_CLIENT_BUILD; + for (int i = 0; accepted_versions[i]; ++i) + { + if (build == accepted_versions[i]) + { + return true; + } + } + return false; +} + +bool IsPostBCAcceptedClientBuild(int build) +{ + int accepted_versions[] = POST_BC_ACCEPTED_CLIENT_BUILD; + for (int i = 0; accepted_versions[i]; ++i) + { + if (build == accepted_versions[i]) + { + return true; + } + } + return false; +} + +bool IsAcceptedClientBuild(int build) +{ + return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); +} + +}; diff --git a/src/server/authserver/AuthCodes.h b/src/server/authserver/AuthCodes.h new file mode 100644 index 00000000000..eb6e4abfb08 --- /dev/null +++ b/src/server/authserver/AuthCodes.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup realmd +*/ + +#ifndef _AUTHCODES_H +#define _AUTHCODES_H + +enum AuthResult +{ + WOW_SUCCESS = 0x00, + WOW_FAIL_UNKNOWN0 = 0x01, ///< ? Unable to connect + WOW_FAIL_UNKNOWN1 = 0x02, ///< ? Unable to connect + WOW_FAIL_BANNED = 0x03, ///< This account has been closed and is no longer available for use. Please go to /banned.html for further information. + WOW_FAIL_UNKNOWN_ACCOUNT = 0x04, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information + WOW_FAIL_INCORRECT_PASSWORD = 0x05, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information + WOW_FAIL_ALREADY_ONLINE = 0x06, ///< This account is already logged into . Please check the spelling and try again. + WOW_FAIL_NO_TIME = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing + WOW_FAIL_DB_BUSY = 0x08, ///< Could not log in to at this time. Please try again later. + WOW_FAIL_VERSION_INVALID = 0x09, ///< Unable to validate game version. This may be caused by file corruption or interference of another program. Please visit for more information and possible solutions to this issue. + WOW_FAIL_VERSION_UPDATE = 0x0A, ///< Downloading + WOW_FAIL_INVALID_SERVER = 0x0B, ///< Unable to connect + WOW_FAIL_SUSPENDED = 0x0C, ///< This account has been temporarily suspended. Please go to /banned.html for further information + WOW_FAIL_FAIL_NOACCESS = 0x0D, ///< Unable to connect + WOW_SUCCESS_SURVEY = 0x0E, ///< Connected. + WOW_FAIL_PARENTCONTROL = 0x0F, ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at + WOW_FAIL_LOCKED_ENFORCED = 0x10, ///< You have applied a lock to your account. You can change your locked status by calling your account lock phone number. + WOW_FAIL_TRIAL_ENDED = 0x11, ///< Your trial subscription has expired. Please visit to upgrade your account. + WOW_FAIL_USE_BATTLENET = 0x12, ///< WOW_FAIL_OTHER This account is now attached to a Battle.net account. Please login with your Battle.net account email address and password. +}; + +enum LoginResult +{ + LOGIN_OK = 0x00, + LOGIN_FAILED = 0x01, + LOGIN_FAILED2 = 0x02, + LOGIN_BANNED = 0x03, + LOGIN_UNKNOWN_ACCOUNT = 0x04, + LOGIN_UNKNOWN_ACCOUNT3 = 0x05, + LOGIN_ALREADYONLINE = 0x06, + LOGIN_NOTIME = 0x07, + LOGIN_DBBUSY = 0x08, + LOGIN_BADVERSION = 0x09, + LOGIN_DOWNLOAD_FILE = 0x0A, + LOGIN_FAILED3 = 0x0B, + LOGIN_SUSPENDED = 0x0C, + LOGIN_FAILED4 = 0x0D, + LOGIN_CONNECTED = 0x0E, + LOGIN_PARENTALCONTROL = 0x0F, + LOGIN_LOCKED_ENFORCED = 0x10, +}; + +//multirealm supported versions: +//1.12.1 build 5875 +//1.12.2 build 6005 +//2.4.3 build 8606 +//3.1.3 build 9947 +//3.1.3 build 10146 Chinese build +//3.2.2a build 10505 +//3.3.0a build 11159 +//3.3.2 build 11403 +//3.3.3a build 11723 + +#define POST_BC_ACCEPTED_CLIENT_BUILD {11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0} +#define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0} + +#define POST_BC_EXP_FLAG 0x2 +#define PRE_BC_EXP_FLAG 0x1 +#define NO_VALID_EXP_FLAG 0x0 + +namespace AuthHelper +{ + bool IsAcceptedClientBuild(int build); + bool IsPostBCAcceptedClientBuild(int build); + bool IsPreBCAcceptedClientBuild(int build); +}; + +#endif diff --git a/src/server/authserver/AuthSocket.cpp b/src/server/authserver/AuthSocket.cpp new file mode 100644 index 00000000000..cc293097977 --- /dev/null +++ b/src/server/authserver/AuthSocket.cpp @@ -0,0 +1,1069 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup realmd +*/ + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "ByteBuffer.h" +#include "Config/ConfigEnv.h" +#include "Log.h" +#include "RealmList.h" +#include "AuthSocket.h" +#include "AuthCodes.h" +#include +#include "Auth/Sha1.h" +//#include "Util.h" -- for commented utf8ToUpperOnlyLatin + +extern DatabaseType LoginDatabase; + +#define ChunkSize 2048 + +enum eAuthCmd +{ + //AUTH_NO_CMD = 0xFF, + AUTH_LOGON_CHALLENGE = 0x00, + AUTH_LOGON_PROOF = 0x01, + AUTH_RECONNECT_CHALLENGE = 0x02, + AUTH_RECONNECT_PROOF = 0x03, + //update srv =4 + REALM_LIST = 0x10, + XFER_INITIATE = 0x30, + XFER_DATA = 0x31, + XFER_ACCEPT = 0x32, + XFER_RESUME = 0x33, + XFER_CANCEL = 0x34 +}; + +enum eStatus +{ + STATUS_CONNECTED = 0, + STATUS_AUTHED +}; + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some paltform +#if defined(__GNUC__) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +typedef struct AUTH_LOGON_CHALLENGE_C +{ + uint8 cmd; + uint8 error; + uint16 size; + uint8 gamename[4]; + uint8 version1; + uint8 version2; + uint8 version3; + uint16 build; + uint8 platform[4]; + uint8 os[4]; + uint8 country[4]; + uint32 timezone_bias; + uint32 ip; + uint8 I_len; + uint8 I[1]; +} sAuthLogonChallenge_C; + +typedef struct AUTH_LOGON_PROOF_C +{ + uint8 cmd; + uint8 A[32]; + uint8 M1[20]; + uint8 crc_hash[20]; + uint8 number_of_keys; + uint8 securityFlags; // 0x00-0x04 +} sAuthLogonProof_C; + +typedef struct AUTH_LOGON_PROOF_S +{ + uint8 cmd; + uint8 error; + uint8 M2[20]; + uint32 unk1; + uint32 unk2; + uint16 unk3; +} sAuthLogonProof_S; + +typedef struct AUTH_LOGON_PROOF_S_OLD +{ + uint8 cmd; + uint8 error; + uint8 M2[20]; + //uint32 unk1; + uint32 unk2; + //uint16 unk3; +} sAuthLogonProof_S_Old; + +typedef struct AUTH_RECONNECT_PROOF_C +{ + uint8 cmd; + uint8 R1[16]; + uint8 R2[20]; + uint8 R3[20]; + uint8 number_of_keys; +} sAuthReconnectProof_C; + +typedef struct XFER_INIT +{ + uint8 cmd; // XFER_INITIATE + uint8 fileNameLen; // strlen(fileName); + uint8 fileName[5]; // fileName[fileNameLen] + uint64 file_size; // file size (bytes) + uint8 md5[MD5_DIGEST_LENGTH]; // MD5 +} XFER_INIT; + +typedef struct XFER_DATA +{ + uint8 opcode; + uint16 data_size; + uint8 data[ChunkSize]; +} XFER_DATA_STRUCT; + +typedef struct AuthHandler +{ + eAuthCmd cmd; + uint32 status; + bool (AuthSocket::*handler)(void); +} AuthHandler; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform +#if defined(__GNUC__) +#pragma pack() +#else +#pragma pack(pop) +#endif + +/// Launch a thread to transfer a patch to the client +class PatcherRunnable: public ACE_Based::Runnable +{ + public: + PatcherRunnable(class AuthSocket *); + void run(); + + private: + AuthSocket * mySocket; +}; + +typedef struct PATCH_INFO +{ + uint8 md5[MD5_DIGEST_LENGTH]; +} PATCH_INFO; + +/// Caches MD5 hash of client patches present on the server +class Patcher +{ + public: + typedef std::map Patches; + ~Patcher(); + Patcher(); + Patches::const_iterator begin() const { return _patches.begin(); } + Patches::const_iterator end() const { return _patches.end(); } + void LoadPatchMD5(char*); + bool GetHash(char * pat,uint8 mymd5[16]); + + private: + void LoadPatchesInfo(); + Patches _patches; +}; + +const AuthHandler table[] = +{ + { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge }, + { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof }, + { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge}, + { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof }, + { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList }, + { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept }, + { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume }, + { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel } +}; + +#define AUTH_TOTAL_COMMANDS sizeof(table)/sizeof(AuthHandler) + +///Holds the MD5 hash of client patches present on the server +Patcher PatchesCache; + +/// Constructor - set the N and g values for SRP6 +AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket) +{ + N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); + g.SetDword(7); + _authed = false; + _accountSecurityLevel = SEC_PLAYER; +} + +/// Close patch file descriptor before leaving +AuthSocket::~AuthSocket(void) +{ +} + +/// Accept the connection and set the s random value for SRP6 +void AuthSocket::OnAccept(void) +{ + sLog.outBasic("Accepting connection from '%s'", socket().get_remote_address().c_str()); +} + +void AuthSocket::OnClose(void) +{ + sLog.outDebug("AuthSocket::OnClose"); +} + +/// Read the packet from the client +void AuthSocket::OnRead() +{ + uint8 _cmd; + while (1) + { + if (!socket().recv_soft((char *)&_cmd, 1)) + return; + + size_t i; + + ///- Circle through known commands and call the correct command handler + for (i = 0; i < AUTH_TOTAL_COMMANDS; ++i) + { + if ((uint8)table[i].cmd == _cmd && + (table[i].status == STATUS_CONNECTED || + (_authed && table[i].status == STATUS_AUTHED))) + { + DEBUG_LOG("[Auth] got data for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len()); + + if (!(*this.*table[i].handler)()) + { + DEBUG_LOG("Command handler failed for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len()); + return; + } + break; + } + } + + // Report unknown packets in the error log + if (i == AUTH_TOTAL_COMMANDS) + { + sLog.outError("[Auth] got unknown packet from '%s'", socket().get_remote_address().c_str()); + socket().shutdown(); + return; + } + } +} + +/// Make the SRP6 calculation from hash in dB +void AuthSocket::_SetVSFields(const std::string& rI) +{ + s.SetRand(s_BYTE_SIZE * 8); + + BigNumber I; + I.SetHexStr(rI.c_str()); + + // In case of leading zeros in the rI hash, restore them + uint8 mDigest[SHA_DIGEST_LENGTH]; + memset(mDigest, 0, SHA_DIGEST_LENGTH); + if (I.GetNumBytes() <= SHA_DIGEST_LENGTH) + memcpy(mDigest, I.AsByteArray(), I.GetNumBytes()); + + std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH); + + Sha1Hash sha; + sha.UpdateData(s.AsByteArray(), s.GetNumBytes()); + sha.UpdateData(mDigest, SHA_DIGEST_LENGTH); + sha.Finalize(); + BigNumber x; + x.SetBinary(sha.GetDigest(), sha.GetLength()); + v = g.ModExp(x, N); + // No SQL injection (username escaped) + const char *v_hex, *s_hex; + v_hex = v.AsHexStr(); + s_hex = s.AsHexStr(); + LoginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '%s'", v_hex, s_hex, _safelogin.c_str()); + OPENSSL_free((void*)v_hex); + OPENSSL_free((void*)s_hex); +} + +/// Logon Challenge command handler +bool AuthSocket::_HandleLogonChallenge() +{ + DEBUG_LOG("Entering _HandleLogonChallenge"); + if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) + return false; + + ///- Read the first 4 bytes (header) to get the length of the remaining of the packet + std::vector buf; + buf.resize(4); + + socket().recv((char *)&buf[0], 4); + + EndianConvert(*((uint16*)(buf[0]))); + uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; + DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining); + + if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) + return false; + + //No big fear of memory outage (size is int16, i.e. < 65536) + buf.resize(remaining + buf.size() + 1); + buf[buf.size() - 1] = 0; + sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; + + ///- Read the remaining of the packet + socket().recv((char *)&buf[4], remaining); + DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); + DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); + + // BigEndian code, nop in little endian case + // size already converted + EndianConvert(*((uint32*)(&ch->gamename[0]))); + EndianConvert(ch->build); + EndianConvert(*((uint32*)(&ch->platform[0]))); + EndianConvert(*((uint32*)(&ch->os[0]))); + EndianConvert(*((uint32*)(&ch->country[0]))); + EndianConvert(ch->timezone_bias); + EndianConvert(ch->ip); + + ByteBuffer pkt; + + _login = (const char*)ch->I; + _build = ch->build; + _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) + (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); + + ///- Normalize account name + //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form + + //Escape the user login to avoid further SQL injection + //Memory will be freed on AuthSocket object destruction + _safelogin = _login; + LoginDatabase.escape_string(_safelogin); + + _build = ch->build; + + pkt << (uint8) AUTH_LOGON_CHALLENGE; + pkt << (uint8) 0x00; + + ///- Verify that this IP is not in the ip_banned table + // No SQL injection possible (paste the IP address as passed by the socket) + LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + + std::string address(socket().get_remote_address().c_str()); + LoginDatabase.escape_string(address); + QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); + if (result) + { + pkt << (uint8)WOW_FAIL_BANNED; + sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!", address.c_str ()); + } + else + { + ///- Get the account details from the account table + // No SQL injection (escaped user name) + + result = LoginDatabase.PQuery("SELECT a.sha_pass_hash,a.id,a.locked,a.last_ip,aa.gmlevel,a.v,a.s " + "FROM account a " + "LEFT JOIN account_access aa " + "ON (a.id = aa.id) " + "WHERE a.username = '%s'",_safelogin.c_str ()); + if (result) + { + ///- If the IP is 'locked', check that the player comes indeed from the correct IP address + bool locked = false; + if ((*result)[2].GetUInt8() == 1) // if ip is locked + { + DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); + DEBUG_LOG("[AuthChallenge] Player address is '%s'", socket().get_remote_address().c_str()); + if (strcmp((*result)[3].GetString(),socket().get_remote_address().c_str())) + { + DEBUG_LOG("[AuthChallenge] Account IP differs"); + pkt << (uint8) WOW_FAIL_SUSPENDED; + locked=true; + } + else + DEBUG_LOG("[AuthChallenge] Account IP matches"); + } + else + DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); + + if (!locked) + { + //set expired bans to inactive + LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); + ///- If the account is banned, reject the logon attempt + QueryResult_AutoPtr banresult = LoginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); + if (banresult) + { + if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) + { + pkt << (uint8) WOW_FAIL_BANNED; + sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); + } + else + { + pkt << (uint8) WOW_FAIL_SUSPENDED; + sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); + } + } + else + { + ///- Get the password from the account table, upper it, and make the SRP6 calculation + std::string rI = (*result)[0].GetCppString(); + + ///- Don't calculate (v, s) if there are already some in the database + std::string databaseV = (*result)[5].GetCppString(); + std::string databaseS = (*result)[6].GetCppString(); + + sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); + + // multiply with 2, bytes are stored as hexstring + if (databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2) + _SetVSFields(rI); + else + { + s.SetHexStr(databaseS.c_str()); + v.SetHexStr(databaseV.c_str()); + } + + b.SetRand(19 * 8); + BigNumber gmod = g.ModExp(b, N); + B = ((v * 3) + gmod) % N; + + ASSERT(gmod.GetNumBytes() <= 32); + + BigNumber unk3; + unk3.SetRand(16 * 8); + + ///- Fill the response packet with the result + pkt << uint8(WOW_SUCCESS); + + // B may be calculated < 32B so we force minimal length to 32B + pkt.append(B.AsByteArray(32), 32); // 32 bytes + pkt << uint8(1); + pkt.append(g.AsByteArray(), 1); + pkt << uint8(32); + pkt.append(N.AsByteArray(32), 32); + pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes + pkt.append(unk3.AsByteArray(16), 16); + uint8 securityFlags = 0; + pkt << uint8(securityFlags); // security flags (0x0...0x04) + + if (securityFlags & 0x01) // PIN input + { + pkt << uint32(0); + pkt << uint64(0) << uint64(0); // 16 bytes hash? + } + + if (securityFlags & 0x02) // Matrix input + { + pkt << uint8(0); + pkt << uint8(0); + pkt << uint8(0); + pkt << uint8(0); + pkt << uint64(0); + } + + if (securityFlags & 0x04) // Security token input + pkt << uint8(1); + + uint8 secLevel = (*result)[4].GetUInt8(); + _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; + + _localizationName.resize(4); + for (int i = 0; i < 4; ++i) + _localizationName[i] = ch->country[4-i-1]; + + sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)); + } + } + } + else //no account + { + pkt<< (uint8) WOW_FAIL_UNKNOWN_ACCOUNT; + } + } + + socket().send((char const*)pkt.contents(), pkt.size()); + return true; +} + +/// Logon Proof command handler +bool AuthSocket::_HandleLogonProof() +{ + DEBUG_LOG("Entering _HandleLogonProof"); + ///- Read the packet + sAuthLogonProof_C lp; + + if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) + return false; + + ///
  • If the client has no valid version + if (_expversion == NO_VALID_EXP_FLAG) + { + ///- Check if we have the appropriate patch on the disk + + sLog.outDebug("Client with invalid version, patching is not implemented"); + socket().shutdown(); + return true; + } + ///
+ + ///- Continue the SRP6 calculation based on data received from the client + BigNumber A; + + A.SetBinary(lp.A, 32); + + // SRP safeguard: abort if A==0 + if (A.isZero()) + { + socket().shutdown(); + return true; + } + + Sha1Hash sha; + sha.UpdateBigNumbers(&A, &B, NULL); + sha.Finalize(); + BigNumber u; + u.SetBinary(sha.GetDigest(), 20); + BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); + + uint8 t[32]; + uint8 t1[16]; + uint8 vK[40]; + memcpy(t, S.AsByteArray(32), 32); + for (int i = 0; i < 16; ++i) + { + t1[i] = t[i * 2]; + } + sha.Initialize(); + sha.UpdateData(t1, 16); + sha.Finalize(); + for (int i = 0; i < 20; ++i) + { + vK[i * 2] = sha.GetDigest()[i]; + } + for (int i = 0; i < 16; ++i) + { + t1[i] = t[i * 2 + 1]; + } + sha.Initialize(); + sha.UpdateData(t1, 16); + sha.Finalize(); + for (int i = 0; i < 20; ++i) + { + vK[i * 2 + 1] = sha.GetDigest()[i]; + } + K.SetBinary(vK, 40); + + uint8 hash[20]; + + sha.Initialize(); + sha.UpdateBigNumbers(&N, NULL); + sha.Finalize(); + memcpy(hash, sha.GetDigest(), 20); + sha.Initialize(); + sha.UpdateBigNumbers(&g, NULL); + sha.Finalize(); + for (int i = 0; i < 20; ++i) + { + hash[i] ^= sha.GetDigest()[i]; + } + BigNumber t3; + t3.SetBinary(hash, 20); + + sha.Initialize(); + sha.UpdateData(_login); + sha.Finalize(); + uint8 t4[SHA_DIGEST_LENGTH]; + memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); + + sha.Initialize(); + sha.UpdateBigNumbers(&t3, NULL); + sha.UpdateData(t4, SHA_DIGEST_LENGTH); + sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); + sha.Finalize(); + BigNumber M; + M.SetBinary(sha.GetDigest(), 20); + + ///- Check if SRP6 results match (password is correct), else send an error + if (!memcmp(M.AsByteArray(), lp.M1, 20)) + { + sLog.outBasic("User '%s' successfully authenticated", _login.c_str()); + + ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account + // No SQL injection (escaped user name) and IP address as received by socket + const char* K_hex = K.AsHexStr(); + LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, socket().get_remote_address().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str()); + OPENSSL_free((void*)K_hex); + + ///- Finish SRP6 and send the final result to the client + sha.Initialize(); + sha.UpdateBigNumbers(&A, &M, &K, NULL); + sha.Finalize(); + + if (_expversion & POST_BC_EXP_FLAG)//2.4.3 and 3.1.3 clients (10146 is Chinese build for 3.1.3) + { + sAuthLogonProof_S proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk1 = 0x00800000; + proof.unk2 = 0x00; + proof.unk3 = 0x00; + socket().send((char *)&proof, sizeof(proof)); + } + else + { + sAuthLogonProof_S_Old proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + //proof.unk1 = 0x00800000; + proof.unk2 = 0x00; + //proof.unk3 = 0x00; + socket().send((char *)&proof, sizeof(proof)); + } + + ///- Set _authed to true! + _authed = true; + } + else + { + char data[4]= { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0}; + socket().send(data, sizeof(data)); + sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ()); + + uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); + if (MaxWrongPassCount > 0) + { + //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP + LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str()); + + if (QueryResult_AutoPtr loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str())) + { + Field* fields = loginfail->Fetch(); + uint32 failed_logins = fields[1].GetUInt32(); + + if (failed_logins >= MaxWrongPassCount) + { + uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); + bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); + + if (WrongPassBanType) + { + uint32 acc_id = fields[0].GetUInt32(); + LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)", + acc_id, WrongPassBanTime); + sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", + _login.c_str(), WrongPassBanTime, failed_logins); + } + else + { + std::string current_ip(socket().get_remote_address().c_str()); + LoginDatabase.escape_string(current_ip); + LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')", + current_ip.c_str(), WrongPassBanTime); + sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", + current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); + } + } + } + } + } + + return true; +} + +/// Reconnect Challenge command handler +bool AuthSocket::_HandleReconnectChallenge() +{ + DEBUG_LOG("Entering _HandleReconnectChallenge"); + if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) + return false; + + ///- Read the first 4 bytes (header) to get the length of the remaining of the packet + std::vector buf; + buf.resize(4); + + socket().recv((char *)&buf[0], 4); + + EndianConvert(*((uint16*)(buf[0]))); + uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; + DEBUG_LOG("[ReconnectChallenge] got header, body is %#04x bytes", remaining); + + if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) + return false; + + //No big fear of memory outage (size is int16, i.e. < 65536) + buf.resize(remaining + buf.size() + 1); + buf[buf.size() - 1] = 0; + sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; + + ///- Read the remaining of the packet + socket().recv((char *)&buf[4], remaining); + DEBUG_LOG("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); + DEBUG_LOG("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); + + _login = (const char*)ch->I; + _safelogin = _login; + + QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ()); + + // Stop if the account is not found + if (!result) + { + sLog.outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str()); + socket().shutdown(); + return false; + } + + Field* fields = result->Fetch (); + K.SetHexStr (fields[0].GetString ()); + + ///- Sending response + ByteBuffer pkt; + pkt << (uint8) AUTH_RECONNECT_CHALLENGE; + pkt << (uint8) 0x00; + _reconnectProof.SetRand(16 * 8); + pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random + pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros + socket().send((char const*)pkt.contents(), pkt.size()); + return true; +} + +/// Reconnect Proof command handler +bool AuthSocket::_HandleReconnectProof() +{ + DEBUG_LOG("Entering _HandleReconnectProof"); + ///- Read the packet + sAuthReconnectProof_C lp; + if (!socket().recv((char *)&lp, sizeof(sAuthReconnectProof_C))) + return false; + + if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) + return false; + + BigNumber t1; + t1.SetBinary(lp.R1, 16); + + Sha1Hash sha; + sha.Initialize(); + sha.UpdateData(_login); + sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); + sha.Finalize(); + + if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) + { + ///- Sending response + ByteBuffer pkt; + pkt << (uint8) AUTH_RECONNECT_PROOF; + pkt << (uint8) 0x00; + pkt << (uint16) 0x00; // 2 bytes zeros + socket().send((char const*)pkt.contents(), pkt.size()); + + ///- Set _authed to true! + _authed = true; + + return true; + } + else + { + sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str()); + socket().shutdown(); + return false; + } +} + +/// %Realm List command handler +bool AuthSocket::_HandleRealmList() +{ + DEBUG_LOG("Entering _HandleRealmList"); + if (socket().recv_len() < 5) + return false; + + socket().recv_skip(5); + + ///- Get the user id (else close the connection) + // No SQL injection (escaped user name) + + QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",_safelogin.c_str()); + if (!result) + { + sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str()); + socket().shutdown(); + return false; + } + + uint32 id = (*result)[0].GetUInt32(); + + ///- Update realm list if need + sRealmList->UpdateIfNeed(); + + ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) + ByteBuffer pkt; + + size_t RealmListSize = 0; + for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) + { + // don't work with realms which not compatible with the client + if (_expversion & POST_BC_EXP_FLAG) // 2.4.3 and 3.1.3 cliens + { + if (i->second.gamebuild != _build) + continue; + } + else if (_expversion & PRE_BC_EXP_FLAG) // 1.12.1 and 1.12.2 clients are compatible with eachother + { + if (!AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) + continue; + } + + uint8 AmountOfCharacters; + + // No SQL injection. id of realm is controlled by the database. + result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id); + if (result) + { + Field *fields = result->Fetch(); + AmountOfCharacters = fields[0].GetUInt8(); + } + else + AmountOfCharacters = 0; + + uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + + pkt << i->second.icon; // realm type + if ( _expversion & POST_BC_EXP_FLAG )//only 2.4.3 and 3.1.3 cliens + pkt << lock; // if 1, then realm locked + pkt << i->second.color; // if 2, then realm is offline + pkt << i->first; + pkt << i->second.address; + pkt << i->second.populationLevel; + pkt << AmountOfCharacters; + pkt << i->second.timezone; // realm category + if ( _expversion & POST_BC_EXP_FLAG )//2.4.3 and 3.1.3 clients + pkt << (uint8) 0x2C; // unk, may be realm number/id? + else + pkt << (uint8) 0x0; //1.12.1 and 1.12.2 clients + + ++RealmListSize; + } + + if ( _expversion & POST_BC_EXP_FLAG )//2.4.3 and 3.1.3 cliens + { + pkt << (uint8) 0x10; + pkt << (uint8) 0x00; + }else{//1.12.1 and 1.12.2 clients + pkt << (uint8) 0x00; + pkt << (uint8) 0x02; + } + + // make a ByteBuffer which stores the RealmList's size + ByteBuffer RealmListSizeBuffer; + RealmListSizeBuffer << (uint32)0; + if (_expversion & POST_BC_EXP_FLAG) // only 2.4.3 and 3.1.3 cliens + RealmListSizeBuffer << (uint16)RealmListSize; + else + RealmListSizeBuffer << (uint32)RealmListSize; + + ByteBuffer hdr; + hdr << (uint8) REALM_LIST; + hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); + hdr.append(RealmListSizeBuffer); // append RealmList's size buffer + hdr.append(pkt); // append realms in the realmlist + + socket().send((char const*)hdr.contents(), hdr.size()); + + return true; +} + +/// Resume patch transfer +bool AuthSocket::_HandleXferResume() +{ + DEBUG_LOG("Entering _HandleXferResume"); + ///- Check packet length and patch existence + if (socket().recv_len() < 9 || !pPatch) + { + sLog.outError("Error while resuming patch transfer (wrong packet)"); + return false; + } + + ///- Launch a PatcherRunnable thread starting at given patch file offset + uint64 start; + socket().recv_skip(1); + socket().recv((char*)&start,sizeof(start)); + fseek(pPatch, start, 0); + + ACE_Based::Thread u(new PatcherRunnable(this)); + return true; +} + +/// Cancel patch transfer +bool AuthSocket::_HandleXferCancel() +{ + DEBUG_LOG("Entering _HandleXferCancel"); + + ///- Close and delete the socket + socket().recv_skip(1); //clear input buffer + + socket().shutdown(); + + return true; +} + +/// Accept patch transfer +bool AuthSocket::_HandleXferAccept() +{ + DEBUG_LOG("Entering _HandleXferAccept"); + + ///- Check packet length and patch existence + if (!pPatch) + { + sLog.outError("Error while accepting patch transfer (wrong packet)"); + return false; + } + + ///- Launch a PatcherRunnable thread, starting at the beginning of the patch file + socket().recv_skip(1); // clear input buffer + fseek(pPatch, 0, 0); + + ACE_Based::Thread u(new PatcherRunnable(this)); + return true; +} + +PatcherRunnable::PatcherRunnable(class AuthSocket * as) +{ + mySocket = as; +} + +/// Send content of patch file to the client +void PatcherRunnable::run() +{ +} + +/// Preload MD5 hashes of existing patch files on server +#ifndef _WIN32 +#include +#include +void Patcher::LoadPatchesInfo() +{ + DIR * dirp; + //int errno; + struct dirent * dp; + dirp = opendir("./patches/"); + if (!dirp) + return; + while (dirp) + { + errno = 0; + if ((dp = readdir(dirp)) != NULL) + { + int l = strlen(dp->d_name); + if (l < 8) + continue; + if (!memcmp(&dp->d_name[l-4],".mpq",4)) + LoadPatchMD5(dp->d_name); + } + else + { + if (errno != 0) + { + closedir(dirp); + return; + } + break; + } + } + + if (dirp) + closedir(dirp); +} + +#else +void Patcher::LoadPatchesInfo() +{ + WIN32_FIND_DATA fil; + HANDLE hFil=FindFirstFile("./patches/*.mpq", &fil); + if (hFil == INVALID_HANDLE_VALUE) + return; // no patches were found + + do + { + LoadPatchMD5(fil.cFileName); + } + while(FindNextFile(hFil, &fil)); +} +#endif + +/// Calculate and store MD5 hash for a given patch file +void Patcher::LoadPatchMD5(char * szFileName) +{ + ///- Try to open the patch file + std::string path = "./patches/"; + path += szFileName; + FILE *pPatch = fopen(path.c_str(), "rb"); + sLog.outDebug("Loading patch info from %s\n", path.c_str()); + if (!pPatch) + { + sLog.outError("Error loading patch %s\n", path.c_str()); + return; + } + + ///- Calculate the MD5 hash + MD5_CTX ctx; + MD5_Init(&ctx); + uint8* buf = new uint8[512*1024]; + + while (!feof(pPatch)) + { + size_t read = fread(buf, 1, 512*1024, pPatch); + MD5_Update(&ctx, buf, read); + } + delete [] buf; + fclose(pPatch); + + ///- Store the result in the internal patch hash map + _patches[path] = new PATCH_INFO; + MD5_Final((uint8 *)&_patches[path]->md5, &ctx); +} + +/// Get cached MD5 hash for a given patch file +bool Patcher::GetHash(char * pat, uint8 mymd5[16]) +{ + for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i) + if (!stricmp(pat, i->first.c_str())) + { + memcpy(mymd5, i->second->md5, 16); + return true; + } + + return false; +} + +/// Launch the patch hashing mechanism on object creation +Patcher::Patcher() +{ + LoadPatchesInfo(); +} + +/// Empty and delete the patch map on termination +Patcher::~Patcher() +{ + for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i) + delete i->second; +} diff --git a/src/server/authserver/AuthSocket.h b/src/server/authserver/AuthSocket.h new file mode 100644 index 00000000000..bfd0fa4fdca --- /dev/null +++ b/src/server/authserver/AuthSocket.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup realmd +/// @{ +/// \file + +#ifndef _AUTHSOCKET_H +#define _AUTHSOCKET_H + +#include "Common.h" +#include "Auth/BigNumber.h" + +#include "RealmSocket.h" + +enum RealmFlags +{ + REALM_FLAG_NONE = 0x00, + REALM_FLAG_INVALID = 0x01, + REALM_FLAG_OFFLINE = 0x02, + REALM_FLAG_SPECIFYBUILD = 0x04, // client will show realm version in RealmList screen in form "RealmName (major.minor.revision.build)" + REALM_FLAG_UNK1 = 0x08, + REALM_FLAG_UNK2 = 0x10, + REALM_FLAG_RECOMMENDED = 0x20, // client checks pop == 600f + REALM_FLAG_NEW = 0x40, // client checks pop == 200f + REALM_FLAG_FULL = 0x80 // client checks pop == 400f +}; + +/// Handle login commands +class AuthSocket: public RealmSocket::Session +{ + public: + const static int s_BYTE_SIZE = 32; + + AuthSocket(RealmSocket& socket); + virtual ~AuthSocket(void); + + virtual void OnRead(void); + virtual void OnAccept(void); + virtual void OnClose(void); + + bool _HandleLogonChallenge(); + bool _HandleLogonProof(); + bool _HandleReconnectChallenge(); + bool _HandleReconnectProof(); + bool _HandleRealmList(); + //data transfer handle for patch + + bool _HandleXferResume(); + bool _HandleXferCancel(); + bool _HandleXferAccept(); + + void _SetVSFields(const std::string& rI); + + FILE *pPatch; + ACE_Thread_Mutex patcherLock; + + private: + RealmSocket& socket_; + RealmSocket& socket(void) { return socket_; } + + BigNumber N, s, g, v; + BigNumber b, B; + BigNumber K; + BigNumber _reconnectProof; + + bool _authed; + + std::string _login; + std::string _safelogin; + + // Since GetLocaleByName() is _NOT_ bijective, we have to store the locale as a string. Otherwise we can't differ + // between enUS and enGB, which is important for the patch system + std::string _localizationName; + uint16 _build; + uint8 _expversion; + AccountTypes _accountSecurityLevel; +}; +#endif +/// @} diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt new file mode 100644 index 00000000000..8f3e9b87540 --- /dev/null +++ b/src/server/authserver/CMakeLists.txt @@ -0,0 +1,60 @@ +########### next target ############### + +SET(trinity-realm_SRCS +AuthCodes.cpp +AuthCodes.h +AuthSocket.cpp +AuthSocket.h +Main.cpp +RealmList.cpp +RealmList.h +RealmSocket.h +RealmSocket.cpp +RealmAcceptor.h +) + +include_directories( + ${ACE_INCLUDE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src/shared + ${CMAKE_SOURCE_DIR}/src/shared/Database + ${CMAKE_SOURCE_DIR}/src/framework + ${MYSQL_INCLUDE_DIR} +) + +SET(trinity-realm_LINK_FLAGS "") + +add_executable(trinity-realm ${trinity-realm_SRCS}) +add_definitions( +-D_TRINITY_REALM_CONFIG='"${CONF_DIR}/trinityrealm.conf"' +) +IF (DO_MYSQL) + SET(trinity-realm_LINK_FLAGS "-pthread ${trinity-realm_LINK_FLAGS}") +ENDIF(DO_MYSQL) + +IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") + SET(trinity-realm_LINK_FLAGS "-framework Carbon ${trinity-realm_LINK_FLAGS}") +ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin") + +SET_TARGET_PROPERTIES(trinity-realm PROPERTIES LINK_FLAGS "${trinity-realm_LINK_FLAGS}") + +target_link_libraries( +trinity-realm +shared +trinityframework +trinitysockets +trinitydatabase +trinityauth +trinityconfig +zlib +${SSLLIB} +${MYSQL_LIBRARIES} +${OSX_LIBS} +) + +install(TARGETS trinity-realm DESTINATION bin) + + +########### install files ############### + +install(FILES trinityrealm.conf.dist DESTINATION etc) diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp new file mode 100644 index 00000000000..09bae4908e0 --- /dev/null +++ b/src/server/authserver/Main.cpp @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup realmd Realm Daemon +/// @{ +/// \file + +#include "Common.h" +#include "Database/DatabaseEnv.h" + +#include "Config/ConfigEnv.h" +#include "Log.h" +#include "SystemConfig.h" +#include "Util.h" +#include "SignalHandler.h" +#include "RealmList.h" +#include "RealmAcceptor.h" + +#include +#include +#include +#include + +#include +#include + +#ifndef _TRINITY_REALM_CONFIG +# define _TRINITY_REALM_CONFIG "TrinityRealm.conf" +#endif //_TRINITY_REALM_CONFIG + +#ifdef WIN32 +#include "ServiceWin32.h" +char serviceName[] = "TrinityRealm"; +char serviceLongName[] = "Trinity realm service"; +char serviceDescription[] = "Massive Network Game Object Server"; +/* + * -1 - not in service mode + * 0 - stopped + * 1 - running + * 2 - paused + */ +int m_ServiceStatus = -1; +#endif + +bool StartDB(); + +bool stopEvent = false; ///< Setting it to true stops the server + +DatabaseType LoginDatabase; ///< Accessor to the realm server database + +/// Handle realmd's termination signals +class RealmdSignalHandler : public Trinity::SignalHandler +{ + public: + virtual void HandleSignal(int SigNum) + { + switch (SigNum) + { + case SIGINT: + case SIGTERM: + stopEvent = true; + break; + #ifdef _WIN32 + case SIGBREAK: + if (m_ServiceStatus != 1) + stopEvent = true; + break; + #endif /* _WIN32 */ + } + } +}; + +/// Print out the usage string for this program on the console. +void usage(const char *prog) +{ + sLog.outString("Usage: \n %s []\n" + " -c config_file use config_file as configuration file\n\r" + #ifdef WIN32 + " Running as service functions:\n\r" + " --service run as service\n\r" + " -s install install service\n\r" + " -s uninstall uninstall service\n\r" + #endif + ,prog); +} + +/// Launch the realm server +extern int main(int argc, char **argv) +{ + sLog.SetLogDB(false); + ///- Command line parsing to get the configuration file name + char const* cfg_file = _TRINITY_REALM_CONFIG; + int c=1; + while(c < argc) + { + if (strcmp(argv[c],"-c") == 0) + { + if (++c >= argc) + { + sLog.outError("Runtime-Error: -c option requires an input argument"); + usage(argv[0]); + return 1; + } + else + cfg_file = argv[c]; + } + + #ifdef WIN32 + //////////// + //Services// + //////////// + if (strcmp(argv[c],"-s") == 0) + { + if (++c >= argc) + { + sLog.outError("Runtime-Error: -s option requires an input argument"); + usage(argv[0]); + return 1; + } + if (strcmp(argv[c],"install") == 0) + { + if (WinServiceInstall()) + sLog.outString("Installing service"); + return 1; + } + else if (strcmp(argv[c],"uninstall") == 0) + { + if (WinServiceUninstall()) + sLog.outString("Uninstalling service"); + return 1; + } + else + { + sLog.outError("Runtime-Error: unsupported option %s",argv[c]); + usage(argv[0]); + return 1; + } + } + if (strcmp(argv[c],"--service") == 0) + { + WinServiceRun(); + } + //// + #endif + ++c; + } + + if (!sConfig.SetSource(cfg_file)) + { + sLog.outError("Could not find configuration file %s.", cfg_file); + return 1; + } + sLog.Initialize(); + + sLog.outString("%s (realm-daemon)", _FULLVERSION); + sLog.outString(" to stop.\n"); + sLog.outString("Using configuration file %s.", cfg_file); + + sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); +#else + ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); +#endif + + sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); + + /// realmd PID file creation + std::string pidfile = sConfig.GetStringDefault("PidFile", ""); + if (!pidfile.empty()) + { + uint32 pid = CreatePIDFile(pidfile); + if (!pid) + { + sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); + return 1; + } + + sLog.outString("Daemon PID: %u\n", pid); + } + + ///- Initialize the database connection + if (!StartDB()) + return 1; + + ///- Initialize the log database + sLog.SetLogDBLater(sConfig.GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished. + sLog.SetLogDB(false); + sLog.SetRealmID(0); // ensure we've set realm to 0 (realmd realmid) + + ///- Get the list of realms for the server + sRealmList->Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); + if (sRealmList->size() == 0) + { + sLog.outError("No valid realms specified."); + return 1; + } + + ///- Launch the listening network socket + RealmAcceptor acceptor; + + uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); + std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); + + ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); + + if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) + { + sLog.outError("Trinity realm can not bind to %s:%d", bind_ip.c_str(), rmport); + return 1; + } + + // Initialise the signal handlers + RealmdSignalHandler SignalINT, SignalTERM; + #ifdef _WIN32 + RealmdSignalHandler SignalBREAK; + #endif /* _WIN32 */ + + // Register realmd's signal handlers + ACE_Sig_Handler Handler; + Handler.register_handler(SIGINT, &SignalINT); + Handler.register_handler(SIGTERM, &SignalTERM); + #ifdef _WIN32 + Handler.register_handler(SIGBREAK, &SignalBREAK); + #endif /* _WIN32 */(); + + ///- Handle affinity for multiple processors and process priority on Windows + #ifdef WIN32 + { + HANDLE hProcess = GetCurrentProcess(); + + uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); + if (Aff > 0) + { + ULONG_PTR appAff; + ULONG_PTR sysAff; + + if (GetProcessAffinityMask(hProcess,&appAff,&sysAff)) + { + ULONG_PTR curAff = Aff & appAff; // remove non accessible processors + + if (!curAff) + { + sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); + } + else + { + if (SetProcessAffinityMask(hProcess,curAff)) + sLog.outString("Using processors (bitmask, hex): %x", curAff); + else + sLog.outError("Can't set used processors (hex): %x", curAff); + } + } + sLog.outString(); + } + + bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); + + if (Prio) + { + if (SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) + sLog.outString("TrinityRealm process priority class set to HIGH"); + else + sLog.outError("ERROR: Can't set realmd process priority class."); + sLog.outString(); + } + } + #endif + + // maximum counter for next ping + uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); + uint32 loopCounter = 0; + + // possibly enable db logging; avoid massive startup spam by doing it here. + if (sLog.GetLogDBLater()) + { + sLog.outString("Enabling database logging..."); + sLog.SetLogDBLater(false); + // login db needs thread for logging + sLog.SetLogDB(true); + } + else + sLog.SetLogDB(false); + + ///- Wait for termination signal + while (!stopEvent) + { + // dont move this outside the loop, the reactor will modify it + ACE_Time_Value interval(0, 100000); + + if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) + break; + + if ((++loopCounter) == numLoops) + { + loopCounter = 0; + sLog.outDetail("Ping MySQL to keep connection alive"); + LoginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); + } +#ifdef WIN32 + if (m_ServiceStatus == 0) stopEvent = true; + while (m_ServiceStatus == 2) Sleep(1000); +#endif + } + + ///- Wait for the delay thread to exit + LoginDatabase.ThreadEnd(); + LoginDatabase.HaltDelayThread(); + + sLog.outString("Halting process..."); + return 0; +} + +/// Initialize connection to the database +bool StartDB() +{ + std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); + if (dbstring.empty()) + { + sLog.outError("Database not specified"); + return false; + } + + if (!LoginDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to database"); + return false; + } + LoginDatabase.ThreadStart(); + + return true; +} + +/// @} diff --git a/src/server/authserver/RealmAcceptor.h b/src/server/authserver/RealmAcceptor.h new file mode 100644 index 00000000000..5e243ea915b --- /dev/null +++ b/src/server/authserver/RealmAcceptor.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup realmd + */ + +#ifndef __REALMACCEPTOR_H__ +#define __REALMACCEPTOR_H__ + +#include +#include + +#include "RealmSocket.h" +#include "AuthSocket.h" + +class RealmAcceptor : public ACE_Acceptor +{ + public: + RealmAcceptor(void) { } + virtual ~RealmAcceptor(void) { } + + protected: + virtual int make_svc_handler(RealmSocket *&sh) + { + if (sh == 0) + ACE_NEW_RETURN(sh, RealmSocket, -1); + + sh->reactor(reactor()); + sh->set_session(new AuthSocket(*sh)); + return 0; + } +}; + +#endif /* __REALMACCEPTOR_H__ */ diff --git a/src/server/authserver/RealmList.cpp b/src/server/authserver/RealmList.cpp new file mode 100644 index 00000000000..1e989c36c5d --- /dev/null +++ b/src/server/authserver/RealmList.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup realmd +*/ + +#include "Common.h" +#include "RealmList.h" +#include "Database/DatabaseEnv.h" + + +extern DatabaseType LoginDatabase; + +RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)) +{ +} + +/// Load the realm list from the database +void RealmList::Initialize(uint32 updateInterval) +{ + m_UpdateInterval = updateInterval; + + ///- Get the content of the realmlist table in the database + UpdateRealms(true); +} + +void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build) +{ + ///- Create new if not exist or update existed + Realm& realm = m_realms[name]; + + realm.m_ID = ID; + realm.name = name; + realm.icon = icon; + realm.color = color; + realm.timezone = timezone; + realm.allowedSecurityLevel = allowedSecurityLevel; + realm.populationLevel = popu; + + ///- Append port to IP address. + std::ostringstream ss; + ss << address << ":" << port; + realm.address = ss.str(); + realm.gamebuild = build; +} + +void RealmList::UpdateIfNeed() +{ + // maybe disabled or updated recently + if (!m_UpdateInterval || m_NextUpdateTime > time(NULL)) + return; + + m_NextUpdateTime = time(NULL) + m_UpdateInterval; + + // Clears Realm list + m_realms.clear(); + + // Get the content of the realmlist table in the database + UpdateRealms(false); +} + +void RealmList::UpdateRealms(bool init) +{ + sLog.outDetail("Updating Realm List..."); + + QueryResult_AutoPtr result = LoginDatabase.Query("SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE color <> 3 ORDER BY name"); + + ///- Circle through results and add them to the realm map + if (result) + { + do + { + Field *fields = result->Fetch(); + + uint8 allowedSecurityLevel = fields[7].GetUInt8(); + + UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat(), fields[9].GetUInt32()); + if (init) + sLog.outString("Added realm \"%s\".", fields[1].GetString()); + } while(result->NextRow()); + } +} diff --git a/src/server/authserver/RealmList.h b/src/server/authserver/RealmList.h new file mode 100644 index 00000000000..b29b561c797 --- /dev/null +++ b/src/server/authserver/RealmList.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup realmd +/// @{ +/// \file + +#ifndef _REALMLIST_H +#define _REALMLIST_H + +#include +#include +#include "Common.h" + +/// Storage object for a realm +struct Realm +{ + std::string address; + std::string name; + uint8 icon; + uint8 color; + uint8 timezone; + uint32 m_ID; + AccountTypes allowedSecurityLevel; + float populationLevel; + uint32 gamebuild; +}; + +/// Storage object for the list of realms on the server +class RealmList +{ + public: + // Null_Mutex is safe because the singleton initialized before the acceptor initialized(another place where the singleton called) + static RealmList* instance() { return ACE_Singleton::instance(); } + + typedef std::map RealmMap; + + RealmList(); + ~RealmList() {} + + void Initialize(uint32 updateInterval); + + void UpdateIfNeed(); + + void AddRealm(Realm NewRealm) {m_realms[NewRealm.name] = NewRealm;} + + RealmMap::const_iterator begin() const { return m_realms.begin(); } + RealmMap::const_iterator end() const { return m_realms.end(); } + uint32 size() const { return m_realms.size(); } + private: + void UpdateRealms(bool init); + void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); + private: + RealmMap m_realms; ///< Internal map of realms + uint32 m_UpdateInterval; + time_t m_NextUpdateTime; +}; + +#define sRealmList RealmList::instance() + +#endif +/// @} diff --git a/src/server/authserver/RealmSocket.cpp b/src/server/authserver/RealmSocket.cpp new file mode 100644 index 00000000000..7eb96cb96f8 --- /dev/null +++ b/src/server/authserver/RealmSocket.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup realmd + */ + +#include "RealmSocket.h" + +#include "Log.h" + +#include +#include +#include + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +RealmSocket::Session::Session(void) +{ +} + +RealmSocket::Session::~Session(void) +{ +} + +RealmSocket::RealmSocket(void): + session_(NULL), + input_buffer_(4096), + remote_address_() +{ + reference_counting_policy().value( + ACE_Event_Handler::Reference_Counting_Policy::ENABLED); + + msg_queue()->high_water_mark(8*1024*1024); + msg_queue()->low_water_mark(8*1024*1024); + +} + +RealmSocket::~RealmSocket(void) +{ + if (msg_queue()) + msg_queue()->close(); + + // delete RealmSocketObject must never be called from our code. + closing_ = true; + + if (session_) + delete session_; + + peer().close(); +} + +int RealmSocket::open(void * arg) +{ + ACE_INET_Addr addr; + + if (peer ().get_remote_addr (addr) == -1) + { + sLog.outError ("RealmSocket::open: peer ().get_remote_addr errno = %s", ACE_OS::strerror (errno)); + return -1; + } + + remote_address_ = addr.get_host_addr(); + + // Register with ACE Reactor + if (Base::open(arg) == -1) + return -1; + + if (session_ != NULL) + { + session_->OnAccept(); + } + + // reactor takes care of the socket from now on + remove_reference(); + + return 0; +} + +int RealmSocket::close(int) +{ + shutdown(); + + closing_ = true; + + remove_reference(); + + return 0; +} + +const ACE_CString& RealmSocket::get_remote_address(void) const +{ + return remote_address_; +} + +size_t RealmSocket::recv_len(void) const +{ + return input_buffer_.length(); +} + +bool RealmSocket::recv_soft(char *buf, size_t len) +{ + if (input_buffer_.length() < len) + return false; + + ACE_OS::memcpy(buf, input_buffer_.rd_ptr(), len); + + return true; +} + +bool RealmSocket::recv(char *buf, size_t len) +{ + bool ret = recv_soft(buf, len); + + if (ret) + recv_skip(len); + + return ret; +} + +void RealmSocket::recv_skip(size_t len) +{ + input_buffer_.rd_ptr(len); +} + +ssize_t RealmSocket::noblk_send(ACE_Message_Block &message_block) +{ + const size_t len = message_block.length(); + + if (len == 0) + return -1; + + // Try to send the message directly. + ssize_t n = peer().send(message_block.rd_ptr(), len, MSG_NOSIGNAL); + + if (n < 0) + { + if (errno == EWOULDBLOCK) + // Blocking signal + return 0; + else + // Error happened + return -1; + } + else if (n == 0) + { + // Can this happen ? + return -1; + } + + // return bytes transmitted + return n; +} + +bool RealmSocket::send(const char *buf, size_t len) +{ + if (buf == NULL || len == 0) + return true; + + ACE_Data_Block db( + len, + ACE_Message_Block::MB_DATA, + (const char*)buf, + 0, + 0, + ACE_Message_Block::DONT_DELETE, + 0); + + ACE_Message_Block message_block( + &db, + ACE_Message_Block::DONT_DELETE, + 0); + + message_block.wr_ptr(len); + + if (msg_queue()->is_empty()) + { + // Try to send it directly. + ssize_t n = noblk_send(message_block); + + if (n < 0) + return false; + else if (n == len) + return true; + + // fall down + message_block.rd_ptr((size_t)n); + } + + ACE_Message_Block *mb = message_block.clone(); + + if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + { + mb->release(); + return false; + } + + if (reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK) == -1) + return false; + + return true; +} + +int RealmSocket::handle_output(ACE_HANDLE /*= ACE_INVALID_HANDLE*/) +{ + if (closing_) + return -1; + + ACE_Message_Block *mb = 0; + + if (msg_queue()->is_empty()) + { + reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK); + return 0; + } + + if (msg_queue()->dequeue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + return -1; + + ssize_t n = noblk_send(*mb); + + if (n < 0) + { + mb->release(); + return -1; + } + else if (n == mb->length()) + { + mb->release(); + return 1; + } + else + { + mb->rd_ptr(n); + + if (msg_queue()->enqueue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + { + mb->release(); + return -1; + } + + return 0; + } + + ACE_NOTREACHED(return -1); +} + +int RealmSocket::handle_close(ACE_HANDLE h, ACE_Reactor_Mask /*m*/) +{ + // As opposed to WorldSocket::handle_close, we don't need locks here. + + closing_ = true; + + if (h == ACE_INVALID_HANDLE) + peer ().close_writer (); + + if (session_ != NULL) + { + session_->OnClose(); + } + + return 0; +} + +int RealmSocket::handle_input(ACE_HANDLE /*= ACE_INVALID_HANDLE*/) +{ + if (closing_) + return -1; + + const ssize_t space = input_buffer_.space(); + + ssize_t n = peer().recv(input_buffer_.wr_ptr(), space); + + if (n < 0) + { + return errno == EWOULDBLOCK ? 0 : -1; + } + else if (n == 0) + { + // EOF + return -1; + } + + input_buffer_.wr_ptr((size_t)n); + + if (session_ != NULL) + { + session_->OnRead(); + + input_buffer_.crunch(); + } + + // return 1 in case there is more data to read from OS + return n == space ? 1 : 0; +} + + +void RealmSocket::set_session(Session* session) +{ + if (session_ != NULL) + delete session_; + + session_ = session; +} + diff --git a/src/server/authserver/RealmSocket.h b/src/server/authserver/RealmSocket.h new file mode 100644 index 00000000000..13be8327533 --- /dev/null +++ b/src/server/authserver/RealmSocket.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup realmd + */ + +#ifndef __REALMSOCKET_H__ +#define __REALMSOCKET_H__ + +#include +#include +#include +#include +#include +#include + +class RealmSocket : public ACE_Svc_Handler +{ + private: + typedef ACE_Svc_Handler Base; + + public: + class Session + { + public: + Session(void); + virtual ~Session(void); + + virtual void OnRead(void) = 0; + virtual void OnAccept(void) = 0; + virtual void OnClose(void) = 0; + }; + + RealmSocket(void); + virtual ~RealmSocket(void); + + size_t recv_len(void) const; + bool recv_soft(char *buf, size_t len); + bool recv(char *buf, size_t len); + void recv_skip(size_t len); + + bool send(const char *buf, size_t len); + + const ACE_CString& get_remote_address(void) const; + + virtual int open(void *); + + virtual int close(int); + + virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE); + virtual int handle_output(ACE_HANDLE = ACE_INVALID_HANDLE); + + virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + void set_session(Session* session); + + private: + ssize_t noblk_send(ACE_Message_Block &message_block); + + private: + ACE_Message_Block input_buffer_; + Session* session_; + ACE_CString remote_address_; +}; + +#endif /* __REALMSOCKET_H__ */ diff --git a/src/server/authserver/TrinityRealm.ico b/src/server/authserver/TrinityRealm.ico new file mode 100644 index 00000000000..da318f48a8c Binary files /dev/null and b/src/server/authserver/TrinityRealm.ico differ diff --git a/src/server/authserver/TrinityRealm.rc b/src/server/authserver/TrinityRealm.rc new file mode 100644 index 00000000000..dfc548305fd --- /dev/null +++ b/src/server/authserver/TrinityRealm.rc @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * 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 "resource.h" +#include "../shared/revision.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" //"afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APPICON ICON "TrinityRealm.ico" + +///////////////////////////////////////////////////////////////////////////// +// Neutre (Par défaut système) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILEVER + PRODUCTVERSION PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x0L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080004b0" + BEGIN + VALUE "FileDescription", "TrinityRealm" + VALUE "FileVersion", STRFILEVER + VALUE "InternalName", "TrinityRealm" + VALUE "LegalCopyright", "Copyright (C) 2008-2009" + VALUE "OriginalFilename", "TrinityRealm.exe" + VALUE "ProductName", "TrinityRealm" + VALUE "ProductVersion", STRPRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x800, 1200 + END +END +#endif diff --git a/src/server/authserver/resource.h b/src/server/authserver/resource.h new file mode 100644 index 00000000000..7dc5cb9ef7b --- /dev/null +++ b/src/server/authserver/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by TrinityCore.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/server/authserver/trinityrealm.conf.dist b/src/server/authserver/trinityrealm.conf.dist new file mode 100644 index 00000000000..e98b9386878 --- /dev/null +++ b/src/server/authserver/trinityrealm.conf.dist @@ -0,0 +1,146 @@ +########################################## +# Trinity Core realmd configuration file # +########################################## +# Note to devs, line breaks should be at column 80 +############################################################################### +# REALMD SETTINGS +# +# LoginDatabaseInfo +# Database connection settings for the realm server. +# Default: +# hostname;port;username;password;database +# .;somenumber;username;password;database +# - use named pipes in Windows +# Named pipes: mySQL required adding +# "enable-named-pipe" to [mysqld] section my.ini +# .;/path/to/unix_socket;username;password;database +# - use Unix sockets in Unix/Linux +# +# LogsDir +# Logs directory setting. +# Important: Logs dir must exists, or all logs need to be disabled +# Default: "" - no log directory prefix, if used log names isn't +# absolute path then logs will be stored in current directory. +# +# MaxPingTime +# Settings for maximum database-ping interval (minutes between pings) +# +# RealmServerPort +# Default RealmServerPort +# +# BindIP +# Bind Realm Server to IP/hostname +# +# PidFile +# Realmd daemon PID file +# Default: "" - do not create PID file +# "./realmd.pid" - create PID file (recommended name) +# +# LogLevel +# Server console level of logging +# Default: 0 = Minimum +# 1 = Basic +# 2 = Detail +# 3 = Full/Debug +# +# LogFile +# Logfile name +# Default: "realmd.log" +# "" - Empty name disable creating log file +# +# LogTimestamp +# Logfile with timestamp of server start in name +# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# Default: 0 - no timestamp in name +# 1 - add timestamp in name +# +# LogFileLevel +# Server file level of logging +# Default: 0 = Minimum +# 1 = Basic +# 2 = Detail +# 3 = Full/Debug +# +# LogColors +# Color for messages (format "normal basic detail debug") +# Default: "" - no colors +# Colors: 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "13 11 9 5" +# +# EnableLogDB +# Enable/disable logging to database (LogDatabaseInfo). +# Default: 0 - disabled +# 1 - enabled +# +# DBLogLevel +# Log level of DB logging. +# 0 = Minimum +# Default: 1 = Basic +# 2 = Detail +# 3 = Full/Debug +# +# UseProcessors +# Processors mask for multi-processor system (Used only in Windows) +# Default: 0 (selected by OS) +# number (bitmask value of selected processors) +# +# ProcessPriority +# Process proirity setting (Used only at Windows) +# Default: 1 (HIGH) +# 0 (Normal) +# +# RealmsStateUpdateDelay +# Realm list Update up delay +# (updated at realm list request if delay expired). +# Default: 20 +# 0 (Disabled) +# +# WrongPass.MaxCount +# Number of login attemps with wrong password +# before the account or IP is banned +# Default: 0 (Never ban) +# +# WrongPass.BanTime +# Duration of the ban in seconds (0 means permanent ban) +# Default: 600 +# +# WrongPass.BanType +# Ban the IP or account on which login is attempted +# Default: 0 (Ban IP) +# 1 (Ban Account) +# +############################################################################### + +LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;realmd" +LogsDir = "" +MaxPingTime = 30 +RealmServerPort = 3724 +BindIP = "0.0.0.0" +PidFile = "" +LogLevel = 0 +LogFile = "realmd.log" +LogTimestamp = 0 +LogFileLevel = 0 +LogColors = "" +EnableLogDB = 0 +DBLogLevel = 1 +UseProcessors = 0 +ProcessPriority = 1 +RealmsStateUpdateDelay = 20 +WrongPass.MaxCount = 0 +WrongPass.BanTime = 600 +WrongPass.BanType = 0 diff --git a/src/server/trinitycore/CMakeLists.txt b/src/server/trinitycore/CMakeLists.txt deleted file mode 100644 index 0efdc63c09e..00000000000 --- a/src/server/trinitycore/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ - -########### next target ############### - -SET(trinity-core_SRCS -CliRunnable.cpp -CliRunnable.h -Main.cpp -Master.cpp -Master.h -RASocket.cpp -RASocket.h -WorldRunnable.cpp -WorldRunnable.h -) - -include_directories( - ${ACE_INCLUDE_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/dep/include - ${CMAKE_SOURCE_DIR}/src/shared - ${CMAKE_SOURCE_DIR}/src/shared/Database - ${CMAKE_SOURCE_DIR}/src/framework - ${CMAKE_SOURCE_DIR}/src/game - ${MYSQL_INCLUDE_DIR} -) - -SET(trinity-core_LINK_FLAGS "") - -add_executable(trinity-core ${trinity-core_SRCS}) -add_definitions( --D_TRINITY_CORE_CONFIG='"${CONF_DIR}/trinitycore.conf"' -) -IF (DO_MYSQL) - SET(trinity-core_LINK_FLAGS "-pthread ${trinity-core_LINK_FLAGS}") -ENDIF(DO_MYSQL) - -IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") - SET(trinity-core_LINK_FLAGS "-framework Carbon ${trinity-core_LINK_FLAGS}") - SET(SCRIPT_LIB "") -ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin") - -SET_TARGET_PROPERTIES(trinity-core PROPERTIES LINK_FLAGS "${trinity-core_LINK_FLAGS}") - -if(DO_SCRIPTS) - SET(SCRIPT_LIB "scripts") -else(DO_SCRIPTS) - SET(SCRIPT_LIB "") -endif(DO_SCRIPTS) - -target_link_libraries( -trinity-core -game -shared -zlib -trinityframework -trinitysockets -trinitydatabase -trinityauth -trinityconfig -vmaps -g3dlite -jmalloc -${SCRIPT_LIB} -${READLINE_LIBRARY} -${TERMCAP_LIBRARY} -${MYSQL_LIBRARIES} -${SSLLIB} -${ACE_LIBRARY} -${ZLIB} -${OSX_LIBS} -) - -install(TARGETS trinity-core DESTINATION bin) - - -########### install files ############### - -install(FILES trinitycore.conf.dist DESTINATION etc) - diff --git a/src/server/trinitycore/CliRunnable.cpp b/src/server/trinitycore/CliRunnable.cpp deleted file mode 100644 index b39faf694db..00000000000 --- a/src/server/trinitycore/CliRunnable.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#include "Common.h" -#include "ObjectMgr.h" -#include "World.h" -#include "WorldSession.h" -#include "Config/ConfigEnv.h" - -#include "AccountMgr.h" -#include "Chat.h" -#include "CliRunnable.h" -#include "Language.h" -#include "Log.h" -#include "MapManager.h" -#include "Player.h" -#include "Util.h" - -#if PLATFORM != WINDOWS -#include -#include - -char * command_finder(const char* text, int state) -{ - static int idx,len; - const char* ret; - ChatCommand *cmd = ChatHandler::getCommandTable(); - - if(!state) - { - idx = 0; - len = strlen(text); - } - - while(ret = cmd[idx].Name) - { - if(!cmd[idx].AllowConsole) - { - idx++; - continue; - } - - idx++; - //printf("Checking %s \n", cmd[idx].Name); - if (strncmp(ret, text, len) == 0) - return strdup(ret); - if(cmd[idx].Name == NULL) - break; - } - - return ((char*)NULL); -} - -char ** cli_completion(const char * text, int start, int end) -{ - char ** matches; - matches = (char**)NULL; - - if(start == 0) - matches = rl_completion_matches((char*)text,&command_finder); - else - rl_bind_key('\t',rl_abort); - return (matches); -} -#endif - -void utf8print(const char* str) -{ -#if PLATFORM == PLATFORM_WINDOWS - wchar_t wtemp_buf[6000]; - size_t wtemp_len = 6000-1; - if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len)) - return; - - char temp_buf[6000]; - CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1); - printf(temp_buf); -#else -{ - va_list v; - vprintf(str, v); - va_end(v); - fflush(stdout); -} -#endif -} - -/// 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) -{ - if(!*args) - return false; - - ///- Get the account name from the command line - char *account_name_str=strtok ((char*)args," "); - if (!account_name_str) - return false; - - std::string account_name = account_name_str; - if(!AccountMgr::normalizeString(account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - uint32 account_id = accmgr.GetId(account_name); - if(!account_id) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - /// Commands not recommended call from chat, but support anyway - /// can delete only for account with less security - /// This is also reject self apply in fact - if(HasLowerSecurityAccount (NULL,account_id,true)) - return false; - - AccountOpResult result = accmgr.DeleteAccount(account_id); - switch(result) - { - case AOR_OK: - PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); - break; - case AOR_NAME_NOT_EXIST: - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - case AOR_DB_INTERNAL_ERROR: - PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); - SetSentErrorMessage(true); - return false; - default: - PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleCharacterDeleteCommand(const char* args) -{ - if(!*args) - return false; - - char *character_name_str = strtok((char*)args," "); - if(!character_name_str) - return false; - - std::string character_name = character_name_str; - if(!normalizePlayerName(character_name)) - return false; - - uint64 character_guid; - uint32 account_id; - - Player *player = objmgr.GetPlayer(character_name.c_str()); - if(player) - { - character_guid = player->GetGUID(); - account_id = player->GetSession()->GetAccountId(); - player->GetSession()->KickPlayer(); - } - else - { - character_guid = objmgr.GetPlayerGUIDByName(character_name); - if(!character_guid) - { - PSendSysMessage(LANG_NO_PLAYER,character_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); - } - - std::string account_name; - accmgr.GetName (account_id,account_name); - - Player::DeleteFromDB(character_guid, account_id, true); - PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id); - return true; -} - -/// Exit the realm -bool ChatHandler::HandleServerExitCommand(const char* /*args*/) -{ - SendSysMessage(LANG_COMMAND_EXIT); - World::StopNow(SHUTDOWN_EXIT_CODE); - return true; -} - -/// Display info on users currently in the realm -bool ChatHandler::HandleAccountOnlineListCommand(const char* /*args*/) -{ - ///- Get the list of accounts ID logged to the realm - QueryResult_AutoPtr resultDB = CharacterDatabase.Query("SELECT name,account,map,zone FROM characters WHERE online > 0"); - if (!resultDB) - { - SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); - return true; - } - - ///- Display the list of account/characters online - SendSysMessage(LANG_ACCOUNT_LIST_BAR_HEADER); - SendSysMessage(LANG_ACCOUNT_LIST_HEADER); - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - - ///- Circle through accounts - do - { - Field *fieldsDB = resultDB->Fetch(); - std::string name = fieldsDB[0].GetCppString(); - uint32 account = fieldsDB[1].GetUInt32(); - - ///- Get the username, last IP and GM level of each account - // No SQL injection. account is uint32. - QueryResult_AutoPtr resultLogin = - LoginDatabase.PQuery("SELECT a.username, a.last_ip, aa.gmlevel, a.expansion " - "FROM account a " - "LEFT JOIN account_access aa " - "ON (a.id = aa.id) " - "WHERE a.id = '%u'", account); - if(resultLogin) - { - Field *fieldsLogin = resultLogin->Fetch(); - PSendSysMessage(LANG_ACCOUNT_LIST_LINE, - fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsDB[2].GetInt32(),fieldsDB[3].GetInt32(),fieldsLogin[3].GetUInt32(),fieldsLogin[2].GetUInt32()); - } - else - PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); - - }while(resultDB->NextRow()); - - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - return true; -} - -/// Create an account -bool ChatHandler::HandleAccountCreateCommand(const char* args) -{ - if(!*args) - return false; - - ///- %Parse the command line arguments - char *szAcc = strtok((char*)args, " "); - char *szPassword = strtok(NULL, " "); - if(!szAcc || !szPassword) - return false; - - // normalized in accmgr.CreateAccount - std::string account_name = szAcc; - std::string password = szPassword; - - AccountOpResult result = accmgr.CreateAccount(account_name, password); - switch(result) - { - case AOR_OK: - PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); - break; - case AOR_NAME_TOO_LONG: - SendSysMessage(LANG_ACCOUNT_TOO_LONG); - SetSentErrorMessage(true); - return false; - case AOR_NAME_ALREDY_EXIST: - SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); - SetSentErrorMessage(true); - return false; - case AOR_DB_INTERNAL_ERROR: - PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); - SetSentErrorMessage(true); - return false; - default: - PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -/// Set the level of logging -bool ChatHandler::HandleServerSetLogFileLevelCommand(const char *args) -{ - if(!*args) - return false; - - char *NewLevel = strtok((char*)args, " "); - if (!NewLevel) - return false; - - sLog.SetLogFileLevel(NewLevel); - return true; -} - -/// Set the level of logging -bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) -{ - if(!*args) - return false; - - char *NewLevel = strtok((char*)args, " "); - if (!NewLevel) - return false; - - sLog.SetLogLevel(NewLevel); - return true; -} - -/// set diff time record interval -bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args) -{ - if(!*args) - return false; - - char *NewTimeStr = strtok((char*)args, " "); - if(!NewTimeStr) - return false; - - int32 NewTime =atoi(NewTimeStr); - if(NewTime < 0) - return false; - - sWorld.SetRecordDiffInterval(NewTime); - printf( "Record diff every %u ms\n", NewTime); - return true; -} - -/// @} - -#ifdef linux -// Non-blocking keypress detector, when return pressed, return 1, else always return 0 -int kb_hit_return() -{ - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); -} -#endif - -/// %Thread start -void CliRunnable::run() -{ - ///- Init new SQL thread for the world database (one connection call enough) - WorldDatabase.ThreadStart(); // let thread do safe mySQL requests - - char commandbuf[256]; - - ///- Display the list of available CLI functions then beep - sLog.outString(""); - #if PLATFORM != WINDOWS - rl_attempted_completion_function = cli_completion; - #endif - if(sConfig.GetBoolDefault("BeepAtStart", true)) - printf("\a"); // \a = Alert - - // print this here the first time - // later it will be printed after command queue updates - printf("TC>"); - - ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it - while (!World::IsStopped()) - { - fflush(stdout); - - char *command_str ; // = fgets(commandbuf,sizeof(commandbuf),stdin); - - #if PLATFORM == WINDOWS - command_str = fgets(commandbuf,sizeof(commandbuf),stdin); - #else - command_str = readline("TC>"); - rl_bind_key('\t',rl_complete); - #endif - if (command_str != NULL) - { - for (int x=0; command_str[x]; x++) - if(command_str[x]=='\r'||command_str[x]=='\n') - { - command_str[x]=0; - break; - } - - if(!*command_str) - { - #if PLATFORM == WINDOWS - printf("TC>"); - #endif - continue; - } - - std::string command; - if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 - { - #if PLATFORM == WINDOWS - printf("TC>"); - #endif - continue; - } - fflush(stdout); - sWorld.QueueCliCommand(&utf8print,command.c_str()); - #if PLATFORM != WINDOWS - add_history(command.c_str()); - #endif - - } - else if (feof(stdin)) - { - World::StopNow(SHUTDOWN_EXIT_CODE); - } - - } - - ///- End the database thread - WorldDatabase.ThreadEnd(); // free mySQL thread resources -} diff --git a/src/server/trinitycore/CliRunnable.h b/src/server/trinitycore/CliRunnable.h deleted file mode 100644 index 9f990b2b469..00000000000 --- a/src/server/trinitycore/CliRunnable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef __CLIRUNNABLE_H -#define __CLIRUNNABLE_H - -/// Command Line Interface handling thread -class CliRunnable : public ACE_Based::Runnable -{ - public: - void run(); -}; -#endif -/// @} diff --git a/src/server/trinitycore/Main.cpp b/src/server/trinitycore/Main.cpp deleted file mode 100644 index 95bb39eca91..00000000000 --- a/src/server/trinitycore/Main.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup Trinityd Trinity Daemon -/// @{ -/// \file - -#include -#include -#include - -#include "Common.h" -#include "Database/DatabaseEnv.h" -#include "Config/ConfigEnv.h" - -#include "Log.h" -#include "Master.h" - -#ifndef _TRINITY_CORE_CONFIG -# define _TRINITY_CORE_CONFIG "TrinityCore.conf" -#endif //_TRINITY_CORE_CONFIG - -#ifdef WIN32 -#include "ServiceWin32.h" -char serviceName[] = "TrinityCore"; -char serviceLongName[] = "Trinity core service"; -char serviceDescription[] = "Massive Network Game Object Server"; -/* - * -1 - not in service mode - * 0 - stopped - * 1 - running - * 2 - paused - */ -int m_ServiceStatus = -1; -#endif - -DatabaseType WorldDatabase; ///< Accessor to the world database -DatabaseType CharacterDatabase; ///< Accessor to the character database -DatabaseType LoginDatabase; ///< Accessor to the realm/login database - -uint32 realmID; ///< Id of the realm - -/// Print out the usage string for this program on the console. -void usage(const char *prog) -{ - sLog.outString("Usage: \n %s []\n" - " -c config_file use config_file as configuration file\n\r" - #ifdef WIN32 - " Running as service functions:\n\r" - " --service run as service\n\r" - " -s install install service\n\r" - " -s uninstall uninstall service\n\r" - #endif - ,prog); -} - -/// Launch the Trinity server -extern int main(int argc, char **argv) -{ - ///- Command line parsing to get the configuration file name - char const* cfg_file = _TRINITY_CORE_CONFIG; - int c=1; - while( c < argc ) - { - if( strcmp(argv[c],"-c") == 0) - { - if( ++c >= argc ) - { - sLog.outError("Runtime-Error: -c option requires an input argument"); - usage(argv[0]); - return 1; - } - else - cfg_file = argv[c]; - } - - #ifdef WIN32 - //////////// - //Services// - //////////// - if( strcmp(argv[c],"-s") == 0) - { - if( ++c >= argc ) - { - sLog.outError("Runtime-Error: -s option requires an input argument"); - usage(argv[0]); - return 1; - } - if( strcmp(argv[c],"install") == 0) - { - if (WinServiceInstall()) - sLog.outString("Installing service"); - return 1; - } - else if( strcmp(argv[c],"uninstall") == 0) - { - if(WinServiceUninstall()) - sLog.outString("Uninstalling service"); - return 1; - } - else - { - sLog.outError("Runtime-Error: unsupported option %s",argv[c]); - usage(argv[0]); - return 1; - } - } - if( strcmp(argv[c],"--service") == 0) - { - WinServiceRun(); - } - //// - #endif - ++c; - } - - if (!sConfig.SetSource(cfg_file)) - { - sLog.outError("Could not find configuration file %s.", cfg_file); - return 1; - } - sLog.outString("Using configuration file %s.", cfg_file); - - sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); - sLog.outDetail("Using ACE: %s", ACE_VERSION); - - ///- and run the 'Master' - /// \todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd? - return sMaster.Run(); - - // at sMaster return function exist with codes - // 0 - normal shutdown - // 1 - shutdown at error - // 2 - restart command used, this code can be used by restarter for restart Trinityd -} - -/// @} diff --git a/src/server/trinitycore/Master.cpp b/src/server/trinitycore/Master.cpp deleted file mode 100644 index 8b34b512f57..00000000000 --- a/src/server/trinitycore/Master.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup Trinityd -*/ - -#include - -#include "Common.h" -#include "SystemConfig.h" -#include "SignalHandler.h" -#include "World.h" -#include "WorldRunnable.h" -#include "WorldSocket.h" -#include "WorldSocketMgr.h" -#include "Config/ConfigEnv.h" -#include "Database/DatabaseEnv.h" -#include "Policies/SingletonImp.h" - -#include "CliRunnable.h" -#include "Log.h" -#include "Master.h" -#include "RASocket.h" -#include "Timer.h" -#include "Util.h" - -#include "sockets/TcpSocket.h" -#include "sockets/Utility.h" -#include "sockets/Parse.h" -#include "sockets/Socket.h" -#include "sockets/SocketHandler.h" -#include "sockets/ListenSocket.h" -#include "Auth/BigNumber.h" - -#ifdef WIN32 -#include "ServiceWin32.h" -extern int m_ServiceStatus; -#endif - -/// \todo Warning disabling not useful under VC++2005. Can somebody say on which compiler it is useful? -#pragma warning(disable:4305) - -INSTANTIATE_SINGLETON_1( Master ); - -volatile uint32 Master::m_masterLoopCounter = 0; - -/// Handle cored's termination signals -class CoredSignalHandler : public Trinity::SignalHandler -{ - public: - virtual void HandleSignal(int SigNum) - { - switch (SigNum) - { - case SIGINT: - World::StopNow(RESTART_EXIT_CODE); - break; - case SIGTERM: - #ifdef _WIN32 - case SIGBREAK: - if (m_ServiceStatus != 1) - #endif /* _WIN32 */ - World::StopNow(SHUTDOWN_EXIT_CODE); - break; - } - } -}; - -class FreezeDetectorRunnable : public ACE_Based::Runnable -{ -public: - FreezeDetectorRunnable() { _delaytime = 0; } - uint32 m_loops, m_lastchange; - uint32 w_loops, w_lastchange; - uint32 _delaytime; - void SetDelayTime(uint32 t) { _delaytime = t; } - void run(void) - { - if(!_delaytime) - return; - sLog.outString("Starting up anti-freeze thread (%u seconds max stuck time)...",_delaytime/1000); - m_loops = 0; - w_loops = 0; - m_lastchange = 0; - w_lastchange = 0; - while(!World::IsStopped()) - { - ACE_Based::Thread::Sleep(1000); - uint32 curtime = getMSTime(); - //DEBUG_LOG("anti-freeze: time=%u, counters=[%u; %u]",curtime,Master::m_masterLoopCounter,World::m_worldLoopCounter); - - // There is no Master anymore - // TODO: clear the rest of the code -// // normal work -// if(m_loops != Master::m_masterLoopCounter) -// { -// m_lastchange = curtime; -// m_loops = Master::m_masterLoopCounter; -// } -// // possible freeze -// else if(getMSTimeDiff(m_lastchange,curtime) > _delaytime) -// { -// sLog.outError("Main/Sockets Thread hangs, kicking out server!"); -// *((uint32 volatile*)NULL) = 0; // bang crash -// } - - // normal work - if(w_loops != World::m_worldLoopCounter) - { - w_lastchange = curtime; - w_loops = World::m_worldLoopCounter; - } - // possible freeze - else if(getMSTimeDiff(w_lastchange,curtime) > _delaytime) - { - sLog.outError("World Thread hangs, kicking out server!"); - *((uint32 volatile*)NULL) = 0; // bang crash - } - } - sLog.outString("Anti-freeze thread exiting without problems."); - } -}; - -class RARunnable : public ACE_Based::Runnable -{ -public: - uint32 numLoops, loopCounter; - - RARunnable () - { - uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); - numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime)); - loopCounter = 0; - } - - void checkping () - { - // ping if need - if ((++loopCounter) == numLoops) - { - loopCounter = 0; - sLog.outDetail ("Ping MySQL to keep connection alive"); - WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1"); - LoginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1"); - CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1"); - } - } - - void run () - { - SocketHandler h; - - // Launch the RA listener socket - ListenSocket RAListenSocket (h); - bool usera = sConfig.GetBoolDefault ("Ra.Enable", false); - - if (usera) - { - port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443); - std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0"); - ipaddr_t raip; - if (!Utility::u2ip (stringip, raip)) - sLog.outError ("Trinity RA can not bind to ip %s", stringip.c_str ()); - else if (RAListenSocket.Bind (raip, raport)) - sLog.outError ("Trinity RA can not bind to port %d on %s", raport, stringip.c_str ()); - else - { - h.Add (&RAListenSocket); - - sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ()); - } - } - - // Socket Selet time is in microseconds , not miliseconds!! - uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); - - // if use ra spend time waiting for io, if not use ra ,just sleep - if (usera) - { - while (!World::IsStopped()) - { - h.Select (0, socketSelecttime); - checkping (); - } - } - else - { - while (!World::IsStopped()) - { - ACE_Based::Thread::Sleep(static_cast (socketSelecttime / 1000)); - checkping (); - } - } - } -}; - -Master::Master() -{ -} - -Master::~Master() -{ -} - -/// Main function -int Master::Run() -{ - BigNumber seed1; - seed1.SetRand(16 * 8); - - sLog.outString( "%s (core-daemon)", _FULLVERSION ); - sLog.outString( " to stop.\n" ); - - sLog.outString( " ______ __"); - sLog.outString( "/\\__ _\\ __ __/\\ \\__"); - sLog.outString( "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\ ,_\\ __ __"); - sLog.outString( " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\"); - sLog.outString( " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\"); - sLog.outString( " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\"); - sLog.outString( " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\"); - sLog.outString( " C O R E /\\___/"); - sLog.outString( "http://TrinityCore.org \\/__/\n"); - - /// worldd PID file creation - std::string pidfile = sConfig.GetStringDefault("PidFile", ""); - if(!pidfile.empty()) - { - uint32 pid = CreatePIDFile(pidfile); - if( !pid ) - { - sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); - return 1; - } - - sLog.outString( "Daemon PID: %u\n", pid ); - } - - ///- Start the databases - if (!_StartDB()) - return 1; - - ///- Initialize the World - sWorld.SetInitialWorldSettings(); - - - // Initialise the signal handlers - CoredSignalHandler SignalINT, SignalTERM; - #ifdef _WIN32 - CoredSignalHandler SignalBREAK; - #endif /* _WIN32 */ - - // Register realmd's signal handlers - ACE_Sig_Handler Handler; - Handler.register_handler(SIGINT, &SignalINT); - Handler.register_handler(SIGTERM, &SignalTERM); - #ifdef _WIN32 - Handler.register_handler(SIGBREAK, &SignalBREAK); - #endif /* _WIN32 */ - - - ///- Launch WorldRunnable thread - ACE_Based::Thread world_thread(new WorldRunnable); - world_thread.setPriority(ACE_Based::Highest); - - // set server online - LoginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID); - - ACE_Based::Thread* cliThread = NULL; - -#ifdef WIN32 - if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) -#else - if (sConfig.GetBoolDefault("Console.Enable", true)) -#endif - { - ///- Launch CliRunnable thread - cliThread = new ACE_Based::Thread(new CliRunnable); - } - - ACE_Based::Thread rar_thread(new RARunnable); - - ///- Handle affinity for multiple processors and process priority on Windows - #ifdef WIN32 - { - HANDLE hProcess = GetCurrentProcess(); - - uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); - if(Aff > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) - { - ULONG_PTR curAff = Aff & appAff; // remove non accessible processors - - if(!curAff ) - { - sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for Trinityd. Accessible processors bitmask (hex): %x",Aff,appAff); - } - else - { - if(SetProcessAffinityMask(hProcess,curAff)) - sLog.outString("Using processors (bitmask, hex): %x", curAff); - else - sLog.outError("Can't set used processors (hex): %x",curAff); - } - } - sLog.outString(""); - } - - bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); - -// if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/) - if(Prio) - { - if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) - sLog.outString("TrinityCore process priority class set to HIGH"); - else - sLog.outError("ERROR: Can't set Trinityd process priority class."); - sLog.outString(""); - } - } - #endif - - uint32 realCurrTime, realPrevTime; - realCurrTime = realPrevTime = getMSTime(); - - ///- Start up freeze catcher thread - if(uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0)) - { - FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable(); - fdr->SetDelayTime(freeze_delay*1000); - ACE_Based::Thread freeze_thread(fdr); - freeze_thread.setPriority(ACE_Based::Highest); - } - - ///- Launch the world listener socket - port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD); - std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0"); - - if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1) - { - sLog.outError ("Failed to start network"); - World::StopNow(ERROR_EXIT_CODE); - // go down and shutdown the server - } - - sWorldSocketMgr->Wait (); - - // set server offline - LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID); - - // when the main thread closes the singletons get unloaded - // since worldrunnable uses them, it will crash if unloaded after master - world_thread.wait(); - rar_thread.wait (); - - ///- Clean database before leaving - clearOnlineAccounts(); - - ///- Wait for delay threads to end - CharacterDatabase.HaltDelayThread(); - WorldDatabase.HaltDelayThread(); - LoginDatabase.HaltDelayThread(); - - sLog.outString( "Halting process..." ); - - if (cliThread) - { - #ifdef WIN32 - - // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) - //_exit(1); - // send keyboard input to safely unblock the CLI thread - INPUT_RECORD b[5]; - HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); - b[0].EventType = KEY_EVENT; - b[0].Event.KeyEvent.bKeyDown = TRUE; - b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; - b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; - b[0].Event.KeyEvent.wRepeatCount = 1; - - b[1].EventType = KEY_EVENT; - b[1].Event.KeyEvent.bKeyDown = FALSE; - b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; - b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; - b[1].Event.KeyEvent.wRepeatCount = 1; - - b[2].EventType = KEY_EVENT; - b[2].Event.KeyEvent.bKeyDown = TRUE; - b[2].Event.KeyEvent.dwControlKeyState = 0; - b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; - b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - b[2].Event.KeyEvent.wRepeatCount = 1; - b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; - - b[3].EventType = KEY_EVENT; - b[3].Event.KeyEvent.bKeyDown = FALSE; - b[3].Event.KeyEvent.dwControlKeyState = 0; - b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; - b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; - b[3].Event.KeyEvent.wRepeatCount = 1; - DWORD numb; - WriteConsoleInput(hStdIn, b, 4, &numb); - - cliThread->wait(); - - #else - - cliThread->destroy(); - - #endif - - delete cliThread; - } - - // for some unknown reason, unloading scripts here and not in worldrunnable - // fixes a memory leak related to detaching threads from the module - //UnloadScriptingModule(); - - // Exit the process with specified return value - return World::GetExitCode(); -} - -/// Initialize connection to the databases -bool Master::_StartDB() -{ - sLog.SetLogDB(false); - std::string dbstring; - - ///- Get world database info from configuration file - dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", ""); - if(dbstring.empty()) - { - sLog.outError("Database not specified in configuration file"); - return false; - } - - ///- Initialise the world database - if(!WorldDatabase.Initialize(dbstring.c_str())) - { - sLog.outError("Cannot connect to world database %s",dbstring.c_str()); - return false; - } - - ///- Get character database info from configuration file - dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", ""); - if(dbstring.empty()) - { - sLog.outError("Character Database not specified in configuration file"); - return false; - } - - ///- Initialise the Character database - if(!CharacterDatabase.Initialize(dbstring.c_str())) - { - sLog.outError("Cannot connect to Character database %s",dbstring.c_str()); - return false; - } - - ///- Get login database info from configuration file - dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); - if(dbstring.empty()) - { - sLog.outError("Login database not specified in configuration file"); - return false; - } - - ///- Initialise the login database - if(!LoginDatabase.Initialize(dbstring.c_str())) - { - sLog.outError("Cannot connect to login database %s",dbstring.c_str()); - return false; - } - - ///- Get the realm Id from the configuration file - realmID = sConfig.GetIntDefault("RealmID", 0); - if(!realmID) - { - sLog.outError("Realm ID not defined in configuration file"); - return false; - } - sLog.outString("Realm running as realm ID %d", realmID); - - ///- Initialize the DB logging system - sLog.SetLogDBLater(sConfig.GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished. - sLog.SetLogDB(false); - sLog.SetRealmID(realmID); - - ///- Clean the database before starting - clearOnlineAccounts(); - - ///- Insert version info into DB - WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _REVISION); - - sWorld.LoadDBVersion(); - - sLog.outString("Using World DB: %s", sWorld.GetDBVersion()); - sLog.outString("Using creature EventAI: %s", sWorld.GetCreatureEventAIVersion()); - return true; -} - -/// Clear 'online' status for all accounts with characters in this realm -void Master::clearOnlineAccounts() -{ - // Cleanup online status for characters hosted at current realm - /// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'? - LoginDatabase.PExecute( - "UPDATE account SET online = 0 WHERE online > 0 " - "AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID); - - CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0"); - - // Battleground instance ids reset at server restart - CharacterDatabase.Execute("UPDATE character_battleground_data SET instance_id = 0"); -} diff --git a/src/server/trinitycore/Master.h b/src/server/trinitycore/Master.h deleted file mode 100644 index 76ff2af1457..00000000000 --- a/src/server/trinitycore/Master.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef _MASTER_H -#define _MASTER_H - -#include "Common.h" -#include "Policies/Singleton.h" - -/// Start the server -class Master -{ - public: - Master(); - ~Master(); - int Run(); - static volatile uint32 m_masterLoopCounter; - - private: - bool _StartDB(); - - void clearOnlineAccounts(); -}; - -#define sMaster Trinity::Singleton::Instance() -#endif -/// @} diff --git a/src/server/trinitycore/RASocket.cpp b/src/server/trinitycore/RASocket.cpp deleted file mode 100644 index 32c16d9980f..00000000000 --- a/src/server/trinitycore/RASocket.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup Trinityd -*/ - -#include "Common.h" -#include "Config/ConfigEnv.h" -#include "Database/DatabaseEnv.h" -#include "AccountMgr.h" -#include "Log.h" -#include "RASocket.h" -#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 -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()); -} - -/// Read data from the network -void RASocket::OnRead() -{ - ///- Read data and check input length - TcpSocket::OnRead(); - - unsigned int sz=ibuf.GetLength(); - if(iInputLength+sz>=RA_BUFF_SIZE) - { - sLog.outRemote("Input buffer overflow, possible DOS attack.\n"); - SetCloseAndDelete(); - 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]; - ibuf.Read(inp,sz); - - /// \todo Can somebody explain this 'Linux bugfix'? - if(stage==NONE) - if(sz>4) //linux remote telnet - if(memcmp(inp ,"USER ",5)) - { - delete [] inp;return; - printf("lin bugfix"); - } //linux bugfix - - ///- Discard data after line break or line feed - bool gotenter=false; - unsigned int y=0; - for (; y
  • If the input is 'USER ' - case NONE: - if(!memcmp(buff,"USER ",5)) //got "USER" cmd - { - szLogin=&buff[5]; - - ///- Get the password from the account table - std::string login = szLogin; - - ///- Convert Account name to Upper Format - AccountMgr::normalizeString(login); - - ///- Escape the Login to allow quotes in names - LoginDatabase.escape_string(login); - - QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = '%s'",login.c_str ()); - - ///- If the user is not found, deny access - if(!result) - { - Sendf("-No such user.\r\n"); - sLog.outRemote("User %s does not exist.\n",szLogin.c_str()); - if(bSecure)SetCloseAndDelete(); - } - else - { - Field *fields = result->Fetch(); - - //szPass=fields[0].GetString(); - - ///- if gmlevel is too low, deny access - if(fields[1].GetUInt32() If the input is 'PASS ' (and the user already gave his username) - case LG: - if(!memcmp(buff,"PASS ",5)) //got "PASS" cmd - { //login+pass ok - ///- If password is correct, increment the number of active administrators - std::string login = szLogin; - std::string pw = &buff[5]; - - AccountMgr::normalizeString(login); - AccountMgr::normalizeString(pw); - LoginDatabase.escape_string(login); - LoginDatabase.escape_string(pw); - - QueryResult_AutoPtr check = LoginDatabase.PQuery( - "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT('%s',':','%s'))", - login.c_str(), login.c_str(), pw.c_str()); - - if(check) - { - r=GetSocket(); - stage=OK; - ++iUsers; - - Sendf("+Logged in.\r\n"); - sLog.outRemote("User %s has logged in.\n",szLogin.c_str()); - Sendf("TC>"); - } - else - { - ///- Else deny access - Sendf("-Wrong pass.\r\n"); - sLog.outRemote("User %s has failed to log in.\n",szLogin.c_str()); - if(bSecure)SetCloseAndDelete(); - } - } - break; - ///
  • If user is logged, parse and execute the command - case OK: - if(strlen(buff)) - { - sLog.outRemote("Got '%s' cmd.\n",buff); - sWorld.QueueCliCommand(&RASocket::zprint , buff); - } - else - Sendf("TC>"); - break; - /// - }; - - } -} - -/// Output function -void RASocket::zprint( 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); - delete [] megabuffer; - - #else - - unsigned int sz=strlen(szText); - send(r,szText,sz,0); - - #endif -} diff --git a/src/server/trinitycore/RASocket.h b/src/server/trinitycore/RASocket.h deleted file mode 100644 index 5c13724f90d..00000000000 --- a/src/server/trinitycore/RASocket.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef _RASOCKET_H -#define _RASOCKET_H - -#include "sockets/TcpSocket.h" - -#include "Common.h" - -#define RA_BUFF_SIZE 1024 - -class ISocketHandler; - -/// Remote Administration socket -class RASocket: public TcpSocket -{ - public: - - RASocket(ISocketHandler& h); - ~RASocket(); - - void OnAccept(); - void OnRead(); - - private: - - char * buff; - std::string szLogin; - uint32 iSess; - unsigned int iInputLength; - bool bLog; - bool bSecure; //kick on wrong pass, non exist. user, user with no priv - //will protect from DOS, bruteforce attacks - //some 'smart' protection must be added for more security - uint8 iMinLevel; - enum - { - NONE, //initial value - LG, //only login was entered - OK, //both login and pass were given, and they are correct and user have enough priv. - }stage; - - static void zprint( const char * szText ); -}; -#endif -/// @} diff --git a/src/server/trinitycore/TrinityCore.ico b/src/server/trinitycore/TrinityCore.ico deleted file mode 100644 index 6f0a5721957..00000000000 Binary files a/src/server/trinitycore/TrinityCore.ico and /dev/null differ diff --git a/src/server/trinitycore/TrinityCore.rc b/src/server/trinitycore/TrinityCore.rc deleted file mode 100644 index 151185f3cec..00000000000 --- a/src/server/trinitycore/TrinityCore.rc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * 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 "resource.h" -#include "../shared/revision.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APPICON ICON "TrinityCore.ico" - -///////////////////////////////////////////////////////////////////////////// -// Neutre (Par défaut système) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION FILEVER - PRODUCTVERSION PRODUCTVER - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x0L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080004b0" - BEGIN - VALUE "FileDescription", "TrinityCore" - VALUE "FileVersion", STRFILEVER - VALUE "InternalName", "TrinityCore" - VALUE "LegalCopyright", "Copyright (C) 2008-2009" - VALUE "OriginalFilename", "TrinityCore.exe" - VALUE "ProductName", "TrinityCore" - VALUE "ProductVersion", STRPRODUCTVER - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x800, 1200 - END -END -#endif diff --git a/src/server/trinitycore/WorldRunnable.cpp b/src/server/trinitycore/WorldRunnable.cpp deleted file mode 100644 index c674ddbc06f..00000000000 --- a/src/server/trinitycore/WorldRunnable.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup Trinityd -*/ - -#include "Common.h" -#include "ObjectAccessor.h" -#include "World.h" -#include "WorldSocketMgr.h" -#include "Database/DatabaseEnv.h" - -#include "BattleGroundMgr.h" -#include "MapManager.h" -#include "Timer.h" -#include "WorldRunnable.h" - -#define WORLD_SLEEP_CONST 50 - -#ifdef WIN32 -#include "ServiceWin32.h" -extern int m_ServiceStatus; -#endif - -/// Heartbeat for the World -void WorldRunnable::run() -{ - ///- Init new SQL thread for the world database - WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough) - - sWorld.InitResultQueue(); - - uint32 realCurrTime = 0; - uint32 realPrevTime = getMSTime(); - - uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST - - ///- While we have not World::m_stopEvent, update the world - while (!World::IsStopped()) - { - ++World::m_worldLoopCounter; - realCurrTime = getMSTime(); - - uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime); - - sWorld.Update( diff ); - realPrevTime = realCurrTime; - - // diff (D0) include time of previous sleep (d0) + tick time (t0) - // we want that next d1 + t1 == WORLD_SLEEP_CONST - // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement - // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0 - if (diff <= WORLD_SLEEP_CONST+prevSleepTime) - { - prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; - ACE_Based::Thread::Sleep(prevSleepTime); - } - else - prevSleepTime = 0; - - #ifdef WIN32 - if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE); - while (m_ServiceStatus == 2) Sleep(1000); - #endif - } - - sWorld.KickAll(); // save and kick all players - sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call - - // unload battleground templates before different singletons destroyed - sBattleGroundMgr.DeleteAllBattleGrounds(); - - sWorldSocketMgr->StopNetwork(); - - MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory) - - ///- End the database thread - WorldDatabase.ThreadEnd(); // free mySQL thread resources -} diff --git a/src/server/trinitycore/WorldRunnable.h b/src/server/trinitycore/WorldRunnable.h deleted file mode 100644 index f14ee021f36..00000000000 --- a/src/server/trinitycore/WorldRunnable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef __WORLDRUNNABLE_H -#define __WORLDRUNNABLE_H - -/// Heartbeat thread for the World -class WorldRunnable : public ACE_Based::Runnable -{ - public: - void run(); -}; -#endif -/// @} diff --git a/src/server/trinitycore/resource.h b/src/server/trinitycore/resource.h deleted file mode 100644 index 7dc5cb9ef7b..00000000000 --- a/src/server/trinitycore/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by TrinityCore.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/server/trinitycore/trinitycore.conf.dist b/src/server/trinitycore/trinitycore.conf.dist deleted file mode 100644 index 3b6d20e093d..00000000000 --- a/src/server/trinitycore/trinitycore.conf.dist +++ /dev/null @@ -1,2212 +0,0 @@ -########################################## -# Trinity Core worldd configuration file # -########################################## -# Note to devs, line breaks should be at column 80 -############################################################################### -# CONNECTIONS AND DIRECTORIES -# -# RealmID -# RealmID must match the realmlist inside the realmd database -# -# DataDir -# Data directory setting. -# Important: DataDir needs to be quoted, as it is a string which may -# contain space characters. -# Example: "@prefix@/share/trinitycore" -# -# LogsDir -# Logs directory setting. -# Important: Logs dir must exists, or all logs need to be disabled -# Default: "" - no log directory prefix, if used log names isn't -# absolute path then logs will be stored in current directory. -# -# -# LoginDatabaseInfo -# WorldDatabaseInfo -# CharacterDatabaseInfo -# Database connection settings for the world server. -# Default: -# hostname;port;username;password;database -# .;somenumber;username;password;database -# - use named pipes in Windows -# Named pipes: mySQL required adding -# "enable-named-pipe" to [mysqld] section my.ini -# .;/path/to/unix_socket;username;password;database -# - use Unix sockets in Unix/Linux -# -# MaxPingTime -# Settings for maximum database-ping interval (minutes between pings) -# -# WorldServerPort -# Default WorldServerPort -# -# BindIP -# Bind World Server to IP/hostname -# -############################################################################### - -RealmID = 1 -DataDir = "." -LogsDir = "" -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;realmd" -WorldDatabaseInfo = "127.0.0.1;3306;trinity;trinity;world" -CharacterDatabaseInfo = "127.0.0.1;3306;trinity;trinity;characters" -MaxPingTime = 30 -WorldServerPort = 8085 -BindIP = "0.0.0.0" - -############################################################################### -# SCRIPTING SETTINGS -# -# Locale -# Setting for current (DBC) locale to use -# -# EventAI Error reporting -# Default: 0 - Only startup -# 1 - Startup errors and Runtime event errors -# 2 - Startup errors, Runtime event errors, and Creation errors -# -############################################################################### - -Locale = 0 -EAIErrorLevel = 2 - -############################################################################### -# PERFORMANCE SETINGS -# -# UseProcessors -# Processors mask for multi-processor system (Used only in Windows) -# Default: 0 (selected by OS) -# number (bitmask value of selected processors) -# -# ProcessPriority -# Process priority setting (Used only at Windows) -# Default: 1 (HIGH) -# 0 (Normal) -# -# Compression -# Compression level for update packages sent to client (1..9) -# Default: 1 (speed) -# 9 (best compression) -# -# PlayerLimit -# Maximum number of players in the world. Excluding Mods, GMs and Admins -# Default: 100 -# 0 (for infinite players) -# If you want to block players and enable Mods, GMs or Admins use -# DB field realmd.realmlist.allowedSecurityLevel -# -# SaveRespawnTimeImmediately -# Save respawn time for creatures at death and gameobjects at use/open -# Default: 1 (save creature/gameobject respawn time immediately) -# 0 (save creature/gameobject respawn time at grid unload) -# -# MaxOverspeedPings -# Maximum overspeed ping count before player kick -# (minimum is 2, 0 used for disable check) -# Default: 2 -# -# GridUnload -# Unload grids -# (if you have lot memory you can disable it to speed up -# player move to new grids second time) -# Default: 1 (unload grids) -# 0 (do not unload grids) -# -# SocketSelectTime -# Socket select time (in milliseconds) -# Default: 10000 (10 secs) -# -# SocketTimeOutTime -# Time in milliseconds afer which a connection sitting idle on the character -# selection screen is disconnected. -# Default: 900000 (15 minutes) -# -# SessionAddDelay -# Time in microseconds that a network thread will sleep after authentication -# protocol and adding a connection to the world session map. -# Default: 10000 (10 milliseconds, 0,01 second) -# -# GridCleanUpDelay -# Grid clean up delay (in milliseconds) -# Default: 300000 (5 min) -# -# MapUpdateInterval -# Map update interval (in milliseconds) -# Default: 100 -# -# ChangeWeatherInterval -# Weather update interval (in milliseconds) -# Default: 600000 (10 min) -# -# PlayerSaveInterval -# Player save interval (in milliseconds) -# Default: 900000 (15 min) -# -# PlayerSave.Stats.MinLevel -# Minimum level for saving character stats for external usage in database -# Default: 0 (do not save character stats) -# 1+ (save stats for characters with level 1+) -# -# PlayerSave.Stats.SaveOnlyOnLogout -# Enable/Disable saving of character stats only on logout -# Default: 1 (only save on logout) -# 0 (save on every player save) -# -# vmap.enableLOS -# vmap.enableHeight -# Enable/Disable VMmap support for line of sight and height calculation -# Default: 0 (disable) -# 1 (enable) -# -# vmap.ignoreMapIds -# Map id that will be ignored by VMaps -# List of ids with delimiter ',' -# If more then one id is defined and spaces are included, the string -# has to be enclosed by " -# Example: "369,0,1,530" -# -# vmap.ignoreSpellIds -# These spells are ignored for LoS calculation -# List of ids with delimiter ',' -# -# vmap.petLOS -# Check LOS for pets, to avoid them going through walls etc. -# Default: 0 (disable, less CPU usage) -# 1 (enable, each pet attack command will check for LOS) -# -# vmap.enableIndoorCheck -# Enable/Disable VMap based indoor check to remove outdoor-only auras (mounts etc.) -# Default: 0 (disabled) -# -# DetectPosCollision -# Check final move position, summon position, etc for visible collision -# with other objects or wall (wall only if vmaps are enabled) -# Default: 1 (enable, required more CPU usage) -# 0 (disable, less position precision but will use less CPU) -# -# TargetPosRecalculateRange -# Max distance from movement target point (+moving unit size) and -# targeted object (+size) after that new target movement point -# calculated. Max: melee attack range (5), min: contact range (0.5) -# More distance let have better performence, less distance let have -# more sensitive reaction at target move. -# Default: 1.5 -# -# UpdateUptimeInterval -# Update realm uptime period in minutes. Must be > 0 -# Default: 10 (minutes) -# -# LogDB.Opt.ClearInterval -# Time for the WUPDATE_CLEANDB timer that clears the `logs` table -# of old entries. Must be > 0. -# Default: 10 (minutes) -# -# LogDB.Opt.ClearTime -# The maximum time in seconds of old `logs` table entries to keep. -# Default: 1209600 (14 days) -# 0 - don't clear -# -# MaxCoreStuckTime -# Periodically check if the process is frozen, if this is the case -# force crash after the specified amount of seconds. Must be > 0. -# Recommended > 10 secs if you use this. -# Default: 0 (Disabled) -# -# AddonChannel -# Permit/disable the use of the addon channel through the server -# (some client side addons will not work correctly with disabled -# addon channel) -# Default: 1 (permit addon channel) -# 0 (do not permit addon channel) -# -# MapUpdate.Threads -# Number of threads to update maps. -# Default: 1 -# -############################################################################### - -UseProcessors = 0 -ProcessPriority = 1 -Compression = 1 -PlayerLimit = 100 -SaveRespawnTimeImmediately = 1 -MaxOverspeedPings = 2 -GridUnload = 1 -SocketSelectTime = 10000 -SocketTimeOutTime = 900000 -SessionAddDelay = 10000 -GridCleanUpDelay = 300000 -MapUpdateInterval = 100 -ChangeWeatherInterval = 600000 -PlayerSaveInterval = 900000 -PlayerSave.Stats.MinLevel = 0 -PlayerSave.Stats.SaveOnlyOnLogout = 1 -vmap.enableLOS = 0 -vmap.enableHeight = 0 -vmap.ignoreMapIds = "369" -vmap.ignoreSpellIds = "7720" -vmap.petLOS = 0 -vmap.enableIndoorCheck = 0 -DetectPosCollision = 1 -TargetPosRecalculateRange = 1.5 -UpdateUptimeInterval = 10 -LogDB.Opt.ClearInterval = 10 -LogDB.Opt.ClearTime = 1209600 -MaxCoreStuckTime = 0 -AddonChannel = 1 -MapUpdate.Threads = 1 - -############################################################################### -# SERVER LOGGING -# -# LogSQL -# Enable logging of SQL commands from in game -# All commands are written to a file: YYYY-MM-DD_logSQL.sql -# If a new day starts (00:00:00) then a new file is created -# the old file will not be deleted. -# Default: 1 - Write SQL code to logfile -# 0 - Do not log -# -# PidFile -# World daemon PID file -# Default: "" - do not create PID file -# "./worldd.pid" - create PID file (recommended name) -# -# LogLevel -# Server console level of logging -# 0 = Minimum -# Default: 1 = Basic -# 2 = Detail -# 3 = Full/Debug -# -# LogFile -# Logfile name -# Default: "Server.log" -# "" - Empty name disable creating log file -# -# ChatLogFile -# Log file for chat logs -# Default: "chat.log" -# "" - Empty name for disable -# -# LogTimestamp -# Logfile with timestamp of server start in name -# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# Default: 0 - no timestamp in name -# 1 - add timestamp in name -# -# LogFileLevel -# Server file level of logging -# Default: 0 = Minimum -# 1 = Basic -# 2 = Detail -# 3 = Full/Debug -# -# LogFilter_AchievementUpdates -# LogFilter_CreatureMoves -# LogFilter_TransportMoves -# LogFilter_VisibilityChanges -# Log filters -# Default: 1 - not include with any log level -# 0 - include in log if log level permit -# -# WorldLogFile -# Packet logging file for the worldserver -# Default: "world.log" -# -# DBErrorLogFile -# Log file of DB errors detected at server run -# Default: "DBErrors.log" -# -# CharLogFile -# Character operations logfile name -# Default: "Char.log" -# "" - Empty name disable creating log file -# -# CharLogTimestamp -# Logfile with timestamp of server start in name -# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# Default: 0 - no timestamp in name -# 1 - add timestamp in name -# -# CharLogDump -# Write character dump before deleting in Char.log -# For restoration, cut character data from log starting from -# line == START DUMP == to line == END DUMP == (exclusive) in file -# and load it using the loadpdump command -# Default: 0 - don't include dumping chars to log -# 1 - include dumping chars to log -# CharLogDump.Separate -# Write character dump to separate file -# Default: 0 - don't write dump to separate file -# 1 - write each dump to separate file -# -# CharLogDump.SeparateDir -# Subdirectory within logs dir for separate char dumps. -# -# -# GmLogFile -# Log file of gm commands -# Default: "gm_commands.log" -# "" - Empty name for disable -# -# GmLogTimestamp -# GM Logfile with timestamp of server start in name -# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# Default: 0 - no timestamp in name -# 1 - add timestamp in name -# -# GmLogPerAccount -# GM Logfiles with GM account id -# (Note: logs not created if GmLogFile not set) -# Default: 0 - add gm log data to single log file -# 1 - add gm log data to account specific log files with name -# in form Logname_#ID_YYYY-MM-DD_HH-MM-SS.Ext -# or form Logname_#ID.Ext -# -# RaLogFile -# Log file of RA commands -# Default: "Ra.log" -# "" - Empty name for disable -# -# ArenaLogFile -# Log file of arena fights and arena team creations -# Default: "" - do not create arena log file -# -# LogColors -# Color for messages (format "normal basic detail debug") -# Default: "" - no colors -# Colors: 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "13 11 9 5" -# -# EnableLogDB -# Enable/disable logging to database (LogDatabaseInfo). -# Default: 0 - disabled -# 1 - enabled -# -# DBLogLevel -# Log level of DB logging. -# 0 = Minimum -# 1 = Basic -# 2 = Detail -# Default: 3 = Full/Debug -# -# LogDB.Char -# Enable/disable logging character outputs to DB. -# Default: 0 - off -# 1 - on -# -# LogDB.GM -# Enable/disable logging GM commands to DB. -# Default: 0 - off -# 1 - on -# -# LogDB.RA -# Enable/disable logging remote access events to DB. -# Default: 0 - off -# 1 - on -# -# LogDB.World -# Enable/disable logging world packets to DB. -# Default: 0 - off -# 1 - on (very heavy) -# -# LogDB.Chat -# Enable/disable logging chat messages to the database. -# Default: 0 - off -# 1 - on -# -# ChatLogs.Channel -# Enable logging chatting in custom channels. -# Default: 0 - off -# 1 - on -# -# ChatLogs.Whisper -# Enable logging whispers between players. -# Default: 0 - off -# 1 - on -# -# ChatLogs.Party -# Enable logging party messages. -# Default: 0 - off -# 1 - on -# -# ChatLogs.Raid -# Enable logging raid messages. -# Default: 0 - off -# 1 - on -# -# ChatLogs.Guild -# Enable logging guild messages. -# Default: 0 - off -# 1 - on -# -# ChatLogs.Public -# Enable logging public chat events (say/yell/emote). -# Default: 0 - off -# 1 - on -# -# ChatLogs.Addon -# Enable logging addon messages. -# Default: 0 - off -# 1 - on -# -# ChatLogs.BattleGround -# Enable logging battleground chats. -# Default: 0 - off -# 1 - on -# -# ChatLogTimestamp -# Chat Logfile with timestamp of server start in name -# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# Default: 0 - no timestamp in name -# 1 - add timestamp in name -# -############################################################################### - -LogSQL = 1 -PidFile = "" -LogLevel = 1 -LogFile = "Server.log" -ChatLogFile = "chat.log" -LogTimestamp = 0 -LogFileLevel = 0 -LogFilter_AchievementUpdates = 1 -LogFilter_CreatureMoves = 1 -LogFilter_TransportMoves = 1 -LogFilter_VisibilityChanges = 1 -WorldLogFile = "" -DBErrorLogFile = "db_errors.log" -CharLogFile = "characters.log" -CharLogTimestamp = 0 -CharLogDump = 0 -CharLogDump.Separate = 0 -CharLogDump.SeparateDir = "" -GmLogFile = "gm_commands.log" -GmLogTimestamp = 0 -GmLogPerAccount = 0 -RaLogFile = "ra_commands.log" -ArenaLogFile = "" -LogColors = "" -EnableLogDB = 0 -DBLogLevel = 2 -LogDB.Char = 0 -LogDB.GM = 0 -LogDB.RA = 0 -LogDB.World = 0 -LogDB.Chat = 0 -ChatLogs.Channel = 0 -ChatLogs.SysChan = 0 -ChatLogs.Whisper = 0 -ChatLogs.Party = 0 -ChatLogs.Raid = 0 -ChatLogs.Guild = 0 -ChatLogs.Public = 0 -ChatLogs.Addon = 0 -ChatLogs.BattleGround = 0 -ChatLogTimestamp = 0 - -############################################################################### -# SERVER SETTINGS -# -# GameType -# Server realm style -# Default: 0 = NORMAL -# 1 = PVP -# 4 = NORMAL -# 6 = RP -# 8 = RPPVP -# 16 FFA_PVP (free for all pvp mode like arena PvP in all -# zones except rest activated places and sanctuaries) -# -# RealmZone -# Server realm zone (set allowed alphabet in character names/etc) -# See also Strict*Names options. -# -# Default: 1 Development - any language -# 2 United States - extended-Latin -# 3 Oceanic - extended-Latin -# 4 Latin America - extended-Latin -# 5 Tournament - basic-Latin at create, any at login -# 6 Korea - East-Asian -# 7 Tournament - basic-Latin at create, any at login -# 8 English - extended-Latin -# 9 German - extended-Latin -# 10 French - extended-Latin -# 11 Spanish - extended-Latin -# 12 Russian - Cyrillic -# 13 Tournament - basic-Latin at create, any at login -# 14 Taiwan - East-Asian -# 15 Tournament - basic-Latin at create, any at login -# 16 China - East-Asian -# 17 CN1 - basic-Latin at create, any at login -# 18 CN2 - basic-Latin at create, any at login -# 19 CN3 - basic-Latin at create, any at login -# 20 CN4 - basic-Latin at create, any at login -# 21 CN5 - basic-Latin at create, any at login -# 22 CN6 - basic-Latin at create, any at login -# 23 CN7 - basic-Latin at create, any at login -# 24 CN8 - basic-Latin at create, any at login -# 25 Tournament - basic-Latin at create, any at login -# 26 Test Server - any language -# 27 Tournament - basic-Latin at create, any at login -# 28 QA Server - any language -# 29 CN9 - basic-Latin at create, any at login -# -# Expansion -# Allow server use content from expansion -# Default: 2 - check expansion 2 maps existence, and if client support -# expansion 2 and account have expansion 2 setting then -# allow visit expansion 2 maps, allow create new class -# character) -# 1 - check expansion 1 maps existence, and if client support -# expansion 1 and account have expansion 1 setting then -# allow visit expansion 1 maps, allow create new races -# character) -# 0 - don't check expansion maps existence, don't allow visit -# maps, don't allow create new race or new class -# characters, ignore account expansion setting) -# -# DBC.Locale -# DBC Language Settings -# Default: 255 = Auto Detect -# 0 = English -# 1 = Korean -# 2 = French -# 3 = German -# 4 = Chinese -# 5 = Taiwanese -# 6 = Spanish -# 7 = Spanish Mexico -# 8 = Russian -# -# DeclinedNames -# Allow russian clients to set and use declined names -# Default: 0 - do not use declined names, except when -# the Russian RealmZone is set -# 1 - use declined names -# -# StrictPlayerNames -# Limit player name to language specific symbol set, don't allow -# character creation, and set rename request and disconnect at not -# allowed symbols name -# Default: 0 disable (limited server timezone dependent client check) -# 1 basic latin characters (strict) -# 2 realm zone specific (strict). See RealmZone setting. -# Note: In any case if you want correctly see character -# name at client this client must have appropriate fonts -# (included in client by default, with active official -# localization or custom localization fonts in -# clientdir/Fonts). -# 3 basic latin characters + server timezone specific -# -# StrictCharterNames -# Limit guild/arena team charter names to language specific symbol set, -# don't allow charter creation with unallowed symbols in name -# Default: 0 disable -# 1 basic latin characters (strict) -# 2 realm zone specific (strict). See RealmZone setting. -# Note: In any case if you want correctly see character -# name at client this client must have appropriate fonts -# (included in client by default, with active official -# localization or custom localization fonts in -# clientdir/Fonts). -# 3 basic latin characters + server timezone specific -# -# StrictPetNames -# Limit pet names to language specific symbols set -# Default: 0 disable -# 1 basic latin characters (strict) -# 2 realm zone specific (strict). See RealmZone setting. -# Note: In any case if you want correctly see character -# name at client this client must have appropriate fonts -# (included in client by default, with active official -# localization or custom localization fonts in -# clientdir/Fonts). -# 3 basic latin characters + server timezone specific -# -# MinPlayerName -# Minimal name length (1..12) -# Default: 2 -# -# MinCharterName -# Minimal name length (1..24) -# Default: 2 -# -# MinPetName -# Minimal name length (1..12) -# Default: 2 -# -# CharactersCreatingDisabled -# Disable characters creating for specific team or any -# (non-player accounts not affected) -# Default: 0 - enabled -# 1 - disabled only for Alliance -# 2 - disabled only for Horde -# 3 - disabled for both teams -# -# MaxWhoListReturns -# Set the max number of players returned in the /who list and interface. -# Default: 49 (stable) -# -# CharactersPerAccount -# Limit numbers of characters per account (at all realms). -# Note: this setting limit character creating at _current_ realm base -# at characters amount at all realms -# Default: 50 -# The number must be >= CharactersPerRealm -# -# CharactersPerRealm -# Limit numbers of characters for account at realm -# Default: 10 (client limitation) -# The number must be between 1 and 10 -# -# HeroicCharactersPerRealm -# Limit numbers of heroic class characters for account at realm -# Default: 1 -# The number must be between 0 (not allowed) and 10 -# -# MinLevelForHeroicCharacterCreating -# Limit creating heroic characters only for account with another -# character of specific level (ignored for GM accounts) -# 0 - not require any existed chaarcter -# 1 - require at least any character existed -# Default: 55 - default requirement -# -# -# SkipCinematics -# Disable in-game script movie at first character's login -# (allows to prevent buggy intro in case of custom start -# location coordinates) -# Default: 0 - show intro for each new characrer -# 1 - show intro only for first character of selected race -# 2 - disable intro show in all cases -# -# MaxPlayerLevel -# Max level that can be reached by player for experience -# (in range from 1 to 100). Going past 100 voids your warranty -# and you will not receive support for bugs you encounter. -# Change not recommended -# Default: 80 -# -# MinDualSpecLevel -# Min level at which players can use Dual Spec functionality -# Default: 40 -# -# StartPlayerLevel -# Staring level that have character upon creation -# (in range 1 to MaxPlayerLevel) -# Default: 1 -# -# StartHeroicPlayerLevel -# Staring level that have character of heroic class upon creation -# (in range 1 to MaxPlayerLevel) -# Default: 55 -# -# StartPlayerMoney -# Amount of money that new players will start with. -# If you want to start with silver, use for example 100 -# (100 copper = 1 silver) -# Default: 0 -# -# MaxHonorPoints -# Max honor points that player can have. -# Default: 75000 -# -# StartHonorPoints -# Amount of honor that new players will start with -# Default: 0 -# -# MaxArenaPoints -# Max arena points that player can have. -# Default: 5000 -# -# StartArenaPoints -# Amount of arena points that new players will start with -# Default: 0 -# -# InstantLogout -# Enable or disable instant logout for security level (0..4) or higher -# (NOT in combat/while dueling/while falling) -# Default: 1 (Mods/GMs/Admins) -# -# DisableWaterBreath -# Disable/enable waterbreathing for security level (0..4) or higher -# Default: 4 (None) -# -# AllFlightPaths -# Players will start with all flight paths -# (Note: ALL flight paths, not only player's team) -# Default: 0 (false) -# 1 (true) -# -# InstantFlightPaths -# Flight paths will take players to their destination instantly, instead -# of making them wait to fly there. -# Default: 0 (false) -# 1 (true) -# -# AlwaysMaxSkillForLevel -# Players will automatically gain max level dependent (weapon/defense) -# skill when logging in, leveling up etc. -# Default: 0 (false) -# 1 (true) -# -# ActivateWeather -# Activate weather system -# Default: 1 (true) -# 0 (false) -# -# CastUnstuck -# Allow cast or not Unstuck spell at .start or client Help option use -# Default: 1 (true) -# 0 (false) -# -# Instance.IgnoreLevel -# Ignore level requirement to enter instance -# Default: 0 (false) -# 1 (true) -# -# Instance.IgnoreRaid -# Ignore raid requirement to enter instance -# Default: 0 (false) -# 1 (true) -# -# Instance.ResetTimeHour -# The hour of the day (0-23) when the global instance resets occur. -# Default: 4 -# -# Instance.UnloadDelay -# Unload the instance map from memory after some time -# if no players are inside. -# Default: 1800000 (miliseconds 30 minutes) -# 0 (instance maps are kept in memory until they are reset) -# -# Quests.LowLevelHideDiff -# Quest level difference to hide for player low level quests: -# if player_level > quest_level + LowLevelQuestsHideDiff then quest -# "!" mark not show for quest giver -# Default: 4 -# -1 (show all available quests marks) -# -# Quests.HighLevelHideDiff -# Quest level difference to hide for player high level quests: -# if player_level < quest_min_level - HighLevelQuestsHideDiff then -# quest "!" mark not show for quest giver -# Default: 7 -# -1 (show all available quests marks) -# -# Guild.EventLogRecordsCount -# Count of guild event log records stored in guild_eventlog table -# Increase to store more guild events in table, minimum is 100 -# You can set it to very high value to prevent oldest guild events to -# be rewritten by latest guild events; can slow down performance -# Default: 100 -# -# Guild.BankEventLogRecordsCount -# Count of guild_bank event log records stored in -# guild_bank_eventlog table -# Increase to store more guild_bank events in table - minimum is 25 -# (GUILD_BANK_MAX_LOGS) for each guild_bank tab -# Useful when you don't want old log events to be overwritten by new, -# but increasing can slow down performance -# Default: 25 -# -# MaxPrimaryTradeSkill -# Max count that player can learn the primary trade skill. -# Default: 2 -# Max : 10 -# -# MinPetitionSigns -# Min signatures count to creating guild (0..9). -# Default: 9 -# -# MaxGroupXPDistance -# Max distance to creature for group member to get XP at creature death. -# Default: 74 -# -# MailDeliveryDelay -# Mail delivery delay time for item sending -# Default: 3600 sec (1 hour) -# -# SkillChance.Prospecting -# For prospecting skillup impossible by default, -# but can be allowed as custom setting -# Default: 0 - no skilups -# 1 - skilups possible -# -# SkillChance.Milling -# For milling skillup impossible by default, -# but can be allowed as custom setting -# Default: 0 - no skilups -# 1 - skilups possible -# -# OffhandCheckAtSpellUnlearn -# Unlearning certain spells can change offhand weapon restrictions -# for equip slots. -# Default: 0 - recheck offhand slot weapon only at zone update -# 1 - recheck offhand slot weapon at unlearning a spell -# -# ClientCacheVersion -# Client cache version for client cache data reset. Use any different -# from DB value and not recently used for triggering reset. -# Default: 0 (use DB value from world DB db_version.cache_id field) -# -# Event.Announce -# Default: 0 (false) -# 1 (true) -# -# BeepAtStart -# Beep at core start finished (mostly work only at Unix/Linux systems) -# Default: 1 (true) -# 0 (false) -# -# Motd -# Message of the Day. Displayed at worldlogin for every user -# Use '@' for a newline, and be sure to escape special characters. -# Example: "Welcome to John\'s Server@WinterGrasp is closed." -# -# Server.LoginInfo -# Enable/disable sending server info (core version) on login. -# Default: 0 - disable -# 1 - enable -# -############################################################################### - -GameType = 0 -RealmZone = 1 -Expansion = 2 -DBC.Locale = 255 -DeclinedNames = 0 -StrictPlayerNames = 0 -StrictCharterNames = 0 -StrictPetNames = 0 -MaxWhoListReturns = 49 -MinPlayerName = 2 -MinCharterName = 2 -MinPetName = 2 -CharactersCreatingDisabled = 0 -CharactersPerAccount = 50 -CharactersPerRealm = 10 -HeroicCharactersPerRealm = 1 -MinLevelForHeroicCharacterCreating = 55 -SkipCinematics = 0 -MaxPlayerLevel = 80 -MinDualSpecLevel = 40 -StartPlayerLevel = 1 -StartHeroicPlayerLevel = 55 -StartPlayerMoney = 0 -MaxHonorPoints = 75000 -StartHonorPoints = 0 -MaxArenaPoints = 5000 -StartArenaPoints = 0 -InstantLogout = 1 -DisableWaterBreath = 4 -AllFlightPaths = 0 -InstantFlightPaths = 0 -AlwaysMaxSkillForLevel = 0 -ActivateWeather = 1 -CastUnstuck = 1 -Instance.IgnoreLevel = 0 -Instance.IgnoreRaid = 0 -Instance.ResetTimeHour = 4 -Instance.UnloadDelay = 1800000 -Quests.LowLevelHideDiff = 4 -Quests.HighLevelHideDiff = 7 -Guild.EventLogRecordsCount = 100 -Guild.BankEventLogRecordsCount = 25 -MaxPrimaryTradeSkill = 2 -MinPetitionSigns = 9 -MaxGroupXPDistance = 74 -MailDeliveryDelay = 3600 -SkillChance.Prospecting = 0 -SkillChance.Milling = 0 -OffhandCheckAtSpellUnlearn = 0 -ClientCacheVersion = 0 -Event.Announce = 0 -BeepAtStart = 1 -Motd = "Welcome to a Trinity Core server." -Server.LoginInfo = 0 - -############################################################################### -# PLAYER INTERACTION -# -# AllowTwoSide.Accounts -# Allow or not accounts to create characters in the 2 teams -# in any game type. -# Default: 1 (Allowed) -# 0 (Not allowed) -# -# AllowTwoSide.Interaction.Chat -# AllowTwoSide.Interaction.Channel -# AllowTwoSide.Interaction.Group -# AllowTwoSide.Interaction.Guild -# AllowTwoSide.Interaction.Auction -# AllowTwoSide.Interaction.Mail -# Allow or not common :chat(say,yell) -# channel(chat) -# group(join) -# guild(join) -# merge all auction houses for players from -# different teams -# send mail to other team. -# Default: 0 (Not allowed) -# 1 (Allowed) -# -# AllowTwoSide.WhoList -# Allow or not show player from both team in who list. -# Default: 0 (Not allowed) -# 1 (Allowed) -# -# AllowTwoSide.AddFriend -# Allow or not adding friends from other team in friend list. -# Default: 0 (Not allowed) -# 1 (Allowed) -# -# AllowTwoSide.Trade -# Allow or not trading with other team in party. -# Default: 0 (Not allowed) -# 1 (Allowed) -# -# TalentsInspecting -# Allow other players see character talents in inspect dialog -# (Characters in Gamemaster mode can inspect talents always) -# Default: 1 (allow) -# 0 (not allow) -# -############################################################################### - -AllowTwoSide.Accounts = 1 -AllowTwoSide.Interaction.Chat = 0 -AllowTwoSide.Interaction.Channel = 0 -AllowTwoSide.Interaction.Group = 0 -AllowTwoSide.Interaction.Guild = 0 -AllowTwoSide.Interaction.Auction = 0 -AllowTwoSide.Interaction.Mail = 0 -AllowTwoSide.WhoList = 0 -AllowTwoSide.AddFriend = 0 -AllowTwoSide.Trade = 0 -TalentsInspecting = 1 - -############################################################################### -# CREATURE SETTINGS -# -# ThreatRadius -# Radius for creature to evade after being -# pulled away from combat start point -# If ThreatRadius is less than creature aggro radius -# then aggro radius will be used -# Default: 60 yards -# -# Rate.Creature.Aggro -# Aggro radius percent or off. -# Default: 1 - 100% -# 1.5 - 150% -# 0 - off (0%) -# -# CreatureFamilyFleeAssistanceRadius -# Radius which creature will use to seek for a nearby creature -# for assistance. Creature will flee to this creature. -# Default: 30 -# 0 - off -# -# CreatureFamilyAssistanceRadius -# Radius which creature will use to call assistance without moving -# Default: 10 -# 0 - off -# -# CreatureFamilyAssistanceDelay -# Reaction time for creature assistance call -# Default: 1500 (1.5s) -# -# CreatureFamilyFleeDelay -# Time during which creature can flee when no assistant found -# Default: 7000 (7s) -# -# WorldBossLevelDiff -# Difference for boss dynamic level with target -# Default: 3 -# -# Corpse.Decay.NORMAL -# Corpse.Decay.RARE -# Corpse.Decay.ELITE -# Corpse.Decay.RAREELITE -# Corpse.Decay.WORLDBOSS -# Seconds until creature corpse will decay if not looted or skinned. -# Default: 60, 300, 300, 300, 3600 -# -# Rate.Corpse.Decay.Looted -# Controls how long the creature corpse stays after it had been looted, -# as a multiplier of its Corpse.Decay.* config. -# Default: 0.5 -# -# Rate.Creature.Normal.Damage -# Rate.Creature.Elite.Elite.Damage -# Rate.Creature.Elite.RAREELITE.Damage -# Rate.Creature.Elite.WORLDBOSS.Damage -# Rate.Creature.Elite.RARE.Damage -# Creature Damage Rates. -# Examples: 2 - creatures will damage 2x, 1.7 - 1.7x. -# -# Rate.Creature.Normal.SpellDamage -# Rate.Creature.Elite.Elite.SpellDamage -# Rate.Creature.Elite.RAREELITE.SpellDamage -# Rate.Creature.Elite.WORLDBOSS.SpellDamag -# Rate.Creature.Elite.RARE.SpellDamage -# Creature Spell Damage Rates. -# Examples: 2 - creatures will damage with spells 2x, 1.7 - 1.7x. -# -# Rate.Creature.Normal.HP -# Rate.Creature.Elite.Elite.HP -# Rate.Creature.Elite.RAREELITE.HP -# Rate.Creature.Elite.WORLDBOSS.HP -# Rate.Creature.Elite.RARE.HP -# Creature Health Ammount Modifier. -# Examples: 2 - creatures have 2x health, 1.7 - 1.7x. -# -# ListenRange.Say -# Distance from player to listen text that creature -# (or other world object) says -# Default: 40 -# -# ListenRange.TextEmote -# Distance from player to listen textemote that creature -# (or other world object) says -# Default: 40 -# -# ListenRange.Yell -# Distance from player to listen text that creature -# (or other world object) yells -# Default: 300 -# -############################################################################### - -ThreatRadius = 60 -Rate.Creature.Aggro = 1 -CreatureFamilyFleeAssistanceRadius = 30 -CreatureFamilyAssistanceRadius = 10 -CreatureFamilyAssistanceDelay = 1500 -CreatureFamilyFleeDelay = 7000 -WorldBossLevelDiff = 3 -Corpse.Decay.NORMAL = 60 -Corpse.Decay.RARE = 300 -Corpse.Decay.ELITE = 300 -Corpse.Decay.RAREELITE = 300 -Corpse.Decay.WORLDBOSS = 3600 -Rate.Corpse.Decay.Looted = 0.5 -Rate.Creature.Normal.Damage = 1 -Rate.Creature.Elite.Elite.Damage = 1 -Rate.Creature.Elite.RAREELITE.Damage = 1 -Rate.Creature.Elite.WORLDBOSS.Damage = 1 -Rate.Creature.Elite.RARE.Damage = 1 -Rate.Creature.Normal.SpellDamage = 1 -Rate.Creature.Elite.Elite.SpellDamage = 1 -Rate.Creature.Elite.RAREELITE.SpellDamage = 1 -Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1 -Rate.Creature.Elite.RARE.SpellDamage = 1 -Rate.Creature.Normal.HP = 1 -Rate.Creature.Elite.Elite.HP = 1 -Rate.Creature.Elite.RAREELITE.HP = 1 -Rate.Creature.Elite.WORLDBOSS.HP = 1 -Rate.Creature.Elite.RARE.HP = 1 -ListenRange.Say = 40 -ListenRange.TextEmote = 40 -ListenRange.Yell = 300 - -############################################################################### -# CHAT SETTINGS -# -# ChatFakeMessagePreventing -# Chat protection from creating fake messages using a lot spaces -# (other invisible symbols), -# not applied to addon language messages, but can cause old addons -# that use normal languages for sending data to another clients. -# Default: 0 (disible fake messages preventing) -# 1 (enabled fake messages preventing) -# -# ChatStrictLinkChecking.Severity -# Check chat messages for ingame links to -# spells, items, quests, achievements etc. -# Default: 0 (disable link checking) -# 1 (check if only valid pipe commands are used. -# This prevents posting pictures for example) -# 2 (verifiy that pipe commands are used in a correct order) -# 3 (check if color, entry and name don't contradict -# each other. For correct work, please assure -# that you have extracted locale DBCs of every language -# specific client playing on this server.) -# -# ChatStrictLinkChecking.Kick -# Defines what should be done if a message is considered to contain -# invalid pipe commands. -# Default: 0 (silently ignore message) -# 1 (kick players who sent invalid formed messages) -# -# ChatFlood.MessageCount -# Chat anti-flood protection, haste message count to activate protection -# Default: 10 -# 0 (disible anti-flood protection) -# -# ChatFlood.MessageDelay -# Chat anti-flood protection, minimum message delay to count message -# Default: 1 (in secs) -# -# ChatFlood.MuteTime -# Chat anti-flood protection, mute time at activation flood protection -# Default: 10 (in secs) -# -# Channel.RestrictedLfg -# Restrict LookupForGroup channel to registered in LFG tool players -# Default: 1 (allow join to channel only if active in LFG) -# 0 (allow join to channel in any time) -# -# Channel.SilentlyGMJoin -# Silently join GM characters (security level > 1) to channels -# Default: 0 (join announcement in normal way) -# 1 (GM join without announcement) -# -# ChatLevelReq.Channel -# The required level of character to be able to write in chat channels -# Default: 1 (From level 1) -# -# ChatLevelReq.Whisper -# The required level of character to be able to whisper -# Default: 1 (From level 1) -# -# ChatLevelReq.Say -# The required level of character to be able to say/yell/emote -# Default: 1 (From level 1) -# -# AllowPlayerCommands -# Allowed the players to use commands -# Default: 1 (allow) -# -############################################################################### - -ChatFakeMessagePreventing = 0 -ChatStrictLinkChecking.Severity = 0 -ChatStrictLinkChecking.Kick = 0 -ChatFlood.MessageCount = 10 -ChatFlood.MessageDelay = 1 -ChatFlood.MuteTime = 10 -Channel.RestrictedLfg = 1 -Channel.SilentlyGMJoin = 0 -ChatLevelReq.Channel = 1 -ChatLevelReq.Whisper = 1 -ChatLevelReq.Say = 1 -AllowPlayerCommands = 1 - -############################################################################### -# GAME MASTER SETTINGS -# -# GM.LoginState -# GM mode at login -# Default: 2 (last save state) -# 0 (disable) -# 1 (enable) -# -# GM.Visible -# GM visibility at login -# Default: 2 (last save state) -# 0 (invisible) -# 1 (visible) -# -# GM.AcceptTickets -# Is GM accepting tickets from player by default or not. -# Default: 2 (last save state) -# 0 (disable) -# 1 (enable) -# -# GM.Chat -# GM chat mode at login -# Default: 2 (last save state) -# 0 (disable) -# 1 (enable) -# -# GM.WhisperingTo -# Is GM accepting whispers from player by default or not. -# Default: 2 (last save state) -# 0 (disable) -# 1 (enable) -# -# GM.InGMList.Level -# Max GM level showed in GM list (if visible) in non-GM state (.gm off) -# 0 (only players) -# 1 (only moderators) -# 2 (only gamemasters) -# Default: 3 (anyone) -# -# GM.InWhoList.Level -# Max GM level showed in who list (if visible). -# 0 (only players) -# 1 (only moderators) -# 2 (only gamemasters) -# Default: 3 (anyone) -# -# GM.LogTrade -# Include GM trade and trade slot enchanting operations in GM log -# Default: 1 (include) -# 0 (not include) -# -# GM.StartLevel -# GM starting level (1-100) -# Default: 1 -# -# GM.AllowInvite -# Is GM accepting invites from players by default or not -# Default: 0 (false) -# 1 (true) -# -# GM.AllowFriend -# Are players allowed to add GMs to their friend list -# Default: 0 (false) -# 1 (true) -# -# GM.LowerSecurity -# Disallow a lower security member to interact with -# a higher one using commands -# Default: 0 (disable) -# 1 (enable) -# -# GM.AllowAchievementGain -# If enabled it allows gaining achievements for GM characters -# Default: 1 (enable) -# 0 (disable) -# -############################################################################### - -GM.LoginState = 2 -GM.Visible = 2 -GM.AcceptTickets = 2 -GM.Chat = 2 -GM.WhisperingTo = 2 -GM.InGMList.Level = 3 -GM.InWhoList.Level = 3 -GM.LogTrade = 1 -GM.StartLevel = 80 -GM.AllowInvite = 0 -GM.AllowFriend = 0 -GM.LowerSecurity = 0 -GM.AllowAchievementGain = 1 - -############################################################################### -# VISIBILITY AND RADIUSES -# -# Visibility.GroupMode -# Group visibility modes -# Default: 0 (standard setting: only members from same group can -# 100% auto detect invisible player) -# 1 (raid members 100% auto detect invisible player from -# same raid) -# 2 (players from same team can 100% auto detect -# invisible player) -# -# Visibility.Distance.Continents -# Visibility.Distance.Instances -# Visibility.Distance.BGArenas -# Visibility distance for different ingame object in different maps. -# Visibility on continents on offy ~90 yards. In BG/Arenas ~180. -# For instances default ~120. -# Max limited by active player zone: ~ 333 -# Min limit is max aggro radius (45) * Rate.Creature.Aggro -# -# Visibility.Distance.Object -# Visible distance for gameobject, dynobject, bodies, corpses, bones -# Min limit is iteraction distance (5) -# -# Visibility.Distance.InFlight -# Visible distance for player in flight -# Min limit is 0 (not show any objects) -# -# Visibility.Distance.Grey.Unit -# Visibility grey distance for creatures/players (fast changing objects) -# addition to appropriate object type Visibility.Distance.* use in case -# visibility removing to object (except corpse around distances) -# If D is distance and G is grey distance then object -# make visible if distance to it <= D -# but make non visible if distance > D+G -# Default: 1 (yard) -# -# Visibility.Distance.Grey.Object -# Visibility grey distance for dynobjects/gameobjects/corpses/creatures -# Default: 10 (yards) -# -############################################################################### - -Visibility.GroupMode = 0 -Visibility.Distance.Continents = 90 -Visibility.Distance.Instances = 120 -Visibility.Distance.BGArenas = 180 -Visibility.Distance.Object = 100 -Visibility.Distance.InFlight = 100 -Visibility.Distance.Grey.Unit = 1 -Visibility.Distance.Grey.Object = 10 - -Visibility.Notify.Period.OnContinents = 1000 -Visibility.Notify.Period.InInstances = 1000 -Visibility.Notify.Period.InBGArenas = 1000 - -############################################################################### -# SERVER RATES -# -# Rate.Health -# Rate.Mana -# Rate.Rage.Income -# Rate.Rage.Loss -# Rate.RunicPower.Income -# Rate.RunicPower.Loss -# Rate.Focus -# Rate.Loyalty -# Health and power regeneration and rage income from damage. -# Default: 1 -# -# Rate.Skill.Discovery -# Skill Discovery Rates -# Default: 1 -# -# Rate.Drop.Item.Poor -# Rate.Drop.Item.Normal -# Rate.Drop.Item.Uncommon -# Rate.Drop.Item.Rare -# Rate.Drop.Item.Epic -# Rate.Drop.Item.Legendary -# Rate.Drop.Item.Artifact -# Rate.Drop.Item.Referenced -# Rate.Drop.Money -# Drop rates (items by quality and money) -# Default: 1 -# -# Rate.Drop.Money -# Drop rates -# Default: 1 -# -# Rate.XP.Kill -# Rate.XP.Quest -# Rate.XP.Explore -# XP rates -# Default: 1 -# -# Rate.RepairCost -# Repair cost rate -# Default: 1 - standard cost -# 2 - double cost -# 0.5 - half cost -# -# Rate.Rest.InGame -# Rate.Rest.Offline.InTavernOrCity -# Rate.Rest.Offline.InWilderness -# Resting points grow rates -# Default: 1 - standard rate -# 2 - double rate -# 0.5 - half rate -# -# Rate.Damage.Fall -# Damage after fall rate. -# Default: 1 - standard damage -# 2 - double damage -# 0.5 - half damage -# -# Rate.Auction.Time -# Rate.Auction.Deposit -# Rate.Auction.Cut -# Auction rates -# (auction time, deposit get at auction start, -# auction cut from price at auction end) -# -# Rate.Honor -# Honor gain rate -# -# Rate.Mining.Amount -# Rate.Mining.Next -# Mining Rates -# Mining.Amount changes minimum/maximum use times of a deposit, -# Mining.Next changes chance to have next use of a deposit -# -# Rate.Talent -# Talent Point rates -# Default: 1 -# -# Rate.Reputation.Gain -# Reputation Gain rate -# Default: 1 -# -# Rate.Reputation.LowLevel.Kill -# Reputation Gain from low level kill (grey creture) -# Default: 1 -# -# Rate.Reputation.LowLevel.Quest -# Reputation Gain rate -# Default: 1 -# -# Rate.MoveSpeed -# Multiply the default movement speed for players -# and whatever they're controlling. -# Default: 1 - no change -# 1.4 - 40% increase -# -# Rate.InstanceResetTime -# Multiplier for the number of days in between -# global raid/heroic instance resets. -# Default: 1 -# -# SkillGain.Crafting -# SkillGain.Defense -# SkillGain.Gathering -# SkillGain.Weapon -# Crafting/defense/gathering/weapon skills gain at skill grow (1,2,...) -# Default: 1 -# -# SkillChance.Orange -# SkillChance.Yellow -# SkillChance.Green -# SkillChance.Grey -# Skill chance values (0..100) -# Default: 100-75-25-0 -# -# SkillChance.MiningSteps -# SkillChance.SkinningSteps -# For skinning and Mining chance decrease with skill level. -# Default: 0 - no decrease -# 75 - in 2 times each 75 skill points -# -# DurabilityLoss.InPvP -# If true, players take durability loss on death in PvP. -# Default: 0 (false) -# 1 (true) -# -# DurabilityLoss.OnDeath -# Durability loss percentage on death -# Default: 10 - standard -# 20 - double -# 5 - half -# -# DurabilityLossChance.Damage -# Chance lost one from equiped items durability -# point at damage apply or receive. -# Default: 0.5 (100/0.5 = 200) -# Each 200 damage apply one from 19 possible equipped items -# -# DurabilityLossChance.Absorb -# Chance lost one from armor items durability point at damage absorb. -# Default: 0.5 (100/0.5 = 200) -# Each 200 absorbs apply one from 15 possible armor equipped items -# -# DurabilityLossChance.Parry -# Chance lost weapon durability point at parry. -# Default: 0.05 (100/0.05 = 2000) -# Each 2000 parry attacks main weapon lost point -# -# DurabilityLossChance.Block -# Chance lost sheild durability point at damage block. -# Default: 0.05 (100/0.05 = 2000) -# Each 2000 partly or full blocked attacks shield lost point -# -# Death.SicknessLevel -# Starting Character start gain sickness at spirit resurrection (1 min) -# Default: 11 -# -10 - character will have full time -# (10min) sickness at 1 level -# maxplayerlevel+1 -# - character will not have sickess at any level -# -# Death.CorpseReclaimDelay.PvP -# Death.CorpseReclaimDelay.PvE -# Enabled/disabled increase corpse reclaim delay at PvP/PvE deaths -# Default: 1 (enabled) -# 0 (disabled) -# -# Death.Bones.World -# Death.Bones.BattlegroundOrArena -# Enable/disable creating bones instead corpse at resurrection -# (in normal zones/instances, or battleground/arenas) -# Default: 1 (enabled) -# 0 (disabled) -# -# Die.Command.Mode -# Switch between two possible .die modes, where mode 1 kills -# and does not trigger anything such as loot, and mode 0 does -# damage and does trigger things such as loot -# Default: 1 -# 0 -# -############################################################################### - -Rate.Health = 1 -Rate.Mana = 1 -Rate.Rage.Income = 1 -Rate.Rage.Loss = 1 -Rate.RunicPower.Income = 1 -Rate.RunicPower.Loss = 1 -Rate.Focus = 1 -Rate.Loyalty = 1 -Rate.Skill.Discovery = 1 -Rate.Drop.Item.Poor = 1 -Rate.Drop.Item.Normal = 1 -Rate.Drop.Item.Uncommon = 1 -Rate.Drop.Item.Rare = 1 -Rate.Drop.Item.Epic = 1 -Rate.Drop.Item.Legendary = 1 -Rate.Drop.Item.Artifact = 1 -Rate.Drop.Item.Referenced = 1 -Rate.Drop.Money = 1 -Rate.XP.Kill = 1 -Rate.XP.Quest = 1 -Rate.XP.Explore = 1 -Rate.RepairCost = 1 -Rate.Rest.InGame = 1 -Rate.Rest.Offline.InTavernOrCity = 1 -Rate.Rest.Offline.InWilderness = 1 -Rate.Damage.Fall = 1 -Rate.Auction.Time = 1 -Rate.Auction.Deposit = 1 -Rate.Auction.Cut = 1 -Rate.Honor = 1 -Rate.Mining.Amount = 1 -Rate.Mining.Next = 1 -Rate.Talent = 1 -Rate.Reputation.Gain = 1 -Rate.Reputation.LowLevel.Kill = 1 -Rate.Reputation.LowLevel.Quest = 1 -Rate.MoveSpeed = 1 -Rate.InstanceResetTime = 1 -SkillGain.Crafting = 1 -SkillGain.Defense = 1 -SkillGain.Gathering = 1 -SkillGain.Weapon = 1 -SkillChance.Orange = 100 -SkillChance.Yellow = 75 -SkillChance.Green = 25 -SkillChance.Grey = 0 -SkillChance.MiningSteps = 0 -SkillChance.SkinningSteps = 0 -DurabilityLoss.InPvP = 0 -DurabilityLoss.OnDeath = 10 -DurabilityLossChance.Damage = 0.5 -DurabilityLossChance.Absorb = 0.5 -DurabilityLossChance.Parry = 0.05 -DurabilityLossChance.Block = 0.05 -Death.SicknessLevel = 11 -Death.CorpseReclaimDelay.PvP = 1 -Death.CorpseReclaimDelay.PvE = 0 -Death.Bones.World = 1 -Death.Bones.BattlegroundOrArena = 1 -Die.Command.Mode = 1 - -############################################################################### -# AUTO BROADCAST -# -# AutoBroadcast.On -# Enable auto broadcast -# Default: 0 - off -# 1 - on -# -# AutoBroadcast.Center -# Display method -# Default: 0 - announce -# 1 - notify -# 2 - both -# -# AutoBroadcast.Timer -# Timer for auto broadcast (in milliseconds) -# -############################################################################### - -AutoBroadcast.On = 0 -AutoBroadcast.Center = 0 -AutoBroadcast.Timer = 60000 - -############################################################################### -# BATTLEGROUND CONFIG -# -# Battleground.CastDeserter -# Cast Deserter spell at player who leave battleground in progress -# Default: 1 (enable) -# 0 (disable) -# -# Battleground.QueueAnnouncer.Enable -# Enable queue announcer posting to chat -# Default: 0 (disable) -# 1 (enable) -# -# Battleground.QueueAnnouncer.PlayerOnly -# Enable queue announcer posting to chat -# Default: 0 (disable) -# 1 (enable) -# -# Battleground.InvitationType -# Set Battleground invitation type -# Default: 0 (normal - invite as much players to bg as possible, -# don't bother with ballance) -# 1 (Experimental - don't allow to invite much more players -# of one faction) -# -# Battleground.PrematureFinishTimer -# The time to end the bg if there are less than MinPlayersPerTeam on -# one side (in milliseconds) -# Default: 300000 (5 minutes) -# 0 - disable (not recommended) -# -# BattleGround.PremadeGroupWaitForMatch -# The time in which premade group of 1 faction waits in BG Queue -# for premade group of other faction -# Default: 1800000 (30 minutes) -# 0 - disable (not recommended) -# -# Battleground.GiveXPForKills -# Give experience for honorable kills in battlegrounds -# Default: 0 (disable) -# 1 (enable) -# -# Battleground.Random.ResetHour -# Reset random battlegrounds at specified hour of the day (0-23) -# Default: 6 -# -############################################################################### - -Battleground.CastDeserter = 1 -Battleground.QueueAnnouncer.Enable = 0 -Battleground.QueueAnnouncer.PlayerOnly = 0 -Battleground.InvitationType = 0 -BattleGround.PrematureFinishTimer = 300000 -BattleGround.PremadeGroupWaitForMatch = 1800000 -Battleground.GiveXPForKills = 0 -Battleground.Random.ResetHour = 6 - -############################################################################### -# ARENA CONFIG -# -# Arena.MaxRatingDifference -# The maximum rating difference between two groups in rated matches -# Default: 150 (enable, recommended) -# 0 (disable, rating difference is discarded) -# -# Arena.RatingDiscardTimer -# After the specified milliseconds has passed, -# rating information will be discarded when selecting teams for -# matches also initiates an update by this timer -# Default: 600000 (10 minutes, recommended) -# 0 (disable) -# -# Arena.AutoDistributePoints -# Set if arena points should be distributed automatically, -# or by GM command -# Default: 0 (disable) (recommended): -# use gm command or sql query to distribute the points -# 1 (enable) arena points are distributed automatically -# -# Arena.AutoDistributeInterval -# How often should the distribution take place -# If automatic distribution is enabled in days -# Default: 7 (weekly) -# -# Arena.QueueAnnouncer.Enable -# Enable bg queue announcer posting to chat -# Default: 0 (disable) -# 1 (enable) -# -# Arena.ArenaSeason.ID -# Current area season id show in client -# Default: 1 -# -# Arena.ArenaSeason.InProgress -# Current area season state -# Default: 1 (active) -# 0 (finished) -# -# Arena.ArenaStartRating -# Start arena team command rating -# Default: 1500 -# -# Arena.StartPersonalRating -# Start personal rating on entry in team -# Default: 1500 -# -############################################################################### - -Arena.MaxRatingDifference = 150 -Arena.RatingDiscardTimer = 600000 -Arena.AutoDistributePoints = 0 -Arena.AutoDistributeInterval = 7 -Arena.QueueAnnouncer.Enable = 0 -Arena.QueueAnnouncer.PlayerOnly = 0 -Arena.ArenaSeason.ID = 1 -Arena.ArenaSeason.InProgress = 1 -Arena.ArenaStartRating = 0 -Arena.ArenaStartPersonalRating = 0 - -############################################################################### -# NETWORK CONFIG -# -# Network.Threads -# Number of threads for network, -# recommend 1 thread per 1000 connections. -# Default: 1 -# -# Network.OutKBuff -# The size of the output kernel buffer used -# ( SO_SNDBUF socket option, tcp manual ). -# Default: -1 (Use system default setting) -# -# Network.OutUBuff -# Userspace buffer for output. -# This is amount of memory reserved per each connection. -# Default: 65536 -# -# Network.TcpNoDelay: -# TCP Nagle algorithm setting -# Default: 0 (enable Nagle algorithm, less traffic, more latency) -# 1 (TCP_NO_DELAY, disable Nagle algorithm, -# more traffic but less latency) -# -############################################################################### - -Network.Threads = 1 -Network.OutKBuff = -1 -Network.OutUBuff = 65536 -Network.TcpNodelay = 1 - -############################################################################### -# AUCTION HOUSE BOT SETTINGS -# -# AuctionHouseBot.DEBUG -# Enable/Disable Debugging output -# Default 0 (disabled) -# -# AuctionHouseBot.DEBUG_FILTERS -# Enable/Disable Debugging output from Filters -# Default 0 (disabled) -# -# AuctionHouseBot.EnableSeller -# Enable/Disable the part of AHBot that puts items up for auction -# Default 0 (disabled) -# -# AuctionHouseBot.EnableBuyer -# Enable/Disable the part of AHBot that buys items from players -# Default 0 (disabled) -# -# AuctionHouseBot.UseBuyPriceForSeller -# Should the Seller use BuyPrice or SellPrice to determine Bid Prices -# Default 0 (use SellPrice) -# -# AuctionHouseBot.UseBuyPriceForBuyer -# Should the Buyer use BuyPrice or SellPrice to determine Bid Prices -# Default 0 (use SellPrice) -# -# Auction House Bot character data -# AuctionHouseBot.Account is the account number -# (in realmd->account table) of the player you want to run -# as the auction bot. -# AuctionHouseBot.GUID is the GUID (in characters->characters table) -# of the player you want to run as the auction bot. -# Default: 0 (Auction House Bot disabled) -# -# AuctionHouseBot.ItemsPerCycle -# Number of Items to Add/Remove from the AH during mass operations -# Default 200 -# -############################################################################### - -AuctionHouseBot.DEBUG = 0 -AuctionHouseBot.DEBUG_FILTERS = 0 -AuctionHouseBot.EnableSeller = 0 -AuctionHouseBot.EnableBuyer = 0 -AuctionHouseBot.UseBuyPriceForSeller = 0 -AuctionHouseBot.UseBuyPriceForBuyer = 0 -AuctionHouseBot.Account = 0 -AuctionHouseBot.GUID = 0 -AuctionHouseBot.ItemsPerCycle = 200 - -############################################################################### -# AUCTION HOUSE BOT FILTERS PART 1 -# -# AuctionHouseBot.VendorItems -# Include items that can be bought from vendors. -# Default 0 (False) -# -# AuctionHouseBot.VendorTradeGoods -# Include Trade Goods that can be bought from vendors. -# Default 0 (False) -# -# AuctionHouseBot.LootItems -# Include items that can be looted or fished for. -# Default 1 (True) -# -# AuctionHouseBot.LootTradeGoods -# Include Trade Goods that can be looted or fished for. -# Default 1 (True) -# -# AuctionHouseBot.OtherItems -# Include misc. items. -# Default 0 (False) -# -# AuctionHouseBot.OtherTradeGoods -# Include misc. Trade Goods. -# Default 0 (False) -# -# AuctionHouseBot.Bonding_types -# Indicates which bonding types to allow seller to put up for auction -# No_Bind -# Default 1 (True) -# Bind_When_Picked_Up -# Default 0 (False) -# Bind_When_Equipped -# Default 1 (True) -# Bind_When_Use -# Default 1 (True) -# Bind_Quest_Item -# Default 0 (False) -# -# AuctionHouseBot.DisableBeta_PTR_Unused -# Disable certain items that are usually unavailable to Players -# Default 0 (False) -# -# AuctionHouseBot.DisablePermEnchant -# Disable Items with a Permanent Enchantment -# Default 0 (False) -# -# AuctionHouseBot.DisableConjured -# Disable Conjured Items -# Default 0 (False) -# -# AuctionHouseBot.DisableGems -# Disable Gems -# Default 0 (False) -# -# AuctionHouseBot.DisableMoney -# Disable Items that are used as money -# Default 0 (False) -# -# AuctionHouseBot.DisableMoneyLoot -# Disable Items that have Money as a loot -# Default 0 (False) -# -# AuctionHouseBot.DisableLootable -# Disable Items that have other items as loot -# Default 0 (False) -# -# AuctionHouseBot.DisableKeys -# Disable Items that are keys -# Default 0 (False) -# -# AuctionHouseBot.DisableDuration -# Disable Items with a duration -# Default 0 (False) -# -# AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel -# Disable items that are BOP or Quest Item -# with a Required level that is less than the Item Level -# (This prevents a level 10 with a level 60 weapon or armor) -# (May need further refinement) -# Default 0 (False) -# -############################################################################### - -AuctionHouseBot.VendorItems = 0 -AuctionHouseBot.VendorTradeGoods = 0 -AuctionHouseBot.LootItems = 1 -AuctionHouseBot.LootTradeGoods = 1 -AuctionHouseBot.OtherItems = 0 -AuctionHouseBot.OtherTradeGoods = 0 -AuctionHouseBot.No_Bind = 1 -AuctionHouseBot.Bind_When_Picked_Up = 0 -AuctionHouseBot.Bind_When_Equipped = 1 -AuctionHouseBot.Bind_When_Use = 1 -AuctionHouseBot.Bind_Quest_Item = 0 -AuctionHouseBot.DisableBeta_PTR_Unused = 0 -AuctionHouseBot.DisablePermEnchant = 0 -AuctionHouseBot.DisableConjured = 0 -AuctionHouseBot.DisableGems = 0 -AuctionHouseBot.DisableMoney = 0 -AuctionHouseBot.DisableMoneyLoot = 0 -AuctionHouseBot.DisableLootable = 0 -AuctionHouseBot.DisableKeys = 0 -AuctionHouseBot.DisableDuration = 0 -AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel = 0 - -############################################################################### -# AUCTION HOUSE BOT FILTERS PART 2 -# -# These Filters are boolean (0 or 1) and will disable items that are -# specifically meant for the Class named. -# (UnusedClass is Class 10, which was skipped for some reason) -# Default 0 (allowed) -# -############################################################################### - -AuctionHouseBot.DisableWarriorItems = 0 -AuctionHouseBot.DisablePaladinItems = 0 -AuctionHouseBot.DisableHunterItems = 0 -AuctionHouseBot.DisableRogueItems = 0 -AuctionHouseBot.DisablePriestItems = 0 -AuctionHouseBot.DisableDKItems = 0 -AuctionHouseBot.DisableShamanItems = 0 -AuctionHouseBot.DisableMageItems = 0 -AuctionHouseBot.DisableWarlockItems = 0 -AuctionHouseBot.DisableUnusedClassItems = 0 -AuctionHouseBot.DisableDruidItems = 0 - -############################################################################### -# AUCTION HOUSE BOT FILTERS PART 3 -# -# AuctionHouseBot.DisableItemsBelowLevel -# Prevent Seller from listing Items below this Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsAboveLevel -# Prevent Seller from listing Items above this Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsBelowLevel -# Prevent Seller from listing Trade Goods below this Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsAboveLevel -# Prevent Seller from listing Trade Goods above this Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsBelowGUID -# Prevent Seller from listing Items below this GUID -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsAboveGUID -# Prevent Seller from listing Items above this GUID -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsBelowGUID -# Prevent Seller from listing Trade Goods below this GUID -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsAboveGUID -# Prevent Seller from listing Trade Goods above this GUID -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsBelowReqLevel -# Prevent Seller from listing Items below this Required Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsAboveReqLevel -# Prevent Seller from listing Items above this Required Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsBelowReqLevel -# Prevent Seller from listing Trade Goods below this Required Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsAboveReqLevel -# Prevent Seller from listing Trade Goods above this Required Level -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsBelowReqSkillRank -# Prevent Seller from listing Items below this Required Skill Rank -# Default 0 (Off) -# -# AuctionHouseBot.DisableItemsAboveReqSkillRank -# Prevent Seller from listing Items above this Required Skill Rank -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsBelowReqSkillRank -# Prevent Seller from listing Trade Goods below this Required Skill Rank -# Default 0 (Off) -# -# AuctionHouseBot.DisableTGsAboveReqSkillRank -# Prevent Seller from listing Trade Goods above this Required Skill Rank -# Default 0 (Off) -# -############################################################################### - -AuctionHouseBot.DisableItemsBelowLevel = 0 -AuctionHouseBot.DisableItemsAboveLevel = 0 -AuctionHouseBot.DisableTGsBelowLevel = 0 -AuctionHouseBot.DisableTGsAboveLevel = 0 -AuctionHouseBot.DisableItemsBelowGUID = 0 -AuctionHouseBot.DisableItemsAboveGUID = 0 -AuctionHouseBot.DisableTGsBelowGUID = 0 -AuctionHouseBot.DisableTGsAboveGUID = 0 -AuctionHouseBot.DisableItemsBelowReqLevel = 0 -AuctionHouseBot.DisableItemsAboveReqLevel = 0 -AuctionHouseBot.DisableTGsBelowReqLevel = 0 -AuctionHouseBot.DisableTGsAboveReqLevel = 0 -AuctionHouseBot.DisableItemsBelowReqSkillRank = 0 -AuctionHouseBot.DisableItemsAboveReqSkillRank = 0 -AuctionHouseBot.DisableTGsBelowReqSkillRank = 0 -AuctionHouseBot.DisableTGsAboveReqSkillRank = 0 - -############################################################################### -# CONSOLE AND REMOTE ACCESS -# -# Console.Enable -# Enable console -# Default: 1 - on -# 0 - off -# -# Ra.Enable -# Enable remote console -# Default: 0 - off -# 1 - on -# -# Ra.IP -# Default remote console ip address, use 0.0.0.0 for every address -# -# Ra.Port -# Default remote console port -# -# Ra.MinLevel -# Minimum level that's required to login,3 by default -# -# Ra.Secure -# Kick client on wrong pass -# -############################################################################### - -Console.Enable = 1 -Ra.Enable = 0 -Ra.IP = 0.0.0.0 -Ra.Port = 3443 -Ra.MinLevel = 3 -Ra.Secure = 1 - -############################################################################### -# CUSTOM SERVER OPTIONS -# -# PlayerStart.AllReputation -# Players will start with most of the high level reputations that are -# needed for items, mounts etc. -# -# PlayerStart.AllSpells -# If enabled, players will start with all their class spells -# (not talents). Useful for instant 80 servers. -# You must populate playercreateinfo_spell_custom table with the spells -# you want, or this WILL NOT WORK! The table has data for all -# classes / races up to TBC expansion. -# Do not enable if you do not know what you are doing! -# Default: 0 - off -# 1 - on -# -# -# PlayerStart.MapsExplored -# Players will start with all maps explored if enabled -# -# MusicInBattleground -# If enabled "L70ETC-Power of the horde" will be played when BG starts -# -# HonorPointsAfterDuel -# The amount of honor points the duel winner will get after a duel. -# Default: 0 - disable -# -# AlwaysMaxWeaponSkill -# Players will automatically gain max weapon/defense skill when -# logging in, leveling up etc. -# -# PvPToken.Enable -# Enable/disable PvP Token System. Players will get a token -# after slaying another player that gives honor. -# -# PvPToken.MapAllowType -# Where players can receive the pvp token -# 4 - In all maps -# 3 - In battlegrounds only -# 2 - In FFA areas only (gurubashi arena etc) -# 1 - In battlegrounds AND FFA areas only -# -# PvPToken.ItemID -# The item players will get after killing someone -# if PvP Token system is enabled. -# Default: 29434 - Badge of justice -# -# PvPToken.ItemCount -# Modify the item ID count - Default: 1 -# -# NoResetTalentsCost -# Enable or disable no cost when reseting talents -# -# Guild.AllowMultipleGuildMaster -# Allow override of 1 Guild Master limit. Additional Guild Masters must -# be set using the ".guild rank" command, not through the UI -# Default: 0 = Only 1 Guild Master per guild -# 1 = Allow more than one Guild Master -# -# ForbiddenMaps -# Map ids that users below SEC_GAMEMASTER cannot enter, -# with delimiter ',' -# Default: "" -# example: "538,90" -# Note that it's HIGHLY DISCOURAGED to forbid starting maps -# (0, 1, 530)! -# -# ShowKickInWorld -# Determines wether a message is broadcasted to the entire server -# when a player gets kicked -# Default: 0 = Disable -# 1 = Enable -# -# RecordUpdateTimeDiffInterval -# Record update time diff to the log file -# update diff can be used as a criterion of performance -# diff < 300: good performance -# diff > 600: bad performance, may be caused by high cpu usage -# Default: 60000 (diff is written into log every 60000 ms or 1 minute. -# >0 = Interval -# 0 = Disable -# -# MinRecordUpdateTimeDiff -# Only record update time diff which is greater than this value -# Default: 10 -# -# PlayerStart.String -# If set to anything other than "", this string will be displayed -# to players when they login to a newly created character. -# Default: "" - send no text -# -# LevelReq.Trade -# The required level of character to be able to trade -# Default: 1 (From level 1) -# -# LevelReq.Ticket -# The required level of character to be able to write tickets -# Default: 1 (From level 1) -# -# LevelReq.Auction -# The required level of character to be able to use auction -# Default: 1 (From level 1) -# -# LevelReq.Mail -# The required level of character to be able to send and receive mail -# Default: 1 (From level 1) -# -############################################################################### - -PlayerStart.AllReputation = 0 -PlayerStart.AllSpells = 0 -PlayerStart.MapsExplored = 0 -MusicInBattleground = 0 -HonorPointsAfterDuel = 0 -AlwaysMaxWeaponSkill = 0 -PvPToken.Enable = 0 -PvPToken.MapAllowType = 4 -PvPToken.ItemID = 29434 -PvPToken.ItemCount = 1 -Guild.AllowMultipleGuildMaster = 0 -NoResetTalentsCost = 0 -ShowKickInWorld = 0 -RecordUpdateTimeDiffInterval = 60000 -MinRecordUpdateTimeDiff = 100 -PlayerStart.String = "" -LevelReq.Trade = 1 -LevelReq.Ticket = 1 -LevelReq.Auction = 1 -LevelReq.Mail = 1 diff --git a/src/server/trinityrealm/AuthCodes.cpp b/src/server/trinityrealm/AuthCodes.cpp deleted file mode 100644 index 812949e0823..00000000000 --- a/src/server/trinityrealm/AuthCodes.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "AuthCodes.h" - -namespace AuthHelper -{ - -bool IsPreBCAcceptedClientBuild(int build) -{ - int accepted_versions[] = PRE_BC_ACCEPTED_CLIENT_BUILD; - for (int i = 0; accepted_versions[i]; ++i) - { - if (build == accepted_versions[i]) - { - return true; - } - } - return false; -} - -bool IsPostBCAcceptedClientBuild(int build) -{ - int accepted_versions[] = POST_BC_ACCEPTED_CLIENT_BUILD; - for (int i = 0; accepted_versions[i]; ++i) - { - if (build == accepted_versions[i]) - { - return true; - } - } - return false; -} - -bool IsAcceptedClientBuild(int build) -{ - return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); -} - -}; diff --git a/src/server/trinityrealm/AuthCodes.h b/src/server/trinityrealm/AuthCodes.h deleted file mode 100644 index eb6e4abfb08..00000000000 --- a/src/server/trinityrealm/AuthCodes.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup realmd -*/ - -#ifndef _AUTHCODES_H -#define _AUTHCODES_H - -enum AuthResult -{ - WOW_SUCCESS = 0x00, - WOW_FAIL_UNKNOWN0 = 0x01, ///< ? Unable to connect - WOW_FAIL_UNKNOWN1 = 0x02, ///< ? Unable to connect - WOW_FAIL_BANNED = 0x03, ///< This account has been closed and is no longer available for use. Please go to /banned.html for further information. - WOW_FAIL_UNKNOWN_ACCOUNT = 0x04, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information - WOW_FAIL_INCORRECT_PASSWORD = 0x05, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see for more information - WOW_FAIL_ALREADY_ONLINE = 0x06, ///< This account is already logged into . Please check the spelling and try again. - WOW_FAIL_NO_TIME = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing - WOW_FAIL_DB_BUSY = 0x08, ///< Could not log in to at this time. Please try again later. - WOW_FAIL_VERSION_INVALID = 0x09, ///< Unable to validate game version. This may be caused by file corruption or interference of another program. Please visit for more information and possible solutions to this issue. - WOW_FAIL_VERSION_UPDATE = 0x0A, ///< Downloading - WOW_FAIL_INVALID_SERVER = 0x0B, ///< Unable to connect - WOW_FAIL_SUSPENDED = 0x0C, ///< This account has been temporarily suspended. Please go to /banned.html for further information - WOW_FAIL_FAIL_NOACCESS = 0x0D, ///< Unable to connect - WOW_SUCCESS_SURVEY = 0x0E, ///< Connected. - WOW_FAIL_PARENTCONTROL = 0x0F, ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at - WOW_FAIL_LOCKED_ENFORCED = 0x10, ///< You have applied a lock to your account. You can change your locked status by calling your account lock phone number. - WOW_FAIL_TRIAL_ENDED = 0x11, ///< Your trial subscription has expired. Please visit to upgrade your account. - WOW_FAIL_USE_BATTLENET = 0x12, ///< WOW_FAIL_OTHER This account is now attached to a Battle.net account. Please login with your Battle.net account email address and password. -}; - -enum LoginResult -{ - LOGIN_OK = 0x00, - LOGIN_FAILED = 0x01, - LOGIN_FAILED2 = 0x02, - LOGIN_BANNED = 0x03, - LOGIN_UNKNOWN_ACCOUNT = 0x04, - LOGIN_UNKNOWN_ACCOUNT3 = 0x05, - LOGIN_ALREADYONLINE = 0x06, - LOGIN_NOTIME = 0x07, - LOGIN_DBBUSY = 0x08, - LOGIN_BADVERSION = 0x09, - LOGIN_DOWNLOAD_FILE = 0x0A, - LOGIN_FAILED3 = 0x0B, - LOGIN_SUSPENDED = 0x0C, - LOGIN_FAILED4 = 0x0D, - LOGIN_CONNECTED = 0x0E, - LOGIN_PARENTALCONTROL = 0x0F, - LOGIN_LOCKED_ENFORCED = 0x10, -}; - -//multirealm supported versions: -//1.12.1 build 5875 -//1.12.2 build 6005 -//2.4.3 build 8606 -//3.1.3 build 9947 -//3.1.3 build 10146 Chinese build -//3.2.2a build 10505 -//3.3.0a build 11159 -//3.3.2 build 11403 -//3.3.3a build 11723 - -#define POST_BC_ACCEPTED_CLIENT_BUILD {11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0} -#define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0} - -#define POST_BC_EXP_FLAG 0x2 -#define PRE_BC_EXP_FLAG 0x1 -#define NO_VALID_EXP_FLAG 0x0 - -namespace AuthHelper -{ - bool IsAcceptedClientBuild(int build); - bool IsPostBCAcceptedClientBuild(int build); - bool IsPreBCAcceptedClientBuild(int build); -}; - -#endif diff --git a/src/server/trinityrealm/AuthSocket.cpp b/src/server/trinityrealm/AuthSocket.cpp deleted file mode 100644 index cc293097977..00000000000 --- a/src/server/trinityrealm/AuthSocket.cpp +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup realmd -*/ - -#include "Common.h" -#include "Database/DatabaseEnv.h" -#include "ByteBuffer.h" -#include "Config/ConfigEnv.h" -#include "Log.h" -#include "RealmList.h" -#include "AuthSocket.h" -#include "AuthCodes.h" -#include -#include "Auth/Sha1.h" -//#include "Util.h" -- for commented utf8ToUpperOnlyLatin - -extern DatabaseType LoginDatabase; - -#define ChunkSize 2048 - -enum eAuthCmd -{ - //AUTH_NO_CMD = 0xFF, - AUTH_LOGON_CHALLENGE = 0x00, - AUTH_LOGON_PROOF = 0x01, - AUTH_RECONNECT_CHALLENGE = 0x02, - AUTH_RECONNECT_PROOF = 0x03, - //update srv =4 - REALM_LIST = 0x10, - XFER_INITIATE = 0x30, - XFER_DATA = 0x31, - XFER_ACCEPT = 0x32, - XFER_RESUME = 0x33, - XFER_CANCEL = 0x34 -}; - -enum eStatus -{ - STATUS_CONNECTED = 0, - STATUS_AUTHED -}; - -// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some paltform -#if defined(__GNUC__) -#pragma pack(1) -#else -#pragma pack(push,1) -#endif - -typedef struct AUTH_LOGON_CHALLENGE_C -{ - uint8 cmd; - uint8 error; - uint16 size; - uint8 gamename[4]; - uint8 version1; - uint8 version2; - uint8 version3; - uint16 build; - uint8 platform[4]; - uint8 os[4]; - uint8 country[4]; - uint32 timezone_bias; - uint32 ip; - uint8 I_len; - uint8 I[1]; -} sAuthLogonChallenge_C; - -typedef struct AUTH_LOGON_PROOF_C -{ - uint8 cmd; - uint8 A[32]; - uint8 M1[20]; - uint8 crc_hash[20]; - uint8 number_of_keys; - uint8 securityFlags; // 0x00-0x04 -} sAuthLogonProof_C; - -typedef struct AUTH_LOGON_PROOF_S -{ - uint8 cmd; - uint8 error; - uint8 M2[20]; - uint32 unk1; - uint32 unk2; - uint16 unk3; -} sAuthLogonProof_S; - -typedef struct AUTH_LOGON_PROOF_S_OLD -{ - uint8 cmd; - uint8 error; - uint8 M2[20]; - //uint32 unk1; - uint32 unk2; - //uint16 unk3; -} sAuthLogonProof_S_Old; - -typedef struct AUTH_RECONNECT_PROOF_C -{ - uint8 cmd; - uint8 R1[16]; - uint8 R2[20]; - uint8 R3[20]; - uint8 number_of_keys; -} sAuthReconnectProof_C; - -typedef struct XFER_INIT -{ - uint8 cmd; // XFER_INITIATE - uint8 fileNameLen; // strlen(fileName); - uint8 fileName[5]; // fileName[fileNameLen] - uint64 file_size; // file size (bytes) - uint8 md5[MD5_DIGEST_LENGTH]; // MD5 -} XFER_INIT; - -typedef struct XFER_DATA -{ - uint8 opcode; - uint16 data_size; - uint8 data[ChunkSize]; -} XFER_DATA_STRUCT; - -typedef struct AuthHandler -{ - eAuthCmd cmd; - uint32 status; - bool (AuthSocket::*handler)(void); -} AuthHandler; - -// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform -#if defined(__GNUC__) -#pragma pack() -#else -#pragma pack(pop) -#endif - -/// Launch a thread to transfer a patch to the client -class PatcherRunnable: public ACE_Based::Runnable -{ - public: - PatcherRunnable(class AuthSocket *); - void run(); - - private: - AuthSocket * mySocket; -}; - -typedef struct PATCH_INFO -{ - uint8 md5[MD5_DIGEST_LENGTH]; -} PATCH_INFO; - -/// Caches MD5 hash of client patches present on the server -class Patcher -{ - public: - typedef std::map Patches; - ~Patcher(); - Patcher(); - Patches::const_iterator begin() const { return _patches.begin(); } - Patches::const_iterator end() const { return _patches.end(); } - void LoadPatchMD5(char*); - bool GetHash(char * pat,uint8 mymd5[16]); - - private: - void LoadPatchesInfo(); - Patches _patches; -}; - -const AuthHandler table[] = -{ - { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge }, - { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof }, - { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge}, - { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof }, - { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList }, - { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept }, - { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume }, - { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel } -}; - -#define AUTH_TOTAL_COMMANDS sizeof(table)/sizeof(AuthHandler) - -///Holds the MD5 hash of client patches present on the server -Patcher PatchesCache; - -/// Constructor - set the N and g values for SRP6 -AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket) -{ - N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword(7); - _authed = false; - _accountSecurityLevel = SEC_PLAYER; -} - -/// Close patch file descriptor before leaving -AuthSocket::~AuthSocket(void) -{ -} - -/// Accept the connection and set the s random value for SRP6 -void AuthSocket::OnAccept(void) -{ - sLog.outBasic("Accepting connection from '%s'", socket().get_remote_address().c_str()); -} - -void AuthSocket::OnClose(void) -{ - sLog.outDebug("AuthSocket::OnClose"); -} - -/// Read the packet from the client -void AuthSocket::OnRead() -{ - uint8 _cmd; - while (1) - { - if (!socket().recv_soft((char *)&_cmd, 1)) - return; - - size_t i; - - ///- Circle through known commands and call the correct command handler - for (i = 0; i < AUTH_TOTAL_COMMANDS; ++i) - { - if ((uint8)table[i].cmd == _cmd && - (table[i].status == STATUS_CONNECTED || - (_authed && table[i].status == STATUS_AUTHED))) - { - DEBUG_LOG("[Auth] got data for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len()); - - if (!(*this.*table[i].handler)()) - { - DEBUG_LOG("Command handler failed for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len()); - return; - } - break; - } - } - - // Report unknown packets in the error log - if (i == AUTH_TOTAL_COMMANDS) - { - sLog.outError("[Auth] got unknown packet from '%s'", socket().get_remote_address().c_str()); - socket().shutdown(); - return; - } - } -} - -/// Make the SRP6 calculation from hash in dB -void AuthSocket::_SetVSFields(const std::string& rI) -{ - s.SetRand(s_BYTE_SIZE * 8); - - BigNumber I; - I.SetHexStr(rI.c_str()); - - // In case of leading zeros in the rI hash, restore them - uint8 mDigest[SHA_DIGEST_LENGTH]; - memset(mDigest, 0, SHA_DIGEST_LENGTH); - if (I.GetNumBytes() <= SHA_DIGEST_LENGTH) - memcpy(mDigest, I.AsByteArray(), I.GetNumBytes()); - - std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH); - - Sha1Hash sha; - sha.UpdateData(s.AsByteArray(), s.GetNumBytes()); - sha.UpdateData(mDigest, SHA_DIGEST_LENGTH); - sha.Finalize(); - BigNumber x; - x.SetBinary(sha.GetDigest(), sha.GetLength()); - v = g.ModExp(x, N); - // No SQL injection (username escaped) - const char *v_hex, *s_hex; - v_hex = v.AsHexStr(); - s_hex = s.AsHexStr(); - LoginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '%s'", v_hex, s_hex, _safelogin.c_str()); - OPENSSL_free((void*)v_hex); - OPENSSL_free((void*)s_hex); -} - -/// Logon Challenge command handler -bool AuthSocket::_HandleLogonChallenge() -{ - DEBUG_LOG("Entering _HandleLogonChallenge"); - if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) - return false; - - ///- Read the first 4 bytes (header) to get the length of the remaining of the packet - std::vector buf; - buf.resize(4); - - socket().recv((char *)&buf[0], 4); - - EndianConvert(*((uint16*)(buf[0]))); - uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; - DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining); - - if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) - return false; - - //No big fear of memory outage (size is int16, i.e. < 65536) - buf.resize(remaining + buf.size() + 1); - buf[buf.size() - 1] = 0; - sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; - - ///- Read the remaining of the packet - socket().recv((char *)&buf[4], remaining); - DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); - DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); - - // BigEndian code, nop in little endian case - // size already converted - EndianConvert(*((uint32*)(&ch->gamename[0]))); - EndianConvert(ch->build); - EndianConvert(*((uint32*)(&ch->platform[0]))); - EndianConvert(*((uint32*)(&ch->os[0]))); - EndianConvert(*((uint32*)(&ch->country[0]))); - EndianConvert(ch->timezone_bias); - EndianConvert(ch->ip); - - ByteBuffer pkt; - - _login = (const char*)ch->I; - _build = ch->build; - _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) + (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); - - ///- Normalize account name - //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form - - //Escape the user login to avoid further SQL injection - //Memory will be freed on AuthSocket object destruction - _safelogin = _login; - LoginDatabase.escape_string(_safelogin); - - _build = ch->build; - - pkt << (uint8) AUTH_LOGON_CHALLENGE; - pkt << (uint8) 0x00; - - ///- Verify that this IP is not in the ip_banned table - // No SQL injection possible (paste the IP address as passed by the socket) - LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - - std::string address(socket().get_remote_address().c_str()); - LoginDatabase.escape_string(address); - QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); - if (result) - { - pkt << (uint8)WOW_FAIL_BANNED; - sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!", address.c_str ()); - } - else - { - ///- Get the account details from the account table - // No SQL injection (escaped user name) - - result = LoginDatabase.PQuery("SELECT a.sha_pass_hash,a.id,a.locked,a.last_ip,aa.gmlevel,a.v,a.s " - "FROM account a " - "LEFT JOIN account_access aa " - "ON (a.id = aa.id) " - "WHERE a.username = '%s'",_safelogin.c_str ()); - if (result) - { - ///- If the IP is 'locked', check that the player comes indeed from the correct IP address - bool locked = false; - if ((*result)[2].GetUInt8() == 1) // if ip is locked - { - DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); - DEBUG_LOG("[AuthChallenge] Player address is '%s'", socket().get_remote_address().c_str()); - if (strcmp((*result)[3].GetString(),socket().get_remote_address().c_str())) - { - DEBUG_LOG("[AuthChallenge] Account IP differs"); - pkt << (uint8) WOW_FAIL_SUSPENDED; - locked=true; - } - else - DEBUG_LOG("[AuthChallenge] Account IP matches"); - } - else - DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); - - if (!locked) - { - //set expired bans to inactive - LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - ///- If the account is banned, reject the logon attempt - QueryResult_AutoPtr banresult = LoginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); - if (banresult) - { - if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) - { - pkt << (uint8) WOW_FAIL_BANNED; - sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); - } - else - { - pkt << (uint8) WOW_FAIL_SUSPENDED; - sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); - } - } - else - { - ///- Get the password from the account table, upper it, and make the SRP6 calculation - std::string rI = (*result)[0].GetCppString(); - - ///- Don't calculate (v, s) if there are already some in the database - std::string databaseV = (*result)[5].GetCppString(); - std::string databaseS = (*result)[6].GetCppString(); - - sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); - - // multiply with 2, bytes are stored as hexstring - if (databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2) - _SetVSFields(rI); - else - { - s.SetHexStr(databaseS.c_str()); - v.SetHexStr(databaseV.c_str()); - } - - b.SetRand(19 * 8); - BigNumber gmod = g.ModExp(b, N); - B = ((v * 3) + gmod) % N; - - ASSERT(gmod.GetNumBytes() <= 32); - - BigNumber unk3; - unk3.SetRand(16 * 8); - - ///- Fill the response packet with the result - pkt << uint8(WOW_SUCCESS); - - // B may be calculated < 32B so we force minimal length to 32B - pkt.append(B.AsByteArray(32), 32); // 32 bytes - pkt << uint8(1); - pkt.append(g.AsByteArray(), 1); - pkt << uint8(32); - pkt.append(N.AsByteArray(32), 32); - pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes - pkt.append(unk3.AsByteArray(16), 16); - uint8 securityFlags = 0; - pkt << uint8(securityFlags); // security flags (0x0...0x04) - - if (securityFlags & 0x01) // PIN input - { - pkt << uint32(0); - pkt << uint64(0) << uint64(0); // 16 bytes hash? - } - - if (securityFlags & 0x02) // Matrix input - { - pkt << uint8(0); - pkt << uint8(0); - pkt << uint8(0); - pkt << uint8(0); - pkt << uint64(0); - } - - if (securityFlags & 0x04) // Security token input - pkt << uint8(1); - - uint8 secLevel = (*result)[4].GetUInt8(); - _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; - - _localizationName.resize(4); - for (int i = 0; i < 4; ++i) - _localizationName[i] = ch->country[4-i-1]; - - sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)); - } - } - } - else //no account - { - pkt<< (uint8) WOW_FAIL_UNKNOWN_ACCOUNT; - } - } - - socket().send((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Logon Proof command handler -bool AuthSocket::_HandleLogonProof() -{ - DEBUG_LOG("Entering _HandleLogonProof"); - ///- Read the packet - sAuthLogonProof_C lp; - - if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) - return false; - - ///
    • If the client has no valid version - if (_expversion == NO_VALID_EXP_FLAG) - { - ///- Check if we have the appropriate patch on the disk - - sLog.outDebug("Client with invalid version, patching is not implemented"); - socket().shutdown(); - return true; - } - ///
    - - ///- Continue the SRP6 calculation based on data received from the client - BigNumber A; - - A.SetBinary(lp.A, 32); - - // SRP safeguard: abort if A==0 - if (A.isZero()) - { - socket().shutdown(); - return true; - } - - Sha1Hash sha; - sha.UpdateBigNumbers(&A, &B, NULL); - sha.Finalize(); - BigNumber u; - u.SetBinary(sha.GetDigest(), 20); - BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); - - uint8 t[32]; - uint8 t1[16]; - uint8 vK[40]; - memcpy(t, S.AsByteArray(32), 32); - for (int i = 0; i < 16; ++i) - { - t1[i] = t[i * 2]; - } - sha.Initialize(); - sha.UpdateData(t1, 16); - sha.Finalize(); - for (int i = 0; i < 20; ++i) - { - vK[i * 2] = sha.GetDigest()[i]; - } - for (int i = 0; i < 16; ++i) - { - t1[i] = t[i * 2 + 1]; - } - sha.Initialize(); - sha.UpdateData(t1, 16); - sha.Finalize(); - for (int i = 0; i < 20; ++i) - { - vK[i * 2 + 1] = sha.GetDigest()[i]; - } - K.SetBinary(vK, 40); - - uint8 hash[20]; - - sha.Initialize(); - sha.UpdateBigNumbers(&N, NULL); - sha.Finalize(); - memcpy(hash, sha.GetDigest(), 20); - sha.Initialize(); - sha.UpdateBigNumbers(&g, NULL); - sha.Finalize(); - for (int i = 0; i < 20; ++i) - { - hash[i] ^= sha.GetDigest()[i]; - } - BigNumber t3; - t3.SetBinary(hash, 20); - - sha.Initialize(); - sha.UpdateData(_login); - sha.Finalize(); - uint8 t4[SHA_DIGEST_LENGTH]; - memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); - - sha.Initialize(); - sha.UpdateBigNumbers(&t3, NULL); - sha.UpdateData(t4, SHA_DIGEST_LENGTH); - sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); - sha.Finalize(); - BigNumber M; - M.SetBinary(sha.GetDigest(), 20); - - ///- Check if SRP6 results match (password is correct), else send an error - if (!memcmp(M.AsByteArray(), lp.M1, 20)) - { - sLog.outBasic("User '%s' successfully authenticated", _login.c_str()); - - ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account - // No SQL injection (escaped user name) and IP address as received by socket - const char* K_hex = K.AsHexStr(); - LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, socket().get_remote_address().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str()); - OPENSSL_free((void*)K_hex); - - ///- Finish SRP6 and send the final result to the client - sha.Initialize(); - sha.UpdateBigNumbers(&A, &M, &K, NULL); - sha.Finalize(); - - if (_expversion & POST_BC_EXP_FLAG)//2.4.3 and 3.1.3 clients (10146 is Chinese build for 3.1.3) - { - sAuthLogonProof_S proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk1 = 0x00800000; - proof.unk2 = 0x00; - proof.unk3 = 0x00; - socket().send((char *)&proof, sizeof(proof)); - } - else - { - sAuthLogonProof_S_Old proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - //proof.unk1 = 0x00800000; - proof.unk2 = 0x00; - //proof.unk3 = 0x00; - socket().send((char *)&proof, sizeof(proof)); - } - - ///- Set _authed to true! - _authed = true; - } - else - { - char data[4]= { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0}; - socket().send(data, sizeof(data)); - sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ()); - - uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); - if (MaxWrongPassCount > 0) - { - //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP - LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str()); - - if (QueryResult_AutoPtr loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str())) - { - Field* fields = loginfail->Fetch(); - uint32 failed_logins = fields[1].GetUInt32(); - - if (failed_logins >= MaxWrongPassCount) - { - uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); - bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); - - if (WrongPassBanType) - { - uint32 acc_id = fields[0].GetUInt32(); - LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)", - acc_id, WrongPassBanTime); - sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", - _login.c_str(), WrongPassBanTime, failed_logins); - } - else - { - std::string current_ip(socket().get_remote_address().c_str()); - LoginDatabase.escape_string(current_ip); - LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')", - current_ip.c_str(), WrongPassBanTime); - sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", - current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); - } - } - } - } - } - - return true; -} - -/// Reconnect Challenge command handler -bool AuthSocket::_HandleReconnectChallenge() -{ - DEBUG_LOG("Entering _HandleReconnectChallenge"); - if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) - return false; - - ///- Read the first 4 bytes (header) to get the length of the remaining of the packet - std::vector buf; - buf.resize(4); - - socket().recv((char *)&buf[0], 4); - - EndianConvert(*((uint16*)(buf[0]))); - uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; - DEBUG_LOG("[ReconnectChallenge] got header, body is %#04x bytes", remaining); - - if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) - return false; - - //No big fear of memory outage (size is int16, i.e. < 65536) - buf.resize(remaining + buf.size() + 1); - buf[buf.size() - 1] = 0; - sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; - - ///- Read the remaining of the packet - socket().recv((char *)&buf[4], remaining); - DEBUG_LOG("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); - DEBUG_LOG("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); - - _login = (const char*)ch->I; - _safelogin = _login; - - QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ()); - - // Stop if the account is not found - if (!result) - { - sLog.outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str()); - socket().shutdown(); - return false; - } - - Field* fields = result->Fetch (); - K.SetHexStr (fields[0].GetString ()); - - ///- Sending response - ByteBuffer pkt; - pkt << (uint8) AUTH_RECONNECT_CHALLENGE; - pkt << (uint8) 0x00; - _reconnectProof.SetRand(16 * 8); - pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random - pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros - socket().send((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Reconnect Proof command handler -bool AuthSocket::_HandleReconnectProof() -{ - DEBUG_LOG("Entering _HandleReconnectProof"); - ///- Read the packet - sAuthReconnectProof_C lp; - if (!socket().recv((char *)&lp, sizeof(sAuthReconnectProof_C))) - return false; - - if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) - return false; - - BigNumber t1; - t1.SetBinary(lp.R1, 16); - - Sha1Hash sha; - sha.Initialize(); - sha.UpdateData(_login); - sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); - sha.Finalize(); - - if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) - { - ///- Sending response - ByteBuffer pkt; - pkt << (uint8) AUTH_RECONNECT_PROOF; - pkt << (uint8) 0x00; - pkt << (uint16) 0x00; // 2 bytes zeros - socket().send((char const*)pkt.contents(), pkt.size()); - - ///- Set _authed to true! - _authed = true; - - return true; - } - else - { - sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str()); - socket().shutdown(); - return false; - } -} - -/// %Realm List command handler -bool AuthSocket::_HandleRealmList() -{ - DEBUG_LOG("Entering _HandleRealmList"); - if (socket().recv_len() < 5) - return false; - - socket().recv_skip(5); - - ///- Get the user id (else close the connection) - // No SQL injection (escaped user name) - - QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",_safelogin.c_str()); - if (!result) - { - sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str()); - socket().shutdown(); - return false; - } - - uint32 id = (*result)[0].GetUInt32(); - - ///- Update realm list if need - sRealmList->UpdateIfNeed(); - - ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) - ByteBuffer pkt; - - size_t RealmListSize = 0; - for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) - { - // don't work with realms which not compatible with the client - if (_expversion & POST_BC_EXP_FLAG) // 2.4.3 and 3.1.3 cliens - { - if (i->second.gamebuild != _build) - continue; - } - else if (_expversion & PRE_BC_EXP_FLAG) // 1.12.1 and 1.12.2 clients are compatible with eachother - { - if (!AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) - continue; - } - - uint8 AmountOfCharacters; - - // No SQL injection. id of realm is controlled by the database. - result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id); - if (result) - { - Field *fields = result->Fetch(); - AmountOfCharacters = fields[0].GetUInt8(); - } - else - AmountOfCharacters = 0; - - uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; - - pkt << i->second.icon; // realm type - if ( _expversion & POST_BC_EXP_FLAG )//only 2.4.3 and 3.1.3 cliens - pkt << lock; // if 1, then realm locked - pkt << i->second.color; // if 2, then realm is offline - pkt << i->first; - pkt << i->second.address; - pkt << i->second.populationLevel; - pkt << AmountOfCharacters; - pkt << i->second.timezone; // realm category - if ( _expversion & POST_BC_EXP_FLAG )//2.4.3 and 3.1.3 clients - pkt << (uint8) 0x2C; // unk, may be realm number/id? - else - pkt << (uint8) 0x0; //1.12.1 and 1.12.2 clients - - ++RealmListSize; - } - - if ( _expversion & POST_BC_EXP_FLAG )//2.4.3 and 3.1.3 cliens - { - pkt << (uint8) 0x10; - pkt << (uint8) 0x00; - }else{//1.12.1 and 1.12.2 clients - pkt << (uint8) 0x00; - pkt << (uint8) 0x02; - } - - // make a ByteBuffer which stores the RealmList's size - ByteBuffer RealmListSizeBuffer; - RealmListSizeBuffer << (uint32)0; - if (_expversion & POST_BC_EXP_FLAG) // only 2.4.3 and 3.1.3 cliens - RealmListSizeBuffer << (uint16)RealmListSize; - else - RealmListSizeBuffer << (uint32)RealmListSize; - - ByteBuffer hdr; - hdr << (uint8) REALM_LIST; - hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); - hdr.append(RealmListSizeBuffer); // append RealmList's size buffer - hdr.append(pkt); // append realms in the realmlist - - socket().send((char const*)hdr.contents(), hdr.size()); - - return true; -} - -/// Resume patch transfer -bool AuthSocket::_HandleXferResume() -{ - DEBUG_LOG("Entering _HandleXferResume"); - ///- Check packet length and patch existence - if (socket().recv_len() < 9 || !pPatch) - { - sLog.outError("Error while resuming patch transfer (wrong packet)"); - return false; - } - - ///- Launch a PatcherRunnable thread starting at given patch file offset - uint64 start; - socket().recv_skip(1); - socket().recv((char*)&start,sizeof(start)); - fseek(pPatch, start, 0); - - ACE_Based::Thread u(new PatcherRunnable(this)); - return true; -} - -/// Cancel patch transfer -bool AuthSocket::_HandleXferCancel() -{ - DEBUG_LOG("Entering _HandleXferCancel"); - - ///- Close and delete the socket - socket().recv_skip(1); //clear input buffer - - socket().shutdown(); - - return true; -} - -/// Accept patch transfer -bool AuthSocket::_HandleXferAccept() -{ - DEBUG_LOG("Entering _HandleXferAccept"); - - ///- Check packet length and patch existence - if (!pPatch) - { - sLog.outError("Error while accepting patch transfer (wrong packet)"); - return false; - } - - ///- Launch a PatcherRunnable thread, starting at the beginning of the patch file - socket().recv_skip(1); // clear input buffer - fseek(pPatch, 0, 0); - - ACE_Based::Thread u(new PatcherRunnable(this)); - return true; -} - -PatcherRunnable::PatcherRunnable(class AuthSocket * as) -{ - mySocket = as; -} - -/// Send content of patch file to the client -void PatcherRunnable::run() -{ -} - -/// Preload MD5 hashes of existing patch files on server -#ifndef _WIN32 -#include -#include -void Patcher::LoadPatchesInfo() -{ - DIR * dirp; - //int errno; - struct dirent * dp; - dirp = opendir("./patches/"); - if (!dirp) - return; - while (dirp) - { - errno = 0; - if ((dp = readdir(dirp)) != NULL) - { - int l = strlen(dp->d_name); - if (l < 8) - continue; - if (!memcmp(&dp->d_name[l-4],".mpq",4)) - LoadPatchMD5(dp->d_name); - } - else - { - if (errno != 0) - { - closedir(dirp); - return; - } - break; - } - } - - if (dirp) - closedir(dirp); -} - -#else -void Patcher::LoadPatchesInfo() -{ - WIN32_FIND_DATA fil; - HANDLE hFil=FindFirstFile("./patches/*.mpq", &fil); - if (hFil == INVALID_HANDLE_VALUE) - return; // no patches were found - - do - { - LoadPatchMD5(fil.cFileName); - } - while(FindNextFile(hFil, &fil)); -} -#endif - -/// Calculate and store MD5 hash for a given patch file -void Patcher::LoadPatchMD5(char * szFileName) -{ - ///- Try to open the patch file - std::string path = "./patches/"; - path += szFileName; - FILE *pPatch = fopen(path.c_str(), "rb"); - sLog.outDebug("Loading patch info from %s\n", path.c_str()); - if (!pPatch) - { - sLog.outError("Error loading patch %s\n", path.c_str()); - return; - } - - ///- Calculate the MD5 hash - MD5_CTX ctx; - MD5_Init(&ctx); - uint8* buf = new uint8[512*1024]; - - while (!feof(pPatch)) - { - size_t read = fread(buf, 1, 512*1024, pPatch); - MD5_Update(&ctx, buf, read); - } - delete [] buf; - fclose(pPatch); - - ///- Store the result in the internal patch hash map - _patches[path] = new PATCH_INFO; - MD5_Final((uint8 *)&_patches[path]->md5, &ctx); -} - -/// Get cached MD5 hash for a given patch file -bool Patcher::GetHash(char * pat, uint8 mymd5[16]) -{ - for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i) - if (!stricmp(pat, i->first.c_str())) - { - memcpy(mymd5, i->second->md5, 16); - return true; - } - - return false; -} - -/// Launch the patch hashing mechanism on object creation -Patcher::Patcher() -{ - LoadPatchesInfo(); -} - -/// Empty and delete the patch map on termination -Patcher::~Patcher() -{ - for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i) - delete i->second; -} diff --git a/src/server/trinityrealm/AuthSocket.h b/src/server/trinityrealm/AuthSocket.h deleted file mode 100644 index bfd0fa4fdca..00000000000 --- a/src/server/trinityrealm/AuthSocket.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup realmd -/// @{ -/// \file - -#ifndef _AUTHSOCKET_H -#define _AUTHSOCKET_H - -#include "Common.h" -#include "Auth/BigNumber.h" - -#include "RealmSocket.h" - -enum RealmFlags -{ - REALM_FLAG_NONE = 0x00, - REALM_FLAG_INVALID = 0x01, - REALM_FLAG_OFFLINE = 0x02, - REALM_FLAG_SPECIFYBUILD = 0x04, // client will show realm version in RealmList screen in form "RealmName (major.minor.revision.build)" - REALM_FLAG_UNK1 = 0x08, - REALM_FLAG_UNK2 = 0x10, - REALM_FLAG_RECOMMENDED = 0x20, // client checks pop == 600f - REALM_FLAG_NEW = 0x40, // client checks pop == 200f - REALM_FLAG_FULL = 0x80 // client checks pop == 400f -}; - -/// Handle login commands -class AuthSocket: public RealmSocket::Session -{ - public: - const static int s_BYTE_SIZE = 32; - - AuthSocket(RealmSocket& socket); - virtual ~AuthSocket(void); - - virtual void OnRead(void); - virtual void OnAccept(void); - virtual void OnClose(void); - - bool _HandleLogonChallenge(); - bool _HandleLogonProof(); - bool _HandleReconnectChallenge(); - bool _HandleReconnectProof(); - bool _HandleRealmList(); - //data transfer handle for patch - - bool _HandleXferResume(); - bool _HandleXferCancel(); - bool _HandleXferAccept(); - - void _SetVSFields(const std::string& rI); - - FILE *pPatch; - ACE_Thread_Mutex patcherLock; - - private: - RealmSocket& socket_; - RealmSocket& socket(void) { return socket_; } - - BigNumber N, s, g, v; - BigNumber b, B; - BigNumber K; - BigNumber _reconnectProof; - - bool _authed; - - std::string _login; - std::string _safelogin; - - // Since GetLocaleByName() is _NOT_ bijective, we have to store the locale as a string. Otherwise we can't differ - // between enUS and enGB, which is important for the patch system - std::string _localizationName; - uint16 _build; - uint8 _expversion; - AccountTypes _accountSecurityLevel; -}; -#endif -/// @} diff --git a/src/server/trinityrealm/CMakeLists.txt b/src/server/trinityrealm/CMakeLists.txt deleted file mode 100644 index 8f3e9b87540..00000000000 --- a/src/server/trinityrealm/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -########### next target ############### - -SET(trinity-realm_SRCS -AuthCodes.cpp -AuthCodes.h -AuthSocket.cpp -AuthSocket.h -Main.cpp -RealmList.cpp -RealmList.h -RealmSocket.h -RealmSocket.cpp -RealmAcceptor.h -) - -include_directories( - ${ACE_INCLUDE_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/src/shared - ${CMAKE_SOURCE_DIR}/src/shared/Database - ${CMAKE_SOURCE_DIR}/src/framework - ${MYSQL_INCLUDE_DIR} -) - -SET(trinity-realm_LINK_FLAGS "") - -add_executable(trinity-realm ${trinity-realm_SRCS}) -add_definitions( --D_TRINITY_REALM_CONFIG='"${CONF_DIR}/trinityrealm.conf"' -) -IF (DO_MYSQL) - SET(trinity-realm_LINK_FLAGS "-pthread ${trinity-realm_LINK_FLAGS}") -ENDIF(DO_MYSQL) - -IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") - SET(trinity-realm_LINK_FLAGS "-framework Carbon ${trinity-realm_LINK_FLAGS}") -ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin") - -SET_TARGET_PROPERTIES(trinity-realm PROPERTIES LINK_FLAGS "${trinity-realm_LINK_FLAGS}") - -target_link_libraries( -trinity-realm -shared -trinityframework -trinitysockets -trinitydatabase -trinityauth -trinityconfig -zlib -${SSLLIB} -${MYSQL_LIBRARIES} -${OSX_LIBS} -) - -install(TARGETS trinity-realm DESTINATION bin) - - -########### install files ############### - -install(FILES trinityrealm.conf.dist DESTINATION etc) diff --git a/src/server/trinityrealm/Main.cpp b/src/server/trinityrealm/Main.cpp deleted file mode 100644 index 09bae4908e0..00000000000 --- a/src/server/trinityrealm/Main.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup realmd Realm Daemon -/// @{ -/// \file - -#include "Common.h" -#include "Database/DatabaseEnv.h" - -#include "Config/ConfigEnv.h" -#include "Log.h" -#include "SystemConfig.h" -#include "Util.h" -#include "SignalHandler.h" -#include "RealmList.h" -#include "RealmAcceptor.h" - -#include -#include -#include -#include - -#include -#include - -#ifndef _TRINITY_REALM_CONFIG -# define _TRINITY_REALM_CONFIG "TrinityRealm.conf" -#endif //_TRINITY_REALM_CONFIG - -#ifdef WIN32 -#include "ServiceWin32.h" -char serviceName[] = "TrinityRealm"; -char serviceLongName[] = "Trinity realm service"; -char serviceDescription[] = "Massive Network Game Object Server"; -/* - * -1 - not in service mode - * 0 - stopped - * 1 - running - * 2 - paused - */ -int m_ServiceStatus = -1; -#endif - -bool StartDB(); - -bool stopEvent = false; ///< Setting it to true stops the server - -DatabaseType LoginDatabase; ///< Accessor to the realm server database - -/// Handle realmd's termination signals -class RealmdSignalHandler : public Trinity::SignalHandler -{ - public: - virtual void HandleSignal(int SigNum) - { - switch (SigNum) - { - case SIGINT: - case SIGTERM: - stopEvent = true; - break; - #ifdef _WIN32 - case SIGBREAK: - if (m_ServiceStatus != 1) - stopEvent = true; - break; - #endif /* _WIN32 */ - } - } -}; - -/// Print out the usage string for this program on the console. -void usage(const char *prog) -{ - sLog.outString("Usage: \n %s []\n" - " -c config_file use config_file as configuration file\n\r" - #ifdef WIN32 - " Running as service functions:\n\r" - " --service run as service\n\r" - " -s install install service\n\r" - " -s uninstall uninstall service\n\r" - #endif - ,prog); -} - -/// Launch the realm server -extern int main(int argc, char **argv) -{ - sLog.SetLogDB(false); - ///- Command line parsing to get the configuration file name - char const* cfg_file = _TRINITY_REALM_CONFIG; - int c=1; - while(c < argc) - { - if (strcmp(argv[c],"-c") == 0) - { - if (++c >= argc) - { - sLog.outError("Runtime-Error: -c option requires an input argument"); - usage(argv[0]); - return 1; - } - else - cfg_file = argv[c]; - } - - #ifdef WIN32 - //////////// - //Services// - //////////// - if (strcmp(argv[c],"-s") == 0) - { - if (++c >= argc) - { - sLog.outError("Runtime-Error: -s option requires an input argument"); - usage(argv[0]); - return 1; - } - if (strcmp(argv[c],"install") == 0) - { - if (WinServiceInstall()) - sLog.outString("Installing service"); - return 1; - } - else if (strcmp(argv[c],"uninstall") == 0) - { - if (WinServiceUninstall()) - sLog.outString("Uninstalling service"); - return 1; - } - else - { - sLog.outError("Runtime-Error: unsupported option %s",argv[c]); - usage(argv[0]); - return 1; - } - } - if (strcmp(argv[c],"--service") == 0) - { - WinServiceRun(); - } - //// - #endif - ++c; - } - - if (!sConfig.SetSource(cfg_file)) - { - sLog.outError("Could not find configuration file %s.", cfg_file); - return 1; - } - sLog.Initialize(); - - sLog.outString("%s (realm-daemon)", _FULLVERSION); - sLog.outString(" to stop.\n"); - sLog.outString("Using configuration file %s.", cfg_file); - - sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); - -#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) - ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); -#else - ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); -#endif - - sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); - - /// realmd PID file creation - std::string pidfile = sConfig.GetStringDefault("PidFile", ""); - if (!pidfile.empty()) - { - uint32 pid = CreatePIDFile(pidfile); - if (!pid) - { - sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); - return 1; - } - - sLog.outString("Daemon PID: %u\n", pid); - } - - ///- Initialize the database connection - if (!StartDB()) - return 1; - - ///- Initialize the log database - sLog.SetLogDBLater(sConfig.GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished. - sLog.SetLogDB(false); - sLog.SetRealmID(0); // ensure we've set realm to 0 (realmd realmid) - - ///- Get the list of realms for the server - sRealmList->Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); - if (sRealmList->size() == 0) - { - sLog.outError("No valid realms specified."); - return 1; - } - - ///- Launch the listening network socket - RealmAcceptor acceptor; - - uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); - std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); - - ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); - - if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) - { - sLog.outError("Trinity realm can not bind to %s:%d", bind_ip.c_str(), rmport); - return 1; - } - - // Initialise the signal handlers - RealmdSignalHandler SignalINT, SignalTERM; - #ifdef _WIN32 - RealmdSignalHandler SignalBREAK; - #endif /* _WIN32 */ - - // Register realmd's signal handlers - ACE_Sig_Handler Handler; - Handler.register_handler(SIGINT, &SignalINT); - Handler.register_handler(SIGTERM, &SignalTERM); - #ifdef _WIN32 - Handler.register_handler(SIGBREAK, &SignalBREAK); - #endif /* _WIN32 */(); - - ///- Handle affinity for multiple processors and process priority on Windows - #ifdef WIN32 - { - HANDLE hProcess = GetCurrentProcess(); - - uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); - if (Aff > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if (GetProcessAffinityMask(hProcess,&appAff,&sysAff)) - { - ULONG_PTR curAff = Aff & appAff; // remove non accessible processors - - if (!curAff) - { - sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); - } - else - { - if (SetProcessAffinityMask(hProcess,curAff)) - sLog.outString("Using processors (bitmask, hex): %x", curAff); - else - sLog.outError("Can't set used processors (hex): %x", curAff); - } - } - sLog.outString(); - } - - bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); - - if (Prio) - { - if (SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) - sLog.outString("TrinityRealm process priority class set to HIGH"); - else - sLog.outError("ERROR: Can't set realmd process priority class."); - sLog.outString(); - } - } - #endif - - // maximum counter for next ping - uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); - uint32 loopCounter = 0; - - // possibly enable db logging; avoid massive startup spam by doing it here. - if (sLog.GetLogDBLater()) - { - sLog.outString("Enabling database logging..."); - sLog.SetLogDBLater(false); - // login db needs thread for logging - sLog.SetLogDB(true); - } - else - sLog.SetLogDB(false); - - ///- Wait for termination signal - while (!stopEvent) - { - // dont move this outside the loop, the reactor will modify it - ACE_Time_Value interval(0, 100000); - - if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) - break; - - if ((++loopCounter) == numLoops) - { - loopCounter = 0; - sLog.outDetail("Ping MySQL to keep connection alive"); - LoginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); - } -#ifdef WIN32 - if (m_ServiceStatus == 0) stopEvent = true; - while (m_ServiceStatus == 2) Sleep(1000); -#endif - } - - ///- Wait for the delay thread to exit - LoginDatabase.ThreadEnd(); - LoginDatabase.HaltDelayThread(); - - sLog.outString("Halting process..."); - return 0; -} - -/// Initialize connection to the database -bool StartDB() -{ - std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); - if (dbstring.empty()) - { - sLog.outError("Database not specified"); - return false; - } - - if (!LoginDatabase.Initialize(dbstring.c_str())) - { - sLog.outError("Cannot connect to database"); - return false; - } - LoginDatabase.ThreadStart(); - - return true; -} - -/// @} diff --git a/src/server/trinityrealm/RealmAcceptor.h b/src/server/trinityrealm/RealmAcceptor.h deleted file mode 100644 index 5e243ea915b..00000000000 --- a/src/server/trinityrealm/RealmAcceptor.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2005-2010 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup realmd - */ - -#ifndef __REALMACCEPTOR_H__ -#define __REALMACCEPTOR_H__ - -#include -#include - -#include "RealmSocket.h" -#include "AuthSocket.h" - -class RealmAcceptor : public ACE_Acceptor -{ - public: - RealmAcceptor(void) { } - virtual ~RealmAcceptor(void) { } - - protected: - virtual int make_svc_handler(RealmSocket *&sh) - { - if (sh == 0) - ACE_NEW_RETURN(sh, RealmSocket, -1); - - sh->reactor(reactor()); - sh->set_session(new AuthSocket(*sh)); - return 0; - } -}; - -#endif /* __REALMACCEPTOR_H__ */ diff --git a/src/server/trinityrealm/RealmList.cpp b/src/server/trinityrealm/RealmList.cpp deleted file mode 100644 index 1e989c36c5d..00000000000 --- a/src/server/trinityrealm/RealmList.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup realmd -*/ - -#include "Common.h" -#include "RealmList.h" -#include "Database/DatabaseEnv.h" - - -extern DatabaseType LoginDatabase; - -RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)) -{ -} - -/// Load the realm list from the database -void RealmList::Initialize(uint32 updateInterval) -{ - m_UpdateInterval = updateInterval; - - ///- Get the content of the realmlist table in the database - UpdateRealms(true); -} - -void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build) -{ - ///- Create new if not exist or update existed - Realm& realm = m_realms[name]; - - realm.m_ID = ID; - realm.name = name; - realm.icon = icon; - realm.color = color; - realm.timezone = timezone; - realm.allowedSecurityLevel = allowedSecurityLevel; - realm.populationLevel = popu; - - ///- Append port to IP address. - std::ostringstream ss; - ss << address << ":" << port; - realm.address = ss.str(); - realm.gamebuild = build; -} - -void RealmList::UpdateIfNeed() -{ - // maybe disabled or updated recently - if (!m_UpdateInterval || m_NextUpdateTime > time(NULL)) - return; - - m_NextUpdateTime = time(NULL) + m_UpdateInterval; - - // Clears Realm list - m_realms.clear(); - - // Get the content of the realmlist table in the database - UpdateRealms(false); -} - -void RealmList::UpdateRealms(bool init) -{ - sLog.outDetail("Updating Realm List..."); - - QueryResult_AutoPtr result = LoginDatabase.Query("SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE color <> 3 ORDER BY name"); - - ///- Circle through results and add them to the realm map - if (result) - { - do - { - Field *fields = result->Fetch(); - - uint8 allowedSecurityLevel = fields[7].GetUInt8(); - - UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat(), fields[9].GetUInt32()); - if (init) - sLog.outString("Added realm \"%s\".", fields[1].GetString()); - } while(result->NextRow()); - } -} diff --git a/src/server/trinityrealm/RealmList.h b/src/server/trinityrealm/RealmList.h deleted file mode 100644 index b29b561c797..00000000000 --- a/src/server/trinityrealm/RealmList.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/// \addtogroup realmd -/// @{ -/// \file - -#ifndef _REALMLIST_H -#define _REALMLIST_H - -#include -#include -#include "Common.h" - -/// Storage object for a realm -struct Realm -{ - std::string address; - std::string name; - uint8 icon; - uint8 color; - uint8 timezone; - uint32 m_ID; - AccountTypes allowedSecurityLevel; - float populationLevel; - uint32 gamebuild; -}; - -/// Storage object for the list of realms on the server -class RealmList -{ - public: - // Null_Mutex is safe because the singleton initialized before the acceptor initialized(another place where the singleton called) - static RealmList* instance() { return ACE_Singleton::instance(); } - - typedef std::map RealmMap; - - RealmList(); - ~RealmList() {} - - void Initialize(uint32 updateInterval); - - void UpdateIfNeed(); - - void AddRealm(Realm NewRealm) {m_realms[NewRealm.name] = NewRealm;} - - RealmMap::const_iterator begin() const { return m_realms.begin(); } - RealmMap::const_iterator end() const { return m_realms.end(); } - uint32 size() const { return m_realms.size(); } - private: - void UpdateRealms(bool init); - void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build); - private: - RealmMap m_realms; ///< Internal map of realms - uint32 m_UpdateInterval; - time_t m_NextUpdateTime; -}; - -#define sRealmList RealmList::instance() - -#endif -/// @} diff --git a/src/server/trinityrealm/RealmSocket.cpp b/src/server/trinityrealm/RealmSocket.cpp deleted file mode 100644 index 7eb96cb96f8..00000000000 --- a/src/server/trinityrealm/RealmSocket.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2005-2010 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup realmd - */ - -#include "RealmSocket.h" - -#include "Log.h" - -#include -#include -#include - -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif - -RealmSocket::Session::Session(void) -{ -} - -RealmSocket::Session::~Session(void) -{ -} - -RealmSocket::RealmSocket(void): - session_(NULL), - input_buffer_(4096), - remote_address_() -{ - reference_counting_policy().value( - ACE_Event_Handler::Reference_Counting_Policy::ENABLED); - - msg_queue()->high_water_mark(8*1024*1024); - msg_queue()->low_water_mark(8*1024*1024); - -} - -RealmSocket::~RealmSocket(void) -{ - if (msg_queue()) - msg_queue()->close(); - - // delete RealmSocketObject must never be called from our code. - closing_ = true; - - if (session_) - delete session_; - - peer().close(); -} - -int RealmSocket::open(void * arg) -{ - ACE_INET_Addr addr; - - if (peer ().get_remote_addr (addr) == -1) - { - sLog.outError ("RealmSocket::open: peer ().get_remote_addr errno = %s", ACE_OS::strerror (errno)); - return -1; - } - - remote_address_ = addr.get_host_addr(); - - // Register with ACE Reactor - if (Base::open(arg) == -1) - return -1; - - if (session_ != NULL) - { - session_->OnAccept(); - } - - // reactor takes care of the socket from now on - remove_reference(); - - return 0; -} - -int RealmSocket::close(int) -{ - shutdown(); - - closing_ = true; - - remove_reference(); - - return 0; -} - -const ACE_CString& RealmSocket::get_remote_address(void) const -{ - return remote_address_; -} - -size_t RealmSocket::recv_len(void) const -{ - return input_buffer_.length(); -} - -bool RealmSocket::recv_soft(char *buf, size_t len) -{ - if (input_buffer_.length() < len) - return false; - - ACE_OS::memcpy(buf, input_buffer_.rd_ptr(), len); - - return true; -} - -bool RealmSocket::recv(char *buf, size_t len) -{ - bool ret = recv_soft(buf, len); - - if (ret) - recv_skip(len); - - return ret; -} - -void RealmSocket::recv_skip(size_t len) -{ - input_buffer_.rd_ptr(len); -} - -ssize_t RealmSocket::noblk_send(ACE_Message_Block &message_block) -{ - const size_t len = message_block.length(); - - if (len == 0) - return -1; - - // Try to send the message directly. - ssize_t n = peer().send(message_block.rd_ptr(), len, MSG_NOSIGNAL); - - if (n < 0) - { - if (errno == EWOULDBLOCK) - // Blocking signal - return 0; - else - // Error happened - return -1; - } - else if (n == 0) - { - // Can this happen ? - return -1; - } - - // return bytes transmitted - return n; -} - -bool RealmSocket::send(const char *buf, size_t len) -{ - if (buf == NULL || len == 0) - return true; - - ACE_Data_Block db( - len, - ACE_Message_Block::MB_DATA, - (const char*)buf, - 0, - 0, - ACE_Message_Block::DONT_DELETE, - 0); - - ACE_Message_Block message_block( - &db, - ACE_Message_Block::DONT_DELETE, - 0); - - message_block.wr_ptr(len); - - if (msg_queue()->is_empty()) - { - // Try to send it directly. - ssize_t n = noblk_send(message_block); - - if (n < 0) - return false; - else if (n == len) - return true; - - // fall down - message_block.rd_ptr((size_t)n); - } - - ACE_Message_Block *mb = message_block.clone(); - - if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) - { - mb->release(); - return false; - } - - if (reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK) == -1) - return false; - - return true; -} - -int RealmSocket::handle_output(ACE_HANDLE /*= ACE_INVALID_HANDLE*/) -{ - if (closing_) - return -1; - - ACE_Message_Block *mb = 0; - - if (msg_queue()->is_empty()) - { - reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK); - return 0; - } - - if (msg_queue()->dequeue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) - return -1; - - ssize_t n = noblk_send(*mb); - - if (n < 0) - { - mb->release(); - return -1; - } - else if (n == mb->length()) - { - mb->release(); - return 1; - } - else - { - mb->rd_ptr(n); - - if (msg_queue()->enqueue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) - { - mb->release(); - return -1; - } - - return 0; - } - - ACE_NOTREACHED(return -1); -} - -int RealmSocket::handle_close(ACE_HANDLE h, ACE_Reactor_Mask /*m*/) -{ - // As opposed to WorldSocket::handle_close, we don't need locks here. - - closing_ = true; - - if (h == ACE_INVALID_HANDLE) - peer ().close_writer (); - - if (session_ != NULL) - { - session_->OnClose(); - } - - return 0; -} - -int RealmSocket::handle_input(ACE_HANDLE /*= ACE_INVALID_HANDLE*/) -{ - if (closing_) - return -1; - - const ssize_t space = input_buffer_.space(); - - ssize_t n = peer().recv(input_buffer_.wr_ptr(), space); - - if (n < 0) - { - return errno == EWOULDBLOCK ? 0 : -1; - } - else if (n == 0) - { - // EOF - return -1; - } - - input_buffer_.wr_ptr((size_t)n); - - if (session_ != NULL) - { - session_->OnRead(); - - input_buffer_.crunch(); - } - - // return 1 in case there is more data to read from OS - return n == space ? 1 : 0; -} - - -void RealmSocket::set_session(Session* session) -{ - if (session_ != NULL) - delete session_; - - session_ = session; -} - diff --git a/src/server/trinityrealm/RealmSocket.h b/src/server/trinityrealm/RealmSocket.h deleted file mode 100644 index 13be8327533..00000000000 --- a/src/server/trinityrealm/RealmSocket.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2005-2010 MaNGOS - * - * Copyright (C) 2008-2010 Trinity - * - * 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 - */ - -/** \file - \ingroup realmd - */ - -#ifndef __REALMSOCKET_H__ -#define __REALMSOCKET_H__ - -#include -#include -#include -#include -#include -#include - -class RealmSocket : public ACE_Svc_Handler -{ - private: - typedef ACE_Svc_Handler Base; - - public: - class Session - { - public: - Session(void); - virtual ~Session(void); - - virtual void OnRead(void) = 0; - virtual void OnAccept(void) = 0; - virtual void OnClose(void) = 0; - }; - - RealmSocket(void); - virtual ~RealmSocket(void); - - size_t recv_len(void) const; - bool recv_soft(char *buf, size_t len); - bool recv(char *buf, size_t len); - void recv_skip(size_t len); - - bool send(const char *buf, size_t len); - - const ACE_CString& get_remote_address(void) const; - - virtual int open(void *); - - virtual int close(int); - - virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE); - virtual int handle_output(ACE_HANDLE = ACE_INVALID_HANDLE); - - virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); - - void set_session(Session* session); - - private: - ssize_t noblk_send(ACE_Message_Block &message_block); - - private: - ACE_Message_Block input_buffer_; - Session* session_; - ACE_CString remote_address_; -}; - -#endif /* __REALMSOCKET_H__ */ diff --git a/src/server/trinityrealm/TrinityRealm.ico b/src/server/trinityrealm/TrinityRealm.ico deleted file mode 100644 index da318f48a8c..00000000000 Binary files a/src/server/trinityrealm/TrinityRealm.ico and /dev/null differ diff --git a/src/server/trinityrealm/TrinityRealm.rc b/src/server/trinityrealm/TrinityRealm.rc deleted file mode 100644 index dfc548305fd..00000000000 --- a/src/server/trinityrealm/TrinityRealm.rc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS - * - * 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 "resource.h" -#include "../shared/revision.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" //"afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APPICON ICON "TrinityRealm.ico" - -///////////////////////////////////////////////////////////////////////////// -// Neutre (Par défaut système) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION FILEVER - PRODUCTVERSION PRODUCTVER - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x0L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080004b0" - BEGIN - VALUE "FileDescription", "TrinityRealm" - VALUE "FileVersion", STRFILEVER - VALUE "InternalName", "TrinityRealm" - VALUE "LegalCopyright", "Copyright (C) 2008-2009" - VALUE "OriginalFilename", "TrinityRealm.exe" - VALUE "ProductName", "TrinityRealm" - VALUE "ProductVersion", STRPRODUCTVER - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x800, 1200 - END -END -#endif diff --git a/src/server/trinityrealm/resource.h b/src/server/trinityrealm/resource.h deleted file mode 100644 index 7dc5cb9ef7b..00000000000 --- a/src/server/trinityrealm/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by TrinityCore.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/server/trinityrealm/trinityrealm.conf.dist b/src/server/trinityrealm/trinityrealm.conf.dist deleted file mode 100644 index e98b9386878..00000000000 --- a/src/server/trinityrealm/trinityrealm.conf.dist +++ /dev/null @@ -1,146 +0,0 @@ -########################################## -# Trinity Core realmd configuration file # -########################################## -# Note to devs, line breaks should be at column 80 -############################################################################### -# REALMD SETTINGS -# -# LoginDatabaseInfo -# Database connection settings for the realm server. -# Default: -# hostname;port;username;password;database -# .;somenumber;username;password;database -# - use named pipes in Windows -# Named pipes: mySQL required adding -# "enable-named-pipe" to [mysqld] section my.ini -# .;/path/to/unix_socket;username;password;database -# - use Unix sockets in Unix/Linux -# -# LogsDir -# Logs directory setting. -# Important: Logs dir must exists, or all logs need to be disabled -# Default: "" - no log directory prefix, if used log names isn't -# absolute path then logs will be stored in current directory. -# -# MaxPingTime -# Settings for maximum database-ping interval (minutes between pings) -# -# RealmServerPort -# Default RealmServerPort -# -# BindIP -# Bind Realm Server to IP/hostname -# -# PidFile -# Realmd daemon PID file -# Default: "" - do not create PID file -# "./realmd.pid" - create PID file (recommended name) -# -# LogLevel -# Server console level of logging -# Default: 0 = Minimum -# 1 = Basic -# 2 = Detail -# 3 = Full/Debug -# -# LogFile -# Logfile name -# Default: "realmd.log" -# "" - Empty name disable creating log file -# -# LogTimestamp -# Logfile with timestamp of server start in name -# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# Default: 0 - no timestamp in name -# 1 - add timestamp in name -# -# LogFileLevel -# Server file level of logging -# Default: 0 = Minimum -# 1 = Basic -# 2 = Detail -# 3 = Full/Debug -# -# LogColors -# Color for messages (format "normal basic detail debug") -# Default: "" - no colors -# Colors: 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "13 11 9 5" -# -# EnableLogDB -# Enable/disable logging to database (LogDatabaseInfo). -# Default: 0 - disabled -# 1 - enabled -# -# DBLogLevel -# Log level of DB logging. -# 0 = Minimum -# Default: 1 = Basic -# 2 = Detail -# 3 = Full/Debug -# -# UseProcessors -# Processors mask for multi-processor system (Used only in Windows) -# Default: 0 (selected by OS) -# number (bitmask value of selected processors) -# -# ProcessPriority -# Process proirity setting (Used only at Windows) -# Default: 1 (HIGH) -# 0 (Normal) -# -# RealmsStateUpdateDelay -# Realm list Update up delay -# (updated at realm list request if delay expired). -# Default: 20 -# 0 (Disabled) -# -# WrongPass.MaxCount -# Number of login attemps with wrong password -# before the account or IP is banned -# Default: 0 (Never ban) -# -# WrongPass.BanTime -# Duration of the ban in seconds (0 means permanent ban) -# Default: 600 -# -# WrongPass.BanType -# Ban the IP or account on which login is attempted -# Default: 0 (Ban IP) -# 1 (Ban Account) -# -############################################################################### - -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;realmd" -LogsDir = "" -MaxPingTime = 30 -RealmServerPort = 3724 -BindIP = "0.0.0.0" -PidFile = "" -LogLevel = 0 -LogFile = "realmd.log" -LogTimestamp = 0 -LogFileLevel = 0 -LogColors = "" -EnableLogDB = 0 -DBLogLevel = 1 -UseProcessors = 0 -ProcessPriority = 1 -RealmsStateUpdateDelay = 20 -WrongPass.MaxCount = 0 -WrongPass.BanTime = 600 -WrongPass.BanType = 0 diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt new file mode 100644 index 00000000000..0efdc63c09e --- /dev/null +++ b/src/server/worldserver/CMakeLists.txt @@ -0,0 +1,79 @@ + +########### next target ############### + +SET(trinity-core_SRCS +CliRunnable.cpp +CliRunnable.h +Main.cpp +Master.cpp +Master.h +RASocket.cpp +RASocket.h +WorldRunnable.cpp +WorldRunnable.h +) + +include_directories( + ${ACE_INCLUDE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/include + ${CMAKE_SOURCE_DIR}/src/shared + ${CMAKE_SOURCE_DIR}/src/shared/Database + ${CMAKE_SOURCE_DIR}/src/framework + ${CMAKE_SOURCE_DIR}/src/game + ${MYSQL_INCLUDE_DIR} +) + +SET(trinity-core_LINK_FLAGS "") + +add_executable(trinity-core ${trinity-core_SRCS}) +add_definitions( +-D_TRINITY_CORE_CONFIG='"${CONF_DIR}/trinitycore.conf"' +) +IF (DO_MYSQL) + SET(trinity-core_LINK_FLAGS "-pthread ${trinity-core_LINK_FLAGS}") +ENDIF(DO_MYSQL) + +IF (CMAKE_SYSTEM_NAME MATCHES "Darwin") + SET(trinity-core_LINK_FLAGS "-framework Carbon ${trinity-core_LINK_FLAGS}") + SET(SCRIPT_LIB "") +ENDIF (CMAKE_SYSTEM_NAME MATCHES "Darwin") + +SET_TARGET_PROPERTIES(trinity-core PROPERTIES LINK_FLAGS "${trinity-core_LINK_FLAGS}") + +if(DO_SCRIPTS) + SET(SCRIPT_LIB "scripts") +else(DO_SCRIPTS) + SET(SCRIPT_LIB "") +endif(DO_SCRIPTS) + +target_link_libraries( +trinity-core +game +shared +zlib +trinityframework +trinitysockets +trinitydatabase +trinityauth +trinityconfig +vmaps +g3dlite +jmalloc +${SCRIPT_LIB} +${READLINE_LIBRARY} +${TERMCAP_LIBRARY} +${MYSQL_LIBRARIES} +${SSLLIB} +${ACE_LIBRARY} +${ZLIB} +${OSX_LIBS} +) + +install(TARGETS trinity-core DESTINATION bin) + + +########### install files ############### + +install(FILES trinitycore.conf.dist DESTINATION etc) + diff --git a/src/server/worldserver/CliRunnable.cpp b/src/server/worldserver/CliRunnable.cpp new file mode 100644 index 00000000000..b39faf694db --- /dev/null +++ b/src/server/worldserver/CliRunnable.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup Trinityd +/// @{ +/// \file + +#include "Common.h" +#include "ObjectMgr.h" +#include "World.h" +#include "WorldSession.h" +#include "Config/ConfigEnv.h" + +#include "AccountMgr.h" +#include "Chat.h" +#include "CliRunnable.h" +#include "Language.h" +#include "Log.h" +#include "MapManager.h" +#include "Player.h" +#include "Util.h" + +#if PLATFORM != WINDOWS +#include +#include + +char * command_finder(const char* text, int state) +{ + static int idx,len; + const char* ret; + ChatCommand *cmd = ChatHandler::getCommandTable(); + + if(!state) + { + idx = 0; + len = strlen(text); + } + + while(ret = cmd[idx].Name) + { + if(!cmd[idx].AllowConsole) + { + idx++; + continue; + } + + idx++; + //printf("Checking %s \n", cmd[idx].Name); + if (strncmp(ret, text, len) == 0) + return strdup(ret); + if(cmd[idx].Name == NULL) + break; + } + + return ((char*)NULL); +} + +char ** cli_completion(const char * text, int start, int end) +{ + char ** matches; + matches = (char**)NULL; + + if(start == 0) + matches = rl_completion_matches((char*)text,&command_finder); + else + rl_bind_key('\t',rl_abort); + return (matches); +} +#endif + +void utf8print(const char* str) +{ +#if PLATFORM == PLATFORM_WINDOWS + wchar_t wtemp_buf[6000]; + size_t wtemp_len = 6000-1; + if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len)) + return; + + char temp_buf[6000]; + CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1); + printf(temp_buf); +#else +{ + va_list v; + vprintf(str, v); + va_end(v); + fflush(stdout); +} +#endif +} + +/// 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) +{ + if(!*args) + return false; + + ///- Get the account name from the command line + char *account_name_str=strtok ((char*)args," "); + if (!account_name_str) + return false; + + std::string account_name = account_name_str; + if(!AccountMgr::normalizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 account_id = accmgr.GetId(account_name); + if(!account_id) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + /// Commands not recommended call from chat, but support anyway + /// can delete only for account with less security + /// This is also reject self apply in fact + if(HasLowerSecurityAccount (NULL,account_id,true)) + return false; + + AccountOpResult result = accmgr.DeleteAccount(account_id); + switch(result) + { + case AOR_OK: + PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); + break; + case AOR_NAME_NOT_EXIST: + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + case AOR_DB_INTERNAL_ERROR: + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; + default: + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +bool ChatHandler::HandleCharacterDeleteCommand(const char* args) +{ + if(!*args) + return false; + + char *character_name_str = strtok((char*)args," "); + if(!character_name_str) + return false; + + std::string character_name = character_name_str; + if(!normalizePlayerName(character_name)) + return false; + + uint64 character_guid; + uint32 account_id; + + Player *player = objmgr.GetPlayer(character_name.c_str()); + if(player) + { + character_guid = player->GetGUID(); + account_id = player->GetSession()->GetAccountId(); + player->GetSession()->KickPlayer(); + } + else + { + character_guid = objmgr.GetPlayerGUIDByName(character_name); + if(!character_guid) + { + PSendSysMessage(LANG_NO_PLAYER,character_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); + } + + std::string account_name; + accmgr.GetName (account_id,account_name); + + Player::DeleteFromDB(character_guid, account_id, true); + PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id); + return true; +} + +/// Exit the realm +bool ChatHandler::HandleServerExitCommand(const char* /*args*/) +{ + SendSysMessage(LANG_COMMAND_EXIT); + World::StopNow(SHUTDOWN_EXIT_CODE); + return true; +} + +/// Display info on users currently in the realm +bool ChatHandler::HandleAccountOnlineListCommand(const char* /*args*/) +{ + ///- Get the list of accounts ID logged to the realm + QueryResult_AutoPtr resultDB = CharacterDatabase.Query("SELECT name,account,map,zone FROM characters WHERE online > 0"); + if (!resultDB) + { + SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); + return true; + } + + ///- Display the list of account/characters online + SendSysMessage(LANG_ACCOUNT_LIST_BAR_HEADER); + SendSysMessage(LANG_ACCOUNT_LIST_HEADER); + SendSysMessage(LANG_ACCOUNT_LIST_BAR); + + ///- Circle through accounts + do + { + Field *fieldsDB = resultDB->Fetch(); + std::string name = fieldsDB[0].GetCppString(); + uint32 account = fieldsDB[1].GetUInt32(); + + ///- Get the username, last IP and GM level of each account + // No SQL injection. account is uint32. + QueryResult_AutoPtr resultLogin = + LoginDatabase.PQuery("SELECT a.username, a.last_ip, aa.gmlevel, a.expansion " + "FROM account a " + "LEFT JOIN account_access aa " + "ON (a.id = aa.id) " + "WHERE a.id = '%u'", account); + if(resultLogin) + { + Field *fieldsLogin = resultLogin->Fetch(); + PSendSysMessage(LANG_ACCOUNT_LIST_LINE, + fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsDB[2].GetInt32(),fieldsDB[3].GetInt32(),fieldsLogin[3].GetUInt32(),fieldsLogin[2].GetUInt32()); + } + else + PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); + + }while(resultDB->NextRow()); + + SendSysMessage(LANG_ACCOUNT_LIST_BAR); + return true; +} + +/// Create an account +bool ChatHandler::HandleAccountCreateCommand(const char* args) +{ + if(!*args) + return false; + + ///- %Parse the command line arguments + char *szAcc = strtok((char*)args, " "); + char *szPassword = strtok(NULL, " "); + if(!szAcc || !szPassword) + return false; + + // normalized in accmgr.CreateAccount + std::string account_name = szAcc; + std::string password = szPassword; + + AccountOpResult result = accmgr.CreateAccount(account_name, password); + switch(result) + { + case AOR_OK: + PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); + break; + case AOR_NAME_TOO_LONG: + SendSysMessage(LANG_ACCOUNT_TOO_LONG); + SetSentErrorMessage(true); + return false; + case AOR_NAME_ALREDY_EXIST: + SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); + SetSentErrorMessage(true); + return false; + case AOR_DB_INTERNAL_ERROR: + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; + default: + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +/// Set the level of logging +bool ChatHandler::HandleServerSetLogFileLevelCommand(const char *args) +{ + if(!*args) + return false; + + char *NewLevel = strtok((char*)args, " "); + if (!NewLevel) + return false; + + sLog.SetLogFileLevel(NewLevel); + return true; +} + +/// Set the level of logging +bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) +{ + if(!*args) + return false; + + char *NewLevel = strtok((char*)args, " "); + if (!NewLevel) + return false; + + sLog.SetLogLevel(NewLevel); + return true; +} + +/// set diff time record interval +bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args) +{ + if(!*args) + return false; + + char *NewTimeStr = strtok((char*)args, " "); + if(!NewTimeStr) + return false; + + int32 NewTime =atoi(NewTimeStr); + if(NewTime < 0) + return false; + + sWorld.SetRecordDiffInterval(NewTime); + printf( "Record diff every %u ms\n", NewTime); + return true; +} + +/// @} + +#ifdef linux +// Non-blocking keypress detector, when return pressed, return 1, else always return 0 +int kb_hit_return() +{ + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); +} +#endif + +/// %Thread start +void CliRunnable::run() +{ + ///- Init new SQL thread for the world database (one connection call enough) + WorldDatabase.ThreadStart(); // let thread do safe mySQL requests + + char commandbuf[256]; + + ///- Display the list of available CLI functions then beep + sLog.outString(""); + #if PLATFORM != WINDOWS + rl_attempted_completion_function = cli_completion; + #endif + if(sConfig.GetBoolDefault("BeepAtStart", true)) + printf("\a"); // \a = Alert + + // print this here the first time + // later it will be printed after command queue updates + printf("TC>"); + + ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it + while (!World::IsStopped()) + { + fflush(stdout); + + char *command_str ; // = fgets(commandbuf,sizeof(commandbuf),stdin); + + #if PLATFORM == WINDOWS + command_str = fgets(commandbuf,sizeof(commandbuf),stdin); + #else + command_str = readline("TC>"); + rl_bind_key('\t',rl_complete); + #endif + if (command_str != NULL) + { + for (int x=0; command_str[x]; x++) + if(command_str[x]=='\r'||command_str[x]=='\n') + { + command_str[x]=0; + break; + } + + if(!*command_str) + { + #if PLATFORM == WINDOWS + printf("TC>"); + #endif + continue; + } + + std::string command; + if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 + { + #if PLATFORM == WINDOWS + printf("TC>"); + #endif + continue; + } + fflush(stdout); + sWorld.QueueCliCommand(&utf8print,command.c_str()); + #if PLATFORM != WINDOWS + add_history(command.c_str()); + #endif + + } + else if (feof(stdin)) + { + World::StopNow(SHUTDOWN_EXIT_CODE); + } + + } + + ///- End the database thread + WorldDatabase.ThreadEnd(); // free mySQL thread resources +} diff --git a/src/server/worldserver/CliRunnable.h b/src/server/worldserver/CliRunnable.h new file mode 100644 index 00000000000..9f990b2b469 --- /dev/null +++ b/src/server/worldserver/CliRunnable.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup Trinityd +/// @{ +/// \file + +#ifndef __CLIRUNNABLE_H +#define __CLIRUNNABLE_H + +/// Command Line Interface handling thread +class CliRunnable : public ACE_Based::Runnable +{ + public: + void run(); +}; +#endif +/// @} diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp new file mode 100644 index 00000000000..95bb39eca91 --- /dev/null +++ b/src/server/worldserver/Main.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup Trinityd Trinity Daemon +/// @{ +/// \file + +#include +#include +#include + +#include "Common.h" +#include "Database/DatabaseEnv.h" +#include "Config/ConfigEnv.h" + +#include "Log.h" +#include "Master.h" + +#ifndef _TRINITY_CORE_CONFIG +# define _TRINITY_CORE_CONFIG "TrinityCore.conf" +#endif //_TRINITY_CORE_CONFIG + +#ifdef WIN32 +#include "ServiceWin32.h" +char serviceName[] = "TrinityCore"; +char serviceLongName[] = "Trinity core service"; +char serviceDescription[] = "Massive Network Game Object Server"; +/* + * -1 - not in service mode + * 0 - stopped + * 1 - running + * 2 - paused + */ +int m_ServiceStatus = -1; +#endif + +DatabaseType WorldDatabase; ///< Accessor to the world database +DatabaseType CharacterDatabase; ///< Accessor to the character database +DatabaseType LoginDatabase; ///< Accessor to the realm/login database + +uint32 realmID; ///< Id of the realm + +/// Print out the usage string for this program on the console. +void usage(const char *prog) +{ + sLog.outString("Usage: \n %s []\n" + " -c config_file use config_file as configuration file\n\r" + #ifdef WIN32 + " Running as service functions:\n\r" + " --service run as service\n\r" + " -s install install service\n\r" + " -s uninstall uninstall service\n\r" + #endif + ,prog); +} + +/// Launch the Trinity server +extern int main(int argc, char **argv) +{ + ///- Command line parsing to get the configuration file name + char const* cfg_file = _TRINITY_CORE_CONFIG; + int c=1; + while( c < argc ) + { + if( strcmp(argv[c],"-c") == 0) + { + if( ++c >= argc ) + { + sLog.outError("Runtime-Error: -c option requires an input argument"); + usage(argv[0]); + return 1; + } + else + cfg_file = argv[c]; + } + + #ifdef WIN32 + //////////// + //Services// + //////////// + if( strcmp(argv[c],"-s") == 0) + { + if( ++c >= argc ) + { + sLog.outError("Runtime-Error: -s option requires an input argument"); + usage(argv[0]); + return 1; + } + if( strcmp(argv[c],"install") == 0) + { + if (WinServiceInstall()) + sLog.outString("Installing service"); + return 1; + } + else if( strcmp(argv[c],"uninstall") == 0) + { + if(WinServiceUninstall()) + sLog.outString("Uninstalling service"); + return 1; + } + else + { + sLog.outError("Runtime-Error: unsupported option %s",argv[c]); + usage(argv[0]); + return 1; + } + } + if( strcmp(argv[c],"--service") == 0) + { + WinServiceRun(); + } + //// + #endif + ++c; + } + + if (!sConfig.SetSource(cfg_file)) + { + sLog.outError("Could not find configuration file %s.", cfg_file); + return 1; + } + sLog.outString("Using configuration file %s.", cfg_file); + + sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + sLog.outDetail("Using ACE: %s", ACE_VERSION); + + ///- and run the 'Master' + /// \todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd? + return sMaster.Run(); + + // at sMaster return function exist with codes + // 0 - normal shutdown + // 1 - shutdown at error + // 2 - restart command used, this code can be used by restarter for restart Trinityd +} + +/// @} diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp new file mode 100644 index 00000000000..8b34b512f57 --- /dev/null +++ b/src/server/worldserver/Master.cpp @@ -0,0 +1,536 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup Trinityd +*/ + +#include + +#include "Common.h" +#include "SystemConfig.h" +#include "SignalHandler.h" +#include "World.h" +#include "WorldRunnable.h" +#include "WorldSocket.h" +#include "WorldSocketMgr.h" +#include "Config/ConfigEnv.h" +#include "Database/DatabaseEnv.h" +#include "Policies/SingletonImp.h" + +#include "CliRunnable.h" +#include "Log.h" +#include "Master.h" +#include "RASocket.h" +#include "Timer.h" +#include "Util.h" + +#include "sockets/TcpSocket.h" +#include "sockets/Utility.h" +#include "sockets/Parse.h" +#include "sockets/Socket.h" +#include "sockets/SocketHandler.h" +#include "sockets/ListenSocket.h" +#include "Auth/BigNumber.h" + +#ifdef WIN32 +#include "ServiceWin32.h" +extern int m_ServiceStatus; +#endif + +/// \todo Warning disabling not useful under VC++2005. Can somebody say on which compiler it is useful? +#pragma warning(disable:4305) + +INSTANTIATE_SINGLETON_1( Master ); + +volatile uint32 Master::m_masterLoopCounter = 0; + +/// Handle cored's termination signals +class CoredSignalHandler : public Trinity::SignalHandler +{ + public: + virtual void HandleSignal(int SigNum) + { + switch (SigNum) + { + case SIGINT: + World::StopNow(RESTART_EXIT_CODE); + break; + case SIGTERM: + #ifdef _WIN32 + case SIGBREAK: + if (m_ServiceStatus != 1) + #endif /* _WIN32 */ + World::StopNow(SHUTDOWN_EXIT_CODE); + break; + } + } +}; + +class FreezeDetectorRunnable : public ACE_Based::Runnable +{ +public: + FreezeDetectorRunnable() { _delaytime = 0; } + uint32 m_loops, m_lastchange; + uint32 w_loops, w_lastchange; + uint32 _delaytime; + void SetDelayTime(uint32 t) { _delaytime = t; } + void run(void) + { + if(!_delaytime) + return; + sLog.outString("Starting up anti-freeze thread (%u seconds max stuck time)...",_delaytime/1000); + m_loops = 0; + w_loops = 0; + m_lastchange = 0; + w_lastchange = 0; + while(!World::IsStopped()) + { + ACE_Based::Thread::Sleep(1000); + uint32 curtime = getMSTime(); + //DEBUG_LOG("anti-freeze: time=%u, counters=[%u; %u]",curtime,Master::m_masterLoopCounter,World::m_worldLoopCounter); + + // There is no Master anymore + // TODO: clear the rest of the code +// // normal work +// if(m_loops != Master::m_masterLoopCounter) +// { +// m_lastchange = curtime; +// m_loops = Master::m_masterLoopCounter; +// } +// // possible freeze +// else if(getMSTimeDiff(m_lastchange,curtime) > _delaytime) +// { +// sLog.outError("Main/Sockets Thread hangs, kicking out server!"); +// *((uint32 volatile*)NULL) = 0; // bang crash +// } + + // normal work + if(w_loops != World::m_worldLoopCounter) + { + w_lastchange = curtime; + w_loops = World::m_worldLoopCounter; + } + // possible freeze + else if(getMSTimeDiff(w_lastchange,curtime) > _delaytime) + { + sLog.outError("World Thread hangs, kicking out server!"); + *((uint32 volatile*)NULL) = 0; // bang crash + } + } + sLog.outString("Anti-freeze thread exiting without problems."); + } +}; + +class RARunnable : public ACE_Based::Runnable +{ +public: + uint32 numLoops, loopCounter; + + RARunnable () + { + uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); + numLoops = (sConfig.GetIntDefault ("MaxPingTime", 30) * (MINUTE * 1000000 / socketSelecttime)); + loopCounter = 0; + } + + void checkping () + { + // ping if need + if ((++loopCounter) == numLoops) + { + loopCounter = 0; + sLog.outDetail ("Ping MySQL to keep connection alive"); + WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1"); + LoginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1"); + CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1"); + } + } + + void run () + { + SocketHandler h; + + // Launch the RA listener socket + ListenSocket RAListenSocket (h); + bool usera = sConfig.GetBoolDefault ("Ra.Enable", false); + + if (usera) + { + port_t raport = sConfig.GetIntDefault ("Ra.Port", 3443); + std::string stringip = sConfig.GetStringDefault ("Ra.IP", "0.0.0.0"); + ipaddr_t raip; + if (!Utility::u2ip (stringip, raip)) + sLog.outError ("Trinity RA can not bind to ip %s", stringip.c_str ()); + else if (RAListenSocket.Bind (raip, raport)) + sLog.outError ("Trinity RA can not bind to port %d on %s", raport, stringip.c_str ()); + else + { + h.Add (&RAListenSocket); + + sLog.outString ("Starting Remote access listner on port %d on %s", raport, stringip.c_str ()); + } + } + + // Socket Selet time is in microseconds , not miliseconds!! + uint32 socketSelecttime = sWorld.getConfig (CONFIG_SOCKET_SELECTTIME); + + // if use ra spend time waiting for io, if not use ra ,just sleep + if (usera) + { + while (!World::IsStopped()) + { + h.Select (0, socketSelecttime); + checkping (); + } + } + else + { + while (!World::IsStopped()) + { + ACE_Based::Thread::Sleep(static_cast (socketSelecttime / 1000)); + checkping (); + } + } + } +}; + +Master::Master() +{ +} + +Master::~Master() +{ +} + +/// Main function +int Master::Run() +{ + BigNumber seed1; + seed1.SetRand(16 * 8); + + sLog.outString( "%s (core-daemon)", _FULLVERSION ); + sLog.outString( " to stop.\n" ); + + sLog.outString( " ______ __"); + sLog.outString( "/\\__ _\\ __ __/\\ \\__"); + sLog.outString( "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\ ,_\\ __ __"); + sLog.outString( " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\"); + sLog.outString( " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\"); + sLog.outString( " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\"); + sLog.outString( " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\"); + sLog.outString( " C O R E /\\___/"); + sLog.outString( "http://TrinityCore.org \\/__/\n"); + + /// worldd PID file creation + std::string pidfile = sConfig.GetStringDefault("PidFile", ""); + if(!pidfile.empty()) + { + uint32 pid = CreatePIDFile(pidfile); + if( !pid ) + { + sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); + return 1; + } + + sLog.outString( "Daemon PID: %u\n", pid ); + } + + ///- Start the databases + if (!_StartDB()) + return 1; + + ///- Initialize the World + sWorld.SetInitialWorldSettings(); + + + // Initialise the signal handlers + CoredSignalHandler SignalINT, SignalTERM; + #ifdef _WIN32 + CoredSignalHandler SignalBREAK; + #endif /* _WIN32 */ + + // Register realmd's signal handlers + ACE_Sig_Handler Handler; + Handler.register_handler(SIGINT, &SignalINT); + Handler.register_handler(SIGTERM, &SignalTERM); + #ifdef _WIN32 + Handler.register_handler(SIGBREAK, &SignalBREAK); + #endif /* _WIN32 */ + + + ///- Launch WorldRunnable thread + ACE_Based::Thread world_thread(new WorldRunnable); + world_thread.setPriority(ACE_Based::Highest); + + // set server online + LoginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID); + + ACE_Based::Thread* cliThread = NULL; + +#ifdef WIN32 + if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) +#else + if (sConfig.GetBoolDefault("Console.Enable", true)) +#endif + { + ///- Launch CliRunnable thread + cliThread = new ACE_Based::Thread(new CliRunnable); + } + + ACE_Based::Thread rar_thread(new RARunnable); + + ///- Handle affinity for multiple processors and process priority on Windows + #ifdef WIN32 + { + HANDLE hProcess = GetCurrentProcess(); + + uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); + if(Aff > 0) + { + ULONG_PTR appAff; + ULONG_PTR sysAff; + + if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) + { + ULONG_PTR curAff = Aff & appAff; // remove non accessible processors + + if(!curAff ) + { + sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for Trinityd. Accessible processors bitmask (hex): %x",Aff,appAff); + } + else + { + if(SetProcessAffinityMask(hProcess,curAff)) + sLog.outString("Using processors (bitmask, hex): %x", curAff); + else + sLog.outError("Can't set used processors (hex): %x",curAff); + } + } + sLog.outString(""); + } + + bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); + +// if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/) + if(Prio) + { + if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) + sLog.outString("TrinityCore process priority class set to HIGH"); + else + sLog.outError("ERROR: Can't set Trinityd process priority class."); + sLog.outString(""); + } + } + #endif + + uint32 realCurrTime, realPrevTime; + realCurrTime = realPrevTime = getMSTime(); + + ///- Start up freeze catcher thread + if(uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0)) + { + FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable(); + fdr->SetDelayTime(freeze_delay*1000); + ACE_Based::Thread freeze_thread(fdr); + freeze_thread.setPriority(ACE_Based::Highest); + } + + ///- Launch the world listener socket + port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD); + std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0"); + + if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1) + { + sLog.outError ("Failed to start network"); + World::StopNow(ERROR_EXIT_CODE); + // go down and shutdown the server + } + + sWorldSocketMgr->Wait (); + + // set server offline + LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID); + + // when the main thread closes the singletons get unloaded + // since worldrunnable uses them, it will crash if unloaded after master + world_thread.wait(); + rar_thread.wait (); + + ///- Clean database before leaving + clearOnlineAccounts(); + + ///- Wait for delay threads to end + CharacterDatabase.HaltDelayThread(); + WorldDatabase.HaltDelayThread(); + LoginDatabase.HaltDelayThread(); + + sLog.outString( "Halting process..." ); + + if (cliThread) + { + #ifdef WIN32 + + // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) + //_exit(1); + // send keyboard input to safely unblock the CLI thread + INPUT_RECORD b[5]; + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + b[0].EventType = KEY_EVENT; + b[0].Event.KeyEvent.bKeyDown = TRUE; + b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; + b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; + b[0].Event.KeyEvent.wRepeatCount = 1; + + b[1].EventType = KEY_EVENT; + b[1].Event.KeyEvent.bKeyDown = FALSE; + b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; + b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; + b[1].Event.KeyEvent.wRepeatCount = 1; + + b[2].EventType = KEY_EVENT; + b[2].Event.KeyEvent.bKeyDown = TRUE; + b[2].Event.KeyEvent.dwControlKeyState = 0; + b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; + b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + b[2].Event.KeyEvent.wRepeatCount = 1; + b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; + + b[3].EventType = KEY_EVENT; + b[3].Event.KeyEvent.bKeyDown = FALSE; + b[3].Event.KeyEvent.dwControlKeyState = 0; + b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; + b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; + b[3].Event.KeyEvent.wRepeatCount = 1; + DWORD numb; + WriteConsoleInput(hStdIn, b, 4, &numb); + + cliThread->wait(); + + #else + + cliThread->destroy(); + + #endif + + delete cliThread; + } + + // for some unknown reason, unloading scripts here and not in worldrunnable + // fixes a memory leak related to detaching threads from the module + //UnloadScriptingModule(); + + // Exit the process with specified return value + return World::GetExitCode(); +} + +/// Initialize connection to the databases +bool Master::_StartDB() +{ + sLog.SetLogDB(false); + std::string dbstring; + + ///- Get world database info from configuration file + dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", ""); + if(dbstring.empty()) + { + sLog.outError("Database not specified in configuration file"); + return false; + } + + ///- Initialise the world database + if(!WorldDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to world database %s",dbstring.c_str()); + return false; + } + + ///- Get character database info from configuration file + dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", ""); + if(dbstring.empty()) + { + sLog.outError("Character Database not specified in configuration file"); + return false; + } + + ///- Initialise the Character database + if(!CharacterDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to Character database %s",dbstring.c_str()); + return false; + } + + ///- Get login database info from configuration file + dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); + if(dbstring.empty()) + { + sLog.outError("Login database not specified in configuration file"); + return false; + } + + ///- Initialise the login database + if(!LoginDatabase.Initialize(dbstring.c_str())) + { + sLog.outError("Cannot connect to login database %s",dbstring.c_str()); + return false; + } + + ///- Get the realm Id from the configuration file + realmID = sConfig.GetIntDefault("RealmID", 0); + if(!realmID) + { + sLog.outError("Realm ID not defined in configuration file"); + return false; + } + sLog.outString("Realm running as realm ID %d", realmID); + + ///- Initialize the DB logging system + sLog.SetLogDBLater(sConfig.GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished. + sLog.SetLogDB(false); + sLog.SetRealmID(realmID); + + ///- Clean the database before starting + clearOnlineAccounts(); + + ///- Insert version info into DB + WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _REVISION); + + sWorld.LoadDBVersion(); + + sLog.outString("Using World DB: %s", sWorld.GetDBVersion()); + sLog.outString("Using creature EventAI: %s", sWorld.GetCreatureEventAIVersion()); + return true; +} + +/// Clear 'online' status for all accounts with characters in this realm +void Master::clearOnlineAccounts() +{ + // Cleanup online status for characters hosted at current realm + /// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'? + LoginDatabase.PExecute( + "UPDATE account SET online = 0 WHERE online > 0 " + "AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID); + + CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0"); + + // Battleground instance ids reset at server restart + CharacterDatabase.Execute("UPDATE character_battleground_data SET instance_id = 0"); +} diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h new file mode 100644 index 00000000000..76ff2af1457 --- /dev/null +++ b/src/server/worldserver/Master.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup Trinityd +/// @{ +/// \file + +#ifndef _MASTER_H +#define _MASTER_H + +#include "Common.h" +#include "Policies/Singleton.h" + +/// Start the server +class Master +{ + public: + Master(); + ~Master(); + int Run(); + static volatile uint32 m_masterLoopCounter; + + private: + bool _StartDB(); + + void clearOnlineAccounts(); +}; + +#define sMaster Trinity::Singleton::Instance() +#endif +/// @} diff --git a/src/server/worldserver/RASocket.cpp b/src/server/worldserver/RASocket.cpp new file mode 100644 index 00000000000..32c16d9980f --- /dev/null +++ b/src/server/worldserver/RASocket.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup Trinityd +*/ + +#include "Common.h" +#include "Config/ConfigEnv.h" +#include "Database/DatabaseEnv.h" +#include "AccountMgr.h" +#include "Log.h" +#include "RASocket.h" +#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 +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()); +} + +/// Read data from the network +void RASocket::OnRead() +{ + ///- Read data and check input length + TcpSocket::OnRead(); + + unsigned int sz=ibuf.GetLength(); + if(iInputLength+sz>=RA_BUFF_SIZE) + { + sLog.outRemote("Input buffer overflow, possible DOS attack.\n"); + SetCloseAndDelete(); + 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]; + ibuf.Read(inp,sz); + + /// \todo Can somebody explain this 'Linux bugfix'? + if(stage==NONE) + if(sz>4) //linux remote telnet + if(memcmp(inp ,"USER ",5)) + { + delete [] inp;return; + printf("lin bugfix"); + } //linux bugfix + + ///- Discard data after line break or line feed + bool gotenter=false; + unsigned int y=0; + for (; y
  • If the input is 'USER ' + case NONE: + if(!memcmp(buff,"USER ",5)) //got "USER" cmd + { + szLogin=&buff[5]; + + ///- Get the password from the account table + std::string login = szLogin; + + ///- Convert Account name to Upper Format + AccountMgr::normalizeString(login); + + ///- Escape the Login to allow quotes in names + LoginDatabase.escape_string(login); + + QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = '%s'",login.c_str ()); + + ///- If the user is not found, deny access + if(!result) + { + Sendf("-No such user.\r\n"); + sLog.outRemote("User %s does not exist.\n",szLogin.c_str()); + if(bSecure)SetCloseAndDelete(); + } + else + { + Field *fields = result->Fetch(); + + //szPass=fields[0].GetString(); + + ///- if gmlevel is too low, deny access + if(fields[1].GetUInt32() If the input is 'PASS ' (and the user already gave his username) + case LG: + if(!memcmp(buff,"PASS ",5)) //got "PASS" cmd + { //login+pass ok + ///- If password is correct, increment the number of active administrators + std::string login = szLogin; + std::string pw = &buff[5]; + + AccountMgr::normalizeString(login); + AccountMgr::normalizeString(pw); + LoginDatabase.escape_string(login); + LoginDatabase.escape_string(pw); + + QueryResult_AutoPtr check = LoginDatabase.PQuery( + "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT('%s',':','%s'))", + login.c_str(), login.c_str(), pw.c_str()); + + if(check) + { + r=GetSocket(); + stage=OK; + ++iUsers; + + Sendf("+Logged in.\r\n"); + sLog.outRemote("User %s has logged in.\n",szLogin.c_str()); + Sendf("TC>"); + } + else + { + ///- Else deny access + Sendf("-Wrong pass.\r\n"); + sLog.outRemote("User %s has failed to log in.\n",szLogin.c_str()); + if(bSecure)SetCloseAndDelete(); + } + } + break; + ///
  • If user is logged, parse and execute the command + case OK: + if(strlen(buff)) + { + sLog.outRemote("Got '%s' cmd.\n",buff); + sWorld.QueueCliCommand(&RASocket::zprint , buff); + } + else + Sendf("TC>"); + break; + /// + }; + + } +} + +/// Output function +void RASocket::zprint( 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); + delete [] megabuffer; + + #else + + unsigned int sz=strlen(szText); + send(r,szText,sz,0); + + #endif +} diff --git a/src/server/worldserver/RASocket.h b/src/server/worldserver/RASocket.h new file mode 100644 index 00000000000..5c13724f90d --- /dev/null +++ b/src/server/worldserver/RASocket.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup Trinityd +/// @{ +/// \file + +#ifndef _RASOCKET_H +#define _RASOCKET_H + +#include "sockets/TcpSocket.h" + +#include "Common.h" + +#define RA_BUFF_SIZE 1024 + +class ISocketHandler; + +/// Remote Administration socket +class RASocket: public TcpSocket +{ + public: + + RASocket(ISocketHandler& h); + ~RASocket(); + + void OnAccept(); + void OnRead(); + + private: + + char * buff; + std::string szLogin; + uint32 iSess; + unsigned int iInputLength; + bool bLog; + bool bSecure; //kick on wrong pass, non exist. user, user with no priv + //will protect from DOS, bruteforce attacks + //some 'smart' protection must be added for more security + uint8 iMinLevel; + enum + { + NONE, //initial value + LG, //only login was entered + OK, //both login and pass were given, and they are correct and user have enough priv. + }stage; + + static void zprint( const char * szText ); +}; +#endif +/// @} diff --git a/src/server/worldserver/TrinityCore.ico b/src/server/worldserver/TrinityCore.ico new file mode 100644 index 00000000000..6f0a5721957 Binary files /dev/null and b/src/server/worldserver/TrinityCore.ico differ diff --git a/src/server/worldserver/TrinityCore.rc b/src/server/worldserver/TrinityCore.rc new file mode 100644 index 00000000000..151185f3cec --- /dev/null +++ b/src/server/worldserver/TrinityCore.rc @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * 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 "resource.h" +#include "../shared/revision.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APPICON ICON "TrinityCore.ico" + +///////////////////////////////////////////////////////////////////////////// +// Neutre (Par défaut système) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILEVER + PRODUCTVERSION PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x0L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080004b0" + BEGIN + VALUE "FileDescription", "TrinityCore" + VALUE "FileVersion", STRFILEVER + VALUE "InternalName", "TrinityCore" + VALUE "LegalCopyright", "Copyright (C) 2008-2009" + VALUE "OriginalFilename", "TrinityCore.exe" + VALUE "ProductName", "TrinityCore" + VALUE "ProductVersion", STRPRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x800, 1200 + END +END +#endif diff --git a/src/server/worldserver/WorldRunnable.cpp b/src/server/worldserver/WorldRunnable.cpp new file mode 100644 index 00000000000..c674ddbc06f --- /dev/null +++ b/src/server/worldserver/WorldRunnable.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/** \file + \ingroup Trinityd +*/ + +#include "Common.h" +#include "ObjectAccessor.h" +#include "World.h" +#include "WorldSocketMgr.h" +#include "Database/DatabaseEnv.h" + +#include "BattleGroundMgr.h" +#include "MapManager.h" +#include "Timer.h" +#include "WorldRunnable.h" + +#define WORLD_SLEEP_CONST 50 + +#ifdef WIN32 +#include "ServiceWin32.h" +extern int m_ServiceStatus; +#endif + +/// Heartbeat for the World +void WorldRunnable::run() +{ + ///- Init new SQL thread for the world database + WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough) + + sWorld.InitResultQueue(); + + uint32 realCurrTime = 0; + uint32 realPrevTime = getMSTime(); + + uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST + + ///- While we have not World::m_stopEvent, update the world + while (!World::IsStopped()) + { + ++World::m_worldLoopCounter; + realCurrTime = getMSTime(); + + uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime); + + sWorld.Update( diff ); + realPrevTime = realCurrTime; + + // diff (D0) include time of previous sleep (d0) + tick time (t0) + // we want that next d1 + t1 == WORLD_SLEEP_CONST + // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement + // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0 + if (diff <= WORLD_SLEEP_CONST+prevSleepTime) + { + prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; + ACE_Based::Thread::Sleep(prevSleepTime); + } + else + prevSleepTime = 0; + + #ifdef WIN32 + if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE); + while (m_ServiceStatus == 2) Sleep(1000); + #endif + } + + sWorld.KickAll(); // save and kick all players + sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call + + // unload battleground templates before different singletons destroyed + sBattleGroundMgr.DeleteAllBattleGrounds(); + + sWorldSocketMgr->StopNetwork(); + + MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory) + + ///- End the database thread + WorldDatabase.ThreadEnd(); // free mySQL thread resources +} diff --git a/src/server/worldserver/WorldRunnable.h b/src/server/worldserver/WorldRunnable.h new file mode 100644 index 00000000000..f14ee021f36 --- /dev/null +++ b/src/server/worldserver/WorldRunnable.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2010 Trinity + * + * 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 + */ + +/// \addtogroup Trinityd +/// @{ +/// \file + +#ifndef __WORLDRUNNABLE_H +#define __WORLDRUNNABLE_H + +/// Heartbeat thread for the World +class WorldRunnable : public ACE_Based::Runnable +{ + public: + void run(); +}; +#endif +/// @} diff --git a/src/server/worldserver/resource.h b/src/server/worldserver/resource.h new file mode 100644 index 00000000000..7dc5cb9ef7b --- /dev/null +++ b/src/server/worldserver/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by TrinityCore.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/server/worldserver/trinitycore.conf.dist b/src/server/worldserver/trinitycore.conf.dist new file mode 100644 index 00000000000..3b6d20e093d --- /dev/null +++ b/src/server/worldserver/trinitycore.conf.dist @@ -0,0 +1,2212 @@ +########################################## +# Trinity Core worldd configuration file # +########################################## +# Note to devs, line breaks should be at column 80 +############################################################################### +# CONNECTIONS AND DIRECTORIES +# +# RealmID +# RealmID must match the realmlist inside the realmd database +# +# DataDir +# Data directory setting. +# Important: DataDir needs to be quoted, as it is a string which may +# contain space characters. +# Example: "@prefix@/share/trinitycore" +# +# LogsDir +# Logs directory setting. +# Important: Logs dir must exists, or all logs need to be disabled +# Default: "" - no log directory prefix, if used log names isn't +# absolute path then logs will be stored in current directory. +# +# +# LoginDatabaseInfo +# WorldDatabaseInfo +# CharacterDatabaseInfo +# Database connection settings for the world server. +# Default: +# hostname;port;username;password;database +# .;somenumber;username;password;database +# - use named pipes in Windows +# Named pipes: mySQL required adding +# "enable-named-pipe" to [mysqld] section my.ini +# .;/path/to/unix_socket;username;password;database +# - use Unix sockets in Unix/Linux +# +# MaxPingTime +# Settings for maximum database-ping interval (minutes between pings) +# +# WorldServerPort +# Default WorldServerPort +# +# BindIP +# Bind World Server to IP/hostname +# +############################################################################### + +RealmID = 1 +DataDir = "." +LogsDir = "" +LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;realmd" +WorldDatabaseInfo = "127.0.0.1;3306;trinity;trinity;world" +CharacterDatabaseInfo = "127.0.0.1;3306;trinity;trinity;characters" +MaxPingTime = 30 +WorldServerPort = 8085 +BindIP = "0.0.0.0" + +############################################################################### +# SCRIPTING SETTINGS +# +# Locale +# Setting for current (DBC) locale to use +# +# EventAI Error reporting +# Default: 0 - Only startup +# 1 - Startup errors and Runtime event errors +# 2 - Startup errors, Runtime event errors, and Creation errors +# +############################################################################### + +Locale = 0 +EAIErrorLevel = 2 + +############################################################################### +# PERFORMANCE SETINGS +# +# UseProcessors +# Processors mask for multi-processor system (Used only in Windows) +# Default: 0 (selected by OS) +# number (bitmask value of selected processors) +# +# ProcessPriority +# Process priority setting (Used only at Windows) +# Default: 1 (HIGH) +# 0 (Normal) +# +# Compression +# Compression level for update packages sent to client (1..9) +# Default: 1 (speed) +# 9 (best compression) +# +# PlayerLimit +# Maximum number of players in the world. Excluding Mods, GMs and Admins +# Default: 100 +# 0 (for infinite players) +# If you want to block players and enable Mods, GMs or Admins use +# DB field realmd.realmlist.allowedSecurityLevel +# +# SaveRespawnTimeImmediately +# Save respawn time for creatures at death and gameobjects at use/open +# Default: 1 (save creature/gameobject respawn time immediately) +# 0 (save creature/gameobject respawn time at grid unload) +# +# MaxOverspeedPings +# Maximum overspeed ping count before player kick +# (minimum is 2, 0 used for disable check) +# Default: 2 +# +# GridUnload +# Unload grids +# (if you have lot memory you can disable it to speed up +# player move to new grids second time) +# Default: 1 (unload grids) +# 0 (do not unload grids) +# +# SocketSelectTime +# Socket select time (in milliseconds) +# Default: 10000 (10 secs) +# +# SocketTimeOutTime +# Time in milliseconds afer which a connection sitting idle on the character +# selection screen is disconnected. +# Default: 900000 (15 minutes) +# +# SessionAddDelay +# Time in microseconds that a network thread will sleep after authentication +# protocol and adding a connection to the world session map. +# Default: 10000 (10 milliseconds, 0,01 second) +# +# GridCleanUpDelay +# Grid clean up delay (in milliseconds) +# Default: 300000 (5 min) +# +# MapUpdateInterval +# Map update interval (in milliseconds) +# Default: 100 +# +# ChangeWeatherInterval +# Weather update interval (in milliseconds) +# Default: 600000 (10 min) +# +# PlayerSaveInterval +# Player save interval (in milliseconds) +# Default: 900000 (15 min) +# +# PlayerSave.Stats.MinLevel +# Minimum level for saving character stats for external usage in database +# Default: 0 (do not save character stats) +# 1+ (save stats for characters with level 1+) +# +# PlayerSave.Stats.SaveOnlyOnLogout +# Enable/Disable saving of character stats only on logout +# Default: 1 (only save on logout) +# 0 (save on every player save) +# +# vmap.enableLOS +# vmap.enableHeight +# Enable/Disable VMmap support for line of sight and height calculation +# Default: 0 (disable) +# 1 (enable) +# +# vmap.ignoreMapIds +# Map id that will be ignored by VMaps +# List of ids with delimiter ',' +# If more then one id is defined and spaces are included, the string +# has to be enclosed by " +# Example: "369,0,1,530" +# +# vmap.ignoreSpellIds +# These spells are ignored for LoS calculation +# List of ids with delimiter ',' +# +# vmap.petLOS +# Check LOS for pets, to avoid them going through walls etc. +# Default: 0 (disable, less CPU usage) +# 1 (enable, each pet attack command will check for LOS) +# +# vmap.enableIndoorCheck +# Enable/Disable VMap based indoor check to remove outdoor-only auras (mounts etc.) +# Default: 0 (disabled) +# +# DetectPosCollision +# Check final move position, summon position, etc for visible collision +# with other objects or wall (wall only if vmaps are enabled) +# Default: 1 (enable, required more CPU usage) +# 0 (disable, less position precision but will use less CPU) +# +# TargetPosRecalculateRange +# Max distance from movement target point (+moving unit size) and +# targeted object (+size) after that new target movement point +# calculated. Max: melee attack range (5), min: contact range (0.5) +# More distance let have better performence, less distance let have +# more sensitive reaction at target move. +# Default: 1.5 +# +# UpdateUptimeInterval +# Update realm uptime period in minutes. Must be > 0 +# Default: 10 (minutes) +# +# LogDB.Opt.ClearInterval +# Time for the WUPDATE_CLEANDB timer that clears the `logs` table +# of old entries. Must be > 0. +# Default: 10 (minutes) +# +# LogDB.Opt.ClearTime +# The maximum time in seconds of old `logs` table entries to keep. +# Default: 1209600 (14 days) +# 0 - don't clear +# +# MaxCoreStuckTime +# Periodically check if the process is frozen, if this is the case +# force crash after the specified amount of seconds. Must be > 0. +# Recommended > 10 secs if you use this. +# Default: 0 (Disabled) +# +# AddonChannel +# Permit/disable the use of the addon channel through the server +# (some client side addons will not work correctly with disabled +# addon channel) +# Default: 1 (permit addon channel) +# 0 (do not permit addon channel) +# +# MapUpdate.Threads +# Number of threads to update maps. +# Default: 1 +# +############################################################################### + +UseProcessors = 0 +ProcessPriority = 1 +Compression = 1 +PlayerLimit = 100 +SaveRespawnTimeImmediately = 1 +MaxOverspeedPings = 2 +GridUnload = 1 +SocketSelectTime = 10000 +SocketTimeOutTime = 900000 +SessionAddDelay = 10000 +GridCleanUpDelay = 300000 +MapUpdateInterval = 100 +ChangeWeatherInterval = 600000 +PlayerSaveInterval = 900000 +PlayerSave.Stats.MinLevel = 0 +PlayerSave.Stats.SaveOnlyOnLogout = 1 +vmap.enableLOS = 0 +vmap.enableHeight = 0 +vmap.ignoreMapIds = "369" +vmap.ignoreSpellIds = "7720" +vmap.petLOS = 0 +vmap.enableIndoorCheck = 0 +DetectPosCollision = 1 +TargetPosRecalculateRange = 1.5 +UpdateUptimeInterval = 10 +LogDB.Opt.ClearInterval = 10 +LogDB.Opt.ClearTime = 1209600 +MaxCoreStuckTime = 0 +AddonChannel = 1 +MapUpdate.Threads = 1 + +############################################################################### +# SERVER LOGGING +# +# LogSQL +# Enable logging of SQL commands from in game +# All commands are written to a file: YYYY-MM-DD_logSQL.sql +# If a new day starts (00:00:00) then a new file is created +# the old file will not be deleted. +# Default: 1 - Write SQL code to logfile +# 0 - Do not log +# +# PidFile +# World daemon PID file +# Default: "" - do not create PID file +# "./worldd.pid" - create PID file (recommended name) +# +# LogLevel +# Server console level of logging +# 0 = Minimum +# Default: 1 = Basic +# 2 = Detail +# 3 = Full/Debug +# +# LogFile +# Logfile name +# Default: "Server.log" +# "" - Empty name disable creating log file +# +# ChatLogFile +# Log file for chat logs +# Default: "chat.log" +# "" - Empty name for disable +# +# LogTimestamp +# Logfile with timestamp of server start in name +# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# Default: 0 - no timestamp in name +# 1 - add timestamp in name +# +# LogFileLevel +# Server file level of logging +# Default: 0 = Minimum +# 1 = Basic +# 2 = Detail +# 3 = Full/Debug +# +# LogFilter_AchievementUpdates +# LogFilter_CreatureMoves +# LogFilter_TransportMoves +# LogFilter_VisibilityChanges +# Log filters +# Default: 1 - not include with any log level +# 0 - include in log if log level permit +# +# WorldLogFile +# Packet logging file for the worldserver +# Default: "world.log" +# +# DBErrorLogFile +# Log file of DB errors detected at server run +# Default: "DBErrors.log" +# +# CharLogFile +# Character operations logfile name +# Default: "Char.log" +# "" - Empty name disable creating log file +# +# CharLogTimestamp +# Logfile with timestamp of server start in name +# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# Default: 0 - no timestamp in name +# 1 - add timestamp in name +# +# CharLogDump +# Write character dump before deleting in Char.log +# For restoration, cut character data from log starting from +# line == START DUMP == to line == END DUMP == (exclusive) in file +# and load it using the loadpdump command +# Default: 0 - don't include dumping chars to log +# 1 - include dumping chars to log +# CharLogDump.Separate +# Write character dump to separate file +# Default: 0 - don't write dump to separate file +# 1 - write each dump to separate file +# +# CharLogDump.SeparateDir +# Subdirectory within logs dir for separate char dumps. +# +# +# GmLogFile +# Log file of gm commands +# Default: "gm_commands.log" +# "" - Empty name for disable +# +# GmLogTimestamp +# GM Logfile with timestamp of server start in name +# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# Default: 0 - no timestamp in name +# 1 - add timestamp in name +# +# GmLogPerAccount +# GM Logfiles with GM account id +# (Note: logs not created if GmLogFile not set) +# Default: 0 - add gm log data to single log file +# 1 - add gm log data to account specific log files with name +# in form Logname_#ID_YYYY-MM-DD_HH-MM-SS.Ext +# or form Logname_#ID.Ext +# +# RaLogFile +# Log file of RA commands +# Default: "Ra.log" +# "" - Empty name for disable +# +# ArenaLogFile +# Log file of arena fights and arena team creations +# Default: "" - do not create arena log file +# +# LogColors +# Color for messages (format "normal basic detail debug") +# Default: "" - no colors +# Colors: 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "13 11 9 5" +# +# EnableLogDB +# Enable/disable logging to database (LogDatabaseInfo). +# Default: 0 - disabled +# 1 - enabled +# +# DBLogLevel +# Log level of DB logging. +# 0 = Minimum +# 1 = Basic +# 2 = Detail +# Default: 3 = Full/Debug +# +# LogDB.Char +# Enable/disable logging character outputs to DB. +# Default: 0 - off +# 1 - on +# +# LogDB.GM +# Enable/disable logging GM commands to DB. +# Default: 0 - off +# 1 - on +# +# LogDB.RA +# Enable/disable logging remote access events to DB. +# Default: 0 - off +# 1 - on +# +# LogDB.World +# Enable/disable logging world packets to DB. +# Default: 0 - off +# 1 - on (very heavy) +# +# LogDB.Chat +# Enable/disable logging chat messages to the database. +# Default: 0 - off +# 1 - on +# +# ChatLogs.Channel +# Enable logging chatting in custom channels. +# Default: 0 - off +# 1 - on +# +# ChatLogs.Whisper +# Enable logging whispers between players. +# Default: 0 - off +# 1 - on +# +# ChatLogs.Party +# Enable logging party messages. +# Default: 0 - off +# 1 - on +# +# ChatLogs.Raid +# Enable logging raid messages. +# Default: 0 - off +# 1 - on +# +# ChatLogs.Guild +# Enable logging guild messages. +# Default: 0 - off +# 1 - on +# +# ChatLogs.Public +# Enable logging public chat events (say/yell/emote). +# Default: 0 - off +# 1 - on +# +# ChatLogs.Addon +# Enable logging addon messages. +# Default: 0 - off +# 1 - on +# +# ChatLogs.BattleGround +# Enable logging battleground chats. +# Default: 0 - off +# 1 - on +# +# ChatLogTimestamp +# Chat Logfile with timestamp of server start in name +# in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# Default: 0 - no timestamp in name +# 1 - add timestamp in name +# +############################################################################### + +LogSQL = 1 +PidFile = "" +LogLevel = 1 +LogFile = "Server.log" +ChatLogFile = "chat.log" +LogTimestamp = 0 +LogFileLevel = 0 +LogFilter_AchievementUpdates = 1 +LogFilter_CreatureMoves = 1 +LogFilter_TransportMoves = 1 +LogFilter_VisibilityChanges = 1 +WorldLogFile = "" +DBErrorLogFile = "db_errors.log" +CharLogFile = "characters.log" +CharLogTimestamp = 0 +CharLogDump = 0 +CharLogDump.Separate = 0 +CharLogDump.SeparateDir = "" +GmLogFile = "gm_commands.log" +GmLogTimestamp = 0 +GmLogPerAccount = 0 +RaLogFile = "ra_commands.log" +ArenaLogFile = "" +LogColors = "" +EnableLogDB = 0 +DBLogLevel = 2 +LogDB.Char = 0 +LogDB.GM = 0 +LogDB.RA = 0 +LogDB.World = 0 +LogDB.Chat = 0 +ChatLogs.Channel = 0 +ChatLogs.SysChan = 0 +ChatLogs.Whisper = 0 +ChatLogs.Party = 0 +ChatLogs.Raid = 0 +ChatLogs.Guild = 0 +ChatLogs.Public = 0 +ChatLogs.Addon = 0 +ChatLogs.BattleGround = 0 +ChatLogTimestamp = 0 + +############################################################################### +# SERVER SETTINGS +# +# GameType +# Server realm style +# Default: 0 = NORMAL +# 1 = PVP +# 4 = NORMAL +# 6 = RP +# 8 = RPPVP +# 16 FFA_PVP (free for all pvp mode like arena PvP in all +# zones except rest activated places and sanctuaries) +# +# RealmZone +# Server realm zone (set allowed alphabet in character names/etc) +# See also Strict*Names options. +# +# Default: 1 Development - any language +# 2 United States - extended-Latin +# 3 Oceanic - extended-Latin +# 4 Latin America - extended-Latin +# 5 Tournament - basic-Latin at create, any at login +# 6 Korea - East-Asian +# 7 Tournament - basic-Latin at create, any at login +# 8 English - extended-Latin +# 9 German - extended-Latin +# 10 French - extended-Latin +# 11 Spanish - extended-Latin +# 12 Russian - Cyrillic +# 13 Tournament - basic-Latin at create, any at login +# 14 Taiwan - East-Asian +# 15 Tournament - basic-Latin at create, any at login +# 16 China - East-Asian +# 17 CN1 - basic-Latin at create, any at login +# 18 CN2 - basic-Latin at create, any at login +# 19 CN3 - basic-Latin at create, any at login +# 20 CN4 - basic-Latin at create, any at login +# 21 CN5 - basic-Latin at create, any at login +# 22 CN6 - basic-Latin at create, any at login +# 23 CN7 - basic-Latin at create, any at login +# 24 CN8 - basic-Latin at create, any at login +# 25 Tournament - basic-Latin at create, any at login +# 26 Test Server - any language +# 27 Tournament - basic-Latin at create, any at login +# 28 QA Server - any language +# 29 CN9 - basic-Latin at create, any at login +# +# Expansion +# Allow server use content from expansion +# Default: 2 - check expansion 2 maps existence, and if client support +# expansion 2 and account have expansion 2 setting then +# allow visit expansion 2 maps, allow create new class +# character) +# 1 - check expansion 1 maps existence, and if client support +# expansion 1 and account have expansion 1 setting then +# allow visit expansion 1 maps, allow create new races +# character) +# 0 - don't check expansion maps existence, don't allow visit +# maps, don't allow create new race or new class +# characters, ignore account expansion setting) +# +# DBC.Locale +# DBC Language Settings +# Default: 255 = Auto Detect +# 0 = English +# 1 = Korean +# 2 = French +# 3 = German +# 4 = Chinese +# 5 = Taiwanese +# 6 = Spanish +# 7 = Spanish Mexico +# 8 = Russian +# +# DeclinedNames +# Allow russian clients to set and use declined names +# Default: 0 - do not use declined names, except when +# the Russian RealmZone is set +# 1 - use declined names +# +# StrictPlayerNames +# Limit player name to language specific symbol set, don't allow +# character creation, and set rename request and disconnect at not +# allowed symbols name +# Default: 0 disable (limited server timezone dependent client check) +# 1 basic latin characters (strict) +# 2 realm zone specific (strict). See RealmZone setting. +# Note: In any case if you want correctly see character +# name at client this client must have appropriate fonts +# (included in client by default, with active official +# localization or custom localization fonts in +# clientdir/Fonts). +# 3 basic latin characters + server timezone specific +# +# StrictCharterNames +# Limit guild/arena team charter names to language specific symbol set, +# don't allow charter creation with unallowed symbols in name +# Default: 0 disable +# 1 basic latin characters (strict) +# 2 realm zone specific (strict). See RealmZone setting. +# Note: In any case if you want correctly see character +# name at client this client must have appropriate fonts +# (included in client by default, with active official +# localization or custom localization fonts in +# clientdir/Fonts). +# 3 basic latin characters + server timezone specific +# +# StrictPetNames +# Limit pet names to language specific symbols set +# Default: 0 disable +# 1 basic latin characters (strict) +# 2 realm zone specific (strict). See RealmZone setting. +# Note: In any case if you want correctly see character +# name at client this client must have appropriate fonts +# (included in client by default, with active official +# localization or custom localization fonts in +# clientdir/Fonts). +# 3 basic latin characters + server timezone specific +# +# MinPlayerName +# Minimal name length (1..12) +# Default: 2 +# +# MinCharterName +# Minimal name length (1..24) +# Default: 2 +# +# MinPetName +# Minimal name length (1..12) +# Default: 2 +# +# CharactersCreatingDisabled +# Disable characters creating for specific team or any +# (non-player accounts not affected) +# Default: 0 - enabled +# 1 - disabled only for Alliance +# 2 - disabled only for Horde +# 3 - disabled for both teams +# +# MaxWhoListReturns +# Set the max number of players returned in the /who list and interface. +# Default: 49 (stable) +# +# CharactersPerAccount +# Limit numbers of characters per account (at all realms). +# Note: this setting limit character creating at _current_ realm base +# at characters amount at all realms +# Default: 50 +# The number must be >= CharactersPerRealm +# +# CharactersPerRealm +# Limit numbers of characters for account at realm +# Default: 10 (client limitation) +# The number must be between 1 and 10 +# +# HeroicCharactersPerRealm +# Limit numbers of heroic class characters for account at realm +# Default: 1 +# The number must be between 0 (not allowed) and 10 +# +# MinLevelForHeroicCharacterCreating +# Limit creating heroic characters only for account with another +# character of specific level (ignored for GM accounts) +# 0 - not require any existed chaarcter +# 1 - require at least any character existed +# Default: 55 - default requirement +# +# +# SkipCinematics +# Disable in-game script movie at first character's login +# (allows to prevent buggy intro in case of custom start +# location coordinates) +# Default: 0 - show intro for each new characrer +# 1 - show intro only for first character of selected race +# 2 - disable intro show in all cases +# +# MaxPlayerLevel +# Max level that can be reached by player for experience +# (in range from 1 to 100). Going past 100 voids your warranty +# and you will not receive support for bugs you encounter. +# Change not recommended +# Default: 80 +# +# MinDualSpecLevel +# Min level at which players can use Dual Spec functionality +# Default: 40 +# +# StartPlayerLevel +# Staring level that have character upon creation +# (in range 1 to MaxPlayerLevel) +# Default: 1 +# +# StartHeroicPlayerLevel +# Staring level that have character of heroic class upon creation +# (in range 1 to MaxPlayerLevel) +# Default: 55 +# +# StartPlayerMoney +# Amount of money that new players will start with. +# If you want to start with silver, use for example 100 +# (100 copper = 1 silver) +# Default: 0 +# +# MaxHonorPoints +# Max honor points that player can have. +# Default: 75000 +# +# StartHonorPoints +# Amount of honor that new players will start with +# Default: 0 +# +# MaxArenaPoints +# Max arena points that player can have. +# Default: 5000 +# +# StartArenaPoints +# Amount of arena points that new players will start with +# Default: 0 +# +# InstantLogout +# Enable or disable instant logout for security level (0..4) or higher +# (NOT in combat/while dueling/while falling) +# Default: 1 (Mods/GMs/Admins) +# +# DisableWaterBreath +# Disable/enable waterbreathing for security level (0..4) or higher +# Default: 4 (None) +# +# AllFlightPaths +# Players will start with all flight paths +# (Note: ALL flight paths, not only player's team) +# Default: 0 (false) +# 1 (true) +# +# InstantFlightPaths +# Flight paths will take players to their destination instantly, instead +# of making them wait to fly there. +# Default: 0 (false) +# 1 (true) +# +# AlwaysMaxSkillForLevel +# Players will automatically gain max level dependent (weapon/defense) +# skill when logging in, leveling up etc. +# Default: 0 (false) +# 1 (true) +# +# ActivateWeather +# Activate weather system +# Default: 1 (true) +# 0 (false) +# +# CastUnstuck +# Allow cast or not Unstuck spell at .start or client Help option use +# Default: 1 (true) +# 0 (false) +# +# Instance.IgnoreLevel +# Ignore level requirement to enter instance +# Default: 0 (false) +# 1 (true) +# +# Instance.IgnoreRaid +# Ignore raid requirement to enter instance +# Default: 0 (false) +# 1 (true) +# +# Instance.ResetTimeHour +# The hour of the day (0-23) when the global instance resets occur. +# Default: 4 +# +# Instance.UnloadDelay +# Unload the instance map from memory after some time +# if no players are inside. +# Default: 1800000 (miliseconds 30 minutes) +# 0 (instance maps are kept in memory until they are reset) +# +# Quests.LowLevelHideDiff +# Quest level difference to hide for player low level quests: +# if player_level > quest_level + LowLevelQuestsHideDiff then quest +# "!" mark not show for quest giver +# Default: 4 +# -1 (show all available quests marks) +# +# Quests.HighLevelHideDiff +# Quest level difference to hide for player high level quests: +# if player_level < quest_min_level - HighLevelQuestsHideDiff then +# quest "!" mark not show for quest giver +# Default: 7 +# -1 (show all available quests marks) +# +# Guild.EventLogRecordsCount +# Count of guild event log records stored in guild_eventlog table +# Increase to store more guild events in table, minimum is 100 +# You can set it to very high value to prevent oldest guild events to +# be rewritten by latest guild events; can slow down performance +# Default: 100 +# +# Guild.BankEventLogRecordsCount +# Count of guild_bank event log records stored in +# guild_bank_eventlog table +# Increase to store more guild_bank events in table - minimum is 25 +# (GUILD_BANK_MAX_LOGS) for each guild_bank tab +# Useful when you don't want old log events to be overwritten by new, +# but increasing can slow down performance +# Default: 25 +# +# MaxPrimaryTradeSkill +# Max count that player can learn the primary trade skill. +# Default: 2 +# Max : 10 +# +# MinPetitionSigns +# Min signatures count to creating guild (0..9). +# Default: 9 +# +# MaxGroupXPDistance +# Max distance to creature for group member to get XP at creature death. +# Default: 74 +# +# MailDeliveryDelay +# Mail delivery delay time for item sending +# Default: 3600 sec (1 hour) +# +# SkillChance.Prospecting +# For prospecting skillup impossible by default, +# but can be allowed as custom setting +# Default: 0 - no skilups +# 1 - skilups possible +# +# SkillChance.Milling +# For milling skillup impossible by default, +# but can be allowed as custom setting +# Default: 0 - no skilups +# 1 - skilups possible +# +# OffhandCheckAtSpellUnlearn +# Unlearning certain spells can change offhand weapon restrictions +# for equip slots. +# Default: 0 - recheck offhand slot weapon only at zone update +# 1 - recheck offhand slot weapon at unlearning a spell +# +# ClientCacheVersion +# Client cache version for client cache data reset. Use any different +# from DB value and not recently used for triggering reset. +# Default: 0 (use DB value from world DB db_version.cache_id field) +# +# Event.Announce +# Default: 0 (false) +# 1 (true) +# +# BeepAtStart +# Beep at core start finished (mostly work only at Unix/Linux systems) +# Default: 1 (true) +# 0 (false) +# +# Motd +# Message of the Day. Displayed at worldlogin for every user +# Use '@' for a newline, and be sure to escape special characters. +# Example: "Welcome to John\'s Server@WinterGrasp is closed." +# +# Server.LoginInfo +# Enable/disable sending server info (core version) on login. +# Default: 0 - disable +# 1 - enable +# +############################################################################### + +GameType = 0 +RealmZone = 1 +Expansion = 2 +DBC.Locale = 255 +DeclinedNames = 0 +StrictPlayerNames = 0 +StrictCharterNames = 0 +StrictPetNames = 0 +MaxWhoListReturns = 49 +MinPlayerName = 2 +MinCharterName = 2 +MinPetName = 2 +CharactersCreatingDisabled = 0 +CharactersPerAccount = 50 +CharactersPerRealm = 10 +HeroicCharactersPerRealm = 1 +MinLevelForHeroicCharacterCreating = 55 +SkipCinematics = 0 +MaxPlayerLevel = 80 +MinDualSpecLevel = 40 +StartPlayerLevel = 1 +StartHeroicPlayerLevel = 55 +StartPlayerMoney = 0 +MaxHonorPoints = 75000 +StartHonorPoints = 0 +MaxArenaPoints = 5000 +StartArenaPoints = 0 +InstantLogout = 1 +DisableWaterBreath = 4 +AllFlightPaths = 0 +InstantFlightPaths = 0 +AlwaysMaxSkillForLevel = 0 +ActivateWeather = 1 +CastUnstuck = 1 +Instance.IgnoreLevel = 0 +Instance.IgnoreRaid = 0 +Instance.ResetTimeHour = 4 +Instance.UnloadDelay = 1800000 +Quests.LowLevelHideDiff = 4 +Quests.HighLevelHideDiff = 7 +Guild.EventLogRecordsCount = 100 +Guild.BankEventLogRecordsCount = 25 +MaxPrimaryTradeSkill = 2 +MinPetitionSigns = 9 +MaxGroupXPDistance = 74 +MailDeliveryDelay = 3600 +SkillChance.Prospecting = 0 +SkillChance.Milling = 0 +OffhandCheckAtSpellUnlearn = 0 +ClientCacheVersion = 0 +Event.Announce = 0 +BeepAtStart = 1 +Motd = "Welcome to a Trinity Core server." +Server.LoginInfo = 0 + +############################################################################### +# PLAYER INTERACTION +# +# AllowTwoSide.Accounts +# Allow or not accounts to create characters in the 2 teams +# in any game type. +# Default: 1 (Allowed) +# 0 (Not allowed) +# +# AllowTwoSide.Interaction.Chat +# AllowTwoSide.Interaction.Channel +# AllowTwoSide.Interaction.Group +# AllowTwoSide.Interaction.Guild +# AllowTwoSide.Interaction.Auction +# AllowTwoSide.Interaction.Mail +# Allow or not common :chat(say,yell) +# channel(chat) +# group(join) +# guild(join) +# merge all auction houses for players from +# different teams +# send mail to other team. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# AllowTwoSide.WhoList +# Allow or not show player from both team in who list. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# AllowTwoSide.AddFriend +# Allow or not adding friends from other team in friend list. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# AllowTwoSide.Trade +# Allow or not trading with other team in party. +# Default: 0 (Not allowed) +# 1 (Allowed) +# +# TalentsInspecting +# Allow other players see character talents in inspect dialog +# (Characters in Gamemaster mode can inspect talents always) +# Default: 1 (allow) +# 0 (not allow) +# +############################################################################### + +AllowTwoSide.Accounts = 1 +AllowTwoSide.Interaction.Chat = 0 +AllowTwoSide.Interaction.Channel = 0 +AllowTwoSide.Interaction.Group = 0 +AllowTwoSide.Interaction.Guild = 0 +AllowTwoSide.Interaction.Auction = 0 +AllowTwoSide.Interaction.Mail = 0 +AllowTwoSide.WhoList = 0 +AllowTwoSide.AddFriend = 0 +AllowTwoSide.Trade = 0 +TalentsInspecting = 1 + +############################################################################### +# CREATURE SETTINGS +# +# ThreatRadius +# Radius for creature to evade after being +# pulled away from combat start point +# If ThreatRadius is less than creature aggro radius +# then aggro radius will be used +# Default: 60 yards +# +# Rate.Creature.Aggro +# Aggro radius percent or off. +# Default: 1 - 100% +# 1.5 - 150% +# 0 - off (0%) +# +# CreatureFamilyFleeAssistanceRadius +# Radius which creature will use to seek for a nearby creature +# for assistance. Creature will flee to this creature. +# Default: 30 +# 0 - off +# +# CreatureFamilyAssistanceRadius +# Radius which creature will use to call assistance without moving +# Default: 10 +# 0 - off +# +# CreatureFamilyAssistanceDelay +# Reaction time for creature assistance call +# Default: 1500 (1.5s) +# +# CreatureFamilyFleeDelay +# Time during which creature can flee when no assistant found +# Default: 7000 (7s) +# +# WorldBossLevelDiff +# Difference for boss dynamic level with target +# Default: 3 +# +# Corpse.Decay.NORMAL +# Corpse.Decay.RARE +# Corpse.Decay.ELITE +# Corpse.Decay.RAREELITE +# Corpse.Decay.WORLDBOSS +# Seconds until creature corpse will decay if not looted or skinned. +# Default: 60, 300, 300, 300, 3600 +# +# Rate.Corpse.Decay.Looted +# Controls how long the creature corpse stays after it had been looted, +# as a multiplier of its Corpse.Decay.* config. +# Default: 0.5 +# +# Rate.Creature.Normal.Damage +# Rate.Creature.Elite.Elite.Damage +# Rate.Creature.Elite.RAREELITE.Damage +# Rate.Creature.Elite.WORLDBOSS.Damage +# Rate.Creature.Elite.RARE.Damage +# Creature Damage Rates. +# Examples: 2 - creatures will damage 2x, 1.7 - 1.7x. +# +# Rate.Creature.Normal.SpellDamage +# Rate.Creature.Elite.Elite.SpellDamage +# Rate.Creature.Elite.RAREELITE.SpellDamage +# Rate.Creature.Elite.WORLDBOSS.SpellDamag +# Rate.Creature.Elite.RARE.SpellDamage +# Creature Spell Damage Rates. +# Examples: 2 - creatures will damage with spells 2x, 1.7 - 1.7x. +# +# Rate.Creature.Normal.HP +# Rate.Creature.Elite.Elite.HP +# Rate.Creature.Elite.RAREELITE.HP +# Rate.Creature.Elite.WORLDBOSS.HP +# Rate.Creature.Elite.RARE.HP +# Creature Health Ammount Modifier. +# Examples: 2 - creatures have 2x health, 1.7 - 1.7x. +# +# ListenRange.Say +# Distance from player to listen text that creature +# (or other world object) says +# Default: 40 +# +# ListenRange.TextEmote +# Distance from player to listen textemote that creature +# (or other world object) says +# Default: 40 +# +# ListenRange.Yell +# Distance from player to listen text that creature +# (or other world object) yells +# Default: 300 +# +############################################################################### + +ThreatRadius = 60 +Rate.Creature.Aggro = 1 +CreatureFamilyFleeAssistanceRadius = 30 +CreatureFamilyAssistanceRadius = 10 +CreatureFamilyAssistanceDelay = 1500 +CreatureFamilyFleeDelay = 7000 +WorldBossLevelDiff = 3 +Corpse.Decay.NORMAL = 60 +Corpse.Decay.RARE = 300 +Corpse.Decay.ELITE = 300 +Corpse.Decay.RAREELITE = 300 +Corpse.Decay.WORLDBOSS = 3600 +Rate.Corpse.Decay.Looted = 0.5 +Rate.Creature.Normal.Damage = 1 +Rate.Creature.Elite.Elite.Damage = 1 +Rate.Creature.Elite.RAREELITE.Damage = 1 +Rate.Creature.Elite.WORLDBOSS.Damage = 1 +Rate.Creature.Elite.RARE.Damage = 1 +Rate.Creature.Normal.SpellDamage = 1 +Rate.Creature.Elite.Elite.SpellDamage = 1 +Rate.Creature.Elite.RAREELITE.SpellDamage = 1 +Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1 +Rate.Creature.Elite.RARE.SpellDamage = 1 +Rate.Creature.Normal.HP = 1 +Rate.Creature.Elite.Elite.HP = 1 +Rate.Creature.Elite.RAREELITE.HP = 1 +Rate.Creature.Elite.WORLDBOSS.HP = 1 +Rate.Creature.Elite.RARE.HP = 1 +ListenRange.Say = 40 +ListenRange.TextEmote = 40 +ListenRange.Yell = 300 + +############################################################################### +# CHAT SETTINGS +# +# ChatFakeMessagePreventing +# Chat protection from creating fake messages using a lot spaces +# (other invisible symbols), +# not applied to addon language messages, but can cause old addons +# that use normal languages for sending data to another clients. +# Default: 0 (disible fake messages preventing) +# 1 (enabled fake messages preventing) +# +# ChatStrictLinkChecking.Severity +# Check chat messages for ingame links to +# spells, items, quests, achievements etc. +# Default: 0 (disable link checking) +# 1 (check if only valid pipe commands are used. +# This prevents posting pictures for example) +# 2 (verifiy that pipe commands are used in a correct order) +# 3 (check if color, entry and name don't contradict +# each other. For correct work, please assure +# that you have extracted locale DBCs of every language +# specific client playing on this server.) +# +# ChatStrictLinkChecking.Kick +# Defines what should be done if a message is considered to contain +# invalid pipe commands. +# Default: 0 (silently ignore message) +# 1 (kick players who sent invalid formed messages) +# +# ChatFlood.MessageCount +# Chat anti-flood protection, haste message count to activate protection +# Default: 10 +# 0 (disible anti-flood protection) +# +# ChatFlood.MessageDelay +# Chat anti-flood protection, minimum message delay to count message +# Default: 1 (in secs) +# +# ChatFlood.MuteTime +# Chat anti-flood protection, mute time at activation flood protection +# Default: 10 (in secs) +# +# Channel.RestrictedLfg +# Restrict LookupForGroup channel to registered in LFG tool players +# Default: 1 (allow join to channel only if active in LFG) +# 0 (allow join to channel in any time) +# +# Channel.SilentlyGMJoin +# Silently join GM characters (security level > 1) to channels +# Default: 0 (join announcement in normal way) +# 1 (GM join without announcement) +# +# ChatLevelReq.Channel +# The required level of character to be able to write in chat channels +# Default: 1 (From level 1) +# +# ChatLevelReq.Whisper +# The required level of character to be able to whisper +# Default: 1 (From level 1) +# +# ChatLevelReq.Say +# The required level of character to be able to say/yell/emote +# Default: 1 (From level 1) +# +# AllowPlayerCommands +# Allowed the players to use commands +# Default: 1 (allow) +# +############################################################################### + +ChatFakeMessagePreventing = 0 +ChatStrictLinkChecking.Severity = 0 +ChatStrictLinkChecking.Kick = 0 +ChatFlood.MessageCount = 10 +ChatFlood.MessageDelay = 1 +ChatFlood.MuteTime = 10 +Channel.RestrictedLfg = 1 +Channel.SilentlyGMJoin = 0 +ChatLevelReq.Channel = 1 +ChatLevelReq.Whisper = 1 +ChatLevelReq.Say = 1 +AllowPlayerCommands = 1 + +############################################################################### +# GAME MASTER SETTINGS +# +# GM.LoginState +# GM mode at login +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.Visible +# GM visibility at login +# Default: 2 (last save state) +# 0 (invisible) +# 1 (visible) +# +# GM.AcceptTickets +# Is GM accepting tickets from player by default or not. +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.Chat +# GM chat mode at login +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.WhisperingTo +# Is GM accepting whispers from player by default or not. +# Default: 2 (last save state) +# 0 (disable) +# 1 (enable) +# +# GM.InGMList.Level +# Max GM level showed in GM list (if visible) in non-GM state (.gm off) +# 0 (only players) +# 1 (only moderators) +# 2 (only gamemasters) +# Default: 3 (anyone) +# +# GM.InWhoList.Level +# Max GM level showed in who list (if visible). +# 0 (only players) +# 1 (only moderators) +# 2 (only gamemasters) +# Default: 3 (anyone) +# +# GM.LogTrade +# Include GM trade and trade slot enchanting operations in GM log +# Default: 1 (include) +# 0 (not include) +# +# GM.StartLevel +# GM starting level (1-100) +# Default: 1 +# +# GM.AllowInvite +# Is GM accepting invites from players by default or not +# Default: 0 (false) +# 1 (true) +# +# GM.AllowFriend +# Are players allowed to add GMs to their friend list +# Default: 0 (false) +# 1 (true) +# +# GM.LowerSecurity +# Disallow a lower security member to interact with +# a higher one using commands +# Default: 0 (disable) +# 1 (enable) +# +# GM.AllowAchievementGain +# If enabled it allows gaining achievements for GM characters +# Default: 1 (enable) +# 0 (disable) +# +############################################################################### + +GM.LoginState = 2 +GM.Visible = 2 +GM.AcceptTickets = 2 +GM.Chat = 2 +GM.WhisperingTo = 2 +GM.InGMList.Level = 3 +GM.InWhoList.Level = 3 +GM.LogTrade = 1 +GM.StartLevel = 80 +GM.AllowInvite = 0 +GM.AllowFriend = 0 +GM.LowerSecurity = 0 +GM.AllowAchievementGain = 1 + +############################################################################### +# VISIBILITY AND RADIUSES +# +# Visibility.GroupMode +# Group visibility modes +# Default: 0 (standard setting: only members from same group can +# 100% auto detect invisible player) +# 1 (raid members 100% auto detect invisible player from +# same raid) +# 2 (players from same team can 100% auto detect +# invisible player) +# +# Visibility.Distance.Continents +# Visibility.Distance.Instances +# Visibility.Distance.BGArenas +# Visibility distance for different ingame object in different maps. +# Visibility on continents on offy ~90 yards. In BG/Arenas ~180. +# For instances default ~120. +# Max limited by active player zone: ~ 333 +# Min limit is max aggro radius (45) * Rate.Creature.Aggro +# +# Visibility.Distance.Object +# Visible distance for gameobject, dynobject, bodies, corpses, bones +# Min limit is iteraction distance (5) +# +# Visibility.Distance.InFlight +# Visible distance for player in flight +# Min limit is 0 (not show any objects) +# +# Visibility.Distance.Grey.Unit +# Visibility grey distance for creatures/players (fast changing objects) +# addition to appropriate object type Visibility.Distance.* use in case +# visibility removing to object (except corpse around distances) +# If D is distance and G is grey distance then object +# make visible if distance to it <= D +# but make non visible if distance > D+G +# Default: 1 (yard) +# +# Visibility.Distance.Grey.Object +# Visibility grey distance for dynobjects/gameobjects/corpses/creatures +# Default: 10 (yards) +# +############################################################################### + +Visibility.GroupMode = 0 +Visibility.Distance.Continents = 90 +Visibility.Distance.Instances = 120 +Visibility.Distance.BGArenas = 180 +Visibility.Distance.Object = 100 +Visibility.Distance.InFlight = 100 +Visibility.Distance.Grey.Unit = 1 +Visibility.Distance.Grey.Object = 10 + +Visibility.Notify.Period.OnContinents = 1000 +Visibility.Notify.Period.InInstances = 1000 +Visibility.Notify.Period.InBGArenas = 1000 + +############################################################################### +# SERVER RATES +# +# Rate.Health +# Rate.Mana +# Rate.Rage.Income +# Rate.Rage.Loss +# Rate.RunicPower.Income +# Rate.RunicPower.Loss +# Rate.Focus +# Rate.Loyalty +# Health and power regeneration and rage income from damage. +# Default: 1 +# +# Rate.Skill.Discovery +# Skill Discovery Rates +# Default: 1 +# +# Rate.Drop.Item.Poor +# Rate.Drop.Item.Normal +# Rate.Drop.Item.Uncommon +# Rate.Drop.Item.Rare +# Rate.Drop.Item.Epic +# Rate.Drop.Item.Legendary +# Rate.Drop.Item.Artifact +# Rate.Drop.Item.Referenced +# Rate.Drop.Money +# Drop rates (items by quality and money) +# Default: 1 +# +# Rate.Drop.Money +# Drop rates +# Default: 1 +# +# Rate.XP.Kill +# Rate.XP.Quest +# Rate.XP.Explore +# XP rates +# Default: 1 +# +# Rate.RepairCost +# Repair cost rate +# Default: 1 - standard cost +# 2 - double cost +# 0.5 - half cost +# +# Rate.Rest.InGame +# Rate.Rest.Offline.InTavernOrCity +# Rate.Rest.Offline.InWilderness +# Resting points grow rates +# Default: 1 - standard rate +# 2 - double rate +# 0.5 - half rate +# +# Rate.Damage.Fall +# Damage after fall rate. +# Default: 1 - standard damage +# 2 - double damage +# 0.5 - half damage +# +# Rate.Auction.Time +# Rate.Auction.Deposit +# Rate.Auction.Cut +# Auction rates +# (auction time, deposit get at auction start, +# auction cut from price at auction end) +# +# Rate.Honor +# Honor gain rate +# +# Rate.Mining.Amount +# Rate.Mining.Next +# Mining Rates +# Mining.Amount changes minimum/maximum use times of a deposit, +# Mining.Next changes chance to have next use of a deposit +# +# Rate.Talent +# Talent Point rates +# Default: 1 +# +# Rate.Reputation.Gain +# Reputation Gain rate +# Default: 1 +# +# Rate.Reputation.LowLevel.Kill +# Reputation Gain from low level kill (grey creture) +# Default: 1 +# +# Rate.Reputation.LowLevel.Quest +# Reputation Gain rate +# Default: 1 +# +# Rate.MoveSpeed +# Multiply the default movement speed for players +# and whatever they're controlling. +# Default: 1 - no change +# 1.4 - 40% increase +# +# Rate.InstanceResetTime +# Multiplier for the number of days in between +# global raid/heroic instance resets. +# Default: 1 +# +# SkillGain.Crafting +# SkillGain.Defense +# SkillGain.Gathering +# SkillGain.Weapon +# Crafting/defense/gathering/weapon skills gain at skill grow (1,2,...) +# Default: 1 +# +# SkillChance.Orange +# SkillChance.Yellow +# SkillChance.Green +# SkillChance.Grey +# Skill chance values (0..100) +# Default: 100-75-25-0 +# +# SkillChance.MiningSteps +# SkillChance.SkinningSteps +# For skinning and Mining chance decrease with skill level. +# Default: 0 - no decrease +# 75 - in 2 times each 75 skill points +# +# DurabilityLoss.InPvP +# If true, players take durability loss on death in PvP. +# Default: 0 (false) +# 1 (true) +# +# DurabilityLoss.OnDeath +# Durability loss percentage on death +# Default: 10 - standard +# 20 - double +# 5 - half +# +# DurabilityLossChance.Damage +# Chance lost one from equiped items durability +# point at damage apply or receive. +# Default: 0.5 (100/0.5 = 200) +# Each 200 damage apply one from 19 possible equipped items +# +# DurabilityLossChance.Absorb +# Chance lost one from armor items durability point at damage absorb. +# Default: 0.5 (100/0.5 = 200) +# Each 200 absorbs apply one from 15 possible armor equipped items +# +# DurabilityLossChance.Parry +# Chance lost weapon durability point at parry. +# Default: 0.05 (100/0.05 = 2000) +# Each 2000 parry attacks main weapon lost point +# +# DurabilityLossChance.Block +# Chance lost sheild durability point at damage block. +# Default: 0.05 (100/0.05 = 2000) +# Each 2000 partly or full blocked attacks shield lost point +# +# Death.SicknessLevel +# Starting Character start gain sickness at spirit resurrection (1 min) +# Default: 11 +# -10 - character will have full time +# (10min) sickness at 1 level +# maxplayerlevel+1 +# - character will not have sickess at any level +# +# Death.CorpseReclaimDelay.PvP +# Death.CorpseReclaimDelay.PvE +# Enabled/disabled increase corpse reclaim delay at PvP/PvE deaths +# Default: 1 (enabled) +# 0 (disabled) +# +# Death.Bones.World +# Death.Bones.BattlegroundOrArena +# Enable/disable creating bones instead corpse at resurrection +# (in normal zones/instances, or battleground/arenas) +# Default: 1 (enabled) +# 0 (disabled) +# +# Die.Command.Mode +# Switch between two possible .die modes, where mode 1 kills +# and does not trigger anything such as loot, and mode 0 does +# damage and does trigger things such as loot +# Default: 1 +# 0 +# +############################################################################### + +Rate.Health = 1 +Rate.Mana = 1 +Rate.Rage.Income = 1 +Rate.Rage.Loss = 1 +Rate.RunicPower.Income = 1 +Rate.RunicPower.Loss = 1 +Rate.Focus = 1 +Rate.Loyalty = 1 +Rate.Skill.Discovery = 1 +Rate.Drop.Item.Poor = 1 +Rate.Drop.Item.Normal = 1 +Rate.Drop.Item.Uncommon = 1 +Rate.Drop.Item.Rare = 1 +Rate.Drop.Item.Epic = 1 +Rate.Drop.Item.Legendary = 1 +Rate.Drop.Item.Artifact = 1 +Rate.Drop.Item.Referenced = 1 +Rate.Drop.Money = 1 +Rate.XP.Kill = 1 +Rate.XP.Quest = 1 +Rate.XP.Explore = 1 +Rate.RepairCost = 1 +Rate.Rest.InGame = 1 +Rate.Rest.Offline.InTavernOrCity = 1 +Rate.Rest.Offline.InWilderness = 1 +Rate.Damage.Fall = 1 +Rate.Auction.Time = 1 +Rate.Auction.Deposit = 1 +Rate.Auction.Cut = 1 +Rate.Honor = 1 +Rate.Mining.Amount = 1 +Rate.Mining.Next = 1 +Rate.Talent = 1 +Rate.Reputation.Gain = 1 +Rate.Reputation.LowLevel.Kill = 1 +Rate.Reputation.LowLevel.Quest = 1 +Rate.MoveSpeed = 1 +Rate.InstanceResetTime = 1 +SkillGain.Crafting = 1 +SkillGain.Defense = 1 +SkillGain.Gathering = 1 +SkillGain.Weapon = 1 +SkillChance.Orange = 100 +SkillChance.Yellow = 75 +SkillChance.Green = 25 +SkillChance.Grey = 0 +SkillChance.MiningSteps = 0 +SkillChance.SkinningSteps = 0 +DurabilityLoss.InPvP = 0 +DurabilityLoss.OnDeath = 10 +DurabilityLossChance.Damage = 0.5 +DurabilityLossChance.Absorb = 0.5 +DurabilityLossChance.Parry = 0.05 +DurabilityLossChance.Block = 0.05 +Death.SicknessLevel = 11 +Death.CorpseReclaimDelay.PvP = 1 +Death.CorpseReclaimDelay.PvE = 0 +Death.Bones.World = 1 +Death.Bones.BattlegroundOrArena = 1 +Die.Command.Mode = 1 + +############################################################################### +# AUTO BROADCAST +# +# AutoBroadcast.On +# Enable auto broadcast +# Default: 0 - off +# 1 - on +# +# AutoBroadcast.Center +# Display method +# Default: 0 - announce +# 1 - notify +# 2 - both +# +# AutoBroadcast.Timer +# Timer for auto broadcast (in milliseconds) +# +############################################################################### + +AutoBroadcast.On = 0 +AutoBroadcast.Center = 0 +AutoBroadcast.Timer = 60000 + +############################################################################### +# BATTLEGROUND CONFIG +# +# Battleground.CastDeserter +# Cast Deserter spell at player who leave battleground in progress +# Default: 1 (enable) +# 0 (disable) +# +# Battleground.QueueAnnouncer.Enable +# Enable queue announcer posting to chat +# Default: 0 (disable) +# 1 (enable) +# +# Battleground.QueueAnnouncer.PlayerOnly +# Enable queue announcer posting to chat +# Default: 0 (disable) +# 1 (enable) +# +# Battleground.InvitationType +# Set Battleground invitation type +# Default: 0 (normal - invite as much players to bg as possible, +# don't bother with ballance) +# 1 (Experimental - don't allow to invite much more players +# of one faction) +# +# Battleground.PrematureFinishTimer +# The time to end the bg if there are less than MinPlayersPerTeam on +# one side (in milliseconds) +# Default: 300000 (5 minutes) +# 0 - disable (not recommended) +# +# BattleGround.PremadeGroupWaitForMatch +# The time in which premade group of 1 faction waits in BG Queue +# for premade group of other faction +# Default: 1800000 (30 minutes) +# 0 - disable (not recommended) +# +# Battleground.GiveXPForKills +# Give experience for honorable kills in battlegrounds +# Default: 0 (disable) +# 1 (enable) +# +# Battleground.Random.ResetHour +# Reset random battlegrounds at specified hour of the day (0-23) +# Default: 6 +# +############################################################################### + +Battleground.CastDeserter = 1 +Battleground.QueueAnnouncer.Enable = 0 +Battleground.QueueAnnouncer.PlayerOnly = 0 +Battleground.InvitationType = 0 +BattleGround.PrematureFinishTimer = 300000 +BattleGround.PremadeGroupWaitForMatch = 1800000 +Battleground.GiveXPForKills = 0 +Battleground.Random.ResetHour = 6 + +############################################################################### +# ARENA CONFIG +# +# Arena.MaxRatingDifference +# The maximum rating difference between two groups in rated matches +# Default: 150 (enable, recommended) +# 0 (disable, rating difference is discarded) +# +# Arena.RatingDiscardTimer +# After the specified milliseconds has passed, +# rating information will be discarded when selecting teams for +# matches also initiates an update by this timer +# Default: 600000 (10 minutes, recommended) +# 0 (disable) +# +# Arena.AutoDistributePoints +# Set if arena points should be distributed automatically, +# or by GM command +# Default: 0 (disable) (recommended): +# use gm command or sql query to distribute the points +# 1 (enable) arena points are distributed automatically +# +# Arena.AutoDistributeInterval +# How often should the distribution take place +# If automatic distribution is enabled in days +# Default: 7 (weekly) +# +# Arena.QueueAnnouncer.Enable +# Enable bg queue announcer posting to chat +# Default: 0 (disable) +# 1 (enable) +# +# Arena.ArenaSeason.ID +# Current area season id show in client +# Default: 1 +# +# Arena.ArenaSeason.InProgress +# Current area season state +# Default: 1 (active) +# 0 (finished) +# +# Arena.ArenaStartRating +# Start arena team command rating +# Default: 1500 +# +# Arena.StartPersonalRating +# Start personal rating on entry in team +# Default: 1500 +# +############################################################################### + +Arena.MaxRatingDifference = 150 +Arena.RatingDiscardTimer = 600000 +Arena.AutoDistributePoints = 0 +Arena.AutoDistributeInterval = 7 +Arena.QueueAnnouncer.Enable = 0 +Arena.QueueAnnouncer.PlayerOnly = 0 +Arena.ArenaSeason.ID = 1 +Arena.ArenaSeason.InProgress = 1 +Arena.ArenaStartRating = 0 +Arena.ArenaStartPersonalRating = 0 + +############################################################################### +# NETWORK CONFIG +# +# Network.Threads +# Number of threads for network, +# recommend 1 thread per 1000 connections. +# Default: 1 +# +# Network.OutKBuff +# The size of the output kernel buffer used +# ( SO_SNDBUF socket option, tcp manual ). +# Default: -1 (Use system default setting) +# +# Network.OutUBuff +# Userspace buffer for output. +# This is amount of memory reserved per each connection. +# Default: 65536 +# +# Network.TcpNoDelay: +# TCP Nagle algorithm setting +# Default: 0 (enable Nagle algorithm, less traffic, more latency) +# 1 (TCP_NO_DELAY, disable Nagle algorithm, +# more traffic but less latency) +# +############################################################################### + +Network.Threads = 1 +Network.OutKBuff = -1 +Network.OutUBuff = 65536 +Network.TcpNodelay = 1 + +############################################################################### +# AUCTION HOUSE BOT SETTINGS +# +# AuctionHouseBot.DEBUG +# Enable/Disable Debugging output +# Default 0 (disabled) +# +# AuctionHouseBot.DEBUG_FILTERS +# Enable/Disable Debugging output from Filters +# Default 0 (disabled) +# +# AuctionHouseBot.EnableSeller +# Enable/Disable the part of AHBot that puts items up for auction +# Default 0 (disabled) +# +# AuctionHouseBot.EnableBuyer +# Enable/Disable the part of AHBot that buys items from players +# Default 0 (disabled) +# +# AuctionHouseBot.UseBuyPriceForSeller +# Should the Seller use BuyPrice or SellPrice to determine Bid Prices +# Default 0 (use SellPrice) +# +# AuctionHouseBot.UseBuyPriceForBuyer +# Should the Buyer use BuyPrice or SellPrice to determine Bid Prices +# Default 0 (use SellPrice) +# +# Auction House Bot character data +# AuctionHouseBot.Account is the account number +# (in realmd->account table) of the player you want to run +# as the auction bot. +# AuctionHouseBot.GUID is the GUID (in characters->characters table) +# of the player you want to run as the auction bot. +# Default: 0 (Auction House Bot disabled) +# +# AuctionHouseBot.ItemsPerCycle +# Number of Items to Add/Remove from the AH during mass operations +# Default 200 +# +############################################################################### + +AuctionHouseBot.DEBUG = 0 +AuctionHouseBot.DEBUG_FILTERS = 0 +AuctionHouseBot.EnableSeller = 0 +AuctionHouseBot.EnableBuyer = 0 +AuctionHouseBot.UseBuyPriceForSeller = 0 +AuctionHouseBot.UseBuyPriceForBuyer = 0 +AuctionHouseBot.Account = 0 +AuctionHouseBot.GUID = 0 +AuctionHouseBot.ItemsPerCycle = 200 + +############################################################################### +# AUCTION HOUSE BOT FILTERS PART 1 +# +# AuctionHouseBot.VendorItems +# Include items that can be bought from vendors. +# Default 0 (False) +# +# AuctionHouseBot.VendorTradeGoods +# Include Trade Goods that can be bought from vendors. +# Default 0 (False) +# +# AuctionHouseBot.LootItems +# Include items that can be looted or fished for. +# Default 1 (True) +# +# AuctionHouseBot.LootTradeGoods +# Include Trade Goods that can be looted or fished for. +# Default 1 (True) +# +# AuctionHouseBot.OtherItems +# Include misc. items. +# Default 0 (False) +# +# AuctionHouseBot.OtherTradeGoods +# Include misc. Trade Goods. +# Default 0 (False) +# +# AuctionHouseBot.Bonding_types +# Indicates which bonding types to allow seller to put up for auction +# No_Bind +# Default 1 (True) +# Bind_When_Picked_Up +# Default 0 (False) +# Bind_When_Equipped +# Default 1 (True) +# Bind_When_Use +# Default 1 (True) +# Bind_Quest_Item +# Default 0 (False) +# +# AuctionHouseBot.DisableBeta_PTR_Unused +# Disable certain items that are usually unavailable to Players +# Default 0 (False) +# +# AuctionHouseBot.DisablePermEnchant +# Disable Items with a Permanent Enchantment +# Default 0 (False) +# +# AuctionHouseBot.DisableConjured +# Disable Conjured Items +# Default 0 (False) +# +# AuctionHouseBot.DisableGems +# Disable Gems +# Default 0 (False) +# +# AuctionHouseBot.DisableMoney +# Disable Items that are used as money +# Default 0 (False) +# +# AuctionHouseBot.DisableMoneyLoot +# Disable Items that have Money as a loot +# Default 0 (False) +# +# AuctionHouseBot.DisableLootable +# Disable Items that have other items as loot +# Default 0 (False) +# +# AuctionHouseBot.DisableKeys +# Disable Items that are keys +# Default 0 (False) +# +# AuctionHouseBot.DisableDuration +# Disable Items with a duration +# Default 0 (False) +# +# AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel +# Disable items that are BOP or Quest Item +# with a Required level that is less than the Item Level +# (This prevents a level 10 with a level 60 weapon or armor) +# (May need further refinement) +# Default 0 (False) +# +############################################################################### + +AuctionHouseBot.VendorItems = 0 +AuctionHouseBot.VendorTradeGoods = 0 +AuctionHouseBot.LootItems = 1 +AuctionHouseBot.LootTradeGoods = 1 +AuctionHouseBot.OtherItems = 0 +AuctionHouseBot.OtherTradeGoods = 0 +AuctionHouseBot.No_Bind = 1 +AuctionHouseBot.Bind_When_Picked_Up = 0 +AuctionHouseBot.Bind_When_Equipped = 1 +AuctionHouseBot.Bind_When_Use = 1 +AuctionHouseBot.Bind_Quest_Item = 0 +AuctionHouseBot.DisableBeta_PTR_Unused = 0 +AuctionHouseBot.DisablePermEnchant = 0 +AuctionHouseBot.DisableConjured = 0 +AuctionHouseBot.DisableGems = 0 +AuctionHouseBot.DisableMoney = 0 +AuctionHouseBot.DisableMoneyLoot = 0 +AuctionHouseBot.DisableLootable = 0 +AuctionHouseBot.DisableKeys = 0 +AuctionHouseBot.DisableDuration = 0 +AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel = 0 + +############################################################################### +# AUCTION HOUSE BOT FILTERS PART 2 +# +# These Filters are boolean (0 or 1) and will disable items that are +# specifically meant for the Class named. +# (UnusedClass is Class 10, which was skipped for some reason) +# Default 0 (allowed) +# +############################################################################### + +AuctionHouseBot.DisableWarriorItems = 0 +AuctionHouseBot.DisablePaladinItems = 0 +AuctionHouseBot.DisableHunterItems = 0 +AuctionHouseBot.DisableRogueItems = 0 +AuctionHouseBot.DisablePriestItems = 0 +AuctionHouseBot.DisableDKItems = 0 +AuctionHouseBot.DisableShamanItems = 0 +AuctionHouseBot.DisableMageItems = 0 +AuctionHouseBot.DisableWarlockItems = 0 +AuctionHouseBot.DisableUnusedClassItems = 0 +AuctionHouseBot.DisableDruidItems = 0 + +############################################################################### +# AUCTION HOUSE BOT FILTERS PART 3 +# +# AuctionHouseBot.DisableItemsBelowLevel +# Prevent Seller from listing Items below this Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsAboveLevel +# Prevent Seller from listing Items above this Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsBelowLevel +# Prevent Seller from listing Trade Goods below this Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsAboveLevel +# Prevent Seller from listing Trade Goods above this Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsBelowGUID +# Prevent Seller from listing Items below this GUID +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsAboveGUID +# Prevent Seller from listing Items above this GUID +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsBelowGUID +# Prevent Seller from listing Trade Goods below this GUID +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsAboveGUID +# Prevent Seller from listing Trade Goods above this GUID +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsBelowReqLevel +# Prevent Seller from listing Items below this Required Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsAboveReqLevel +# Prevent Seller from listing Items above this Required Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsBelowReqLevel +# Prevent Seller from listing Trade Goods below this Required Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsAboveReqLevel +# Prevent Seller from listing Trade Goods above this Required Level +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsBelowReqSkillRank +# Prevent Seller from listing Items below this Required Skill Rank +# Default 0 (Off) +# +# AuctionHouseBot.DisableItemsAboveReqSkillRank +# Prevent Seller from listing Items above this Required Skill Rank +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsBelowReqSkillRank +# Prevent Seller from listing Trade Goods below this Required Skill Rank +# Default 0 (Off) +# +# AuctionHouseBot.DisableTGsAboveReqSkillRank +# Prevent Seller from listing Trade Goods above this Required Skill Rank +# Default 0 (Off) +# +############################################################################### + +AuctionHouseBot.DisableItemsBelowLevel = 0 +AuctionHouseBot.DisableItemsAboveLevel = 0 +AuctionHouseBot.DisableTGsBelowLevel = 0 +AuctionHouseBot.DisableTGsAboveLevel = 0 +AuctionHouseBot.DisableItemsBelowGUID = 0 +AuctionHouseBot.DisableItemsAboveGUID = 0 +AuctionHouseBot.DisableTGsBelowGUID = 0 +AuctionHouseBot.DisableTGsAboveGUID = 0 +AuctionHouseBot.DisableItemsBelowReqLevel = 0 +AuctionHouseBot.DisableItemsAboveReqLevel = 0 +AuctionHouseBot.DisableTGsBelowReqLevel = 0 +AuctionHouseBot.DisableTGsAboveReqLevel = 0 +AuctionHouseBot.DisableItemsBelowReqSkillRank = 0 +AuctionHouseBot.DisableItemsAboveReqSkillRank = 0 +AuctionHouseBot.DisableTGsBelowReqSkillRank = 0 +AuctionHouseBot.DisableTGsAboveReqSkillRank = 0 + +############################################################################### +# CONSOLE AND REMOTE ACCESS +# +# Console.Enable +# Enable console +# Default: 1 - on +# 0 - off +# +# Ra.Enable +# Enable remote console +# Default: 0 - off +# 1 - on +# +# Ra.IP +# Default remote console ip address, use 0.0.0.0 for every address +# +# Ra.Port +# Default remote console port +# +# Ra.MinLevel +# Minimum level that's required to login,3 by default +# +# Ra.Secure +# Kick client on wrong pass +# +############################################################################### + +Console.Enable = 1 +Ra.Enable = 0 +Ra.IP = 0.0.0.0 +Ra.Port = 3443 +Ra.MinLevel = 3 +Ra.Secure = 1 + +############################################################################### +# CUSTOM SERVER OPTIONS +# +# PlayerStart.AllReputation +# Players will start with most of the high level reputations that are +# needed for items, mounts etc. +# +# PlayerStart.AllSpells +# If enabled, players will start with all their class spells +# (not talents). Useful for instant 80 servers. +# You must populate playercreateinfo_spell_custom table with the spells +# you want, or this WILL NOT WORK! The table has data for all +# classes / races up to TBC expansion. +# Do not enable if you do not know what you are doing! +# Default: 0 - off +# 1 - on +# +# +# PlayerStart.MapsExplored +# Players will start with all maps explored if enabled +# +# MusicInBattleground +# If enabled "L70ETC-Power of the horde" will be played when BG starts +# +# HonorPointsAfterDuel +# The amount of honor points the duel winner will get after a duel. +# Default: 0 - disable +# +# AlwaysMaxWeaponSkill +# Players will automatically gain max weapon/defense skill when +# logging in, leveling up etc. +# +# PvPToken.Enable +# Enable/disable PvP Token System. Players will get a token +# after slaying another player that gives honor. +# +# PvPToken.MapAllowType +# Where players can receive the pvp token +# 4 - In all maps +# 3 - In battlegrounds only +# 2 - In FFA areas only (gurubashi arena etc) +# 1 - In battlegrounds AND FFA areas only +# +# PvPToken.ItemID +# The item players will get after killing someone +# if PvP Token system is enabled. +# Default: 29434 - Badge of justice +# +# PvPToken.ItemCount +# Modify the item ID count - Default: 1 +# +# NoResetTalentsCost +# Enable or disable no cost when reseting talents +# +# Guild.AllowMultipleGuildMaster +# Allow override of 1 Guild Master limit. Additional Guild Masters must +# be set using the ".guild rank" command, not through the UI +# Default: 0 = Only 1 Guild Master per guild +# 1 = Allow more than one Guild Master +# +# ForbiddenMaps +# Map ids that users below SEC_GAMEMASTER cannot enter, +# with delimiter ',' +# Default: "" +# example: "538,90" +# Note that it's HIGHLY DISCOURAGED to forbid starting maps +# (0, 1, 530)! +# +# ShowKickInWorld +# Determines wether a message is broadcasted to the entire server +# when a player gets kicked +# Default: 0 = Disable +# 1 = Enable +# +# RecordUpdateTimeDiffInterval +# Record update time diff to the log file +# update diff can be used as a criterion of performance +# diff < 300: good performance +# diff > 600: bad performance, may be caused by high cpu usage +# Default: 60000 (diff is written into log every 60000 ms or 1 minute. +# >0 = Interval +# 0 = Disable +# +# MinRecordUpdateTimeDiff +# Only record update time diff which is greater than this value +# Default: 10 +# +# PlayerStart.String +# If set to anything other than "", this string will be displayed +# to players when they login to a newly created character. +# Default: "" - send no text +# +# LevelReq.Trade +# The required level of character to be able to trade +# Default: 1 (From level 1) +# +# LevelReq.Ticket +# The required level of character to be able to write tickets +# Default: 1 (From level 1) +# +# LevelReq.Auction +# The required level of character to be able to use auction +# Default: 1 (From level 1) +# +# LevelReq.Mail +# The required level of character to be able to send and receive mail +# Default: 1 (From level 1) +# +############################################################################### + +PlayerStart.AllReputation = 0 +PlayerStart.AllSpells = 0 +PlayerStart.MapsExplored = 0 +MusicInBattleground = 0 +HonorPointsAfterDuel = 0 +AlwaysMaxWeaponSkill = 0 +PvPToken.Enable = 0 +PvPToken.MapAllowType = 4 +PvPToken.ItemID = 29434 +PvPToken.ItemCount = 1 +Guild.AllowMultipleGuildMaster = 0 +NoResetTalentsCost = 0 +ShowKickInWorld = 0 +RecordUpdateTimeDiffInterval = 60000 +MinRecordUpdateTimeDiff = 100 +PlayerStart.String = "" +LevelReq.Trade = 1 +LevelReq.Ticket = 1 +LevelReq.Auction = 1 +LevelReq.Mail = 1 -- cgit v1.2.3