* 90% working UPDATE_OBJECT stuff, just bags are missing (need to make the class for bags).

* need to remove lots of debug output later, after bags are done.
* fixed ObjMgr. better store objects in only 1 list instead of storing them in 1 list per type.
* eased config: if you modify the conf files during runtime, just type "config" in the console and the changes will be applied.
This commit is contained in:
False.Genesis 2007-02-25 19:25:15 +00:00
parent 0a346b4a4d
commit d208bb3ec1
14 changed files with 209 additions and 200 deletions

View File

@ -4,15 +4,8 @@
LOG * DefScript StartUp [${@version_short}]...
// Load required conf files.
LOADCONF PseuWoW.conf
LOADCONF users.conf
// Apply the configureation
APPLYCONF
// Apply user permissions
APPLYPERMISSIONS
// loads & applies the configuration
CONFIG
// preload the scripts, however its not important to load them now.
//they will get loaded automatically if needed

9
bin/scripts/config.def Normal file
View File

@ -0,0 +1,9 @@
// Load required conf files.
LOADCONF PseuWoW.conf
LOADCONF users.conf
// Apply the configureation
APPLYCONF
// Apply user permissions
APPLYPERMISSIONS

View File

@ -103,4 +103,10 @@ Item::Item()
_valuescount = ITEM_END;
_slot = 0;
//_bag = NULL; // not yet implemented
}
void Item::Create(uint64 guid)
{
Object::Create(guid);
// what else?
}

View File

@ -392,6 +392,7 @@ class Item : public Object
{
public:
Item();
void Create(uint64);
uint8 GetSlot(void) { return _slot; }
void SetSlot(uint8 nr) { _slot = nr; }
//void SetProto(ItemProto *proto) { _proto = proto; }

View File

@ -8,37 +8,29 @@ ObjMgr::~ObjMgr()
{
delete *i;
}
// need to remove other objects also
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
{
delete *i;
}
}
void ObjMgr::Remove(uint64 guid)
{
_RemovePlayer(guid);
_RemoveItem(guid);
//_RemoveGO(guid);
//_RemoveDO(guid);
//_RemoveNpc(guid);
//_RemoveCorpse(guid);
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
if((*i)->GetGUID() == guid)
_obj.erase(i);
delete *i;
}
void ObjMgr::_RemovePlayer(uint64 guid)
void ObjMgr::Add(Object *o)
{
for(PlayerList::iterator i = _players.begin(); i!=_players.end(); i++)
if((*i)->GetGUID() == guid)
{
delete *i;
_players.erase(i);
}
_obj.push_back(o);
}
void ObjMgr::Add(Player *o)
Object *ObjMgr::GetObj(uint64 guid)
{
_players.push_back(o);
}
Player *ObjMgr::GetPlayer(uint64 guid)
{
for(PlayerList::iterator i = _players.begin(); i!=_players.end(); i++)
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
if((*i)->GetGUID() == guid)
return (*i);
return NULL;
@ -76,42 +68,3 @@ bool ObjMgr::ItemNonExistent(uint32 id)
}
return false;
}
void ObjMgr::_RemoveItem(uint64 guid)
{
for(ItemList::iterator i = _items.begin(); i!=_items.end(); i++)
if((*i)->GetGUID() == guid)
{
delete *i;
_items.erase(i);
}
}
void ObjMgr::Add(Item *o)
{
_items.push_back(o);
}
Item *ObjMgr::GetItem(uint64 guid)
{
for(ItemList::iterator i = _items.begin(); i!=_items.end(); i++)
if((*i)->GetGUID() == guid)
return (*i);
return NULL;
}
Object *ObjMgr::GetObj(uint64 guid, uint8 type)
{
switch (type)
{
case TYPEID_ITEM: return (Object*)GetItem(guid);
case TYPEID_PLAYER: return (Object*)GetPlayer(guid);
// TODO: need the other object types here
}
return NULL;
}
// TODO: add more object class functions here

View File

