2014-09-12 23:49:30 +02:00
/*
2015-01-01 00:27:46 +01:00
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
2014-09-12 23:49:30 +02:00
* Copyright (C) 2005-2009 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, see <http://www.gnu.org/licenses/>.
*/
#include "ObjectGuid.h"
#include "World.h"
#include "ObjectMgr.h"
#include <sstream>
2014-09-14 16:14:12 +02:00
#include <iomanip>
2014-10-29 21:13:21 +01:00
char const * TypeNames [] =
{
"Null" ,
"Uniq" ,
"Player" ,
"Item" ,
"StaticDoor" ,
"Transport" ,
"Conversation" ,
"Creature" ,
"Vehicle" ,
"Pet" ,
"GameObject" ,
"DynamicObject" ,
"AreaTrigger" ,
"Corpse" ,
"LootObject" ,
"SceneObject" ,
"Scenario" ,
"AIGroup" ,
"DynamicDoor" ,
"ClientActor" ,
"Vignette" ,
"CallForHelp" ,
"AIResource" ,
"AILock" ,
"AILockTicket" ,
"ChatChannel" ,
"Party" ,
"Guild" ,
"WowAccount" ,
"BNetAccount" ,
"GMTask" ,
"MobileSession" ,
"RaidGroup" ,
"Spell" ,
"Mail" ,
"WebObj" ,
"LFGObject" ,
"LFGList" ,
"UserRouter" ,
"PVPQueueGroup" ,
"UserClient" ,
"PetBattle" ,
"UniqueUserClient" ,
"BattlePet" ,
};
2014-09-12 23:49:30 +02:00
char const * ObjectGuid :: GetTypeName ( HighGuid high )
{
2014-12-29 01:00:16 +01:00
if ( high >= HighGuid :: Count )
2014-10-29 21:13:21 +01:00
return "<unknown>" ;
return TypeNames [ uint32 ( high )];
2014-09-12 23:49:30 +02:00
}
std :: string ObjectGuid :: ToString () const
{
std :: ostringstream str ;
2015-03-09 11:02:06 +01:00
str << "GUID Full: 0x" << std :: hex << std :: uppercase << std :: setw ( 16 ) << std :: setfill ( '0' ) << _high << std :: setw ( 16 ) << _low << std :: dec << std :: nouppercase ;
2014-09-14 16:14:12 +02:00
str << " Type: " << GetTypeName ();
2014-09-12 23:49:30 +02:00
if ( HasEntry ())
2015-03-09 11:02:06 +01:00
str << ( IsPet () ? " Pet number: " : " Entry: " ) << GetEntry ();
2014-09-14 16:14:12 +02:00
str << " Low: " << GetCounter ();
2014-09-12 23:49:30 +02:00
return str . str ();
}
2014-10-23 17:01:26 +02:00
std :: vector < uint8 > ObjectGuid :: GetRawValue () const
{
std :: vector < uint8 > raw ( 16 );
memcpy ( raw . data (), this , sizeof ( * this ));
return raw ;
}
void ObjectGuid :: SetRawValue ( std :: vector < uint8 > const & guid )
{
ASSERT ( guid . size () == sizeof ( * this ));
memcpy ( this , guid . data (), sizeof ( * this ));
}
2014-10-29 21:13:21 +01:00
void PackedGuid :: Set ( ObjectGuid const & guid )
2014-10-23 17:01:26 +02:00
{
uint8 lowMask = 0 ;
uint8 highMask = 0 ;
2014-11-02 14:56:16 +01:00
_packedGuid . clear ();
2014-10-23 17:01:26 +02:00
_packedGuid << uint8 ( lowMask );
_packedGuid << uint8 ( highMask );
uint8 packed [ 8 ];
if ( size_t packedSize = _packedGuid . PackUInt64 ( guid . _low , & lowMask , packed ))
_packedGuid . append ( packed , packedSize );
if ( size_t packedSize = _packedGuid . PackUInt64 ( guid . _high , & highMask , packed ))
_packedGuid . append ( packed , packedSize );
_packedGuid . put ( 0 , lowMask );
_packedGuid . put ( 1 , highMask );
}
2014-09-12 23:49:30 +02:00
template < HighGuid high >
2014-10-26 02:57:28 +02:00
ObjectGuid :: LowType ObjectGuidGenerator < high >:: Generate ()
2014-09-12 23:49:30 +02:00
{
2014-09-19 03:16:59 +02:00
if ( _nextGuid >= ObjectGuid :: GetMaxCounter ( high ) - 1 )
2014-09-12 23:49:30 +02:00
{
TC_LOG_ERROR ( "" , "%s guid overflow!! Can't continue, shutting down server. " , ObjectGuid :: GetTypeName ( high ));
World :: StopNow ( ERROR_EXIT_CODE );
}
2014-09-19 03:16:59 +02:00
return _nextGuid ++ ;
2014-09-12 23:49:30 +02:00
}
ByteBuffer & operator << ( ByteBuffer & buf , ObjectGuid const & guid )
{
2014-10-23 17:01:26 +02:00
buf << guid . WriteAsPacked ();
2014-09-12 23:49:30 +02:00
return buf ;
}
ByteBuffer & operator >> ( ByteBuffer & buf , ObjectGuid & guid )
{
2014-10-23 17:01:26 +02:00
buf >> guid . ReadAsPacked ();
2014-09-12 23:49:30 +02:00
return buf ;
}
ByteBuffer & operator << ( ByteBuffer & buf , PackedGuid const & guid )
{
2014-09-19 03:16:59 +02:00
buf . append ( guid . _packedGuid );
2014-09-12 23:49:30 +02:00
return buf ;
}
ByteBuffer & operator >> ( ByteBuffer & buf , PackedGuidReader const & guid )
{
2014-10-23 17:01:26 +02:00
uint8 lowMask , highMask ;
buf >> lowMask >> highMask ;
buf . ReadPackedUInt64 ( lowMask , guid . GuidPtr -> _low );
buf . ReadPackedUInt64 ( highMask , guid . GuidPtr -> _high );
2014-09-12 23:49:30 +02:00
return buf ;
}
2014-10-23 17:01:26 +02:00
std :: ostream & operator << ( std :: ostream & stream , ObjectGuid const & guid )
{
std :: ostringstream tmp ;
tmp << std :: hex << std :: setw ( 16 ) << std :: setfill ( '0' ) << guid . _high << std :: setw ( 16 ) << std :: setfill ( '0' ) << guid . _low ;
stream << tmp . str ();
return stream ;
}
2014-10-29 21:13:21 +01:00
class GuidFormat
{
public :
inline static ObjectGuid Global ( HighGuid type , ObjectGuid :: LowType counter )
{
return ObjectGuid ( uint64 ( uint64 ( type ) << 58 ), counter );
}
inline static ObjectGuid RealmSpecific ( HighGuid type , ObjectGuid :: LowType counter )
{
return ObjectGuid ( uint64 ( uint64 ( type ) << 58 | uint64 ( realmHandle . Index ) << 42 ), counter );
}
inline static ObjectGuid MapSpecific ( HighGuid type , uint8 subType , uint16 mapId , uint32 serverId , uint32 entry , ObjectGuid :: LowType counter )
{
2014-10-31 01:20:53 +01:00
return ObjectGuid ( uint64 (( uint64 ( type ) << 58 ) | ( uint64 ( realmHandle . Index & 0x1FFF ) << 42 ) | ( uint64 ( mapId & 0x1FFF ) << 29 ) | ( uint64 ( entry & 0x7FFFFF ) << 6 ) | ( uint64 ( subType ) & 0x3F )),
2014-10-29 21:13:21 +01:00
uint64 (( uint64 ( serverId & 0xFFFFFF ) << 40 ) | ( counter & UI64LIT ( 0xFFFFFFFFFF ))));
}
};
#define GLOBAL_GUID_CREATE(highguid) template<> ObjectGuid ObjectGuid::Create<highguid>(LowType counter) { return GuidFormat::Global(highguid, counter); }
#define REALM_GUID_CREATE(highguid) template<> ObjectGuid ObjectGuid::Create<highguid>(LowType counter) { return GuidFormat::RealmSpecific(highguid, counter); }
#define MAP_GUID_CREATE(highguid) template<> ObjectGuid ObjectGuid::Create<highguid>(uint16 mapId, uint32 entry, LowType counter) { return GuidFormat::MapSpecific(highguid, 0, mapId, 0, entry, counter); }
GLOBAL_GUID_CREATE ( HighGuid :: Uniq )
GLOBAL_GUID_CREATE ( HighGuid :: Party )
GLOBAL_GUID_CREATE ( HighGuid :: WowAccount )
GLOBAL_GUID_CREATE ( HighGuid :: BNetAccount )
GLOBAL_GUID_CREATE ( HighGuid :: GMTask )
GLOBAL_GUID_CREATE ( HighGuid :: RaidGroup )
GLOBAL_GUID_CREATE ( HighGuid :: Spell )
GLOBAL_GUID_CREATE ( HighGuid :: Mail )
GLOBAL_GUID_CREATE ( HighGuid :: UserRouter )
GLOBAL_GUID_CREATE ( HighGuid :: PVPQueueGroup )
GLOBAL_GUID_CREATE ( HighGuid :: UserClient )
GLOBAL_GUID_CREATE ( HighGuid :: UniqueUserClient )
GLOBAL_GUID_CREATE ( HighGuid :: BattlePet )
REALM_GUID_CREATE ( HighGuid :: Player )
REALM_GUID_CREATE ( HighGuid :: Item ) // This is not exactly correct, there are 2 more unknown parts in highguid: (high >> 10 & 0xFF), (high >> 18 & 0xFFFFFF)
REALM_GUID_CREATE ( HighGuid :: Transport )
REALM_GUID_CREATE ( HighGuid :: Guild )
MAP_GUID_CREATE ( HighGuid :: Conversation )
MAP_GUID_CREATE ( HighGuid :: Creature )
MAP_GUID_CREATE ( HighGuid :: Vehicle )
MAP_GUID_CREATE ( HighGuid :: Pet )
MAP_GUID_CREATE ( HighGuid :: GameObject )
MAP_GUID_CREATE ( HighGuid :: DynamicObject )
MAP_GUID_CREATE ( HighGuid :: AreaTrigger )
MAP_GUID_CREATE ( HighGuid :: Corpse )
MAP_GUID_CREATE ( HighGuid :: LootObject )
MAP_GUID_CREATE ( HighGuid :: SceneObject )
MAP_GUID_CREATE ( HighGuid :: Scenario )
MAP_GUID_CREATE ( HighGuid :: AIGroup )
MAP_GUID_CREATE ( HighGuid :: DynamicDoor )
MAP_GUID_CREATE ( HighGuid :: Vignette )
MAP_GUID_CREATE ( HighGuid :: CallForHelp )
MAP_GUID_CREATE ( HighGuid :: AIResource )
MAP_GUID_CREATE ( HighGuid :: AILock )
MAP_GUID_CREATE ( HighGuid :: AILockTicket )
ObjectGuid const ObjectGuid :: Empty = ObjectGuid ();
ObjectGuid const ObjectGuid :: TradeItem = ObjectGuid :: Create < HighGuid :: Uniq > ( uint64 ( 10 ));
template < HighGuid type >
2014-12-07 01:24:00 +01:00
ObjectGuid ObjectGuid :: Create ( LowType /*counter*/ )
2014-10-29 21:13:21 +01:00
{
2014-10-30 20:59:07 +01:00
static_assert ( type == HighGuid :: Count , "This guid type cannot be constructed using Create(LowType counter)." );
2014-10-29 21:13:21 +01:00
}
template < HighGuid type >
2014-12-07 01:24:00 +01:00
ObjectGuid ObjectGuid :: Create ( uint16 /*mapId*/ , uint32 /*entry*/ , LowType /*counter*/ )
2014-10-29 21:13:21 +01:00
{
2014-10-30 20:59:07 +01:00
static_assert ( type == HighGuid :: Count , "This guid type cannot be constructed using Create(uint16 mapId, uint32 entry, LowType counter)." );
2014-10-29 21:13:21 +01:00
}
2014-10-27 12:03:35 +01:00
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Player >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Creature >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Pet >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Vehicle >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Item >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: GameObject >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: DynamicObject >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Corpse >:: Generate ();
2014-12-30 02:23:37 +02:00
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: LootObject >:: Generate ();
2014-10-27 12:03:35 +01:00
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: AreaTrigger >:: Generate ();
template ObjectGuid :: LowType ObjectGuidGenerator < HighGuid :: Transport >:: Generate ();