* fixed object highguids. they are now correct MaNGOS highguids, not sure about other server software. should work anyway.

* output some warnings only in debug>=1 mode
* made spellcasting with no target possible
* fixed exception when the server sent an object_update packet for an object that just got deleted; the rest of this packet got skipped then. this is now fixed; PseuWoW guesses the original object type and can now handle these packets almost 100%.
* fixed possible crash when handling emotes. thx Sesk for pointing out the problem.
This commit is contained in:
false_genesis 2008-02-28 21:51:15 +00:00
parent 1d26aa8eb8
commit 4633ed64be
6 changed files with 85 additions and 43 deletions

View File

@ -598,10 +598,7 @@ DefReturnResult DefScriptPackage::SCGetItemProtoValue(CmdSet& Set)
uint32 tmp=0;
if(t=="class") r.ret=toString(proto->Class);
else if(t=="subclass") r.ret=toString(proto->SubClass);
else if(t=="name1" || t=="name") r.ret=proto->Name[0];
else if(t=="name2") r.ret=proto->Name[1];
else if(t=="name3") r.ret=proto->Name[2];
else if(t=="name4") r.ret=proto->Name[3];
else if(t=="name") r.ret=proto->Name;
else if(t=="model" || t=="displayid") r.ret=toString(proto->DisplayInfoID);
else if(t=="quality") r.ret=toString(proto->Quality);
else if(t=="flags") r.ret=toString(proto->Flags);

View File

