aboutsummaryrefslogtreecommitdiff
path: root/src/server/worldserver
diff options
context:
space:
mode:
authorclick <none@none>2010-06-05 22:44:53 +0200
committerclick <none@none>2010-06-05 22:44:53 +0200
commitfd28bc6aff6fe356262b5ac20e152c6ec8569c43 (patch)
tree79cdf14a40d1fcbb3ded952e67831a8fb0ecdb46 /src/server/worldserver
parent1f87b6d34aee1e98981763adb017a79dfc211b67 (diff)
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
Diffstat (limited to 'src/server/worldserver')
-rw-r--r--src/server/worldserver/CMakeLists.txt79
-rw-r--r--src/server/worldserver/CliRunnable.cpp445
-rw-r--r--src/server/worldserver/CliRunnable.h35
-rw-r--r--src/server/worldserver/Main.cpp154
-rw-r--r--src/server/worldserver/Master.cpp536
-rw-r--r--src/server/worldserver/Master.h48
-rw-r--r--src/server/worldserver/RASocket.cpp265
-rw-r--r--src/server/worldserver/RASocket.h68
-rw-r--r--src/server/worldserver/TrinityCore.icobin0 -> 136606 bytes
-rw-r--r--src/server/worldserver/TrinityCore.rc86
-rw-r--r--src/server/worldserver/WorldRunnable.cpp97
-rw-r--r--src/server/worldserver/WorldRunnable.h35
-rw-r--r--src/server/worldserver/resource.h15
-rw-r--r--src/server/worldserver/trinitycore.conf.dist2212
14 files changed, 4075 insertions, 0 deletions
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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <readline/readline.h>
+#include <readline/history.h>
+
+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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#include <ace/Version.h>
+
+#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 [<options>]\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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <ace/Sig_Handler.h>
+
+#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<RASocket> 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<unsigned long> (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( "<Ctrl-C> 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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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<Master>::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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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<sz; y++)
+ if(inp[y]=='\r'||inp[y]=='\n')
+ {
+ gotenter=true;
+ break;
+ }
+
+ //No buffer overflow (checked above)
+ memcpy(&buff[iInputLength],inp,y);
+ iInputLength+=y;
+ delete [] inp;
+ if(gotenter)
+ {
+
+ buff[iInputLength]=0;
+ iInputLength=0;
+ switch(stage)
+ {
+ /// <ul> <li> If the input is 'USER <username>'
+ 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()<iMinLevel || fields[1].GetUInt32() == NULL)
+ {
+ Sendf("-Not enough privileges.\r\n");
+ sLog.outRemote("User %s has no privilege.\n",szLogin.c_str());
+ if(bSecure)SetCloseAndDelete();
+ }
+ else if(fields[2].GetInt32() != -1)
+ {
+ ///- if RealmID isn't -1, deny access
+ Sendf("-Not enough privileges.\r\n");
+ sLog.outRemote("User %s has to be assigned on all realms (with RealmID = '-1').\n",szLogin.c_str());
+ if(bSecure)SetCloseAndDelete();
+ }
+ else
+ {
+ stage=LG;
+ }
+ }
+ }
+ break;
+ ///<li> If the input is 'PASS <password>' (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;
+ ///<li> 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;
+ ///</ul>
+ };
+
+ }
+}
+
+/// 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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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
--- /dev/null
+++ b/src/server/worldserver/TrinityCore.ico
Binary files 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 <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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 <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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