@ -1,6 +1,7 @@
#ifndef _OBJMGR_H
#define _OBJMGR_H
#include "common.h"
#include <list>
#include "Object.h"
#include "Player.h"
@ -8,14 +9,7 @@
#include "Item.h"
typedef std::vector<ItemProto*> ItemProtoList;
//typedef std::list<Npc*> NpcList;
typedef std::list<Player*> PlayerList;
typedef std::list<Item*> ItemList;
//typedef std::list<Gameobject*> GOList;
//typedef std::list<DynamicObject*> DOList;
//typedef std::list<Corpse*> CorpseList;
typedef std::list<Object*> ObjectList;
class ObjMgr
{
@ -32,41 +26,14 @@ public:
void AddNonexistentItem(uint32);
bool ItemNonExistent(uint32);
// Player functions
void Add(Player*);
Player *GetPlayer(uint64 guid);
uint32 GetPlayersCount(void) { return _players.size(); }
// Item functions
void Add(Item*);
Item *GetItem(uint64);
uint32 GetItemsCount(void) { return _items.size(); }
// generic functions
// Object functions
void Add(Object*);
void Remove(uint64); // remove all objects with that guid (should be only 1 object in total anyway)
Object *GetObj(uint64 guid, uint8 type = 0);
private:
void _RemovePlayer(uint64);
void _RemoveItem(uint64);
//void _RemoveGO(uint64);
//void _RemoveDO(uint64);
//void _RemoveNpc(uint64);
//void _RemoveCorpse(uint64);
Object *GetObj(uint64 guid);
private:
ItemProtoList _iproto;
PlayerList _players;
ItemList _items;
ObjectList _obj;
std::vector<uint32> _noitem;
};

View File

@ -24,7 +24,7 @@ void Object::_InitValues()
memset(_uint32values, 0, _valuescount*sizeof(uint32));
}
void Object::_Create( uint64 guid )
void Object::Create( uint64 guid )
{
//ASSERT(_valuescount > 0);
if(!_uint32values)

View File

@ -2,6 +2,7 @@
#define _OBJECT_H
#include "UpdateFields.h"
#include "ObjectDefines.h"
enum TYPE
{
@ -71,9 +72,10 @@ public:
_uint32values[ index ] = value;
}
void Create(uint64 guid);
protected:
void _Create(uint64 guid);
void _InitValues(void);
uint16 _valuescount;

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.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 MANGOS_OBJECTDEFINES_H
#define MANGOS_OBJECTDEFINES_H
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
};
#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT )
#define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER )
#define IS_ITEM_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_ITEM )
#define IS_GAMEOBJECT_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_GAMEOBJECT )
#define IS_DYNAMICOBJECT_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_DYNAMICOBJECT )
#define IS_CORPSE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_CORPSE )
#define IS_PLAYER_CORPSE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER_CORPSE )
#define IS_TRANSPORT(Guid) ( GUID_HIPART(Guid) == HIGHGUID_TRANSPORT )
#endif

View File

@ -19,7 +19,7 @@ Player::Player() : Unit()
void Player::Create(uint64 guid)
{
Object::_Create(guid);
Object::Create(guid);
}

View File

