mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
Merge commit 'origin/master' into 320
Conflicts: src/game/DBCStructure.h src/game/DBCfmt.h src/game/MiscHandler.cpp src/game/ObjectMgr.cpp
This commit is contained in:
commit
4a8431f581
51 changed files with 739 additions and 612 deletions
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_8416_01_mangos_spell_learn_spell` bit(1) default NULL
|
||||
`required_8462_01_mangos_creature_ai_texts` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -1043,7 +1043,7 @@ CREATE TABLE `creature_ai_texts` (
|
|||
`sound` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`language` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`emote` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`emote` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`comment` text,
|
||||
PRIMARY KEY (`entry`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Texts';
|
||||
|
|
@ -2720,6 +2720,7 @@ INSERT INTO `mangos_string` VALUES
|
|||
(345,'Forced customize for player %s will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(346,'Forced customize for player %s (GUID #%u) will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(347,'TaxiNode ID %u not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(348,'Game Object (Entry: %u) have invalid data and can\'t be spawned',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(401,'You change security level of account %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
@ -2841,7 +2842,7 @@ INSERT INTO `mangos_string` VALUES
|
|||
(519,'|cffffffff|Htele:%s|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(520,'%d - |cffffffff|Hspell:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(521,'%d - |cffffffff|Hskill:%d|h[%s %s]|h|r %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(522,'Game Object (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(522,'Game Object (Entry: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(523,'>> Game Object %s (GUID: %u) at %f %f %f. Orientation %f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(524,'Selected object:\n|cffffffff|Hgameobject:%d|h[%s]|h|r GUID: %u ID: %u\nX: %f Y: %f Z: %f MapId: %u\nOrientation: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(525,'>> Add Game Object \'%i\' (%s) (GUID: %i) added at \'%f %f %f\'.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
@ -17840,6 +17841,7 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(53569, 0x00000000, 10, 0x00200000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53576, 0x00000000, 10, 0x00200000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53601, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6),
|
||||
(53646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53671, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53673, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(54149, 0x00000000, 10, 0x00200000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
|
|
|
|||
6
sql/updates/8444_01_mangos_mangos_string.sql
Normal file
6
sql/updates/8444_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_8416_01_mangos_spell_learn_spell required_8444_01_mangos_mangos_string bit;
|
||||
|
||||
DELETE FROM mangos_string WHERE entry IN(348,522);
|
||||
INSERT INTO mangos_string VALUES
|
||||
(348,'Game Object (Entry: %u) have invalid data and can\'t be spawned',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(522,'Game Object (Entry: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
5
sql/updates/8451_01_mangos_spell_proc_event.sql
Normal file
5
sql/updates/8451_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_8444_01_mangos_mangos_string required_8451_01_mangos_spell_proc_event bit;
|
||||
|
||||
DELETE FROM spell_proc_event WHERE entry = 53646;
|
||||
INSERT INTO spell_proc_event VALUES
|
||||
(53646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
|
||||
3
sql/updates/8462_01_mangos_creature_ai_texts.sql
Normal file
3
sql/updates/8462_01_mangos_creature_ai_texts.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_8451_01_mangos_spell_proc_event required_8462_01_mangos_creature_ai_texts bit;
|
||||
|
||||
ALTER TABLE creature_ai_texts CHANGE emote emote smallint(5) unsigned NOT NULL default '0';
|
||||
|
|
@ -96,6 +96,9 @@ pkgdata_DATA = \
|
|||
8412_01_mangos_mangos_string.sql \
|
||||
8416_01_mangos_spell_learn_spell.sql \
|
||||
8433_01_characters_character_account_data.sql \
|
||||
8444_01_mangos_mangos_string.sql \
|
||||
8451_01_mangos_spell_proc_event.sql \
|
||||
8462_01_mangos_creature_ai_texts.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -172,4 +175,7 @@ EXTRA_DIST = \
|
|||
8412_01_mangos_mangos_string.sql \
|
||||
8416_01_mangos_spell_learn_spell.sql \
|
||||
8433_01_characters_character_account_data.sql \
|
||||
8444_01_mangos_mangos_string.sql \
|
||||
8451_01_mangos_spell_proc_event.sql \
|
||||
8462_01_mangos_creature_ai_texts.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "Player.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Util.h"
|
||||
#include "Auth/Sha1.h"
|
||||
|
||||
extern DatabaseType loginDatabase;
|
||||
|
||||
|
|
@ -41,17 +42,12 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
|
|||
normalizeString(username);
|
||||
normalizeString(password);
|
||||
|
||||
loginDatabase.escape_string(username);
|
||||
loginDatabase.escape_string(password);
|
||||
|
||||
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
|
||||
if(result)
|
||||
if(GetId(username))
|
||||
{
|
||||
delete result;
|
||||
return AOR_NAME_ALREDY_EXIST; // username does already exist
|
||||
}
|
||||
|
||||
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1("_CONCAT3_("'%s'","':'","'%s'")"),NOW())", username.c_str(), username.c_str(), password.c_str()))
|
||||
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s','%s',NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str()))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
|
||||
|
||||
|
|
@ -121,9 +117,11 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
|
|||
normalizeString(new_uname);
|
||||
normalizeString(new_passwd);
|
||||
|
||||
loginDatabase.escape_string(new_uname);
|
||||
loginDatabase.escape_string(new_passwd);
|
||||
if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1("_CONCAT3_("'%s'","':'","'%s'")") WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
|
||||
std::string safe_new_uname = new_uname;
|
||||
loginDatabase.escape_string(safe_new_uname);
|
||||
|
||||
if(!loginDatabase.PExecute("UPDATE account SET v='0',s='0',username='%s',sha_pass_hash='%s' WHERE id='%d'", safe_new_uname.c_str(),
|
||||
CalculateShaPassHash(new_uname, new_passwd).c_str(), accid))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
|
||||
return AOR_OK;
|
||||
|
|
@ -131,18 +129,19 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
|
|||
|
||||
AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
|
||||
{
|
||||
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
|
||||
if(!result)
|
||||
std::string username;
|
||||
|
||||
if(!GetName(accid, username))
|
||||
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
||||
delete result;
|
||||
|
||||
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
|
||||
return AOR_PASS_TOO_LONG;
|
||||
|
||||
normalizeString(new_passwd);
|
||||
|
||||
loginDatabase.escape_string(new_passwd);
|
||||
if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")") WHERE id='%d'", new_passwd.c_str(), accid))
|
||||
// also reset s and v to force update at next realmd login
|
||||
if(!loginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'",
|
||||
CalculateShaPassHash(username, new_passwd).c_str(), accid))
|
||||
return AOR_DB_INTERNAL_ERROR; // unexpected error
|
||||
|
||||
return AOR_OK;
|
||||
|
|
@ -190,10 +189,13 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name)
|
|||
|
||||
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
|
||||
{
|
||||
normalizeString(passwd);
|
||||
loginDatabase.escape_string(passwd);
|
||||
std::string username;
|
||||
if(!GetName(accid, username))
|
||||
return false;
|
||||
|
||||
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")")", accid, passwd.c_str());
|
||||
normalizeString(passwd);
|
||||
|
||||
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str());
|
||||
if (result)
|
||||
{
|
||||
delete result;
|
||||
|
|
@ -215,3 +217,19 @@ bool AccountMgr::normalizeString(std::string& utf8str)
|
|||
|
||||
return WStrToUtf8(wstr_buf,wstr_len,utf8str);
|
||||
}
|
||||
|
||||
std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& password)
|
||||
{
|
||||
Sha1Hash sha;
|
||||
sha.Initialize();
|
||||
sha.UpdateData(name);
|
||||
sha.UpdateData(":");
|
||||
sha.UpdateData(password);
|
||||
sha.Finalize();
|
||||
|
||||
std::string encoded;
|
||||
hexEncodeByteArray(sha.GetDigest(), sha.GetLength(), encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class AccountMgr
|
|||
uint32 GetId(std::string username);
|
||||
uint32 GetSecurity(uint32 acc_id);
|
||||
bool GetName(uint32 acc_id, std::string &name);
|
||||
std::string CalculateShaPassHash(std::string& name, std::string& password);
|
||||
|
||||
static bool normalizeString(std::string& utf8str);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1017,10 +1017,22 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
{
|
||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
|
||||
continue;
|
||||
|
||||
// those requirements couldn't be found in the dbc
|
||||
AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
|
||||
if(!data)
|
||||
continue;
|
||||
|
||||
if(!data->Meets(GetPlayer(),unit))
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
|
||||
if(miscvalue1 && miscvalue1!=achievementCriteria->learn_spell.spellID)
|
||||
continue;
|
||||
|
|
@ -1279,25 +1291,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
|
||||
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetVisibleFactionCount());
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
{
|
||||
if (!miscvalue1)
|
||||
continue;
|
||||
|
||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
|
||||
continue;
|
||||
|
||||
// those requirements couldn't be found in the dbc
|
||||
AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
|
||||
if(!data)
|
||||
continue;
|
||||
|
||||
if(!data->Meets(GetPlayer(),unit))
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
|
||||
{
|
||||
if (miscvalue1 && miscvalue1 != achievementCriteria->learn_skill_line.skillLine)
|
||||
|
|
|
|||
|
|
@ -119,9 +119,6 @@ class CharacterHandler
|
|||
|
||||
void WorldSession::HandleCharEnum(QueryResult * result)
|
||||
{
|
||||
// keys can be non cleared if player open realm list and close it by 'cancel'
|
||||
loginDatabase.PExecute("UPDATE account SET v = '0', s = '0' WHERE id = '%u'", GetAccountId());
|
||||
|
||||
WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
|
||||
|
||||
uint8 num = 0;
|
||||
|
|
|
|||
|
|
@ -1480,7 +1480,7 @@ valid examples:
|
|||
bool foundName = false;
|
||||
for(uint8 i=0; i<MAX_LOCALE; ++i)
|
||||
{
|
||||
if (*linkedAchievement->name[i], strcmp(linkedAchievement->name[i], buffer) == 0)
|
||||
if (*linkedAchievement->name[i] && strcmp(linkedAchievement->name[i], buffer) == 0)
|
||||
{
|
||||
foundName = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1320,7 +1320,7 @@ struct SpellEntry
|
|||
uint32 AttributesEx3; // 7 m_attributesExC
|
||||
uint32 AttributesEx4; // 8 m_attributesExD
|
||||
uint32 AttributesEx5; // 9 m_attributesExE
|
||||
//uint32 AttributesEx6; // 10 m_attributesExF not used
|
||||
uint32 AttributesEx6; // 10 m_attributesExF
|
||||
// uint32 unk_320_1; // 11 3.2.0 (0x20 - totems, 0x4 - paladin auras, etc...)
|
||||
uint32 Stances; // 12 m_shapeshiftMask
|
||||
// uint32 unk_320_2; // 13 3.2.0
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
|
|||
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char SpellCastTimefmt[]="nixx";
|
||||
const char SpellDurationfmt[]="niii";
|
||||
const char SpellEntryfmt[]="niiiiiiiiixxixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxx";
|
||||
const char SpellEntryfmt[]="niiiiiiiiiixixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxx";
|
||||
const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx";
|
||||
const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixxx";
|
||||
const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class MANGOS_DLL_DECL DestinationHolder
|
|||
uint32 StartTravel(TRAVELLER &traveller, bool sendMove = true);
|
||||
void GetLocationNow(const Map * map, float &x, float &y, float &z, bool is3D = false) const;
|
||||
void GetLocationNowNoMicroMovement(float &x, float &y, float &z) const; // For use without micro movement
|
||||
float GetDistance2dFromDestSq(const WorldObject &obj) const;
|
||||
float GetDistance3dFromDestSq(const WorldObject &obj) const;
|
||||
|
||||
private:
|
||||
void _findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y);
|
||||
|
|
|
|||
|
|
@ -93,19 +93,19 @@ template<typename TRAVELLER>
|
|||
bool
|
||||
DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool force_update, bool micro_movement)
|
||||
{
|
||||
if(!micro_movement)
|
||||
if (!micro_movement)
|
||||
{
|
||||
i_tracker.Update(diff);
|
||||
i_timeElapsed += diff;
|
||||
if( i_tracker.Passed() || force_update )
|
||||
if (i_tracker.Passed() || force_update)
|
||||
{
|
||||
ResetUpdate();
|
||||
if(!i_destSet) return true;
|
||||
if (!i_destSet) return true;
|
||||
|
||||
float x,y,z;
|
||||
GetLocationNowNoMicroMovement(x, y, z);
|
||||
if( x == -431602080 )
|
||||
return false;
|
||||
if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y )
|
||||
|
||||
if (traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y || traveller.GetTraveller().GetPositionZ() != z)
|
||||
{
|
||||
float ori = traveller.GetTraveller().GetAngle(x, y);
|
||||
traveller.Relocation(x, y, z, ori);
|
||||
|
|
@ -116,24 +116,21 @@ DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff,
|
|||
}
|
||||
i_tracker.Update(diff);
|
||||
i_timeElapsed += diff;
|
||||
if( i_tracker.Passed() || force_update )
|
||||
if (i_tracker.Passed() || force_update)
|
||||
{
|
||||
ResetUpdate();
|
||||
if(!i_destSet) return true;
|
||||
float x,y,z;
|
||||
if (!i_destSet) return true;
|
||||
|
||||
if(!traveller.GetTraveller().hasUnitState(UNIT_STAT_MOVING | UNIT_STAT_IN_FLIGHT))
|
||||
if (!traveller.GetTraveller().hasUnitState(UNIT_STAT_MOVING | UNIT_STAT_IN_FLIGHT))
|
||||
return true;
|
||||
|
||||
if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
|
||||
float x,y,z;
|
||||
if (traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
|
||||
GetLocationNow(traveller.GetTraveller().GetBaseMap() ,x, y, z, true); // Should reposition Object with right Coord, so I can bypass some Grid Relocation
|
||||
else
|
||||
GetLocationNow(traveller.GetTraveller().GetBaseMap(), x, y, z, false);
|
||||
|
||||
if( x == -431602080 )
|
||||
return false;
|
||||
|
||||
if( traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y )
|
||||
if (traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y || traveller.GetTraveller().GetPositionZ() != z)
|
||||
{
|
||||
float ori = traveller.GetTraveller().GetAngle(x, y);
|
||||
traveller.Relocation(x, y, z, ori);
|
||||
|
|
@ -160,13 +157,13 @@ template<typename TRAVELLER>
|
|||
void
|
||||
DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y, float &z, bool is3D) const
|
||||
{
|
||||
if( HasArrived() )
|
||||
if (HasArrived())
|
||||
{
|
||||
x = i_destX;
|
||||
y = i_destY;
|
||||
z = i_destZ;
|
||||
}
|
||||
else if(HasDestination())
|
||||
else if (HasDestination())
|
||||
{
|
||||
double percent_passed = (double)i_timeElapsed / (double)i_totalTravelTime;
|
||||
const float distanceX = ((i_destX - i_fromX) * percent_passed);
|
||||
|
|
@ -176,7 +173,7 @@ DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y
|
|||
y = i_fromY + distanceY;
|
||||
float z2 = i_fromZ + distanceZ;
|
||||
// All that is not finished but previous code neither... Traveller need be able to swim.
|
||||
if(is3D)
|
||||
if (is3D)
|
||||
z = z2;
|
||||
else
|
||||
{
|
||||
|
|
@ -193,11 +190,11 @@ DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y
|
|||
|
||||
template<typename TRAVELLER>
|
||||
float
|
||||
DestinationHolder<TRAVELLER>::GetDistance2dFromDestSq(const WorldObject &obj) const
|
||||
DestinationHolder<TRAVELLER>::GetDistance3dFromDestSq(const WorldObject &obj) const
|
||||
{
|
||||
float x,y,z;
|
||||
obj.GetPosition(x,y,z);
|
||||
return (i_destX-x)*(i_destX-x)+(i_destY-y)*(i_destY-y);
|
||||
return (i_destX-x)*(i_destX-x)+(i_destY-y)*(i_destY-y)+(i_destZ-z)*(i_destZ-z);
|
||||
}
|
||||
|
||||
template<typename TRAVELLER>
|
||||
|
|
@ -211,7 +208,7 @@ template<typename TRAVELLER>
|
|||
void
|
||||
DestinationHolder<TRAVELLER>::GetLocationNowNoMicroMovement(float &x, float &y, float &z) const
|
||||
{
|
||||
if( HasArrived() )
|
||||
if (HasArrived())
|
||||
{
|
||||
x = i_destX;
|
||||
y = i_destY;
|
||||
|
|
|
|||
|
|
@ -150,9 +150,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
|
|||
|
||||
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
|
||||
|
||||
// GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3
|
||||
SetGoState(go_state);
|
||||
SetGoType(GameobjectTypes(goinfo->type));
|
||||
|
||||
SetGoArtKit(0); // unknown what this is
|
||||
SetGoAnimProgress(animprogress);
|
||||
|
||||
//Notify the map's instance data.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -237,25 +237,25 @@ struct GuildBankTab
|
|||
|
||||
struct GuildItemPosCount
|
||||
{
|
||||
GuildItemPosCount(uint8 _slot, uint32 _count) : slot(_slot), count(_count) {}
|
||||
GuildItemPosCount(uint8 _slot, uint32 _count) : Slot(_slot), Count(_count) {}
|
||||
|
||||
bool isContainedIn(std::vector<GuildItemPosCount> const& vec) const;
|
||||
|
||||
uint8 slot;
|
||||
uint32 count;
|
||||
uint8 Slot;
|
||||
uint32 Count;
|
||||
};
|
||||
typedef std::vector<GuildItemPosCount> GuildItemPosCountVec;
|
||||
|
||||
struct MemberSlot
|
||||
{
|
||||
uint64 logout_time;
|
||||
std::string name;
|
||||
std::string Name;
|
||||
uint32 RankId;
|
||||
uint8 Level;
|
||||
uint8 Class;
|
||||
uint32 ZoneId;
|
||||
uint64 LogoutTime;
|
||||
std::string Pnote;
|
||||
std::string OFFnote;
|
||||
uint32 RankId;
|
||||
uint32 zoneId;
|
||||
uint8 level;
|
||||
uint8 Class;
|
||||
uint32 BankResetTimeMoney;
|
||||
uint32 BankRemMoney;
|
||||
uint32 BankResetTimeTab[GUILD_BANK_MAX_TABS];
|
||||
|
|
@ -264,7 +264,7 @@ struct MemberSlot
|
|||
|
||||
struct RankInfo
|
||||
{
|
||||
RankInfo(const std::string& _name, uint32 _rights, uint32 _money) : name(_name), rights(_rights), BankMoneyPerDay(_money)
|
||||
RankInfo(const std::string& _name, uint32 _rights, uint32 _money) : Name(_name), Rights(_rights), BankMoneyPerDay(_money)
|
||||
{
|
||||
for(uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i)
|
||||
{
|
||||
|
|
@ -273,8 +273,8 @@ struct RankInfo
|
|||
}
|
||||
}
|
||||
|
||||
std::string name;
|
||||
uint32 rights;
|
||||
std::string Name;
|
||||
uint32 Rights;
|
||||
uint32 BankMoneyPerDay;
|
||||
uint32 TabRight[GUILD_BANK_MAX_TABS];
|
||||
uint32 TabSlotPerDay[GUILD_BANK_MAX_TABS];
|
||||
|
|
@ -365,7 +365,7 @@ class Guild
|
|||
{
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
if(itr->second.name == name)
|
||||
if(itr->second.Name == name)
|
||||
{
|
||||
guid = itr->first;
|
||||
return &itr->second;
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ enum ItemModType
|
|||
ITEM_MOD_ATTACK_POWER = 38,
|
||||
ITEM_MOD_RANGED_ATTACK_POWER = 39,
|
||||
ITEM_MOD_FERAL_ATTACK_POWER = 40,
|
||||
ITEM_MOD_SPELL_HEALING_DONE = 41,
|
||||
ITEM_MOD_SPELL_DAMAGE_DONE = 42,
|
||||
ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated
|
||||
ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated
|
||||
ITEM_MOD_MANA_REGENERATION = 43,
|
||||
ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
|
||||
ITEM_MOD_SPELL_POWER = 45,
|
||||
|
|
|
|||
|
|
@ -331,7 +331,8 @@ enum MangosStrings
|
|||
LANG_CUSTOMIZE_PLAYER = 345,
|
||||
LANG_CUSTOMIZE_PLAYER_GUID = 346,
|
||||
LANG_COMMAND_GOTAXINODENOTFOUND = 347,
|
||||
// Room for more level 2 348-399 not used
|
||||
LANG_GAMEOBJECT_HAVE_INVALID_DATA = 348,
|
||||
// Room for more level 2 349-399 not used
|
||||
|
||||
// level 3 chat
|
||||
LANG_SCRIPTS_RELOADED = 400,
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
|
|||
|
||||
PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),"");
|
||||
if (needReportToTarget(target))
|
||||
ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str());
|
||||
ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, playerLink(_player->GetName()).c_str());
|
||||
|
||||
// stop flight if need
|
||||
if (target->isInFlight())
|
||||
|
|
|
|||
|
|
@ -700,15 +700,24 @@ bool ChatHandler::HandleGameObjectAddCommand(const char* args)
|
|||
|
||||
char* spawntimeSecs = strtok(NULL, " ");
|
||||
|
||||
const GameObjectInfo *goI = objmgr.GetGameObjectInfo(id);
|
||||
const GameObjectInfo *gInfo = objmgr.GetGameObjectInfo(id);
|
||||
|
||||
if (!goI)
|
||||
if (!gInfo)
|
||||
{
|
||||
PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST,id);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
|
||||
{
|
||||
// report to DB errors log as in loading case
|
||||
sLog.outErrorDb("Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.",id, gInfo->type, gInfo->displayId);
|
||||
PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA,id);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Player *chr = m_session->GetPlayer();
|
||||
float x = float(chr->GetPositionX());
|
||||
float y = float(chr->GetPositionY());
|
||||
|
|
@ -719,7 +728,7 @@ bool ChatHandler::HandleGameObjectAddCommand(const char* args)
|
|||
GameObject* pGameObj = new GameObject;
|
||||
uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
|
||||
|
||||
if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
|
||||
if(!pGameObj->Create(db_lowGUID, gInfo->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
|
||||
{
|
||||
delete pGameObj;
|
||||
return false;
|
||||
|
|
@ -742,14 +751,14 @@ bool ChatHandler::HandleGameObjectAddCommand(const char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), goI->name, db_lowGUID, x, y, z, o);
|
||||
sLog.outDebug(GetMangosString(LANG_GAMEOBJECT_CURRENT), gInfo->name, db_lowGUID, x, y, z, o);
|
||||
|
||||
map->Add(pGameObj);
|
||||
|
||||
// TODO: is it really necessary to add both the real and DB table guid here ?
|
||||
objmgr.AddGameobjectToGrid(db_lowGUID, objmgr.GetGOData(db_lowGUID));
|
||||
|
||||
PSendSysMessage(LANG_GAMEOBJECT_ADD,id,goI->name,db_lowGUID,x,y,z);
|
||||
PSendSysMessage(LANG_GAMEOBJECT_ADD,id,gInfo->name,db_lowGUID,x,y,z);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ enum MailShowFlags
|
|||
MAIL_SHOW_UNK0 = 0x0001,
|
||||
MAIL_SHOW_DELETE = 0x0002, // forced show delete button instead return button
|
||||
MAIL_SHOW_AUCTION = 0x0004, // from old comment
|
||||
MAIL_SHOW_COD = 0x0008, // show subject prefix
|
||||
MAIL_SHOW_UNK4 = 0x0010,
|
||||
MAIL_SHOW_UNK2 = 0x0008, // unknown, COD will be shown even without that flag
|
||||
MAIL_SHOW_RETURN = 0x0010,
|
||||
};
|
||||
|
||||
void MailItem::deleteItem( bool inDB )
|
||||
|
|
@ -321,7 +321,16 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
|
|||
pl->m_mailsUpdated = true;
|
||||
Mail *m = pl->GetMail(mailId);
|
||||
if(m)
|
||||
{
|
||||
// delete shouldn't show up for COD mails
|
||||
if (m->COD)
|
||||
{
|
||||
pl->SendMailResult(mailId, MAIL_DELETED, MAIL_ERR_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
m->state = MAIL_STATE_DELETED;
|
||||
}
|
||||
pl->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
|
||||
}
|
||||
|
||||
|
|
@ -594,8 +603,8 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
|
|||
show_flags |= MAIL_SHOW_DELETE;
|
||||
if ((*itr)->messageType == MAIL_AUCTION)
|
||||
show_flags |= MAIL_SHOW_AUCTION;
|
||||
if ((*itr)->COD)
|
||||
show_flags |= MAIL_SHOW_COD;
|
||||
if ((*itr)->HasItems() && (*itr)->messageType == MAIL_NORMAL)
|
||||
show_flags |= MAIL_SHOW_RETURN;
|
||||
|
||||
data << uint16(0x0040); // unknown 2.3.0, different values
|
||||
data << uint32((*itr)->messageID); // Message ID
|
||||
|
|
|
|||
|
|
@ -592,11 +592,10 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
|||
if (isType(TYPEMASK_GAMEOBJECT) && !((GameObject*)this)->IsTransport())
|
||||
{
|
||||
if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())
|
||||
{
|
||||
IsActivateToQuest = true;
|
||||
|
||||
updateMask->SetBit(GAMEOBJECT_DYNAMIC);
|
||||
}
|
||||
}
|
||||
else if (isType(TYPEMASK_UNIT))
|
||||
{
|
||||
if( ((Unit*)this)->HasAuraState(AURA_STATE_CONFLAGRATE))
|
||||
|
|
@ -711,18 +710,27 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
|||
switch(((GameObject*)this)->GetGoType())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
*data << uint32(9); // enable quest object. Represent 9, but 1 for client before 2.3.0
|
||||
// enable quest object. Represent 9, but 1 for client before 2.3.0
|
||||
*data << uint16(9);
|
||||
*data << uint16(-1);
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_GOOBER:
|
||||
*data << uint32(1);
|
||||
*data << uint16(1);
|
||||
*data << uint16(-1);
|
||||
break;
|
||||
default:
|
||||
*data << uint32(0); // unknown, not happen.
|
||||
// unknown, not happen.
|
||||
*data << uint16(0);
|
||||
*data << uint16(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
*data << uint32(0); // disable quest object
|
||||
{
|
||||
// disable quest object
|
||||
*data << uint16(0);
|
||||
*data << uint16(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
*data << m_uint32Values[ index ]; // other cases
|
||||
|
|
|
|||
|
|
@ -1220,7 +1220,7 @@ void ObjectMgr::LoadGameobjects()
|
|||
uint32 entry = fields[ 1].GetUInt32();
|
||||
|
||||
GameObjectInfo const* gInfo = GetGameObjectInfo(entry);
|
||||
if(!gInfo)
|
||||
if (!gInfo)
|
||||
{
|
||||
sLog.outErrorDb("Table `gameobject` has gameobject (GUID: %u) with non existing gameobject entry %u, skipped.", guid, entry);
|
||||
continue;
|
||||
|
|
@ -1232,7 +1232,7 @@ void ObjectMgr::LoadGameobjects()
|
|||
continue;
|
||||
}
|
||||
|
||||
if(gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
|
||||
if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
|
||||
{
|
||||
sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
|
||||
continue;
|
||||
|
|
@ -1272,13 +1272,13 @@ void ObjectMgr::LoadGameobjects()
|
|||
int16 gameEvent = fields[16].GetInt16();
|
||||
int16 PoolId = fields[17].GetInt16();
|
||||
|
||||
if(data.rotation2 < -1.0f || data.rotation2 > 1.0f)
|
||||
if (data.rotation2 < -1.0f || data.rotation2 > 1.0f)
|
||||
{
|
||||
sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation2 (%f) value, skip", guid, data.id, data.rotation2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(data.rotation3 < -1.0f || data.rotation3 > 1.0f)
|
||||
if (data.rotation3 < -1.0f || data.rotation3 > 1.0f)
|
||||
{
|
||||
sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation3 (%f) value, skip", guid, data.id, data.rotation3);
|
||||
continue;
|
||||
|
|
@ -1786,6 +1786,16 @@ void ObjectMgr::LoadItemPrototypes()
|
|||
sLog.outErrorDb("Item (Entry: %u) has wrong stat_type%d (%u)",i,j+1,proto->ItemStat[j].ItemStatType);
|
||||
const_cast<ItemPrototype*>(proto)->ItemStat[j].ItemStatType = 0;
|
||||
}
|
||||
|
||||
switch(proto->ItemStat[j].ItemStatType)
|
||||
{
|
||||
case ITEM_MOD_SPELL_HEALING_DONE:
|
||||
case ITEM_MOD_SPELL_DAMAGE_DONE:
|
||||
sLog.outErrorDb("Item (Entry: %u) has deprecated stat_type%d (%u)",i,j+1,proto->ItemStat[j].ItemStatType);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
|
||||
|
|
|
|||
|
|
@ -445,10 +445,10 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
|||
for (int i = 0; i < MAX_COMBAT_RATING; ++i)
|
||||
m_baseRatingValue[i] = 0;
|
||||
|
||||
m_baseSpellDamage = 0;
|
||||
m_baseSpellHealing = 0;
|
||||
m_baseSpellPower = 0;
|
||||
m_baseFeralAP = 0;
|
||||
m_baseManaRegen = 0;
|
||||
m_armorPenetrationPct = 0.0f;
|
||||
|
||||
// Honor System
|
||||
m_lastHonorUpdateTime = time(NULL);
|
||||
|
|
@ -809,10 +809,10 @@ void Player::StopMirrorTimer(MirrorTimerType Type)
|
|||
GetSession()->SendPacket( &data );
|
||||
}
|
||||
|
||||
void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
|
||||
uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
|
||||
{
|
||||
if(!isAlive() || isGameMaster())
|
||||
return;
|
||||
return 0;
|
||||
|
||||
// Absorb, resist some environmental damage type
|
||||
uint32 absorb = 0;
|
||||
|
|
@ -834,7 +834,7 @@ void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
|
|||
data << uint32(resist);
|
||||
SendMessageToSet(&data, true);
|
||||
|
||||
DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
uint32 final_damage = DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
|
||||
if(!isAlive())
|
||||
{
|
||||
|
|
@ -849,6 +849,8 @@ void Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
|
|||
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type);
|
||||
}
|
||||
|
||||
return final_damage;
|
||||
}
|
||||
|
||||
int32 Player::getMaxTimer(MirrorTimerType timer)
|
||||
|
|
@ -4980,6 +4982,8 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
|
|||
}
|
||||
break;
|
||||
case CR_ARMOR_PENETRATION:
|
||||
if(affectStats)
|
||||
UpdateArmorPenetration();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -6666,12 +6670,6 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
|
|||
case ITEM_MOD_FERAL_ATTACK_POWER:
|
||||
ApplyFeralAPBonus(int32(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_HEALING_DONE:
|
||||
ApplySpellHealingBonus(int32(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_DAMAGE_DONE:
|
||||
ApplySpellDamageBonus(int32(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_MANA_REGENERATION:
|
||||
ApplyManaRegenBonus(int32(val), apply);
|
||||
break;
|
||||
|
|
@ -6679,8 +6677,11 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
|
|||
ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_POWER:
|
||||
ApplySpellHealingBonus(int32(val), apply);
|
||||
ApplySpellDamageBonus(int32(val), apply);
|
||||
ApplySpellPowerBonus(int32(val), apply);
|
||||
break;
|
||||
// depricated item mods
|
||||
case ITEM_MOD_SPELL_HEALING_DONE:
|
||||
case ITEM_MOD_SPELL_DAMAGE_DONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -10448,9 +10449,15 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
|
|||
ApplyEquipCooldown(pItem);
|
||||
|
||||
if( slot == EQUIPMENT_SLOT_MAINHAND )
|
||||
{
|
||||
UpdateExpertise(BASE_ATTACK);
|
||||
UpdateArmorPenetration();
|
||||
}
|
||||
else if( slot == EQUIPMENT_SLOT_OFFHAND )
|
||||
{
|
||||
UpdateExpertise(OFF_ATTACK);
|
||||
UpdateArmorPenetration();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -10590,9 +10597,13 @@ void Player::RemoveItem( uint8 bag, uint8 slot, bool update )
|
|||
}
|
||||
|
||||
UpdateExpertise(BASE_ATTACK);
|
||||
UpdateArmorPenetration();
|
||||
}
|
||||
else if( slot == EQUIPMENT_SLOT_OFFHAND )
|
||||
{
|
||||
UpdateExpertise(OFF_ATTACK);
|
||||
UpdateArmorPenetration();
|
||||
}
|
||||
}
|
||||
}
|
||||
// need update known currency
|
||||
|
|
@ -10701,10 +10712,16 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update )
|
|||
RemoveItemDependentAurasAndCasts(pItem);
|
||||
|
||||
// update expertise
|
||||
if ( slot == EQUIPMENT_SLOT_MAINHAND )
|
||||
if( slot == EQUIPMENT_SLOT_MAINHAND )
|
||||
{
|
||||
UpdateExpertise(BASE_ATTACK);
|
||||
UpdateArmorPenetration();
|
||||
}
|
||||
else if( slot == EQUIPMENT_SLOT_OFFHAND )
|
||||
{
|
||||
UpdateExpertise(OFF_ATTACK);
|
||||
UpdateArmorPenetration();
|
||||
}
|
||||
|
||||
// equipment visual show
|
||||
SetVisibleItemSlot(slot, NULL);
|
||||
|
|
@ -11939,14 +11956,6 @@ void Player::ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool
|
|||
((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply);
|
||||
sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_HEALING_DONE:
|
||||
((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
|
||||
sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_DAMAGE_DONE:
|
||||
((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
|
||||
sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_MANA_REGENERATION:
|
||||
((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply);
|
||||
sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount);
|
||||
|
|
@ -11956,10 +11965,11 @@ void Player::ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool
|
|||
sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_POWER:
|
||||
((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply);
|
||||
((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply);
|
||||
((Player*)this)->ApplySpellPowerBonus(enchant_amount, apply);
|
||||
sLog.outDebug("+ %u SPELL_POWER", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_SPELL_HEALING_DONE: // deprecated
|
||||
case ITEM_MOD_SPELL_DAMAGE_DONE: // deprecated
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -18690,9 +18700,9 @@ void Player::UpdateForQuestWorldObjects()
|
|||
continue;
|
||||
|
||||
SpellClickInfoMapBounds clickPair = objmgr.GetSpellClickInfoMapBounds(obj->GetEntry());
|
||||
for(SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
|
||||
for(SpellClickInfoMap::const_iterator _itr = clickPair.first; _itr != clickPair.second; ++_itr)
|
||||
{
|
||||
if(itr->second.questStart || itr->second.questEnd)
|
||||
if(_itr->second.questStart || _itr->second.questEnd)
|
||||
{
|
||||
obj->BuildCreateUpdateBlockForPlayer(&udata,this);
|
||||
break;
|
||||
|
|
@ -19914,10 +19924,11 @@ void Player::HandleFall(MovementInfo const& movementInfo)
|
|||
if (GetDummyAura(43621))
|
||||
damage = GetMaxHealth()/2;
|
||||
|
||||
EnvironmentalDamage(DAMAGE_FALL, damage);
|
||||
uint32 original_health = GetHealth();
|
||||
uint32 final_damage = EnvironmentalDamage(DAMAGE_FALL, damage);
|
||||
|
||||
// recheck alive, might have died of EnvironmentalDamage
|
||||
if (isAlive())
|
||||
// recheck alive, might have died of EnvironmentalDamage, avoid cases when player die in fact like Spirit of Redemption case
|
||||
if (isAlive() && final_damage < original_health)
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1700,8 +1700,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void UpdateAttackPowerAndDamage(bool ranged = false);
|
||||
void UpdateShieldBlockValue();
|
||||
void UpdateDamagePhysical(WeaponAttackType attType);
|
||||
void ApplySpellDamageBonus(int32 amount, bool apply);
|
||||
void ApplySpellHealingBonus(int32 amount, bool apply);
|
||||
void ApplySpellPowerBonus(int32 amount, bool apply);
|
||||
void UpdateSpellDamageAndHealingBonus();
|
||||
|
||||
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage);
|
||||
|
|
@ -1719,8 +1718,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 GetRangedCritDamageReduction(uint32 damage) const;
|
||||
uint32 GetSpellCritDamageReduction(uint32 damage) const;
|
||||
uint32 GetDotDamageReduction(uint32 damage) const;
|
||||
uint32 GetBaseSpellDamageBonus() { return m_baseSpellDamage;}
|
||||
uint32 GetBaseSpellHealingBonus() { return m_baseSpellHealing;}
|
||||
uint32 GetBaseSpellPowerBonus() { return m_baseSpellPower; }
|
||||
|
||||
float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
|
||||
void UpdateBlockPercentage();
|
||||
|
|
@ -1735,6 +1733,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void UpdateAllSpellCritChances();
|
||||
void UpdateSpellCritChance(uint32 school);
|
||||
void UpdateExpertise(WeaponAttackType attType);
|
||||
void UpdateArmorPenetration();
|
||||
void ApplyManaRegenBonus(int32 amount, bool apply);
|
||||
void UpdateManaRegen();
|
||||
|
||||
|
|
@ -1899,6 +1898,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
float GetTotalPercentageModValue(BaseModGroup modGroup) const { return m_auraBaseMod[modGroup][FLAT_MOD] + m_auraBaseMod[modGroup][PCT_MOD]; }
|
||||
void _ApplyAllStatBonuses();
|
||||
void _RemoveAllStatBonuses();
|
||||
float GetArmorPenetrationPct() const { return m_armorPenetrationPct; }
|
||||
|
||||
void _ApplyWeaponDependentAuraMods(Item *item, WeaponAttackType attackType, bool apply);
|
||||
void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply);
|
||||
|
|
@ -2060,7 +2060,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
/*** ENVIROMENTAL SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
void EnvironmentalDamage(EnviromentalDamage type, uint32 damage);
|
||||
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage);
|
||||
|
||||
/*********************************************************/
|
||||
/*** FLOOD FILTER SYSTEM ***/
|
||||
|
|
@ -2364,10 +2364,10 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
float m_auraBaseMod[BASEMOD_END][MOD_END];
|
||||
int16 m_baseRatingValue[MAX_COMBAT_RATING];
|
||||
uint16 m_baseSpellDamage;
|
||||
uint16 m_baseSpellHealing;
|
||||
uint16 m_baseSpellPower;
|
||||
uint16 m_baseFeralAP;
|
||||
uint16 m_baseManaRegen;
|
||||
float m_armorPenetrationPct;
|
||||
|
||||
SpellModList m_spellMods[MAX_SPELLMOD];
|
||||
int32 m_SpellModRemoveCount;
|
||||
|
|
|
|||
|
|
@ -179,11 +179,6 @@ enum SpellSchoolMask
|
|||
SPELL_SCHOOL_MASK_ALL = ( SPELL_SCHOOL_MASK_NORMAL | SPELL_SCHOOL_MASK_MAGIC )
|
||||
};
|
||||
|
||||
#define SPELL_SCHOOL_MASK_MAGIC \
|
||||
( SPELL_SCHOOL_MASK_HOLY | SPELL_SCHOOL_MASK_FIRE | SPELL_SCHOOL_MASK_NATURE | \
|
||||
SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW | \
|
||||
SPELL_SCHOOL_MASK_ARCANE )
|
||||
|
||||
inline SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
|
||||
{
|
||||
for(int i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
|
|
@ -422,7 +417,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
|
|||
#define SPELL_ATTR_EX5_UNK31 0x80000000 // 31 Forces all nearby enemies to focus attacks caster
|
||||
|
||||
#define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag
|
||||
#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_ONLY_IN_ARENA 0x00000002 // 1 only usable in arena, not used in 3.2.0a and early
|
||||
#define SPELL_ATTR_EX6_UNK2 0x00000004 // 2
|
||||
#define SPELL_ATTR_EX6_UNK3 0x00000008 // 3
|
||||
#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4
|
||||
|
|
@ -432,7 +427,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = {
|
|||
#define SPELL_ATTR_EX6_UNK8 0x00000100 // 8
|
||||
#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9
|
||||
#define SPELL_ATTR_EX6_UNK10 0x00000400 // 10
|
||||
#define SPELL_ATTR_EX6_UNK11 0x00000800 // 11
|
||||
#define SPELL_ATTR_EX6_NOT_IN_RAID_INSTANCE 0x00000800 // 11 not usable in raid instance
|
||||
#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12
|
||||
#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13
|
||||
#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select
|
||||
&Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
|
||||
&Aura::HandleNULL, //279 visual effects? 58836 and 57507
|
||||
&Aura::HandleNULL, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
|
||||
&Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
|
||||
&Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN
|
||||
&Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
|
||||
&Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
|
||||
|
|
@ -7287,3 +7287,11 @@ bool Aura::IsCritFromAbilityAura(Unit* caster, uint32& damage)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Aura::HandleModTargetArmorPct(bool apply, bool Real)
|
||||
{
|
||||
if(m_target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
((Player*)m_target)->UpdateArmorPenetration();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
|
||||
void HandleNoReagentUseAura(bool Apply, bool Real);
|
||||
void HandlePhase(bool Apply, bool Real);
|
||||
void HandleModTargetArmorPct(bool Apply, bool Real);
|
||||
|
||||
virtual ~Aura();
|
||||
|
||||
|
|
|
|||
|
|
@ -5102,7 +5102,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
|||
return;
|
||||
}
|
||||
case 55693: // Remove Collapsing Cave Aura
|
||||
if(unitTarget)
|
||||
if(!unitTarget)
|
||||
return;
|
||||
unitTarget->RemoveAurasDueToSpell(m_spellInfo->CalculateSimpleValue(effIndex));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -708,8 +708,6 @@ void SpellMgr::LoadSpellTargetPositions()
|
|||
|
||||
bar.step();
|
||||
|
||||
++count;
|
||||
|
||||
uint32 Spell_ID = fields[0].GetUInt32();
|
||||
|
||||
SpellTargetPosition st;
|
||||
|
|
@ -756,6 +754,7 @@ void SpellMgr::LoadSpellTargetPositions()
|
|||
}
|
||||
|
||||
mSpellTargetPositions[Spell_ID] = st;
|
||||
++count;
|
||||
|
||||
} while( result->NextRow() );
|
||||
|
||||
|
|
@ -2747,7 +2746,7 @@ SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spell
|
|||
while (groupEntry)
|
||||
{
|
||||
for (uint32 i=0; i<6; ++i)
|
||||
if( groupEntry->AreaId[i] == zone_id || groupEntry->AreaId[i] == area_id )
|
||||
if (groupEntry->AreaId[i] == zone_id || groupEntry->AreaId[i] == area_id)
|
||||
found = true;
|
||||
if (found || !groupEntry->nextGroup)
|
||||
break;
|
||||
|
|
@ -2755,7 +2754,7 @@ SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spell
|
|||
groupEntry = sAreaGroupStore.LookupEntry(groupEntry->nextGroup);
|
||||
}
|
||||
|
||||
if(!found)
|
||||
if (!found)
|
||||
return SPELL_FAILED_INCORRECT_AREA;
|
||||
}
|
||||
|
||||
|
|
@ -2764,10 +2763,18 @@ SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spell
|
|||
{
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
|
||||
if(!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
|
||||
if (!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
|
||||
return SPELL_FAILED_INCORRECT_AREA;
|
||||
}
|
||||
|
||||
// raid instance limitation
|
||||
if (spellInfo->AttributesEx6 & SPELL_ATTR_EX6_NOT_IN_RAID_INSTANCE)
|
||||
{
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
|
||||
if (!mapEntry || mapEntry->IsRaid())
|
||||
return SPELL_FAILED_NOT_IN_RAID_INSTANCE;
|
||||
}
|
||||
|
||||
// DB base check (if non empty then must fit at least single for allow)
|
||||
SpellAreaMapBounds saBounds = spellmgr.GetSpellAreaMapBounds(spellInfo->Id);
|
||||
if (saBounds.first != saBounds.second)
|
||||
|
|
|
|||
|
|
@ -91,17 +91,12 @@ bool Player::UpdateStats(Stats stat)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Player::ApplySpellDamageBonus(int32 amount, bool apply)
|
||||
void Player::ApplySpellPowerBonus(int32 amount, bool apply)
|
||||
{
|
||||
m_baseSpellDamage+=apply?amount:-amount;
|
||||
m_baseSpellPower+=apply?amount:-amount;
|
||||
|
||||
// For speed just update for client
|
||||
ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply);
|
||||
}
|
||||
|
||||
void Player::ApplySpellHealingBonus(int32 amount, bool apply)
|
||||
{
|
||||
m_baseSpellHealing+=apply?amount:-amount;
|
||||
// For speed just update for client
|
||||
for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, amount, apply);;
|
||||
}
|
||||
|
|
@ -137,6 +132,7 @@ bool Player::UpdateAllStats()
|
|||
UpdateAllSpellCritChances();
|
||||
UpdateDefenseBonusesMod();
|
||||
UpdateShieldBlockValue();
|
||||
UpdateArmorPenetration();
|
||||
UpdateSpellDamageAndHealingBonus();
|
||||
UpdateManaRegen();
|
||||
UpdateExpertise(BASE_ATTACK);
|
||||
|
|
@ -653,6 +649,33 @@ void Player::UpdateExpertise(WeaponAttackType attack)
|
|||
}
|
||||
}
|
||||
|
||||
void Player::UpdateArmorPenetration()
|
||||
{
|
||||
m_armorPenetrationPct = GetRatingBonusValue(CR_ARMOR_PENETRATION);
|
||||
|
||||
AuraList const& armorAuras = GetAurasByType(SPELL_AURA_MOD_TARGET_ARMOR_PCT);
|
||||
for(AuraList::const_iterator itr = armorAuras.begin(); itr != armorAuras.end(); ++itr)
|
||||
{
|
||||
// affects all weapons
|
||||
if((*itr)->GetSpellProto()->EquippedItemClass == -1)
|
||||
{
|
||||
m_armorPenetrationPct += (*itr)->GetModifier()->m_amount;
|
||||
continue;
|
||||
}
|
||||
|
||||
// dependent on weapon class
|
||||
for(uint8 i = 0; i < MAX_ATTACK; ++i)
|
||||
{
|
||||
Item *weapon = GetWeaponForAttack(WeaponAttackType(i));
|
||||
if(weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto()))
|
||||
{
|
||||
m_armorPenetrationPct += (*itr)->GetModifier()->m_amount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ApplyManaRegenBonus(int32 amount, bool apply)
|
||||
{
|
||||
m_baseManaRegen+= apply ? amount : -amount;
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
|||
return true;
|
||||
|
||||
// prevent movement while casting spells with cast time or channel time
|
||||
if ( owner.IsNonMeleeSpellCasted(false, false, true))
|
||||
if (owner.IsNonMeleeSpellCasted(false, false, true))
|
||||
{
|
||||
if (!owner.IsStopped())
|
||||
owner.StopMoving();
|
||||
|
|
@ -149,9 +149,9 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
|||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
if( !i_destinationHolder.HasDestination() )
|
||||
if (!i_destinationHolder.HasDestination())
|
||||
_setTargetLocation(owner);
|
||||
if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
|
||||
if (owner.IsStopped() && !i_destinationHolder.HasArrived())
|
||||
{
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
|
|
@ -172,16 +172,16 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
|||
//More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
|
||||
// try to counter precision differences
|
||||
if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
|
||||
if (i_destinationHolder.GetDistance3dFromDestSq(*i_target.getTarget()) >= dist * dist)
|
||||
{
|
||||
owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
|
||||
_setTargetLocation(owner); //Calculate New Dest and Send data To Player
|
||||
}
|
||||
// Update the Angle of the target only for Map::, no need to send packet for player
|
||||
else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) )
|
||||
else if (!i_angle && !owner.HasInArc(0.01f, i_target.getTarget()))
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
|
||||
if ((owner.IsStopped() && !i_destinationHolder.HasArrived()) || i_recalculateTravel)
|
||||
{
|
||||
i_recalculateTravel = false;
|
||||
//Angle update will take place into owner.StopMoving()
|
||||
|
|
|
|||
|
|
@ -1565,26 +1565,29 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)
|
|||
{
|
||||
uint32 newdamage = 0;
|
||||
float armor = pVictim->GetArmor();
|
||||
|
||||
// Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
|
||||
armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
|
||||
|
||||
// Apply Player CR_ARMOR_PENETRATION rating
|
||||
// Apply Player CR_ARMOR_PENETRATION rating and percent talents
|
||||
if (GetTypeId()==TYPEID_PLAYER)
|
||||
armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f;
|
||||
armor *= 1.0f - ((Player*)this)->GetArmorPenetrationPct() / 100.0f;
|
||||
|
||||
if (armor < 0.0f) armor=0.0f;
|
||||
if (armor < 0.0f)
|
||||
armor = 0.0f;
|
||||
|
||||
float levelModifier = getLevel();
|
||||
if ( levelModifier > 59 )
|
||||
if (levelModifier > 59)
|
||||
levelModifier = levelModifier + (4.5f * (levelModifier-59));
|
||||
|
||||
float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40);
|
||||
tmpvalue = tmpvalue/(1.0f + tmpvalue);
|
||||
|
||||
if(tmpvalue < 0.0f)
|
||||
if (tmpvalue < 0.0f)
|
||||
tmpvalue = 0.0f;
|
||||
if(tmpvalue > 0.75f)
|
||||
if (tmpvalue > 0.75f)
|
||||
tmpvalue = 0.75f;
|
||||
|
||||
newdamage = uint32(damage - (damage * tmpvalue));
|
||||
|
||||
return (newdamage > 1) ? newdamage : 1;
|
||||
|
|
@ -6288,10 +6291,10 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
// Set trigger spell id, target, custom basepoints
|
||||
uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()];
|
||||
Unit* target = NULL;
|
||||
int32 basepoints0 = 0;
|
||||
int32 basepoints[3] = {0, 0, 0};
|
||||
|
||||
if(triggeredByAura->GetModifier()->m_auraname == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE)
|
||||
basepoints0 = triggerAmount;
|
||||
basepoints[0] = triggerAmount;
|
||||
|
||||
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
|
||||
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
|
||||
|
|
@ -6329,7 +6332,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
|
||||
{
|
||||
// Pct value stored in dummy
|
||||
basepoints0 = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100;
|
||||
basepoints[0] = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100;
|
||||
target = pVictim;
|
||||
break;
|
||||
}
|
||||
|
|
@ -6499,7 +6502,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
{
|
||||
int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this);
|
||||
// Drain Soul
|
||||
CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
|
||||
CastCustomSpell(this, 18371, &basepoints[0], NULL, NULL, true, castItem, triggeredByAura);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -6545,7 +6548,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id);
|
||||
return false;
|
||||
}
|
||||
basepoints0 = damage * triggerAmount / 100 / 3;
|
||||
basepoints[0] = damage * triggerAmount / 100 / 3;
|
||||
target = this;
|
||||
}
|
||||
break;
|
||||
|
|
@ -6574,7 +6577,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
{
|
||||
if (triggerAmount == 0)
|
||||
return false;
|
||||
basepoints0 = triggerAmount * GetMaxHealth() / 100;
|
||||
basepoints[0] = triggerAmount * GetMaxHealth() / 100;
|
||||
trigger_spell_id = 34299;
|
||||
}
|
||||
break;
|
||||
|
|
@ -6643,7 +6646,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
}
|
||||
// percent stored in effect 1 (class scripts) base points
|
||||
int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100;
|
||||
basepoints0 = cost*auraSpellInfo->CalculateSimpleValue(1)/100;
|
||||
basepoints[0] = cost*auraSpellInfo->CalculateSimpleValue(1)/100;
|
||||
trigger_spell_id = 20272;
|
||||
target = this;
|
||||
}
|
||||
|
|
@ -6732,7 +6735,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
{
|
||||
if(!procSpell)
|
||||
return false;
|
||||
basepoints0 = procSpell->manaCost * 35 / 100;
|
||||
basepoints[0] = procSpell->manaCost * 35 / 100;
|
||||
trigger_spell_id = 23571;
|
||||
target = this;
|
||||
}
|
||||
|
|
@ -6746,7 +6749,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
if(pVictim && pVictim->isAlive())
|
||||
pVictim->getThreatManager().modifyThreatPercent(this,-10);
|
||||
|
||||
basepoints0 = triggerAmount * GetMaxHealth() / 100;
|
||||
basepoints[0] = triggerAmount * GetMaxHealth() / 100;
|
||||
trigger_spell_id = 31616;
|
||||
target = this;
|
||||
}
|
||||
|
|
@ -6781,7 +6784,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
if (!((Player*)this)->isHonorOrXPTarget(pVictim))
|
||||
return false;
|
||||
trigger_spell_id = 50475;
|
||||
basepoints0 = damage * triggerAmount / 100;
|
||||
basepoints[0] = damage * triggerAmount / 100;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -6811,7 +6814,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
// This spell originally trigger 13567 - Dummy Trigger (vs dummy efect)
|
||||
case 26467:
|
||||
{
|
||||
basepoints0 = damage * 15 / 100;
|
||||
basepoints[0] = damage * 15 / 100;
|
||||
target = pVictim;
|
||||
trigger_spell_id = 26470;
|
||||
break;
|
||||
|
|
@ -6917,13 +6920,13 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
// Bloodthirst (($m/100)% of max health)
|
||||
case 23880:
|
||||
{
|
||||
basepoints0 = int32(GetMaxHealth() * triggerAmount / 100);
|
||||
basepoints[0] = int32(GetMaxHealth() * triggerAmount / 100);
|
||||
break;
|
||||
}
|
||||
// Shamanistic Rage triggered spell
|
||||
case 30824:
|
||||
{
|
||||
basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100);
|
||||
basepoints[0] = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100);
|
||||
break;
|
||||
}
|
||||
// Enlightenment (trigger only from mana cost spells)
|
||||
|
|
@ -6933,6 +6936,34 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
return false;
|
||||
break;
|
||||
}
|
||||
// Demonic Pact
|
||||
case 48090:
|
||||
{
|
||||
// As the spell is proced from pet's attack - find owner
|
||||
Unit* owner = GetOwner();
|
||||
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
|
||||
// This spell doesn't stack, but refreshes duration. So we receive current bonuses to minus them later.
|
||||
int32 curBonus = 0;
|
||||
if (Aura* aur = owner->GetAura(48090,0))
|
||||
curBonus = aur->GetModifier()->m_amount;
|
||||
int32 spellDamage = owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_MAGIC) - curBonus;
|
||||
if(spellDamage <= 0)
|
||||
return false;
|
||||
|
||||
// percent stored in owner talent dummy
|
||||
AuraList const& dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
for (AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i)
|
||||
{
|
||||
if ((*i)->GetSpellProto()->SpellIconID == 3220)
|
||||
{
|
||||
basepoints[0] = basepoints[1] = int32(spellDamage * (*i)->GetModifier()->m_amount / 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Sword and Board
|
||||
case 50227:
|
||||
{
|
||||
|
|
@ -7018,8 +7049,12 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
if(!target || target!=this && !target->isAlive())
|
||||
return false;
|
||||
|
||||
if(basepoints0)
|
||||
CastCustomSpell(target,trigger_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
|
||||
if(basepoints[0] || basepoints[1] || basepoints[2])
|
||||
CastCustomSpell(target,trigger_spell_id,
|
||||
basepoints[0] ? &basepoints[0] : NULL,
|
||||
basepoints[1] ? &basepoints[1] : NULL,
|
||||
basepoints[2] ? &basepoints[2] : NULL,
|
||||
true,castItem,triggeredByAura);
|
||||
else
|
||||
CastSpell(target,trigger_spell_id,true,castItem,triggeredByAura);
|
||||
|
||||
|
|
@ -8267,7 +8302,7 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
|
|||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// Base value
|
||||
DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellDamageBonus();
|
||||
DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellPowerBonus();
|
||||
|
||||
// Damage bonus from stats
|
||||
AuraList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
|
||||
|
|
@ -8714,7 +8749,7 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
|
|||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// Base value
|
||||
AdvertisedBenefit +=((Player*)this)->GetBaseSpellHealingBonus();
|
||||
AdvertisedBenefit +=((Player*)this)->GetBaseSpellPowerBonus();
|
||||
|
||||
// Healing bonus from stats
|
||||
AuraList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
|
||||
|
|
@ -9169,8 +9204,13 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
|
|||
if(isCharmed() || (GetTypeId()!=TYPEID_PLAYER && ((Creature*)this)->isPet()))
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT);
|
||||
|
||||
if(creatureNotInCombat && ((Creature*)this)->AI())
|
||||
if (creatureNotInCombat)
|
||||
{
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
|
||||
if (((Creature*)this)->AI())
|
||||
((Creature*)this)->AI()->EnterCombat(enemy);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::ClearInCombat()
|
||||
|
|
@ -9182,8 +9222,13 @@ void Unit::ClearInCombat()
|
|||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT);
|
||||
|
||||
// Player's state will be cleared in Player::UpdateContestedPvP
|
||||
if(GetTypeId()!=TYPEID_PLAYER)
|
||||
if (GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
if (((Creature*)this)->GetCreatureInfo()->unit_flags & UNIT_FLAG_OOC_NOT_ATTACKABLE)
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
|
||||
clearUnitState(UNIT_STAT_ATTACK_PLAYER);
|
||||
}
|
||||
else
|
||||
((Player*)this)->UpdatePotionCooldown();
|
||||
}
|
||||
|
|
@ -9193,7 +9238,11 @@ bool Unit::isTargetableForAttack() const
|
|||
if (GetTypeId()==TYPEID_PLAYER && ((Player *)this)->isGameMaster())
|
||||
return false;
|
||||
|
||||
if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
|
||||
return false;
|
||||
|
||||
// to be removed if unit by any reason enter combat
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
||||
return false;
|
||||
|
||||
return IsInWorld() && isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/;
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ enum UnitFlags
|
|||
UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP
|
||||
UNIT_FLAG_UNK_6 = 0x00000040,
|
||||
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
|
||||
UNIT_FLAG_UNK_8 = 0x00000100, // 2.0.8
|
||||
UNIT_FLAG_OOC_NOT_ATTACKABLE = 0x00000100, // 2.0.8 - (OOC Out Of Combat) Can not be attacked when not in combat. Removed if unit for some reason enter combat.
|
||||
UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything
|
||||
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
|
||||
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
|
||||
|
|
@ -515,7 +515,7 @@ enum UnitFlags
|
|||
UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
|
||||
UNIT_FLAG_CONFUSED = 0x00400000,
|
||||
UNIT_FLAG_FLEEING = 0x00800000,
|
||||
UNIT_FLAG_PLAYER_CONTROLLED= 0x01000000, // used in spell Eyes of the Beast for pet... let attack by controlled creature
|
||||
UNIT_FLAG_PLAYER_CONTROLLED = 0x01000000, // used in spell Eyes of the Beast for pet... let attack by controlled creature
|
||||
UNIT_FLAG_NOT_SELECTABLE = 0x02000000,
|
||||
UNIT_FLAG_SKINNABLE = 0x04000000,
|
||||
UNIT_FLAG_MOUNT = 0x08000000,
|
||||
|
|
|
|||
|
|
@ -112,8 +112,9 @@ World::~World()
|
|||
|
||||
m_weathers.clear();
|
||||
|
||||
while (!cliCmdQueue.empty())
|
||||
delete cliCmdQueue.next();
|
||||
CliCommandHolder* command;
|
||||
while (cliCmdQueue.next(command))
|
||||
delete command;
|
||||
|
||||
VMAP::VMapFactory::clear();
|
||||
|
||||
|
|
@ -2004,11 +2005,9 @@ void World::SendServerMessage(ServerMessageType type, const char *text, Player*
|
|||
void World::UpdateSessions( uint32 diff )
|
||||
{
|
||||
///- Add new sessions
|
||||
while(!addSessQueue.empty())
|
||||
{
|
||||
WorldSession* sess = addSessQueue.next ();
|
||||
WorldSession* sess;
|
||||
while(addSessQueue.next(sess))
|
||||
AddSession_ (sess);
|
||||
}
|
||||
|
||||
///- Then send an update signal to remaining ones
|
||||
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
|
||||
|
|
@ -2032,24 +2031,19 @@ void World::UpdateSessions( uint32 diff )
|
|||
// This handles the issued and queued CLI commands
|
||||
void World::ProcessCliCommands()
|
||||
{
|
||||
if (cliCmdQueue.empty())
|
||||
return;
|
||||
CliCommandHolder::Print* zprint = NULL;
|
||||
|
||||
CliCommandHolder::Print* zprint;
|
||||
|
||||
while (!cliCmdQueue.empty())
|
||||
CliCommandHolder* command;
|
||||
while (cliCmdQueue.next(command))
|
||||
{
|
||||
sLog.outDebug("CLI command under processing...");
|
||||
CliCommandHolder *command = cliCmdQueue.next();
|
||||
|
||||
zprint = command->m_print;
|
||||
|
||||
CliHandler(zprint).ParseCommands(command->m_command);
|
||||
|
||||
delete command;
|
||||
}
|
||||
|
||||
// print the console message here so it looks right
|
||||
if (zprint)
|
||||
zprint("mangos>");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,11 +69,9 @@ WorldSession::~WorldSession()
|
|||
}
|
||||
|
||||
///- empty incoming packet queue
|
||||
while(!_recvQueue.empty())
|
||||
{
|
||||
WorldPacket *packet = _recvQueue.next ();
|
||||
WorldPacket* packet;
|
||||
while(_recvQueue.next(packet))
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const
|
||||
|
|
@ -163,10 +161,9 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
{
|
||||
///- Retrieve packets from the receive queue and call the appropriate handlers
|
||||
/// not proccess packets if socket already closed
|
||||
while (!_recvQueue.empty() && m_Socket && !m_Socket->IsClosed ())
|
||||
WorldPacket* packet;
|
||||
while (_recvQueue.next(packet) && m_Socket && !m_Socket->IsClosed ())
|
||||
{
|
||||
WorldPacket *packet = _recvQueue.next();
|
||||
|
||||
/*#if 1
|
||||
sLog.outError( "MOEP: %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
|
|
|
|||
|
|
@ -766,7 +766,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
|||
LocaleConstant locale;
|
||||
std::string account;
|
||||
Sha1Hash sha1;
|
||||
BigNumber v, s, g, N, x, I;
|
||||
BigNumber v, s, g, N;
|
||||
WorldPacket packet, SendAddonPacked;
|
||||
|
||||
BigNumber K;
|
||||
|
|
@ -799,12 +799,11 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
|||
"sessionkey, " //2
|
||||
"last_ip, " //3
|
||||
"locked, " //4
|
||||
"sha_pass_hash, " //5
|
||||
"v, " //6
|
||||
"s, " //7
|
||||
"expansion, " //8
|
||||
"mutetime, " //9
|
||||
"locale " //10
|
||||
"v, " //5
|
||||
"s, " //6
|
||||
"expansion, " //7
|
||||
"mutetime, " //8
|
||||
"locale " //9
|
||||
"FROM account "
|
||||
"WHERE username = '%s'",
|
||||
safe_account.c_str ());
|
||||
|
|
@ -823,57 +822,21 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
|||
|
||||
Field* fields = result->Fetch ();
|
||||
|
||||
expansion = ((sWorld.getConfig(CONFIG_EXPANSION) > fields[8].GetUInt8()) ? fields[8].GetUInt8() : sWorld.getConfig(CONFIG_EXPANSION));
|
||||
expansion = ((sWorld.getConfig(CONFIG_EXPANSION) > fields[7].GetUInt8()) ? fields[7].GetUInt8() : sWorld.getConfig(CONFIG_EXPANSION));
|
||||
|
||||
N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
|
||||
g.SetDword (7);
|
||||
I.SetHexStr (fields[5].GetString ());
|
||||
|
||||
//In case of leading zeros in the I hash, restore them
|
||||
uint8 mDigest[SHA_DIGEST_LENGTH];
|
||||
memset (mDigest, 0, SHA_DIGEST_LENGTH);
|
||||
|
||||
if (I.GetNumBytes () <= SHA_DIGEST_LENGTH)
|
||||
memcpy (mDigest, I.AsByteArray (), I.GetNumBytes ());
|
||||
|
||||
std::reverse (mDigest, mDigest + SHA_DIGEST_LENGTH);
|
||||
|
||||
s.SetHexStr (fields[7].GetString ());
|
||||
sha1.UpdateData (s.AsByteArray (), s.GetNumBytes ());
|
||||
sha1.UpdateData (mDigest, SHA_DIGEST_LENGTH);
|
||||
sha1.Finalize ();
|
||||
x.SetBinary (sha1.GetDigest (), sha1.GetLength ());
|
||||
v = g.ModExp (x, N);
|
||||
v.SetHexStr(fields[5].GetString());
|
||||
s.SetHexStr (fields[6].GetString ());
|
||||
|
||||
const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free()
|
||||
const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free()
|
||||
const char* vold = fields[6].GetString ();
|
||||
|
||||
DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v_old: %s v_new: %s",
|
||||
DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s",
|
||||
sStr,
|
||||
vold,
|
||||
vStr);
|
||||
|
||||
loginDatabase.PExecute ("UPDATE account "
|
||||
"SET "
|
||||
"v = '0', "
|
||||
"s = '0' "
|
||||
"WHERE username = '%s'",
|
||||
safe_account.c_str ());
|
||||
|
||||
if (!vold || strcmp (vStr, vold))
|
||||
{
|
||||
packet.Initialize (SMSG_AUTH_RESPONSE, 1);
|
||||
packet << uint8 (AUTH_UNKNOWN_ACCOUNT);
|
||||
SendPacket (packet);
|
||||
delete result;
|
||||
OPENSSL_free ((void*) sStr);
|
||||
OPENSSL_free ((void*) vStr);
|
||||
|
||||
sLog.outBasic ("WorldSocket::HandleAuthSession: User not logged.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
OPENSSL_free ((void*) sStr);
|
||||
OPENSSL_free ((void*) vStr);
|
||||
|
||||
|
|
@ -899,9 +862,9 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
|||
|
||||
K.SetHexStr (fields[2].GetString ());
|
||||
|
||||
time_t mutetime = time_t (fields[9].GetUInt64 ());
|
||||
time_t mutetime = time_t (fields[8].GetUInt64 ());
|
||||
|
||||
locale = LocaleConstant (fields[10].GetUInt8 ());
|
||||
locale = LocaleConstant (fields[9].GetUInt8 ());
|
||||
if (locale >= MAX_LOCALE)
|
||||
locale = LOCALE_enUS;
|
||||
|
||||
|
|
@ -909,13 +872,10 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
|||
|
||||
// Re-check account ban (same check as in realmd)
|
||||
QueryResult *banresult =
|
||||
loginDatabase.PQuery ("SELECT "
|
||||
"bandate, "
|
||||
"unbandate "
|
||||
"FROM account_banned "
|
||||
"WHERE id = '%u' "
|
||||
"AND active = 1",
|
||||
id);
|
||||
loginDatabase.PQuery ("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 "
|
||||
"UNION "
|
||||
"SELECT 1 FROM ip_banned WHERE ip = '%s'",
|
||||
id, GetRemoteAddress().c_str());
|
||||
|
||||
if (banresult) // if account banned
|
||||
{
|
||||
|
|
|
|||
|
|
@ -246,7 +246,6 @@ void AuthSocket::OnAccept()
|
|||
sLog.outBasic("Accepting connection from '%s:%d'",
|
||||
GetRemoteAddress().c_str(), GetRemotePort());
|
||||
|
||||
s.SetRand(s_BYTE_SIZE * 8);
|
||||
}
|
||||
|
||||
/// Read the packet from the client
|
||||
|
|
@ -295,6 +294,8 @@ void AuthSocket::OnRead()
|
|||
/// Make the SRP6 calculation from hash in dB
|
||||
void AuthSocket::_SetVSFields(const std::string& rI)
|
||||
{
|
||||
s.SetRand(s_BYTE_SIZE * 8);
|
||||
|
||||
BigNumber I;
|
||||
I.SetHexStr(rI.c_str());
|
||||
|
||||
|
|
@ -396,7 +397,7 @@ bool AuthSocket::_HandleLogonChallenge()
|
|||
///- Get the account details from the account table
|
||||
// No SQL injection (escaped user name)
|
||||
|
||||
result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ());
|
||||
result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel,v,s FROM account WHERE username = '%s'",_safelogin.c_str ());
|
||||
if( result )
|
||||
{
|
||||
///- If the IP is 'locked', check that the player comes indeed from the correct IP address
|
||||
|
|
@ -446,7 +447,21 @@ bool AuthSocket::_HandleLogonChallenge()
|
|||
{
|
||||
///- Get the password from the account table, upper it, and make the SRP6 calculation
|
||||
std::string rI = (*result)[0].GetCppString();
|
||||
|
||||
///- Don't calculate (v, s) if there are already some in the database
|
||||
std::string databaseV = (*result)[5].GetCppString();
|
||||
std::string databaseS = (*result)[6].GetCppString();
|
||||
|
||||
sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());
|
||||
|
||||
// multiply with 2, bytes are stored as hexstring
|
||||
if(databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2)
|
||||
_SetVSFields(rI);
|
||||
else
|
||||
{
|
||||
s.SetHexStr(databaseS.c_str());
|
||||
v.SetHexStr(databaseV.c_str());
|
||||
}
|
||||
|
||||
b.SetRand(19 * 8);
|
||||
BigNumber gmod = g.ModExp(b, N);
|
||||
|
|
@ -591,8 +606,13 @@ bool AuthSocket::_HandleLogonProof()
|
|||
|
||||
///- Continue the SRP6 calculation based on data received from the client
|
||||
BigNumber A;
|
||||
|
||||
A.SetBinary(lp.A, 32);
|
||||
|
||||
// SRP safeguard: abort if A==0
|
||||
if (A.isZero())
|
||||
return false;
|
||||
|
||||
Sha1Hash sha;
|
||||
sha.UpdateBigNumbers(&A, &B, NULL);
|
||||
sha.Finalize();
|
||||
|
|
@ -603,7 +623,7 @@ bool AuthSocket::_HandleLogonProof()
|
|||
uint8 t[32];
|
||||
uint8 t1[16];
|
||||
uint8 vK[40];
|
||||
memcpy(t, S.AsByteArray(), 32);
|
||||
memcpy(t, S.AsByteArray(32), 32);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
t1[i] = t[i * 2];
|
||||
|
|
@ -905,8 +925,6 @@ bool AuthSocket::_HandleRealmList()
|
|||
|
||||
SendBuf((char const*)hdr.contents(), hdr.size());
|
||||
|
||||
// Set check field before possible relogin to realm
|
||||
_SetVSFields(rI);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ extern int main(int argc, char **argv)
|
|||
sLog.outError("Could not find configuration file %s.", cfg_file);
|
||||
return 1;
|
||||
}
|
||||
sLog.Initialize();
|
||||
|
||||
sLog.outString( "%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) );
|
||||
sLog.outString( "<Ctrl-C> to stop.\n" );
|
||||
|
|
|
|||
|
|
@ -159,6 +159,11 @@ uint32 BigNumber::AsDword()
|
|||
return (uint32)BN_get_word(_bn);
|
||||
}
|
||||
|
||||
bool BigNumber::isZero() const
|
||||
{
|
||||
return BN_is_zero(_bn)!=0;
|
||||
}
|
||||
|
||||
uint8 *BigNumber::AsByteArray(int minSize)
|
||||
{
|
||||
int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes();
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ class BigNumber
|
|||
return t %= bn;
|
||||
}
|
||||
|
||||
bool isZero() const;
|
||||
|
||||
BigNumber ModExp(const BigNumber &bn1, const BigNumber &bn2);
|
||||
BigNumber Exp(const BigNumber &);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ class Sha1Hash
|
|||
uint8 *GetDigest(void) { return mDigest; };
|
||||
int GetLength(void) { return SHA_DIGEST_LENGTH; };
|
||||
|
||||
BigNumber GetBigNumber();
|
||||
|
||||
private:
|
||||
SHA_CTX mC;
|
||||
uint8 mDigest[SHA_DIGEST_LENGTH];
|
||||
|
|
|
|||
|
|
@ -220,12 +220,12 @@ bool Database::CheckRequiredField( char const* table_name, char const* required_
|
|||
delete result;
|
||||
|
||||
if(!reqName.empty())
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` have field `%s` but expected `%s`! Not all sql updates applied?",table_name,reqName.c_str(),required_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
sLog.outErrorDb("Table `%s` not have required_* field but expected `%s`! Not all sql updates applied?",table_name,required_name);
|
||||
}
|
||||
else
|
||||
sLog.outErrorDb("Table `%s` fields list query fail but expected have `%s`! No records in `%s`?",table_name,required_name,table_name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@ SqlDelayThread::SqlDelayThread(Database* db) : m_dbEngine(db), m_running(true)
|
|||
|
||||
void SqlDelayThread::run()
|
||||
{
|
||||
SqlOperation* s;
|
||||
#ifndef DO_POSTGRESQL
|
||||
mysql_thread_init();
|
||||
#endif
|
||||
|
|
@ -36,9 +35,9 @@ void SqlDelayThread::run()
|
|||
// if the running state gets turned off while sleeping
|
||||
// empty the queue before exiting
|
||||
ACE_Based::Thread::Sleep(10);
|
||||
while (!m_sqlQueue.empty())
|
||||
SqlOperation* s;
|
||||
while (m_sqlQueue.next(s))
|
||||
{
|
||||
s = m_sqlQueue.next();
|
||||
s->Execute(m_dbEngine);
|
||||
delete s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,9 +71,9 @@ void SqlQuery::Execute(Database *db)
|
|||
void SqlResultQueue::Update()
|
||||
{
|
||||
/// execute the callbacks waiting in the synchronization queue
|
||||
while(!empty())
|
||||
MaNGOS::IQueryCallback* callback;
|
||||
while (next(callback))
|
||||
{
|
||||
MaNGOS::IQueryCallback * callback = next();
|
||||
callback->Execute();
|
||||
delete callback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,99 +30,65 @@ namespace ACE_Based
|
|||
template <class T, class LockType, typename StorageType=std::deque<T> >
|
||||
class LockedQueue
|
||||
{
|
||||
//! Serialize access to the Queue
|
||||
//! Lock access to the queue.
|
||||
LockType _lock;
|
||||
|
||||
//! Storage backing the queue
|
||||
//! Storage backing the queue.
|
||||
StorageType _queue;
|
||||
|
||||
//! Cancellation flag
|
||||
volatile bool _canceled;
|
||||
//! Cancellation flag.
|
||||
/*volatile*/ bool _canceled;
|
||||
|
||||
public:
|
||||
|
||||
//! Create a LockedQueue
|
||||
//! Create a LockedQueue.
|
||||
LockedQueue() : _canceled(false) {}
|
||||
|
||||
//! Destroy a LockedQueue
|
||||
//! Destroy a LockedQueue.
|
||||
virtual ~LockedQueue() { }
|
||||
|
||||
/**
|
||||
* @see Queue::add(const T& item)
|
||||
*/
|
||||
//! Adds an item to the queue.
|
||||
void add(const T& item)
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
|
||||
ASSERT(!this->_canceled);
|
||||
//ASSERT(!this->_canceled);
|
||||
// throw Cancellation_Exception();
|
||||
|
||||
this->_queue.push_back(item);
|
||||
_queue.push_back(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Queue::next()
|
||||
*/
|
||||
T next()
|
||||
//! Gets the next result in the queue, if any.
|
||||
bool next(T& result)
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
|
||||
ASSERT (!_queue.empty() || !this->_canceled);
|
||||
if (_queue.empty())
|
||||
return false;
|
||||
|
||||
//ASSERT (!_queue.empty() || !this->_canceled);
|
||||
// throw Cancellation_Exception();
|
||||
|
||||
T item = this->_queue.front();
|
||||
this->_queue.pop_front();
|
||||
result = _queue.front();
|
||||
_queue.pop_front();
|
||||
|
||||
return item;
|
||||
return true;
|
||||
}
|
||||
|
||||
T front()
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
|
||||
ASSERT (!this->_queue.empty());
|
||||
// throw NoSuchElement_Exception();
|
||||
|
||||
return this->_queue.front();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Queue::cancel()
|
||||
*/
|
||||
//! Cancels the queue.
|
||||
void cancel()
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
|
||||
this->_canceled = true;
|
||||
_canceled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Queue::isCanceled()
|
||||
*/
|
||||
bool isCanceled()
|
||||
{
|
||||
// Faster check since the queue will not become un-canceled
|
||||
if(this->_canceled)
|
||||
return true;
|
||||
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
|
||||
return this->_canceled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Queue::size()
|
||||
*/
|
||||
size_t size()
|
||||
//! Checks if the queue is cancelled.
|
||||
bool cancelled()
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
return this->_queue.size();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
return this->_queue.empty();
|
||||
return _canceled;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,3 +441,23 @@ void vutf8printf(FILE *out, const char *str, va_list* ap)
|
|||
vfprintf(out, str, *ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
for(uint32 i=0; i<arrayLen; ++i)
|
||||
{
|
||||
for(uint8 j=0; j<2; ++j)
|
||||
{
|
||||
unsigned char nibble = 0x0F & (bytes[i]>>((1-j)*4));
|
||||
char encodedNibble;
|
||||
if(nibble < 0x0A)
|
||||
encodedNibble = '0'+nibble;
|
||||
else
|
||||
encodedNibble = 'A'+nibble-0x0A;
|
||||
ss << encodedNibble;
|
||||
}
|
||||
}
|
||||
result = ss.str();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -289,4 +289,5 @@ void vutf8printf(FILE *out, const char *str, va_list* ap);
|
|||
bool IsIPAddress(char const* ipaddress);
|
||||
uint32 CreatePIDFile(const std::string& filename);
|
||||
|
||||
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "8441"
|
||||
#define REVISION_NR "8467"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_8433_01_characters_character_account_data"
|
||||
#define REVISION_DB_MANGOS "required_8416_01_mangos_spell_learn_spell"
|
||||
#define REVISION_DB_MANGOS "required_8462_01_mangos_creature_ai_texts"
|
||||
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue