Big update! Projectile sync, latency and weapon fix
This commit is contained in:
@ -243,7 +243,7 @@ namespace RageCoop.Client
|
||||
/// <param name="enable">true to disable traffic</param>
|
||||
public static void SetLocalTraffic(bool enable)
|
||||
{
|
||||
Main.DisableTraffic = !enable;
|
||||
Main.Settings.DisableTraffic = !enable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -26,7 +26,6 @@ namespace RageCoop.Client
|
||||
public static readonly string CurrentVersion = "V0_1";
|
||||
|
||||
public static int LocalPlayerID=0;
|
||||
public static bool DisableTraffic = true;
|
||||
public static bool NPCsAllowed = false;
|
||||
internal static RelationshipGroup SyncedPedsGroup;
|
||||
|
||||
|
@ -97,7 +97,7 @@ namespace RageCoop.Client.Menus
|
||||
{
|
||||
MainMenu.Items[2].Enabled = true;
|
||||
MainMenu.Items[2].Title = "Disconnect";
|
||||
SubSettings.MainMenu.Items[1].Enabled = !Main.DisableTraffic && Main.NPCsAllowed;
|
||||
SubSettings.MainMenu.Items[1].Enabled = !Main.Settings.DisableTraffic && Main.NPCsAllowed;
|
||||
|
||||
MainMenu.Visible = false;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace RageCoop.Client.Menus.Sub
|
||||
Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
|
||||
};
|
||||
|
||||
private readonly NativeCheckboxItem _disableTrafficItem = new NativeCheckboxItem("Disable Traffic (NPCs/Vehicles)", "Local traffic only", Main.DisableTraffic);
|
||||
private readonly NativeCheckboxItem _disableTrafficItem = new NativeCheckboxItem("Disable Traffic (NPCs/Vehicles)", "Local traffic only", Main.Settings.DisableTraffic);
|
||||
private readonly NativeCheckboxItem _flipMenuItem = new NativeCheckboxItem("Flip menu", Main.Settings.FlipMenu);
|
||||
private readonly NativeCheckboxItem _showNetworkInfoItem = new NativeCheckboxItem("Show Network Info", Networking.ShowNetworkInfo);
|
||||
private static NativeItem _menuKey = new NativeItem("Menu Key","The key to open menu", Main.Settings.MenuKey.ToString());
|
||||
@ -74,7 +74,7 @@ namespace RageCoop.Client.Menus.Sub
|
||||
|
||||
public void DisableTrafficCheckboxChanged(object a, System.EventArgs b)
|
||||
{
|
||||
Main.DisableTraffic = _disableTrafficItem.Checked;
|
||||
Main.Settings.DisableTraffic = _disableTrafficItem.Checked;
|
||||
}
|
||||
|
||||
public void FlipMenuCheckboxChanged(object a, System.EventArgs b)
|
||||
|
@ -60,7 +60,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
XmlSerializer ser = new XmlSerializer(typeof(Settings));
|
||||
|
||||
string path = Directory.GetCurrentDirectory() + "\\Scripts\\RageCoop\\Settings.xml";
|
||||
string path = Directory.GetCurrentDirectory() + "\\Scripts\\RageCoop\\RageCoop.Client.Settings.xml";
|
||||
Settings settings = null;
|
||||
|
||||
if (File.Exists(path))
|
||||
@ -89,7 +89,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = Directory.GetCurrentDirectory() + "\\Scripts\\RageCoop\\Settings.xml";
|
||||
string path = Directory.GetCurrentDirectory() + "\\Scripts\\RageCoop\\RageCoop.Client.Settings.xml";
|
||||
|
||||
using (FileStream stream = new FileStream(path, File.Exists(path) ? FileMode.Truncate : FileMode.Create, FileAccess.ReadWrite))
|
||||
{
|
||||
@ -487,6 +487,12 @@ namespace RageCoop.Client
|
||||
return p.Bones[Bone.SkelRightHand].Position;
|
||||
}
|
||||
|
||||
public static bool IsUsingProjectileWeapon(this Ped p)
|
||||
{
|
||||
var w = p.Weapons.Current;
|
||||
return w.Group==WeaponGroup.Thrown||ProjectileWeapons.Contains(w.Hash);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region VEHICLE
|
||||
@ -890,7 +896,33 @@ namespace RageCoop.Client
|
||||
{WeaponHash.PumpShotgunMk2,7},
|
||||
|
||||
};
|
||||
|
||||
public static readonly HashSet<WeaponHash> ProjectileWeapons = new HashSet<WeaponHash> {
|
||||
WeaponHash.HomingLauncher,
|
||||
WeaponHash.RPG,
|
||||
WeaponHash.Firework,
|
||||
WeaponHash.UpNAtomizer,
|
||||
WeaponHash.GrenadeLauncher,
|
||||
WeaponHash.GrenadeLauncherSmoke,
|
||||
WeaponHash.CompactGrenadeLauncher
|
||||
};
|
||||
/*
|
||||
public static readonly Dictionary<WeaponHash, ExplosionType> WeaponExplosionTypes = new Dictionary<WeaponHash, ExplosionType> {
|
||||
{ WeaponHash.Grenade,ExplosionType.Grenade},
|
||||
{ WeaponHash.GrenadeLauncher,ExplosionType.Grenade},
|
||||
{ WeaponHash.CompactGrenadeLauncher,ExplosionType.Grenade},
|
||||
{ WeaponHash.SmokeGrenade,ExplosionType.SmokeG},
|
||||
{ WeaponHash.GrenadeLauncherSmoke,ExplosionType.SmokeG},
|
||||
{ WeaponHash.StickyBomb,ExplosionType.StickyBomb},
|
||||
{ WeaponHash.Flare,ExplosionType.Flare},
|
||||
{ WeaponHash.FlareGun,ExplosionType.Flare},
|
||||
{ WeaponHash.Molotov,ExplosionType.Molotov1},
|
||||
{ WeaponHash.BZGas,ExplosionType.BZGas},
|
||||
{ WeaponHash.PipeBomb,ExplosionType.PipeBomb},
|
||||
{ WeaponHash.ProximityMine,ExplosionType.ProxMine},
|
||||
{ WeaponHash.Firework,ExplosionType.FireWork},
|
||||
{ WeaponHash.RPG,ExplosionType.Rocket},
|
||||
};
|
||||
*/
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -11,7 +11,7 @@ using GTA.Native;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
public static partial class Networking
|
||||
internal static partial class Networking
|
||||
{
|
||||
public static NetClient Client;
|
||||
public static float Latency = 0;
|
||||
|
@ -10,7 +10,7 @@ using GTA.Native;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
public static partial class Networking
|
||||
internal static partial class Networking
|
||||
{
|
||||
public static void ReceiveMessages()
|
||||
{
|
||||
@ -137,6 +137,13 @@ namespace RageCoop.Client
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.PlayerInfoUpdate:
|
||||
{
|
||||
var packet = new Packets.PlayerInfoUpdate();
|
||||
packet.Unpack(data);
|
||||
PlayerList.SetPlayer(packet.PedID,packet.Username,packet.Latency);
|
||||
break;
|
||||
}
|
||||
#region ENTITY SYNC
|
||||
case PacketTypes.VehicleSync:
|
||||
{
|
||||
@ -147,7 +154,7 @@ namespace RageCoop.Client
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.CharacterSync:
|
||||
case PacketTypes.PedSync:
|
||||
{
|
||||
|
||||
Packets.PedSync packet = new Packets.PedSync();
|
||||
@ -165,7 +172,7 @@ namespace RageCoop.Client
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.CharacterStateSync:
|
||||
case PacketTypes.PedStateSync:
|
||||
{
|
||||
|
||||
|
||||
@ -175,6 +182,13 @@ namespace RageCoop.Client
|
||||
|
||||
}
|
||||
break;
|
||||
case PacketTypes.ProjectileSync:
|
||||
{
|
||||
Packets.ProjectileSync packet = new Packets.ProjectileSync();
|
||||
packet.Unpack(data);
|
||||
ProjectileSync(packet);
|
||||
break;
|
||||
}
|
||||
#endregion
|
||||
case PacketTypes.ChatMessage:
|
||||
{
|
||||
@ -289,125 +303,132 @@ namespace RageCoop.Client
|
||||
Client.Recycle(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void PedSync(Packets.PedSync packet)
|
||||
{
|
||||
lock (EntityPool.PedsLock)
|
||||
if (!EntityPool.PedExists(packet.ID))
|
||||
{
|
||||
if (!EntityPool.Exists(packet.ID))
|
||||
{
|
||||
Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}");
|
||||
|
||||
EntityPool.Add(new SyncedPed(packet.ID));
|
||||
}
|
||||
PedDataFlags flags=packet.Flag;
|
||||
SyncedPed c = EntityPool.GetPedByID(packet.ID);
|
||||
c.ID=packet.ID;
|
||||
//c.OwnerID=packet.OwnerID;
|
||||
c.Health = packet.Health;
|
||||
c.Position = packet.Position.ToVector();
|
||||
c.Rotation = packet.Rotation.ToVector();
|
||||
c.Velocity = packet.Velocity.ToVector();
|
||||
c.Speed = packet.Speed;
|
||||
c.CurrentWeaponHash = packet.CurrentWeaponHash;
|
||||
c.IsAiming = flags.HasFlag(PedDataFlags.IsAiming);
|
||||
c.IsReloading = flags.HasFlag(PedDataFlags.IsReloading);
|
||||
c.IsJumping = flags.HasFlag(PedDataFlags.IsJumping) ;
|
||||
c.IsRagdoll = flags.HasFlag(PedDataFlags.IsRagdoll);
|
||||
c.IsOnFire = flags.HasFlag(PedDataFlags.IsOnFire) ;
|
||||
c.IsInParachuteFreeFall = flags.HasFlag(PedDataFlags.IsInParachuteFreeFall);
|
||||
c.IsParachuteOpen = flags.HasFlag(PedDataFlags.IsParachuteOpen);
|
||||
c.IsOnLadder = flags.HasFlag(PedDataFlags.IsOnLadder);
|
||||
c.IsVaulting = flags.HasFlag(PedDataFlags.IsVaulting);
|
||||
c.IsInCover = flags.HasFlag(PedDataFlags.IsInCover);
|
||||
c.Heading=packet.Heading;
|
||||
c.LastSynced = Main.Ticked;
|
||||
if (c.IsAiming)
|
||||
{
|
||||
c.AimCoords = packet.AimCoords.ToVector();
|
||||
}
|
||||
if (c.IsRagdoll)
|
||||
{
|
||||
c.RotationVelocity=packet.RotationVelocity.ToVector();
|
||||
}
|
||||
Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}");
|
||||
|
||||
EntityPool.ThreadSafe.Add(new SyncedPed(packet.ID));
|
||||
}
|
||||
PedDataFlags flags = packet.Flag;
|
||||
SyncedPed c = EntityPool.GetPedByID(packet.ID);
|
||||
c.ID=packet.ID;
|
||||
//c.OwnerID=packet.OwnerID;
|
||||
c.Health = packet.Health;
|
||||
c.Position = packet.Position.ToVector();
|
||||
c.Rotation = packet.Rotation.ToVector();
|
||||
c.Velocity = packet.Velocity.ToVector();
|
||||
c.Speed = packet.Speed;
|
||||
c.CurrentWeaponHash = packet.CurrentWeaponHash;
|
||||
c.IsAiming = flags.HasFlag(PedDataFlags.IsAiming);
|
||||
c.IsReloading = flags.HasFlag(PedDataFlags.IsReloading);
|
||||
c.IsJumping = flags.HasFlag(PedDataFlags.IsJumping);
|
||||
c.IsRagdoll = flags.HasFlag(PedDataFlags.IsRagdoll);
|
||||
c.IsOnFire = flags.HasFlag(PedDataFlags.IsOnFire);
|
||||
c.IsInParachuteFreeFall = flags.HasFlag(PedDataFlags.IsInParachuteFreeFall);
|
||||
c.IsParachuteOpen = flags.HasFlag(PedDataFlags.IsParachuteOpen);
|
||||
c.IsOnLadder = flags.HasFlag(PedDataFlags.IsOnLadder);
|
||||
c.IsVaulting = flags.HasFlag(PedDataFlags.IsVaulting);
|
||||
c.IsInCover = flags.HasFlag(PedDataFlags.IsInCover);
|
||||
c.Heading=packet.Heading;
|
||||
c.LastSynced = Main.Ticked;
|
||||
if (c.IsAiming)
|
||||
{
|
||||
c.AimCoords = packet.AimCoords.ToVector();
|
||||
}
|
||||
if (c.IsRagdoll)
|
||||
{
|
||||
c.RotationVelocity=packet.RotationVelocity.ToVector();
|
||||
}
|
||||
}
|
||||
private static void PedStateSync(Packets.PedStateSync packet)
|
||||
{
|
||||
lock (EntityPool.PedsLock)
|
||||
if (!EntityPool.PedExists(packet.ID))
|
||||
{
|
||||
if (!EntityPool.Exists(packet.ID))
|
||||
{
|
||||
Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}");
|
||||
Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}");
|
||||
|
||||
EntityPool.Add(new SyncedPed(packet.ID));
|
||||
}
|
||||
SyncedPed c = EntityPool.GetPedByID(packet.ID);
|
||||
c.ID=packet.ID;
|
||||
c.OwnerID=packet.OwnerID;
|
||||
c.Clothes=packet.Clothes;
|
||||
c.WeaponComponents=packet.WeaponComponents;
|
||||
c.ModelHash=packet.ModelHash;
|
||||
c.LastSynced=c.LastStateSynced = Main.Ticked;
|
||||
EntityPool.ThreadSafe.Add(new SyncedPed(packet.ID));
|
||||
}
|
||||
SyncedPed c = EntityPool.GetPedByID(packet.ID);
|
||||
c.ID=packet.ID;
|
||||
c.OwnerID=packet.OwnerID;
|
||||
c.Clothes=packet.Clothes;
|
||||
c.WeaponComponents=packet.WeaponComponents;
|
||||
c.ModelHash=packet.ModelHash;
|
||||
c.LastSynced=c.LastStateSynced = Main.Ticked;
|
||||
}
|
||||
private static void VehicleSync(Packets.VehicleSync packet)
|
||||
{
|
||||
lock (EntityPool.VehiclesLock)
|
||||
if (!EntityPool.VehicleExists(packet.ID))
|
||||
{
|
||||
if (!EntityPool.Exists(packet.ID))
|
||||
{
|
||||
EntityPool.Add(new SyncedVehicle(packet.ID));
|
||||
}
|
||||
SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID);
|
||||
v.ID= packet.ID;
|
||||
v.Position=packet.Position.ToVector();
|
||||
v.Rotation=packet.Rotation.ToVector();
|
||||
v.SteeringAngle=packet.SteeringAngle;
|
||||
v.ThrottlePower=packet.ThrottlePower;
|
||||
v.BrakePower=packet.BrakePower;
|
||||
v.Velocity=packet.Velocity.ToVector();
|
||||
v.RotationVelocity=packet.RotationVelocity.ToVector();
|
||||
v.LastSynced=Main.Ticked;
|
||||
EntityPool.ThreadSafe.Add(new SyncedVehicle(packet.ID));
|
||||
}
|
||||
SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID);
|
||||
v.ID= packet.ID;
|
||||
v.Position=packet.Position.ToVector();
|
||||
v.Rotation=packet.Rotation.ToVector();
|
||||
v.SteeringAngle=packet.SteeringAngle;
|
||||
v.ThrottlePower=packet.ThrottlePower;
|
||||
v.BrakePower=packet.BrakePower;
|
||||
v.Velocity=packet.Velocity.ToVector();
|
||||
v.RotationVelocity=packet.RotationVelocity.ToVector();
|
||||
v.LastSynced=Main.Ticked;
|
||||
}
|
||||
private static void VehicleStateSync(Packets.VehicleStateSync packet)
|
||||
{
|
||||
lock (EntityPool.VehiclesLock)
|
||||
if (!EntityPool.VehicleExists(packet.ID))
|
||||
{
|
||||
if (!EntityPool.Exists(packet.ID))
|
||||
{
|
||||
EntityPool.Add( new SyncedVehicle(packet.ID));
|
||||
}
|
||||
SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID);
|
||||
v.ID= packet.ID;
|
||||
v.OwnerID= packet.OwnerID;
|
||||
v.DamageModel=packet.DamageModel;
|
||||
v.EngineHealth=packet.EngineHealth;
|
||||
v.OwnerID=packet.OwnerID;
|
||||
v.Mods=packet.Mods;
|
||||
v.ModelHash=packet.ModelHash;
|
||||
v.Colors=packet.Colors;
|
||||
v.LandingGear=packet.LandingGear;
|
||||
v.EngineRunning = packet.Flag.HasFlag(VehicleDataFlags.IsEngineRunning);
|
||||
v.LightsOn = packet.Flag.HasFlag(VehicleDataFlags.AreLightsOn);
|
||||
v.BrakeLightsOn = packet.Flag.HasFlag(VehicleDataFlags.AreBrakeLightsOn);
|
||||
v.HighBeamsOn = packet.Flag.HasFlag(VehicleDataFlags.AreHighBeamsOn);
|
||||
v.SireneActive = packet.Flag.HasFlag(VehicleDataFlags.IsSirenActive) ;
|
||||
v.IsDead = packet.Flag.HasFlag(VehicleDataFlags.IsDead) ;
|
||||
v.HornActive = packet.Flag.HasFlag(VehicleDataFlags.IsHornActive);
|
||||
v.Transformed = packet.Flag.HasFlag(VehicleDataFlags.IsTransformed);
|
||||
v.Passengers=new Dictionary<VehicleSeat, SyncedPed>();
|
||||
v.LockStatus=packet.LockStatus;
|
||||
foreach (KeyValuePair<int, int> pair in packet.Passengers)
|
||||
{
|
||||
if (EntityPool.Exists(pair.Value))
|
||||
{
|
||||
v.Passengers.Add((VehicleSeat)pair.Key, EntityPool.GetPedByID(pair.Value));
|
||||
}
|
||||
}
|
||||
v.LastStateSynced=v.LastSynced= Main.Ticked;
|
||||
EntityPool.ThreadSafe.Add(new SyncedVehicle(packet.ID));
|
||||
}
|
||||
SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID);
|
||||
v.ID= packet.ID;
|
||||
v.OwnerID= packet.OwnerID;
|
||||
v.DamageModel=packet.DamageModel;
|
||||
v.EngineHealth=packet.EngineHealth;
|
||||
v.OwnerID=packet.OwnerID;
|
||||
v.Mods=packet.Mods;
|
||||
v.ModelHash=packet.ModelHash;
|
||||
v.Colors=packet.Colors;
|
||||
v.LandingGear=packet.LandingGear;
|
||||
v.EngineRunning = packet.Flag.HasFlag(VehicleDataFlags.IsEngineRunning);
|
||||
v.LightsOn = packet.Flag.HasFlag(VehicleDataFlags.AreLightsOn);
|
||||
v.BrakeLightsOn = packet.Flag.HasFlag(VehicleDataFlags.AreBrakeLightsOn);
|
||||
v.HighBeamsOn = packet.Flag.HasFlag(VehicleDataFlags.AreHighBeamsOn);
|
||||
v.SireneActive = packet.Flag.HasFlag(VehicleDataFlags.IsSirenActive);
|
||||
v.IsDead = packet.Flag.HasFlag(VehicleDataFlags.IsDead);
|
||||
v.HornActive = packet.Flag.HasFlag(VehicleDataFlags.IsHornActive);
|
||||
v.Transformed = packet.Flag.HasFlag(VehicleDataFlags.IsTransformed);
|
||||
v.Passengers=new Dictionary<VehicleSeat, SyncedPed>();
|
||||
v.LockStatus=packet.LockStatus;
|
||||
foreach (KeyValuePair<int, int> pair in packet.Passengers)
|
||||
{
|
||||
if (EntityPool.PedExists(pair.Value))
|
||||
{
|
||||
v.Passengers.Add((VehicleSeat)pair.Key, EntityPool.GetPedByID(pair.Value));
|
||||
}
|
||||
}
|
||||
v.LastStateSynced=v.LastSynced= Main.Ticked;
|
||||
|
||||
}
|
||||
private static void ProjectileSync(Packets.ProjectileSync packet)
|
||||
{
|
||||
var p = EntityPool.GetProjectileByID(packet.ID);
|
||||
if (p==null)
|
||||
{
|
||||
if (packet.Exploded) { return; }
|
||||
Main.Logger.Debug($"Creating new projectile: {(WeaponHash)packet.WeaponHash}");
|
||||
EntityPool.ThreadSafe.Add(p=new SyncedProjectile(packet.ID));
|
||||
}
|
||||
p.Position=packet.Position.ToVector();
|
||||
p.Rotation=packet.Rotation.ToVector();
|
||||
p.Velocity=packet.Velocity.ToVector();
|
||||
p.Hash=(WeaponHash)packet.WeaponHash;
|
||||
p.ShooterID=packet.ShooterID;
|
||||
p.Exploded=packet.Exploded;
|
||||
p.LastSynced=Main.Ticked;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -11,23 +11,24 @@ using GTA.Math;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
public static partial class Networking
|
||||
internal static partial class Networking
|
||||
{
|
||||
|
||||
|
||||
#region -- SEND --
|
||||
/// <summary>
|
||||
/// Pack the packet then send to server.
|
||||
/// </summary>
|
||||
/// <param name="p"></param>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="method"></param>
|
||||
public static void Send(Packet p, ConnectionChannel channel = ConnectionChannel.Default,NetDeliveryMethod method=NetDeliveryMethod.UnreliableSequenced)
|
||||
public static void Send(Packet p, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = Client.CreateMessage();
|
||||
p.Pack(outgoingMessage);
|
||||
Client.SendMessage(outgoingMessage, method, (int)channel);
|
||||
}
|
||||
|
||||
#region -- SEND --
|
||||
public static void SendPed(SyncedPed c)
|
||||
{
|
||||
Ped p = c.MainPed;
|
||||
@ -51,7 +52,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
packet.RotationVelocity=p.RotationVelocity.ToLVector();
|
||||
}
|
||||
Send(packet, ConnectionChannel.CharacterSync);
|
||||
Send(packet, ConnectionChannel.PedSync);
|
||||
}
|
||||
public static void SendPedState(SyncedPed c)
|
||||
{
|
||||
@ -66,7 +67,7 @@ namespace RageCoop.Client
|
||||
WeaponComponents=p.Weapons.Current.GetWeaponComponents(),
|
||||
};
|
||||
|
||||
Send(packet, ConnectionChannel.CharacterSync);
|
||||
Send(packet, ConnectionChannel.PedSync);
|
||||
}
|
||||
public static void SendVehicle(SyncedVehicle v)
|
||||
{
|
||||
@ -109,6 +110,23 @@ namespace RageCoop.Client
|
||||
};
|
||||
Send(packet, ConnectionChannel.VehicleSync);
|
||||
}
|
||||
public static void SendProjectile(SyncedProjectile sp)
|
||||
{
|
||||
var p = sp.MainProjectile;
|
||||
var packet = new Packets.ProjectileSync()
|
||||
{
|
||||
ID =sp.ID,
|
||||
ShooterID=sp.ShooterID,
|
||||
Position=p.Position.ToLVector(),
|
||||
Rotation=p.Rotation.ToLVector(),
|
||||
Velocity=p.Velocity.ToLVector(),
|
||||
WeaponHash=(uint)p.WeaponHash,
|
||||
Exploded=p.IsDead
|
||||
};
|
||||
if (p.IsDead) { EntityPool.RemoveProjectile(sp.ID,"Dead"); }
|
||||
Send(packet, ConnectionChannel.ProjectileSync);
|
||||
}
|
||||
|
||||
|
||||
#region SYNC EVENTS
|
||||
public static void SendBulletShot(Vector3 start,Vector3 end,uint weapon,int ownerID)
|
||||
|
@ -58,7 +58,7 @@ namespace RageCoop.Client
|
||||
_mainScaleform.CallFunction("SET_TITLE", "Player list", (Players.Count) + " players");
|
||||
_mainScaleform.CallFunction("DISPLAY_VIEW");
|
||||
}
|
||||
public static void SetPlayer(int id, string username)
|
||||
public static void SetPlayer(int id, string username,float latency=0)
|
||||
{
|
||||
|
||||
var toset = Players.Where(x => x.PedID==id);
|
||||
@ -67,10 +67,11 @@ namespace RageCoop.Client
|
||||
var p=toset.First();
|
||||
p.Username=username;
|
||||
p.PedID=id;
|
||||
p.Latency=latency;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerData p = new PlayerData { PedID=id, Username=username };
|
||||
PlayerData p = new PlayerData { PedID=id, Username=username,Latency=latency };
|
||||
Players.Add(p);
|
||||
}
|
||||
}
|
||||
|
@ -40,5 +40,11 @@ namespace RageCoop.Client
|
||||
/// </summary>
|
||||
public Keys PassengerKey { get; set; }=Keys.G;
|
||||
|
||||
/// <summary>
|
||||
/// Disable world NPC traffic, mission entities won't be affected
|
||||
/// </summary>
|
||||
public bool DisableTraffic { get; set; } = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,15 +24,7 @@ namespace RageCoop.Client
|
||||
/// <param name="p"></param>
|
||||
public SyncedPed(Ped p)
|
||||
{
|
||||
while((ID==0) || (EntityPool.GetPedByID(ID)!=null))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
|
||||
RandomNumberGenerator.Create().GetBytes(rngBytes);
|
||||
|
||||
// Convert the bytes into an integer
|
||||
ID = BitConverter.ToInt32(rngBytes,0);
|
||||
}
|
||||
ID=EntityPool.RequestNewID();
|
||||
p.CanWrithe=false;
|
||||
p.IsOnlyDamagedByPlayer=false;
|
||||
MainPed=p;
|
||||
@ -143,7 +135,8 @@ namespace RageCoop.Client
|
||||
{
|
||||
SetClothes();
|
||||
}
|
||||
|
||||
|
||||
CheckCurrentWeapon();
|
||||
}
|
||||
|
||||
|
||||
@ -500,7 +493,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
CheckCurrentWeapon();
|
||||
|
||||
if (IsReloading)
|
||||
{
|
||||
@ -576,27 +568,25 @@ namespace RageCoop.Client
|
||||
if (MainPed.Weapons.Current.Hash != (WeaponHash)CurrentWeaponHash || !WeaponComponents.Compare(_lastWeaponComponents))
|
||||
{
|
||||
MainPed.Weapons.RemoveAll();
|
||||
|
||||
_lastWeaponObj = Function.Call<int>(Hash.CREATE_WEAPON_OBJECT, CurrentWeaponHash, -1, Position.X, Position.Y, Position.Z, true, 0, 0);
|
||||
|
||||
if (CurrentWeaponHash != (uint)WeaponHash.Unarmed)
|
||||
{
|
||||
if (WeaponComponents == null || WeaponComponents.Count == 0)
|
||||
if (WeaponComponents != null && WeaponComponents.Count != 0)
|
||||
{
|
||||
MainPed.Weapons.Give((WeaponHash)CurrentWeaponHash, 0, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastWeaponObj = Function.Call<int>(Hash.CREATE_WEAPON_OBJECT, CurrentWeaponHash, -1, Position.X, Position.Y, Position.Z, true, 0, 0);
|
||||
|
||||
foreach (KeyValuePair<uint, bool> comp in WeaponComponents)
|
||||
{
|
||||
|
||||
if (comp.Value)
|
||||
{
|
||||
Function.Call(Hash.GIVE_WEAPON_COMPONENT_TO_WEAPON_OBJECT, _lastWeaponObj, comp.Key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Function.Call(Hash.GIVE_WEAPON_OBJECT_TO_PED, _lastWeaponObj, MainPed.Handle);
|
||||
}
|
||||
Function.Call(Hash.GIVE_WEAPON_OBJECT_TO_PED, _lastWeaponObj, MainPed.Handle);
|
||||
|
||||
}
|
||||
|
||||
_lastWeaponComponents = WeaponComponents;
|
||||
|
@ -7,74 +7,56 @@ using GTA;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
internal class SyncedProjectile:SyncedEntity
|
||||
internal class SyncedProjectile : SyncedEntity
|
||||
{
|
||||
public SyncedProjectile(Projectile p)
|
||||
{
|
||||
ID=EntityPool.RequestNewID();
|
||||
IsMine=true;
|
||||
MainProjectile = p;
|
||||
ShooterID=p.Owner.GetSyncEntity().ID;
|
||||
}
|
||||
public SyncedProjectile(int id)
|
||||
{
|
||||
ID= id;
|
||||
IsMine=false;
|
||||
}
|
||||
public new bool IsMine { get; private set; }
|
||||
public bool Exploded { get; set; } = false;
|
||||
public Projectile MainProjectile { get; set; }
|
||||
public int ShooterID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Invalid property for projectile.
|
||||
/// </summary>
|
||||
private new int OwnerID{ set { } }
|
||||
public WeaponHash Hash { get; set; }
|
||||
private WeaponAsset Asset { get; set; }
|
||||
private bool _creatingProjectile{ get;set; }=false;
|
||||
private ulong _projectileShotTime { get;set; }
|
||||
public override void Update()
|
||||
{
|
||||
// Check if all data avalible
|
||||
if (!IsReady) { return; }
|
||||
|
||||
// Skip update if no new sync message has arrived.
|
||||
if (!NeedUpdate)
|
||||
{ return; }
|
||||
|
||||
if (_creatingProjectile) { return; }
|
||||
if (!NeedUpdate){ return; }
|
||||
|
||||
if (MainProjectile == null || !MainProjectile.Exists())
|
||||
{
|
||||
CreateProjectile();
|
||||
return;
|
||||
}
|
||||
MainProjectile.Position=Position+Velocity*Networking.Latency;
|
||||
MainProjectile.PositionNoOffset=Position+Velocity*Networking.Latency;
|
||||
MainProjectile.Velocity=Velocity;
|
||||
MainProjectile.Rotation=Rotation;
|
||||
if (Exploded)
|
||||
{
|
||||
if (Exploded)
|
||||
{
|
||||
if(MainProjectile != null && MainProjectile.Exists())
|
||||
{
|
||||
MainProjectile.Explode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
LastUpdated=Main.Ticked;
|
||||
}
|
||||
|
||||
private void CreateProjectile()
|
||||
{
|
||||
Asset=new WeaponAsset(Hash);
|
||||
if (!Asset.IsLoaded) { Asset.Request(); }
|
||||
World.ShootBullet(Position,Position+Velocity,EntityPool.GetPedByID(ShooterID)?.MainPed,Asset,0,Velocity.Length());
|
||||
_projectileShotTime=Main.Ticked;
|
||||
_creatingProjectile=true;
|
||||
|
||||
EventHandler<ProjectileShotEventArgs> checker = null;
|
||||
checker= (sender, e) =>
|
||||
{
|
||||
if (Main.Ticked<=_projectileShotTime+1)
|
||||
{
|
||||
if (e.Projectile.WeaponHash==Hash)
|
||||
{
|
||||
MainProjectile=e.Projectile;
|
||||
_creatingProjectile=false;
|
||||
SyncEvents.OnProjectileShot-=checker;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_creatingProjectile=false;
|
||||
SyncEvents.OnProjectileShot-=checker;
|
||||
}
|
||||
};
|
||||
SyncEvents.OnProjectileShot+=checker;
|
||||
World.ShootBullet(Position,Position+Velocity,EntityPool.GetPedByID(ShooterID)?.MainPed,Asset,0);
|
||||
var ps = World.GetAllProjectiles();
|
||||
MainProjectile=ps[ps.Length-1];
|
||||
EntityPool.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,15 +22,8 @@ namespace RageCoop.Client
|
||||
/// <param name="p"></param>
|
||||
public SyncedVehicle(Vehicle v)
|
||||
{
|
||||
while ((ID==0) || EntityPool.Exists(ID))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
|
||||
RandomNumberGenerator.Create().GetBytes(rngBytes);
|
||||
|
||||
// Convert the bytes into an integer
|
||||
ID = BitConverter.ToInt32(rngBytes, 0);
|
||||
}
|
||||
ID=EntityPool.RequestNewID();
|
||||
MainVehicle=v;
|
||||
MainVehicle.CanPretendOccupants=false;
|
||||
OwnerID=Main.LocalPlayerID;
|
||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -26,6 +27,11 @@ namespace RageCoop.Client
|
||||
private static Dictionary<int, SyncedVehicle> ID_Vehicles = new Dictionary<int, SyncedVehicle>();
|
||||
private static Dictionary<int, SyncedVehicle> Handle_Vehicles = new Dictionary<int, SyncedVehicle>();
|
||||
|
||||
public static object ProjectilesLock = new object();
|
||||
private static Dictionary<int, SyncedProjectile> ID_Projectiles = new Dictionary<int, SyncedProjectile>();
|
||||
private static Dictionary<int, SyncedProjectile> Handle_Projectiles = new Dictionary<int, SyncedProjectile>();
|
||||
|
||||
|
||||
public static void Cleanup(bool keepPlayer=true,bool keepMine=true)
|
||||
{
|
||||
foreach(int id in new List<int>(ID_Peds.Keys))
|
||||
@ -44,6 +50,9 @@ namespace RageCoop.Client
|
||||
}
|
||||
ID_Vehicles.Clear();
|
||||
Handle_Vehicles.Clear();
|
||||
|
||||
ID_Projectiles.Clear();
|
||||
Handle_Projectiles.Clear();
|
||||
}
|
||||
public static SyncedPed GetPedByID(int id)
|
||||
{
|
||||
@ -193,22 +202,111 @@ namespace RageCoop.Client
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool Exists(int id)
|
||||
public static SyncedProjectile GetProjectileByID(int id)
|
||||
{
|
||||
return ID_Peds.ContainsKey(id) || ID_Vehicles.ContainsKey(id);
|
||||
return ID_Projectiles.ContainsKey(id) ? ID_Projectiles[id] : null;
|
||||
}
|
||||
public static void Add(SyncedProjectile p)
|
||||
{
|
||||
if (ID_Projectiles.ContainsKey(p.ID))
|
||||
{
|
||||
ID_Projectiles[p.ID]=p;
|
||||
}
|
||||
else
|
||||
{
|
||||
ID_Projectiles.Add(p.ID, p);
|
||||
}
|
||||
if (p.MainProjectile==null) { return; }
|
||||
if (Handle_Projectiles.ContainsKey(p.MainProjectile.Handle))
|
||||
{
|
||||
Handle_Projectiles[p.MainProjectile.Handle]=p;
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle_Projectiles.Add(p.MainProjectile.Handle, p);
|
||||
}
|
||||
}
|
||||
public static void RemoveProjectile(int id, string reason)
|
||||
{
|
||||
if (ID_Projectiles.ContainsKey(id))
|
||||
{
|
||||
SyncedProjectile sp = ID_Projectiles[id];
|
||||
var p = sp.MainProjectile;
|
||||
if (p!=null)
|
||||
{
|
||||
if (Handle_Projectiles.ContainsKey(p.Handle))
|
||||
{
|
||||
Handle_Projectiles.Remove(p.Handle);
|
||||
}
|
||||
Main.Logger.Debug($"Removing projectile {sp.ID}. Reason:{reason}");
|
||||
p.Explode();
|
||||
}
|
||||
ID_Projectiles.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool PedExists(int id)
|
||||
{
|
||||
return ID_Peds.ContainsKey(id);
|
||||
}
|
||||
public static bool VehicleExists(int id)
|
||||
{
|
||||
return ID_Vehicles.ContainsKey(id);
|
||||
}
|
||||
public static bool ProjectileExists(int id)
|
||||
{
|
||||
return ID_Projectiles.ContainsKey(id);
|
||||
}
|
||||
public static void DoSync()
|
||||
{
|
||||
PerfCounter.Restart();
|
||||
SyncEvents.CheckProjectiles();
|
||||
Debug.TimeStamps[TimeStamp.CheckProjectiles]=PerfCounter.ElapsedTicks;
|
||||
var allPeds = World.GetAllPeds();
|
||||
var allVehicles=World.GetAllVehicles();
|
||||
var allProjectiles=World.GetAllProjectiles();
|
||||
|
||||
if (Main.Ticked%100==0) { if (allVehicles.Length>50) { SetBudget(0); } else { SetBudget(1); } }
|
||||
Debug.TimeStamps[TimeStamp.GetAllEntities]=PerfCounter.ElapsedTicks;
|
||||
lock (ProjectilesLock)
|
||||
{
|
||||
|
||||
lock (EntityPool.PedsLock)
|
||||
foreach (Projectile p in allProjectiles)
|
||||
{
|
||||
if (!Handle_Projectiles.ContainsKey(p.Handle))
|
||||
{
|
||||
Add(new SyncedProjectile(p));
|
||||
Main.Logger.Debug($"Projectile shot: {p.Handle}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SyncedProjectile p in ID_Projectiles.Values.ToArray())
|
||||
{
|
||||
|
||||
// Outgoing sync
|
||||
if (p.IsMine)
|
||||
{
|
||||
if (p.MainProjectile.AttachedEntity==null)
|
||||
{
|
||||
Networking.SendProjectile(p);
|
||||
}
|
||||
}
|
||||
else // Incoming sync
|
||||
{
|
||||
if (p.Exploded || p.IsOutOfSync)
|
||||
{
|
||||
RemoveProjectile(p.ID, "OutOfSync | Exploded");
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
lock (PedsLock)
|
||||
{
|
||||
EntityPool.AddPlayer();
|
||||
|
||||
@ -255,16 +353,10 @@ namespace RageCoop.Client
|
||||
}
|
||||
else // Incoming sync
|
||||
{
|
||||
|
||||
|
||||
c.Update();
|
||||
if (c.IsOutOfSync)
|
||||
{
|
||||
try
|
||||
{
|
||||
EntityPool.RemovePed(c.ID,"OutOfSync");
|
||||
}
|
||||
catch { }
|
||||
RemovePed(c.ID, "OutOfSync");
|
||||
}
|
||||
|
||||
}
|
||||
@ -272,13 +364,12 @@ namespace RageCoop.Client
|
||||
Debug.TimeStamps[TimeStamp.PedTotal]=PerfCounter.ElapsedTicks;
|
||||
|
||||
}
|
||||
lock (EntityPool.VehiclesLock)
|
||||
lock (VehiclesLock)
|
||||
{
|
||||
|
||||
foreach (Vehicle veh in allVehicles)
|
||||
{
|
||||
SyncedVehicle v = EntityPool.GetVehicleByHandle(veh.Handle);
|
||||
if (v==null)
|
||||
if (!Handle_Vehicles.ContainsKey(veh.Handle))
|
||||
{
|
||||
Main.Logger.Debug($"Creating SyncEntity for vehicle, handle:{veh.Handle}");
|
||||
|
||||
@ -318,11 +409,7 @@ namespace RageCoop.Client
|
||||
v.Update();
|
||||
if (v.IsOutOfSync)
|
||||
{
|
||||
try
|
||||
{
|
||||
EntityPool.RemoveVehicle(v.ID, "OutOfSync");
|
||||
}
|
||||
catch { }
|
||||
RemoveVehicle(v.ID, "OutOfSync");
|
||||
}
|
||||
|
||||
}
|
||||
@ -335,6 +422,8 @@ namespace RageCoop.Client
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void RemoveAllFromPlayer(int playerPedId)
|
||||
{
|
||||
foreach(SyncedPed p in ID_Peds.Values.ToArray())
|
||||
@ -352,6 +441,24 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int RequestNewID()
|
||||
{
|
||||
int ID=0;
|
||||
while ((ID==0)
|
||||
|| ID_Peds.ContainsKey(ID)
|
||||
|| ID_Vehicles.ContainsKey(ID)
|
||||
|| ID_Projectiles.ContainsKey(ID))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
|
||||
RandomNumberGenerator.Create().GetBytes(rngBytes);
|
||||
|
||||
// Convert the bytes into an integer
|
||||
ID = BitConverter.ToInt32(rngBytes, 0);
|
||||
}
|
||||
return ID;
|
||||
}
|
||||
private static void SetBudget(int b)
|
||||
{
|
||||
Function.Call(Hash.SET_PED_POPULATION_BUDGET, b); // 0 - 3
|
||||
@ -366,5 +473,29 @@ namespace RageCoop.Client
|
||||
s+="\nHandle_Vehicles: "+Handle_Vehicles.Count;
|
||||
return s;
|
||||
}
|
||||
public static class ThreadSafe
|
||||
{
|
||||
public static void Add(SyncedVehicle v)
|
||||
{
|
||||
lock (EntityPool.VehiclesLock)
|
||||
{
|
||||
EntityPool.Add(v);
|
||||
}
|
||||
}
|
||||
public static void Add(SyncedPed p)
|
||||
{
|
||||
lock (EntityPool.PedsLock)
|
||||
{
|
||||
EntityPool.Add(p);
|
||||
}
|
||||
}
|
||||
public static void Add(SyncedProjectile sp)
|
||||
{
|
||||
lock (EntityPool.ProjectilesLock)
|
||||
{
|
||||
EntityPool.Add(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,5 +10,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
public bool IsMine { get; set; }
|
||||
public Projectile Projectile { get; set; }
|
||||
|
||||
public SyncedPed Owner { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -12,17 +12,7 @@ using System.Threading;
|
||||
namespace RageCoop.Client {
|
||||
internal static class SyncEvents
|
||||
{
|
||||
public static event EventHandler<ProjectileShotEventArgs> OnProjectileShot;
|
||||
|
||||
static SyncEvents() {
|
||||
OnProjectileShot+=(s, e) =>
|
||||
{
|
||||
if (e.IsMine)
|
||||
{
|
||||
TriggerProjectileShot(e.Projectile);
|
||||
}
|
||||
};
|
||||
}
|
||||
#region TRIGGER
|
||||
public static void TriggerPedKilled(SyncedPed victim)
|
||||
{
|
||||
@ -69,6 +59,8 @@ namespace RageCoop.Client {
|
||||
|
||||
public static void TriggerBulletShot(uint hash,SyncedPed owner,Vector3 impactPosition)
|
||||
{
|
||||
Main.Logger.Trace($"bullet shot:{(WeaponHash)hash}");
|
||||
|
||||
// Minigun, not working for some reason
|
||||
if (hash==(uint)WeaponHash.Minigun)
|
||||
{
|
||||
@ -100,17 +92,6 @@ namespace RageCoop.Client {
|
||||
|
||||
}
|
||||
|
||||
public static void TriggerProjectileShot(Projectile p)
|
||||
{
|
||||
var pp = p.Owner;
|
||||
if (pp.IsShooting)
|
||||
{
|
||||
|
||||
var start = p.Position;
|
||||
var end = start+p.Velocity;
|
||||
Networking.SendBulletShot(start, end, (uint)p.WeaponHash, pp.GetSyncEntity().ID);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region HANDLE
|
||||
@ -135,8 +116,16 @@ namespace RageCoop.Client {
|
||||
public static void HandleEnteredVehicle(int pedId, int vehId, VehicleSeat seat)
|
||||
{
|
||||
var v = EntityPool.GetVehicleByID(vehId);
|
||||
if (v==null) { return; }
|
||||
EntityPool.GetPedByID(pedId)?.MainPed?.SetIntoVehicle(v.MainVehicle, seat);
|
||||
var p = EntityPool.GetPedByID(pedId)?.MainPed;
|
||||
if (v==null||p==null) { return; }
|
||||
if (!v.MainVehicle.IsSeatFree(seat))
|
||||
{
|
||||
if (v.MainVehicle.GetPedOnSeat(seat)!=p)
|
||||
{
|
||||
v.MainVehicle.GetPedOnSeat(seat).Task.WarpOutOfVehicle(v.MainVehicle);
|
||||
}
|
||||
}
|
||||
p.SetIntoVehicle(v.MainVehicle, seat);
|
||||
}
|
||||
public static void HandleOwnerChanged(Packets.OwnerChanged p)
|
||||
{
|
||||
@ -269,46 +258,11 @@ namespace RageCoop.Client {
|
||||
*/
|
||||
#region CHECK EVENTS
|
||||
|
||||
static bool _projectileShot = false;
|
||||
static Projectile[] lastProjectiles=new Projectile[0];
|
||||
public static void CheckProjectiles()
|
||||
{
|
||||
Projectile[] projectiles = World.GetAllProjectiles();
|
||||
|
||||
_projectileShot=false;
|
||||
foreach (Projectile p in projectiles)
|
||||
{
|
||||
var owner = p.Owner?.GetSyncEntity();
|
||||
if (!lastProjectiles.Contains(p))
|
||||
{
|
||||
if((owner!=null) && owner.IsMine)
|
||||
{
|
||||
_projectileShot=true;
|
||||
OnProjectileShot?.Invoke(null, new ProjectileShotEventArgs()
|
||||
{
|
||||
Projectile=p,
|
||||
IsMine=true
|
||||
}) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnProjectileShot?.Invoke(null, new ProjectileShotEventArgs()
|
||||
{
|
||||
Projectile=p,
|
||||
IsMine=false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lastProjectiles=projectiles;
|
||||
}
|
||||
|
||||
public static void Check(SyncedPed c)
|
||||
{
|
||||
Ped subject = c.MainPed;
|
||||
if (subject.IsShooting && !_projectileShot)
|
||||
if (subject.IsShooting && !subject.IsUsingProjectileWeapon())
|
||||
{
|
||||
int i = 0;
|
||||
Func<bool> getBulletImpact = (() =>
|
||||
|
@ -42,8 +42,8 @@ namespace RageCoop.Client
|
||||
Function.Call(Hash.SET_DEEP_OCEAN_SCALER, 0.0f); // Works only ~200 meters around the player
|
||||
|
||||
Function.Call(Hash.SET_CAN_ATTACK_FRIENDLY, Game.Player.Character.Handle, true, false);
|
||||
|
||||
if (Main.DisableTraffic)
|
||||
if (Main.Settings==null) { return; }
|
||||
if (Main.Settings.DisableTraffic)
|
||||
{
|
||||
if (!_lastDisableTraffic)
|
||||
{
|
||||
@ -63,7 +63,7 @@ namespace RageCoop.Client
|
||||
Traffic(true);
|
||||
}
|
||||
|
||||
_lastDisableTraffic = Main.DisableTraffic;
|
||||
_lastDisableTraffic = Main.Settings.DisableTraffic;
|
||||
}
|
||||
|
||||
private void Traffic(bool enable)
|
||||
|
@ -117,6 +117,7 @@ namespace RageCoop.Core
|
||||
Handshake=0,
|
||||
PlayerConnect=1,
|
||||
PlayerDisconnect=2,
|
||||
PlayerInfoUpdate=3,
|
||||
|
||||
ChatMessage=10,
|
||||
NativeCall=11,
|
||||
@ -133,8 +134,8 @@ namespace RageCoop.Core
|
||||
#region INTERVAL
|
||||
VehicleSync = 20,
|
||||
VehicleStateSync = 21,
|
||||
CharacterSync = 22,
|
||||
CharacterStateSync = 23,
|
||||
PedSync = 22,
|
||||
PedStateSync = 23,
|
||||
ProjectileSync=24,
|
||||
#endregion
|
||||
|
||||
@ -169,15 +170,9 @@ namespace RageCoop.Core
|
||||
File = 8,
|
||||
Event = 9,
|
||||
VehicleSync=20,
|
||||
CharacterSync=21,
|
||||
SyncEvents=30,
|
||||
///obsolete
|
||||
/*
|
||||
PlayerLight = 1,
|
||||
PlayerFull = 2,
|
||||
PlayerSuperLight = 3,
|
||||
NPCFull = 4,
|
||||
*/
|
||||
PedSync=21,
|
||||
ProjectileSync = 22,
|
||||
SyncEvents =30,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
@ -30,7 +30,7 @@ namespace RageCoop.Core
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketTypes.CharacterStateSync);
|
||||
message.Write((byte)PacketTypes.PedStateSync);
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
@ -145,7 +145,7 @@ namespace RageCoop.Core
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketTypes.CharacterSync);
|
||||
message.Write((byte)PacketTypes.PedSync);
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
@ -147,17 +147,18 @@ namespace RageCoop.Core
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerPedID : Packet
|
||||
public class PlayerInfoUpdate : Packet
|
||||
{
|
||||
/// <summary>
|
||||
/// Ped ID for this Player
|
||||
/// </summary>
|
||||
public int PedID { get; set; }
|
||||
public string Username { get; set; }
|
||||
public float Latency { get; set; }
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketTypes.PlayerConnect);
|
||||
message.Write((byte)PacketTypes.PlayerInfoUpdate);
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
@ -167,12 +168,16 @@ namespace RageCoop.Core
|
||||
// Get Username bytes
|
||||
byte[] usernameBytes = Encoding.UTF8.GetBytes(Username);
|
||||
|
||||
|
||||
// Write UsernameLength
|
||||
byteArray.AddRange(BitConverter.GetBytes(usernameBytes.Length));
|
||||
|
||||
// Write Username
|
||||
byteArray.AddRange(usernameBytes);
|
||||
|
||||
// Write Latency
|
||||
byteArray.AddFloat(Latency);
|
||||
|
||||
byte[] result = byteArray.ToArray();
|
||||
|
||||
message.Write(result.Length);
|
||||
@ -190,6 +195,8 @@ namespace RageCoop.Core
|
||||
// Read Username
|
||||
int usernameLength = reader.ReadInt();
|
||||
Username = reader.ReadString(usernameLength);
|
||||
|
||||
Latency=reader.ReadFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,63 +5,89 @@ using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal class ProjectileSync:Packet
|
||||
public partial class Packets
|
||||
{
|
||||
|
||||
public int ID { get; set; }
|
||||
|
||||
public LVector3 Position { get; set; }
|
||||
|
||||
public LVector3 Rotation { get; set; }
|
||||
|
||||
public LVector3 Velocity { get; set; }
|
||||
|
||||
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
public class ProjectileSync : Packet
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketTypes.ProjectileSync);
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
public int ID { get; set; }
|
||||
|
||||
// Write vehicle id
|
||||
byteArray.AddInt(ID);
|
||||
public int ShooterID { get; set; }
|
||||
public uint WeaponHash { get; set; }
|
||||
|
||||
// Write position
|
||||
byteArray.AddLVector3(Position);
|
||||
public LVector3 Position { get; set; }
|
||||
|
||||
public LVector3 Rotation { get; set; }
|
||||
|
||||
public LVector3 Velocity { get; set; }
|
||||
|
||||
public bool Exploded { get; set; }
|
||||
|
||||
|
||||
// Write rotation
|
||||
byteArray.AddLVector3(Rotation);
|
||||
|
||||
// Write velocity
|
||||
byteArray.AddLVector3(Velocity);
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketTypes.ProjectileSync);
|
||||
|
||||
byte[] result = byteArray.ToArray();
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
message.Write(result.Length);
|
||||
message.Write(result);
|
||||
#endregion
|
||||
}
|
||||
// Write id
|
||||
byteArray.AddInt(ID);
|
||||
|
||||
public override void Unpack(byte[] array)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
// Write ShooterID
|
||||
byteArray.AddInt(ShooterID);
|
||||
|
||||
// Read id
|
||||
ID = reader.ReadInt();
|
||||
byteArray.AddUint(WeaponHash);
|
||||
|
||||
// Read position
|
||||
Position = reader.ReadLVector3();
|
||||
// Write position
|
||||
byteArray.AddLVector3(Position);
|
||||
|
||||
// Read rotation
|
||||
Rotation = reader.ReadLVector3();
|
||||
|
||||
// Read velocity
|
||||
Velocity =reader.ReadLVector3();
|
||||
// Write rotation
|
||||
byteArray.AddLVector3(Rotation);
|
||||
|
||||
#endregion
|
||||
// Write velocity
|
||||
byteArray.AddLVector3(Velocity);
|
||||
|
||||
if (Exploded) { byteArray.Add(1); }
|
||||
|
||||
byte[] result = byteArray.ToArray();
|
||||
|
||||
message.Write(result.Length);
|
||||
message.Write(result);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void Unpack(byte[] array)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
// Read id
|
||||
ID = reader.ReadInt();
|
||||
|
||||
// Read ShooterID
|
||||
ShooterID= reader.ReadInt();
|
||||
|
||||
WeaponHash= reader.ReadUInt();
|
||||
|
||||
// Read position
|
||||
Position = reader.ReadLVector3();
|
||||
|
||||
// Read rotation
|
||||
Rotation = reader.ReadLVector3();
|
||||
|
||||
// Read velocity
|
||||
Velocity =reader.ReadLVector3();
|
||||
|
||||
if (reader.CanRead(1))
|
||||
{
|
||||
Exploded=true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,11 @@ namespace RageCoop.Core
|
||||
public int VehicleID { get; set; }
|
||||
public bool IsInVehicle { get; internal set; }
|
||||
public LVector3 Position { get; set; }
|
||||
public int Latency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Player Latency in second.
|
||||
/// </summary>
|
||||
public float Latency { get; set; }
|
||||
public int Health { get; set; }
|
||||
|
||||
public bool IsInRangeOf(LVector3 position, float distance)
|
||||
|
@ -6,13 +6,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<PropertyGroup>
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>bin\Release\net6.0\publish\win-x64\</PublishDir>
|
||||
<PublishDir>bin\Release\net6.0\publish\linux-x64\</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>True</PublishSingleFile>
|
||||
<PublishReadyToRun>True</PublishReadyToRun>
|
||||
<PublishTrimmed>True</PublishTrimmed>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -4,6 +4,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<History>True|2022-05-22T08:56:31.0481188Z;True|2022-05-18T13:35:57.1402751+08:00;True|2022-05-18T13:10:28.4995253+08:00;True|2022-05-01T18:35:01.9624101+08:00;True|2022-05-01T12:32:20.8671319+08:00;False|2022-05-01T12:30:25.4596227+08:00;</History>
|
||||
<History>True|2022-05-24T03:00:13.3617113Z;True|2022-05-22T16:56:31.0481188+08:00;True|2022-05-18T13:35:57.1402751+08:00;True|2022-05-18T13:10:28.4995253+08:00;True|2022-05-01T18:35:01.9624101+08:00;True|2022-05-01T12:32:20.8671319+08:00;False|2022-05-01T12:30:25.4596227+08:00;</History>
|
||||
</PropertyGroup>
|
||||
</Project>
|
221
Server/Server.cs
221
Server/Server.cs
@ -34,6 +34,7 @@ namespace RageCoop.Server
|
||||
public static Resource RunningResource = null;
|
||||
public static readonly Dictionary<Command, Action<CommandContext>> Commands = new();
|
||||
public static readonly Dictionary<TriggerEvent, Action<EventContext>> TriggerEvents = new();
|
||||
private static Thread BackgroundThread;
|
||||
|
||||
public static readonly List<Client> Clients = new();
|
||||
|
||||
@ -210,6 +211,8 @@ namespace RageCoop.Server
|
||||
DownloadManager.CheckForDirectoryAndFiles();
|
||||
|
||||
Listen();
|
||||
|
||||
BackgroundThread=new Thread(() => Background());
|
||||
}
|
||||
|
||||
private void Listen()
|
||||
@ -304,7 +307,7 @@ namespace RageCoop.Server
|
||||
|
||||
#region SyncData
|
||||
|
||||
case PacketTypes.CharacterStateSync:
|
||||
case PacketTypes.PedStateSync:
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -340,7 +343,7 @@ namespace RageCoop.Server
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PacketTypes.CharacterSync:
|
||||
case PacketTypes.PedSync:
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -376,6 +379,23 @@ namespace RageCoop.Server
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PacketTypes.ProjectileSync:
|
||||
{
|
||||
try
|
||||
{
|
||||
int len = message.ReadInt32();
|
||||
byte[] data = message.ReadBytes(len);
|
||||
|
||||
Packets.ProjectileSync packet = new();
|
||||
packet.Unpack(data);
|
||||
ProjectileSync(packet, message.SenderConnection.RemoteUniqueIdentifier);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DisconnectAndLog(message.SenderConnection, type, e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#endregion
|
||||
@ -563,7 +583,7 @@ namespace RageCoop.Server
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != message.SenderConnection.RemoteUniqueIdentifier).ForEach(x =>
|
||||
{
|
||||
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.CharacterSync);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||
|
||||
});
|
||||
}
|
||||
@ -629,6 +649,29 @@ namespace RageCoop.Server
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
private void Background()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
foreach(Client c in Clients)
|
||||
{
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != c.ClientID).ForEach(x =>
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new Packets.PlayerInfoUpdate()
|
||||
{
|
||||
PedID=c.Player.PedID,
|
||||
Username=c.Player.Username,
|
||||
Latency=c.Player.Latency=c.Latency,
|
||||
}.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default);
|
||||
});
|
||||
}
|
||||
|
||||
// Update Latency every 20 seconds.
|
||||
Thread.Sleep(1000*20);
|
||||
}
|
||||
}
|
||||
|
||||
private void DisconnectAndLog(NetConnection senderConnection,PacketTypes type, Exception e)
|
||||
{
|
||||
@ -830,7 +873,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.CharacterSync);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||
|
||||
});
|
||||
|
||||
@ -839,7 +882,6 @@ namespace RageCoop.Server
|
||||
RunningResource.InvokePlayerUpdate(client);
|
||||
}
|
||||
}
|
||||
|
||||
private static void VehicleStateSync(Packets.VehicleStateSync packet, long ClientID)
|
||||
{
|
||||
Client client = Util.GetClientByID(ClientID);
|
||||
@ -862,7 +904,6 @@ namespace RageCoop.Server
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static void CharacterSync(Packets.PedSync packet, long ClientID)
|
||||
{
|
||||
Client client = Util.GetClientByID(ClientID);
|
||||
@ -877,7 +918,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.CharacterSync);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||
|
||||
});
|
||||
|
||||
@ -886,7 +927,6 @@ namespace RageCoop.Server
|
||||
RunningResource.InvokePlayerUpdate(client);
|
||||
}
|
||||
}
|
||||
|
||||
private static void VehicleSync(Packets.VehicleSync packet, long ClientID)
|
||||
{
|
||||
Client client = Util.GetClientByID(ClientID);
|
||||
@ -932,177 +972,22 @@ namespace RageCoop.Server
|
||||
}
|
||||
*/
|
||||
}
|
||||
#region Obsolete
|
||||
/*
|
||||
private static void FullSyncPlayer(Packets.FullSyncPlayer packet)
|
||||
private static void ProjectileSync(Packets.ProjectileSync packet, long ClientID)
|
||||
{
|
||||
Client client = Util.GetClientByNetHandle(packet.NetHandle);
|
||||
Client client = Util.GetClientByID(ClientID);
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Save the new data
|
||||
client.Player.PedHandle = packet.PedHandle;
|
||||
client.Player.IsInVehicle = false;
|
||||
client.Player.Position = packet.Position;
|
||||
client.Player.Health = packet.Health;
|
||||
|
||||
// Override the latency
|
||||
packet.Latency = client.Latency;
|
||||
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != packet.NetHandle).ForEach(x =>
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != ClientID).ForEach(x =>
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
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 Packets.SuperLightSync()
|
||||
{
|
||||
NetHandle = packet.NetHandle,
|
||||
Position = packet.Position,
|
||||
Latency = packet.Latency
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
|
||||
}
|
||||
packet.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.ProjectileSync);
|
||||
});
|
||||
|
||||
if (RunningResource != null)
|
||||
{
|
||||
RunningResource.InvokePlayerUpdate(client);
|
||||
}
|
||||
}
|
||||
|
||||
private static void FullSyncPlayerVeh(Packets.FullSyncPlayerVeh packet)
|
||||
{
|
||||
Client client = Util.GetClientByNetHandle(packet.NetHandle);
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Save the new data
|
||||
client.Player.PedHandle = packet.PedHandle;
|
||||
client.Player.VehicleHandle = packet.VehicleHandle;
|
||||
client.Player.IsInVehicle = true;
|
||||
client.Player.Position = packet.Position;
|
||||
client.Player.Health = packet.Health;
|
||||
|
||||
// Override the latency
|
||||
packet.Latency = client.Latency;
|
||||
|
||||
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.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerFull);
|
||||
}
|
||||
else
|
||||
{
|
||||
new Packets.SuperLightSync()
|
||||
{
|
||||
NetHandle = packet.NetHandle,
|
||||
Position = packet.Position,
|
||||
Latency = packet.Latency
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
|
||||
}
|
||||
});
|
||||
|
||||
if (RunningResource != null)
|
||||
{
|
||||
RunningResource.InvokePlayerUpdate(client);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LightSyncPlayer(Packets.LightSyncPlayer packet)
|
||||
{
|
||||
Client client = Util.GetClientByNetHandle(packet.NetHandle);
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Save the new data
|
||||
client.Player.Position = packet.Position;
|
||||
client.Player.Health = packet.Health;
|
||||
|
||||
// Override the latency
|
||||
packet.Latency = client.Latency;
|
||||
|
||||
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.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerLight);
|
||||
}
|
||||
else
|
||||
{
|
||||
new Packets.SuperLightSync()
|
||||
{
|
||||
NetHandle = packet.NetHandle,
|
||||
Position = packet.Position,
|
||||
Latency = packet.Latency
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
|
||||
}
|
||||
});
|
||||
|
||||
if (RunningResource != null)
|
||||
{
|
||||
RunningResource.InvokePlayerUpdate(client);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LightSyncPlayerVeh(Packets.LightSyncPlayerVeh packet)
|
||||
{
|
||||
Client client = Util.GetClientByNetHandle(packet.NetHandle);
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Save the new data
|
||||
client.Player.Position = packet.Position;
|
||||
client.Player.Health = packet.Health;
|
||||
|
||||
// Override the latency
|
||||
packet.Latency = client.Latency;
|
||||
|
||||
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.Position, 550f))
|
||||
{
|
||||
packet.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerLight);
|
||||
}
|
||||
else
|
||||
{
|
||||
new Packets.SuperLightSync()
|
||||
{
|
||||
NetHandle = packet.NetHandle,
|
||||
Position = packet.Position,
|
||||
Latency = packet.Latency
|
||||
}.PacketToNetOutGoingMessage(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PlayerSuperLight);
|
||||
}
|
||||
});
|
||||
|
||||
if (RunningResource != null)
|
||||
{
|
||||
RunningResource.InvokePlayerUpdate(client);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
#endregion
|
||||
// Send a message to targets or all players
|
||||
private static void SendChatMessage(Packets.ChatMessage packet, List<NetConnection> targets = null)
|
||||
|
Reference in New Issue
Block a user