@ -40,7 +40,7 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
uint64 uguid;
recvPacket >> ublocks >> unk8;
logdebug("UpdateObject: ublocks=%u unk=%u",ublocks,unk8);
while(true) // TODO: find out correct packet structure or this loop will fail!
while(recvPacket.rpos() < recvPacket.size())
{
recvPacket >> utype;
logdebug("-UpdateObject: utype=%u",utype);
@ -48,61 +48,15 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
{
case UPDATETYPE_VALUES:
{
uint8 blockcount, masksize;
uint32 value, valuesCount = GetValuesCountByTypeId(utype);
uguid = recvPacket.GetPackedGuid();
Object *obj = objmgr.GetObj(uguid,utype);
if (obj)
{
recvPacket >> blockcount;
masksize = blockcount * 4;
logdebug("--UPDATETYPE_VALUES: guid="I64FMT" blockcount=%u masksize=%d",uguid,blockcount, masksize);
uint32 *updateMask = new uint32[100];
UpdateMask umask;
umask.SetCount(masksize);
recvPacket.read((uint8*)updateMask, masksize);
umask.SetMask(updateMask);
for (uint32 i = 0; i < valuesCount; i++) // How do we get valuesCount?
{
if (umask.GetBit(i))
{
recvPacket >> value;
// These values are sent by the server as uint32 but must be stored at the client as float values
if( obj->isType(TYPE_UNIT) && (
i >= UNIT_FIELD_POWER1 && i <= UNIT_FIELD_MAXPOWER5 ||
i >= UNIT_FIELD_BASEATTACKTIME && i <= UNIT_FIELD_RANGEDATTACKTIME ||
i >= UNIT_FIELD_STR && i <= UNIT_FIELD_RESISTANCES + 6 )
|| obj->isType(TYPE_PLAYER) &&
i >= PLAYER_FIELD_POSSTAT0 && i <= PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6 )
{
obj->SetFloatValue(i, (float)value);
}
else
{
obj->SetUInt32Value(i, value);
}
//logdebug("Value (%d): %d", i, value);
}
}
}
else
{
logerror("--Got UpdateObject_Values for unknown object "I64FMT,uguid);
}
uguid = recvPacket.GetPackedGuid();
_ValuesUpdate(uguid,recvPacket);
}
break;
case UPDATETYPE_MOVEMENT:
{
recvPacket >> uguid; // the guid is NOT packed here!
Object *obj = objmgr.GetObj(uguid,utype);
Object *obj = objmgr.GetObj(uguid);
if(obj)
this->_MovementUpdate(obj->GetTypeId(),uguid,recvPacket);
else
@ -124,33 +78,37 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
{
case TYPEID_OBJECT: // no data to read
{
logerror("--Got UPDATE_OBJECT for Object!"); // getting this should not be the case
Object *obj = new Object();
obj->Create(uguid);
objmgr.Add(obj);
break;
}
case TYPEID_ITEM:
{
Item *item = new Item();
// item needs to be created, e.g. item->Create(uguid);
item->Create(uguid);
objmgr.Add(item);
break;
}
//case TYPEID_CONTAINER: // not yet handled
case TYPEID_UNIT:
{
logerror("--Got UPDATE_OBJECT for Unit!");
Unit *unit = new Unit();
unit->Create(uguid);
objmgr.Add(unit);
break;
}
case TYPEID_PLAYER:
{
logdetail("--DEBUG: create player");
recvPacket.hexlike();
Player *player = new Player();
player->Create(uguid);
objmgr.Add(player);
break;
Player *player = new Player();
player->Create(uguid);
objmgr.Add(player);
break;
}
}
this->_MovementUpdate(objtypeid, uguid, recvPacket);
this->_ValuesUpdate(uguid, recvPacket);
}
break;
@ -167,76 +125,149 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
default:
logerror("-Got unk updatetype 0x%X",utype);
logerror("## Read %u / %u bytes",recvPacket.rpos(),recvPacket.size());
return;
} // switch
} // while
logdebug("## Read %u / %u bytes",recvPacket.rpos(),recvPacket.size());
logdebug("## Parsing successful!!");
} // func
void WorldSession::_MovementUpdate(uint8 objtypeid, uint64 uguid, WorldPacket& recvPacket)
{
uint8 flags;
uint32 unk32,flags2,time,posCount,transtime;
float unkf,x,y,z,o,tx,ty,tz,to;
uint64 transguid;
float speedWalk, speedRun, speedSwimBack, speedSwim, speedWalkBack, speedTurn;
recvPacket >> flags;
logdebug("--- flags:%X",flags);
if(objtypeid==TYPEID_PLAYER)
{
uint32 flags, flags2, time;
uint64 tguid;
float nul;
float x, y, z, o;
float tx, ty, tz, to;
float speedWalk, speedRun, speedSwimBack, speedSwim, speedWalkBack, speedTurn;
recvPacket >> flags >> flags2 >> time;
recvPacket >> flags2 >> time;
logdebug("--- flags2=0x%X time=%u",flags2,time);
if (flags2 & 0x02000000) // On a transport
{
recvPacket >> x >> y >> z >> o >> tguid >> tx >> ty >> tz >> to;
recvPacket >> x >> y >> z >> o >> transguid >> tx >> ty >> tz >> to;
}
else
{
recvPacket >> x >> y >> z >> o;
}
recvPacket >> nul;
recvPacket >> unkf;
logdebug("--- DEBUG: %f == 0 ?",unkf);
if(flags2 & 0x2000) // Self update
{
// What is this data used for?
recvPacket >> nul;
recvPacket >> nul;
recvPacket >> nul;
recvPacket >> nul;
recvPacket >> unkf;
recvPacket >> unkf;
recvPacket >> unkf;
recvPacket >> unkf;
}
recvPacket >> speedWalk >> speedRun >> speedSwimBack >> speedSwim >> speedWalkBack >> speedTurn;
logdebug("TYPEID_PLAYER: OnTransport=%s x=%d y=%d z=%d o=%d", flags2 & 0x02000000 ? "true" : "false", x, y, z, o);
logdebug("--- TYPEID_PLAYER: walk=%f run=%f swimb=%f swim=%f walkb=%f turn=%f",speedWalk,speedRun,speedSwimBack,speedSwim,speedWalkBack,speedTurn);
logdebug("--- TYPEID_PLAYER: OnTransport=%s x=%f y=%f z=%f o=%f", flags2 & 0x02000000 ? "true" : "false", x, y, z, o);
}
if(objtypeid==TYPEID_UNIT)
{
uint32 flags2, unk, posCount;
float nul, unkf;
float x, y, z, o;
float speedWalk, speedRun, speedSwimBack, speedSwim, speedWalkBack, speedTurn;
recvPacket >> flags2 >> unk >> x >> y >> z >> o >> nul;
recvPacket >> flags2 >> unk32 >> x >> y >> z >> o >> unkf;
recvPacket >> speedWalk >> speedRun >> speedSwimBack >> speedSwim >> speedWalkBack >> speedTurn;
if (flags2 & 0x400000)
{
recvPacket >> unk >> unk >> unk >> unk >> posCount;
recvPacket >> unk32 >> unk32 >> unk32 >> unk32 >> posCount;
for (uint8 i = 0; i < posCount + 1; i++)
{
recvPacket >> unkf >> unkf >> unkf; // Some x, y, z value
}
}
logdebug("TYPEID_UNIT: 0x400000 flag=%s x=%d y=%d z=%d o=%d", flags2 & 0x400000 ? "true" : "false", x, y, z, o);
logdebug("--- TYPEID_UNIT: walk=%f run=%f swimb=%f swim=%f walkb=%f turn=%f",speedWalk,speedRun,speedSwimBack,speedSwim,speedWalkBack,speedTurn);
logdebug("--- TYPEID_UNIT: flag=%s x=%f y=%f z=%f o=%f", flags2 & 0x400000 ? "true" : "false", x, y, z, o);
}
if( (objtypeid==TYPEID_CORPSE) || (objtypeid==TYPEID_GAMEOBJECT) || (objtypeid==TYPEID_DYNAMICOBJECT))
{
float x, y, z, o;
recvPacket >> x >> y >> z >> o;
// TODO: Check for transport and corpse extra data
if(GUID_HIPART(uguid) != HIGHGUID_TRANSPORT)
{
recvPacket >> x >> y >> z;
}
else
{
recvPacket >> unk32 >> unk32 >> unk32; // should be 0?
}
recvPacket >> o;
}
recvPacket >> unk32; // (uint32)0x1
logdebug("--- REFERENCE: %u (should be = 1)",unk32);
if ((GUID_HIPART(uguid) == HIGHGUID_TRANSPORT))
{
recvPacket >> transtime;
}
if( GUID_HIPART(uguid) == HIGHGUID_PLAYER_CORPSE)
recvPacket >> unk32; // ??
}
void WorldSession::_ValuesUpdate(uint64 uguid, WorldPacket& recvPacket)
{
Object *obj = objmgr.GetObj(uguid);
uint8 blockcount;
uint32 value, masksize, valuesCount;
if (obj)
{
valuesCount = obj->GetValuesCount();
recvPacket >> blockcount;
masksize = blockcount << 2; // each sizeof(uint32) == <4> * sizeof(uint8) // 1<<2 == <4>
logdebug("--UPDATETYPE_VALUES: guid="I64FMT" values=%u blockcount=%u masksize=%d",uguid,valuesCount,blockcount, masksize);
UpdateMask umask;
uint32 *updateMask = new uint32[blockcount];
umask.SetCount(masksize);
recvPacket.read((uint8*)updateMask, masksize);
umask.SetMask(updateMask);
//delete [] updateMask; // will be deleted at ~UpdateMask() !!!!
for (uint32 i = 0; i < valuesCount; i++)
{
if (umask.GetBit(i))
{
recvPacket >> value;
// TODO: which values are float and which values are uin32 ??!
if( obj->isType(TYPE_UNIT) && (
i >= UNIT_FIELD_POWER1 && i <= UNIT_FIELD_MAXPOWER5 ||
i >= UNIT_FIELD_BASEATTACKTIME && i <= UNIT_FIELD_RANGEDATTACKTIME ||
i >= UNIT_FIELD_STR && i <= UNIT_FIELD_RESISTANCES + 6 )
|| obj->isType(TYPE_PLAYER) &&
i >= PLAYER_FIELD_POSSTAT0 && i <= PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6 )
{
obj->SetFloatValue(i, (float)value);
}
else
{
obj->SetUInt32Value(i, value);
}
logdebug("--- Value (%d): %d", i, value);
}
}
}
else
{
logerror("--Got UpdateObject_Values for unknown object "I64FMT,uguid);
}
}

View File

@ -93,6 +93,7 @@ private:
void _HandleInitialSpellsOpcode(WorldPacket& recvPacket);
void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode
void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ...
PseuInstance *_instance;
WorldSocket *_socket;

View File

@ -280,6 +280,9 @@
<File
RelativePath=".\Client\World\Object.h">
</File>
<File
RelativePath=".\Client\World\ObjectDefines.h">
</File>
<File
RelativePath=".\Client\World\ObjMgr.cpp">
</File>

View File

@ -12,7 +12,7 @@
#define CODEDEB(code) (code;)
#endif
#define ASSERT( assertion ) { if( !(assertion) ) { fprintf( stderr, "\n%s:%i ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, #assertion ); throw "Assertion Failed";
#define ASSERT( assertion ) { if( !(assertion) ) { fprintf( stderr, "\n%s:%i ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, #assertion ); throw "Assertion Failed"; }}