[svn] *Implement new player conditions CONDITION_NO_AURA, CONDITION_ACTIVE_EVENT

* Default behaviour of pets for creatures changed to REACT_DEFENSIVE
* Disallowed sending wrapped items as COD
* Prevent loading and saving single target auras for pet in same way as already implemented for player
* Correctly limit use some flask types to zones.
* Fixed extracting common.MPQ under *nix
* Many small xleanups and fixes.
** mangos merge rev.

TEST REV so be careful of creepy crawly bugs!

--HG--
branch : trunk
This commit is contained in:
KingPin
2008-11-02 16:53:46 -06:00
parent 6633d3c680
commit d5beb2bbe9
30 changed files with 414 additions and 342 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) {
memset(mpq_a->header, 0, sizeof(mpq_header));
/* Check if file exists and is readable */
fd = _open((char *)mpq_filename, O_RDONLY | O_BINARY);
fd = _open((char *)mpq_filename, O_RDONLY | O_BINARY | O_LARGEFILE);
if (fd == LIBMPQ_EFILE) {
return LIBMPQ_EFILE;
}
+6
View File
@@ -1838,6 +1838,12 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
//*********************************
//*** Functions used internally ***
//Trinity_DLL_EXPORT
//char const* ScriptsVersion()
//{
// return "Default Trinity scripting library";
//}
Script* GetScriptByName(std::string Name)
{
if (Name.empty())
+2 -2
View File
@@ -77,9 +77,9 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target = NULL);
#ifdef WIN32
#define TRINITY_DLL_EXPORT extern "C" __declspec(dllexport)
#elif defined( __GNUC__ )
#define TRINITY_DLL_EXPORT extern "C"
#define TRINITY_DLL_EXPORT extern "C"
#else
#define TRINITY_DLL_EXPORT extern "C" export
#define TRINITY_DLL_EXPORT extern "C" export
#endif
#endif
+1 -1
View File
@@ -379,7 +379,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
data << (uint8)CHAR_CREATE_SUCCESS;
SendPacket( &data );
std::string IP_str = GetRemoteAddress().c_str();
std::string IP_str = GetRemoteAddress();
sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str());
sLog.outChar("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str());
}
+1 -1
View File
@@ -69,7 +69,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", NULL },
{ "idlerestart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleRestartCommand, "", NULL },
{ "idleshutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleShutDownCommand, "", NULL },
{ "info", SEC_PLAYER, true, &ChatHandler::HandleInfoCommand, "", NULL },
{ "info", SEC_PLAYER, true, &ChatHandler::HandleServerInfoCommand, "", NULL },
{ "motd", SEC_PLAYER, true, &ChatHandler::HandleServerMotdCommand, "", NULL },
{ "restart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleRestartCommand, "", NULL },
{ "shutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleShutDownCommand, "", NULL },
+1 -1
View File
@@ -99,7 +99,6 @@ class ChatHandler
bool HandleHelpCommand(const char* args);
bool HandleCommandsCommand(const char* args);
bool HandleStartCommand(const char* args);
bool HandleInfoCommand(const char* args);
bool HandleDismountCommand(const char* args);
bool HandleSaveCommand(const char* args);
bool HandleGMListIngameCommand(const char* args);
@@ -229,6 +228,7 @@ class ChatHandler
bool HandleServerCorpsesCommand(const char* args);
bool HandleServerExitCommand(const char* args);
bool HandleServerInfoCommand(const char* args);
bool HandleServerMotdCommand(const char* args);
bool HandleServerSetMotdCommand(const char* args);
bool HandleServerSetLogLevelCommand(const char* args);
+3 -1
View File
@@ -82,7 +82,9 @@ enum TrinityStrings
LANG_NEW_PASSWORDS_NOT_MATCH = 54,
LANG_PASSWORD_TOO_LONG = 55,
LANG_MOTD_CURRENT = 56,
// Room for more level 0 57-99 not used
LANG_USING_WORLD_DB = 57,
LANG_USING_SCRIPT_LIB = 58,
// Room for more level 0 59-99 not used
// level 1 chat
LANG_GLOBAL_NOTIFY = 100,
+10 -2
View File
@@ -86,7 +86,7 @@ bool ChatHandler::HandleStartCommand(const char* /*args*/)
return true;
}
bool ChatHandler::HandleInfoCommand(const char* /*args*/)
bool ChatHandler::HandleServerInfoCommand(const char* /*args*/)
{
uint32 activeClientsNum = sWorld.GetActiveSessionCount();
uint32 queuedClientsNum = sWorld.GetQueuedSessionCount();
@@ -94,7 +94,15 @@ bool ChatHandler::HandleInfoCommand(const char* /*args*/)
uint32 maxQueuedClientsNum = sWorld.GetMaxQueuedSessionCount();
std::string str = secsToTimeString(sWorld.GetUptime());
PSendSysMessage(_FULLVERSION);
PSendSysMessage(_FULLVERSION); //char const* full;
//if(m_session)
// full = _FULLVERSION(REVISION_DATE,REVISION_TIME,"|cffffffff|Hurl:" REVISION_ID "|h" REVISION_ID "|h|r");
//else
// full = _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_ID);
//SendSysMessage(full);
//PSendSysMessage(LANG_USING_SCRIPT_LIB,sWorld.GetScriptsVersion());
//PSendSysMessage(LANG_USING_WORLD_DB,sWorld.GetDBVersion());
PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
PSendSysMessage(LANG_UPTIME, str.c_str());
+3 -6
View File
@@ -1954,7 +1954,7 @@ bool ChatHandler::HandleTicketCommand(const char* args)
int num = atoi(px);
if(num > 0)
{
QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC LIMIT %d,1",num-1);
QueryResult *result = CharacterDatabase.PQuery("SELECT guid,ticket_text,ticket_lastchange FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_, num-1);
if(!result)
{
@@ -2066,9 +2066,9 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
// delticket #num
if(num > 0)
{
QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket LIMIT %i",num);
QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
if(!result || uint64(num) > result->GetRowCount())
if(!result)
{
PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
delete result;
@@ -2076,9 +2076,6 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
return false;
}
for(int i = 1; i < num; ++i)
result->NextRow();
Field* fields = result->Fetch();
uint32 id = fields[0].GetUInt32();
+1 -1
View File
@@ -5542,7 +5542,7 @@ bool ChatHandler::HandleLoadPDumpCommand(const char *args)
SetSentErrorMessage(true);
return false;
case DUMP_TOO_MANY_CHARS:
PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name,account_id);
PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL,account_name.c_str(),account_id);
SetSentErrorMessage(true);
return false;
default:
+7
View File
@@ -187,11 +187,18 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
return;
}
if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION))
{
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
return;
}
if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
{
pl->SendMailResult(0, 0, MAIL_ERR_CANT_SEND_WRAPPED_COD);
return;
}
}
}
pl->SendMailResult(0, 0, MAIL_OK);
+8 -9
View File
@@ -579,15 +579,6 @@ void Map::Update(const uint32 &t_diff)
}
}
void InstanceMap::Update(const uint32& t_diff)
{
Map::Update(t_diff);
if(i_data)
i_data->Update(t_diff);
}
void Map::Remove(Player *player, bool remove)
{
CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
@@ -1557,6 +1548,14 @@ bool InstanceMap::Add(Player *player)
return true;
}
void InstanceMap::Update(const uint32& t_diff)
{
Map::Update(t_diff);
if(i_data)
i_data->Update(t_diff);
}
void InstanceMap::Remove(Player *player, bool remove)
{
sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName());
+28
View File
@@ -6569,6 +6569,10 @@ bool PlayerCondition::Meets(Player const * player) const
return true;
return false;
}
case CONDITION_NO_AURA:
return !player->HasAura(value1, value2);
case CONDITION_ACTIVE_EVENT:
return gameeventmgr.IsActiveEvent(value1);
default:
return false;
}
@@ -6689,6 +6693,30 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val
sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2);
break;
}
case CONDITION_NO_AURA:
{
if(!sSpellStore.LookupEntry(value1))
{
sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1);
return false;
}
if(value2 > 2)
{
sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2);
return false;
}
break;
}
case CONDITION_ACTIVE_EVENT:
{
GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap();
if(value1 >=events.size() || !events[value1].isValid())
{
sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1);
return false;
}
break;
}
}
return true;
}
+4 -1
View File
@@ -205,9 +205,11 @@ enum ConditionType
CONDITION_QUESTREWARDED = 8, // quest_id 0
CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active.
CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD ñommission aura active
CONDITION_NO_AURA = 11, // spell_id effindex
CONDITION_ACTIVE_EVENT = 12, // event_id
};
#define MAX_CONDITION 11 // maximum value in ConditionType enum
#define MAX_CONDITION 13 // maximum value in ConditionType enum
//Player's info
typedef struct _tagCachePlayerInfo
@@ -770,6 +772,7 @@ class ObjectMgr
void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true);
bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true);
bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
protected:
uint32 m_auctionid;
uint32 m_mailid;
+17 -4
View File
@@ -1366,6 +1366,10 @@ void Pet::_LoadAuras(uint32 timediff)
else
remaincharges = -1;
/// do not load single target auras (unless they were cast by the player)
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
continue;
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
if(!damage)
@@ -1395,10 +1399,19 @@ void Pet::_SaveAuras()
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET )
break;
if (i == 3 && !itr->second->IsPassive())
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d')",
m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(),(*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges));
if (i != 3)
continue;
if(itr->second->IsPassive())
continue;
/// do not save single target auras (unless they were cast by the player)
if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))
continue;
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d')",
m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(),(*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges));
}
}
+8 -17
View File
@@ -3257,6 +3257,8 @@ void Player::InitVisibleBits()
{
updateVisualBits.SetCount(PLAYER_END);
// TODO: really implement OWNER_ONLY and GROUP_ONLY. Flags can be found in UpdateFields.h
updateVisualBits.SetBit(OBJECT_FIELD_GUID);
updateVisualBits.SetBit(OBJECT_FIELD_TYPE);
updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X);
@@ -3268,6 +3270,7 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1);
updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY);
updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY+1);
updateVisualBits.SetBit(UNIT_FIELD_TARGET);
updateVisualBits.SetBit(UNIT_FIELD_TARGET+1);
@@ -3299,12 +3302,10 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(UNIT_FIELD_AURASTATE);
updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME);
updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1);
updateVisualBits.SetBit(UNIT_FIELD_RANGEDATTACKTIME);
updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS);
updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH);
updateVisualBits.SetBit(UNIT_FIELD_DISPLAYID);
updateVisualBits.SetBit(UNIT_FIELD_NATIVEDISPLAYID);
updateVisualBits.SetBit(UNIT_FIELD_MOUNTDISPLAYID);
updateVisualBits.SetBit(UNIT_FIELD_BYTES_1);
updateVisualBits.SetBit(UNIT_FIELD_MOUNTDISPLAYID);
updateVisualBits.SetBit(UNIT_FIELD_PETNUMBER);
@@ -3314,16 +3315,16 @@ void Player::InitVisibleBits()
updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED);
updateVisualBits.SetBit(UNIT_FIELD_BYTES_2);
updateVisualBits.SetBit(PLAYER_DUEL_ARBITER);
updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1);
updateVisualBits.SetBit(PLAYER_FLAGS);
updateVisualBits.SetBit(PLAYER_GUILDID);
updateVisualBits.SetBit(PLAYER_GUILDRANK);
updateVisualBits.SetBit(PLAYER_BYTES);
updateVisualBits.SetBit(PLAYER_BYTES_2);
updateVisualBits.SetBit(PLAYER_BYTES_3);
updateVisualBits.SetBit(PLAYER_GUILDID);
updateVisualBits.SetBit(PLAYER_GUILDRANK);
updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
updateVisualBits.SetBit(PLAYER_DUEL_TEAM);
updateVisualBits.SetBit(PLAYER_DUEL_ARBITER);
updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1);
updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
// PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4)
@@ -3352,16 +3353,6 @@ void Player::InitVisibleBits()
}
updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 1);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 2);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 3);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 4);
updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_INFO + 5);
}
void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const
+4
View File
@@ -24,6 +24,7 @@
#include "Platform/Define.h"
#include "ScriptCalls.h"
#include "World.h"
ScriptsSet Script=NULL;
@@ -57,6 +58,7 @@ bool LoadScriptingModule(char const* libName)
if( !(testScript->ScriptsInit =(scriptCallScriptsInit )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsInit" ))
||!(testScript->ScriptsFree =(scriptCallScriptsFree )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsFree" ))
||!(testScript->ScriptsVersion =(scriptCallScriptsVersion )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsVersion" ))
||!(testScript->GossipHello =(scriptCallGossipHello )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"GossipHello" ))
||!(testScript->GOChooseReward =(scriptCallGOChooseReward )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"GOChooseReward" ))
||!(testScript->QuestAccept =(scriptCallQuestAccept )TRINITY_GET_PROC_ADDR(testScript->hScriptsLib,"QuestAccept" ))
@@ -93,5 +95,7 @@ bool LoadScriptingModule(char const* libName)
Script=testScript;
Script->ScriptsInit();
sWorld.SetScriptsVersion(Script->ScriptsVersion());
return true;
}
+2
View File
@@ -39,6 +39,7 @@ void UnloadScriptingModule();
typedef void(TRINITY_IMPORT * scriptCallScriptsInit) ();
typedef void(TRINITY_IMPORT * scriptCallScriptsFree) ();
typedef char const* (TRINITY_IMPORT * scriptCallScriptsVersion) ();
typedef bool(TRINITY_IMPORT * scriptCallGossipHello) (Player *player, Creature *_Creature );
typedef bool(TRINITY_IMPORT * scriptCallQuestAccept) (Player *player, Creature *_Creature, Quest const *);
@@ -64,6 +65,7 @@ typedef struct
{
scriptCallScriptsInit ScriptsInit;
scriptCallScriptsFree ScriptsFree;
scriptCallScriptsVersion ScriptsVersion;
scriptCallGossipHello GossipHello;
scriptCallGOChooseReward GOChooseReward;
+5 -5
View File
@@ -4073,12 +4073,12 @@ void Spell::EffectSummonPet(uint32 i)
NewSummon->setPetType(SUMMON_PET);
uint32 faction = m_caster->getFaction();
if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isTotem())
if(m_caster->GetTypeId() == TYPEID_UNIT)
{
Unit* owner = ((Totem*)m_caster)->GetOwner();
if(owner)
faction = owner->getFaction();
NewSummon->GetCharmInfo()->SetReactState(REACT_AGGRESSIVE);
if ( ((Creature*)m_caster)->isTotem() )
NewSummon->GetCharmInfo()->SetReactState(REACT_AGGRESSIVE);
else
NewSummon->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
}
NewSummon->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
+1 -1
View File
@@ -2192,7 +2192,7 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
// in the Blade's Edge Mountains Plateaus and Gruul's Lair.
return zone_id ==3522 || map_id==565;
}
if(mask & ELIXIR_UNSTABLE_MASK)
if(mask & ELIXIR_SHATTRATH_MASK)
{
// in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple
// TODO: and the Sunwell Plateau
+4 -4
View File
@@ -6484,21 +6484,21 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint
{
case 836: // Improved Blizzard (Rank 1)
{
if( !procSpell || procSpell->SpellVisual!=9487 )
if( !procSpell || procSpell->SpellVisual!=9487)
return false;
triggered_spell_id = 12484;
break;
}
case 988: // Improved Blizzard (Rank 2)
{
if( !procSpell || procSpell->SpellVisual!=9487 )
if( !procSpell || procSpell->SpellVisual!=9487)
return false;
triggered_spell_id = 12485;
break;
}
case 989: // Improved Blizzard (Rank 3)
{
if( !procSpell || procSpell->SpellVisual!=9487 )
if( !procSpell || procSpell->SpellVisual!=9487)
return false;
triggered_spell_id = 12486;
break;
@@ -9870,7 +9870,7 @@ CharmInfo* Unit::InitCharmInfo(Unit *charm)
}
CharmInfo::CharmInfo(Unit* unit)
: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_ReactSate(REACT_PASSIVE), m_petnumber(0)
: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_reactState(REACT_PASSIVE), m_petnumber(0)
{
for(int i =0; i<4; ++i)
{
+4 -4
View File
@@ -646,9 +646,9 @@ struct CharmInfo
void SetCommandState(CommandStates st) { m_CommandState = st; }
CommandStates GetCommandState() { return m_CommandState; }
bool HasCommandState(CommandStates state) { return (m_CommandState == state); }
void SetReactState(ReactStates st) { m_ReactSate = st; }
ReactStates GetReactState() { return m_ReactSate; }
bool HasReactState(ReactStates state) { return (m_ReactSate == state); }
void SetReactState(ReactStates st) { m_reactState = st; }
ReactStates GetReactState() { return m_reactState; }
bool HasReactState(ReactStates state) { return (m_reactState == state); }
void InitPossessCreateSpells();
void InitCharmCreateSpells();
@@ -665,7 +665,7 @@ struct CharmInfo
UnitActionBarEntry PetActionBar[10];
CharmSpellEntry m_charmspells[4];
CommandStates m_CommandState;
ReactStates m_ReactSate;
ReactStates m_reactState;
uint32 m_petnumber;
};
+14
View File
@@ -2612,3 +2612,17 @@ void World::UpdateMaxSessionCounters()
m_maxActiveSessionCount = std::max(m_maxActiveSessionCount,uint32(m_sessions.size()-m_QueuedPlayer.size()));
m_maxQueuedSessionCount = std::max(m_maxQueuedSessionCount,uint32(m_QueuedPlayer.size()));
}
void World::LoadDBVersion()
{
QueryResult* result = WorldDatabase.Query("SELECT version FROM db_version LIMIT 1");
if(result)
{
Field* fields = result->Fetch();
m_DBVersion = fields[0].GetString();
delete result;
}
else
m_DBVersion = "unknown world database";
}
+13
View File
@@ -480,6 +480,15 @@ class World
void UpdateRealmCharCount(uint32 accid);
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(); }
//used Script version
void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; }
char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); }
protected:
void _UpdateGameTime();
void ScriptsProcess();
@@ -540,6 +549,10 @@ class World
//sessions that are added async
void AddSession_(WorldSession* s);
ZThread::LockedQueue<WorldSession*, ZThread::FastMutex> addSessQueue;
//used versions
std::string m_DBVersion;
std::string m_ScriptsVersion;
};
extern uint32 realmID;
+17 -18
View File
@@ -51,10 +51,10 @@ m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex
_logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0)
{
if (sock)
{
m_Address = sock->GetRemoteAddress ();
sock->AddReference ();
}
{
m_Address = sock->GetRemoteAddress ();
sock->AddReference ();
}
}
/// WorldSession destructor
@@ -99,7 +99,9 @@ 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;
@@ -131,12 +133,11 @@ void WorldSession::SendPacket(WorldPacket const* packet)
sendLastPacketCount = 1;
sendLastPacketBytes = packet->wpos(); // wpos is real written size
}
#endif // !TRINITY_DEBUG
if (m_Socket->SendPacket (*packet) == -1)
{
m_Socket->CloseSocket ();
}
#endif // !TRINITY_DEBUG
if (m_Socket->SendPacket (*packet) == -1)
m_Socket->CloseSocket ();
}
/// Add an incoming packet to the queue
@@ -157,12 +158,11 @@ void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(uint32 /*diff*/)
{
if (m_Socket)
if (m_Socket->IsClosed ())
{
if (m_Socket && m_Socket->IsClosed ())
{
m_Socket->RemoveReference ();
m_Socket = NULL;
}
}
WorldPacket *packet;
@@ -395,7 +395,8 @@ void WorldSession::LogoutPlayer(bool Save)
///- 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());
CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'",
GetAccountId());
sLog.outDebug( "SESSION: Sent SMSG_LOGOUT_COMPLETE Message" );
}
@@ -407,10 +408,8 @@ void WorldSession::LogoutPlayer(bool Save)
/// Kick a player out of the World
void WorldSession::KickPlayer()
{
if (m_Socket)
{
m_Socket->CloseSocket ();
}
if (m_Socket)
m_Socket->CloseSocket ();
}
/// Cancel channeling handler
+3 -3
View File
@@ -18,9 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "WorldSocket.h"
#include <ace/Message_Block.h>
#include <ace/OS_NS_string.h>
#include <ace/OS_NS_unistd.h>
@@ -32,6 +29,9 @@
#include <ace/Reactor.h>
#include <ace/Auto_Ptr.h>
#include "WorldSocket.h"
#include "Common.h"
#include "Util.h"
#include "World.h"
#include "WorldPacket.h"
+234 -245
View File
@@ -1,27 +1,27 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* Copyright (C) 2008 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
*/
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* Copyright (C) 2008 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 <derex101@gmail.com>
*/
* \ingroup u2w
* \author Derex <derex101@gmail.com>
*/
#include "WorldSocketMgr.h"
@@ -47,172 +47,168 @@
#include "WorldSocket.h"
/**
* This is a helper class to WorldSocketMgr ,that manages
* network threads, and assigning connections from acceptor thread
* to other network threads
*/
* 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;
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);
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);
imp = new ACE_TP_Reactor ();
imp->max_notify_iterations (128);
#endif
m_Reactor = new ACE_Reactor (imp, 1);
}
m_Reactor = new ACE_Reactor (imp, 1);
}
virtual
~ReactorRunnable ()
{
this->Stop ();
this->Wait ();
virtual ~ReactorRunnable ()
{
this->Stop ();
this->Wait ();
if (m_Reactor)
delete m_Reactor;
}
if (m_Reactor)
delete m_Reactor;
}
void
Stop ()
{
m_Reactor->end_reactor_event_loop ();
}
void Stop ()
{
m_Reactor->end_reactor_event_loop ();
}
int
Start ()
{
if (m_ThreadId != -1)
return -1;
int Start ()
{
if (m_ThreadId != -1)
return -1;
return (m_ThreadId = this->activate ());
}
return (m_ThreadId = this->activate ());
}
void
Wait ()
{
ACE_Task_Base::wait ();
}
void Wait ()
{
ACE_Task_Base::wait ();
}
long
Connections ()
{
return static_cast<long> (m_Connections.value ());
}
long Connections ()
{
return static_cast<long> (m_Connections.value ());
}
int
AddSocket (WorldSocket* sock)
{
ACE_GUARD_RETURN (ACE_Thread_Mutex, Guard, m_NewSockets_Lock, -1);
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);
++m_Connections;
sock->AddReference();
sock->reactor (m_Reactor);
m_NewSockets.insert (sock);
return 0;
}
ACE_Reactor* GetReactor ()
{
return m_Reactor;
}
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;
void AddNewSockets ()
{
ACE_GUARD (ACE_Thread_Mutex, Guard, m_NewSockets_Lock);
for (SocketSet::iterator i = m_NewSockets.begin (); i != m_NewSockets.end (); ++i)
{
WorldSocket* sock = (*i);
if (m_NewSockets.empty ())
return;
if (sock->IsClosed ())
{
sock->RemoveReference ();
--m_Connections;
}
else
m_Sockets.insert (sock);
}
for (SocketSet::iterator i = m_NewSockets.begin (); i != m_NewSockets.end (); ++i)
{
WorldSocket* sock = (*i);
m_NewSockets.clear ();
}
if (sock->IsClosed ())
{
sock->RemoveReference ();
--m_Connections;
}
else
m_Sockets.insert (sock);
}
virtual int
svc (void)
{
DEBUG_LOG ("Network Thread Starting");
m_NewSockets.clear ();
}
WorldDatabase.ThreadStart ();
virtual int svc (void)
{
DEBUG_LOG ("Network Thread Starting");
ACE_ASSERT (m_Reactor);
WorldDatabase.ThreadStart ();
SocketSet::iterator i, t;
ACE_ASSERT (m_Reactor);
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);
SocketSet::iterator i, t;
if (m_Reactor->run_reactor_event_loop (interval) == -1)
break;
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);
AddNewSockets ();
if (m_Reactor->run_reactor_event_loop (interval) == -1)
break;
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++;
}
}
AddNewSockets ();
WorldDatabase.ThreadEnd ();
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++;
}
}
DEBUG_LOG ("Network Thread Exitting");
WorldDatabase.ThreadEnd ();
return 0;
}
DEBUG_LOG ("Network Thread Exitting");
return 0;
}
private:
typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> AtomicInt;
typedef std::set<WorldSocket*> SocketSet;
typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> AtomicInt;
typedef std::set<WorldSocket*> SocketSet;
ACE_Reactor* m_Reactor;
AtomicInt m_Connections;
int m_ThreadId;
ACE_Reactor* m_Reactor;
AtomicInt m_Connections;
int m_ThreadId;
SocketSet m_Sockets;
SocketSet m_Sockets;
SocketSet m_NewSockets;
ACE_Thread_Mutex m_NewSockets_Lock;
SocketSet m_NewSockets;
ACE_Thread_Mutex m_NewSockets_Lock;
};
@@ -227,145 +223,138 @@ m_Acceptor (0) {}
WorldSocketMgr::~WorldSocketMgr ()
{
if (m_NetThreads)
delete [] m_NetThreads;
if(m_Acceptor)
delete m_Acceptor;
if (m_NetThreads)
delete [] m_NetThreads;
if(m_Acceptor)
delete m_Acceptor;
}
int
WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)
int WorldSocketMgr::StartReactiveIO (ACE_UINT16 port, const char* address)
{
m_UseNoDelay = sConfig.GetBoolDefault ("Network.TcpNodelay", true);
m_UseNoDelay = sConfig.GetBoolDefault ("Network.TcpNodelay", true);
int num_threads = sConfig.GetIntDefault ("Network.Threads", 1);
int num_threads = sConfig.GetIntDefault ("Network.Threads", 1);
if (num_threads <= 0)
{
sLog.outError ("Network.Threads is wrong in your config file");
return -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_NetThreadsCount = static_cast<size_t> (num_threads + 1);
m_NetThreads = new ReactorRunnable[m_NetThreadsCount];
m_NetThreads = new ReactorRunnable[m_NetThreadsCount];
sLog.outBasic ("Max alowed socket connections %d",ACE::max_handles ());
sLog.outBasic ("Max alowed socket connections %d",ACE::max_handles ());
m_SockOutKBuff = sConfig.GetIntDefault ("Network.OutKBuff", -1); // -1 means use default
m_SockOutKBuff = sConfig.GetIntDefault ("Network.OutKBuff", -1); // -1 means use default
m_SockOutUBuff = sConfig.GetIntDefault ("Network.OutUBuff", 65536);
m_SockOutUBuff = sConfig.GetIntDefault ("Network.OutUBuff", 65536);
if ( m_SockOutUBuff <= 0 )
{
sLog.outError ("Network.OutUBuff is wrong in your config file");
return -1;
}
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;
WorldSocket::Acceptor *acc = new WorldSocket::Acceptor;
m_Acceptor = acc;
ACE_INET_Addr listen_addr (port, address);
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;
}
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 ();
for (size_t i = 0; i < m_NetThreadsCount; ++i)
m_NetThreads[i].Start ();
return 0;
return 0;
}
int
WorldSocketMgr::StartNetwork (ACE_UINT16 port, const char* address)
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 (!sLog.IsOutDebug ())
ACE_Log_Msg::instance ()->priority_mask (LM_ERROR, ACE_Log_Msg::PROCESS);
if (this->StartReactiveIO (port, address) == -1)
return -1;
if (this->StartReactiveIO (port, address) == -1)
return -1;
return 0;
return 0;
}
void
WorldSocketMgr::StopNetwork ()
void WorldSocketMgr::StopNetwork ()
{
if (m_Acceptor)
{
WorldSocket::Acceptor* acc = dynamic_cast<WorldSocket::Acceptor*> (m_Acceptor);
if (m_Acceptor)
{
WorldSocket::Acceptor* acc = dynamic_cast<WorldSocket::Acceptor*> (m_Acceptor);
if (acc)
acc->close ();
}
if (acc)
acc->close ();
}
if (m_NetThreadsCount != 0)
{
for (size_t i = 0; i < m_NetThreadsCount; ++i)
m_NetThreads[i].Stop ();
}
this->Wait ();
if (m_NetThreadsCount != 0)
{
for (size_t i = 0; i < m_NetThreadsCount; ++i)
m_NetThreads[i].Stop ();
}
this->Wait ();
}
void
WorldSocketMgr::Wait ()
void WorldSocketMgr::Wait ()
{
if (m_NetThreadsCount != 0)
{
for (size_t i = 0; i < m_NetThreadsCount; ++i)
m_NetThreads[i].Wait ();
}
if (m_NetThreadsCount != 0)
{
for (size_t i = 0; i < m_NetThreadsCount; ++i)
m_NetThreads[i].Wait ();
}
}
int
WorldSocketMgr::OnSocketOpen (WorldSocket* sock)
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;
}
// 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;
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);
// 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;
}
// we skip the Acceptor Thread
size_t min = 1;
sock->m_OutBufferSize = static_cast<size_t> (m_SockOutUBuff);
ACE_ASSERT (m_NetThreadsCount >= 1);
// we skip the Acceptor Thread
size_t min = 1;
for (size_t i = 1; i < m_NetThreadsCount; ++i)
if (m_NetThreads[i].Connections () < m_NetThreads[min].Connections ())
min = i;
ACE_ASSERT (m_NetThreadsCount >= 1);
return m_NetThreads[min].AddSocket (sock);
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 ()
WorldSocketMgr* WorldSocketMgr::Instance ()
{
return ACE_Singleton<WorldSocketMgr,ACE_Thread_Mutex>::instance();
return ACE_Singleton<WorldSocketMgr,ACE_Thread_Mutex>::instance();
}
+6 -4
View File
@@ -34,9 +34,10 @@
#include "Database/Database.h"
#include "Database/DatabasePostgre.h"
typedef DatabasePostgre DatabaseType;
#define _LIKE_ "ILIKE"
#define _TABLE_SIM_ "\""
#define _LIKE_ "ILIKE"
#define _TABLE_SIM_ "\""
#define _CONCAT3_(A,B,C) "( " A " || " B " || " C " )"
#define _OFFSET_ "LIMIT 1 OFFSET %d"
#else
#include "Database/QueryResultMysql.h"
#include "Database/QueryResultSqlite.h"
@@ -44,9 +45,10 @@ typedef DatabasePostgre DatabaseType;
#include "Database/DatabaseMysql.h"
#include "Database/DatabaseSqlite.h"
typedef DatabaseMysql DatabaseType;
#define _LIKE_ "LIKE"
#define _TABLE_SIM_ "`"
#define _LIKE_ "LIKE"
#define _TABLE_SIM_ "`"
#define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )"
#define _OFFSET_ "LIMIT %d,1"
#endif
extern DatabaseType WorldDatabase;
+2 -10
View File
@@ -457,17 +457,9 @@ bool Master::_StartDB()
///- Clean the database before starting
clearOnlineAccounts();
QueryResult* result = WorldDatabase.Query("SELECT version FROM db_version LIMIT 1");
if(result)
{
Field* fields = result->Fetch();
sLog.outString("Using %s", fields[0].GetString());
delete result;
}
else
sLog.outString("Using unknown world database.");
sWorld.LoadDBVersion();
sLog.outString("Using %s", sWorld.GetDBVersion());
return true;
}
+4 -1
View File
@@ -196,7 +196,10 @@ void RASocket::OnRead()
loginDatabase.escape_string(login);
loginDatabase.escape_string(pw);
QueryResult *check = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", login.c_str(), pw.c_str());
QueryResult *check = loginDatabase.PQuery(
"SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))",
login.c_str(), pw.c_str());
if(check)
{
delete check;