@ -112,15 +112,15 @@ void WorldSession::SendCastSpell(uint32 spellid, bool nocheck)
Object *target = objmgr.GetObj(my->GetTarget());
if(!target) // this is wrong, some spells dont require a target (areaspells, self-only spells)
return; // but for now, this should be ok, until a db is used that provides spell info
//if(!target) // this is wrong, some spells dont require a target (areaspells, self-only spells)
// return; // but for now, this should be ok, until a db is used that provides spell info
WorldPacket packet;
ByteBuffer temp;
uint16 flags=TARGET_FLAG_SELF; // target mask. spellcast implementeation needs to be changed if TARGET_MASK_SELF is != 0
packet << spellid;
packet << (uint8)0; // unk
if(my->GetTarget() != GetGuid()) // self cast?
if(target && my->GetTarget() != GetGuid()) // self cast?
{
if(target->GetTypeId() == TYPEID_PLAYER || target->GetTypeId() == TYPEID_UNIT)
{
@ -145,7 +145,7 @@ void WorldSession::SendCastSpell(uint32 spellid, bool nocheck)
SendWorldPacket(packet);
logdetail("Casting spell %u on target "I64FMT,spellid,my->GetTarget());
if(!known)
logerror(" - WARNING: spell is NOT known!");
logcustom(1,RED," - WARNING: spell is NOT known!");
}
void WorldSession::SendWhoListRequest(uint32 minlvl, uint32 maxlvl, uint32 racemask, uint32 classmask, std::string name, std::string guildname, std::vector<uint32> *zonelist, std::vector<std::string> *strlist)

View File

@ -4,6 +4,7 @@
#include "UpdateFields.h"
#include "ObjectDefines.h"
#include "common.h"
#include "HelperDefs.h"
enum TYPE
{
@ -145,6 +146,28 @@ inline uint32 GetValuesCountByTypeId(uint8 tid)
return 0;
}
inline uint8 GetTypeIdByGuid(uint64 guid)
{
switch(GUID_HIPART(guid))
{
case HIGHGUID_PLAYER:
return TYPEID_PLAYER;
case HIGHGUID_CORPSE:
case HIGHGUID_PLAYER_CORPSE: // not sure
return TYPEID_CORPSE;
case HIGHGUID_ITEM: // == HIGHGUID_CONTAINER
return TYPEID_ITEM;
case HIGHGUID_DYNAMICOBJECT:
return TYPEID_DYNAMICOBJECT;
case HIGHGUID_GAMEOBJECT:
case HIGHGUID_TRANSPORT: // not sure
return TYPEID_GAMEOBJECT;
case HIGHGUID_UNIT:
return TYPEID_UNIT;
}
return TYPEID_OBJECT;
}
#endif

View File

@ -19,17 +19,18 @@
#ifndef MANGOS_OBJECTDEFINES_H
#define MANGOS_OBJECTDEFINES_H
enum HIGHGUID
enum HighGuid
{
HIGHGUID_ITEM = 0x40000070,
HIGHGUID_CONTAINER = 0x40000070,
HIGHGUID_UNIT = 0xF0001000,
HIGHGUID_PLAYER = 0x00000000,
HIGHGUID_GAMEOBJECT = 0xF0004000,
HIGHGUID_DYNAMICOBJECT = 0xF000A000,
HIGHGUID_CORPSE = 0xF0007000,
HIGHGUID_PLAYER_CORPSE = 0x80000001, // ??
HIGHGUID_TRANSPORT = 0x80000000
HIGHGUID_ITEM = 0x40000000, // blizz 40000000
HIGHGUID_CONTAINER = 0x40000000, // blizz 40000000
HIGHGUID_UNIT = 0xF0070000, // blizz F009????, where "????" is unit entry
HIGHGUID_PLAYER = 0x00000000, // blizz 00000000
HIGHGUID_GAMEOBJECT = 0xF0060000, // blizz F0090000
HIGHGUID_DYNAMICOBJECT = 0xF00A0000, // blizz F0090000, F0320000
HIGHGUID_CORPSE = 0xF0090000, // blizz F0090000, F0320000
HIGHGUID_PLAYER_CORPSE = 0xF0080000, // blizz F0090000, F0320000
HIGHGUID_MO_TRANSPORT = 0x1FC00000, // blizz 1FC00000 (type 15)
HIGHGUID_TRANSPORT = 0x1FA70000 // blizz 1FA70000 (type 11)
};
#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT )

View File

@ -56,11 +56,18 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
case UPDATETYPE_MOVEMENT:
{
recvPacket >> uguid; // the guid is NOT packed here!
uint8 tyid;
Object *obj = objmgr.GetObj(uguid);
if(obj)
this->_MovementUpdate(obj->GetTypeId(),uguid,recvPacket);
else
logerror("Got UpdateObject_Movement for unknown object "I64FMT,uguid);
tyid = obj->GetTypeId();
else // sometimes objects get deleted BEFORE a last update packet arrives, this must be handled also
{
tyid = GetTypeIdByGuid(uguid);
logerror("Got UpdateObject_Movement for unknown object "I64FMT". Using typeid %u",uguid,(uint32)tyid);
}
if(obj)
this->_MovementUpdate(tyid,uguid,recvPacket);
}
break;
@ -315,13 +322,23 @@ void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& r
void WorldSession::_ValuesUpdate(uint64 uguid, WorldPacket& recvPacket)
{
Object *obj = objmgr.GetObj(uguid);
uint8 blockcount;
uint8 blockcount,tyid;
uint32 value, masksize, valuesCount;
float fvalue;
if (obj)
if(obj)
{
valuesCount = obj->GetValuesCount();
tyid = obj->GetTypeId();
}
else
{
logcustom(1,RED,"Got UpdateObject_Values for unknown object "I64FMT,uguid);
tyid = GetTypeIdByGuid(uguid); // can cause problems with TYPEID_CONTAINER!!
valuesCount = GetValuesCountByTypeId(tyid);
}
recvPacket >> blockcount;
masksize = blockcount << 2; // each sizeof(uint32) == <4> * sizeof(uint8) // 1<<2 == <4>
UpdateMask umask;
@ -330,11 +347,17 @@ void WorldSession::_ValuesUpdate(uint64 uguid, WorldPacket& recvPacket)
recvPacket.read((uint8*)updateMask, masksize);
umask.SetMask(updateMask);
//delete [] updateMask; // will be deleted at ~UpdateMask() !!!!
logdev("ValuesUpdate TypeId=%u GUID="I64FMT" pObj=%X Blocks=%u Masksize=%u",obj->GetTypeId(),uguid,obj,blockcount,masksize);
logdev("ValuesUpdate TypeId=%u GUID="I64FMT" pObj=%X Blocks=%u Masksize=%u",tyid,uguid,obj,blockcount,masksize);
// just in case the object does not exist, and we have really a container instead of an item, and a value in
// the container fields is set, THEN we have a problem. this should never be the case; it can be fixed in a
// more correct way if there is the need.
// (-> valuesCount smaller then it should be might skip a few bytes and corrupt the packet)
for (uint32 i = 0; i < valuesCount; i++)
{
if (umask.GetBit(i))
{
if(obj)
{
if(IsFloatField(obj->GetTypeMask(),i))
{
@ -348,15 +371,13 @@ void WorldSession::_ValuesUpdate(uint64 uguid, WorldPacket& recvPacket)
obj->SetUInt32Value(i, value);
logdev("-> Field[%u] = %u",i,value);
}
}
}
}
else
{
logerror("Got UpdateObject_Values for unknown object "I64FMT,uguid);
recvPacket >> value; // drop the value, since object doesnt exist (always 4 bytes)
}
}
}
}
void WorldSession::_QueryObjectInfo(uint64 guid)

View File

@ -1028,7 +1028,7 @@ void WorldSession::_HandleEmoteOpcode(WorldPacket& recvPacket)
}
if(name.empty())
{
if(o->IsPlayer())
if(IS_PLAYER_GUID(guid))
{
name = GetOrRequestPlayerName(guid);
if(name.empty())