diff options
author | KingPin <none@none> | 2008-11-10 09:04:23 -0600 |
---|---|---|
committer | KingPin <none@none> | 2008-11-10 09:04:23 -0600 |
commit | 09a0d1122afb5b97f36dbedf0f58fc10d1ad135a (patch) | |
tree | ea121fe9591077c9b5de6d58e51762a4dd84f6b3 | |
parent | 09280b0091474b58d43daf42c0f3d99f86e6ec25 (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
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> |