Network traffic reduced. Changes!

Bugs:
- Character rotation?
This commit is contained in:
EntenKoeniq
2021-12-23 22:03:01 +01:00
parent 013a71a1ed
commit b9a1089fd0
16 changed files with 3824 additions and 1502 deletions

106
Client/BitReader.cs Normal file
View File

@ -0,0 +1,106 @@
using System;
using System.Text;
using System.Linq;
namespace CoopClient
{
internal class BitReader
{
public int CurrentIndex { get; set; }
private byte[] ResultArray;
public BitReader(byte[] array)
{
CurrentIndex = 0;
ResultArray = array;
}
~BitReader()
{
ResultArray = null;
}
public bool CanRead(int bytes)
{
return ResultArray.Length >= CurrentIndex + bytes;
}
public bool ReadBool()
{
bool value = BitConverter.ToBoolean(ResultArray, CurrentIndex);
CurrentIndex += 1;
return value;
}
public float ReadFloat()
{
float value = BitConverter.ToSingle(ResultArray, CurrentIndex);
CurrentIndex += 4;
return value;
}
public byte ReadByte()
{
byte value = ResultArray[CurrentIndex];
CurrentIndex += 1;
return value;
}
public byte[] ReadByteArray(int length)
{
byte[] value = ResultArray.Skip(CurrentIndex).Take(length).ToArray();
CurrentIndex += length;
return value;
}
public short ReadShort()
{
short value = BitConverter.ToInt16(ResultArray, CurrentIndex);
CurrentIndex += 2;
return value;
}
public ushort ReadUShort()
{
ushort value = BitConverter.ToUInt16(ResultArray, CurrentIndex);
CurrentIndex += 2;
return value;
}
public int ReadInt()
{
int value = BitConverter.ToInt32(ResultArray, CurrentIndex);
CurrentIndex += 4;
return value;
}
public uint ReadUInt()
{
uint value = BitConverter.ToUInt32(ResultArray, CurrentIndex);
CurrentIndex += 4;
return value;
}
public long ReadLong()
{
long value = BitConverter.ToInt64(ResultArray, CurrentIndex);
CurrentIndex += 8;
return value;
}
public ulong ReadULong()
{
ulong value = BitConverter.ToUInt64(ResultArray, CurrentIndex);
CurrentIndex += 8;
return value;
}
public string ReadString(int index)
{
string value = Encoding.UTF8.GetString(ResultArray.Skip(CurrentIndex).Take(index).ToArray());
CurrentIndex += index;
return value;
}
}
}

View File

@ -132,7 +132,7 @@ namespace CoopClient
switch (keyChar[0])
{
case (char)8:
if (CurrentInput.Length > 0)
if (CurrentInput?.Length > 0)
{
CurrentInput = CurrentInput.Remove(CurrentInput.Length - 1);
MainScaleForm.CallFunction("DELETE_TEXT");

View File

@ -51,9 +51,6 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\Release\scripts\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="protobuf-net">
<HintPath>..\Libs\Release\scripts\protobuf-net.dll</HintPath>
</Reference>
<Reference Include="ScriptHookVDotNet3, Version=3.3.2.0, Culture=neutral, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\Release\ScriptHookVDotNet3.dll</HintPath>
@ -74,6 +71,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BitReader.cs" />
<Compile Include="Chat.cs" />
<Compile Include="COOPAPI.cs" />
<Compile Include="Entities\EntitiesPed.cs" />

View File

@ -40,10 +40,6 @@ namespace CoopClient.Entities
/// </summary>
public Vehicle MainVehicle { get; internal set; }
/// <summary>
/// The latest vehicle position (may not have been applied yet)
/// </summary>
public Vector3 VehiclePosition { get; internal set; }
/// <summary>
/// The latest vehicle rotation (may not have been applied yet)
/// </summary>
public Quaternion VehicleRotation { get; internal set; }
@ -72,10 +68,7 @@ namespace CoopClient.Entities
internal byte VehLandingGear { get; set; }
internal bool VehRoofOpened { get; set; }
internal bool VehIsSireneActive { get; set; }
private VehicleDoors[] LastVehDoors;
internal VehicleDoors[] VehDoors { get; set; }
private int LastVehTires;
internal int VehTires { get; set; }
internal VehicleDamageModel VehDamageModel { get; set; }
#endregion
private void DisplayInVehicle()
@ -125,7 +118,7 @@ namespace CoopClient.Entities
return;
}
MainVehicle = World.CreateVehicle(vehicleModel, VehiclePosition);
MainVehicle = World.CreateVehicle(vehicleModel, Position);
vehicleModel.MarkAsNoLongerNeeded();
if (NPCVehHandle != 0)
{
@ -295,69 +288,7 @@ namespace CoopClient.Entities
if (LastSyncWasFull)
{
if (VehDoors != null && VehDoors != LastVehDoors)
{
int doorLength = VehDoors.Length;
if (VehDoors.Length != 0)
{
for (int i = 0; i < (doorLength - 1); i++)
{
VehicleDoor door = MainVehicle.Doors[(VehicleDoorIndex)i];
VehicleDoors aDoor = VehDoors[i];
if (aDoor.Broken)
{
if (!door.IsBroken)
{
door.Break();
}
continue;
}
else if (!aDoor.Broken && door.IsBroken)
{
// Repair?
//MainVehicle.Repair();
}
if (aDoor.FullyOpen)
{
if (!door.IsFullyOpen)
{
door.Open(false, true);
}
continue;
}
else if (aDoor.Open)
{
if (!door.IsOpen)
{
door.Open();
}
door.AngleRatio = aDoor.AngleRatio;
continue;
}
door.Close(true);
}
}
LastVehDoors = VehDoors;
}
if (VehTires != default && LastVehTires != VehTires)
{
foreach (var wheel in MainVehicle.Wheels.GetAllWheels())
{
if ((VehTires & 1 << (int)wheel.BoneId) != 0)
{
wheel.Puncture();
wheel.Burst();
}
}
LastVehTires = VehTires;
}
MainVehicle.SetVehicleDamageModel(VehDamageModel);
}
}
}
@ -368,25 +299,25 @@ namespace CoopClient.Entities
}
// Good enough for now, but we need to create a better sync
if (CurrentVehicleSpeed > 0.05f && MainVehicle.IsInRange(VehiclePosition, 7.0f))
if (CurrentVehicleSpeed > 0.05f && MainVehicle.IsInRange(Position, 7.0f))
{
int forceMultiplier = (Game.Player.Character.IsInVehicle() && MainVehicle.IsTouching(Game.Player.Character.CurrentVehicle)) ? 1 : 3;
MainVehicle.Velocity = VehicleVelocity + forceMultiplier * (VehiclePosition - MainVehicle.Position);
MainVehicle.Velocity = VehicleVelocity + forceMultiplier * (Position - MainVehicle.Position);
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, 0.5f);
VehicleStopTime = Util.GetTickCount64();
}
else if ((Util.GetTickCount64() - VehicleStopTime) <= 1000)
{
Vector3 posTarget = Util.LinearVectorLerp(MainVehicle.Position, VehiclePosition + (VehiclePosition - MainVehicle.Position), Util.GetTickCount64() - VehicleStopTime, 1000);
Vector3 posTarget = Util.LinearVectorLerp(MainVehicle.Position, Position + (Position - MainVehicle.Position), Util.GetTickCount64() - VehicleStopTime, 1000);
MainVehicle.PositionNoOffset = posTarget;
MainVehicle.Quaternion = Quaternion.Slerp(MainVehicle.Quaternion, VehicleRotation, 0.5f);
}
else
{
MainVehicle.PositionNoOffset = VehiclePosition;
MainVehicle.PositionNoOffset = Position;
MainVehicle.Quaternion = VehicleRotation;
}
#endregion

View File

