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