MovementHandler.cpp
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:6k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. // Copyright (C) 2004 Team Python
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. #include "MovementHandler.h"
  17. #include "NetworkInterface.h"
  18. #include "Opcodes.h"
  19. #include "Log.h"
  20. #include "Character.h"
  21. #include "WorldServer.h"
  22. #include "UpdateMask.h"
  23. #include <time.h>
  24. #include "math.h"
  25. #define world WorldServer::getSingleton()
  26. MovementHandler::MovementHandler()
  27. {
  28. }
  29. MovementHandler::~MovementHandler()
  30. {
  31. }
  32. void MovementHandler::HandleMsg( wowWData & recv_data, GameClient *pClient )
  33. {
  34.     wowWData data;
  35.     bool updateself = false;
  36.     // Was getting crashes receiving heartbeats from players that had logged out
  37.     // So dont go any further if they have no current character
  38.     if (!pClient->IsInWorld())  return;
  39.     //printf("WORLD: Movement Opcode 0x%.4Xn", recv_data.opcode );
  40.     switch (recv_data.opcode)
  41.     {
  42.     case MSG_MOVE_HEARTBEAT:
  43.         {
  44.             data.clear();
  45.             data.Initialise( recv_data.length+8, MSG_MOVE_HEARTBEAT);
  46.             if( pClient->getCurrentChar() && !pClient->getCurrentChar( )->setPosition( recv_data.data+8 ) ) {
  47.                 wowWData movedata;
  48.                 pClient->getCurrentChar( )->TeleportAck( &movedata, pClient->getCurrentChar( )->getPositionX( ), pClient->getCurrentChar( )->getPositionY( ), pClient->getCurrentChar( )->getPositionZ( ) );
  49.                 pClient->getNetwork( )->sendWData(&movedata);
  50.             }
  51.             // GUID of player who sent heartbeat
  52.             uint32 guid = pClient->getCurrentChar()->getGUID();
  53.             memcpy(data.data, &guid, 4);
  54.             data.data[4] = 0x00;
  55.             data.data[5] = 0x00;
  56.             data.data[6] = 0x00;
  57.             data.data[7] = 0x00;
  58.             memcpy(data.data+8, recv_data.data, recv_data.length);
  59.             //memcpy(data.data+8, recv_data.data+8, recv_data.length-8);
  60. // if (pClient->getCurrentChar()->getDeathState() != CORPSE)
  61. if (pClient->getCurrentChar()->getDeathState() == ALIVE)
  62. world.SendAreaMessage(&data, pClient, 0);
  63. //            pClient->getCurrentChar()->SendMessageToSet(&data, false);
  64. if (pClient->getCurrentChar()->isWorldPort())
  65. pClient->getCurrentChar()->setWorldPort(false);
  66.         }break;
  67.     case MSG_MOVE_JUMP: case MSG_MOVE_START_FORWARD : case MSG_MOVE_START_BACKWARD: case MSG_MOVE_SET_FACING:
  68.     case MSG_MOVE_STOP: case MSG_MOVE_START_STRAFE_LEFT: case MSG_MOVE_START_STRAFE_RIGHT: case MSG_MOVE_STOP_STRAFE:
  69.     case MSG_MOVE_START_TURN_LEFT: case MSG_MOVE_START_TURN_RIGHT:  case MSG_MOVE_STOP_TURN: case MSG_MOVE_START_PITCH_UP :
  70.     case MSG_MOVE_START_PITCH_DOWN: case MSG_MOVE_STOP_PITCH : case MSG_MOVE_SET_RUN_MODE: case MSG_MOVE_SET_WALK_MODE:
  71.     case MSG_MOVE_SET_PITCH: case MSG_MOVE_START_SWIM:
  72.     case MSG_MOVE_STOP_SWIM:
  73.         {
  74.             if( !pClient->getCurrentChar( )->setPosition( recv_data.data+8 ) ) {
  75.                 wowWData movedata;
  76.                 pClient->getCurrentChar( )->TeleportAck( &movedata, pClient->getCurrentChar( )->getPositionX( ), pClient->getCurrentChar( )->getPositionY( ), pClient->getCurrentChar( )->getPositionZ( ) );
  77.                 pClient->getNetwork( )->sendWData(&movedata);
  78.                 pClient->getCurrentChar( )->getPosition( recv_data.data+8 );
  79.             }
  80.             // GUID of player who sent the message
  81.             uint32 guid = pClient->getCurrentChar()->getGUID();
  82.             data.clear();
  83.             data.Initialise( 8+recv_data.length, recv_data.opcode);
  84.             //data.Initialise( recv_data.length, recv_data.opcode);
  85.             memcpy(data.data, &guid, 4);
  86.             data.data[4] = 0x00;
  87.             data.data[5] = 0x00;
  88.             data.data[6] = 0x00;
  89.             data.data[7] = 0x00;
  90.             memcpy(data.data+8, recv_data.data, recv_data.length);
  91.             //memcpy(data.data+8, recv_data.data+8, recv_data.length-8);
  92. // if (pClient->getCurrentChar()->getDeathState() != CORPSE)
  93. if (pClient->getCurrentChar()->getDeathState() == ALIVE)
  94.             world.SendAreaMessage(&data, pClient, 0);
  95. //            pClient->getCurrentChar()->SendMessageToSet(&data, false);
  96.         }break;
  97.     case MSG_MOVE_WORLDPORT_ACK:
  98.         {
  99.             Log::getSingleton( ).outString( "WORLD: got MSG_MOVE_WORLDPORT_ACK." );
  100.             // Create myself for other clients
  101.             pClient->getCurrentChar()->SetPosToNewPos();
  102.             // Create Player Character
  103.             WorldServer::getSingleton().mObjectMgr.BuildAndSendCreatePlayer( pClient->getCurrentChar(), 1, NULL );
  104.             // Build the in-range set
  105.             WorldServer::getSingleton().CheckForInRangeObjects( pClient->getCurrentChar() );
  106.             // Send a message to other Clients that a new player has entered the world
  107.             std::list<wowWData*> msglist;
  108.             WorldServer::getSingleton().mObjectMgr.BuildCreatePlayerMsg( pClient->getCurrentChar(), &msglist, 0 );
  109.             std::list<wowWData*>::iterator msgitr;
  110.             for (msgitr = msglist.begin(); msgitr != msglist.end(); )
  111.             {
  112.                 wowWData *msg = (*msgitr);
  113.                 pClient->getCurrentChar()->SendMessageToSet(msg, false);
  114.                 delete msg;
  115.                 msgitr = msglist.erase(msgitr);
  116.             }
  117.         };
  118.     default: {}break;
  119.     }
  120. }