aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKingPin <none@none>2008-11-10 09:04:23 -0600
committerKingPin <none@none>2008-11-10 09:04:23 -0600
commit09a0d1122afb5b97f36dbedf0f58fc10d1ad135a (patch)
treeea121fe9591077c9b5de6d58e51762a4dd84f6b3
parent09280b0091474b58d43daf42c0f3d99f86e6ec25 (diff)
[svn] * Improve some arena team related DB access
* Cache GM tickets on server startup. * Remove unused src/game/HateMatrix.h and references. * Better check client inventory pos data received in some client packets to skip invalid cases --HG-- branch : trunk
-rw-r--r--src/framework/Dynamic/ObjectRegistry.h1
-rw-r--r--src/game/ArenaTeam.cpp43
-rw-r--r--src/game/Chat.h1
-rw-r--r--src/game/CreatureAI.cpp3
-rw-r--r--src/game/GMTicketHandler.cpp181
-rw-r--r--src/game/GMTicketMgr.cpp82
-rw-r--r--src/game/GMTicketMgr.h118
-rw-r--r--src/game/HateMatrix.h86
-rw-r--r--src/game/ItemHandler.cpp42
-rw-r--r--src/game/Level2.cpp102
-rw-r--r--src/game/Makefile.am4
-rw-r--r--src/game/MiscHandler.cpp183
-rw-r--r--src/game/Object.h5
-rw-r--r--src/game/ObjectMgr.cpp12
-rw-r--r--src/game/Pet.cpp3
-rw-r--r--src/game/PetitionsHandler.cpp5
-rw-r--r--src/game/Player.cpp116
-rw-r--r--src/game/Player.h2
-rw-r--r--src/game/QueryHandler.cpp6
-rw-r--r--src/game/QuestHandler.cpp5
-rw-r--r--src/game/SpellAuras.cpp4
-rw-r--r--src/game/SpellEffects.cpp15
-rw-r--r--src/game/SpellHandler.cpp2
-rw-r--r--src/game/Transports.cpp3
-rw-r--r--src/game/WaypointManager.cpp8
-rw-r--r--src/game/World.cpp10
-rw-r--r--win/VC71/game.vcproj3
-rw-r--r--win/VC80/game.vcproj4
-rw-r--r--win/VC90/game.vcproj4
29 files changed, 611 insertions, 442 deletions
diff --git a/src/framework/Dynamic/ObjectRegistry.h b/src/framework/Dynamic/ObjectRegistry.h
index 83a99766e80..26cb8a8f144 100644
--- a/src/framework/Dynamic/ObjectRegistry.h
+++ b/src/framework/Dynamic/ObjectRegistry.h
@@ -26,6 +26,7 @@
#include "Policies/Singleton.h"
#include <string>
+#include <vector>
#include <map>
/** ObjectRegistry holds all registry item of the same type
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp
index e364f7a0e7e..8d89a841a2f 100644
--- a/src/game/ArenaTeam.cpp
+++ b/src/game/ArenaTeam.cpp
@@ -90,40 +90,45 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid)
std::string plName;
uint8 plClass;
+ // arena team is full (can't have more than type * 2 players!)
if(GetMembersSize() >= GetType() * 2)
- {
- // arena team is full (can't have more than type * 2 players!)
- // return false
return false;
- }
-
- if(!objmgr.GetPlayerNameByGUID(PlayerGuid, plName)) // player doesnt exist
- return false;
- // player already in arenateam of that size
- if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
- {
- sLog.outError("Arena::AddMember() : player already in this sized team");
- return false;
- }
-
- // remove all player signs from another petitions
- // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
- Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
Player *pl = objmgr.GetPlayer(PlayerGuid);
if(pl)
{
+ if(pl->GetArenaTeamId(GetType()))
+ {
+ sLog.outError("Arena::AddMember() : player already in this sized team");
+ return false;
+ }
+
plClass = (uint8)pl->getClass();
+ plName = pl->GetName();
}
else
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
+ // 0 1
+ QueryResult *result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
if(!result)
return false;
- plClass = (*result)[0].GetUInt8();
+
+ plName = (*result)[0].GetCppString();
+ plClass = (*result)[1].GetUInt8();
delete result;
+
+ // check if player already in arenateam of that size
+ if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
+ {
+ sLog.outError("Arena::AddMember() : player already in this sized team");
+ return false;
+ }
}
+ // remove all player signs from another petitions
+ // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
+ Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
+
ArenaTeamMember newmember;
newmember.name = plName;
newmember.guid = PlayerGuid;
diff --git a/src/game/Chat.h b/src/game/Chat.h
index d1adecaec7d..06e5f7be4ca 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -465,7 +465,6 @@ class ChatHandler
// Utility methods for commands
void ShowTicket(uint64 guid, char const* text, char const* time);
- uint32 GetTicketIDByNum(uint32 num);
bool LookupPlayerSearchCommand(QueryResult* result, int32 limit);
bool HandleBanListHelper(QueryResult* result);
bool HandleBanHelper(BanMode mode,char const* args);
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index e5fe2e30ea8..3cb8db202fa 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -19,10 +19,7 @@
*/
#include "CreatureAI.h"
-#include "HateMatrix.h"
CreatureAI::~CreatureAI()
{
}
-
-uint32 HateBinder::si_noHateValue=0;
diff --git a/src/game/GMTicketHandler.cpp b/src/game/GMTicketHandler.cpp
new file mode 100644
index 00000000000..8d16fe3697f
--- /dev/null
+++ b/src/game/GMTicketHandler.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS
+ *
+ * Copyright (C) 2008 Trinity
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Language.h"
+#include "WorldPacket.h"
+#include "Log.h"
+#include "GMTicketMgr.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "Chat.h"
+
+void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
+{
+ int len = text ? strlen(text) : 0;
+ WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
+ data << uint32(status); // standard 0x0A, 0x06 if text present
+ if(status == 6)
+ {
+ data << text; // ticket text
+ data << uint8(0x7); // ticket category
+ data << float(0); // time from ticket creation?
+ data << float(0); // const
+ data << float(0); // const
+ data << uint8(0); // const
+ data << uint8(0); // const
+ }
+ SendPacket( &data );
+}
+
+void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
+{
+ WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
+ data << (uint32)time(NULL);
+ data << (uint32)0;
+ SendPacket( &data );
+
+ GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow());
+ if(ticket)
+ SendGMTicketGetTicket(0x06,ticket->GetText());
+ else
+ SendGMTicketGetTicket(0x0A,0);
+}
+
+void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data,1);
+
+ std::string ticketText;
+ recv_data >> ticketText;
+
+ CharacterDatabase.escape_string(ticketText);
+
+ if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
+ ticket->SetText(ticketText.c_str());
+ else
+ sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
+}
+
+void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
+{
+ ticketmgr.Delete(GetPlayer()->GetGUIDLow());
+
+ WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
+ data << uint32(9);
+ SendPacket( &data );
+
+ SendGMTicketGetTicket(0x0A, 0);
+}
+
+void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
+
+ uint32 map;
+ float x, y, z;
+ std::string ticketText = "";
+ uint32 unk1, unk2;
+
+ recv_data >> map >> x >> y >> z; // last check 2.4.3
+ recv_data >> ticketText;
+
+ // recheck
+ CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
+
+ recv_data >> unk1 >> unk2;
+ // note: the packet might contain more data, but the exact structure of that is unknown
+
+ sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
+
+ CharacterDatabase.escape_string(ticketText);
+
+ if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
+ {
+ WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
+ data << uint32(1);
+ SendPacket( &data );
+ return;
+ }
+
+ ticketmgr.Create(_player->GetGUIDLow(), ticketText.c_str());
+
+ WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
+ data << (uint32)time(NULL);
+ data << (uint32)0;
+ SendPacket( &data );
+
+ data.Initialize( SMSG_GMTICKET_CREATE, 4 );
+ data << uint32(2);
+ SendPacket( &data );
+ DEBUG_LOG("update the ticket\n");
+
+ //TODO: Guard player map
+ HashMapHolder::MapType &m = ObjectAccessor::Instance().GetPlayers();
+ for(HashMapHolder::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
+ {
+ if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
+ ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
+ }
+}
+
+void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
+{
+ WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
+ data << uint32(1); // we can also disable ticket system by sending 0 value
+
+ SendPacket( &data );
+}
+
+void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
+{
+ // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
+ CHECK_PACKET_SIZE(recv_data,4+4);
+ uint32 x;
+ recv_data >> x; // answer range? (6 = 0-5?)
+ sLog.outDebug("SURVEY: X = %u", x);
+
+ uint8 result[10];
+ memset(result, 0, sizeof(result));
+ for( int i = 0; i < 10; ++i)
+ {
+ CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
+ uint32 questionID;
+ recv_data >> questionID; // GMSurveyQuestions.dbc
+ if (!questionID)
+ break;
+
+ CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
+ uint8 value;
+ std::string unk_text;
+ recv_data >> value; // answer
+ recv_data >> unk_text; // always empty?
+
+ result[i] = value;
+ sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
+ }
+
+ CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
+ std::string comment;
+ recv_data >> comment; // addional comment
+ sLog.outDebug("SURVEY: comment %s", comment.c_str());
+
+ // TODO: chart this data in some way
+}
diff --git a/src/game/GMTicketMgr.cpp b/src/game/GMTicketMgr.cpp
new file mode 100644
index 00000000000..623382628b7
--- /dev/null
+++ b/src/game/GMTicketMgr.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS
+ *
+ * Copyright (C) 2008 Trinity
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Database/DatabaseEnv.h"
+#include "Database/SQLStorage.h"
+#include "GMTicketMgr.h"
+#include "ObjectMgr.h"
+#include "ProgressBar.h"
+#include "Policies/SingletonImp.h"
+#include "Player.h"
+#include "ObjectDefines.h"
+
+INSTANTIATE_SINGLETON_1(GMTicketMgr);
+
+void GMTicketMgr::LoadGMTickets()
+{
+ m_GMTicketMap.clear(); // For reload case
+
+ QueryResult *result = CharacterDatabase.Query(
+ // 0 1 2
+ "SELECT guid, ticket_text,UNIX_TIMESTAMP(ticket_lastchange) FROM character_ticket");
+
+ if( !result )
+ {
+ barGoLink bar( 1 );
+
+ bar.step();
+
+ sLog.outString();
+ sLog.outErrorDb(">> Loaded `character_ticket`, table is empty!");
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+
+ uint32 count = 0;
+
+ do
+ {
+ bar.step();
+
+ Field* fields = result->Fetch();
+
+ uint32 guid = fields[0].GetUInt32();
+ m_GMTicketMap[guid] = GMTicket(guid, fields[1].GetCppString(), time_t(fields[2].GetUInt64()));
+ ++count;
+
+ } while (result->NextRow());
+ delete result;
+
+ sLog.outString();
+ sLog.outString( ">> Loaded %d GM tickets", count );
+}
+
+void GMTicketMgr::DeleteAll()
+{
+ for(GMTicketMap::iterator itr = m_GMTicketMap.begin(); itr != m_GMTicketMap.end(); ++itr)
+ {
+ if(Player* owner = objmgr.GetPlayer(MAKE_NEW_GUID(itr->first,0,HIGHGUID_PLAYER)))
+ owner->GetSession()->SendGMTicketGetTicket(0x0A,0);
+ }
+ CharacterDatabase.PExecute("DELETE FROM character_ticket");
+ m_GMTicketMap.clear();
+}
diff --git a/src/game/GMTicketMgr.h b/src/game/GMTicketMgr.h
new file mode 100644
index 00000000000..38ba9429990
--- /dev/null
+++ b/src/game/GMTicketMgr.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _GMTICKETMGR_H
+#define _GMTICKETMGR_H
+
+#include "Policies/Singleton.h"
+#include "Database/DatabaseEnv.h"
+#include "Util.h"
+#include <map>
+
+class GMTicket
+{
+ public:
+ explicit GMTicket()
+ {
+ }
+
+ GMTicket(uint32 guid, std::string text, time_t update) : m_guid(guid), m_text(text), m_lastUpdate(update)
+ {
+
+ }
+
+ const char* GetText() const
+ {
+ return m_text.c_str();
+ }
+
+ uint64 GetLastUpdate() const
+ {
+ return m_lastUpdate;
+ }
+
+ void SetText(const char* text)
+ {
+ m_text = text ? text : "";
+ m_lastUpdate = time(NULL);
+ CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", m_text.c_str(), m_guid);
+ }
+
+ void DeleteFromDB() const
+ {
+ CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1", m_guid);
+ }
+
+ void SaveToDB() const
+ {
+ CharacterDatabase.BeginTransaction();
+ DeleteFromDB();
+ CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, GetText());
+ CharacterDatabase.CommitTransaction();
+ }
+ private:
+ uint32 m_guid;
+ std::string m_text;
+ time_t m_lastUpdate;
+};
+typedef std::map<uint32, GMTicket> GMTicketMap;
+
+class GMTicketMgr
+{
+ public:
+ GMTicketMgr() { }
+ ~GMTicketMgr() { }
+
+ void LoadGMTickets();
+
+ GMTicket* GetGMTicket(uint32 guid)
+ {
+ GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
+ if(itr == m_GMTicketMap.end())
+ return NULL;
+ return &(itr->second);
+ }
+
+ size_t GetTicketCount() const
+ {
+ return m_GMTicketMap.size();
+ }
+
+ void Delete(uint32 guid)
+ {
+ GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
+ if(itr == m_GMTicketMap.end())
+ return;
+ itr->second.DeleteFromDB();
+ m_GMTicketMap.erase(itr);
+ }
+
+ void DeleteAll();
+
+ void Create(uint32 guid, const char* text)
+ {
+ GMTicket t = GMTicket(guid, text, time(NULL));
+ t.SaveToDB();
+ m_GMTicketMap[guid] = t;
+ }
+ private:
+ GMTicketMap m_GMTicketMap;
+};
+
+#define ticketmgr Trinity::Singleton<GMTicketMgr>::Instance()
+#endif \ No newline at end of file
diff --git a/src/game/HateMatrix.h b/src/game/HateMatrix.h
deleted file mode 100644
index f4c7d62f5cd..00000000000
--- a/src/game/HateMatrix.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TRINITY_HATEMATRIX_H
-#define TRINITY_HATEMATRIX_H
-
-#include "Utilities/UnorderedMap.h"
-#include <cassert>
-
-class Unit;
-
-struct TRINITY_DLL_DECL HateMatrix
-{
- typedef hash_map<Unit *, uint32> HateMatrixMapType;
-
- inline uint32 operator[](Unit *unit) const
- {
- HateMatrixMapType::const_iterator iter = i_hateValues.find(unit);
- return (iter == i_hateValues.end() ? 0 : iter->second);
- }
-
- inline uint32& operator[](Unit *unit)
- {
- HateMatrixMapType::iterator iter = i_hateValues.find(unit);
- if( iter == i_hateValues.end() )
- {
- std::pair<HateMatrixMapType::iterator, bool> p = i_hateValues.insert( HateMatrixMapType::value_type(unit, 0) );
- assert(p.second);
- iter = p.first;
- }
-
- return iter->second;
- }
-
- inline void ClearMatrix(void) { i_hateValues.clear(); }
-
- inline void RemoveValue(Unit *unit)
- {
- HateMatrixMapType::iterator iter = i_hateValues.find(unit);
- if( iter != i_hateValues.end() )
- i_hateValues.erase( iter );
- }
-
- inline void AddValue(Unit *unit, uint32 val)
- {
- (*this)[unit] += val;
- }
-
- private:
- HateMatrixMapType i_hateValues;
-};
-
-struct HateBinder
-{
- static uint32 si_noHateValue;
- uint32 &i_hateValue;
- Unit *i_unit;
- HateBinder(uint32 &val, Unit *u) : i_hateValue(val), i_unit(u) {}
- HateBinder() : i_hateValue(si_noHateValue), i_unit(NULL) {}
- HateBinder(const HateBinder &obj) : i_hateValue(obj.i_hateValue), i_unit(obj.i_unit) {}
-
- HateBinder& operator=(const HateBinder &obj)
- {
- i_hateValue = obj.i_hateValue;
- i_unit = obj.i_unit;
- return *this;
- }
-};
-#endif
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 1c34a1a58a3..62efe7dd234 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -49,6 +49,18 @@ void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data )
if (count==0)
return; //check count - if zero it's fake packet
+ if(!_player->IsValidPos(srcbag,srcslot))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
+ return;
+ }
+
+ if(!_player->IsValidPos(dstbag,dstslot))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL );
+ return;
+ }
+
_player->SplitItem( src, dst, count );
}
@@ -66,6 +78,18 @@ void WorldSession::HandleSwapInvItemOpcode( WorldPacket & recv_data )
if(srcslot==dstslot)
return;
+ if(!_player->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
+ return;
+ }
+
+ if(!_player->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL );
+ return;
+ }
+
uint16 src = ( (INVENTORY_SLOT_BAG_0 << 8) | srcslot );
uint16 dst = ( (INVENTORY_SLOT_BAG_0 << 8) | dstslot );
@@ -109,6 +133,18 @@ void WorldSession::HandleSwapItem( WorldPacket & recv_data )
if(src==dst)
return;
+ if(!_player->IsValidPos(srcbag,srcslot))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
+ return;
+ }
+
+ if(!_player->IsValidPos(dstbag,dstslot))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL );
+ return;
+ }
+
_player->SwapItem( src, dst );
}
@@ -746,6 +782,12 @@ void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data )
if( !pItem )
return;
+ if(!_player->IsValidPos(dstbag,NULL_SLOT))
+ {
+ _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL );
+ return;
+ }
+
uint16 src = pItem->GetPos();
// check unequip potability for equipped items and bank bags
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 9aff34d79f3..62b68a04cc8 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -36,6 +36,7 @@
#include "GameEvent.h"
#include "SpellMgr.h"
#include "AccountMgr.h"
+#include "GMTicketMgr.h"
#include "WaypointManager.h"
#include "Util.h"
#include <cctype>
@@ -862,7 +863,13 @@ bool ChatHandler::HandleItemMoveCommand(const char* args)
if(srcslot==dstslot)
return true;
-
+
+ if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot))
+ return false;
+
+ if(!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0,dstslot))
+ return false;
+
uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
@@ -1795,7 +1802,7 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
// get additional information from DB
else
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", targetGUID);
+ QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID));
if (!result)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -1920,15 +1927,7 @@ bool ChatHandler::HandleTicketCommand(const char* args)
return false;
}
- size_t count;
- QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket");
- if(result)
- {
- count = (*result)[0].GetUInt32();
- delete result;
- }
- else
- count = 0;
+ size_t count = ticketmgr.GetTicketCount();
bool accept = m_session->GetPlayer()->isAcceptTickets();
@@ -1975,18 +1974,17 @@ bool ChatHandler::HandleTicketCommand(const char* args)
if(!result)
{
PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
- delete result;
SetSentErrorMessage(true);
return false;
}
Field* fields = result->Fetch();
- uint64 guid = fields[0].GetUInt64();
+ uint32 guid = fields[0].GetUInt32();
char const* text = fields[1].GetString();
char const* time = fields[2].GetString();
- ShowTicket(guid,text,time);
+ ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
delete result;
return true;
}
@@ -2006,43 +2004,17 @@ bool ChatHandler::HandleTicketCommand(const char* args)
return false;
// ticket $char_name
- QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid));
-
- if(!result)
+ GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid));
+ if(!ticket)
return false;
- Field* fields = result->Fetch();
+ std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
- char const* text = fields[0].GetString();
- char const* time = fields[1].GetString();
-
- ShowTicket(guid,text,time);
- delete result;
+ ShowTicket(guid, ticket->GetText(), time.c_str());
return true;
}
-uint32 ChatHandler::GetTicketIDByNum(uint32 num)
-{
- QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket");
-
- if(!result || num > result->GetRowCount())
- {
- PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
- delete result;
- return 0;
- }
-
- for(uint32 i = 1; i < num; ++i)
- result->NextRow();
-
- Field* fields = result->Fetch();
-
- uint32 id = fields[0].GetUInt32();
- delete result;
- return id;
-}
-
//dell all tickets
bool ChatHandler::HandleDelTicketCommand(const char *args)
{
@@ -2053,26 +2025,7 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
// delticket all
if(strncmp(px,"all",4) == 0)
{
- QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket");
-
- if(!result)
- return true;
-
- // notify players about ticket deleting
- do
- {
- Field* fields = result->Fetch();
-
- uint64 guid = fields[0].GetUInt64();
-
- if(Player* sender = objmgr.GetPlayer(guid))
- sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
-
- }while(result->NextRow());
-
- delete result;
-
- CharacterDatabase.PExecute("DELETE FROM character_ticket");
+ ticketmgr.DeleteAll();
SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
return true;
}
@@ -2082,32 +2035,29 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
// delticket #num
if(num > 0)
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
-
+ QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
if(!result)
{
PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
- delete result;
SetSentErrorMessage(true);
return false;
}
Field* fields = result->Fetch();
- uint32 id = fields[0].GetUInt32();
- uint64 guid = fields[1].GetUInt64();
+ uint32 guid = fields[0].GetUInt32();
delete result;
- CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id);
+ ticketmgr.Delete(guid);
- // notify players about ticket deleting
- if(Player* sender = objmgr.GetPlayer(guid))
+ //notify player
+ if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
{
- sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
- PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName());
+ pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
+ PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, pl->GetName());
}
else
- SendSysMessage(LANG_COMMAND_TICKETDEL);
+ PSendSysMessage(LANG_COMMAND_TICKETDEL);
return true;
}
@@ -2127,7 +2077,7 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
return false;
// delticket $char_name
- CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid));
+ ticketmgr.Delete(GUID_LOPART(guid));
// notify players about ticket deleting
if(Player* sender = objmgr.GetPlayer(guid))
diff --git a/src/game/Makefile.am b/src/game/Makefile.am
index 8cebc1715d0..ddadee44f9b 100644
--- a/src/game/Makefile.am
+++ b/src/game/Makefile.am
@@ -114,6 +114,9 @@ $(srcdir)/GameObject.cpp \
$(srcdir)/GameObject.h \
$(srcdir)/GlobalEvents.cpp \
$(srcdir)/GlobalEvents.h \
+$(srcdir)/GMTicketHandler.cpp \
+$(srcdir)/GMTicketMgr.cpp \
+$(srcdir)/GMTicketMgr.h \
$(srcdir)/GossipDef.cpp \
$(srcdir)/GossipDef.h \
$(srcdir)/GridDefines.h \
@@ -130,7 +133,6 @@ $(srcdir)/GuardAI.h \
$(srcdir)/Guild.cpp \
$(srcdir)/Guild.h \
$(srcdir)/GuildHandler.cpp \
-$(srcdir)/HateMatrix.h \
$(srcdir)/HomeMovementGenerator.cpp \
$(srcdir)/HomeMovementGenerator.h \
$(srcdir)/HostilRefManager.cpp \
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index d4306443f5f..fff73254bbb 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -360,189 +360,6 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ )
sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" );
}
-void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
-{
- int len = text ? strlen(text) : 0;
- WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
- data << uint32(status); // standard 0x0A, 0x06 if text present
- if(status == 6)
- {
- data << text; // ticket text
- data << uint8(0x7); // ticket category
- data << float(0); // time from ticket creation?
- data << float(0); // const
- data << float(0); // const
- data << uint8(0); // const
- data << uint8(0); // const
- }
- SendPacket( &data );
-}
-
-void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
-{
- WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
- data << (uint32)time(NULL);
- data << (uint32)0;
- SendPacket( &data );
-
- uint64 guid;
- Field *fields;
- guid = GetPlayer()->GetGUID();
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(ticket_id) FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid));
-
- if (result)
- {
- int cnt;
- fields = result->Fetch();
- cnt = fields[0].GetUInt32();
- delete result;
-
- if ( cnt > 0 )
- {
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT ticket_text FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid));
- if(result2)
- {
- Field *fields2 = result2->Fetch();
- SendGMTicketGetTicket(0x06,fields2[0].GetString());
- delete result2;
- }
- }
- else
- SendGMTicketGetTicket(0x0A,0);
- }
-}
-
-void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
-{
- CHECK_PACKET_SIZE(recv_data,1);
-
- std::string ticketText;
- recv_data >> ticketText;
-
- CharacterDatabase.escape_string(ticketText);
- CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", ticketText.c_str(), _player->GetGUIDLow());
-}
-
-void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
-{
- uint32 guid = GetPlayer()->GetGUIDLow();
-
- CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1",guid);
-
- WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
- data << uint32(9);
- SendPacket( &data );
-
- SendGMTicketGetTicket(0x0A, 0);
-}
-
-void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
-{
- CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
-
- uint32 map;
- float x, y, z;
- std::string ticketText = "";
- uint32 unk1, unk2;
-
- recv_data >> map >> x >> y >> z; // last check 2.4.3
- recv_data >> ticketText;
-
- // recheck
- CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
-
- recv_data >> unk1 >> unk2;
- // note: the packet might contain more data, but the exact structure of that is unknown
-
- sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
-
- CharacterDatabase.escape_string(ticketText);
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM character_ticket WHERE guid = '%u'", _player->GetGUIDLow());
-
- if (result)
- {
- int cnt;
- Field *fields = result->Fetch();
- cnt = fields[0].GetUInt32();
- delete result;
-
- if ( cnt > 0 )
- {
- WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
- data << uint32(1);
- SendPacket( &data );
- }
- else
- {
- CharacterDatabase.PExecute("INSERT INTO character_ticket (guid,ticket_text) VALUES ('%u', '%s')", _player->GetGUIDLow(), ticketText.c_str());
-
- WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
- data << (uint32)time(NULL);
- data << (uint32)0;
- SendPacket( &data );
-
- data.Initialize( SMSG_GMTICKET_CREATE, 4 );
- data << uint32(2);
- SendPacket( &data );
- DEBUG_LOG("update the ticket\n");
-
- //TODO: Guard player map
- HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
- for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
- {
- if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
- ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
- }
- }
- }
-}
-
-void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
-{
- WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
- data << uint32(1); // we can also disable ticket system by sending 0 value
-
- SendPacket( &data );
-}
-
-void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
-{
- // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
- CHECK_PACKET_SIZE(recv_data,4+4);
- uint32 x;
- recv_data >> x; // answer range? (6 = 0-5?)
- sLog.outDebug("SURVEY: X = %u", x);
-
- uint8 result[10];
- memset(result, 0, sizeof(result));
- for( int i = 0; i < 10; ++i)
- {
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
- uint32 questionID;
- recv_data >> questionID; // GMSurveyQuestions.dbc
- if (!questionID)
- break;
-
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
- uint8 value;
- std::string unk_text;
- recv_data >> value; // answer
- recv_data >> unk_text; // always empty?
-
- result[i] = value;
- sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
- }
-
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
- std::string comment;
- recv_data >> comment; // addional comment
- sLog.outDebug("SURVEY: comment %s", comment.c_str());
-
- // TODO: chart this data in some way
-}
-
void WorldSession::HandleTogglePvP( WorldPacket & recv_data )
{
// this opcode can be used in two ways: Either set explicit new status or toggle old status
diff --git a/src/game/Object.h b/src/game/Object.h
index f5dbe92010c..75d75be0728 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -33,9 +33,8 @@
#include <string>
#define CONTACT_DISTANCE 0.5f
-#define INTERACTION_DISTANCE 5
-#define ATTACK_DISTANCE 5
-#define DETECT_DISTANCE 20 // max distance to successful detect stealthed unit
+#define INTERACTION_DISTANCE 5.0f
+#define ATTACK_DISTANCE 5.0f
#define MAX_VISIBILITY_DISTANCE (5*SIZE_OF_GRID_CELL/2.0f) // max distance for visible object show, limited by active zone for player based at cell size (active zone = 5x5 cells)
#define DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL) // default visible distance
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 87706bc68a1..aead2c68964 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -3900,19 +3900,22 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
if(float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE)
{
- sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",tablename,tmp.datalong2,tmp.id);
+ sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u",
+ tablename,tmp.datalong2,tmp.id);
continue;
}
if(tmp.datalong2 && float(tmp.datalong2) > DEFAULT_VISIBILITY_DISTANCE)
{
- sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, max distance is %u or 0 for disable distance check",tablename,tmp.datalong2,tmp.id,uint32(DEFAULT_VISIBILITY_DISTANCE));
+ sLog.outErrorDb("Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, max distance is %f or 0 for disable distance check",
+ tablename,tmp.datalong2,tmp.id,DEFAULT_VISIBILITY_DISTANCE);
continue;
}
if(tmp.datalong2 && float(tmp.datalong2) < INTERACTION_DISTANCE)
{
- sLog.outErrorDb("Table `%s` has too small distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, min distance is %u or 0 for disable distance check",tablename,tmp.datalong2,tmp.id,uint32(INTERACTION_DISTANCE));
+ sLog.outErrorDb("Table `%s` has too small distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, min distance is %f or 0 for disable distance check",
+ tablename,tmp.datalong2,tmp.id,INTERACTION_DISTANCE);
continue;
}
@@ -3924,7 +3927,8 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
{
if(!sSpellStore.LookupEntry(tmp.datalong))
{
- sLog.outErrorDb("Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_REMOVE_AURA or SCRIPT_COMMAND_CAST_SPELL for script id %u",tablename,tmp.datalong,tmp.id);
+ sLog.outErrorDb("Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_REMOVE_AURA or SCRIPT_COMMAND_CAST_SPELL for script id %u",
+ tablename,tmp.datalong,tmp.id);
continue;
}
break;
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 4eaf047f96c..b66579895fb 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -935,7 +935,8 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
if(!IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %d Y: ^%d)", GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY());
+ sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)",
+ GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY());
return false;
}
diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp
index b6c14d70161..9c2107d2ee7 100644
--- a/src/game/PetitionsHandler.cpp
+++ b/src/game/PetitionsHandler.cpp
@@ -835,8 +835,9 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data)
for(uint8 i = 0; i < signs; ++i)
{
Field* fields = result->Fetch();
- sLog.outDebug("PetitionsHandler: adding arena member %u", fields[0].GetUInt64());
- at->AddMember(fields[0].GetUInt64());
+ uint64 memberGUID = fields[0].GetUInt64();
+ sLog.outDebug("PetitionsHandler: adding arena member %u", GUID_LOPART(memberGUID));
+ at->AddMember(memberGUID);
result->NextRow();
}
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 23aae2cd363..7c839f32a3e 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -4043,24 +4043,20 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
uint32 LostDurability = maxDurability - curDurability;
if(LostDurability>0)
{
- ItemPrototype const *ditemProto = sItemStorage.LookupEntry<ItemPrototype>(item->GetEntry());
- if(!ditemProto)
- {
- sLog.outError("ERROR: RepairDurability: Unknown item id %u", ditemProto);
- return TotalCost;
- }
+ ItemPrototype const *ditemProto = item->GetProto();
DurabilityCostsEntry const *dcost = sDurabilityCostsStore.LookupEntry(ditemProto->ItemLevel);
if(!dcost)
{
- sLog.outError("ERROR: RepairDurability: Wrong item lvl %u", dcost);
+ sLog.outError("ERROR: RepairDurability: Wrong item lvl %u", ditemProto->ItemLevel);
return TotalCost;
}
- DurabilityQualityEntry const *dQualitymodEntry = sDurabilityQualityStore.LookupEntry((ditemProto->Quality+1)*2);
+ uint32 dQualitymodEntryId = (ditemProto->Quality+1)*2;
+ DurabilityQualityEntry const *dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId);
if(!dQualitymodEntry)
{
- sLog.outError("ERROR: RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntry);
+ sLog.outError("ERROR: RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntryId);
return TotalCost;
}
@@ -6156,32 +6152,11 @@ uint32 Player::GetRankFromDB(uint64 guid)
uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid FROM arena_team_member WHERE guid='%u'", GUID_LOPART(guid));
- if(result)
- {
- bool found = false;
- // init id to find the type of the arenateam
- uint32 id = (*result)[0].GetUInt32();
- do
- {
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM arena_team WHERE arenateamid='%u'", id);
- if(result2)
- {
- uint8 dbtype = (*result2)[0].GetUInt32();
- delete result2;
- if(dbtype == type)
- {
- // if the type matches, we've found the id
- found = true;
- break;
- }
- }
- } while(result->NextRow());
- delete result;
- if(found) return id;
- }
- // no arenateam for the specified guid, return 0
- return 0;
+ QueryResult *result = CharacterDatabase.PQuery("SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid='%u' AND type='%u' LIMIT 1", GUID_LOPART(guid), type);
+ if(!result)
+ return 0;
+
+ return (*result)[0].GetUInt32();
}
uint32 Player::GetZoneIdFromDB(uint64 guid)
@@ -8575,6 +8550,77 @@ bool Player::IsBagPos( uint16 pos )
return false;
}
+bool Player::IsValidPos( uint8 bag, uint8 slot )
+{
+ // post selected
+ if(bag == NULL_BAG)
+ return true;
+
+ if (bag == INVENTORY_SLOT_BAG_0)
+ {
+ // any post selected
+ if (slot == NULL_SLOT)
+ return true;
+
+ // equipment
+ if (slot < EQUIPMENT_SLOT_END)
+ return true;
+
+ // bag equip slots
+ if (slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END)
+ return true;
+
+ // backpack slots
+ if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_END)
+ return true;
+
+ // keyring slots
+ if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END)
+ return true;
+
+ // bank main slots
+ if (slot >= BANK_SLOT_ITEM_START && slot < BANK_SLOT_ITEM_END)
+ return true;
+
+ // bank bag slots
+ if (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END)
+ return true;
+
+ return false;
+ }
+
+ // bag content slots
+ if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)
+ {
+ Bag* pBag = (Bag*)GetItemByPos (INVENTORY_SLOT_BAG_0, bag);
+ if(!pBag)
+ return false;
+
+ // any post selected
+ if (slot == NULL_SLOT)
+ return true;
+
+ return slot < pBag->GetBagSize();
+ }
+
+ // bank bag content slots
+ if( bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END )
+ {
+ Bag* pBag = (Bag*)GetItemByPos (INVENTORY_SLOT_BAG_0, bag);
+ if(!pBag)
+ return false;
+
+ // any post selected
+ if (slot == NULL_SLOT)
+ return true;
+
+ return slot < pBag->GetBagSize();
+ }
+
+ // where this?
+ return false;
+}
+
bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const
{
uint32 tempcount = 0;
diff --git a/src/game/Player.h b/src/game/Player.h
index 9083f35cda1..427f97de14a 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1046,6 +1046,8 @@ class TRINITY_DLL_SPEC Player : public Unit
static bool IsBagPos( uint16 pos );
static bool IsBankPos( uint16 pos ) { return IsBankPos(pos >> 8,pos & 255); }
static bool IsBankPos( uint8 bag, uint8 slot );
+ bool IsValidPos( uint16 pos ) { return IsBankPos(pos >> 8,pos & 255); }
+ bool IsValidPos( uint8 bag, uint8 slot );
bool HasBankBagSlot( uint8 slot ) const;
bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;
bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL);
diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp
index efd27281e29..9f9eecc2234 100644
--- a/src/game/QueryHandler.cpp
+++ b/src/game/QueryHandler.cpp
@@ -202,7 +202,8 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- sLog.outDebug( "WORLD: CMSG_CREATURE_QUERY - (%u) NO CREATURE INFO! (GUID: %u, ENTRY: %u)", uint32(GUID_LOPART(guid)), guid, entry );
+ sLog.outDebug("WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)",
+ GUID_LOPART(guid), entry);
WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 );
data << uint32(entry | 0x80000000);
SendPacket( &data );
@@ -260,7 +261,8 @@ void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- sLog.outDebug( "WORLD: CMSG_GAMEOBJECT_QUERY - (%u) Missing gameobject info for (GUID: %u, ENTRY: %u)", uint32(GUID_LOPART(guid)), guid, entryID );
+ sLog.outDebug( "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)",
+ GUID_LOPART(guid), entryID );
WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 );
data << uint32(entryID | 0x80000000);
SendPacket( &data );
diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
index 7215f5a6060..1dbb8e92b38 100644
--- a/src/game/QuestHandler.cpp
+++ b/src/game/QuestHandler.cpp
@@ -87,12 +87,13 @@ void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
- sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u",guid );
+ sLog.outDebug ("WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid));
Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid,UNIT_NPC_FLAG_NONE);
if (!pCreature)
{
- sLog.outDebug( "WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
+ sLog.outDebug ("WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.",
+ GUID_LOPART(guid));
return;
}
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 8a2eb28ceed..25f69aa3046 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -5602,7 +5602,7 @@ void Aura::PeriodicTick()
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
- GetCasterGUID(), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size
data.append(m_target->GetPackGUID());
@@ -5723,7 +5723,7 @@ void Aura::PeriodicTick()
pdamage = uint32(m_target->GetHealth());
sLog.outDetail("PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
- GetCasterGUID(), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0);
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 2a3823118cb..b0744d9b009 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -1950,7 +1950,8 @@ void Spell::EffectTriggerMissileSpell(uint32 effect_idx)
if(!spellInfo)
{
- sLog.outError("EffectTriggerMissileSpell of spell %u: triggering unknown spell id %effect_idx", m_spellInfo->Id,triggered_spell_id);
+ sLog.outError("EffectTriggerMissileSpell of spell %u (eff: %u): triggering unknown spell id %u",
+ m_spellInfo->Id,effect_idx,triggered_spell_id);
return;
}
@@ -3215,7 +3216,8 @@ void Spell::EffectSummon(uint32 i)
if(!spawnCreature->IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %d Y: ^%d)", spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY());
+ sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",
+ spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY());
delete spawnCreature;
return;
}
@@ -3657,7 +3659,8 @@ void Spell::EffectSummonGuardian(uint32 i)
if(!spawnCreature->IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %d Y: ^%d)", spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY());
+ sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)",
+ spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY());
delete spawnCreature;
return;
}
@@ -4075,7 +4078,8 @@ void Spell::EffectSummonPet(uint32 i)
if(!NewSummon->IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %d Y: ^%d)", NewSummon->GetGUIDLow(), NewSummon->GetEntry(), NewSummon->GetPositionX(), NewSummon->GetPositionY());
+ sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",
+ NewSummon->GetGUIDLow(), NewSummon->GetEntry(), NewSummon->GetPositionX(), NewSummon->GetPositionY());
delete NewSummon;
return;
}
@@ -5673,7 +5677,8 @@ void Spell::EffectSummonCritter(uint32 i)
if(!critter->IsPositionValid())
{
- sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %d Y: ^%d)", critter->GetGUIDLow(), critter->GetEntry(), critter->GetPositionX(), critter->GetPositionY());
+ sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",
+ critter->GetGUIDLow(), critter->GetEntry(), critter->GetPositionX(), critter->GetPositionY());
delete critter;
return;
}
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 190134c7b02..00979cd23d3 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -263,7 +263,7 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
recv_data >> guid;
- sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", guid);
+ sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid));
GameObject *obj = ObjectAccessor::GetGameObject(*_player, guid);
if(!obj)
diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp
index d73835c172d..2125fcf0567 100644
--- a/src/game/Transports.cpp
+++ b/src/game/Transports.cpp
@@ -148,7 +148,8 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
if(!IsPositionValid())
{
- sLog.outError("ERROR: Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %d Y: ^%d)",guidlow,x,y);
+ sLog.outError("ERROR: Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
+ guidlow,x,y);
return false;
}
diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp
index ebcce9d5c11..d72ac1e266e 100644
--- a/src/game/WaypointManager.cpp
+++ b/src/game/WaypointManager.cpp
@@ -91,8 +91,12 @@ void WaypointManager::Load()
if(!Trinity::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
{
QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
- if(result1) sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %d, Y: %d).", id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
- else sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %d, Y: %d).", id, point, node.x, node.y);
+ if(result1)
+ sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
+ id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
+ else
+ sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
+ id, point, node.x, node.y);
Trinity::NormalizeMapCoord(node.x);
Trinity::NormalizeMapCoord(node.y);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index ad99e676ee7..b599e617f04 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -59,6 +59,7 @@
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
#include "WaypointManager.h"
+#include "GMTicketMgr.h"
#include "Util.h"
#include "Language.h"
@@ -460,7 +461,8 @@ void World::LoadConfigSettings(bool reload)
}
else if(rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] > ATTACK_DISTANCE)
{
- sLog.outError("TargetPosRecalculateRange (%f) must be <= %f. Using %f instead.",rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],ATTACK_DISTANCE,ATTACK_DISTANCE);
+ sLog.outError("TargetPosRecalculateRange (%f) must be <= %f. Using %f instead.",
+ rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],ATTACK_DISTANCE,ATTACK_DISTANCE);
rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = ATTACK_DISTANCE;
}
@@ -1174,6 +1176,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Waypoints..." );
WaypointMgr.Load();
+ sLog.outString( "Loading GM tickets...");
+ ticketmgr.LoadGMTickets();
+
///- Handle outdated emails (delete/return)
sLog.outString( "Returning old mails..." );
objmgr.ReturnOrDeleteOldMails(false);
@@ -1203,7 +1208,8 @@ void World::SetInitialWorldSettings()
sprintf( isoDate, "%04d-%02d-%02d %02d:%02d:%02d",
local.tm_year+1900, local.tm_mon+1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec);
- WorldDatabase.PExecute("INSERT INTO uptime (startstring, starttime, uptime) VALUES('%s', %ld, 0)", isoDate, m_startTime );
+ WorldDatabase.PExecute("INSERT INTO uptime (startstring, starttime, uptime) VALUES('%s', " I64FMTD ", 0)",
+ isoDate, uint64(m_startTime));
m_timers[WUPDATE_OBJECTS].SetInterval(0);
m_timers[WUPDATE_SESSIONS].SetInterval(0);
diff --git a/win/VC71/game.vcproj b/win/VC71/game.vcproj
index 6e53e44e467..2a260c26d61 100644
--- a/win/VC71/game.vcproj
+++ b/win/VC71/game.vcproj
@@ -626,9 +626,6 @@
RelativePath="..\..\src\game\Guild.h">
</File>
<File
- RelativePath="..\..\src\game\HateMatrix.h">
- </File>
- <File
RelativePath="..\..\src\game\HomeMovementGenerator.cpp">
</File>
<File
diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj
index 883feadb4fe..e0778b07108 100644
--- a/win/VC80/game.vcproj
+++ b/win/VC80/game.vcproj
@@ -991,10 +991,6 @@
>
</File>
<File
- RelativePath="..\..\src\game\HateMatrix.h"
- >
- </File>
- <File
RelativePath="..\..\src\game\HomeMovementGenerator.cpp"
>
</File>
diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj
index 14a0d9257b1..1dde7c90d41 100644
--- a/win/VC90/game.vcproj
+++ b/win/VC90/game.vcproj
@@ -996,10 +996,6 @@
>
</File>
<File
- RelativePath="..\..\src\game\HateMatrix.h"
- >
- </File>
- <File
RelativePath="..\..\src\game\HomeMovementGenerator.cpp"
>
</File>