@ -21,7 +21,7 @@ namespace CoopClient
private bool GameLoaded = false;
internal static readonly string CurrentVersion = "V1_2_0";
internal static readonly string CurrentVersion = "V1_3_0";
internal static bool ShareNPCsWithPlayers = false;
internal static bool DisableTraffic = false;
@ -290,14 +290,14 @@ namespace CoopClient
DebugSyncPed.Health = player.Health;
DebugSyncPed.Position = player.Position;
byte? flags;
ushort? flags;
if (player.IsInVehicle())
{
Vehicle veh = player.CurrentVehicle;
veh.Opacity = 75;
flags = veh.GetVehicleFlags();
flags = player.GetVehicleFlags(veh);
byte secondaryColor;
byte primaryColor;
@ -308,7 +308,7 @@ namespace CoopClient
DebugSyncPed.VehicleModelHash = veh.Model.Hash;
DebugSyncPed.VehicleSeatIndex = (short)player.SeatIndex;
DebugSyncPed.VehiclePosition = veh.Position;
DebugSyncPed.Position = veh.Position;
DebugSyncPed.VehicleRotation = veh.Quaternion;
DebugSyncPed.VehicleEngineHealth = veh.EngineHealth;
DebugSyncPed.VehRPM = veh.CurrentRPM;
@ -318,18 +318,17 @@ namespace CoopClient
DebugSyncPed.AimCoords = veh.IsTurretSeat((int)player.SeatIndex) ? Util.GetVehicleAimCoords() : new GTA.Math.Vector3();
DebugSyncPed.VehicleColors = new byte[] { primaryColor, secondaryColor };
DebugSyncPed.VehicleMods = veh.Mods.GetVehicleMods();
DebugSyncPed.VehDoors = veh.Doors.GetVehicleDoors();
DebugSyncPed.VehTires = veh.Wheels.GetBurstedTires();
DebugSyncPed.VehDamageModel = veh.GetVehicleDamageModel();
DebugSyncPed.LastSyncWasFull = true;
DebugSyncPed.IsInVehicle = true;
DebugSyncPed.VehIsEngineRunning = (flags.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
DebugSyncPed.VehAreLightsOn = (flags.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
DebugSyncPed.VehAreHighBeamsOn = (flags.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
DebugSyncPed.VehIsSireneActive = (flags.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
DebugSyncPed.VehicleDead = (flags.Value & (byte)VehicleDataFlags.IsDead) > 0;
DebugSyncPed.IsHornActive = (flags.Value & (byte)VehicleDataFlags.IsHornActive) > 0;
DebugSyncPed.Transformed = (flags.Value & (byte)VehicleDataFlags.IsTransformed) > 0;
DebugSyncPed.VehRoofOpened = (flags.Value & (byte)VehicleDataFlags.RoofOpened) > 0;
DebugSyncPed.VehIsEngineRunning = (flags.Value & (ushort)VehicleDataFlags.IsEngineRunning) > 0;
DebugSyncPed.VehAreLightsOn = (flags.Value & (ushort)VehicleDataFlags.AreLightsOn) > 0;
DebugSyncPed.VehAreHighBeamsOn = (flags.Value & (ushort)VehicleDataFlags.AreHighBeamsOn) > 0;
DebugSyncPed.VehIsSireneActive = (flags.Value & (ushort)VehicleDataFlags.IsSirenActive) > 0;
DebugSyncPed.VehicleDead = (flags.Value & (ushort)VehicleDataFlags.IsDead) > 0;
DebugSyncPed.IsHornActive = (flags.Value & (ushort)VehicleDataFlags.IsHornActive) > 0;
DebugSyncPed.Transformed = (flags.Value & (ushort)VehicleDataFlags.IsTransformed) > 0;
DebugSyncPed.VehRoofOpened = (flags.Value & (ushort)VehicleDataFlags.RoofOpened) > 0;
DebugSyncPed.VehLandingGear = veh.IsPlane ? (byte)veh.LandingGearState : (byte)0;
if (DebugSyncPed.MainVehicle != null && DebugSyncPed.MainVehicle.Exists() && player.IsInVehicle())

View File

@ -64,7 +64,7 @@ namespace CoopClient
NetHandle = 0,
Username = Main.MainSettings.Username,
ModVersion = Main.CurrentVersion,
NpcsAllowed = false
NPCsAllowed = false
}.PacketToNetOutGoingMessage(outgoingMessage);
Client.Connect(ip[0], short.Parse(ip[1]), outgoingMessage);
@ -111,13 +111,14 @@ namespace CoopClient
}
else
{
Packet remoteHailMessagePacket;
remoteHailMessagePacket = new HandshakePacket();
remoteHailMessagePacket.NetIncomingMessageToPacket(message.SenderConnection.RemoteHailMessage);
int len = message.SenderConnection.RemoteHailMessage.ReadInt32();
byte[] data = message.SenderConnection.RemoteHailMessage.ReadBytes(len);
HandshakePacket handshakePacket = new HandshakePacket();
handshakePacket.NetIncomingMessageToPacket(data);
HandshakePacket handshakePacket = (HandshakePacket)remoteHailMessagePacket;
Main.LocalNetHandle = handshakePacket.NetHandle;
Main.NPCsAllowed = handshakePacket.NpcsAllowed;
Main.NPCsAllowed = handshakePacket.NPCsAllowed;
Main.MainChat.Init();
@ -154,80 +155,166 @@ namespace CoopClient
case NetIncomingMessageType.Data:
byte packetType = message.ReadByte();
Packet packet;
switch (packetType)
{
case (byte)PacketTypes.PlayerConnectPacket:
packet = new PlayerConnectPacket();
packet.NetIncomingMessageToPacket(message);
PlayerConnect((PlayerConnectPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
PlayerConnectPacket packet = new PlayerConnectPacket();
packet.NetIncomingMessageToPacket(data);
PlayerConnect(packet);
}
break;
case (byte)PacketTypes.PlayerDisconnectPacket:
packet = new PlayerDisconnectPacket();
packet.NetIncomingMessageToPacket(message);
PlayerDisconnect((PlayerDisconnectPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
PlayerDisconnectPacket packet = new PlayerDisconnectPacket();
packet.NetIncomingMessageToPacket(data);
PlayerDisconnect(packet);
}
break;
case (byte)PacketTypes.FullSyncPlayerPacket:
packet = new FullSyncPlayerPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncPlayer((FullSyncPlayerPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncPlayerPacket packet = new FullSyncPlayerPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncPlayer(packet);
}
break;
case (byte)PacketTypes.FullSyncPlayerVehPacket:
packet = new FullSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncPlayerVeh((FullSyncPlayerVehPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncPlayerVehPacket packet = new FullSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncPlayerVeh(packet);
}
break;
case (byte)PacketTypes.LightSyncPlayerPacket:
packet = new LightSyncPlayerPacket();
packet.NetIncomingMessageToPacket(message);
LightSyncPlayer((LightSyncPlayerPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
LightSyncPlayerPacket packet = new LightSyncPlayerPacket();
packet.NetIncomingMessageToPacket(data);
LightSyncPlayer(packet);
}
break;
case (byte)PacketTypes.LightSyncPlayerVehPacket:
packet = new LightSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(message);
LightSyncPlayerVeh((LightSyncPlayerVehPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
LightSyncPlayerVehPacket packet = new LightSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(data);
LightSyncPlayerVeh(packet);
}
break;
case (byte)PacketTypes.SuperLightSyncPacket:
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
SuperLightSyncPacket packet = new SuperLightSyncPacket();
packet.NetIncomingMessageToPacket(data);
if (Main.Players.ContainsKey(packet.NetHandle))
{
EntitiesPlayer player = Main.Players[packet.NetHandle];
player.Position = packet.Position.ToVector();
player.Latency = packet.Latency.HasValue ? packet.Latency.Value : 0;
}
}
break;
case (byte)PacketTypes.FullSyncNpcPacket:
packet = new FullSyncNpcPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncNpc((FullSyncNpcPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncNpcPacket packet = new FullSyncNpcPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncNpc(packet);
}
break;
case (byte)PacketTypes.FullSyncNpcVehPacket:
packet = new FullSyncNpcVehPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncNpcVeh((FullSyncNpcVehPacket)packet);
break;
case (byte)PacketTypes.SuperLightSyncPlayerPacket:
packet = new SuperLightSyncPlayerPacket();
packet.NetIncomingMessageToPacket(message);
SuperLightSyncPlayer((SuperLightSyncPlayerPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncNpcVehPacket packet = new FullSyncNpcVehPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncNpcVeh(packet);
}
break;
case (byte)PacketTypes.ChatMessagePacket:
packet = new ChatMessagePacket();
packet.NetIncomingMessageToPacket(message);
ChatMessagePacket chatMessagePacket = (ChatMessagePacket)packet;
if (!COOPAPI.ChatMessageReceived(chatMessagePacket.Username, chatMessagePacket.Message))
{
Main.MainChat.AddMessage(chatMessagePacket.Username, chatMessagePacket.Message);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
ChatMessagePacket packet = new ChatMessagePacket();
packet.NetIncomingMessageToPacket(data);
if (!COOPAPI.ChatMessageReceived(packet.Username, packet.Message))
{
Main.MainChat.AddMessage(packet.Username, packet.Message);
}
}
break;
case (byte)PacketTypes.NativeCallPacket:
packet = new NativeCallPacket();
packet.NetIncomingMessageToPacket(message);
DecodeNativeCall((NativeCallPacket)packet);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
NativeCallPacket packet = new NativeCallPacket();
packet.NetIncomingMessageToPacket(data);
DecodeNativeCall(packet);
}
break;
case (byte)PacketTypes.NativeResponsePacket:
packet = new NativeResponsePacket();
packet.NetIncomingMessageToPacket(message);
DecodeNativeResponse((NativeResponsePacket)packet);
{
try
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
NativeResponsePacket packet = new NativeResponsePacket();
packet.NetIncomingMessageToPacket(data);
DecodeNativeResponse(packet);
}
catch (Exception ex)
{
GTA.UI.Notification.Show($"{ex.Message}");
}
}
break;
case (byte)PacketTypes.ModPacket:
packet = new ModPacket();
packet.NetIncomingMessageToPacket(message);
ModPacket modPacket = (ModPacket)packet;
COOPAPI.ModPacketReceived(modPacket.NetHandle, modPacket.Mod, modPacket.CustomPacketID, modPacket.Bytes);
{
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
ModPacket packet = new ModPacket();
packet.NetIncomingMessageToPacket(data);
COOPAPI.ModPacketReceived(packet.NetHandle, packet.Mod, packet.CustomPacketID, packet.Bytes);
}
break;
}
break;
@ -280,14 +367,14 @@ namespace CoopClient
private void FullSyncPlayer(FullSyncPlayerPacket packet)
{
if (Main.Players.ContainsKey(packet.Extra.NetHandle))
if (Main.Players.ContainsKey(packet.NetHandle))
{
EntitiesPlayer player = Main.Players[packet.Extra.NetHandle];
EntitiesPlayer player = Main.Players[packet.NetHandle];
player.ModelHash = packet.ModelHash;
player.Clothes = packet.Clothes;
player.Health = packet.Extra.Health;
player.Position = packet.Extra.Position.ToVector();
player.Health = packet.Health;
player.Position = packet.Position.ToVector();
player.Rotation = packet.Rotation.ToVector();
player.Velocity = packet.Velocity.ToVector();
player.Speed = packet.Speed;
@ -303,24 +390,23 @@ namespace CoopClient
player.IsInVehicle = false;
player.LastSyncWasFull = true;
player.Latency = packet.Extra.Latency;
player.Latency = packet.Latency.Value;
player.LastUpdateReceived = Util.GetTickCount64();
}
}
private void FullSyncPlayerVeh(FullSyncPlayerVehPacket packet)
{
if (Main.Players.ContainsKey(packet.Extra.NetHandle))
if (Main.Players.ContainsKey(packet.NetHandle))
{
EntitiesPlayer player = Main.Players[packet.Extra.NetHandle];
EntitiesPlayer player = Main.Players[packet.NetHandle];
player.ModelHash = packet.ModelHash;
player.Clothes = packet.Clothes;
player.Health = packet.Extra.Health;
player.Position = packet.Extra.Position.ToVector();
player.Health = packet.Health;
player.VehicleModelHash = packet.VehModelHash;
player.VehicleSeatIndex = packet.VehSeatIndex;
player.VehiclePosition = packet.VehPosition.ToVector();
player.Position = packet.Position.ToVector();
player.VehicleRotation = packet.VehRotation.ToQuaternion();
player.VehicleEngineHealth = packet.VehEngineHealth;
player.VehRPM = packet.VehRPM;
@ -330,33 +416,32 @@ namespace CoopClient
player.AimCoords = packet.VehAimCoords.ToVector();
player.VehicleColors = packet.VehColors;
player.VehicleMods = packet.VehMods;
player.VehDoors = packet.VehDoors;
player.VehTires = packet.VehTires;
player.VehDamageModel = packet.VehDamageModel;
player.VehLandingGear = packet.VehLandingGear;
player.VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
player.VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
player.VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
player.VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
player.VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0;
player.IsHornActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsHornActive) > 0;
player.Transformed = (packet.Flag.Value & (byte)VehicleDataFlags.IsTransformed) > 0;
player.VehRoofOpened = (packet.Flag.Value & (byte)VehicleDataFlags.RoofOpened) > 0;
player.VehIsEngineRunning = (packet.Flag.Value & (ushort)VehicleDataFlags.IsEngineRunning) > 0;
player.VehAreLightsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreLightsOn) > 0;
player.VehAreHighBeamsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreHighBeamsOn) > 0;
player.VehIsSireneActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsSirenActive) > 0;
player.VehicleDead = (packet.Flag.Value & (ushort)VehicleDataFlags.IsDead) > 0;
player.IsHornActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsHornActive) > 0;
player.Transformed = (packet.Flag.Value & (ushort)VehicleDataFlags.IsTransformed) > 0;
player.VehRoofOpened = (packet.Flag.Value & (ushort)VehicleDataFlags.RoofOpened) > 0;
player.IsInVehicle = true;
player.LastSyncWasFull = true;
player.Latency = packet.Extra.Latency;
player.Latency = packet.Latency.Value;
player.LastUpdateReceived = Util.GetTickCount64();
}
}
private void LightSyncPlayer(LightSyncPlayerPacket packet)
{
if (Main.Players.ContainsKey(packet.Extra.NetHandle))
if (Main.Players.ContainsKey(packet.NetHandle))
{
EntitiesPlayer player = Main.Players[packet.Extra.NetHandle];
EntitiesPlayer player = Main.Players[packet.NetHandle];
player.Health = packet.Extra.Health;
player.Position = packet.Extra.Position.ToVector();
player.Health = packet.Health;
player.Position = packet.Position.ToVector();
player.Rotation = packet.Rotation.ToVector();
player.Velocity = packet.Velocity.ToVector();
player.Speed = packet.Speed;
@ -371,52 +456,40 @@ namespace CoopClient
player.IsInVehicle = false;
player.LastSyncWasFull = false;
player.Latency = packet.Extra.Latency;
if (packet.Flag.HasValue)
{
player.Latency = packet.Latency.Value;
}
player.LastUpdateReceived = Util.GetTickCount64();
}
}
private void LightSyncPlayerVeh(LightSyncPlayerVehPacket packet)
{
if (Main.Players.ContainsKey(packet.Extra.NetHandle))
if (Main.Players.ContainsKey(packet.NetHandle))
{
EntitiesPlayer player = Main.Players[packet.Extra.NetHandle];
EntitiesPlayer player = Main.Players[packet.NetHandle];
player.Health = packet.Extra.Health;
player.Position = packet.Extra.Position.ToVector();
player.Health = packet.Health;
player.VehicleModelHash = packet.VehModelHash;
player.VehicleSeatIndex = packet.VehSeatIndex;
player.VehiclePosition = packet.VehPosition.ToVector();
player.Position = packet.Position.ToVector();
player.VehicleRotation = packet.VehRotation.ToQuaternion();
player.VehicleVelocity = packet.VehVelocity.ToVector();
player.VehicleSpeed = packet.VehSpeed;
player.VehicleSteeringAngle = packet.VehSteeringAngle;
player.VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
player.VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
player.VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
player.VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
player.VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0;
player.IsHornActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsHornActive) > 0;
player.Transformed = (packet.Flag.Value & (byte)VehicleDataFlags.IsTransformed) > 0;
player.VehRoofOpened = (packet.Flag.Value & (byte)VehicleDataFlags.RoofOpened) > 0;
player.VehIsEngineRunning = (packet.Flag.Value & (ushort)VehicleDataFlags.IsEngineRunning) > 0;
player.VehAreLightsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreLightsOn) > 0;
player.VehAreHighBeamsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreHighBeamsOn) > 0;
player.VehIsSireneActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsSirenActive) > 0;
player.VehicleDead = (packet.Flag.Value & (ushort)VehicleDataFlags.IsDead) > 0;
player.IsHornActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsHornActive) > 0;
player.Transformed = (packet.Flag.Value & (ushort)VehicleDataFlags.IsTransformed) > 0;
player.VehRoofOpened = (packet.Flag.Value & (ushort)VehicleDataFlags.RoofOpened) > 0;
player.IsInVehicle = true;
player.LastSyncWasFull = false;
player.Latency = packet.Extra.Latency;
player.LastUpdateReceived = Util.GetTickCount64();
}
}
private void SuperLightSyncPlayer(SuperLightSyncPlayerPacket packet)
{
if (Main.Players.ContainsKey(packet.Extra.NetHandle))
{
EntitiesPlayer player = Main.Players[packet.Extra.NetHandle];
player.Health = packet.Extra.Health;
player.Position = packet.Extra.Position.ToVector();
player.Latency = packet.Extra.Latency;
player.Latency = packet.Latency.Value;
player.LastUpdateReceived = Util.GetTickCount64();
}
}
@ -427,31 +500,32 @@ namespace CoopClient
if (packet.Args != null && packet.Args.Count > 0)
{
packet.Args.ForEach(arg =>
packet.Args.ForEach(x =>
{
Type typeOf = arg.GetType();
Type type = x.GetType();
if (typeOf == typeof(IntArgument))
if (type == typeof(int))
{
arguments.Add(((IntArgument)arg).Data);
arguments.Add((int)x);
}
else if (typeOf == typeof(BoolArgument))
else if (type == typeof(bool))
{
arguments.Add(((BoolArgument)arg).Data);
arguments.Add((bool)x);
}
else if (typeOf == typeof(FloatArgument))
else if (type == typeof(float))
{
arguments.Add(((FloatArgument)arg).Data);
arguments.Add((float)x);
}
else if (typeOf == typeof(StringArgument))
else if (type == typeof(string))
{
arguments.Add(((StringArgument)arg).Data);
arguments.Add((string)x);
}
else if (typeOf == typeof(LVector3Argument))
else if (type == typeof(LVector3))
{
arguments.Add(((LVector3Argument)arg).Data.X);
arguments.Add(((LVector3Argument)arg).Data.Y);
arguments.Add(((LVector3Argument)arg).Data.Z);
LVector3 vector = (LVector3)x;
arguments.Add((float)vector.X);
arguments.Add((float)vector.Y);
arguments.Add((float)vector.Z);
}
else
{
@ -471,66 +545,61 @@ namespace CoopClient
if (packet.Args != null && packet.Args.Count > 0)
{
packet.Args.ForEach(arg =>
packet.Args.ForEach(x =>
{
typeOf = arg.GetType();
typeOf = x.GetType();
if (typeOf == typeof(IntArgument))
if (typeOf == typeof(int))
{
arguments.Add(((IntArgument)arg).Data);
arguments.Add((int)x);
}
else if (typeOf == typeof(BoolArgument))
else if (typeOf == typeof(bool))
{
arguments.Add(((BoolArgument)arg).Data);
arguments.Add((bool)x);
}
else if (typeOf == typeof(FloatArgument))
else if (typeOf == typeof(float))
{
arguments.Add(((FloatArgument)arg).Data);
arguments.Add((float)x);
}
else if (typeOf == typeof(StringArgument))
else if (typeOf == typeof(string))
{
arguments.Add(((StringArgument)arg).Data);
arguments.Add((string)x);
}
else if (typeOf == typeof(LVector3Argument))
else if (typeOf == typeof(LVector3))
{
arguments.Add(((LVector3Argument)arg).Data.X);
arguments.Add(((LVector3Argument)arg).Data.Y);
arguments.Add(((LVector3Argument)arg).Data.Z);
LVector3 vector = (LVector3)x;
arguments.Add((float)vector.X);
arguments.Add((float)vector.Y);
arguments.Add((float)vector.Z);
}
else
{
GTA.UI.Notification.Show("[DecodeNativeCall][" + packet.Hash + "]: Type of argument not found!");
GTA.UI.Notification.Show("[DecodeNativeResponse][" + packet.Hash + "]: Type of argument not found!");
return;
}
});
}
NativeArgument result = null;
typeOf = packet.Type.GetType();
if (typeOf == typeof(IntArgument))
object result;
switch (packet.ResultType.Value)
{
result = new IntArgument() { Data = Function.Call<int>((Hash)packet.Hash, arguments.ToArray()) };
}
else if (typeOf == typeof(BoolArgument))
{
result = new BoolArgument() { Data = Function.Call<bool>((Hash)packet.Hash, arguments.ToArray()) };
}
else if (typeOf == typeof(FloatArgument))
{
result = new FloatArgument() { Data = Function.Call<float>((Hash)packet.Hash, arguments.ToArray()) };
}
else if (typeOf == typeof(StringArgument))
{
result = new StringArgument() { Data = Function.Call<string>((Hash)packet.Hash, arguments.ToArray()) };
}
else if (typeOf == typeof(LVector3Argument))
{
result = new LVector3Argument() { Data = Function.Call<GTA.Math.Vector3>((Hash)packet.Hash, arguments.ToArray()).ToLVector() };
}
else
{
GTA.UI.Notification.Show("[DecodeNativeResponse][" + packet.Hash + "]: Type of argument not found!");
case 0x00: // int
result = Function.Call<int>((Hash)packet.Hash, arguments.ToArray());
break;
case 0x01: // bool
result = Function.Call<bool>((Hash)packet.Hash, arguments.ToArray());
break;
case 0x02: // float
result = Function.Call<float>((Hash)packet.Hash, arguments.ToArray());
break;
case 0x03: // string
result = Function.Call<string>((Hash)packet.Hash, arguments.ToArray());
break;
case 0x04: // vector3
result = Function.Call<GTA.Math.Vector3>((Hash)packet.Hash, arguments.ToArray()).ToLVector();
break;
default:
GTA.UI.Notification.Show("[DecodeNativeResponse][" + packet.Hash + "]: Type of return not found!");
return;
}
@ -538,11 +607,10 @@ namespace CoopClient
new NativeResponsePacket()
{
Hash = 0,
Args = null,
Type = result,
NetHandle = packet.NetHandle
Args = new List<object>() { result },
ID = packet.ID
}.PacketToNetOutGoingMessage(outgoingMessage);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Native);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
Client.FlushSendQueue();
}
#endregion // -- PLAYER --
@ -620,10 +688,9 @@ namespace CoopClient
npc.ModelHash = packet.ModelHash;
npc.Clothes = packet.Clothes;
npc.Health = packet.Health;
npc.Position = packet.Position.ToVector();
npc.VehicleModelHash = packet.VehModelHash;
npc.VehicleSeatIndex = packet.VehSeatIndex;
npc.VehiclePosition = packet.VehPosition.ToVector();
npc.Position = packet.Position.ToVector();
npc.VehicleRotation = packet.VehRotation.ToQuaternion();
npc.VehicleEngineHealth = packet.VehEngineHealth;
npc.VehRPM = packet.VehRPM;
@ -631,17 +698,16 @@ namespace CoopClient
npc.VehicleSpeed = packet.VehSpeed;
npc.VehicleSteeringAngle = packet.VehSteeringAngle;
npc.VehicleColors = packet.VehColors;
npc.VehDoors = packet.VehDoors;
npc.VehTires = packet.VehTires;
npc.VehDamageModel = packet.VehDamageModel;
npc.VehLandingGear = packet.VehLandingGear;
npc.VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0;
npc.VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0;
npc.VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0;
npc.VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0;
npc.VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0;
npc.IsHornActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsHornActive) > 0;
npc.Transformed = (packet.Flag.Value & (byte)VehicleDataFlags.IsTransformed) > 0;
npc.VehRoofOpened = (packet.Flag.Value & (byte)VehicleDataFlags.RoofOpened) > 0;
npc.VehIsEngineRunning = (packet.Flag.Value & (ushort)VehicleDataFlags.IsEngineRunning) > 0;
npc.VehAreLightsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreLightsOn) > 0;
npc.VehAreHighBeamsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreHighBeamsOn) > 0;
npc.VehIsSireneActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsSirenActive) > 0;
npc.VehicleDead = (packet.Flag.Value & (ushort)VehicleDataFlags.IsDead) > 0;
npc.IsHornActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsHornActive) > 0;
npc.Transformed = (packet.Flag.Value & (ushort)VehicleDataFlags.IsTransformed) > 0;
npc.VehRoofOpened = (packet.Flag.Value & (ushort)VehicleDataFlags.RoofOpened) > 0;
npc.IsInVehicle = true;
npc.LastSyncWasFull = true;
@ -656,10 +722,9 @@ namespace CoopClient
ModelHash = packet.ModelHash,
Clothes = packet.Clothes,
Health = packet.Health,
Position = packet.Position.ToVector(),
VehicleModelHash = packet.VehModelHash,
VehicleSeatIndex = packet.VehSeatIndex,
VehiclePosition = packet.VehPosition.ToVector(),
Position = packet.Position.ToVector(),
VehicleRotation = packet.VehRotation.ToQuaternion(),
VehicleEngineHealth = packet.VehEngineHealth,
VehRPM = packet.VehRPM,
@ -667,17 +732,16 @@ namespace CoopClient
VehicleSpeed = packet.VehSpeed,
VehicleSteeringAngle = packet.VehSteeringAngle,
VehicleColors = packet.VehColors,
VehDoors = packet.VehDoors,
VehTires = packet.VehTires,
VehDamageModel = packet.VehDamageModel,
VehLandingGear = packet.VehLandingGear,
VehIsEngineRunning = (packet.Flag.Value & (byte)VehicleDataFlags.IsEngineRunning) > 0,
VehAreLightsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreLightsOn) > 0,
VehAreHighBeamsOn = (packet.Flag.Value & (byte)VehicleDataFlags.AreHighBeamsOn) > 0,
VehIsSireneActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsSirenActive) > 0,
VehicleDead = (packet.Flag.Value & (byte)VehicleDataFlags.IsDead) > 0,
IsHornActive = (packet.Flag.Value & (byte)VehicleDataFlags.IsHornActive) > 0,
Transformed = (packet.Flag.Value & (byte)VehicleDataFlags.IsTransformed) > 0,
VehRoofOpened = (packet.Flag.Value & (byte)VehicleDataFlags.RoofOpened) > 0,
VehIsEngineRunning = (packet.Flag.Value & (ushort)VehicleDataFlags.IsEngineRunning) > 0,
VehAreLightsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreLightsOn) > 0,
VehAreHighBeamsOn = (packet.Flag.Value & (ushort)VehicleDataFlags.AreHighBeamsOn) > 0,
VehIsSireneActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsSirenActive) > 0,
VehicleDead = (packet.Flag.Value & (ushort)VehicleDataFlags.IsDead) > 0,
IsHornActive = (packet.Flag.Value & (ushort)VehicleDataFlags.IsHornActive) > 0,
Transformed = (packet.Flag.Value & (ushort)VehicleDataFlags.IsTransformed) > 0,
VehRoofOpened = (packet.Flag.Value & (ushort)VehicleDataFlags.RoofOpened) > 0,
IsInVehicle = true,
LastSyncWasFull = true,
@ -697,10 +761,12 @@ namespace CoopClient
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
NetDeliveryMethod messageType;
int connectionChannel = 0;
if ((Util.GetTickCount64() - LastPlayerFullSync) > 500)
{
messageType = NetDeliveryMethod.UnreliableSequenced;
connectionChannel = (byte)ConnectionChannel.PlayerFull;
if (player.IsInVehicle())
{
@ -714,18 +780,14 @@ namespace CoopClient
}
new FullSyncPlayerVehPacket()
{
Extra = new PlayerPacket()
{
NetHandle = Main.LocalNetHandle,
Health = player.Health,
Position = player.Position.ToLVector()
},
ModelHash = player.Model.Hash,
Clothes = player.GetPedClothes(),
VehModelHash = veh.Model.Hash,
VehSeatIndex = (short)player.SeatIndex,
VehPosition = veh.Position.ToLVector(),
Position = veh.Position.ToLVector(),
VehRotation = veh.Quaternion.ToLQuaternion(),
VehEngineHealth = veh.EngineHealth,
VehRPM = veh.CurrentRPM,
@ -735,24 +797,20 @@ namespace CoopClient
VehAimCoords = veh.IsTurretSeat((int)player.SeatIndex) ? Util.GetVehicleAimCoords().ToLVector() : new LVector3(),
VehColors = new byte[] { primaryColor, secondaryColor },
VehMods = veh.Mods.GetVehicleMods(),
VehDoors = veh.Doors.GetVehicleDoors(),
VehTires = veh.Wheels.GetBurstedTires(),
VehDamageModel = veh.GetVehicleDamageModel(),
VehLandingGear = veh.IsPlane ? (byte)veh.LandingGearState : (byte)0,
Flag = veh.GetVehicleFlags()
Flag = player.GetVehicleFlags(veh)
}.PacketToNetOutGoingMessage(outgoingMessage);
}
else
{
new FullSyncPlayerPacket()
{
Extra = new PlayerPacket()
{
NetHandle = Main.LocalNetHandle,
Health = player.Health,
Position = player.Position.ToLVector()
},
ModelHash = player.Model.Hash,
Clothes = player.GetPedClothes(),
Position = player.Position.ToLVector(),
Rotation = player.Rotation.ToLVector(),
Velocity = player.Velocity.ToLVector(),
Speed = player.GetPedSpeed(),
@ -768,39 +826,33 @@ namespace CoopClient
else
{
messageType = NetDeliveryMethod.ReliableSequenced;
connectionChannel = (byte)ConnectionChannel.PlayerLight;
if (player.IsInVehicle())
{
Vehicle veh = player.CurrentVehicle;
new LightSyncPlayerVehPacket()
{
Extra = new PlayerPacket()
{
NetHandle = Main.LocalNetHandle,
Health = player.Health,
Position = player.Position.ToLVector()
},
VehModelHash = veh.Model.Hash,
VehSeatIndex = (short)player.SeatIndex,
VehPosition = veh.Position.ToLVector(),
Position = veh.Position.ToLVector(),
VehRotation = veh.Quaternion.ToLQuaternion(),
VehVelocity = veh.Velocity.ToLVector(),
VehSpeed = veh.Speed,
VehSteeringAngle = veh.SteeringAngle,
Flag = veh.GetVehicleFlags()
Flag = player.GetVehicleFlags(veh)
}.PacketToNetOutGoingMessage(outgoingMessage);
}
else
{
new LightSyncPlayerPacket()
{
Extra = new PlayerPacket()
{
NetHandle = Main.LocalNetHandle,
Health = player.Health,
Position = player.Position.ToLVector()
},
Position = player.Position.ToLVector(),
Rotation = player.Rotation.ToLVector(),
Velocity = player.Velocity.ToLVector(),
Speed = player.GetPedSpeed(),
@ -811,7 +863,7 @@ namespace CoopClient
}
}
Client.SendMessage(outgoingMessage, messageType, (int)ConnectionChannel.Player);
Client.SendMessage(outgoingMessage, messageType, connectionChannel);
Client.FlushSendQueue();
#if DEBUG
@ -844,10 +896,9 @@ namespace CoopClient
ModelHash = npc.Model.Hash,
Clothes = npc.GetPedClothes(),
Health = npc.Health,
Position = npc.Position.ToLVector(),
VehModelHash = veh.Model.Hash,
VehSeatIndex = (short)npc.SeatIndex,
VehPosition = veh.Position.ToLVector(),
Position = veh.Position.ToLVector(),
VehRotation = veh.Quaternion.ToLQuaternion(),
VehEngineHealth = veh.EngineHealth,
VehRPM = veh.CurrentRPM,
@ -856,10 +907,9 @@ namespace CoopClient
VehSteeringAngle = veh.SteeringAngle,
VehColors = new byte[] { primaryColor, secondaryColor },
VehMods = veh.Mods.GetVehicleMods(),
VehDoors = veh.Doors.GetVehicleDoors(),
VehTires = veh.Wheels.GetBurstedTires(),
VehDamageModel = veh.GetVehicleDamageModel(),
VehLandingGear = veh.IsPlane ? (byte)veh.LandingGearState : (byte)0,
Flag = veh.GetVehicleFlags()
Flag = npc.GetVehicleFlags(veh)
}.PacketToNetOutGoingMessage(outgoingMessage);
}
else
@ -880,7 +930,7 @@ namespace CoopClient
}.PacketToNetOutGoingMessage(outgoingMessage);
}
Client.SendMessage(outgoingMessage, NetDeliveryMethod.Unreliable, (int)ConnectionChannel.NPC);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.Unreliable, (byte)ConnectionChannel.NPCFull);
Client.FlushSendQueue();
#if DEBUG
@ -894,12 +944,10 @@ namespace CoopClient
internal void SendChatMessage(string message)
{
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
new ChatMessagePacket()
{
Username = Main.MainSettings.Username,
Message = message
}.PacketToNetOutGoingMessage(outgoingMessage);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
new ChatMessagePacket() { Username = Main.MainSettings.Username, Message = message }.PacketToNetOutGoingMessage(outgoingMessage);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
Client.FlushSendQueue();
#if DEBUG
@ -921,7 +969,7 @@ namespace CoopClient
CustomPacketID = customID,
Bytes = bytes
}.PacketToNetOutGoingMessage(outgoingMessage);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Mod);
Client.SendMessage(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
Client.FlushSendQueue();
#if DEBUG

File diff suppressed because it is too large Load Diff

View File

@ -168,48 +168,58 @@ namespace CoopClient
return RaycastEverything(new Vector2(0, 0));
}
public static byte? GetVehicleFlags(this Vehicle veh)
public static ushort? GetVehicleFlags(this Ped ped, Vehicle veh)
{
byte? flags = 0;
ushort? flags = 0;
if (veh.IsEngineRunning)
{
flags |= (byte)VehicleDataFlags.IsEngineRunning;
flags |= (ushort)VehicleDataFlags.IsEngineRunning;
}
if (veh.AreLightsOn)
{
flags |= (byte)VehicleDataFlags.AreLightsOn;
flags |= (ushort)VehicleDataFlags.AreLightsOn;
}
if (veh.AreHighBeamsOn)
{
flags |= (byte)VehicleDataFlags.AreHighBeamsOn;
flags |= (ushort)VehicleDataFlags.AreHighBeamsOn;
}
if (veh.IsSirenActive)
{
flags |= (byte)VehicleDataFlags.IsSirenActive;
flags |= (ushort)VehicleDataFlags.IsSirenActive;
}
if (veh.IsDead)
{
flags |= (byte)VehicleDataFlags.IsDead;
flags |= (ushort)VehicleDataFlags.IsDead;
}
if (Function.Call<bool>(Hash.IS_HORN_ACTIVE, veh.Handle))
{
flags |= (byte)VehicleDataFlags.IsHornActive;
flags |= (ushort)VehicleDataFlags.IsHornActive;
}
if (veh.IsSubmarineCar && Function.Call<bool>(Hash._GET_IS_SUBMARINE_VEHICLE_TRANSFORMED, veh.Handle))
{
flags |= (byte)VehicleDataFlags.IsTransformed;
flags |= (ushort)VehicleDataFlags.IsTransformed;
}
if (veh.HasRoof && (veh.RoofState == VehicleRoofState.Opened || veh.RoofState == VehicleRoofState.Opening))
{
flags |= (byte)VehicleDataFlags.RoofOpened;
flags |= (ushort)VehicleDataFlags.RoofOpened;
}
if (veh.IsTurretSeat((int)ped.SeatIndex))
{
flags |= (ushort)VehicleDataFlags.OnTurretSeat;
}
if (veh.IsPlane)
{
flags |= (ushort)VehicleDataFlags.IsPlane;
}
return flags;
@ -290,43 +300,103 @@ namespace CoopClient
return result;
}
public static VehicleDoors[] GetVehicleDoors(this VehicleDoorCollection doors)
public static VehicleDamageModel GetVehicleDamageModel(this Vehicle veh)
{
int doorLength = doors.ToArray().Length;
if (doorLength == 0)
VehicleDamageModel result = new VehicleDamageModel()
{
return null;
BrokenDoors = 0,
BrokenWindows = 0,
BurstedTires = 0,
PuncturedTires = 0
};
// Broken windows
for (int i = 0; i < 8; i++)
{
if (!veh.Windows[(VehicleWindowIndex)i].IsIntact)
{
result.BrokenWindows |= (byte)(1 << i);
}
}
VehicleDoors[] result = new VehicleDoors[doorLength];
for (int i = 0; i < (doorLength - 1); i++)
// Broken doors
foreach (VehicleDoor door in veh.Doors)
{
VehicleDoors currentDoor = new VehicleDoors()
if (door.IsBroken)
{
AngleRatio = doors[(VehicleDoorIndex)i].AngleRatio,
Broken = doors[(VehicleDoorIndex)i].IsBroken,
Open = doors[(VehicleDoorIndex)i].IsOpen,
FullyOpen = doors[(VehicleDoorIndex)i].IsFullyOpen
};
result[i] = currentDoor;
result.BrokenDoors |= (byte)(1 << (byte)door.Index);
}
}
// Bursted and Punctured tires
foreach (VehicleWheel wheel in veh.Wheels.GetAllWheels())
{
if (wheel.IsBursted)
{
result.BurstedTires |= (ushort)(1 << (int)wheel.BoneId);
}
if (wheel.IsPunctured)
{
result.PuncturedTires |= (ushort)(1 << (int)wheel.BoneId);
}
}
return result;
}
public static int GetBurstedTires(this VehicleWheelCollection wheels)
public static void SetVehicleDamageModel(this Vehicle veh, VehicleDamageModel model, bool leavedoors = true)
{
int tireFlag = 0;
// Set doors
for (int i = 0; i < 8; i++)
{
if ((model.BrokenDoors & (byte)(1 << i)) != 0)
{
veh.Doors[(VehicleDoorIndex)i].Break(leavedoors);
}
else if (veh.Doors[(VehicleDoorIndex)i].IsBroken)
{
// The vehicle can only fix a door if the vehicle was completely fixed
veh.Repair();
return;
}
foreach (var wheel in wheels.GetAllWheels())
if ((model.BrokenWindows & (byte)(1 << i)) != 0)
{
if (wheel.IsBursted)
veh.Windows[(VehicleWindowIndex)i].Smash();
}
else if (!veh.Windows[(VehicleWindowIndex)i].IsIntact)
{
tireFlag |= (1 << (int)wheel.BoneId);
veh.Windows[(VehicleWindowIndex)i].Repair();
}
}
return tireFlag;
foreach (VehicleWheel wheel in veh.Wheels)
{
if ((model.PuncturedTires & (ushort)(1 << (int)wheel.BoneId)) != 0)
{
if (!wheel.IsPunctured)
{
wheel.Puncture();
}
}
else if (wheel.IsPunctured)
{
wheel.Fix();
}
if ((model.BurstedTires & (ushort)(1 << (int)wheel.BoneId)) != 0)
{
if (!wheel.IsBursted)
{
wheel.Burst();
}
}
else if (wheel.IsBursted)
{
wheel.Fix();
}
}
}
public static Settings ReadSettings()

