diff --git a/bin/scripts/_startup.def b/bin/scripts/_startup.def index 916ed04..8fc790c 100644 --- a/bin/scripts/_startup.def +++ b/bin/scripts/_startup.def @@ -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 diff --git a/bin/scripts/config.def b/bin/scripts/config.def new file mode 100644 index 0000000..ec672a4 --- /dev/null +++ b/bin/scripts/config.def @@ -0,0 +1,9 @@ +// Load required conf files. +LOADCONF PseuWoW.conf +LOADCONF users.conf + +// Apply the configureation +APPLYCONF + +// Apply user permissions +APPLYPERMISSIONS \ No newline at end of file diff --git a/src/Client/World/Item.cpp b/src/Client/World/Item.cpp index 91c8955..13f933c 100644 --- a/src/Client/World/Item.cpp +++ b/src/Client/World/Item.cpp @@ -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? } \ No newline at end of file diff --git a/src/Client/World/Item.h b/src/Client/World/Item.h index 81ab938..93c702b 100644 --- a/src/Client/World/Item.h +++ b/src/Client/World/Item.h @@ -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; } diff --git a/src/Client/World/ObjMgr.cpp b/src/Client/World/ObjMgr.cpp index ab1b168..9d20e09 100644 --- a/src/Client/World/ObjMgr.cpp +++ b/src/Client/World/ObjMgr.cpp @@ -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 - - diff --git a/src/Client/World/ObjMgr.h b/src/Client/World/ObjMgr.h index c897f4b..6a49ee7 100644 --- a/src/Client/World/ObjMgr.h +++ b/src/Client/World/ObjMgr.h @@ -1,6 +1,7 @@ #ifndef _OBJMGR_H #define _OBJMGR_H +#include "common.h" #include #include "Object.h" #include "Player.h" @@ -8,14 +9,7 @@ #include "Item.h" typedef std::vector ItemProtoList; -//typedef std::list NpcList; -typedef std::list PlayerList; -typedef std::list ItemList; -//typedef std::list GOList; -//typedef std::list DOList; -//typedef std::list CorpseList; - - +typedef std::list 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 _noitem; }; diff --git a/src/Client/World/Object.cpp b/src/Client/World/Object.cpp index 37e738b..0be546a 100644 --- a/src/Client/World/Object.cpp +++ b/src/Client/World/Object.cpp @@ -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) diff --git a/src/Client/World/Object.h b/src/Client/World/Object.h index dd01a34..f83ed71 100644 --- a/src/Client/World/Object.h +++ b/src/Client/World/Object.h @@ -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; diff --git a/src/Client/World/ObjectDefines.h b/src/Client/World/ObjectDefines.h new file mode 100644 index 0000000..296a228 --- /dev/null +++ b/src/Client/World/ObjectDefines.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2005,2006,2007 MaNGOS + * + * 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 diff --git a/src/Client/World/Player.cpp b/src/Client/World/Player.cpp index d45ab6a..0f6175e 100644 --- a/src/Client/World/Player.cpp +++ b/src/Client/World/Player.cpp @@ -19,7 +19,7 @@ Player::Player() : Unit() void Player::Create(uint64 guid) { - Object::_Create(guid); + Object::Create(guid); } diff --git a/src/Client/World/UpdateData.cpp b/src/Client/World/UpdateData.cpp index 5808b79..0530be0 100644 --- a/src/Client/World/UpdateData.cpp +++ b/src/Client/World/UpdateData.cpp @@ -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); + } + } \ No newline at end of file diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index 7b7352b..f1b0344 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -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; diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index 05a9f64..dcc1a3a 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -280,6 +280,9 @@ + + diff --git a/src/shared/DebugStuff.h b/src/shared/DebugStuff.h index d6bb98e..f54b155 100644 --- a/src/shared/DebugStuff.h +++ b/src/shared/DebugStuff.h @@ -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"; }}