예제 #1
0
        /// <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();
        }
예제 #2
0
        /// <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();
        }
예제 #3
0
		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);
		}
예제 #4
0
		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();
			}
		}
예제 #5
0
		/// <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();
		}