106
Server/BitReader.cs Normal file
View File

@ -0,0 +1,106 @@
using System;
using System.Linq;
using System.Text;
namespace CoopServer
{
internal class BitReader
{
public int CurrentIndex { get; set; }
private byte[] ResultArray;
public BitReader(byte[] array)
{
CurrentIndex = 0;
ResultArray = array;
}
~BitReader()
{
ResultArray = null;
}
public bool CanRead(int bytes)
{
return ResultArray.Length >= CurrentIndex + bytes;
}
public bool ReadBool()
{
bool value = BitConverter.ToBoolean(ResultArray, CurrentIndex);
CurrentIndex += 1;
return value;
}
public float ReadFloat()
{
float value = BitConverter.ToSingle(ResultArray, CurrentIndex);
CurrentIndex += 4;
return value;
}
public byte ReadByte()
{
byte value = ResultArray[CurrentIndex];
CurrentIndex += 1;
return value;
}
public byte[] ReadByteArray(int length)
{
byte[] value = ResultArray.Skip(CurrentIndex).Take(length).ToArray();
CurrentIndex += length;
return value;
}
public short ReadShort()
{
short value = BitConverter.ToInt16(ResultArray, CurrentIndex);
CurrentIndex += 2;
return value;
}
public ushort ReadUShort()
{
ushort value = BitConverter.ToUInt16(ResultArray, CurrentIndex);
CurrentIndex += 2;
return value;
}
public int ReadInt()
{
int value = BitConverter.ToInt32(ResultArray, CurrentIndex);
CurrentIndex += 4;
return value;
}
public uint ReadUInt()
{
uint value = BitConverter.ToUInt32(ResultArray, CurrentIndex);
CurrentIndex += 4;
return value;
}
public long ReadLong()
{
long value = BitConverter.ToInt64(ResultArray, CurrentIndex);
CurrentIndex += 8;
return value;
}
public ulong ReadULong()
{
ulong value = BitConverter.ToUInt64(ResultArray, CurrentIndex);
CurrentIndex += 8;
return value;
}
public string ReadString(int index)
{
string value = Encoding.UTF8.GetString(ResultArray.Skip(CurrentIndex).Take(index).ToArray());
CurrentIndex += index;
return value;
}
}
}

