diff --git a/src/Client/Realm/RealmSession.cpp b/src/Client/Realm/RealmSession.cpp index 65da43f..834ee6b 100644 --- a/src/Client/Realm/RealmSession.cpp +++ b/src/Client/Realm/RealmSession.cpp @@ -137,9 +137,14 @@ void RealmSession::Update(void) ByteBuffer *pkt; uint8 cmd; - if( _sh.GetCount() ) - { + if( _sh.GetCount() ) // the socket will remove itself from the handler if it got closed _sh.Select(0,0); + else // so we just need to check if the socket doesnt exist or if it exists but isnt valid anymore. + { // if thats the case, we dont need the session anymore either + if(!_socket || (_socket && !_socket->IsOk())) + { + SetMustDie(); + } } while(pktQueue.size()) diff --git a/src/Client/World/Player.h b/src/Client/World/Player.h index 0f00cf7..19885cf 100644 --- a/src/Client/World/Player.h +++ b/src/Client/World/Player.h @@ -204,6 +204,7 @@ public: void SetActionButtons(WorldPacket &data); void AddSpell(uint32 spellid, uint16 spellslot); void RemoveSpell(uint32 spellid); + void ClearSpells(void) { _spells.clear(); } uint64 GetTarget(void) { return _target; } void SetTarget(uint64 guid) { _target = guid; } // should only be called by WorldSession::SendSetSelection() !! bool HasSpell(uint32 spellid) { return GetSpellSlot(spellid) != 0; } diff --git a/src/Client/World/UpdateData.cpp b/src/Client/World/UpdateData.cpp index a7bf5d3..f184ef3 100644 --- a/src/Client/World/UpdateData.cpp +++ b/src/Client/World/UpdateData.cpp @@ -71,6 +71,13 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket) uint8 objtypeid; recvPacket >> objtypeid; logdebug("Create Object type %u with guid "I64FMT,objtypeid,uguid); + // dont create objects if already present in memory. + // recreate every object except ourself! + if( uguid != GetGuid() && objmgr.GetObj(uguid)) + { + logdev("- already exists, deleting old , creating new object"); + objmgr.Remove(uguid); + } switch(objtypeid) { diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index 0402134..8ed8037 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -93,12 +93,15 @@ void WorldSession::SendWorldPacket(WorldPacket &pkt) void WorldSession::Update(void) { - if( _sh.GetCount() ) // the socketwil remove itself from the handler if it got closed + if( _sh.GetCount() ) // the socket will remove itself from the handler if it got closed _sh.Select(0,0); else // so we just need to check if the socket doesnt exist or if it exists but isnt valid anymore. { // if thats the case, we dont need the session anymore either if(!_socket || (_socket && !_socket->IsOk())) + { + _OnLeaveWorld(); SetMustDie(); + } } @@ -202,6 +205,7 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const {SMSG_CHANNEL_LIST, &WorldSession::_HandleChannelListOpcode}, {SMSG_EMOTE, &WorldSession::_HandleEmoteOpcode}, {SMSG_TEXT_EMOTE, &WorldSession::_HandleTextEmoteOpcode}, + {SMSG_NEW_WORLD, &WorldSession::_HandleNewWorldOpcode}, // table termination { 0, NULL } @@ -624,23 +628,36 @@ void WorldSession::_HandleMovementOpcode(WorldPacket& recvPacket) void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket) { - uint8 unk; - uint16 unk1, unk2; - uint32 unk3, unk4; + uint32 unk32,time; uint64 guid; - float x, y, z, o, ang; + float x, y, z, o; - recvPacket >> unk >> guid >> unk3 >> unk1 >> unk2 >> o >> x >> y >> z >> ang >> unk4; + guid = recvPacket.GetPackedGuid(); + recvPacket >> unk32 >> unk32 >> time >> x >> y >> z >> o >> unk32; logdetail("Got teleported, data: x: %f, y: %f, z: %f, o: %f, guid: "I64FMT, x, y, z, o, guid); + // TODO: put this into a capsule class later, that autodetects movement flags etc. WorldPacket response; response.SetOpcode(MSG_MOVE_FALL_LAND); - response << uint32(0) << uint32(0) << x << y << z << o << uint32(0); + response << uint32(0) << (uint32)getMSTime(); // no flags; time correct? + response << x << y << z << o << uint32(0); SendWorldPacket(response); } +void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket) +{ + uint32 mapid; + float x,y,z,o; + // we assume we are NOT on a transport! + // else we had to do the following before: + // recvPacket >> tmapid >> tx >> ty >> tz >> to; + recvPacket >> mapid >> x >> y >> z >> o; + GetMyChar()->ClearSpells(); // will be resent by server + // clear action buttons +} + void WorldSession::_HandleChannelNotifyOpcode(WorldPacket& recvPacket) { _channels->HandleNotifyOpcode(recvPacket); diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index b00a86b..221a716 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -87,6 +87,7 @@ private: void _HandleChannelListOpcode(WorldPacket& recvPacket); void _HandleEmoteOpcode(WorldPacket& recvPacket); void _HandleTextEmoteOpcode(WorldPacket& recvPacket); + void _HandleNewWorldOpcode(WorldPacket& recvPacket); void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ... diff --git a/src/shared.vcproj b/src/shared.vcproj index 26baafe..269e924 100644 --- a/src/shared.vcproj +++ b/src/shared.vcproj @@ -38,7 +38,8 @@ + Name="VCLibrarianTool" + AdditionalDependencies="winmm.lib"/> #include #include -#include #include +#include #include "tools.h" -#ifndef _WIN32 -# include -# include -#else +#if PLATFORM == PLATFORM_WIN32 # include +# include +# include +#else +# include +# if defined(__FreeBSD__) || defined(__APPLE_CC__) +# include +# endif +# include #endif -void printchex(std::string in, bool spaces=true){ + +void printchex(std::string in, bool spaces=true) +{ unsigned int len=0,i; len=in.length(); printf("["); @@ -24,7 +31,8 @@ void printchex(std::string in, bool spaces=true){ printf("]\n"); } -void printchex(char *in, uint32 len, bool spaces=true){ +void printchex(char *in, uint32 len, bool spaces=true) +{ unsigned int i; printf("["); if(spaces) @@ -147,6 +155,7 @@ bool FileExists(std::string fn) return false; } +// must return true if creating the directory was successful bool CreateDir(const char *dir) { bool result; @@ -160,4 +169,20 @@ bool CreateDir(const char *dir) return result; } +// current system time in ms +uint32 getMSTime(void) +{ + uint32 time_in_ms = 0; +#if PLATFORM == PLATFORM_WIN32 + time_in_ms = timeGetTime(); +#else + struct timeb tp; + ftime(&tp); + + time_in_ms = tp.time * 1000 + tp.millitm; +#endif + + return time_in_ms; +} + diff --git a/src/shared/tools.h b/src/shared/tools.h index c104d9a..839046a 100644 --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -18,5 +18,6 @@ std::string toHexDump(uint8* array,uint32 size,bool spaces=true); std::deque GetFileList(std::string); bool FileExists(std::string); bool CreateDir(const char*); +uint32 getMSTime(void); #endif \ No newline at end of file