/// <summary> /// This is used to build a server side "Position Object" /// Usually Position Packet Should only be relayed /// The only purpose of this method is refreshing postion when there is Lag /// </summary> /// <param name="player"></param> public override void SendPlayerForgedPosition(GamePlayer player) { using (GSUDPPacketOut pak = new GSUDPPacketOut(GetPacketCode(eServerPackets.PlayerPosition))) { // PID pak.WriteShort((ushort)player.Client.SessionID); // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { player.Heading = player.Steed.Heading; pak.WriteShort(0x1800); } else { short rSpeed = player.CurrentSpeed; if (player.IsIncapacitated) { rSpeed = 0; } ushort content; if (rSpeed < 0) { content = (ushort)((Math.Abs(rSpeed) > 511 ? 511 : Math.Abs(rSpeed)) + 0x200); } else { content = (ushort)(rSpeed > 511 ? 511 : rSpeed); } if (!player.IsAlive) { content += 5 << 10; } else { ushort state = 0; if (player.IsSwimming) { state = 1; } if (player.IsClimbing) { state = 7; } if (player.IsSitting) { state = 4; } content += (ushort)(state << 10); } content += (ushort)(player.IsStrafing ? 1 << 13 : 0 << 13); pak.WriteShort(content); } // Get Off Corrd var offX = player.Position.X - player.CurrentZone.XOffset; var offY = player.Position.Y - player.CurrentZone.YOffset; pak.WriteShort((ushort)player.Position.Z); pak.WriteShort((ushort)offX); pak.WriteShort((ushort)offY); // Write Zone pak.WriteShort(player.CurrentZone.ZoneSkinID); // Copy Heading && Falling or Write Steed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { pak.WriteShort((ushort)player.Steed.ObjectID); pak.WriteShort((ushort)player.Steed.RiderSlot(player)); } else { // Set Player always on ground, this is an "anti lag" packet ushort contenthead = (ushort)(player.Heading + (true ? 0x1000 : 0)); pak.WriteShort(contenthead); // No Fall Speed. pak.WriteShort(0); } // Write Flags byte flagcontent = 0; if (player.IsDiving) { flagcontent += 0x04; } if (player.IsWireframe) { flagcontent += 0x01; } if (player.IsStealthed) { flagcontent += 0x02; } if (player.IsTorchLighted) { flagcontent += 0x80; } pak.WriteByte(flagcontent); // Write health + Attack byte healthcontent = (byte)(player.HealthPercent + (player.AttackState ? 0x80 : 0)); pak.WriteByte(healthcontent); // Write Remainings. pak.WriteByte(player.ManaPercent); pak.WriteByte(player.EndurancePercent); pak.FillString(player.CharacterClass.Name, 32); pak.WriteByte((byte)(player.RPFlag ? 1 : 0)); pak.WriteByte(0); // send last byte for 190+ packets SendUDP(pak); } // Update Cache m_gameClient.GameObjectUpdateArray[new Tuple <ushort, ushort>(player.CurrentRegionID, (ushort)player.ObjectID)] = GameTimer.GetTickCount(); }
/// <summary> /// This is used to build a server side "Position Object" /// Usually Position Packet Should only be relayed /// The only purpose of this method is refreshing postion when there is Lag /// </summary> public override void SendPlayerForgedPosition(GamePlayer player) { using (GSUDPPacketOut pak = new GSUDPPacketOut(GetPacketCode(eServerPackets.PlayerPosition))) { int heading = 4096 + player.Heading; pak.WriteFloatLowEndian(player.X); pak.WriteFloatLowEndian(player.Y); pak.WriteFloatLowEndian(player.Z); pak.WriteFloatLowEndian(player.CurrentSpeed); pak.WriteInt(0); // needs to be Zaxis speed pak.WriteShort((ushort)player.Client.SessionID); pak.WriteShort(player.CurrentZone.ZoneSkinID); // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { player.Heading = player.Steed.Heading; pak.WriteShort(0x1800); } else { short rSpeed = player.CurrentSpeed; if (player.IsIncapacitated) { rSpeed = 0; } ushort content; if (rSpeed < 0) { content = (ushort)((Math.Abs(rSpeed) > 511 ? 511 : Math.Abs(rSpeed)) + 0x200); } else { content = (ushort)(rSpeed > 511 ? 511 : rSpeed); } if (!player.IsAlive) { content += 5 << 10; } else { ushort state = 0; if (player.IsSwimming) { state = 1; } if (player.IsClimbing) { state = 7; } if (player.IsSitting) { state = 4; } content += (ushort)(state << 10); } content += (ushort)(player.IsStrafing ? 1 << 13 : 0 << 13); pak.WriteShort(content); } pak.WriteByte(0); pak.WriteByte(0); pak.WriteShort((ushort)heading); // Write Flags byte flagcontent = 0; if (player.IsDiving) { flagcontent += 0x04; } if (player.IsWireframe) { flagcontent += 0x01; } if (player.IsStealthed) { flagcontent += 0x02; } if (player.IsTorchLighted) { flagcontent += 0x80; } pak.WriteByte(flagcontent); pak.WriteByte((byte)(player.RPFlag ? 1 : 0)); pak.WriteByte(0); pak.WriteByte(player.HealthPercent); pak.WriteByte(player.ManaPercent); pak.WriteByte(player.EndurancePercent); SendUDP(pak); } // Update Cache m_gameClient.GameObjectUpdateArray[new Tuple <ushort, ushort>(player.CurrentRegionID, (ushort)player.ObjectID)] = GameTimer.GetTickCount(); }
public virtual void SendUDPInitReply() { var pak = new GSUDPPacketOut(GetPacketCode(eServerPackets.UDPInitReply)); Region playerRegion = null; if (!m_gameClient.Socket.Connected) return; if (m_gameClient.Player != null && m_gameClient.Player.CurrentRegion != null) playerRegion = m_gameClient.Player.CurrentRegion; if (playerRegion == null) pak.Fill(0x0, 0x18); else { //Try to fix the region ip so UDP is enabled! string ip = playerRegion.ServerIP; if (ip == "any" || ip == "0.0.0.0" || ip == "127.0.0.1" || ip.StartsWith("10.13.") || ip.StartsWith("192.168.")) ip = ((IPEndPoint) m_gameClient.Socket.LocalEndPoint).Address.ToString(); pak.FillString(ip, 22); pak.WriteShort(playerRegion.ServerPort); } SendUDP(pak, true); }
public virtual void SendObjectUpdate(GameObject obj) { Zone z = obj.CurrentZone; if (z == null || m_gameClient.Player == null || m_gameClient.Player.IsVisibleTo(obj) == false) { return; } var xOffsetInZone = (ushort) (obj.X - z.XOffset); var yOffsetInZone = (ushort) (obj.Y - z.YOffset); ushort xOffsetInTargetZone = 0; ushort yOffsetInTargetZone = 0; ushort zOffsetInTargetZone = 0; int speed = 0; ushort targetZone = 0; byte flags = 0; int targetOID = 0; if (obj is GameNPC) { var npc = obj as GameNPC; flags = (byte) (GameServer.ServerRules.GetLivingRealm(m_gameClient.Player, npc) << 6); if (m_gameClient.Account.PrivLevel < 2) { // no name only if normal player if ((npc.Flags & GameNPC.eFlags.CANTTARGET) != 0) flags |= 0x01; if ((npc.Flags & GameNPC.eFlags.DONTSHOWNAME) != 0) flags |= 0x02; } if ((npc.Flags & GameNPC.eFlags.STATUE) != 0) { flags |= 0x01; } if (npc.IsUnderwater) { flags |= 0x10; } if ((npc.Flags & GameNPC.eFlags.FLYING) != 0) { flags |= 0x20; } if (npc.IsMoving && !npc.IsAtTargetPosition) { speed = npc.CurrentSpeed; if (npc.TargetPosition.X != 0 || npc.TargetPosition.Y != 0 || npc.TargetPosition.Z != 0) { Zone tz = npc.CurrentRegion.GetZone(npc.TargetPosition.X, npc.TargetPosition.Y); if (tz != null) { xOffsetInTargetZone = (ushort) (npc.TargetPosition.X - tz.XOffset); yOffsetInTargetZone = (ushort) (npc.TargetPosition.Y - tz.YOffset); zOffsetInTargetZone = (ushort) (npc.TargetPosition.Z); //Dinberg:Instances - zoneSkinID for object positioning clientside. targetZone = tz.ZoneSkinID; } } if (speed > 0x07FF) { speed = 0x07FF; } else if (speed < 0) { speed = 0; } } GameObject target = npc.TargetObject; if (npc.AttackState && target != null && target.ObjectState == GameObject.eObjectState.Active && !npc.IsTurningDisabled) targetOID = (ushort) target.ObjectID; } var pak = new GSUDPPacketOut(GetPacketCode(eServerPackets.ObjectUpdate)); pak.WriteShort((ushort) speed); if (obj is GameNPC) { pak.WriteShort((ushort)(obj.Heading & 0xFFF)); } else { pak.WriteShort(obj.Heading); } pak.WriteShort(xOffsetInZone); pak.WriteShort(xOffsetInTargetZone); pak.WriteShort(yOffsetInZone); pak.WriteShort(yOffsetInTargetZone); pak.WriteShort((ushort) obj.Z); pak.WriteShort(zOffsetInTargetZone); pak.WriteShort((ushort) obj.ObjectID); pak.WriteShort((ushort) targetOID); //health if (obj is GameLiving) { pak.WriteByte((obj as GameLiving).HealthPercent); } else { pak.WriteByte(0); } //Dinberg:Instances - zoneskinID for positioning of objects clientside. flags |= (byte) (((z.ZoneSkinID & 0x100) >> 6) | ((targetZone & 0x100) >> 5)); pak.WriteByte(flags); pak.WriteByte((byte) z.ZoneSkinID); //Dinberg:Instances - targetZone already accomodates for this feat. pak.WriteByte((byte) targetZone); SendUDP(pak); if (obj is GameNPC) { (obj as GameNPC).NPCUpdatedCallback(); } }
/// <summary> /// This is used to build a server side "Position Object" /// Usually Position Packet Should only be relayed /// The only purpose of this method is refreshing postion when there is Lag /// </summary> /// <param name="player"></param> public virtual void SendPlayerForgedPosition(GamePlayer player) { using (GSUDPPacketOut pak = new GSUDPPacketOut(GetPacketCode(eServerPackets.PlayerPosition))) { // PID pak.WriteShort((ushort)player.Client.SessionID); // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { player.Heading = player.Steed.Heading; pak.WriteShort(0x1800); } else { short rSpeed = player.CurrentSpeed; if (player.IsIncapacitated) rSpeed = 0; ushort content; if (rSpeed < 0) { content = (ushort)((Math.Abs(rSpeed) > 511 ? 511 : Math.Abs(rSpeed)) + 0x200); } else { content = (ushort)(rSpeed > 511 ? 511 : rSpeed); } if (!player.IsAlive) { content += 5 << 10; } else { ushort state = 0; if (player.IsSwimming) state = 1; if (player.IsClimbing) state = 7; if (player.IsSitting) state = 4; content += (ushort)(state << 10); } content += (ushort)(player.IsStrafing ? 1 << 13 : 0 << 13); pak.WriteShort(content); } // Get Off Corrd int offX = player.X - player.CurrentZone.XOffset; int offY = player.Y - player.CurrentZone.YOffset; pak.WriteShort((ushort)player.Z); pak.WriteShort((ushort)offX); pak.WriteShort((ushort)offY); // Write Zone pak.WriteByte((byte)player.CurrentZone.ZoneSkinID); pak.WriteByte(0); // Copy Heading && Falling or Write Steed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { pak.WriteShort((ushort)player.Steed.ObjectID); pak.WriteShort((ushort)player.Steed.RiderSlot(player)); } else { // Set Player always on ground, this is an "anti lag" packet ushort contenthead = (ushort)(player.Heading + (true ? 0x1000 : 0)); pak.WriteShort(contenthead); // No Fall Speed. pak.WriteShort(0); } // Write Flags byte flagcontent = 0; if (player.IsDiving) { flagcontent += 0x04; } if (player.IsWireframe) { flagcontent += 0x01; } if (player.IsStealthed) { flagcontent += 0x02; } if (player.IsTorchLighted) { flagcontent += 0x80; } pak.WriteByte(flagcontent); // Write health + Attack byte healthcontent = (byte)(player.HealthPercent + (player.AttackState ? 0x80 : 0)); pak.WriteByte(healthcontent); SendUDP(pak); } // Update Cache m_gameClient.GameObjectUpdateArray[new Tuple<ushort, ushort>(player.CurrentRegionID, (ushort)player.ObjectID)] = GameTimer.GetTickCount(); }