View File

@ -65,15 +65,7 @@ namespace CoopServer
return;
}
ChatMessagePacket packet = new()
{
Username = from,
Message = message
};
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
Server.SendChatMessage(from, message, userConnection);
}
catch (Exception e)
{
@ -81,7 +73,7 @@ namespace CoopServer
}
}
public void SendNativeCall(ulong hash, params object[] args)
public void SendNativeCall(ulong hash, List<object> args = null)
{
try
{
@ -92,27 +84,21 @@ namespace CoopServer
return;
}
List<NativeArgument> arguments = null;
if (args != null && args.Length > 0)
if (args != null && args.Count == 0)
{
arguments = Util.ParseNativeArguments(args);
if (arguments == null)
{
Logging.Error($"[Client->SendNativeCall(ulong hash, params object[] args)]: Missing arguments!");
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
return;
}
}
NativeCallPacket packet = new()
{
Hash = hash,
Args = arguments
Args = args ?? new List<object>(),
};
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Native);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
}
catch (Exception e)
{
@ -120,7 +106,7 @@ namespace CoopServer
}
}
public void SendNativeResponse(Action<object> callback, ulong hash, Type type, params object[] args)
public void SendNativeResponse(Action<object> callback, ulong hash, Type returnType, List<object> args = null)
{
try
{
@ -131,59 +117,51 @@ namespace CoopServer
return;
}
NativeArgument returnType = null;
Type typeOf = type;
if (typeOf == typeof(int))
if (args != null && args.Count == 0)
{
returnType = new IntArgument();
}
else if (typeOf == typeof(bool))
{
returnType = new BoolArgument();
}
else if (typeOf == typeof(float))
{
returnType = new FloatArgument();
}
else if (typeOf == typeof(string))
{
returnType = new StringArgument();
}
else if (typeOf == typeof(LVector3))
{
returnType = new LVector3Argument();
}
else
{
Logging.Error($"[Client->SendNativeResponse(Action<object> callback, ulong hash, Type type, params object[] args)]: Argument does not exist!");
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
return;
}
List<NativeArgument> arguments = null;
if (args != null && args.Length > 0)
{
arguments = Util.ParseNativeArguments(args);
if (arguments == null)
{
Logging.Error($"[Client->SendNativeResponse(Action<object> callback, ulong hash, Type type, params object[] args)]: One or more arguments do not exist!");
return;
}
}
long id = 0;
Callbacks.Add(id = Environment.TickCount64, callback);
NativeResponsePacket packet = new()
byte returnTypeValue = 0x00;
if (returnType == typeof(int))
{
Hash = hash,
Args = arguments,
Type = returnType,
NetHandle = id
};
// NOTHING BECAUSE VALUE IS 0x00
}
else if (returnType == typeof(bool))
{
returnTypeValue = 0x01;
}
else if (returnType == typeof(float))
{
returnTypeValue = 0x02;
}
else if (returnType == typeof(string))
{
returnTypeValue = 0x03;
}
else if (returnType == typeof(LVector3))
{
returnTypeValue = 0x04;
}
else
{
Logging.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing return type!");
return;
}
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Native);
new NativeResponsePacket()
{
Hash = hash,
Args = args ?? new List<object>(),
ResultType = returnTypeValue,
ID = id
}.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
}
catch (Exception e)
{
@ -210,7 +188,7 @@ namespace CoopServer
CustomPacketID = customID,
Bytes = bytes
}.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Mod);
Server.MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
Server.MainNetServer.FlushSendQueue();
}
catch (Exception e)

