aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorVincent_Michael <Vincent_Michael@gmx.de>2013-02-15 14:23:21 +0100
committerVincent_Michael <Vincent_Michael@gmx.de>2013-02-15 14:23:21 +0100
commit6beda05e3d5cdf77a49fa1fcdfd5e64070d7a10c (patch)
tree6106a48422550d02d501b276024c9c8306cff84e /src/server/game
parent3c5bf554ffa58e46eb88aebd46af21335d581432 (diff)
parent45363b8216f03f2dd4ce21cfb5ce183560374dd8 (diff)
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts: src/server/game/Handlers/CharacterHandler.cpp src/server/game/World/World.h
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp14
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp3
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp35
-rw-r--r--src/server/game/Maps/MapManager.cpp9
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp4
-rw-r--r--src/server/game/Server/WorldSession.h6
-rw-r--r--src/server/game/World/World.h2
9 files changed, 62 insertions, 15 deletions
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index a4716de9524..22b86a094dd 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -95,6 +95,20 @@ void LFGPlayerScript::OnMapChanged(Player* player)
if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficulty()))
{
Group* group = player->GetGroup();
+ // This function is also called when players log in
+ // if for some reason the LFG system recognises the player as being in a LFG dungeon,
+ // but the player was loaded without a valid group, we'll teleport to homebind to prevent
+ // crashes or other undefined behaviour
+ if (!group)
+ {
+ sLFGMgr->LeaveLfg(player->GetGUID());
+ player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW);
+ player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, 0.0f);
+ sLog->outError(LOG_FILTER_LFG, "LFGPlayerScript::OnMapChanged, Player %s (%u) is in LFG dungeon map but does not have a valid group! "
+ "Teleporting to homebind.", player->GetName().c_str(), player->GetGUIDLow());
+ return;
+ }
+
for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
if (Player* member = itr->getSource())
player->GetSession()->SendNameQueryOpcode(member->GetGUID());
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index fd87054b2d8..97d414b9915 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -290,7 +290,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data
}
// Initialize loot duplicate count depending on raid difficulty
- if (GetMap()->IsRaid() && GetMap()->GetSpawnMode() & RAID_DIFFICULTY_MASK_25MAN)
+ if (GetMap()->Is25ManRaid())
loot.maxDuplicates = 3;
SetEntry(Entry); // normal entry always
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 7f9e317c2d2..e333c8bb211 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -260,7 +260,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
AIM_Initialize();
// Initialize loot duplicate count depending on raid difficulty
- if (map->IsRaid() && map->GetSpawnMode() & RAID_DIFFICULTY_MASK_25MAN)
+ if (map->Is25ManRaid())
loot.maxDuplicates = 3;
return true;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a520ae67442..19de01ffd41 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7662,6 +7662,9 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
float posy = fields[2].GetFloat();
float posz = fields[3].GetFloat();
+ if (!sMapStore.LookupEntry(map))
+ return 0;
+
zone = sMapMgr->GetZoneId(map, posx, posy, posz);
if (zone > 0)
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index ace5a0b68eb..5dfba797448 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -229,7 +229,7 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result)
bitBuffer.WriteBit(1);
if (result)
{
- _allowedCharsToLogin.clear();
+ _legitCharacters.clear();
charCount = uint32(result->GetRowCount());
bitBuffer.reserve(24 * charCount / 8);
@@ -245,7 +245,9 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result)
Player::BuildEnumData(result, &dataBuffer, &bitBuffer);
- _allowedCharsToLogin.insert(guidLow);
+ _legitCharacters.insert(guidLow);
+ if (!sWorld->HasCharacterNameData(guidLow)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
+ sWorld->AddCharacterNameData(guidLow, (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[7].GetUInt8());
} while (result->NextRow());
bitBuffer.FlushBits();
@@ -800,7 +802,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
sLog->outDebug(LOG_FILTER_NETWORKIO, "Character (Guid: %u) logging in", GUID_LOPART(playerGuid));
- if (!CharCanLogin(GUID_LOPART(playerGuid)))
+ if (!IsLegitCharacterForAccount(GUID_LOPART(playerGuid)))
{
sLog->outError(LOG_FILTER_NETWORKIO, "Account (%u) can't login with that character (%u).", GetAccountId(), GUID_LOPART(playerGuid));
KickPlayer();
@@ -1473,6 +1475,15 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
std::string newName;
recvData >> guid;
+ if (!IsLegitCharacterForAccount(GUID_LOPART(guid)))
+ {
+ sLog->outError(LOG_FILTER_NETWORKIO, "Account %u, IP: %s tried to customise character %u, but it does not belong to their account!",
+ GetAccountId(), GetRemoteAddress().c_str(), GUID_LOPART(guid));
+ recvData.rfinish();
+ KickPlayer();
+ return;
+ }
+
recvData >> newName;
uint8 gender, skin, face, hairStyle, hairColor, facialHair;
@@ -1704,6 +1715,16 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
std::string newname;
uint8 gender, skin, face, hairStyle, hairColor, facialHair, race;
recvData >> guid;
+
+ if (!IsLegitCharacterForAccount(GUID_LOPART(guid)))
+ {
+ sLog->outError(LOG_FILTER_NETWORKIO, "Account %u, IP: %s tried to factionchange character %u, but it does not belong to their account!",
+ GetAccountId(), GetRemoteAddress().c_str(), GUID_LOPART(guid));
+ recvData.rfinish();
+ KickPlayer();
+ return;
+ }
+
recvData >> newname;
recvData >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face >> race;
@@ -1711,6 +1732,14 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
// get the players old (at this moment current) race
CharacterNameData const* nameData = sWorld->GetCharacterNameData(lowGuid);
+ if (!nameData)
+ {
+ WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1);
+ data << uint8(CHAR_CREATE_ERROR);
+ SendPacket(&data);
+ return;
+ }
+
uint8 oldRace = nameData->m_race;
uint8 playerClass = nameData->m_class;
uint8 level = nameData->m_level;
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index b42a2f3c0ed..32824addff2 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -105,16 +105,17 @@ Map* MapManager::CreateBaseMap(uint32 id)
{
TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- const MapEntry* entry = sMapStore.LookupEntry(id);
- if (entry && entry->Instanceable())
- {
+ MapEntry const* entry = sMapStore.LookupEntry(id);
+ ASSERT(entry);
+
+ if (entry->Instanceable())
map = new MapInstanced(id, i_gridCleanUpDelay);
- }
else
{
map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
map->LoadRespawnTimes();
}
+
i_maps[id] = map;
}
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 5a973395c68..dd479984178 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -489,14 +489,14 @@ void ScriptMgr::OnGroupRateCalculation(float& rate, uint32 count, bool isRaid)
}
#define SCR_MAP_BGN(M, V, I, E, C, T) \
- if (V->GetEntry()->T()) \
+ if (V->GetEntry() && V->GetEntry()->T()) \
{ \
FOR_SCRIPTS(M, I, E) \
{ \
MapEntry const* C = I->second->GetEntry(); \
if (!C) \
continue; \
- if (entry->MapID == V->GetId()) \
+ if (C->MapID == V->GetId()) \
{
#define SCR_MAP_END \
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 419de3a466e..70a405fd808 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -974,14 +974,14 @@ class WorldSession
void LogUnprocessedTail(WorldPacket* packet);
// EnumData helpers
- bool CharCanLogin(uint32 lowGUID)
+ bool IsLegitCharacterForAccount(uint32 lowGUID)
{
- return _allowedCharsToLogin.find(lowGUID) != _allowedCharsToLogin.end();
+ return _legitCharacters.find(lowGUID) != _legitCharacters.end();
}
// this stores the GUIDs of the characters who can login
// characters who failed on Player::BuildEnumData shouldn't login
- std::set<uint32> _allowedCharsToLogin;
+ std::set<uint32> _legitCharacters;
uint32 m_GUIDLow; // set loggined or recently logout player (while m_playerRecentlyLogout set)
Player* _player;
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 6c86057eefb..872a6c7afb3 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -753,8 +753,8 @@ class World
void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level);
void UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender = GENDER_NONE, uint8 race = RACE_NONE);
void UpdateCharacterNameDataLevel(uint32 guid, uint8 level);
-
void DeleteCharacterNameData(uint32 guid) { _characterNameDataMap.erase(guid); }
+ bool HasCharacterNameData(uint32 guid) { return _characterNameDataMap.find(guid) != _characterNameDataMap.end(); }
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }