rearranged core files
--HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "TimeMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(GameTime);
|
||||
|
||||
bool PeriodicTimer::Update(const uint32 &diff)
|
||||
{
|
||||
if((i_expireTime -= diff) > 0)
|
||||
return false;
|
||||
|
||||
i_expireTime += i_period > diff ? i_period : diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PeriodicTimer::SetPeriodic(int32 period, int32 start_time)
|
||||
{
|
||||
i_expireTime=start_time, i_period=period;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _TIMEMGR_H
|
||||
#define _TIMEMGR_H
|
||||
|
||||
#include "Timer.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
struct IntervalTimer
|
||||
{
|
||||
public:
|
||||
IntervalTimer() : _interval(0), _current(0) {}
|
||||
|
||||
void Update(time_t diff) { _current += diff; if(_current<0) _current=0;}
|
||||
bool Passed() { return _current >= _interval; }
|
||||
void Reset() { if(_current >= _interval) _current -= _interval; }
|
||||
|
||||
void SetCurrent(time_t current) { _current = current; }
|
||||
void SetInterval(time_t interval) { _interval = interval; }
|
||||
time_t GetInterval() const { return _interval; }
|
||||
time_t GetCurrent() const { return _current; }
|
||||
|
||||
private:
|
||||
time_t _interval;
|
||||
time_t _current;
|
||||
};
|
||||
|
||||
template <typename T> struct TimeTrack
|
||||
{
|
||||
public:
|
||||
TimeTrack(T expire) : i_expireTime(expire) {}
|
||||
void Update(T diff) { i_expireTime -= diff; }
|
||||
bool Passed(void) const { return (i_expireTime <= 0); }
|
||||
void Reset(T interval) { i_expireTime = interval; }
|
||||
T GetExpireTime(void) const { return i_expireTime; }
|
||||
private:
|
||||
T i_expireTime;
|
||||
};
|
||||
|
||||
typedef TimeTrack<time_t> TimeTracker;
|
||||
typedef TimeTrack<int32> TimeTrackerSmall;
|
||||
|
||||
struct PeriodicTimer
|
||||
{
|
||||
public:
|
||||
PeriodicTimer(int32 period, int32 start_time) :
|
||||
i_expireTime(start_time), i_period(period) {}
|
||||
|
||||
bool Update(const uint32 &diff);
|
||||
void SetPeriodic(int32 period, int32 start_time);
|
||||
|
||||
private:
|
||||
int32 i_period;
|
||||
int32 i_expireTime;
|
||||
};
|
||||
|
||||
class GameTime
|
||||
{
|
||||
public:
|
||||
/// When server started?
|
||||
time_t const& GetStartTime() const { return m_startTime; }
|
||||
/// What time is it?
|
||||
time_t const& GetGameTime() const { return m_gameTime; }
|
||||
/// Uptime (in secs)
|
||||
uint32 GetUptime() const { return uint32(m_gameTime - m_startTime); }
|
||||
|
||||
void SetGameTime(void) { m_gameTime = time(NULL); }
|
||||
void SetStartTime(void){ m_startTime = time(NULL); }
|
||||
private:
|
||||
time_t m_gameTime;
|
||||
time_t m_startTime;
|
||||
};
|
||||
|
||||
#define sGameTime Trinity::Singleton<GameTime>::Instance()
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,784 @@
|
||||
/*
|
||||
* 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 world The World
|
||||
/// @{
|
||||
/// \file
|
||||
|
||||
#ifndef __WORLD_H
|
||||
#define __WORLD_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Timer.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "ace/Atomic_Op.h"
|
||||
#include "QueryResult.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
class Object;
|
||||
class WorldPacket;
|
||||
class WorldSession;
|
||||
class Player;
|
||||
class Weather;
|
||||
struct ScriptAction;
|
||||
struct ScriptInfo;
|
||||
class SqlResultQueue;
|
||||
class QueryResult;
|
||||
class WorldSocket;
|
||||
class SystemMgr;
|
||||
|
||||
// ServerMessages.dbc
|
||||
enum ServerMessageType
|
||||
{
|
||||
SERVER_MSG_SHUTDOWN_TIME = 1,
|
||||
SERVER_MSG_RESTART_TIME = 2,
|
||||
SERVER_MSG_STRING = 3,
|
||||
SERVER_MSG_SHUTDOWN_CANCELLED = 4,
|
||||
SERVER_MSG_RESTART_CANCELLED = 5
|
||||
};
|
||||
|
||||
enum ShutdownMask
|
||||
{
|
||||
SHUTDOWN_MASK_RESTART = 1,
|
||||
SHUTDOWN_MASK_IDLE = 2,
|
||||
};
|
||||
|
||||
enum ShutdownExitCode
|
||||
{
|
||||
SHUTDOWN_EXIT_CODE = 0,
|
||||
ERROR_EXIT_CODE = 1,
|
||||
RESTART_EXIT_CODE = 2,
|
||||
};
|
||||
|
||||
/// Timers for different object refresh rates
|
||||
enum WorldTimers
|
||||
{
|
||||
WUPDATE_OBJECTS = 0,
|
||||
WUPDATE_SESSIONS = 1,
|
||||
WUPDATE_AUCTIONS = 2,
|
||||
WUPDATE_WEATHERS = 3,
|
||||
WUPDATE_UPTIME = 4,
|
||||
WUPDATE_CORPSES = 5,
|
||||
WUPDATE_EVENTS = 6,
|
||||
WUPDATE_CLEANDB = 7,
|
||||
WUPDATE_AUTOBROADCAST = 8,
|
||||
WUPDATE_MAILBOXQUEUE = 9,
|
||||
WUPDATE_COUNT = 10
|
||||
};
|
||||
|
||||
/// Configuration elements
|
||||
enum WorldConfigs
|
||||
{
|
||||
CONFIG_COMPRESSION = 0,
|
||||
CONFIG_GRID_UNLOAD,
|
||||
CONFIG_INTERVAL_SAVE,
|
||||
CONFIG_INTERVAL_GRIDCLEAN,
|
||||
CONFIG_INTERVAL_MAPUPDATE,
|
||||
CONFIG_INTERVAL_CHANGEWEATHER,
|
||||
CONFIG_INTERVAL_DISCONNECT_TOLERANCE,
|
||||
CONFIG_PORT_WORLD,
|
||||
CONFIG_SOCKET_SELECTTIME,
|
||||
CONFIG_SOCKET_TIMEOUTTIME,
|
||||
CONFIG_SESSION_ADD_DELAY,
|
||||
CONFIG_GROUP_XP_DISTANCE,
|
||||
CONFIG_SIGHT_MONSTER,
|
||||
CONFIG_SIGHT_GUARDER,
|
||||
CONFIG_GAME_TYPE,
|
||||
CONFIG_REALM_ZONE,
|
||||
CONFIG_ALLOW_TWO_SIDE_ACCOUNTS,
|
||||
CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT,
|
||||
CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL,
|
||||
CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP,
|
||||
CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD,
|
||||
CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION,
|
||||
CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL,
|
||||
CONFIG_ALLOW_TWO_SIDE_WHO_LIST,
|
||||
CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND,
|
||||
CONFIG_ALLOW_TWO_SIDE_TRADE,
|
||||
CONFIG_STRICT_PLAYER_NAMES,
|
||||
CONFIG_STRICT_CHARTER_NAMES,
|
||||
CONFIG_STRICT_PET_NAMES,
|
||||
CONFIG_MIN_PLAYER_NAME,
|
||||
CONFIG_MIN_CHARTER_NAME,
|
||||
CONFIG_MIN_PET_NAME,
|
||||
CONFIG_CHARACTERS_CREATING_DISABLED,
|
||||
CONFIG_CHARACTERS_PER_ACCOUNT,
|
||||
CONFIG_CHARACTERS_PER_REALM,
|
||||
CONFIG_HEROIC_CHARACTERS_PER_REALM,
|
||||
CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING,
|
||||
CONFIG_SKIP_CINEMATICS,
|
||||
CONFIG_MAX_PLAYER_LEVEL,
|
||||
CONFIG_MIN_DUALSPEC_LEVEL,
|
||||
CONFIG_START_PLAYER_LEVEL,
|
||||
CONFIG_START_HEROIC_PLAYER_LEVEL,
|
||||
CONFIG_START_PLAYER_MONEY,
|
||||
CONFIG_MAX_HONOR_POINTS,
|
||||
CONFIG_START_HONOR_POINTS,
|
||||
CONFIG_MAX_ARENA_POINTS,
|
||||
CONFIG_START_ARENA_POINTS,
|
||||
CONFIG_INSTANCE_IGNORE_LEVEL,
|
||||
CONFIG_INSTANCE_IGNORE_RAID,
|
||||
CONFIG_INSTANCE_RESET_TIME_HOUR,
|
||||
CONFIG_INSTANCE_UNLOAD_DELAY,
|
||||
CONFIG_CAST_UNSTUCK,
|
||||
CONFIG_MAX_PRIMARY_TRADE_SKILL,
|
||||
CONFIG_MIN_PETITION_SIGNS,
|
||||
CONFIG_GM_LOGIN_STATE,
|
||||
CONFIG_GM_VISIBLE_STATE,
|
||||
CONFIG_GM_ACCEPT_TICKETS,
|
||||
CONFIG_GM_CHAT,
|
||||
CONFIG_GM_WHISPERING_TO,
|
||||
CONFIG_GM_LEVEL_IN_GM_LIST,
|
||||
CONFIG_GM_LEVEL_IN_WHO_LIST,
|
||||
CONFIG_GM_LOG_TRADE,
|
||||
CONFIG_START_GM_LEVEL,
|
||||
CONFIG_ALLOW_GM_GROUP,
|
||||
CONFIG_ALLOW_GM_FRIEND,
|
||||
CONFIG_GM_LOWER_SECURITY,
|
||||
CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS,
|
||||
CONFIG_GROUP_VISIBILITY,
|
||||
CONFIG_MAIL_DELIVERY_DELAY,
|
||||
CONFIG_UPTIME_UPDATE,
|
||||
CONFIG_SKILL_CHANCE_ORANGE,
|
||||
CONFIG_SKILL_CHANCE_YELLOW,
|
||||
CONFIG_SKILL_CHANCE_GREEN,
|
||||
CONFIG_SKILL_CHANCE_GREY,
|
||||
CONFIG_SKILL_CHANCE_MINING_STEPS,
|
||||
CONFIG_SKILL_CHANCE_SKINNING_STEPS,
|
||||
CONFIG_SKILL_PROSPECTING,
|
||||
CONFIG_SKILL_GAIN_CRAFTING,
|
||||
CONFIG_SKILL_GAIN_DEFENSE,
|
||||
CONFIG_SKILL_GAIN_GATHERING,
|
||||
CONFIG_SKILL_GAIN_WEAPON,
|
||||
CONFIG_DURABILITY_LOSS_IN_PVP,
|
||||
CONFIG_MAX_OVERSPEED_PINGS,
|
||||
CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY,
|
||||
CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL,
|
||||
CONFIG_WEATHER,
|
||||
CONFIG_EXPANSION,
|
||||
CONFIG_CHATFLOOD_MESSAGE_COUNT,
|
||||
CONFIG_CHATFLOOD_MESSAGE_DELAY,
|
||||
CONFIG_CHATFLOOD_MUTE_TIME,
|
||||
CONFIG_EVENT_ANNOUNCE,
|
||||
CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS,
|
||||
CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS,
|
||||
CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY,
|
||||
CONFIG_CREATURE_FAMILY_FLEE_DELAY,
|
||||
CONFIG_WORLD_BOSS_LEVEL_DIFF,
|
||||
CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF,
|
||||
CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF,
|
||||
CONFIG_DETECT_POS_COLLISION,
|
||||
CONFIG_RESTRICTED_LFG_CHANNEL,
|
||||
CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL,
|
||||
CONFIG_TALENTS_INSPECTING,
|
||||
CONFIG_CHAT_FAKE_MESSAGE_PREVENTING,
|
||||
CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY,
|
||||
CONFIG_CHAT_STRICT_LINK_CHECKING_KICK,
|
||||
CONFIG_CHAT_CHANNEL_LEVEL_REQ,
|
||||
CONFIG_CHAT_WHISPER_LEVEL_REQ,
|
||||
CONFIG_CHAT_SAY_LEVEL_REQ,
|
||||
CONFIG_TRADE_LEVEL_REQ,
|
||||
CONFIG_TICKET_LEVEL_REQ,
|
||||
CONFIG_AUCTION_LEVEL_REQ,
|
||||
CONFIG_MAIL_LEVEL_REQ,
|
||||
CONFIG_ALLOW_PLAYER_COMMANDS,
|
||||
CONFIG_CORPSE_DECAY_NORMAL,
|
||||
CONFIG_CORPSE_DECAY_RARE,
|
||||
CONFIG_CORPSE_DECAY_ELITE,
|
||||
CONFIG_CORPSE_DECAY_RAREELITE,
|
||||
CONFIG_CORPSE_DECAY_WORLDBOSS,
|
||||
CONFIG_ADDON_CHANNEL,
|
||||
CONFIG_DEATH_SICKNESS_LEVEL,
|
||||
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
|
||||
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
|
||||
CONFIG_DEATH_BONES_WORLD,
|
||||
CONFIG_DEATH_BONES_BG_OR_ARENA,
|
||||
CONFIG_DIE_COMMAND_MODE,
|
||||
CONFIG_THREAT_RADIUS,
|
||||
CONFIG_INSTANT_LOGOUT,
|
||||
CONFIG_DISABLE_BREATHING,
|
||||
CONFIG_ALL_TAXI_PATHS,
|
||||
CONFIG_INSTANT_TAXI,
|
||||
CONFIG_DECLINED_NAMES_USED,
|
||||
CONFIG_LISTEN_RANGE_SAY,
|
||||
CONFIG_LISTEN_RANGE_TEXTEMOTE,
|
||||
CONFIG_LISTEN_RANGE_YELL,
|
||||
CONFIG_SKILL_MILLING,
|
||||
CONFIG_BATTLEGROUND_CAST_DESERTER,
|
||||
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
|
||||
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
|
||||
CONFIG_BATTLEGROUND_INVITATION_TYPE,
|
||||
CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
|
||||
CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH,
|
||||
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
|
||||
CONFIG_ARENA_RATING_DISCARD_TIMER,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
|
||||
CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,
|
||||
CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY,
|
||||
CONFIG_ARENA_SEASON_ID,
|
||||
CONFIG_ARENA_SEASON_IN_PROGRESS,
|
||||
CONFIG_ARENA_START_RATING,
|
||||
CONFIG_ARENA_START_PERSONAL_RATING,
|
||||
CONFIG_MAX_WHO,
|
||||
CONFIG_BG_START_MUSIC,
|
||||
CONFIG_START_ALL_SPELLS,
|
||||
CONFIG_HONOR_AFTER_DUEL,
|
||||
CONFIG_START_ALL_EXPLORED,
|
||||
CONFIG_START_ALL_REP,
|
||||
CONFIG_ALWAYS_MAXSKILL,
|
||||
CONFIG_PVP_TOKEN_ENABLE,
|
||||
CONFIG_PVP_TOKEN_MAP_TYPE,
|
||||
CONFIG_PVP_TOKEN_ID,
|
||||
CONFIG_PVP_TOKEN_COUNT,
|
||||
CONFIG_NO_RESET_TALENT_COST,
|
||||
CONFIG_SHOW_KICK_IN_WORLD,
|
||||
CONFIG_INTERVAL_LOG_UPDATE,
|
||||
CONFIG_MIN_LOG_UPDATE,
|
||||
CONFIG_ENABLE_SINFO_LOGIN,
|
||||
CONFIG_PLAYER_ALLOW_COMMANDS,
|
||||
CONFIG_PET_LOS,
|
||||
CONFIG_NUMTHREADS,
|
||||
CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN,
|
||||
CONFIG_CHATLOG_CHANNEL,
|
||||
CONFIG_CHATLOG_WHISPER,
|
||||
CONFIG_CHATLOG_SYSCHAN,
|
||||
CONFIG_CHATLOG_PARTY,
|
||||
CONFIG_CHATLOG_RAID,
|
||||
CONFIG_CHATLOG_GUILD,
|
||||
CONFIG_CHATLOG_PUBLIC,
|
||||
CONFIG_CHATLOG_ADDON,
|
||||
CONFIG_CHATLOG_BGROUND,
|
||||
CONFIG_LOGDB_CLEARINTERVAL,
|
||||
CONFIG_LOGDB_CLEARTIME,
|
||||
CONFIG_CLIENTCACHE_VERSION,
|
||||
CONFIG_GUILD_EVENT_LOG_COUNT,
|
||||
CONFIG_GUILD_BANK_EVENT_LOG_COUNT,
|
||||
CONFIG_MIN_LEVEL_STAT_SAVE,
|
||||
CONFIG_STATS_SAVE_ONLY_ON_LOGOUT,
|
||||
CONFIG_BG_XP_FOR_KILL,
|
||||
CONFIG_RANDOM_BG_RESET_HOUR,
|
||||
CONFIG_VMAP_INDOOR_CHECK,
|
||||
CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
/// Server rates
|
||||
enum Rates
|
||||
{
|
||||
RATE_HEALTH=0,
|
||||
RATE_POWER_MANA,
|
||||
RATE_POWER_RAGE_INCOME,
|
||||
RATE_POWER_RAGE_LOSS,
|
||||
RATE_POWER_RUNICPOWER_INCOME,
|
||||
RATE_POWER_RUNICPOWER_LOSS,
|
||||
RATE_POWER_FOCUS,
|
||||
RATE_SKILL_DISCOVERY,
|
||||
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,
|
||||
RATE_XP_KILL,
|
||||
RATE_XP_QUEST,
|
||||
RATE_XP_EXPLORE,
|
||||
RATE_REPAIRCOST,
|
||||
RATE_REPUTATION_GAIN,
|
||||
RATE_REPUTATION_LOWLEVEL_KILL,
|
||||
RATE_REPUTATION_LOWLEVEL_QUEST,
|
||||
RATE_CREATURE_NORMAL_HP,
|
||||
RATE_CREATURE_ELITE_ELITE_HP,
|
||||
RATE_CREATURE_ELITE_RAREELITE_HP,
|
||||
RATE_CREATURE_ELITE_WORLDBOSS_HP,
|
||||
RATE_CREATURE_ELITE_RARE_HP,
|
||||
RATE_CREATURE_NORMAL_DAMAGE,
|
||||
RATE_CREATURE_ELITE_ELITE_DAMAGE,
|
||||
RATE_CREATURE_ELITE_RAREELITE_DAMAGE,
|
||||
RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE,
|
||||
RATE_CREATURE_ELITE_RARE_DAMAGE,
|
||||
RATE_CREATURE_NORMAL_SPELLDAMAGE,
|
||||
RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE,
|
||||
RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE,
|
||||
RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE,
|
||||
RATE_CREATURE_ELITE_RARE_SPELLDAMAGE,
|
||||
RATE_CREATURE_AGGRO,
|
||||
RATE_REST_INGAME,
|
||||
RATE_REST_OFFLINE_IN_TAVERN_OR_CITY,
|
||||
RATE_REST_OFFLINE_IN_WILDERNESS,
|
||||
RATE_DAMAGE_FALL,
|
||||
RATE_AUCTION_TIME,
|
||||
RATE_AUCTION_DEPOSIT,
|
||||
RATE_AUCTION_CUT,
|
||||
RATE_HONOR,
|
||||
RATE_MINING_AMOUNT,
|
||||
RATE_MINING_NEXT,
|
||||
RATE_TALENT,
|
||||
RATE_CORPSE_DECAY_LOOTED,
|
||||
RATE_INSTANCE_RESET_TIME,
|
||||
RATE_TARGET_POS_RECALCULATION_RANGE,
|
||||
RATE_DURABILITY_LOSS_ON_DEATH,
|
||||
RATE_DURABILITY_LOSS_DAMAGE,
|
||||
RATE_DURABILITY_LOSS_PARRY,
|
||||
RATE_DURABILITY_LOSS_ABSORB,
|
||||
RATE_DURABILITY_LOSS_BLOCK,
|
||||
RATE_MOVESPEED,
|
||||
MAX_RATES
|
||||
};
|
||||
|
||||
/// Can be used in SMSG_AUTH_RESPONSE packet
|
||||
enum BillingPlanFlags
|
||||
{
|
||||
SESSION_NONE = 0x00,
|
||||
SESSION_UNUSED = 0x01,
|
||||
SESSION_RECURRING_BILL = 0x02,
|
||||
SESSION_FREE_TRIAL = 0x04,
|
||||
SESSION_IGR = 0x08,
|
||||
SESSION_USAGE = 0x10,
|
||||
SESSION_TIME_MIXTURE = 0x20,
|
||||
SESSION_RESTRICTED = 0x40,
|
||||
SESSION_ENABLE_CAIS = 0x80,
|
||||
};
|
||||
|
||||
/// Type of server, this is values from second column of Cfg_Configs.dbc
|
||||
enum RealmType
|
||||
{
|
||||
REALM_TYPE_NORMAL = 0,
|
||||
REALM_TYPE_PVP = 1,
|
||||
REALM_TYPE_NORMAL2 = 4,
|
||||
REALM_TYPE_RP = 6,
|
||||
REALM_TYPE_RPPVP = 8,
|
||||
REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries
|
||||
// replaced by REALM_PVP in realm list
|
||||
};
|
||||
|
||||
enum RealmZone
|
||||
{
|
||||
REALM_ZONE_UNKNOWN = 0, // any language
|
||||
REALM_ZONE_DEVELOPMENT = 1, // any language
|
||||
REALM_ZONE_UNITED_STATES = 2, // extended-Latin
|
||||
REALM_ZONE_OCEANIC = 3, // extended-Latin
|
||||
REALM_ZONE_LATIN_AMERICA = 4, // extended-Latin
|
||||
REALM_ZONE_TOURNAMENT_5 = 5, // basic-Latin at create, any at login
|
||||
REALM_ZONE_KOREA = 6, // East-Asian
|
||||
REALM_ZONE_TOURNAMENT_7 = 7, // basic-Latin at create, any at login
|
||||
REALM_ZONE_ENGLISH = 8, // extended-Latin
|
||||
REALM_ZONE_GERMAN = 9, // extended-Latin
|
||||
REALM_ZONE_FRENCH = 10, // extended-Latin
|
||||
REALM_ZONE_SPANISH = 11, // extended-Latin
|
||||
REALM_ZONE_RUSSIAN = 12, // Cyrillic
|
||||
REALM_ZONE_TOURNAMENT_13 = 13, // basic-Latin at create, any at login
|
||||
REALM_ZONE_TAIWAN = 14, // East-Asian
|
||||
REALM_ZONE_TOURNAMENT_15 = 15, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CHINA = 16, // East-Asian
|
||||
REALM_ZONE_CN1 = 17, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN2 = 18, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN3 = 19, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN4 = 20, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN5 = 21, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN6 = 22, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN7 = 23, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN8 = 24, // basic-Latin at create, any at login
|
||||
REALM_ZONE_TOURNAMENT_25 = 25, // basic-Latin at create, any at login
|
||||
REALM_ZONE_TEST_SERVER = 26, // any language
|
||||
REALM_ZONE_TOURNAMENT_27 = 27, // basic-Latin at create, any at login
|
||||
REALM_ZONE_QA_SERVER = 28, // any language
|
||||
REALM_ZONE_CN9 = 29, // basic-Latin at create, any at login
|
||||
REALM_ZONE_TEST_SERVER_2 = 30, // any language
|
||||
REALM_ZONE_CN10 = 31, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CTC = 32,
|
||||
REALM_ZONE_CNC = 33,
|
||||
REALM_ZONE_CN1_4 = 34, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN2_6_9 = 35, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN3_7 = 36, // basic-Latin at create, any at login
|
||||
REALM_ZONE_CN5_8 = 37 // basic-Latin at create, any at login
|
||||
};
|
||||
|
||||
enum WorldStates
|
||||
{
|
||||
WS_WEEKLY_QUEST_RESET_TIME = 20002, // Next weekly reset time
|
||||
WS_BG_DAILY_RESET_TIME = 20003 // Next daily BG reset time
|
||||
};
|
||||
|
||||
// DB scripting commands
|
||||
#define SCRIPT_COMMAND_TALK 0 // source = unit, target=any, datalong (0=say, 1=whisper, 2=yell, 3=emote text, 4=boss emote text)
|
||||
#define SCRIPT_COMMAND_EMOTE 1 // source = unit, datalong = anim_id
|
||||
#define SCRIPT_COMMAND_FIELD_SET 2 // source = any, datalong = field_id, datalog2 = value
|
||||
#define SCRIPT_COMMAND_MOVE_TO 3 // source = Creature, datalog2 = time, x/y/z
|
||||
#define SCRIPT_COMMAND_FLAG_SET 4 // source = any, datalong = field_id, datalog2 = bitmask
|
||||
#define SCRIPT_COMMAND_FLAG_REMOVE 5 // source = any, datalong = field_id, datalog2 = bitmask
|
||||
#define SCRIPT_COMMAND_TELEPORT_TO 6 // source or target with Player, datalong = map_id, x/y/z
|
||||
#define SCRIPT_COMMAND_QUEST_EXPLORED 7 // one from source or target must be Player, another GO/Creature, datalong=quest_id, datalong2=distance or 0
|
||||
#define SCRIPT_COMMAND_KILL_CREDIT 8 // source or target with Player, datalong = creature entry, datalong2 = bool (0=personal credit, 1=group credit)
|
||||
#define SCRIPT_COMMAND_RESPAWN_GAMEOBJECT 9 // source = any (summoner), datalong=db_guid, datalong2=despawn_delay
|
||||
#define SCRIPT_COMMAND_TEMP_SUMMON_CREATURE 10 // source = any (summoner), datalong=creature entry, datalong2=despawn_delay
|
||||
#define SCRIPT_COMMAND_OPEN_DOOR 11 // source = unit, datalong=db_guid, datalong2=reset_delay
|
||||
#define SCRIPT_COMMAND_CLOSE_DOOR 12 // source = unit, datalong=db_guid, datalong2=reset_delay
|
||||
#define SCRIPT_COMMAND_ACTIVATE_OBJECT 13 // source = unit, target=GO
|
||||
#define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2 != 0) or target (datalong == 0) unit, datalong = spell_id
|
||||
#define SCRIPT_COMMAND_CAST_SPELL 15 // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
|
||||
#define SCRIPT_COMMAND_PLAY_SOUND 16 // source = any object, target=any/player, datalong (sound_id), datalong2 (bitmask: 0/1=anyone/target, 0/2=with distance dependent, so 1|2 = 3 is target with distance dependent)
|
||||
#define SCRIPT_COMMAND_CREATE_ITEM 17 // source or target must be player, datalong = item entry, datalong2 = amount
|
||||
#define SCRIPT_COMMAND_DESPAWN_SELF 18 // source or target must be creature, datalong = despawn delay
|
||||
|
||||
#define SCRIPT_COMMAND_LOAD_PATH 20 // source = unit, path = datalong, repeatable datalong2
|
||||
#define SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT 21 // datalong scriptid, lowguid datalong2, dataint table
|
||||
#define SCRIPT_COMMAND_KILL 22 // datalong removecorpse
|
||||
|
||||
//trinity only
|
||||
#define SCRIPT_COMMAND_ORIENTATION 30 // o = orientation
|
||||
#define SCRIPT_COMMAND_EQUIP 31 // datalong = equipment id
|
||||
#define SCRIPT_COMMAND_MODEL 32 // datalong = model id
|
||||
#define SCRIPT_COMMAND_CLOSE_GOSSIP 33 // close gossip window -- no values
|
||||
#define SCRIPT_COMMAND_PLAYMOVIE 34 // datalong = movie id
|
||||
|
||||
/// Storage class for commands issued for delayed execution
|
||||
struct CliCommandHolder
|
||||
{
|
||||
typedef void Print(const char*);
|
||||
|
||||
char *m_command;
|
||||
Print* m_print;
|
||||
|
||||
CliCommandHolder(const char *command, Print* zprint)
|
||||
: m_print(zprint)
|
||||
{
|
||||
size_t len = strlen(command)+1;
|
||||
m_command = new char[len];
|
||||
memcpy(m_command, command, len);
|
||||
}
|
||||
|
||||
~CliCommandHolder() { delete[] m_command; }
|
||||
};
|
||||
|
||||
/// The World
|
||||
class World
|
||||
{
|
||||
public:
|
||||
static volatile uint32 m_worldLoopCounter;
|
||||
|
||||
World();
|
||||
~World();
|
||||
|
||||
WorldSession* FindSession(uint32 id) const;
|
||||
void AddSession(WorldSession *s);
|
||||
void SendRNDBroadcast();
|
||||
bool RemoveSession(uint32 id);
|
||||
/// Get the number of current active sessions
|
||||
void UpdateMaxSessionCounters();
|
||||
uint32 GetActiveAndQueuedSessionCount() const { return m_sessions.size(); }
|
||||
uint32 GetActiveSessionCount() const { return m_sessions.size() - m_QueuedPlayer.size(); }
|
||||
uint32 GetQueuedSessionCount() const { return m_QueuedPlayer.size(); }
|
||||
/// Get the maximum number of parallel sessions on the server since last reboot
|
||||
uint32 GetMaxQueuedSessionCount() const { return m_maxQueuedSessionCount; }
|
||||
uint32 GetMaxActiveSessionCount() const { return m_maxActiveSessionCount; }
|
||||
/// Get number of players
|
||||
inline uint32 GetPlayerCount() const { return m_PlayerCount; }
|
||||
inline uint32 GetMaxPlayerCount() const { return m_MaxPlayerCount; }
|
||||
/// Increase/Decrease number of players
|
||||
inline void IncreasePlayerCount()
|
||||
{
|
||||
m_PlayerCount++;
|
||||
m_MaxPlayerCount = std::max(m_MaxPlayerCount, m_PlayerCount);
|
||||
}
|
||||
inline void DecreasePlayerCount() { m_PlayerCount--; }
|
||||
|
||||
Player* FindPlayerInZone(uint32 zone);
|
||||
Weather* FindWeather(uint32 id) const;
|
||||
Weather* AddWeather(uint32 zone_id);
|
||||
void RemoveWeather(uint32 zone_id);
|
||||
|
||||
/// Deny clients?
|
||||
bool IsClosed() { return m_isClosed; }
|
||||
|
||||
/// Close world
|
||||
void SetClosed(bool val) { m_isClosed = val; }
|
||||
|
||||
/// Get the active session server limit (or security level limitations)
|
||||
uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; }
|
||||
AccountTypes GetPlayerSecurityLimit() const { return m_allowedSecurityLevel < 0 ? SEC_PLAYER : m_allowedSecurityLevel; }
|
||||
void SetPlayerSecurityLimit(AccountTypes sec) { m_allowedSecurityLevel = (sec < SEC_PLAYER ? SEC_PLAYER : sec); }
|
||||
|
||||
/// Set the active session server limit (or security level limitation)
|
||||
void SetPlayerLimit(int32 limit, bool needUpdate = false);
|
||||
|
||||
//player Queue
|
||||
typedef std::list<WorldSession*> Queue;
|
||||
void AddQueuedPlayer(WorldSession*);
|
||||
bool RemoveQueuedPlayer(WorldSession* session);
|
||||
int32 GetQueuePos(WorldSession*);
|
||||
bool HasRecentlyDisconnected(WorldSession*);
|
||||
uint32 GetQueueSize() const { return m_QueuedPlayer.size(); }
|
||||
|
||||
/// \todo Actions on m_allowMovement still to be implemented
|
||||
/// Is movement allowed?
|
||||
bool getAllowMovement() const { return m_allowMovement; }
|
||||
/// Allow/Disallow object movements
|
||||
void SetAllowMovement(bool allow) { m_allowMovement = allow; }
|
||||
|
||||
/// Set a new Message of the Day
|
||||
void SetMotd(const std::string& motd) { m_motd = motd; }
|
||||
/// Get the current Message of the Day
|
||||
const char* GetMotd() const { return m_motd.c_str(); }
|
||||
|
||||
/// Set the string for new characters (first login)
|
||||
void SetNewCharString(std::string str) { m_newCharString = str; }
|
||||
/// Get the string for new characters (first login)
|
||||
const std::string& GetNewCharString() const { return m_newCharString; }
|
||||
|
||||
LocaleConstant GetDefaultDbcLocale() const { return m_defaultDbcLocale; }
|
||||
|
||||
/// Get the path where data (dbc, maps) are stored on disk
|
||||
std::string GetDataPath() const { return m_dataPath; }
|
||||
|
||||
/// When server started?
|
||||
time_t const& GetStartTime() const { return m_startTime; }
|
||||
/// What time is it?
|
||||
time_t const& GetGameTime() const { return m_gameTime; }
|
||||
/// Uptime (in secs)
|
||||
uint32 GetUptime() const { return uint32(m_gameTime - m_startTime); }
|
||||
/// Update time
|
||||
uint32 GetUpdateTime() const { return m_updateTime; }
|
||||
void SetRecordDiffInterval(int32 t) { if (t >= 0) m_configs[CONFIG_INTERVAL_LOG_UPDATE] = (uint32)t; }
|
||||
|
||||
/// Next daily quests and random bg reset time
|
||||
time_t GetNextDailyQuestsResetTime() const { return m_NextDailyQuestReset; }
|
||||
time_t GetNextWeeklyQuestsResetTime() const { return m_NextWeeklyQuestReset; }
|
||||
time_t GetNextRandomBGResetTime() const { return m_NextRandomBGReset; }
|
||||
|
||||
/// Get the maximum skill level a player can reach
|
||||
uint16 GetConfigMaxSkillValue() const
|
||||
{
|
||||
uint8 lvl = getConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||
return lvl > 60 ? 300 + ((lvl - 60) * 75) / 10 : lvl*5;
|
||||
}
|
||||
|
||||
void SetInitialWorldSettings();
|
||||
void LoadConfigSettings(bool reload = false);
|
||||
|
||||
void SendWorldText(int32 string_id, ...);
|
||||
void SendGlobalText(const char* text, WorldSession *self);
|
||||
void SendGMText(int32 string_id, ...);
|
||||
void SendGlobalMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
|
||||
void SendGlobalGMMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
|
||||
void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
|
||||
void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0);
|
||||
void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL);
|
||||
|
||||
/// Are we in the middle of a shutdown?
|
||||
bool IsShutdowning() const { return m_ShutdownTimer > 0; }
|
||||
void ShutdownServ(uint32 time, uint32 options, uint8 exitcode);
|
||||
void ShutdownCancel();
|
||||
void ShutdownMsg(bool show = false, Player* player = NULL);
|
||||
static uint8 GetExitCode() { return m_ExitCode; }
|
||||
static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; }
|
||||
static bool IsStopped() { return m_stopEvent; }
|
||||
|
||||
void Update(uint32 diff);
|
||||
|
||||
void UpdateSessions(uint32 diff);
|
||||
/// Set a server rate (see #Rates)
|
||||
void setRate(Rates rate,float value) { rate_values[rate]=value; }
|
||||
/// Get a server rate (see #Rates)
|
||||
float getRate(Rates rate) const { return rate_values[rate]; }
|
||||
|
||||
/// Set a server configuration element (see #WorldConfigs)
|
||||
void setConfig(uint32 index,uint32 value)
|
||||
{
|
||||
if (index < CONFIG_VALUE_COUNT)
|
||||
m_configs[index] = value;
|
||||
}
|
||||
|
||||
/// Get a server configuration element (see #WorldConfigs)
|
||||
uint32 getConfig(uint32 index) const
|
||||
{
|
||||
return index < CONFIG_VALUE_COUNT ? m_configs[index] : 0;
|
||||
}
|
||||
|
||||
void setWorldState(uint32 index, uint64 value);
|
||||
uint64 getWorldState(uint32 index) const;
|
||||
void LoadWorldStates();
|
||||
|
||||
/// Are we on a "Player versus Player" server?
|
||||
bool IsPvPRealm() { return (getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); }
|
||||
bool IsFFAPvPRealm() { return getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; }
|
||||
|
||||
void KickAll();
|
||||
void KickAllLess(AccountTypes sec);
|
||||
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
|
||||
bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
|
||||
|
||||
uint32 IncreaseScheduledScriptsCount() { return (uint32)++m_scheduledScripts; }
|
||||
uint32 DecreaseScheduledScriptCount() { return (uint32)--m_scheduledScripts; }
|
||||
uint32 DecreaseScheduledScriptCount(size_t count) { return (uint32)(m_scheduledScripts -= count); }
|
||||
bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
|
||||
|
||||
bool IsAllowedMap(uint32 mapid) { return m_forbiddenMapIds.count(mapid) == 0 ;}
|
||||
|
||||
// for max speed access
|
||||
static float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; }
|
||||
static float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInstances; }
|
||||
static float GetMaxVisibleDistanceInBGArenas() { return m_MaxVisibleDistanceInBGArenas; }
|
||||
static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; }
|
||||
|
||||
static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; }
|
||||
static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
|
||||
static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
|
||||
|
||||
static int32 GetVisibilityNotifyPeriodOnContinents(){ return m_visibility_notify_periodOnContinents; }
|
||||
static int32 GetVisibilityNotifyPeriodInInstances() { return m_visibility_notify_periodInInstances; }
|
||||
static int32 GetVisibilityNotifyPeriodInBGArenas() { return m_visibility_notify_periodInBGArenas; }
|
||||
|
||||
void ProcessCliCommands();
|
||||
void QueueCliCommand(CliCommandHolder::Print* zprintf, char const* input) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); }
|
||||
|
||||
void UpdateResultQueue();
|
||||
void InitResultQueue();
|
||||
|
||||
void ForceGameEventUpdate();
|
||||
|
||||
void UpdateRealmCharCount(uint32 accid);
|
||||
|
||||
void UpdateAllowedSecurity();
|
||||
|
||||
LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const { if (m_availableDbcLocaleMask & (1 << locale)) return locale; else return m_defaultDbcLocale; }
|
||||
|
||||
//used World DB version
|
||||
void LoadDBVersion();
|
||||
char const* GetDBVersion() { return m_DBVersion.c_str(); }
|
||||
char const* GetCreatureEventAIVersion() { return m_CreatureEventAIVersion.c_str(); }
|
||||
|
||||
void RecordTimeDiff(const char * text, ...);
|
||||
|
||||
void LoadAutobroadcasts();
|
||||
|
||||
void UpdateAreaDependentAuras();
|
||||
|
||||
void ProcessStartEvent();
|
||||
void ProcessStopEvent();
|
||||
bool GetEventKill() { return isEventKillStart; }
|
||||
|
||||
bool isEventKillStart;
|
||||
protected:
|
||||
void _UpdateGameTime();
|
||||
// callback for UpdateRealmCharacters
|
||||
void _UpdateRealmCharCount(QueryResult_AutoPtr resultCharCount, uint32 accountId);
|
||||
|
||||
void InitDailyQuestResetTime();
|
||||
void InitWeeklyQuestResetTime();
|
||||
void InitRandomBGResetTime();
|
||||
void ResetDailyQuests();
|
||||
void ResetWeeklyQuests();
|
||||
void ResetRandomBG();
|
||||
private:
|
||||
static volatile bool m_stopEvent;
|
||||
static uint8 m_ExitCode;
|
||||
uint32 m_ShutdownTimer;
|
||||
uint32 m_ShutdownMask;
|
||||
|
||||
bool m_isClosed;
|
||||
|
||||
//atomic op counter for active scripts amount
|
||||
ACE_Atomic_Op<ACE_Thread_Mutex, long> m_scheduledScripts;
|
||||
|
||||
time_t m_startTime;
|
||||
time_t m_gameTime;
|
||||
IntervalTimer m_timers[WUPDATE_COUNT];
|
||||
uint32 mail_timer;
|
||||
uint32 mail_timer_expires;
|
||||
uint32 m_updateTime, m_updateTimeSum;
|
||||
uint32 m_updateTimeCount;
|
||||
uint32 m_currentTime;
|
||||
|
||||
typedef UNORDERED_MAP<uint32, Weather*> WeatherMap;
|
||||
WeatherMap m_weathers;
|
||||
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
|
||||
SessionMap m_sessions;
|
||||
typedef UNORDERED_MAP<uint32, time_t> DisconnectMap;
|
||||
DisconnectMap m_disconnects;
|
||||
uint32 m_maxActiveSessionCount;
|
||||
uint32 m_maxQueuedSessionCount;
|
||||
uint32 m_PlayerCount;
|
||||
uint32 m_MaxPlayerCount;
|
||||
|
||||
std::string m_newCharString;
|
||||
|
||||
float rate_values[MAX_RATES];
|
||||
uint32 m_configs[CONFIG_VALUE_COUNT];
|
||||
typedef std::map<uint32,uint64> WorldStatesMap;
|
||||
WorldStatesMap m_worldstates;
|
||||
int32 m_playerLimit;
|
||||
AccountTypes m_allowedSecurityLevel;
|
||||
LocaleConstant m_defaultDbcLocale; // from config for one from loaded DBC locales
|
||||
uint32 m_availableDbcLocaleMask; // by loaded DBC
|
||||
void DetectDBCLang();
|
||||
bool m_allowMovement;
|
||||
std::string m_motd;
|
||||
std::string m_dataPath;
|
||||
std::set<uint32> m_forbiddenMapIds;
|
||||
|
||||
// for max speed access
|
||||
static float m_MaxVisibleDistanceOnContinents;
|
||||
static float m_MaxVisibleDistanceInInstances;
|
||||
static float m_MaxVisibleDistanceInBGArenas;
|
||||
static float m_MaxVisibleDistanceForObject;
|
||||
|
||||
static float m_MaxVisibleDistanceInFlight;
|
||||
static float m_VisibleUnitGreyDistance;
|
||||
static float m_VisibleObjectGreyDistance;
|
||||
|
||||
static int32 m_visibility_notify_periodOnContinents;
|
||||
static int32 m_visibility_notify_periodInInstances;
|
||||
static int32 m_visibility_notify_periodInBGArenas;
|
||||
|
||||
// CLI command holder to be thread safe
|
||||
ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> cliCmdQueue;
|
||||
SqlResultQueue *m_resultQueue;
|
||||
|
||||
// next daily quests and random bg reset time
|
||||
time_t m_NextDailyQuestReset;
|
||||
time_t m_NextWeeklyQuestReset;
|
||||
time_t m_NextRandomBGReset;
|
||||
|
||||
//Player Queue
|
||||
Queue m_QueuedPlayer;
|
||||
|
||||
//sessions that are added async
|
||||
void AddSession_(WorldSession* s);
|
||||
ACE_Based::LockedQueue<WorldSession*, ACE_Thread_Mutex> addSessQueue;
|
||||
|
||||
//used versions
|
||||
std::string m_DBVersion;
|
||||
std::string m_CreatureEventAIVersion;
|
||||
|
||||
std::list<std::string> m_Autobroadcasts;
|
||||
};
|
||||
|
||||
extern uint32 realmID;
|
||||
|
||||
#define sWorld Trinity::Singleton<World>::Instance()
|
||||
#endif
|
||||
/// @}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 u2w
|
||||
*/
|
||||
|
||||
#include "WorldLog.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Log.h"
|
||||
|
||||
#define CLASS_LOCK Trinity::ClassLevelLockable<WorldLog, ACE_Thread_Mutex>
|
||||
INSTANTIATE_SINGLETON_2(WorldLog, CLASS_LOCK);
|
||||
INSTANTIATE_CLASS_MUTEX(WorldLog, ACE_Thread_Mutex);
|
||||
|
||||
WorldLog::WorldLog() : i_file(NULL)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
WorldLog::~WorldLog()
|
||||
{
|
||||
if (i_file != NULL)
|
||||
fclose(i_file);
|
||||
i_file = NULL;
|
||||
}
|
||||
|
||||
/// Open the log file (if specified so in the configuration file)
|
||||
void WorldLog::Initialize()
|
||||
{
|
||||
std::string logsDir = sConfig.GetStringDefault("LogsDir","");
|
||||
|
||||
if (!logsDir.empty())
|
||||
{
|
||||
if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
|
||||
logsDir.append("/");
|
||||
}
|
||||
|
||||
std::string logname = sConfig.GetStringDefault("WorldLogFile", "");
|
||||
if (!logname.empty())
|
||||
{
|
||||
i_file = fopen((logsDir+logname).c_str(), "w");
|
||||
}
|
||||
|
||||
m_dbWorld = sConfig.GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled
|
||||
}
|
||||
|
||||
void WorldLog::outTimestampLog(char const *fmt, ...)
|
||||
{
|
||||
if (LogWorld())
|
||||
{
|
||||
Guard guard(*this);
|
||||
ASSERT(i_file);
|
||||
|
||||
Log::outTimestamp(i_file);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(i_file, fmt, args);
|
||||
//fprintf(i_file, "\n");
|
||||
va_end(args);
|
||||
|
||||
fflush(i_file);
|
||||
}
|
||||
|
||||
if (sLog.GetLogDB() && m_dbWorld)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, fmt);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
|
||||
sLog.outDB(LOG_TYPE_WORLD, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldLog::outLog(char const *fmt, ...)
|
||||
{
|
||||
if (LogWorld())
|
||||
{
|
||||
Guard guard(*this);
|
||||
ASSERT(i_file);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(i_file, fmt, args);
|
||||
//fprintf(i_file, "\n");
|
||||
va_end(args);
|
||||
|
||||
fflush(i_file);
|
||||
}
|
||||
|
||||
if (sLog.GetLogDB() && m_dbWorld)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, fmt);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
|
||||
sLog.outDB(LOG_TYPE_WORLD, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
}
|
||||
|
||||
#define sWorldLog WorldLog::Instance()
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 u2w
|
||||
/// @{
|
||||
/// \file
|
||||
|
||||
#ifndef TRINITY_WORLDLOG_H
|
||||
#define TRINITY_WORLDLOG_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "Errors.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/// %Log packets to a file
|
||||
class WorldLog : public Trinity::Singleton<WorldLog, Trinity::ClassLevelLockable<WorldLog, ACE_Thread_Mutex> >
|
||||
{
|
||||
friend class Trinity::OperatorNew<WorldLog>;
|
||||
WorldLog();
|
||||
WorldLog(const WorldLog &);
|
||||
WorldLog& operator=(const WorldLog &);
|
||||
typedef Trinity::ClassLevelLockable<WorldLog, ACE_Thread_Mutex>::Lock Guard;
|
||||
|
||||
/// Close the file in destructor
|
||||
~WorldLog();
|
||||
|
||||
public:
|
||||
void Initialize();
|
||||
/// Is the world logger active?
|
||||
bool LogWorld(void) const { return (i_file != NULL); }
|
||||
/// %Log to the file
|
||||
void outLog(char const *fmt, ...);
|
||||
void outTimestampLog(char const *fmt, ...);
|
||||
|
||||
private:
|
||||
FILE *i_file;
|
||||
|
||||
bool m_dbWorld;
|
||||
};
|
||||
|
||||
#define sWorldLog WorldLog::Instance()
|
||||
#endif
|
||||
/// @}
|
||||
|
||||
@@ -0,0 +1,959 @@
|
||||
/*
|
||||
* 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 u2w
|
||||
*/
|
||||
|
||||
#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Group.h"
|
||||
#include "Guild.h"
|
||||
#include "World.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "zlib/zlib.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "LFGMgr.h"
|
||||
|
||||
/// WorldSession constructor
|
||||
WorldSession::WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale) :
|
||||
LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),
|
||||
_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
|
||||
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)),
|
||||
_logoutTime(0), m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_playerSave(false),
|
||||
m_latency(0), m_TutorialsChanged(false), m_timeOutTime(0)
|
||||
{
|
||||
if (sock)
|
||||
{
|
||||
m_Address = sock->GetRemoteAddress ();
|
||||
sock->AddReference ();
|
||||
ResetTimeOutTime();
|
||||
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
/// WorldSession destructor
|
||||
WorldSession::~WorldSession()
|
||||
{
|
||||
///- unload player if not unloaded
|
||||
if (_player)
|
||||
LogoutPlayer (true);
|
||||
|
||||
/// - If have unclosed socket, close it
|
||||
if (m_Socket)
|
||||
{
|
||||
m_Socket->CloseSocket ();
|
||||
m_Socket->RemoveReference ();
|
||||
m_Socket = NULL;
|
||||
}
|
||||
|
||||
///- empty incoming packet queue
|
||||
WorldPacket* packet;
|
||||
while (_recvQueue.next(packet))
|
||||
delete packet;
|
||||
|
||||
LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId());
|
||||
CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = %u;", GetAccountId());
|
||||
}
|
||||
|
||||
void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const
|
||||
{
|
||||
sLog.outError("Client (account %u) send packet %s (%u) with size " SIZEFMTD " but expected %u (attempt crash server?), skipped",
|
||||
GetAccountId(),LookupOpcodeName(packet.GetOpcode()),packet.GetOpcode(),packet.size(),size);
|
||||
}
|
||||
|
||||
/// Get the player name
|
||||
char const* WorldSession::GetPlayerName() const
|
||||
{
|
||||
return GetPlayer() ? GetPlayer()->GetName() : "<none>";
|
||||
}
|
||||
|
||||
/// Send a packet to the client
|
||||
void WorldSession::SendPacket(WorldPacket const* packet)
|
||||
{
|
||||
if (!m_Socket)
|
||||
return;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
|
||||
// Code for network use statistic
|
||||
static uint64 sendPacketCount = 0;
|
||||
static uint64 sendPacketBytes = 0;
|
||||
|
||||
static time_t firstTime = time(NULL);
|
||||
static time_t lastTime = firstTime; // next 60 secs start time
|
||||
|
||||
static uint64 sendLastPacketCount = 0;
|
||||
static uint64 sendLastPacketBytes = 0;
|
||||
|
||||
time_t cur_time = time(NULL);
|
||||
|
||||
if ((cur_time - lastTime) < 60)
|
||||
{
|
||||
sendPacketCount+=1;
|
||||
sendPacketBytes+=packet->size();
|
||||
|
||||
sendLastPacketCount+=1;
|
||||
sendLastPacketBytes+=packet->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 minTime = uint64(cur_time - lastTime);
|
||||
uint64 fullTime = uint64(lastTime - firstTime);
|
||||
sLog.outDetail("Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u",sendPacketCount,sendPacketBytes,float(sendPacketCount)/fullTime,float(sendPacketBytes)/fullTime,uint32(fullTime));
|
||||
sLog.outDetail("Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f",sendLastPacketCount,sendLastPacketBytes,float(sendLastPacketCount)/minTime,float(sendLastPacketBytes)/minTime);
|
||||
|
||||
lastTime = cur_time;
|
||||
sendLastPacketCount = 1;
|
||||
sendLastPacketBytes = packet->wpos(); // wpos is real written size
|
||||
}
|
||||
|
||||
#endif // !TRINITY_DEBUG
|
||||
|
||||
if (m_Socket->SendPacket (*packet) == -1)
|
||||
m_Socket->CloseSocket ();
|
||||
}
|
||||
|
||||
/// Add an incoming packet to the queue
|
||||
void WorldSession::QueuePacket(WorldPacket* new_packet)
|
||||
{
|
||||
_recvQueue.add(new_packet);
|
||||
}
|
||||
|
||||
/// Logging helper for unexpected opcodes
|
||||
void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char *reason)
|
||||
{
|
||||
sLog.outError("SESSION: received unexpected opcode %s (0x%.4X) %s",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode(),
|
||||
reason);
|
||||
}
|
||||
|
||||
/// Logging helper for unexpected opcodes
|
||||
void WorldSession::LogUnprocessedTail(WorldPacket *packet)
|
||||
{
|
||||
sLog.outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode(),
|
||||
packet->rpos(),packet->wpos());
|
||||
|
||||
packet->print_storage();
|
||||
}
|
||||
|
||||
/// Update the WorldSession (triggered by World update)
|
||||
bool WorldSession::Update(uint32 diff)
|
||||
{
|
||||
/// Update Timeout timer.
|
||||
UpdateTimeOutTime(diff);
|
||||
|
||||
///- Before we process anything:
|
||||
/// If necessary, kick the player from the character select screen
|
||||
if (IsConnectionIdle())
|
||||
m_Socket->CloseSocket();
|
||||
|
||||
///- Retrieve packets from the receive queue and call the appropriate handlers
|
||||
/// not proccess packets if socket already closed
|
||||
WorldPacket* packet;
|
||||
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet))
|
||||
{
|
||||
/*#if 1
|
||||
sLog.outError("MOEP: %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
#endif*/
|
||||
|
||||
if (packet->GetOpcode() >= NUM_MSG_TYPES)
|
||||
{
|
||||
sLog.outError("SESSION: received non-existed opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
}
|
||||
else
|
||||
{
|
||||
OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
|
||||
try
|
||||
{
|
||||
switch (opHandle.status)
|
||||
{
|
||||
case STATUS_LOGGEDIN:
|
||||
if (!_player)
|
||||
{
|
||||
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
|
||||
if (!m_playerRecentlyLogout)
|
||||
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
||||
}
|
||||
else if (_player->IsInWorld())
|
||||
{
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
||||
break;
|
||||
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
|
||||
if (!_player && !m_playerRecentlyLogout)
|
||||
{
|
||||
LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
|
||||
}
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if (!_player)
|
||||
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
||||
else if (_player->IsInWorld())
|
||||
LogUnexpectedOpcode(packet, "the player is still in world");
|
||||
else
|
||||
{
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_AUTHED:
|
||||
// prevent cheating with skip queue wait
|
||||
if (m_inQueue)
|
||||
{
|
||||
LogUnexpectedOpcode(packet, "the player not pass queue yet");
|
||||
break;
|
||||
}
|
||||
|
||||
// single from authed time opcodes send in to after logout time
|
||||
// and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
|
||||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
break;
|
||||
case STATUS_NEVER:
|
||||
/*
|
||||
sLog.outError("SESSION: received not allowed opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(ByteBufferException &)
|
||||
{
|
||||
sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
|
||||
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
|
||||
if (sLog.IsOutDebug())
|
||||
{
|
||||
sLog.outDebug("Dumping error causing packet:");
|
||||
packet->hexlike();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete packet;
|
||||
}
|
||||
|
||||
time_t currTime = time(NULL);
|
||||
///- If necessary, log the player out
|
||||
if (ShouldLogOut(currTime) && !m_playerLoading)
|
||||
LogoutPlayer(true);
|
||||
|
||||
///- Cleanup socket pointer if need
|
||||
if (m_Socket && m_Socket->IsClosed())
|
||||
{
|
||||
m_Socket->RemoveReference();
|
||||
m_Socket = NULL;
|
||||
}
|
||||
|
||||
if (!m_Socket)
|
||||
return false; //Will remove this session from the world session map
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// %Log the player out
|
||||
void WorldSession::LogoutPlayer(bool Save)
|
||||
{
|
||||
// finish pending transfers before starting the logout
|
||||
while (_player && _player->IsBeingTeleportedFar())
|
||||
HandleMoveWorldportAckOpcode();
|
||||
|
||||
m_playerLogout = true;
|
||||
m_playerSave = Save;
|
||||
|
||||
if (_player)
|
||||
{
|
||||
sLFGMgr.Leave(_player);
|
||||
GetPlayer()->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
|
||||
GetPlayer()->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
|
||||
GetPlayer()->GetSession()->SendLfgUpdateSearch(false);
|
||||
|
||||
if (uint64 lguid = GetPlayer()->GetLootGUID())
|
||||
DoLootRelease(lguid);
|
||||
|
||||
///- If the player just died before logging out, make him appear as a ghost
|
||||
//FIXME: logout must be delayed in case lost connection with client in time of combat
|
||||
if (_player->GetDeathTimer())
|
||||
{
|
||||
_player->getHostileRefManager().deleteReferences();
|
||||
_player->BuildPlayerRepop();
|
||||
_player->RepopAtGraveyard();
|
||||
}
|
||||
else if (!_player->getAttackers().empty())
|
||||
{
|
||||
_player->CombatStop();
|
||||
_player->getHostileRefManager().setOnlineOfflineState(false);
|
||||
_player->RemoveAllAurasOnDeath();
|
||||
|
||||
// build set of player who attack _player or who have pet attacking of _player
|
||||
std::set<Player*> aset;
|
||||
for (Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr)
|
||||
{
|
||||
Unit* owner = (*itr)->GetOwner(); // including player controlled case
|
||||
if (owner)
|
||||
{
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER)
|
||||
aset.insert(owner->ToPlayer());
|
||||
}
|
||||
else
|
||||
if ((*itr)->GetTypeId() == TYPEID_PLAYER)
|
||||
aset.insert((Player*)(*itr));
|
||||
}
|
||||
|
||||
_player->SetPvPDeath(!aset.empty());
|
||||
_player->KillPlayer();
|
||||
_player->BuildPlayerRepop();
|
||||
_player->RepopAtGraveyard();
|
||||
|
||||
// give honor to all attackers from set like group case
|
||||
for (std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr)
|
||||
(*itr)->RewardHonor(_player,aset.size());
|
||||
|
||||
// give bg rewards and update counters like kill by first from attackers
|
||||
// this can't be called for all attackers.
|
||||
if (!aset.empty())
|
||||
if (BattleGround *bg = _player->GetBattleGround())
|
||||
bg->HandleKillPlayer(_player,*aset.begin());
|
||||
}
|
||||
else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
|
||||
{
|
||||
// this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
|
||||
_player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
|
||||
//_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time
|
||||
_player->KillPlayer();
|
||||
_player->BuildPlayerRepop();
|
||||
_player->RepopAtGraveyard();
|
||||
}
|
||||
//drop a flag if player is carrying it
|
||||
if (BattleGround *bg = _player->GetBattleGround())
|
||||
bg->EventPlayerLoggedOut(_player);
|
||||
|
||||
///- Teleport to home if the player is in an invalid instance
|
||||
if (!_player->m_InstanceValid && !_player->isGameMaster())
|
||||
_player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation());
|
||||
|
||||
sOutdoorPvPMgr.HandlePlayerLeaveZone(_player,_player->GetZoneId());
|
||||
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
{
|
||||
if (BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i))
|
||||
{
|
||||
_player->RemoveBattleGroundQueueId(bgQueueTypeId);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[ bgQueueTypeId ].RemovePlayer(_player->GetGUID(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Repop at GraveYard or other player far teleport will prevent saving player because of not present map
|
||||
// Teleport player immediately for correct player save
|
||||
while (_player->IsBeingTeleportedFar())
|
||||
HandleMoveWorldportAckOpcode();
|
||||
|
||||
///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
|
||||
Guild *guild = objmgr.GetGuildById(_player->GetGuildId());
|
||||
if (guild)
|
||||
{
|
||||
guild->SetMemberStats(_player->GetGUID());
|
||||
guild->UpdateLogoutTime(_player->GetGUID());
|
||||
|
||||
guild->BroadcastEvent(GE_SIGNED_OFF, _player->GetGUID(), 1, _player->GetName(), "", "");
|
||||
}
|
||||
|
||||
///- Remove pet
|
||||
_player->RemovePet(NULL,PET_SAVE_AS_CURRENT, true);
|
||||
|
||||
///- empty buyback items and save the player in the database
|
||||
// some save parts only correctly work in case player present in map/player_lists (pets, etc)
|
||||
if (Save)
|
||||
{
|
||||
uint32 eslot;
|
||||
for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
|
||||
{
|
||||
eslot = j - BUYBACK_SLOT_START;
|
||||
_player->SetUInt64Value(PLAYER_FIELD_VENDORBUYBACK_SLOT_1 + (eslot * 2), 0);
|
||||
_player->SetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1 + eslot, 0);
|
||||
_player->SetUInt32Value(PLAYER_FIELD_BUYBACK_TIMESTAMP_1 + eslot, 0);
|
||||
}
|
||||
_player->SaveToDB();
|
||||
}
|
||||
|
||||
///- Leave all channels before player delete...
|
||||
_player->CleanupChannels();
|
||||
|
||||
///- If the player is in a group (or invited), remove him. If the group if then only 1 person, disband the group.
|
||||
_player->UninviteFromGroup();
|
||||
|
||||
// remove player from the group if he is:
|
||||
// a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected)
|
||||
if (_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket)
|
||||
_player->RemoveFromGroup();
|
||||
|
||||
///- Send update to group and reset stored max enchanting level
|
||||
if (_player->GetGroup())
|
||||
{
|
||||
_player->GetGroup()->SendUpdate();
|
||||
_player->GetGroup()->ResetMaxEnchantingLevel();
|
||||
}
|
||||
|
||||
///- Broadcast a logout message to the player's friends
|
||||
sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true);
|
||||
sSocialMgr.RemovePlayerSocial (_player->GetGUIDLow ());
|
||||
|
||||
///- Remove the player from the world
|
||||
// the player may not be in the world when logging out
|
||||
// e.g if he got disconnected during a transfer to another map
|
||||
// calls to GetMap in this case may cause crashes
|
||||
_player->CleanupsBeforeDelete();
|
||||
sLog.outChar("Account: %d (IP: %s) Logout Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName() ,_player->GetGUIDLow());
|
||||
Map* _map = _player->GetMap();
|
||||
_map->Remove(_player, true);
|
||||
SetPlayer(NULL); // deleted in Remove call
|
||||
|
||||
///- Send the 'logout complete' packet to the client
|
||||
WorldPacket data(SMSG_LOGOUT_COMPLETE, 0);
|
||||
SendPacket(&data);
|
||||
|
||||
///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline
|
||||
//No SQL injection as AccountId is uint32
|
||||
CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",
|
||||
GetAccountId());
|
||||
sLog.outDebug("SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
|
||||
}
|
||||
|
||||
//Hook for OnLogout Event
|
||||
sScriptMgr.OnLogout(_player);
|
||||
|
||||
m_playerLogout = false;
|
||||
m_playerSave = false;
|
||||
m_playerRecentlyLogout = true;
|
||||
LogoutRequest(0);
|
||||
}
|
||||
|
||||
/// Kick a player out of the World
|
||||
void WorldSession::KickPlayer()
|
||||
{
|
||||
if (m_Socket)
|
||||
m_Socket->CloseSocket ();
|
||||
}
|
||||
|
||||
void WorldSession::SendNotification(const char *format,...)
|
||||
{
|
||||
if (format)
|
||||
{
|
||||
va_list ap;
|
||||
char szStr [1024];
|
||||
szStr[0] = '\0';
|
||||
va_start(ap, format);
|
||||
vsnprintf(szStr, 1024, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1));
|
||||
data << szStr;
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::SendNotification(int32 string_id,...)
|
||||
{
|
||||
char const* format = GetTrinityString(string_id);
|
||||
if (format)
|
||||
{
|
||||
va_list ap;
|
||||
char szStr [1024];
|
||||
szStr[0] = '\0';
|
||||
va_start(ap, string_id);
|
||||
vsnprintf(szStr, 1024, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1));
|
||||
data << szStr;
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
const char * WorldSession::GetTrinityString(int32 entry) const
|
||||
{
|
||||
return objmgr.GetTrinityString(entry,GetSessionDbLocaleIndex());
|
||||
}
|
||||
|
||||
void WorldSession::Handle_NULL(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outError("SESSION: received unhandled opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(recvPacket.GetOpcode()),
|
||||
recvPacket.GetOpcode());
|
||||
}
|
||||
|
||||
void WorldSession::Handle_EarlyProccess(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outError("SESSION: received opcode %s (0x%.4X) that must be processed in WorldSocket::OnRead",
|
||||
LookupOpcodeName(recvPacket.GetOpcode()),
|
||||
recvPacket.GetOpcode());
|
||||
}
|
||||
|
||||
void WorldSession::Handle_ServerSide(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outError("SESSION: received server-side opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(recvPacket.GetOpcode()),
|
||||
recvPacket.GetOpcode());
|
||||
}
|
||||
|
||||
void WorldSession::Handle_Deprecated(WorldPacket& recvPacket)
|
||||
{
|
||||
sLog.outError("SESSION: received deprecated opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(recvPacket.GetOpcode()),
|
||||
recvPacket.GetOpcode());
|
||||
}
|
||||
|
||||
void WorldSession::SendAuthWaitQue(uint32 position)
|
||||
{
|
||||
if (position == 0)
|
||||
{
|
||||
WorldPacket packet(SMSG_AUTH_RESPONSE, 1);
|
||||
packet << uint8(AUTH_OK);
|
||||
SendPacket(&packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPacket packet(SMSG_AUTH_RESPONSE, 6);
|
||||
packet << uint8(AUTH_WAIT_QUEUE);
|
||||
packet << uint32(position);
|
||||
packet << uint8(0); // unk
|
||||
SendPacket(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::LoadGlobalAccountData()
|
||||
{
|
||||
LoadAccountData(
|
||||
CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId()),
|
||||
GLOBAL_CACHE_MASK
|
||||
);
|
||||
}
|
||||
|
||||
void WorldSession::LoadAccountData(QueryResult_AutoPtr result, uint32 mask)
|
||||
{
|
||||
for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
|
||||
if (mask & (1 << i))
|
||||
m_accountData[i] = AccountData();
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
uint32 type = fields[0].GetUInt32();
|
||||
if (type >= NUM_ACCOUNT_DATA_TYPES)
|
||||
{
|
||||
sLog.outError("Table `%s` have invalid account data type (%u), ignore.",
|
||||
mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mask & (1 << type)) == 0)
|
||||
{
|
||||
sLog.outError("Table `%s` have non appropriate for table account data type (%u), ignore.",
|
||||
mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
m_accountData[type].Time = fields[1].GetUInt32();
|
||||
m_accountData[type].Data = fields[2].GetCppString();
|
||||
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::string data)
|
||||
{
|
||||
if ((1 << type) & GLOBAL_CACHE_MASK)
|
||||
{
|
||||
uint32 acc = GetAccountId();
|
||||
|
||||
CharacterDatabase.BeginTransaction ();
|
||||
CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
|
||||
CharacterDatabase.escape_string(data);
|
||||
CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
|
||||
CharacterDatabase.CommitTransaction ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// _player can be NULL and packet received after logout but m_GUID still store correct guid
|
||||
if (!m_GUIDLow)
|
||||
return;
|
||||
|
||||
CharacterDatabase.BeginTransaction ();
|
||||
CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid='%u' AND type='%u'", m_GUIDLow, type);
|
||||
CharacterDatabase.escape_string(data);
|
||||
CharacterDatabase.PExecute("INSERT INTO character_account_data VALUES ('%u','%u','%u','%s')", m_GUIDLow, type, (uint32)time_, data.c_str());
|
||||
CharacterDatabase.CommitTransaction ();
|
||||
}
|
||||
|
||||
m_accountData[type].Time = time_;
|
||||
m_accountData[type].Data = data;
|
||||
}
|
||||
|
||||
void WorldSession::SendAccountDataTimes(uint32 mask)
|
||||
{
|
||||
WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); // changed in WotLK
|
||||
data << uint32(time(NULL)); // unix time of something
|
||||
data << uint8(1);
|
||||
data << uint32(mask); // type mask
|
||||
for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
|
||||
if (mask & (1 << i))
|
||||
data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::LoadTutorialsData()
|
||||
{
|
||||
for (int aX = 0 ; aX < 8 ; ++aX)
|
||||
m_Tutorials[ aX ] = 0;
|
||||
|
||||
QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u'", GetAccountId());
|
||||
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
for (int iI = 0; iI < 8; ++iI)
|
||||
m_Tutorials[iI] = fields[iI].GetUInt32();
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
m_TutorialsChanged = false;
|
||||
}
|
||||
|
||||
void WorldSession::SendTutorialsData()
|
||||
{
|
||||
WorldPacket data(SMSG_TUTORIAL_FLAGS, 4*8);
|
||||
for (uint32 i = 0; i < 8; ++i)
|
||||
data << m_Tutorials[i];
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SaveTutorialsData()
|
||||
{
|
||||
if (!m_TutorialsChanged)
|
||||
return;
|
||||
|
||||
uint32 Rows=0;
|
||||
// it's better than rebuilding indexes multiple times
|
||||
QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT count(*) AS r FROM character_tutorial WHERE account = '%u'", GetAccountId());
|
||||
if (result)
|
||||
Rows = result->Fetch()[0].GetUInt32();
|
||||
|
||||
if (Rows)
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u'",
|
||||
m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetAccountId());
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("INSERT INTO character_tutorial (account,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]);
|
||||
}
|
||||
|
||||
m_TutorialsChanged = false;
|
||||
}
|
||||
|
||||
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
|
||||
{
|
||||
data >> mi->flags;
|
||||
data >> mi->unk1;
|
||||
data >> mi->time;
|
||||
data >> mi->x;
|
||||
data >> mi->y;
|
||||
data >> mi->z;
|
||||
data >> mi->o;
|
||||
|
||||
if (mi->flags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
{
|
||||
if (!data.readPackGUID(mi->t_guid))
|
||||
return;
|
||||
|
||||
data >> mi->t_x;
|
||||
data >> mi->t_y;
|
||||
data >> mi->t_z;
|
||||
data >> mi->t_o;
|
||||
data >> mi->t_time;
|
||||
data >> mi->t_seat;
|
||||
}
|
||||
|
||||
if ((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->unk1 & 0x20))
|
||||
{
|
||||
data >> mi->s_pitch;
|
||||
}
|
||||
|
||||
data >> mi->fallTime;
|
||||
|
||||
if (mi->flags & MOVEMENTFLAG_JUMPING)
|
||||
{
|
||||
data >> mi->j_zspeed;
|
||||
data >> mi->j_sinAngle;
|
||||
data >> mi->j_cosAngle;
|
||||
data >> mi->j_xyspeed;
|
||||
}
|
||||
|
||||
if (mi->flags & MOVEMENTFLAG_SPLINE)
|
||||
{
|
||||
data >> mi->u_unk1;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
|
||||
{
|
||||
data->appendPackGUID(mi->guid);
|
||||
|
||||
*data << mi->flags;
|
||||
*data << mi->unk1;
|
||||
*data << mi->time;
|
||||
*data << mi->x;
|
||||
*data << mi->y;
|
||||
*data << mi->z;
|
||||
*data << mi->o;
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
data->appendPackGUID(mi->t_guid);
|
||||
|
||||
*data << mi->t_x;
|
||||
*data << mi->t_y;
|
||||
*data << mi->t_z;
|
||||
*data << mi->t_o;
|
||||
*data << mi->t_time;
|
||||
*data << mi->t_seat;
|
||||
}
|
||||
|
||||
if ((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->unk1 & 0x20))
|
||||
{
|
||||
*data << mi->s_pitch;
|
||||
}
|
||||
|
||||
*data << mi->fallTime;
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||
{
|
||||
*data << mi->j_zspeed;
|
||||
*data << mi->j_sinAngle;
|
||||
*data << mi->j_cosAngle;
|
||||
*data << mi->j_xyspeed;
|
||||
}
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE))
|
||||
{
|
||||
*data << mi->u_unk1;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::ReadAddonsInfo(WorldPacket &data)
|
||||
{
|
||||
if (data.rpos() + 4 > data.size())
|
||||
return;
|
||||
uint32 size;
|
||||
data >> size;
|
||||
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (size > 0xFFFFF)
|
||||
{
|
||||
sLog.outError("WorldSession::ReadAddonsInfo addon info too big, size %u", size);
|
||||
return;
|
||||
}
|
||||
|
||||
uLongf uSize = size;
|
||||
|
||||
uint32 pos = data.rpos();
|
||||
|
||||
ByteBuffer addonInfo;
|
||||
addonInfo.resize(size);
|
||||
|
||||
if (uncompress(const_cast<uint8*>(addonInfo.contents()), &uSize, const_cast<uint8*>(data.contents() + pos), data.size() - pos) == Z_OK)
|
||||
{
|
||||
uint32 addonsCount;
|
||||
addonInfo >> addonsCount; // addons count
|
||||
|
||||
for (uint32 i = 0; i < addonsCount; ++i)
|
||||
{
|
||||
std::string addonName;
|
||||
uint8 enabled;
|
||||
uint32 crc, unk1;
|
||||
|
||||
// check next addon data format correctness
|
||||
if (addonInfo.rpos()+1 > addonInfo.size())
|
||||
return;
|
||||
|
||||
addonInfo >> addonName;
|
||||
|
||||
addonInfo >> enabled >> crc >> unk1;
|
||||
|
||||
sLog.outDetail("ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1);
|
||||
|
||||
AddonInfo addon(addonName, enabled, crc, 2, true);
|
||||
|
||||
SavedAddon const* savedAddon = sAddonMgr.GetAddonInfo(addonName);
|
||||
if (savedAddon)
|
||||
{
|
||||
bool match = true;
|
||||
|
||||
if (addon.CRC != savedAddon->CRC)
|
||||
match = false;
|
||||
|
||||
if (!match)
|
||||
sLog.outDetail("ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC);
|
||||
else
|
||||
sLog.outDetail("ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC);
|
||||
}
|
||||
else
|
||||
{
|
||||
sAddonMgr.SaveAddon(addon);
|
||||
|
||||
sLog.outDetail("ADDON: %s (0x%x) was not known, saving...", addon.Name.c_str(), addon.CRC);
|
||||
}
|
||||
|
||||
// TODO: Find out when to not use CRC/pubkey, and other possible states.
|
||||
m_addonsList.push_back(addon);
|
||||
}
|
||||
|
||||
uint32 currentTime;
|
||||
addonInfo >> currentTime;
|
||||
sLog.outDebug("ADDON: CurrentTime: %u", currentTime);
|
||||
|
||||
if (addonInfo.rpos() != addonInfo.size())
|
||||
sLog.outDebug("packet under-read!");
|
||||
}
|
||||
else
|
||||
sLog.outError("Addon packet uncompress error!");
|
||||
}
|
||||
|
||||
void WorldSession::SendAddonsInfo()
|
||||
{
|
||||
uint8 addonPublicKey[256] =
|
||||
{
|
||||
0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
|
||||
0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
|
||||
0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
|
||||
0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
|
||||
0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
|
||||
0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
|
||||
0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
|
||||
0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
|
||||
0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
|
||||
0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
|
||||
0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
|
||||
0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
|
||||
0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
|
||||
0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
|
||||
0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
|
||||
0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
|
||||
};
|
||||
|
||||
WorldPacket data(SMSG_ADDON_INFO, 4);
|
||||
|
||||
for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
|
||||
{
|
||||
data << uint8(itr->State);
|
||||
|
||||
uint8 crcpub = itr->UsePublicKeyOrCRC;
|
||||
data << uint8(crcpub);
|
||||
if (crcpub)
|
||||
{
|
||||
uint8 usepk = (itr->CRC != STANDARD_ADDON_CRC); // If addon is Standard addon CRC
|
||||
data << uint8(usepk);
|
||||
if (usepk) // if CRC is wrong, add public key (client need it)
|
||||
{
|
||||
sLog.outDetail("ADDON: CRC (0x%x) for addon %s is wrong (does not match expected 0x%x), sending pubkey",
|
||||
itr->CRC, itr->Name.c_str(), STANDARD_ADDON_CRC);
|
||||
|
||||
data.append(addonPublicKey, sizeof(addonPublicKey));
|
||||
}
|
||||
|
||||
data << uint32(/*itr->CRC*/ 0); // TODO: Find out the meaning of this.
|
||||
}
|
||||
|
||||
uint8 unk3 = 0; // 0 is sent here
|
||||
data << uint8(unk3);
|
||||
if (unk3)
|
||||
{
|
||||
// String, length 256 (null terminated)
|
||||
data << uint8(0);
|
||||
}
|
||||
}
|
||||
|
||||
m_addonsList.clear();
|
||||
|
||||
uint32 count = 0;
|
||||
data << uint32(count);
|
||||
/*for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
uint32
|
||||
string (16 bytes)
|
||||
string (16 bytes)
|
||||
uint32
|
||||
uint32
|
||||
}*/
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SetPlayer(Player *plr)
|
||||
{
|
||||
_player = plr;
|
||||
|
||||
// set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset
|
||||
if (_player)
|
||||
m_GUIDLow = _player->GetGUIDLow();
|
||||
}
|
||||
@@ -0,0 +1,829 @@
|
||||
/*
|
||||
* 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 u2w
|
||||
/// @{
|
||||
/// \file
|
||||
|
||||
#ifndef __WORLDSESSION_H
|
||||
#define __WORLDSESSION_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "AddonMgr.h"
|
||||
#include "QueryResult.h"
|
||||
#include "World.h"
|
||||
|
||||
struct ItemPrototype;
|
||||
struct AuctionEntry;
|
||||
struct DeclinedName;
|
||||
struct MovementInfo;
|
||||
|
||||
class Creature;
|
||||
class Item;
|
||||
class Object;
|
||||
class Player;
|
||||
class Unit;
|
||||
class GameObject;
|
||||
class WorldPacket;
|
||||
class WorldSocket;
|
||||
class QueryResult;
|
||||
class LoginQueryHolder;
|
||||
class CharacterHandler;
|
||||
struct AreaTableEntry;
|
||||
|
||||
enum AccountDataType
|
||||
{
|
||||
GLOBAL_CONFIG_CACHE = 0, // 0x01 g
|
||||
PER_CHARACTER_CONFIG_CACHE = 1, // 0x02 p
|
||||
GLOBAL_BINDINGS_CACHE = 2, // 0x04 g
|
||||
PER_CHARACTER_BINDINGS_CACHE = 3, // 0x08 p
|
||||
GLOBAL_MACROS_CACHE = 4, // 0x10 g
|
||||
PER_CHARACTER_MACROS_CACHE = 5, // 0x20 p
|
||||
PER_CHARACTER_LAYOUT_CACHE = 6, // 0x40 p
|
||||
PER_CHARACTER_CHAT_CACHE = 7, // 0x80 p
|
||||
};
|
||||
|
||||
#define NUM_ACCOUNT_DATA_TYPES 8
|
||||
|
||||
#define GLOBAL_CACHE_MASK 0x15
|
||||
#define PER_CHARACTER_CACHE_MASK 0xEA
|
||||
|
||||
struct AccountData
|
||||
{
|
||||
AccountData() : Time(0), Data("") {}
|
||||
|
||||
time_t Time;
|
||||
std::string Data;
|
||||
};
|
||||
|
||||
enum PartyOperation
|
||||
{
|
||||
PARTY_OP_INVITE = 0,
|
||||
PARTY_OP_UNINVITE = 1,
|
||||
PARTY_OP_LEAVE = 2,
|
||||
PARTY_OP_SWAP = 4
|
||||
};
|
||||
|
||||
enum PartyResult
|
||||
{
|
||||
ERR_PARTY_RESULT_OK = 0,
|
||||
ERR_BAD_PLAYER_NAME_S = 1,
|
||||
ERR_TARGET_NOT_IN_GROUP_S = 2,
|
||||
ERR_TARGET_NOT_IN_INSTANCE_S = 3,
|
||||
ERR_GROUP_FULL = 4,
|
||||
ERR_ALREADY_IN_GROUP_S = 5,
|
||||
ERR_NOT_IN_GROUP = 6,
|
||||
ERR_NOT_LEADER = 7,
|
||||
ERR_PLAYER_WRONG_FACTION = 8,
|
||||
ERR_IGNORING_YOU_S = 9,
|
||||
ERR_LFG_PENDING = 12,
|
||||
ERR_INVITE_RESTRICTED = 13,
|
||||
ERR_GROUP_SWAP_FAILED = 14, // if (PartyOperation == PARTY_OP_SWAP) ERR_GROUP_SWAP_FAILED else ERR_INVITE_IN_COMBAT
|
||||
ERR_INVITE_UNKNOWN_REALM = 15,
|
||||
ERR_INVITE_NO_PARTY_SERVER = 16,
|
||||
ERR_INVITE_PARTY_BUSY = 17,
|
||||
ERR_PARTY_TARGET_AMBIGUOUS = 18,
|
||||
ERR_PARTY_LFG_INVITE_RAID_LOCKED = 19,
|
||||
ERR_PARTY_LFG_BOOT_LIMIT = 20,
|
||||
ERR_PARTY_LFG_BOOT_COOLDOWN_S = 21,
|
||||
ERR_PARTY_LFG_BOOT_IN_PROGRESS = 22,
|
||||
ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS = 23,
|
||||
ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S = 24,
|
||||
ERR_RAID_DISALLOWED_BY_LEVEL = 25,
|
||||
ERR_PARTY_LFG_BOOT_IN_COMBAT = 26,
|
||||
ERR_VOTE_KICK_REASON_NEEDED = 27,
|
||||
ERR_PARTY_LFG_BOOT_DUNGEON_COMPLETE = 28,
|
||||
ERR_PARTY_LFG_BOOT_LOOT_ROLLS = 29,
|
||||
ERR_PARTY_LFG_TELEPORT_IN_COMBAT = 30
|
||||
};
|
||||
|
||||
enum ChatRestrictionType
|
||||
{
|
||||
ERR_CHAT_RESTRICTED = 0,
|
||||
ERR_CHAT_THROTTLED = 1,
|
||||
ERR_USER_SQUELCHED = 2,
|
||||
ERR_YELL_RESTRICTED = 3
|
||||
};
|
||||
|
||||
/// Player session in the World
|
||||
class WorldSession
|
||||
{
|
||||
friend class CharacterHandler;
|
||||
public:
|
||||
WorldSession(uint32 id, WorldSocket *sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale);
|
||||
~WorldSession();
|
||||
|
||||
bool PlayerLoading() const { return m_playerLoading; }
|
||||
bool PlayerLogout() const { return m_playerLogout; }
|
||||
bool PlayerLogoutWithSave() const { return m_playerLogout && m_playerSave; }
|
||||
|
||||
void SizeError(WorldPacket const& packet, uint32 size) const;
|
||||
|
||||
void ReadAddonsInfo(WorldPacket &data);
|
||||
void SendAddonsInfo();
|
||||
|
||||
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi);
|
||||
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi);
|
||||
|
||||
void SendPacket(WorldPacket const* packet);
|
||||
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
|
||||
void SendNotification(int32 string_id,...);
|
||||
void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName);
|
||||
void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
|
||||
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3);
|
||||
void SendSetPhaseShift(uint32 phaseShift);
|
||||
void SendQueryTimeResponse();
|
||||
|
||||
AccountTypes GetSecurity() const { return _security; }
|
||||
uint32 GetAccountId() const { return _accountId; }
|
||||
Player* GetPlayer() const { return _player; }
|
||||
char const* GetPlayerName() const;
|
||||
void SetSecurity(AccountTypes security) { _security = security; }
|
||||
std::string const& GetRemoteAddress() { return m_Address; }
|
||||
void SetPlayer(Player *plr);
|
||||
uint8 Expansion() const { return m_expansion; }
|
||||
|
||||
/// Session in auth.queue currently
|
||||
void SetInQueue(bool state) { m_inQueue = state; }
|
||||
|
||||
/// Is the user engaged in a log out process?
|
||||
bool isLogingOut() const { return _logoutTime || m_playerLogout; }
|
||||
|
||||
/// Engage the logout process for the user
|
||||
void LogoutRequest(time_t requestTime)
|
||||
{
|
||||
_logoutTime = requestTime;
|
||||
}
|
||||
|
||||
/// Is logout cooldown expired?
|
||||
bool ShouldLogOut(time_t currTime) const
|
||||
{
|
||||
return (_logoutTime > 0 && currTime >= _logoutTime + 20);
|
||||
}
|
||||
|
||||
void LogoutPlayer(bool Save);
|
||||
void KickPlayer();
|
||||
|
||||
void QueuePacket(WorldPacket* new_packet);
|
||||
bool Update(uint32 diff);
|
||||
|
||||
/// Handle the authentication waiting queue (to be completed)
|
||||
void SendAuthWaitQue(uint32 position);
|
||||
|
||||
//void SendTestCreatureQueryOpcode(uint32 entry, uint64 guid, uint32 testvalue);
|
||||
void SendNameQueryOpcode(Player* p);
|
||||
void SendNameQueryOpcodeFromDB(uint64 guid);
|
||||
static void SendNameQueryOpcodeFromDBCallBack(QueryResult_AutoPtr result, uint32 accountId);
|
||||
|
||||
void SendTrainerList(uint64 guid);
|
||||
void SendTrainerList(uint64 guid, const std::string& strTitle);
|
||||
void SendListInventory(uint64 guid);
|
||||
void SendShowBank(uint64 guid);
|
||||
void SendTabardVendorActivate(uint64 guid);
|
||||
void SendSpiritResurrect();
|
||||
void SendBindPoint(Creature* npc);
|
||||
|
||||
void SendAttackStop(Unit const* enemy);
|
||||
|
||||
void SendBattlegGroundList(uint64 guid, BattleGroundTypeId bgTypeId);
|
||||
|
||||
void SendTradeStatus(uint32 status);
|
||||
void SendCancelTrade();
|
||||
|
||||
void SendStablePet(uint64 guid);
|
||||
void SendPetitionQueryOpcode(uint64 petitionguid);
|
||||
void SendUpdateTrade();
|
||||
|
||||
//pet
|
||||
void SendPetNameQuery(uint64 guid, uint32 petnumber);
|
||||
|
||||
// Account Data
|
||||
AccountData *GetAccountData(AccountDataType type) { return &m_accountData[type]; }
|
||||
void SetAccountData(AccountDataType type, time_t time_, std::string data);
|
||||
void SendAccountDataTimes(uint32 mask);
|
||||
void LoadGlobalAccountData();
|
||||
void LoadAccountData(QueryResult_AutoPtr result, uint32 mask);
|
||||
void LoadTutorialsData();
|
||||
void SendTutorialsData();
|
||||
void SaveTutorialsData();
|
||||
uint32 GetTutorialInt(uint32 intId)
|
||||
{
|
||||
return m_Tutorials[intId];
|
||||
}
|
||||
|
||||
void SetTutorialInt(uint32 intId, uint32 value)
|
||||
{
|
||||
if (m_Tutorials[intId] != value)
|
||||
{
|
||||
m_Tutorials[intId] = value;
|
||||
m_TutorialsChanged = true;
|
||||
}
|
||||
}
|
||||
//used with item_page table
|
||||
bool SendItemInfo(uint32 itemid, WorldPacket data);
|
||||
//auction
|
||||
void SendAuctionHello(uint64 guid, Creature * unit);
|
||||
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0);
|
||||
void SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template);
|
||||
void SendAuctionOwnerNotification(AuctionEntry * auction);
|
||||
void SendAuctionOutbiddedMail(AuctionEntry * auction, uint32 newPrice);
|
||||
void SendAuctionCancelledToBidderMail(AuctionEntry* auction);
|
||||
|
||||
//Item Enchantment
|
||||
void SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID);
|
||||
void SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid,uint32 slot,uint32 Duration);
|
||||
|
||||
//Taxi
|
||||
void SendTaxiStatus(uint64 guid);
|
||||
void SendTaxiMenu(Creature* unit);
|
||||
void SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathNode = 0);
|
||||
bool SendLearnNewTaxiNode(Creature* unit);
|
||||
|
||||
// Guild/Arena Team
|
||||
void SendGuildCommandResult(uint32 typecmd, const std::string& str, uint32 cmdresult);
|
||||
void SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id);
|
||||
void SendNotInArenaTeamPacket(uint8 type);
|
||||
void SendPetitionShowList(uint64 guid);
|
||||
void SendSaveGuildEmblem(uint32 msg);
|
||||
// Looking For Group
|
||||
// TRUE values set by client sending CMSG_LFG_SET_AUTOJOIN and CMSG_LFM_CLEAR_AUTOFILL before player login
|
||||
bool LookingForGroup_auto_join;
|
||||
bool LookingForGroup_auto_add;
|
||||
|
||||
void BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data);
|
||||
|
||||
void DoLootRelease(uint64 lguid);
|
||||
|
||||
// Account mute time
|
||||
time_t m_muteTime;
|
||||
|
||||
// Locales
|
||||
LocaleConstant GetSessionDbcLocale() const { return m_sessionDbcLocale; }
|
||||
int GetSessionDbLocaleIndex() const { return m_sessionDbLocaleIndex; }
|
||||
const char *GetTrinityString(int32 entry) const;
|
||||
|
||||
uint32 GetLatency() const { return m_latency; }
|
||||
void SetLatency(uint32 latency) { m_latency = latency; }
|
||||
uint32 getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus);
|
||||
|
||||
time_t m_timeOutTime;
|
||||
void UpdateTimeOutTime(uint32 diff)
|
||||
{
|
||||
if (diff > m_timeOutTime)
|
||||
m_timeOutTime = 0;
|
||||
else
|
||||
m_timeOutTime -= diff;
|
||||
}
|
||||
void ResetTimeOutTime()
|
||||
{
|
||||
m_timeOutTime = sWorld.getConfig(CONFIG_SOCKET_TIMEOUTTIME);
|
||||
}
|
||||
bool IsConnectionIdle() const
|
||||
{
|
||||
if (m_timeOutTime <= 0 && !m_inQueue)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public: // opcodes handlers
|
||||
|
||||
void Handle_NULL(WorldPacket& recvPacket); // not used
|
||||
void Handle_EarlyProccess(WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnRead
|
||||
void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client
|
||||
void Handle_Deprecated(WorldPacket& recvPacket); // never used anymore by client
|
||||
|
||||
void HandleCharEnumOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharDeleteOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharCreateOpcode(WorldPacket& recvPacket);
|
||||
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharEnum(QueryResult_AutoPtr result);
|
||||
void HandlePlayerLogin(LoginQueryHolder * holder);
|
||||
|
||||
// played time
|
||||
void HandlePlayedTime(WorldPacket& recvPacket);
|
||||
|
||||
// new
|
||||
void HandleMoveUnRootAck(WorldPacket& recvPacket);
|
||||
void HandleMoveRootAck(WorldPacket& recvPacket);
|
||||
void HandleLookingForGroup(WorldPacket& recvPacket);
|
||||
|
||||
// new inspect
|
||||
void HandleInspectOpcode(WorldPacket& recvPacket);
|
||||
|
||||
// new party stats
|
||||
void HandleInspectHonorStatsOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleMoveWaterWalkAck(WorldPacket& recvPacket);
|
||||
void HandleFeatherFallAck(WorldPacket &recv_data);
|
||||
|
||||
void HandleMoveHoverAck(WorldPacket & recv_data);
|
||||
|
||||
void HandleMountSpecialAnimOpcode(WorldPacket &recvdata);
|
||||
|
||||
// character view
|
||||
void HandleShowingHelmOpcode(WorldPacket& recv_data);
|
||||
void HandleShowingCloakOpcode(WorldPacket& recv_data);
|
||||
|
||||
// repair
|
||||
void HandleRepairItemOpcode(WorldPacket& recvPacket);
|
||||
|
||||
// Knockback
|
||||
void HandleMoveKnockBackAck(WorldPacket& recvPacket);
|
||||
|
||||
void HandleMoveTeleportAck(WorldPacket& recvPacket);
|
||||
void HandleForceSpeedChangeAck(WorldPacket & recv_data);
|
||||
|
||||
void HandlePingOpcode(WorldPacket& recvPacket);
|
||||
void HandleAuthSessionOpcode(WorldPacket& recvPacket);
|
||||
void HandleRepopRequestOpcode(WorldPacket& recvPacket);
|
||||
void HandleAutostoreLootItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleLootMoneyOpcode(WorldPacket& recvPacket);
|
||||
void HandleLootOpcode(WorldPacket& recvPacket);
|
||||
void HandleLootReleaseOpcode(WorldPacket& recvPacket);
|
||||
void HandleLootMasterGiveOpcode(WorldPacket& recvPacket);
|
||||
void HandleWhoOpcode(WorldPacket& recvPacket);
|
||||
void HandleLogoutRequestOpcode(WorldPacket& recvPacket);
|
||||
void HandlePlayerLogoutOpcode(WorldPacket& recvPacket);
|
||||
void HandleLogoutCancelOpcode(WorldPacket& recvPacket);
|
||||
|
||||
// GM Ticket opcodes
|
||||
void HandleGMTicketCreateOpcode(WorldPacket& recvPacket);
|
||||
void HandleGMTicketUpdateOpcode(WorldPacket& recvPacket);
|
||||
void HandleGMTicketDeleteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGMTicketGetTicketOpcode(WorldPacket& recvPacket);
|
||||
void HandleGMTicketSystemStatusOpcode(WorldPacket& recvPacket);
|
||||
void SendGMTicketGetTicket(uint32 status, char const* text);
|
||||
|
||||
//void HandleGMSurveySubmit(WorldPacket& recvPacket);
|
||||
|
||||
void HandleTogglePvP(WorldPacket& recvPacket);
|
||||
|
||||
void HandleZoneUpdateOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetTargetOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetSelectionOpcode(WorldPacket& recvPacket);
|
||||
void HandleStandStateChangeOpcode(WorldPacket& recvPacket);
|
||||
void HandleEmoteOpcode(WorldPacket& recvPacket);
|
||||
void HandleContactListOpcode(WorldPacket& recvPacket);
|
||||
void HandleAddFriendOpcode(WorldPacket& recvPacket);
|
||||
static void HandleAddFriendOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string friendNote);
|
||||
void HandleDelFriendOpcode(WorldPacket& recvPacket);
|
||||
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
|
||||
static void HandleAddIgnoreOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId);
|
||||
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
|
||||
void HandleBugOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetAmmoOpcode(WorldPacket& recvPacket);
|
||||
void HandleItemNameQueryOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleAreaTriggerOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleSetFactionAtWar(WorldPacket & recv_data);
|
||||
void HandleSetFactionCheat(WorldPacket & recv_data);
|
||||
void HandleSetWatchedFactionOpcode(WorldPacket & recv_data);
|
||||
void HandleSetFactionInactiveOpcode(WorldPacket & recv_data);
|
||||
|
||||
void HandleUpdateAccountData(WorldPacket& recvPacket);
|
||||
void HandleRequestAccountData(WorldPacket& recvPacket);
|
||||
void HandleSetActionButtonOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleGameObjectUseOpcode(WorldPacket& recPacket);
|
||||
void HandleMeetingStoneInfo(WorldPacket& recPacket);
|
||||
void HandleGameobjectReportUse(WorldPacket& recvPacket);
|
||||
|
||||
void HandleNameQueryOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleQueryTimeOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleCreatureQueryOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleGameObjectQueryOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleMoveWorldportAckOpcode(WorldPacket& recvPacket);
|
||||
void HandleMoveWorldportAckOpcode(); // for server-side calls
|
||||
|
||||
void HandleMovementOpcodes(WorldPacket& recvPacket);
|
||||
void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
|
||||
void HandleMoveNotActiveMover(WorldPacket &recv_data);
|
||||
void HandleDismissControlledVehicle(WorldPacket &recv_data);
|
||||
void HandleRequestVehicleExit(WorldPacket &recv_data);
|
||||
void HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data);
|
||||
void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
|
||||
|
||||
void HandleRequestRaidInfoOpcode(WorldPacket & recv_data);
|
||||
|
||||
void HandleBattlefieldStatusOpcode(WorldPacket &recv_data);
|
||||
void HandleBattleMasterHelloOpcode(WorldPacket &recv_data);
|
||||
|
||||
void HandleGroupInviteOpcode(WorldPacket& recvPacket);
|
||||
//void HandleGroupCancelOpcode(WorldPacket& recvPacket);
|
||||
void HandleGroupAcceptOpcode(WorldPacket& recvPacket);
|
||||
void HandleGroupDeclineOpcode(WorldPacket& recvPacket);
|
||||
void HandleGroupUninviteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket);
|
||||
void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket);
|
||||
void HandleGroupDisbandOpcode(WorldPacket& recvPacket);
|
||||
void HandleOptOutOfLootOpcode(WorldPacket &recv_data);
|
||||
void HandleLootMethodOpcode(WorldPacket& recvPacket);
|
||||
void HandleLootRoll(WorldPacket &recv_data);
|
||||
void HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data);
|
||||
void HandleRaidTargetUpdateOpcode(WorldPacket & recv_data);
|
||||
void HandleRaidReadyCheckOpcode(WorldPacket & recv_data);
|
||||
void HandleRaidReadyCheckFinishedOpcode(WorldPacket & recv_data);
|
||||
void HandleGroupRaidConvertOpcode(WorldPacket & recv_data);
|
||||
void HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data);
|
||||
void HandleGroupAssistantLeaderOpcode(WorldPacket & recv_data);
|
||||
void HandlePartyAssignmentOpcode(WorldPacket & recv_data);
|
||||
|
||||
void HandlePetitionBuyOpcode(WorldPacket& recv_data);
|
||||
void HandlePetitionShowSignOpcode(WorldPacket& recv_data);
|
||||
void HandlePetitionQueryOpcode(WorldPacket& recv_data);
|
||||
void HandlePetitionRenameOpcode(WorldPacket& recv_data);
|
||||
void HandlePetitionSignOpcode(WorldPacket& recv_data);
|
||||
void HandlePetitionDeclineOpcode(WorldPacket& recv_data);
|
||||
void HandleOfferPetitionOpcode(WorldPacket& recv_data);
|
||||
void HandleTurnInPetitionOpcode(WorldPacket& recv_data);
|
||||
|
||||
void HandleGuildQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildCreateOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildInviteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildRemoveOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildAcceptOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildDeclineOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildInfoOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildEventLogQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildRosterOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildPromoteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildDemoteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildLeaveOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildDisbandOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildLeaderOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildMOTDOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildRankOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildAddRankOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildDelRankOpcode(WorldPacket& recvPacket);
|
||||
void HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket);
|
||||
void HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);
|
||||
void HandleActivateTaxiOpcode(WorldPacket& recvPacket);
|
||||
void HandleActivateTaxiExpressOpcode(WorldPacket& recvPacket);
|
||||
void HandleMoveSplineDoneOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleTabardVendorActivateOpcode(WorldPacket& recvPacket);
|
||||
void HandleBankerActivateOpcode(WorldPacket& recvPacket);
|
||||
void HandleBuyBankSlotOpcode(WorldPacket& recvPacket);
|
||||
void HandleTrainerListOpcode(WorldPacket& recvPacket);
|
||||
void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket);
|
||||
void HandlePetitionShowListOpcode(WorldPacket& recvPacket);
|
||||
void HandleGossipHelloOpcode(WorldPacket& recvPacket);
|
||||
void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket);
|
||||
void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket);
|
||||
void HandleNpcTextQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleBinderActivateOpcode(WorldPacket& recvPacket);
|
||||
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
|
||||
void HandleStablePet(WorldPacket& recvPacket);
|
||||
void HandleUnstablePet(WorldPacket& recvPacket);
|
||||
void HandleBuyStableSlot(WorldPacket& recvPacket);
|
||||
void HandleStableRevivePet(WorldPacket& recvPacket);
|
||||
void HandleStableSwapPet(WorldPacket& recvPacket);
|
||||
|
||||
void HandleDuelAcceptedOpcode(WorldPacket& recvPacket);
|
||||
void HandleDuelCancelledOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleAcceptTradeOpcode(WorldPacket& recvPacket);
|
||||
void HandleBeginTradeOpcode(WorldPacket& recvPacket);
|
||||
void HandleBusyTradeOpcode(WorldPacket& recvPacket);
|
||||
void HandleCancelTradeOpcode(WorldPacket& recvPacket);
|
||||
void HandleClearTradeItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleIgnoreTradeOpcode(WorldPacket& recvPacket);
|
||||
void HandleInitiateTradeOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetTradeGoldOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetTradeItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleUnacceptTradeOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleAuctionHelloOpcode(WorldPacket& recvPacket);
|
||||
void HandleAuctionListItems(WorldPacket & recv_data);
|
||||
void HandleAuctionListBidderItems(WorldPacket & recv_data);
|
||||
void HandleAuctionSellItem(WorldPacket & recv_data);
|
||||
void HandleAuctionRemoveItem(WorldPacket & recv_data);
|
||||
void HandleAuctionListOwnerItems(WorldPacket & recv_data);
|
||||
void HandleAuctionPlaceBid(WorldPacket & recv_data);
|
||||
void HandleAuctionListPendingSales(WorldPacket & recv_data);
|
||||
|
||||
void HandleGetMailList(WorldPacket & recv_data);
|
||||
void HandleSendMail(WorldPacket & recv_data);
|
||||
void HandleMailTakeMoney(WorldPacket & recv_data);
|
||||
void HandleMailTakeItem(WorldPacket & recv_data);
|
||||
void HandleMailMarkAsRead(WorldPacket & recv_data);
|
||||
void HandleMailReturnToSender(WorldPacket & recv_data);
|
||||
void HandleMailDelete(WorldPacket & recv_data);
|
||||
void HandleItemTextQuery(WorldPacket & recv_data);
|
||||
void HandleMailCreateTextItem(WorldPacket & recv_data);
|
||||
void HandleQueryNextMailTime(WorldPacket & recv_data);
|
||||
void HandleCancelChanneling(WorldPacket & recv_data);
|
||||
|
||||
void SendItemPageInfo(ItemPrototype *itemProto);
|
||||
void HandleSplitItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleSwapInvItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleDestroyItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleAutoEquipItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleItemQuerySingleOpcode(WorldPacket& recvPacket);
|
||||
void HandleSellItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
|
||||
void HandleBuyItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleListInventoryOpcode(WorldPacket& recvPacket);
|
||||
void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleReadItem(WorldPacket& recvPacket);
|
||||
void HandleAutoEquipItemSlotOpcode(WorldPacket & recvPacket);
|
||||
void HandleSwapItem(WorldPacket & recvPacket);
|
||||
void HandleBuybackItem(WorldPacket & recvPacket);
|
||||
void HandleAutoBankItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleWrapItemOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleAttackSwingOpcode(WorldPacket& recvPacket);
|
||||
void HandleAttackStopOpcode(WorldPacket& recvPacket);
|
||||
void HandleSetSheathedOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleUseItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleOpenItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleCastSpellOpcode(WorldPacket& recvPacket);
|
||||
void HandleCancelCastOpcode(WorldPacket& recvPacket);
|
||||
void HandleCancelAuraOpcode(WorldPacket& recvPacket);
|
||||
void HandleCancelGrowthAuraOpcode(WorldPacket& recvPacket);
|
||||
void HandleCancelAutoRepeatSpellOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleLearnTalentOpcode(WorldPacket& recvPacket);
|
||||
void HandleLearnPreviewTalents(WorldPacket& recvPacket);
|
||||
void HandleTalentWipeConfirmOpcode(WorldPacket& recvPacket);
|
||||
void HandleUnlearnSkillOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleQuestgiverStatusQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverStatusMultipleQuery(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverHelloOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverQueryQuestOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverRequestRewardOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleQuestgiverCancel(WorldPacket& recv_data);
|
||||
void HandleQuestLogSwapQuest(WorldPacket& recv_data);
|
||||
void HandleQuestLogRemoveQuest(WorldPacket& recv_data);
|
||||
void HandleQuestConfirmAccept(WorldPacket& recv_data);
|
||||
void HandleQuestgiverCompleteQuest(WorldPacket& recv_data);
|
||||
void HandleQuestgiverQuestAutoLaunch(WorldPacket& recvPacket);
|
||||
void HandlePushQuestToParty(WorldPacket& recvPacket);
|
||||
void HandleQuestPushResult(WorldPacket& recvPacket);
|
||||
|
||||
bool processChatmessageFurtherAfterSecurityChecks(std::string&, uint32);
|
||||
void HandleMessagechatOpcode(WorldPacket& recvPacket);
|
||||
void SendPlayerNotFoundNotice(std::string name);
|
||||
void SendPlayerAmbiguousNotice(std::string name);
|
||||
void SendWrongFactionNotice();
|
||||
void SendChatRestrictedNotice(ChatRestrictionType restriction);
|
||||
void HandleTextEmoteOpcode(WorldPacket& recvPacket);
|
||||
void HandleChatIgnoredOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleReclaimCorpseOpcode(WorldPacket& recvPacket);
|
||||
void HandleCorpseQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleCorpseMapPositionQuery(WorldPacket& recvPacket);
|
||||
void HandleResurrectResponseOpcode(WorldPacket& recvPacket);
|
||||
void HandleSummonResponseOpcode(WorldPacket& recv_data);
|
||||
|
||||
void HandleJoinChannel(WorldPacket& recvPacket);
|
||||
void HandleLeaveChannel(WorldPacket& recvPacket);
|
||||
void HandleChannelList(WorldPacket& recvPacket);
|
||||
void HandleChannelPassword(WorldPacket& recvPacket);
|
||||
void HandleChannelSetOwner(WorldPacket& recvPacket);
|
||||
void HandleChannelOwner(WorldPacket& recvPacket);
|
||||
void HandleChannelModerator(WorldPacket& recvPacket);
|
||||
void HandleChannelUnmoderator(WorldPacket& recvPacket);
|
||||
void HandleChannelMute(WorldPacket& recvPacket);
|
||||
void HandleChannelUnmute(WorldPacket& recvPacket);
|
||||
void HandleChannelInvite(WorldPacket& recvPacket);
|
||||
void HandleChannelKick(WorldPacket& recvPacket);
|
||||
void HandleChannelBan(WorldPacket& recvPacket);
|
||||
void HandleChannelUnban(WorldPacket& recvPacket);
|
||||
void HandleChannelAnnouncements(WorldPacket& recvPacket);
|
||||
void HandleChannelModerate(WorldPacket& recvPacket);
|
||||
void HandleChannelDeclineInvite(WorldPacket& recvPacket);
|
||||
void HandleChannelDisplayListQuery(WorldPacket& recvPacket);
|
||||
void HandleGetChannelMemberCount(WorldPacket& recvPacket);
|
||||
void HandleSetChannelWatch(WorldPacket& recvPacket);
|
||||
|
||||
void HandleCompleteCinematic(WorldPacket& recvPacket);
|
||||
void HandleNextCinematicCamera(WorldPacket& recvPacket);
|
||||
|
||||
void HandlePageQuerySkippedOpcode(WorldPacket& recvPacket);
|
||||
void HandlePageTextQueryOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleTutorialFlag (WorldPacket & recv_data);
|
||||
void HandleTutorialClear(WorldPacket & recv_data);
|
||||
void HandleTutorialReset(WorldPacket & recv_data);
|
||||
|
||||
//Pet
|
||||
void HandlePetAction(WorldPacket & recv_data);
|
||||
void HandlePetActionHelper(Unit *pet, uint64 guid1, uint16 spellid, uint16 flag, uint64 guid2);
|
||||
void HandlePetNameQuery(WorldPacket & recv_data);
|
||||
void HandlePetSetAction(WorldPacket & recv_data);
|
||||
void HandlePetAbandon(WorldPacket & recv_data);
|
||||
void HandlePetRename(WorldPacket & recv_data);
|
||||
void HandlePetCancelAuraOpcode(WorldPacket& recvPacket);
|
||||
void HandlePetUnlearnOpcode(WorldPacket& recvPacket);
|
||||
void HandlePetSpellAutocastOpcode(WorldPacket& recvPacket);
|
||||
void HandlePetCastSpellOpcode(WorldPacket& recvPacket);
|
||||
void HandlePetLearnTalent(WorldPacket& recvPacket);
|
||||
void HandleLearnPreviewTalentsPet(WorldPacket& recvPacket);
|
||||
|
||||
void HandleSetActionBarToggles(WorldPacket& recv_data);
|
||||
|
||||
void HandleCharRenameOpcode(WorldPacket& recv_data);
|
||||
static void HandleChangePlayerNameOpcodeCallBack(QueryResult_AutoPtr result, uint32 accountId, std::string newname);
|
||||
void HandleSetPlayerDeclinedNames(WorldPacket& recv_data);
|
||||
|
||||
void HandleTotemDestroyed(WorldPacket& recv_data);
|
||||
void HandleDismissCritter(WorldPacket& recv_data);
|
||||
|
||||
//BattleGround
|
||||
void HandleBattlemasterHelloOpcode(WorldPacket &recv_data);
|
||||
void HandleBattlemasterJoinOpcode(WorldPacket &recv_data);
|
||||
void HandleBattleGroundPlayerPositionsOpcode(WorldPacket& recv_data);
|
||||
void HandlePVPLogDataOpcode(WorldPacket &recv_data);
|
||||
void HandleBattleFieldPortOpcode(WorldPacket &recv_data);
|
||||
void HandleBattlefieldListOpcode(WorldPacket &recv_data);
|
||||
void HandleLeaveBattlefieldOpcode(WorldPacket &recv_data);
|
||||
void HandleBattlemasterJoinArena(WorldPacket &recv_data);
|
||||
void HandleReportPvPAFK(WorldPacket &recv_data);
|
||||
|
||||
void HandleWardenDataOpcode(WorldPacket& recv_data);
|
||||
void HandleWorldTeleportOpcode(WorldPacket& recv_data);
|
||||
void HandleMinimapPingOpcode(WorldPacket& recv_data);
|
||||
void HandleRandomRollOpcode(WorldPacket& recv_data);
|
||||
void HandleFarSightOpcode(WorldPacket& recv_data);
|
||||
void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data);
|
||||
void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data);
|
||||
void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data);
|
||||
void HandleSetTitleOpcode(WorldPacket& recv_data);
|
||||
void HandleRealmSplitOpcode(WorldPacket& recv_data);
|
||||
void HandleTimeSyncResp(WorldPacket& recv_data);
|
||||
void HandleWhoisOpcode(WorldPacket& recv_data);
|
||||
void HandleResetInstancesOpcode(WorldPacket& recv_data);
|
||||
|
||||
// Looking for Dungeon/Raid
|
||||
void HandleSetLfgCommentOpcode(WorldPacket & recv_data);
|
||||
void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recv_data);
|
||||
void HandleLfgPartyLockInfoRequestOpcode(WorldPacket& recv_data);
|
||||
void HandleLfgJoinOpcode(WorldPacket &recv_data);
|
||||
void HandleLfgLeaveOpcode(WorldPacket & /*recv_data*/);
|
||||
void HandleLfgSetRolesOpcode(WorldPacket &recv_data);
|
||||
void SendLfgUpdatePlayer(uint8 updateType);
|
||||
void SendLfgUpdateParty(uint8 updateType);
|
||||
void SendLfgRoleChosen(uint64 guid, uint8 roles);
|
||||
void SendLfgUpdateSearch(bool update);
|
||||
void SendLfgJoinResult(uint8 checkResult, uint8 checkValue);
|
||||
void SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps);
|
||||
|
||||
// Arena Team
|
||||
void HandleInspectArenaTeamsOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamQueryOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamRosterOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamInviteOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamAcceptOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamDeclineOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamLeaveOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamRemoveOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamDisbandOpcode(WorldPacket& recv_data);
|
||||
void HandleArenaTeamLeaderOpcode(WorldPacket& recv_data);
|
||||
|
||||
void HandleAreaSpiritHealerQueryOpcode(WorldPacket& recv_data);
|
||||
void HandleAreaSpiritHealerQueueOpcode(WorldPacket& recv_data);
|
||||
void HandleCancelMountAuraOpcode(WorldPacket& recv_data);
|
||||
void HandleSelfResOpcode(WorldPacket& recv_data);
|
||||
void HandleComplainOpcode(WorldPacket& recv_data);
|
||||
void HandleRequestPetInfoOpcode(WorldPacket& recv_data);
|
||||
|
||||
// Socket gem
|
||||
void HandleSocketOpcode(WorldPacket& recv_data);
|
||||
|
||||
void HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data);
|
||||
|
||||
void HandleItemRefundInfoRequest(WorldPacket& recv_data);
|
||||
void HandleItemRefund(WorldPacket& recv_data);
|
||||
|
||||
void HandleChannelVoiceOnOpcode(WorldPacket & recv_data);
|
||||
void HandleVoiceSessionEnableOpcode(WorldPacket& recv_data);
|
||||
void HandleSetActiveVoiceChannel(WorldPacket& recv_data);
|
||||
void HandleSetTaxiBenchmarkOpcode(WorldPacket& recv_data);
|
||||
|
||||
// Guild Bank
|
||||
void HandleGuildPermissions(WorldPacket& recv_data);
|
||||
void HandleGuildBankMoneyWithdrawn(WorldPacket& recv_data);
|
||||
void HandleGuildBankerActivate(WorldPacket& recv_data);
|
||||
void HandleGuildBankQueryTab(WorldPacket& recv_data);
|
||||
void HandleGuildBankLogQuery(WorldPacket& recv_data);
|
||||
void HandleGuildBankDepositMoney(WorldPacket& recv_data);
|
||||
void HandleGuildBankWithdrawMoney(WorldPacket& recv_data);
|
||||
void HandleGuildBankSwapItems(WorldPacket& recv_data);
|
||||
|
||||
void HandleGuildBankUpdateTab(WorldPacket& recv_data);
|
||||
void HandleGuildBankBuyTab(WorldPacket& recv_data);
|
||||
void HandleQueryGuildBankTabText(WorldPacket& recv_data);
|
||||
void HandleSetGuildBankTabText(WorldPacket& recv_data);
|
||||
|
||||
// Calendar
|
||||
void HandleCalendarGetCalendar(WorldPacket& recv_data);
|
||||
void HandleCalendarGetEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarGuildFilter(WorldPacket& recv_data);
|
||||
void HandleCalendarArenaTeam(WorldPacket& recv_data);
|
||||
void HandleCalendarAddEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarUpdateEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarRemoveEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarCopyEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarEventInvite(WorldPacket& recv_data);
|
||||
void HandleCalendarEventRsvp(WorldPacket& recv_data);
|
||||
void HandleCalendarEventRemoveInvite(WorldPacket& recv_data);
|
||||
void HandleCalendarEventStatus(WorldPacket& recv_data);
|
||||
void HandleCalendarEventModeratorStatus(WorldPacket& recv_data);
|
||||
void HandleCalendarComplain(WorldPacket& recv_data);
|
||||
void HandleCalendarGetNumPending(WorldPacket& recv_data);
|
||||
|
||||
void HandleSpellClick(WorldPacket& recv_data);
|
||||
void HandleMirrrorImageDataRequest(WorldPacket & recv_data);
|
||||
void HandleAlterAppearance(WorldPacket& recv_data);
|
||||
void HandleRemoveGlyph(WorldPacket& recv_data);
|
||||
void HandleCharCustomize(WorldPacket& recv_data);
|
||||
void HandleQueryInspectAchievements(WorldPacket& recv_data);
|
||||
void HandleEquipmentSetSave(WorldPacket& recv_data);
|
||||
void HandleEquipmentSetDelete(WorldPacket& recv_data);
|
||||
void HandleEquipmentSetUse(WorldPacket& recv_data);
|
||||
void HandleWorldStateUITimerUpdate(WorldPacket& recv_data);
|
||||
void HandleReadyForAccountDataTimes(WorldPacket& recv_data);
|
||||
void HandleQueryQuestsCompleted(WorldPacket& recv_data);
|
||||
void HandleQuestPOIQuery(WorldPacket& recv_data);
|
||||
void HandleOnPVPKill(Player *killed);
|
||||
bool HandleOnPlayerChat(const char *text);
|
||||
uint32 HandleOnGetXP(uint32 amount);
|
||||
int32 HandleOnGetMoney(int32 amount);
|
||||
void HandleOnAreaChange(AreaTableEntry const *pArea);
|
||||
bool HandleOnItemClick(Item *pItem);
|
||||
bool HandleOnItemOpen(Item *pItem);
|
||||
bool HandleOnGoClick(GameObject *pGameObject);
|
||||
void HandleOnCreatureKill(Creature *pCreature);
|
||||
void HandleEjectPasenger(WorldPacket &data);
|
||||
void HandleEnterPlayerVehicle(WorldPacket &data);
|
||||
private:
|
||||
// private trade methods
|
||||
void moveItems(Item* myItems[], Item* hisItems[]);
|
||||
|
||||
// logging helper
|
||||
void LogUnexpectedOpcode(WorldPacket *packet, const char * reason);
|
||||
void LogUnprocessedTail(WorldPacket *packet);
|
||||
|
||||
uint32 m_GUIDLow; // set loggined or recently logout player (while m_playerRecentlyLogout set)
|
||||
Player *_player;
|
||||
WorldSocket *m_Socket;
|
||||
std::string m_Address;
|
||||
|
||||
AccountTypes _security;
|
||||
uint32 _accountId;
|
||||
uint8 m_expansion;
|
||||
|
||||
time_t _logoutTime;
|
||||
bool m_inQueue; // session wait in auth.queue
|
||||
bool m_playerLoading; // code processed in LoginPlayer
|
||||
bool m_playerLogout; // code processed in LogoutPlayer
|
||||
bool m_playerRecentlyLogout;
|
||||
bool m_playerSave;
|
||||
LocaleConstant m_sessionDbcLocale;
|
||||
int m_sessionDbLocaleIndex;
|
||||
uint32 m_latency;
|
||||
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
|
||||
uint32 m_Tutorials[8];
|
||||
bool m_TutorialsChanged;
|
||||
AddonsList m_addonsList;
|
||||
ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
|
||||
};
|
||||
#endif
|
||||
/// @}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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 u2w User to World Communication
|
||||
* @{
|
||||
* \file WorldSocket.h
|
||||
* \author Derex <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef _WORLDSOCKET_H
|
||||
#define _WORLDSOCKET_H
|
||||
|
||||
#include <ace/Basic_Types.h>
|
||||
#include <ace/Synch_Traits.h>
|
||||
#include <ace/Svc_Handler.h>
|
||||
#include <ace/SOCK_Stream.h>
|
||||
#include <ace/SOCK_Acceptor.h>
|
||||
#include <ace/Acceptor.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <ace/Guard_T.h>
|
||||
#include <ace/Unbounded_Queue.h>
|
||||
#include <ace/Message_Block.h>
|
||||
|
||||
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
||||
|
||||
#include "Common.h"
|
||||
#include "Auth/AuthCrypt.h"
|
||||
|
||||
class ACE_Message_Block;
|
||||
class WorldPacket;
|
||||
class WorldSession;
|
||||
|
||||
/// Handler that can communicate over stream sockets.
|
||||
typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> WorldHandler;
|
||||
|
||||
/**
|
||||
* WorldSocket.
|
||||
*
|
||||
* This class is responsible for the communication with
|
||||
* remote clients.
|
||||
* Most methods return -1 on failure.
|
||||
* The class uses reference counting.
|
||||
*
|
||||
* For output the class uses one buffer (64K usually) and
|
||||
* a queue where it stores packet if there is no place on
|
||||
* the queue. The reason this is done, is because the server
|
||||
* does really a lot of small-size writes to it, and it doesn't
|
||||
* scale well to allocate memory for every. When something is
|
||||
* written to the output buffer the socket is not immediately
|
||||
* activated for output (again for the same reason), there
|
||||
* is 10ms celling (thats why there is Update() method).
|
||||
* This concept is similar to TCP_CORK, but TCP_CORK
|
||||
* uses 200ms celling. As result overhead generated by
|
||||
* sending packets from "producer" threads is minimal,
|
||||
* and doing a lot of writes with small size is tolerated.
|
||||
*
|
||||
* The calls to Update() method are managed by WorldSocketMgr
|
||||
* and ReactorRunnable.
|
||||
*
|
||||
* For input ,the class uses one 1024 bytes buffer on stack
|
||||
* to which it does recv() calls. And then received data is
|
||||
* distributed where its needed. 1024 matches pretty well the
|
||||
* traffic generated by client for now.
|
||||
*
|
||||
* The input/output do speculative reads/writes (AKA it tryes
|
||||
* to read all data available in the kernel buffer or tryes to
|
||||
* write everything available in userspace buffer),
|
||||
* which is ok for using with Level and Edge Triggered IO
|
||||
* notification.
|
||||
*
|
||||
*/
|
||||
class WorldSocket : protected WorldHandler
|
||||
{
|
||||
public:
|
||||
/// Declare some friends
|
||||
friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >;
|
||||
friend class WorldSocketMgr;
|
||||
friend class ReactorRunnable;
|
||||
|
||||
/// Declare the acceptor for this class
|
||||
typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor;
|
||||
|
||||
/// Mutex type used for various synchronizations.
|
||||
typedef ACE_Thread_Mutex LockType;
|
||||
typedef ACE_Guard<LockType> GuardType;
|
||||
|
||||
/// Check if socket is closed.
|
||||
bool IsClosed (void) const;
|
||||
|
||||
/// Close the socket.
|
||||
void CloseSocket (void);
|
||||
|
||||
/// Get address of connected peer.
|
||||
const std::string& GetRemoteAddress (void) const;
|
||||
|
||||
/// Send A packet on the socket, this function is reentrant.
|
||||
/// @param pct packet to send
|
||||
/// @return -1 of failure
|
||||
int SendPacket (const WorldPacket& pct);
|
||||
|
||||
/// Add reference to this object.
|
||||
long AddReference (void);
|
||||
|
||||
/// Remove reference to this object.
|
||||
long RemoveReference (void);
|
||||
|
||||
protected:
|
||||
/// things called by ACE framework.
|
||||
WorldSocket (void);
|
||||
virtual ~WorldSocket (void);
|
||||
|
||||
/// Called on open ,the void* is the acceptor.
|
||||
virtual int open (void *);
|
||||
|
||||
/// Called on failures inside of the acceptor, don't call from your code.
|
||||
virtual int close (int);
|
||||
|
||||
/// Called when we can read from the socket.
|
||||
virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE);
|
||||
|
||||
/// Called when the socket can write.
|
||||
virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE);
|
||||
|
||||
/// Called when connection is closed or error happens.
|
||||
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
|
||||
ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
|
||||
|
||||
/// Called by WorldSocketMgr/ReactorRunnable.
|
||||
int Update (void);
|
||||
|
||||
private:
|
||||
/// Helper functions for processing incoming data.
|
||||
int handle_input_header (void);
|
||||
int handle_input_payload (void);
|
||||
int handle_input_missing_data (void);
|
||||
|
||||
/// Help functions to mark/unmark the socket for output.
|
||||
/// @param g the guard is for m_OutBufferLock, the function will release it
|
||||
int cancel_wakeup_output (GuardType& g);
|
||||
int schedule_wakeup_output (GuardType& g);
|
||||
|
||||
/// Drain the queue if its not empty.
|
||||
int handle_output_queue (GuardType& g);
|
||||
|
||||
/// process one incoming packet.
|
||||
/// @param new_pct received packet ,note that you need to delete it.
|
||||
int ProcessIncoming (WorldPacket* new_pct);
|
||||
|
||||
/// Called by ProcessIncoming() on CMSG_AUTH_SESSION.
|
||||
int HandleAuthSession (WorldPacket& recvPacket);
|
||||
|
||||
/// Called by ProcessIncoming() on CMSG_PING.
|
||||
int HandlePing (WorldPacket& recvPacket);
|
||||
|
||||
private:
|
||||
/// Time in which the last ping was received
|
||||
ACE_Time_Value m_LastPingTime;
|
||||
|
||||
/// Keep track of over-speed pings ,to prevent ping flood.
|
||||
uint32 m_OverSpeedPings;
|
||||
|
||||
/// Address of the remote peer
|
||||
std::string m_Address;
|
||||
|
||||
/// Class used for managing encryption of the headers
|
||||
AuthCrypt m_Crypt;
|
||||
|
||||
/// Mutex lock to protect m_Session
|
||||
LockType m_SessionLock;
|
||||
|
||||
/// Session to which received packets are routed
|
||||
WorldSession* m_Session;
|
||||
|
||||
/// here are stored the fragments of the received data
|
||||
WorldPacket* m_RecvWPct;
|
||||
|
||||
/// This block actually refers to m_RecvWPct contents,
|
||||
/// which allows easy and safe writing to it.
|
||||
/// It wont free memory when its deleted. m_RecvWPct takes care of freeing.
|
||||
ACE_Message_Block m_RecvPct;
|
||||
|
||||
/// Fragment of the received header.
|
||||
ACE_Message_Block m_Header;
|
||||
|
||||
/// Mutex for protecting output related data.
|
||||
LockType m_OutBufferLock;
|
||||
|
||||
/// Buffer used for writing output.
|
||||
ACE_Message_Block *m_OutBuffer;
|
||||
|
||||
/// Size of the m_OutBuffer.
|
||||
size_t m_OutBufferSize;
|
||||
|
||||
/// True if the socket is registered with the reactor for output
|
||||
bool m_OutActive;
|
||||
|
||||
uint32 m_Seed;
|
||||
|
||||
};
|
||||
|
||||
#endif /* _WORLDSOCKET_H */
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008,2007 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 WorldSocketMgr.cpp
|
||||
* \ingroup u2w
|
||||
* \author Derex <[email protected]>
|
||||
*/
|
||||
|
||||
#include "WorldSocketMgr.h"
|
||||
|
||||
#include <ace/ACE.h>
|
||||
#include <ace/Log_Msg.h>
|
||||
#include <ace/Reactor.h>
|
||||
#include <ace/Reactor_Impl.h>
|
||||
#include <ace/TP_Reactor.h>
|
||||
#include <ace/Dev_Poll_Reactor.h>
|
||||
#include <ace/Guard_T.h>
|
||||
#include <ace/Atomic_Op.h>
|
||||
#include <ace/os_include/arpa/os_inet.h>
|
||||
#include <ace/os_include/netinet/os_tcp.h>
|
||||
#include <ace/os_include/sys/os_types.h>
|
||||
#include <ace/os_include/sys/os_socket.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "Log.h"
|
||||
#include "Common.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "WorldSocket.h"
|
||||
|
||||
/**
|
||||
* This is a helper class to WorldSocketMgr ,that manages
|
||||
* network threads, and assigning connections from acceptor thread
|
||||
* to other network threads
|
||||
*/
|
||||
class ReactorRunnable : protected ACE_Task_Base
|
||||
{
|
||||
public:
|
||||
|
||||
ReactorRunnable() :
|
||||
m_ThreadId(-1),
|
||||
m_Connections(0),
|
||||
m_Reactor(0)
|
||||
{
|
||||
ACE_Reactor_Impl* imp = 0;
|
||||
|
||||
#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
|
||||
|
||||
imp = new ACE_Dev_Poll_Reactor();
|
||||
|
||||
imp->max_notify_iterations (128);
|
||||
imp->restart (1);
|
||||
|
||||
#else
|
||||
|
||||
imp = new ACE_TP_Reactor();
|
||||
imp->max_notify_iterations (128);
|
||||
|
||||
#endif
|
||||
|
||||
m_Reactor = new ACE_Reactor (imp, 1);
|
||||
}
|
||||
|
||||
virtual ~ReactorRunnable()
|
||||
{
|
||||
Stop();
|
||||
Wait();
|
||||
|
||||
if (m_Reactor)
|
||||
delete m_Reactor;
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_Reactor->end_reactor_event_loop();
|
||||
}
|
||||
|
||||
int Start()
|
||||
{
|
||||
if (m_ThreadId != -1)
|
||||
return -1;
|
||||
|
||||
return (m_ThreadId = activate());
|
||||
}
|
||||
|
||||
void Wait() { ACE_Task_Base::wait(); }
|
||||
|
||||
long Connections()
|
||||
{
|
||||
return static_cast<long> (m_Connections.value());
|
||||
}
|
||||
|
||||
int AddSocket (WorldSocket* sock)
|
||||
{
|
||||
ACE_GUARD_RETURN (ACE_Thread_Mutex, Guard, m_NewSockets_Lock, -1);
|
||||
|
||||
++m_Connections;
|
||||
sock->AddReference();
|
||||
sock->reactor (m_Reactor);
|
||||
m_NewSockets.insert (sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACE_Reactor* GetReactor()
|
||||
{
|
||||
return m_Reactor;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void AddNewSockets()
|
||||
{
|
||||
ACE_GUARD (ACE_Thread_Mutex, Guard, m_NewSockets_Lock);
|
||||
|
||||
if (m_NewSockets.empty())
|
||||
return;
|
||||
|
||||
for (SocketSet::const_iterator i = m_NewSockets.begin(); i != m_NewSockets.end(); ++i)
|
||||
{
|
||||
WorldSocket* sock = (*i);
|
||||
|
||||
if (sock->IsClosed())
|
||||
{
|
||||
sock->RemoveReference();
|
||||
--m_Connections;
|
||||
}
|
||||
else
|
||||
m_Sockets.insert (sock);
|
||||
}
|
||||
|
||||
m_NewSockets.clear();
|
||||
}
|
||||
|
||||
virtual int svc()
|
||||
{
|
||||
DEBUG_LOG ("Network Thread Starting");
|
||||
|
||||
WorldDatabase.ThreadStart();
|
||||
|
||||
ACE_ASSERT (m_Reactor);
|
||||
|
||||
SocketSet::iterator i, t;
|
||||
|
||||
while (!m_Reactor->reactor_event_loop_done())
|
||||
{
|
||||
// dont be too smart to move this outside the loop
|
||||
// the run_reactor_event_loop will modify interval
|
||||
ACE_Time_Value interval (0, 10000);
|
||||
|
||||
if (m_Reactor->run_reactor_event_loop (interval) == -1)
|
||||
break;
|
||||
|
||||
AddNewSockets();
|
||||
|
||||
for (i = m_Sockets.begin(); i != m_Sockets.end();)
|
||||
{
|
||||
if ((*i)->Update() == -1)
|
||||
{
|
||||
t = i;
|
||||
++i;
|
||||
(*t)->CloseSocket();
|
||||
(*t)->RemoveReference();
|
||||
--m_Connections;
|
||||
m_Sockets.erase (t);
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
WorldDatabase.ThreadEnd();
|
||||
|
||||
DEBUG_LOG ("Network Thread Exitting");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> AtomicInt;
|
||||
typedef std::set<WorldSocket*> SocketSet;
|
||||
|
||||
ACE_Reactor* m_Reactor;
|
||||
AtomicInt m_Connections;
|
||||
int m_ThreadId;
|
||||
|
||||
SocketSet m_Sockets;
|
||||
|
||||
SocketSet m_NewSockets;
|
||||
ACE_Thread_Mutex m_NewSockets_Lock;
|
||||
};
|
||||
|
||||
WorldSocketMgr::WorldSocketMgr() :
|
||||
m_NetThreadsCount(0),
|
||||
m_NetThreads(0),
|
||||
m_SockOutKBuff(-1),
|
||||
m_SockOutUBuff(65536),
|
||||
m_UseNoDelay(true),
|
||||
m_Acceptor (0)
|
||||
{
|
||||
}
|
||||
|
||||
WorldSocketMgr::~WorldSocketMgr()
|
||||
{
|
||||
if (m_NetThreads)
|
||||
delete [] m_NetThreads;
|
||||
|
||||
if (m_Acceptor)
|
||||
delete m_Acceptor;
|
||||
}
|
||||
|
||||
int
|
||||
WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)
|
||||
{
|
||||
m_UseNoDelay = sConfig.GetBoolDefault ("Network.TcpNodelay", true);
|
||||
|
||||
int num_threads = sConfig.GetIntDefault ("Network.Threads", 1);
|
||||
|
||||
if (num_threads <= 0)
|
||||
{
|
||||
sLog.outError ("Network.Threads is wrong in your config file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_NetThreadsCount = static_cast<size_t> (num_threads + 1);
|
||||
|
||||
m_NetThreads = new ReactorRunnable[m_NetThreadsCount];
|
||||
|
||||
sLog.outBasic ("Max allowed socket connections %d", ACE::max_handles());
|
||||
|
||||
// -1 means use default
|
||||
m_SockOutKBuff = sConfig.GetIntDefault ("Network.OutKBuff", -1);
|
||||
|
||||
m_SockOutUBuff = sConfig.GetIntDefault ("Network.OutUBuff", 65536);
|
||||
|
||||
if (m_SockOutUBuff <= 0)
|
||||
{
|
||||
sLog.outError ("Network.OutUBuff is wrong in your config file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
WorldSocket::Acceptor *acc = new WorldSocket::Acceptor;
|
||||
m_Acceptor = acc;
|
||||
|
||||
ACE_INET_Addr listen_addr (port, address);
|
||||
|
||||
if (acc->open(listen_addr, m_NetThreads[0].GetReactor(), ACE_NONBLOCK) == -1)
|
||||
{
|
||||
sLog.outError ("Failed to open acceptor ,check if the port is free");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_NetThreadsCount; ++i)
|
||||
m_NetThreads[i].Start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
WorldSocketMgr::StartNetwork (ACE_UINT16 port, const char* address)
|
||||
{
|
||||
if (!sLog.IsOutDebug())
|
||||
ACE_Log_Msg::instance()->priority_mask (LM_ERROR, ACE_Log_Msg::PROCESS);
|
||||
|
||||
if (StartReactiveIO(port, address) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WorldSocketMgr::StopNetwork()
|
||||
{
|
||||
if (m_Acceptor)
|
||||
{
|
||||
WorldSocket::Acceptor* acc = dynamic_cast<WorldSocket::Acceptor*> (m_Acceptor);
|
||||
|
||||
if (acc)
|
||||
acc->close();
|
||||
}
|
||||
|
||||
if (m_NetThreadsCount != 0)
|
||||
{
|
||||
for (size_t i = 0; i < m_NetThreadsCount; ++i)
|
||||
m_NetThreads[i].Stop();
|
||||
}
|
||||
|
||||
Wait();
|
||||
}
|
||||
|
||||
void
|
||||
WorldSocketMgr::Wait()
|
||||
{
|
||||
if (m_NetThreadsCount != 0)
|
||||
{
|
||||
for (size_t i = 0; i < m_NetThreadsCount; ++i)
|
||||
m_NetThreads[i].Wait();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WorldSocketMgr::OnSocketOpen (WorldSocket* sock)
|
||||
{
|
||||
// set some options here
|
||||
if (m_SockOutKBuff >= 0)
|
||||
{
|
||||
if (sock->peer().set_option (SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
(void*) & m_SockOutKBuff,
|
||||
sizeof (int)) == -1 && errno != ENOTSUP)
|
||||
{
|
||||
sLog.outError ("WorldSocketMgr::OnSocketOpen set_option SO_SNDBUF");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static const int ndoption = 1;
|
||||
|
||||
// Set TCP_NODELAY.
|
||||
if (m_UseNoDelay)
|
||||
{
|
||||
if (sock->peer().set_option (ACE_IPPROTO_TCP,
|
||||
TCP_NODELAY,
|
||||
(void*)&ndoption,
|
||||
sizeof (int)) == -1)
|
||||
{
|
||||
sLog.outError ("WorldSocketMgr::OnSocketOpen: peer().set_option TCP_NODELAY errno = %s", ACE_OS::strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sock->m_OutBufferSize = static_cast<size_t> (m_SockOutUBuff);
|
||||
|
||||
// we skip the Acceptor Thread
|
||||
size_t min = 1;
|
||||
|
||||
ACE_ASSERT (m_NetThreadsCount >= 1);
|
||||
|
||||
for (size_t i = 1; i < m_NetThreadsCount; ++i)
|
||||
if (m_NetThreads[i].Connections() < m_NetThreads[min].Connections())
|
||||
min = i;
|
||||
|
||||
return m_NetThreads[min].AddSocket (sock);
|
||||
}
|
||||
|
||||
WorldSocketMgr*
|
||||
WorldSocketMgr::Instance()
|
||||
{
|
||||
return ACE_Singleton<WorldSocketMgr,ACE_Thread_Mutex>::instance();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 u2w User to World Communication
|
||||
* @{
|
||||
* \file WorldSocketMgr.h
|
||||
* \author Derex <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef __WORLDSOCKETMGR_H
|
||||
#define __WORLDSOCKETMGR_H
|
||||
|
||||
#include <ace/Basic_Types.h>
|
||||
#include <ace/Singleton.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
|
||||
class WorldSocket;
|
||||
class ReactorRunnable;
|
||||
class ACE_Event_Handler;
|
||||
|
||||
/// Manages all sockets connected to peers and network threads
|
||||
class WorldSocketMgr
|
||||
{
|
||||
public:
|
||||
friend class WorldSocket;
|
||||
friend class ACE_Singleton<WorldSocketMgr,ACE_Thread_Mutex>;
|
||||
|
||||
/// Start network, listen at address:port .
|
||||
int StartNetwork (ACE_UINT16 port, const char* address);
|
||||
|
||||
/// Stops all network threads, It will wait for all running threads .
|
||||
void StopNetwork();
|
||||
|
||||
/// Wait untill all network threads have "joined" .
|
||||
void Wait();
|
||||
|
||||
/// Make this class singleton .
|
||||
static WorldSocketMgr* Instance();
|
||||
|
||||
private:
|
||||
int OnSocketOpen(WorldSocket* sock);
|
||||
|
||||
int StartReactiveIO(ACE_UINT16 port, const char* address);
|
||||
|
||||
private:
|
||||
WorldSocketMgr();
|
||||
virtual ~WorldSocketMgr();
|
||||
|
||||
ReactorRunnable* m_NetThreads;
|
||||
size_t m_NetThreadsCount;
|
||||
|
||||
int m_SockOutKBuff;
|
||||
int m_SockOutUBuff;
|
||||
bool m_UseNoDelay;
|
||||
|
||||
ACE_Event_Handler* m_Acceptor;
|
||||
};
|
||||
|
||||
#define sWorldSocketMgr WorldSocketMgr::Instance()
|
||||
|
||||
#endif
|
||||
/// @}
|
||||
|
||||
Reference in New Issue
Block a user