View File

@ -15,9 +15,6 @@
<Reference Include="Newtonsoft.Json">
<HintPath>..\Libs\Release\scripts\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="protobuf-net">
<HintPath>..\Libs\Release\scripts\protobuf-net.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ namespace CoopServer
internal class Server
{
private static readonly string CompatibleVersion = "V1_2";
private static readonly string CompatibleVersion = "V1_3";
public static readonly Settings MainSettings = Util.Read<Settings>("CoopSettings.xml");
private readonly Blocklist MainBlocklist = Util.Read<Blocklist>("Blocklist.xml");
@ -237,10 +237,13 @@ namespace CoopServer
{
try
{
Packet approvalPacket;
approvalPacket = new HandshakePacket();
approvalPacket.NetIncomingMessageToPacket(message);
GetHandshake(message.SenderConnection, (HandshakePacket)approvalPacket);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
HandshakePacket packet = new HandshakePacket();
packet.NetIncomingMessageToPacket(data);
GetHandshake(message.SenderConnection, packet);
}
catch (Exception e)
{
@ -265,79 +268,111 @@ namespace CoopServer
// Get packet type
byte type = message.ReadByte();
// Create packet
Packet packet;
switch (type)
{
case (byte)PacketTypes.FullSyncPlayerPacket:
{
try
{
packet = new FullSyncPlayerPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncPlayer((FullSyncPlayerPacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncPlayerPacket packet = new FullSyncPlayerPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncPlayer(packet);
}
catch (Exception e)
{
message.SenderConnection.Disconnect(e.Message);
}
}
break;
case (byte)PacketTypes.FullSyncPlayerVehPacket:
{
try
{
packet = new FullSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncPlayerVeh((FullSyncPlayerVehPacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncPlayerVehPacket packet = new FullSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncPlayerVeh(packet);
}
catch (Exception e)
{
message.SenderConnection.Disconnect(e.Message);
}
}
break;
case (byte)PacketTypes.LightSyncPlayerPacket:
{
try
{
packet = new LightSyncPlayerPacket();
packet.NetIncomingMessageToPacket(message);
LightSyncPlayer((LightSyncPlayerPacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
LightSyncPlayerPacket packet = new LightSyncPlayerPacket();
packet.NetIncomingMessageToPacket(data);
LightSyncPlayer(packet);
}
catch (Exception e)
{
message.SenderConnection.Disconnect(e.Message);
}
}
break;
case (byte)PacketTypes.LightSyncPlayerVehPacket:
{
try
{
packet = new LightSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(message);
LightSyncPlayerVeh((LightSyncPlayerVehPacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
LightSyncPlayerVehPacket packet = new LightSyncPlayerVehPacket();
packet.NetIncomingMessageToPacket(data);
LightSyncPlayerVeh(packet);
}
catch (Exception e)
{
message.SenderConnection.Disconnect(e.Message);
}
}
break;
case (byte)PacketTypes.ChatMessagePacket:
{
try
{
packet = new ChatMessagePacket();
packet.NetIncomingMessageToPacket(message);
SendChatMessage((ChatMessagePacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
ChatMessagePacket packet = new ChatMessagePacket();
packet.NetIncomingMessageToPacket(data);
SendChatMessage(packet);
}
catch (Exception e)
{
message.SenderConnection.Disconnect(e.Message);
}
}
break;
case (byte)PacketTypes.FullSyncNpcPacket:
{
if (MainSettings.NpcsAllowed)
{
try
{
packet = new FullSyncNpcPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncNpc(message.SenderConnection, (FullSyncNpcPacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncNpcPacket packet = new FullSyncNpcPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncNpc(message.SenderConnection, packet);
}
catch (Exception e)
{
@ -348,15 +383,21 @@ namespace CoopServer
{
message.SenderConnection.Disconnect("Npcs are not allowed!");
}
}
break;
case (byte)PacketTypes.FullSyncNpcVehPacket:
{
if (MainSettings.NpcsAllowed)
{
try
{
packet = new FullSyncNpcVehPacket();
packet.NetIncomingMessageToPacket(message);
FullSyncNpcVeh(message.SenderConnection, (FullSyncNpcVehPacket)packet);
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
FullSyncNpcVehPacket packet = new FullSyncNpcVehPacket();
packet.NetIncomingMessageToPacket(data);
FullSyncNpcVeh(message.SenderConnection, packet);
}
catch (Exception e)
{
@ -367,44 +408,25 @@ namespace CoopServer
{
message.SenderConnection.Disconnect("Npcs are not allowed!");
}
}
break;
case (byte)PacketTypes.NativeResponsePacket:
{
try
{
packet = new NativeResponsePacket();
packet.NetIncomingMessageToPacket(message);
NativeResponsePacket responsePacket = (NativeResponsePacket)packet;
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
NativeResponsePacket packet = new NativeResponsePacket();
packet.NetIncomingMessageToPacket(data);
Client client = Clients.Find(x => x.NetHandle == message.SenderConnection.RemoteUniqueIdentifier);
if (client != null)
{
if (client.Callbacks.ContainsKey(responsePacket.NetHandle))
if (client.Callbacks.ContainsKey(packet.ID))
{
object resp = null;
if (responsePacket.Type is IntArgument argument)
{
resp = argument.Data;
}
else if (responsePacket.Type is StringArgument argument1)
{
resp = argument1.Data;
}
else if (responsePacket.Type is FloatArgument argument2)
{
resp = argument2.Data;
}
else if (responsePacket.Type is BoolArgument argument3)
{
resp = argument3.Data;
}
else if (responsePacket.Type is LVector3Argument argument4)
{
resp = argument4.Data;
}
client.Callbacks[responsePacket.NetHandle].Invoke(resp);
client.Callbacks.Remove(responsePacket.NetHandle);
client.Callbacks[packet.ID].Invoke(packet.Args[0]);
client.Callbacks.Remove(packet.ID);
}
}
}
@ -415,48 +437,51 @@ namespace CoopServer
}
break;
case (byte)PacketTypes.ModPacket:
{
if (MainSettings.ModsAllowed)
{
try
{
packet = new ModPacket();
packet.NetIncomingMessageToPacket(message);
ModPacket modPacket = (ModPacket)packet;
int len = message.ReadInt32();
byte[] data = message.ReadBytes(len);
ModPacket packet = new ModPacket();
packet.NetIncomingMessageToPacket(data);
bool resourceResult = false;
if (Resources.Any())
{
Resources.ForEach(x =>
{
if (x.InvokeModPacketReceived(modPacket.NetHandle, modPacket.Target, modPacket.Mod, modPacket.CustomPacketID, modPacket.Bytes))
if (x.InvokeModPacketReceived(packet.NetHandle, packet.Target, packet.Mod, packet.CustomPacketID, packet.Bytes))
{
resourceResult = true;
}
});
}
if (!resourceResult && modPacket.Target != -1)
if (!resourceResult && packet.Target != -1)
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
modPacket.PacketToNetOutGoingMessage(outgoingMessage);
packet.PacketToNetOutGoingMessage(outgoingMessage);
if (modPacket.Target != 0)
if (packet.Target != 0)
{
NetConnection target = MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == modPacket.Target);
NetConnection target = MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == packet.Target);
if (target == null)
{
Logging.Error($"[ModPacket] target \"{modPacket.Target}\" not found!");
Logging.Error($"[ModPacket] target \"{packet.Target}\" not found!");
}
else
{
// Send back to target
MainNetServer.SendMessage(outgoingMessage, target, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Mod);
MainNetServer.SendMessage(outgoingMessage, target, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
}
}
else
{
// Send back to all players
MainNetServer.SendMessage(outgoingMessage, MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Mod);
MainNetServer.SendMessage(outgoingMessage, MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
}
}
}
@ -469,6 +494,7 @@ namespace CoopServer
{
message.SenderConnection.Disconnect("Mods are not allowed!");
}
}
break;
default:
Logging.Error("Unhandled Data / Packet type");
@ -598,7 +624,7 @@ namespace CoopServer
NetHandle = localNetHandle,
Username = string.Empty,
ModVersion = string.Empty,
NpcsAllowed = MainSettings.NpcsAllowed
NPCsAllowed = MainSettings.NpcsAllowed
}.PacketToNetOutGoingMessage(outgoingMessage);
// Accept the connection and send back a new handshake packet with the connection ID
@ -697,36 +723,36 @@ namespace CoopServer
private static void FullSyncPlayer(FullSyncPlayerPacket packet)
{
Client client = Util.GetClientByNetHandle(packet.Extra.NetHandle);
Client client = Util.GetClientByNetHandle(packet.NetHandle);
if (client == null)
{
return;
}
client.Player.Position = packet.Extra.Position;
client.Player.Health = packet.Extra.Health;
// Save the new data
client.Player.Position = packet.Position;
client.Player.Health = packet.Health;
PlayerPacket playerPacket = packet.Extra;
playerPacket.Latency = client.Latency;
// Override the latency
packet.Latency = client.Latency;
packet.Extra = playerPacket;
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.NetHandle).ForEach(x =>
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.NetHandle).ForEach(x =>
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Position, 550f))
{
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerFull);
}
else
{
new SuperLightSyncPlayerPacket()
new SuperLightSyncPacket()
{
Extra = packet.Extra
NetHandle = packet.NetHandle,
Position = packet.Position,
Latency = packet.Latency
}.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
}
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.Player);
});
if (Resources.Any())
@ -737,36 +763,37 @@ namespace CoopServer
private static void FullSyncPlayerVeh(FullSyncPlayerVehPacket packet)
{
Client client = Util.GetClientByNetHandle(packet.Extra.NetHandle);
Client client = Util.GetClientByNetHandle(packet.NetHandle);
if (client == null)
{
return;
}
client.Player.Position = packet.Extra.Position;
client.Player.Health = packet.Extra.Health;
// Save the new data
client.Player.Position = packet.Position;
client.Player.Health = packet.Health;
PlayerPacket playerPacket = packet.Extra;
playerPacket.Latency = client.Latency;
// Override the latency
packet.Latency = client.Latency;
packet.Extra = playerPacket;
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.NetHandle).ForEach(x =>
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.NetHandle).ForEach(x =>
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Position, 550f))
{
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerFull);
}
else
{
new SuperLightSyncPlayerPacket()
new SuperLightSyncPacket()
{
Extra = packet.Extra
NetHandle = packet.NetHandle,
Position = packet.Position,
Latency = packet.Latency
}.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
}
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.Player);
});
if (Resources.Any())
@ -777,36 +804,37 @@ namespace CoopServer
private static void LightSyncPlayer(LightSyncPlayerPacket packet)
{
Client client = Util.GetClientByNetHandle(packet.Extra.NetHandle);
Client client = Util.GetClientByNetHandle(packet.NetHandle);
if (client == null)
{
return;
}
client.Player.Position = packet.Extra.Position;
client.Player.Health = packet.Extra.Health;
// Save the new data
client.Player.Position = packet.Position;
client.Player.Health = packet.Health;
PlayerPacket playerPacket = packet.Extra;
playerPacket.Latency = client.Latency;
// Override the latency
packet.Latency = client.Latency;
packet.Extra = playerPacket;
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.NetHandle).ForEach(x =>
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.NetHandle).ForEach(x =>
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Position, 550f))
{
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerLight);
}
else
{
new SuperLightSyncPlayerPacket()
new SuperLightSyncPacket()
{
Extra = packet.Extra
NetHandle = packet.NetHandle,
Position = packet.Position,
Latency = packet.Latency
}.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
}
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.Player);
});
if (Resources.Any())
@ -817,36 +845,37 @@ namespace CoopServer
private static void LightSyncPlayerVeh(LightSyncPlayerVehPacket packet)
{
Client client = Util.GetClientByNetHandle(packet.Extra.NetHandle);
Client client = Util.GetClientByNetHandle(packet.NetHandle);
if (client == null)
{
return;
}
client.Player.Position = packet.Extra.Position;
client.Player.Health = packet.Extra.Health;
// Save the new data
client.Player.Position = packet.Position;
client.Player.Health = packet.Health;
PlayerPacket playerPacket = packet.Extra;
playerPacket.Latency = client.Latency;
// Override the latency
packet.Latency = client.Latency;
packet.Extra = playerPacket;
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.Extra.NetHandle).ForEach(x =>
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.NetHandle).ForEach(x =>
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Extra.Position, 550f))
if (Clients.First(y => y.NetHandle == x.RemoteUniqueIdentifier).Player.IsInRangeOf(packet.Position, 550f))
{
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerLight);
}
else
{
new SuperLightSyncPlayerPacket()
new SuperLightSyncPacket()
{
Extra = packet.Extra
NetHandle = packet.NetHandle,
Position = packet.Position,
Latency = packet.Latency
}.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
}
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.Player);
});
if (Resources.Any())
@ -858,8 +887,6 @@ namespace CoopServer
// Send a message to targets or all players
private static void SendChatMessage(ChatMessagePacket packet, List<NetConnection> targets = null)
{
NetOutgoingMessage outgoingMessage;
if (Resources.Any())
{
if (packet.Message.StartsWith('/'))
@ -886,13 +913,7 @@ namespace CoopServer
return;
}
outgoingMessage = MainNetServer.CreateMessage();
new ChatMessagePacket()
{
Username = "Server",
Message = command.Key.Usage
}.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
SendChatMessage("Server", command.Key.Usage, userConnection);
return;
}
@ -906,13 +927,7 @@ namespace CoopServer
return;
}
outgoingMessage = MainNetServer.CreateMessage();
new ChatMessagePacket()
{
Username = "Server",
Message = "Command not found!"
}.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, userConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
SendChatMessage("Server", "Command not found!", userConnection);
}
return;
@ -938,12 +953,23 @@ namespace CoopServer
packet.Message = packet.Message.Replace("~", "");
outgoingMessage = MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, targets ?? MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
SendChatMessage(packet.Username, packet.Message, targets);
Logging.Info(packet.Username + ": " + packet.Message);
}
internal static void SendChatMessage(string username, string message, List<NetConnection> targets = null)
{
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
new ChatMessagePacket() { Username = username, Message = message }.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, targets ?? MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
}
internal static void SendChatMessage(string username, string message, NetConnection target)
{
SendChatMessage(username, message, new List<NetConnection>() { target });
}
#endregion
#region -- NPC --
@ -957,7 +983,7 @@ namespace CoopServer
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.NPC);
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.NPCFull);
}
private static void FullSyncNpcVeh(NetConnection local, FullSyncNpcVehPacket packet)
@ -970,7 +996,7 @@ namespace CoopServer
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.UnreliableSequenced, (int)ConnectionChannel.NPC);
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.NPCFull);
}
#endregion

