rendered paste bodyusing System;
using System.Globalization;
using RunServer.Common;
using RunWoW.Accounting;
using RunWoW.Common;
using RunWoW.Misc;
using RunWoW.Objects;
namespace RunWoW.GamePackets
{
[PacketHandlerClass()]
public class Movement
{/*
private struct MovementJob : IJob
{
private ClientBase m_client;
private BinReader m_data;
private CMSG m_msgId;
public ExecutionPriority ExecutionPriority
{
get { return ExecutionPriority.Primary; }
}
public string Name
{
get { return m_msgId.ToString(); }
}
public bool Empty
{
get { return false; }
}
public MovementJob(ClientBase client, BinReader data, CMSG msgId)
{
m_client = client;
m_data = data;
m_data.NoDispose = true;
m_msgId = msgId;
}
public void Execute(object state)
{
try
{
ProcessMovement(m_client, m_data, m_msgId);
}
finally
{
m_data.Clean();
}
}
}
private static JobQueue[] m_moveJobs = new JobQueue[10];
static Movement()
{
for (int i = 0; i < m_moveJobs.Length; i++)
{
m_moveJobs[i] = new JobQueue(true, 1000);
m_moveJobs[i].Start(CultureInfo.CurrentCulture);
}
}
*/
public static ShortPacket MakeMovement(SMSG msg, LivingObject living, int moveTime, out int timePos)
{
ShortPacket pkg = new ShortPacket(msg);
pkg.WriteGuid(living.GUID);
pkg.Write(living.MovementFlags);
timePos = pkg.BaseStream.Position;
pkg.Write(0);
pkg.WriteVector(living.Position);
pkg.Write(living.Facing);
pkg.Write(moveTime);
return pkg;
}
[PacketHandler(CMSG.MOVE_START_FORWARD)]
[PacketHandler(CMSG.MOVE_START_BACKWARD)]
[PacketHandler(CMSG.MOVE_STOP)]
[PacketHandler(CMSG.MOVE_START_STRAFE_LEFT)]
[PacketHandler(CMSG.MOVE_START_STRAFE_RIGHT)]
[PacketHandler(CMSG.MOVE_STOP_STRAFE)]
[PacketHandler(CMSG.MOVE_JUMP)]
[PacketHandler(CMSG.MOVE_FALL_LAND)]
[PacketHandler(CMSG.MOVE_SET_FACING)]
[PacketHandler(CMSG.MOVE_HEARTBEAT)]
[PacketHandler(CMSG.MOVE_STOP_TURN)]
[PacketHandler(CMSG.MOVE_START_SWIM)]
[PacketHandler(CMSG.MOVE_STOP_SWIM)]
[PacketHandler(CMSG.MOVE_START_TURN_LEFT)]
[PacketHandler(CMSG.MOVE_START_TURN_RIGHT)]
[PacketHandler(CMSG.MOVE_FEATHER_FALL)]
[PacketHandler(CMSG.MOVE_START_PITCH_UP)]
[PacketHandler(CMSG.MOVE_START_PITCH_DOWN)]
[PacketHandler(CMSG.MOVE_STOP_PITCH)]
[PacketHandler(CMSG.MOVE_SET_RUN_MODE)]
[PacketHandler(CMSG.MOVE_SET_WALK_MODE)]
[PacketHandler(CMSG.MOVE_SET_PITCH)]
public static void OnMovement(ClientBase client, BinReader data, int msgID)
{
ClientData Client = (ClientData) client.Data;
if (Client == null || Client.Player == null || Client.Player.MapTile == null || data.Length <= 6)
return;
if (Client.Player.WorldChange == WCHANGESTATE.CHANGING)
return;
/* m_moveJobs[Client.CharacterID%m_moveJobs.Length].Enqueue(new MovementJob(client, data, (CMSG) msgID));
}
private static void ProcessMovement(ClientBase client, BinReader data, CMSG msgID)
{
ClientData Client = (ClientData) client.Data;
if (Client == null || Client.Player == null || Client.Player.MapTile == null || data.Length <= 6)
return;
if (Client.Player.WorldChange == WCHANGESTATE.CHANGING)
return;
/*switch ((CMSG)msgID)
{
case CMSG.MOVE_START_FORWARD:
case CMSG.MOVE_START_BACKWARD:
case CMSG.MOVE_START_STRAFE_LEFT:
case CMSG.MOVE_START_STRAFE_RIGHT:
case CMSG.MOVE_START_SWIM:
case CMSG.MOVE_HEARTBEAT:
if (Client.Player.Rooted || Client.Player.Stunned)
{
MonsterMove.FixPosition(Client.Player);
return;
}
Client.Player.Moved(data.InnerTime);
break;
case CMSG.MOVE_STOP:
case CMSG.MOVE_STOP_SWIM:
case CMSG.MOVE_STOP_TURN:
case CMSG.MOVE_STOP_STRAFE:
break;
default:
break;
}*/
int movementFlags = data.ReadInt32();
int moveTime = 0;
try
{
int startTime = data.ReadInt32();
if (Client.ClientTimeDelay == 0)
Client.ClientTimeDelay = Utility.PreciseTimestamp() - startTime;
int delay = startTime - Client.ClientTime;
//Console.WriteLine("{3}, {0} with movement flags 0x{1,4:X4}, time {2}, delay {3}", (CMSG)msgID, Client.Player.MovementFlags, new DateTime(startTime * TimeSpan.TicksPerMillisecond).ToString("HH:mm:ss.ffff"), delay);
Vector playerPosition = data.ReadVector();
float playerFacing = data.ReadSingle();
moveTime = data.ReadInt32();
bool isTransporting = (Client.Player.MovementFlags & 0x2000000) == 0x2000000 ||
Client.Player.WorldMapID == 369;
//bool isSwimming = (Client.Player.MovementFlags & 0x200000) == 0x200000;
//bool isFalling = (Client.Player.MovementFlags & 0x2000) == 0x2000;
if ((!isTransporting && playerPosition.DistanceFlat(Client.Player.Position) /*moved*/> 40f))
{
Teleport.TeleportTo(Client.Player.Position, Client.Player);
return;
}
//if ((Client.Player.MovementFlags & 31) != 0)
{
if (Client.Player.Rooted || Client.Player.Stunned || Client.Player.NoControl)
{
Client.Player.MovementFlags &= ~31;
//playerPosition = Client.Player.Position;
MonsterMove.FixPosition(Client.Player, delay);
return;
}
else
if (!Client.Player.Moved(data.InnerTime, playerPosition.DistanceAvr(Client.Player.Position) >0.1f))
return; // that movement is obsolete and can harm cast, etc
}
DateTime packetTime = CustomDateTime.Now.AddMilliseconds(delay);
//Client.AddMovementPosition(playerPosition.Clone(), delay);
// !!!!!!!!!!!!!!!
//Client.Player.MapTile.Map.Move(Client.Player); // !!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!
switch ((CMSG) msgID)
{
case CMSG.MOVE_FALL_LAND:
if (Client.Player.Attackable && Client.Player.WorldChange != WCHANGESTATE.CHANGED)
{
float height = Client.Player.LastPos.Z - playerPosition.Z;
if (height > Constants.FallDamageMinHeightConst)
{
float damage = Client.Player.MaxHealth*height*Constants.FallDamageConst;
Client.Player.TakeEnvironmentDamage(Client.Player, null, (DAMAGETYPE) 2, damage, damage);
}
//if (Constants.FallDamageTime > moveTime)
//{
// float damage = Client.Player.MaxHealth * (moveTime - Constants.FallDamageTime) * Constants.FallDamageConst;
// Client.Player.TakeEnvironmentDamage(Client.Player, 0, (DAMAGETYPE) 2, damage, damage);
//}
}
goto case CMSG.MOVE_JUMP;
case CMSG.MOVE_HEARTBEAT:
/*if ((Client.Player.MovementFlags & 0x2000) != 0)*/
goto case CMSG.MOVE_JUMP;
/*break;*/
case CMSG.MOVE_SET_FACING:
if ((Client.Player.MovementFlags & 0x31) == 0)
goto case CMSG.MOVE_JUMP;
break; // send change facing only while standing
case CMSG.MOVE_START_FORWARD:
case CMSG.MOVE_START_BACKWARD:
case CMSG.MOVE_STOP:
case CMSG.MOVE_START_STRAFE_LEFT:
case CMSG.MOVE_START_STRAFE_RIGHT:
case CMSG.MOVE_STOP_STRAFE:
case CMSG.MOVE_JUMP:
case CMSG.MOVE_START_TURN_LEFT:
case CMSG.MOVE_START_TURN_RIGHT:
case CMSG.MOVE_STOP_TURN:
case CMSG.MOVE_START_SWIM:
case CMSG.MOVE_STOP_SWIM:
if (packetTime >= Client.LastMovement)
{
Client.Player.Facing = playerFacing;
Client.Player.Position = playerPosition;
Client.LastMovement = packetTime;
Client.Player.MovementFlags = movementFlags;
}
else
return;
int plength = data.BaseStream.Length - data.BaseStream.Position;
int timePos;
ShortPacket pkg = MakeMovement((SMSG) msgID, Client.Player, moveTime, out timePos);
if (plength > 0)
pkg.Write(data.ReadBytes(plength));
#if true
Client.Player.MapTile.SendSurroundingTimed(pkg, Client.Player, Client.Player, timePos, delay);
#else
pkg.Set(timePos, startTime);
Client.Player.MapTile.SendSurrounding(pkg, Client.Player, Client.Player);
#endif
/*if (Client.Player.Group != null)
Client.Player.Group.SendExcept(pkg, Client.Player);*/
break;
}
}
catch (Exception e)
{
Console.WriteLine("Exception {3} while reading move packet {0}, packet length {1}, movement flags {2}", (CMSG) msgID,
data.Length, Client.Player.MovementFlags, e.ToString());
}
Client.Player.LastPos = Client.Player.Position.Clone();
if (Client.Player.WorldChange == WCHANGESTATE.CHANGED)
Client.Player.WorldChange = WCHANGESTATE.NONE;
}
}
}