View File

@ -261,7 +261,7 @@ namespace CoopServer
CustomPacketID = customID,
Bytes = bytes
}.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, connections, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Mod);
Server.MainNetServer.SendMessage(outgoingMessage, connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Mod);
Server.MainNetServer.FlushSendQueue();
}
catch (Exception e)
@ -271,11 +271,12 @@ namespace CoopServer
}
/// <summary>
/// Send a native call (Function.Call) to all players
/// Send a native call (Function.Call) to all players.
/// Keys = int, float, bool, string and lvector3
/// </summary>
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</param>
/// <param name="args">The arguments (Example: "Function.Call(Hash.SET_TIME_SCALE, args);")</param>
public static void SendNativeCallToAll(ulong hash, params object[] args)
/// <param name="args">The arguments (Example: string = int, object = 5)</param>
public static void SendNativeCallToAll(ulong hash, List<object> args = null)
{
try
{
@ -284,22 +285,21 @@ namespace CoopServer
return;
}
List<NativeArgument> arguments = Util.ParseNativeArguments(args);
if (arguments == null)
if (args != null && args.Count == 0)
{
Logging.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: One or more arguments do not exist!");
Logging.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: args is not null!");
return;
}
NativeCallPacket packet = new()
{
Hash = hash,
Args = arguments
Args = args ?? new List<object>()
};
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
packet.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Native);
Server.MainNetServer.SendMessage(outgoingMessage, Server.MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Native);
}
catch (Exception e)
{
@ -354,13 +354,7 @@ namespace CoopServer
? Server.MainNetServer.Connections
: Server.MainNetServer.Connections.FindAll(c => netHandleList.Contains(c.RemoteUniqueIdentifier));
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
new ChatMessagePacket()
{
Username = username,
Message = message
}.PacketToNetOutGoingMessage(outgoingMessage);
Server.MainNetServer.SendMessage(outgoingMessage, connections, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
Server.SendChatMessage(username, message, connections);
}
catch (Exception e)
{

View File

@ -10,48 +10,6 @@ namespace CoopServer
{
internal class Util
{
public static List<NativeArgument> ParseNativeArguments(params object[] args)
{
List<NativeArgument> result = null;
if (args != null && args.Length > 0)
{
result = new();
foreach (object arg in args)
{
Type typeOf = arg.GetType();
if (typeOf == typeof(int))
{
result.Add(new IntArgument() { Data = (int)arg });
}
else if (typeOf == typeof(bool))
{
result.Add(new BoolArgument() { Data = (bool)arg });
}
else if (typeOf == typeof(float))
{
result.Add(new FloatArgument() { Data = (float)arg });
}
else if (typeOf == typeof(string))
{
result.Add(new StringArgument() { Data = (string)arg });
}
else if (typeOf == typeof(LVector3))
{
result.Add(new LVector3Argument() { Data = (LVector3)arg });
}
else
{
return null;
}
}
}
return result;
}
public static Client GetClientByNetHandle(long netHandle)
{
Client result = Server.Clients.Find(x => x.NetHandle == netHandle);