Cleanup and rewrite some bullshit

This commit is contained in:
Sardelka9515
2023-02-13 20:44:50 +08:00
parent f555fef48d
commit e4f432b593
35 changed files with 255 additions and 219 deletions

View File

@ -0,0 +1,13 @@
using RageCoop.Core.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RageCoop.Client.Scripting
{
public class ClientFile : ResourceFile
{
}
}

View File

@ -1,4 +1,6 @@
using RageCoop.Core.Scripting; using Newtonsoft.Json;
using RageCoop.Core.Scripting;
using SHVDN;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -27,11 +29,6 @@ namespace RageCoop.Client.Scripting
/// </summary> /// </summary>
public string DataFolder { get; internal set; } public string DataFolder { get; internal set; }
/// <summary>
/// Get all <see cref="ClientScript" /> instance in this resource.
/// </summary>
public List<ClientScript> Scripts { get; internal set; } = new List<ClientScript>();
/// <summary> /// <summary>
/// Get the <see cref="ResourceFile" /> where this script is loaded from. /// Get the <see cref="ResourceFile" /> where this script is loaded from.
/// </summary> /// </summary>
@ -40,21 +37,16 @@ namespace RageCoop.Client.Scripting
/// <summary> /// <summary>
/// A <see cref="Core.Logger" /> instance that can be used to debug your resource. /// A <see cref="Core.Logger" /> instance that can be used to debug your resource.
/// </summary> /// </summary>
public Core.Logger Logger { get; internal set; } [JsonIgnore]
// TODO: call the api and use logging sinks
public Core.Logger Logger => throw new NotImplementedException();
/// <summary>
/// Get all <see cref="ClientScript" /> instance in this resource.
/// </summary>
[JsonIgnore]
public List<ClientScript> Scripts { get; } = SHVDN.Core.ListScripts().OfType<ClientScript>().ToList();
} }
public class PlayerInfo
{
public byte HolePunchStatus { get; internal set; }
public bool IsHost { get; internal set; }
public string Username { get; internal set; }
public int ID { get; internal set; }
public int EntityHandle { get; internal set; }
public IPEndPoint InternalEndPoint { get; internal set; }
public IPEndPoint ExternalEndPoint { get; internal set; }
public float Ping { get; internal set; }
public float PacketTravelTime { get; internal set; }
public bool DisplayNameTag { get; internal set; }
public bool HasDirectConnection { get; internal set; }
}
} }

View File

@ -1,9 +1,24 @@
using GTA; using GTA;
using RageCoop.Core.Scripting;
namespace RageCoop.Client.Scripting namespace RageCoop.Client.Scripting
{ {
[ScriptAttributes(NoDefaultInstance = true)] [ScriptAttributes(NoDefaultInstance = true)]
public class ClientScript : Script public abstract class ClientScript : Script
{ {
/// <summary>
/// Get the <see cref="ResourceFile" /> instance where this script is loaded from.
/// </summary>
public ClientFile CurrentFile { get; internal set; }
/// <summary>
/// Get the <see cref="ClientResource" /> that this script belongs to.
/// </summary>
public ClientResource CurrentResource { get; internal set; }
/// <summary>
/// Eqivalent of <see cref="ClientResource.Logger" /> in <see cref="Script.CurrentResource" />
/// </summary>
public Core.Logger Logger => CurrentResource.Logger;
} }
} }

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace RageCoop.Client.Scripting
{
public class PlayerInfo
{
public byte HolePunchStatus { get; internal set; }
public bool IsHost { get; internal set; }
public string Username { get; internal set; }
public int ID { get; internal set; }
public int EntityHandle { get; internal set; }
public IPEndPoint InternalEndPoint { get; internal set; }
public IPEndPoint ExternalEndPoint { get; internal set; }
public float Ping { get; internal set; }
public float PacketTravelTime { get; internal set; }
public bool DisplayNameTag { get; internal set; }
public bool HasDirectConnection { get; internal set; }
}
}

View File

@ -5,7 +5,7 @@ namespace RageCoop.Client
/// <summary> /// <summary>
/// Don't use it! /// Don't use it!
/// </summary> /// </summary>
public class Settings public class ClientSettings
{ {
/// <summary> /// <summary>
/// LogLevel for RageCoop. /// LogLevel for RageCoop.

View File

@ -22,15 +22,15 @@ namespace RageCoop.Client
[ScriptAttributes(Author = "RageCoop", SupportURL = "https://github.com/RAGECOOP/RAGECOOP-V", NoScriptThread = true)] [ScriptAttributes(Author = "RageCoop", SupportURL = "https://github.com/RAGECOOP/RAGECOOP-V", NoScriptThread = true)]
internal class Main : Script internal class Main : Script
{ {
internal static Version Version = typeof(Main).Assembly.GetName().Version; internal static Version ModVersion = typeof(Main).Assembly.GetName().Version;
internal static int LocalPlayerID = 0; internal static int LocalPlayerID = 0;
internal static RelationshipGroup SyncedPedsGroup; internal static RelationshipGroup SyncedPedsGroup;
internal static Settings Settings = null; internal static ClientSettings Settings = null;
internal static Chat MainChat = null; internal static Chat MainChat = null;
internal static Stopwatch Counter = new Stopwatch(); internal static Stopwatch Counter = new();
internal static Logger Log = null; internal static Logger Log = null;
internal static ulong Ticked = 0; internal static ulong Ticked = 0;
internal static Vector3 PlayerPosition; internal static Vector3 PlayerPosition;
@ -55,7 +55,7 @@ namespace RageCoop.Client
catch catch
{ {
Notification.Show("Malformed configuration, overwriting with default values..."); Notification.Show("Malformed configuration, overwriting with default values...");
Settings = new Settings(); Settings = new();
Util.SaveSettings(); Util.SaveSettings();
} }
@ -102,9 +102,8 @@ namespace RageCoop.Client
WorldThread.DoQueuedActions(); WorldThread.DoQueuedActions();
if (IsUnloading) if (IsUnloading)
{ {
Log.Dispose();
Networking.Peer?.Dispose();
ThreadManager.OnUnload(); ThreadManager.OnUnload();
Log.Dispose();
} }
} }
catch (Exception ex) catch (Exception ex)
@ -238,18 +237,6 @@ namespace RageCoop.Client
return; return;
} }
if (e.KeyCode == Keys.U)
{
foreach (var prop in typeof(APIBridge).GetProperties(BindingFlags.Public | BindingFlags.Static))
{
Console.PrintInfo($"{prop.Name}: {JsonSerialize(prop.GetValue(null))}");
}
foreach (var prop in typeof(APIBridge.Config).GetProperties(BindingFlags.Public | BindingFlags.Static))
{
Console.PrintInfo($"{prop.Name}: {JsonSerialize(prop.GetValue(null))}");
}
}
if (e.KeyCode == Keys.I) if (e.KeyCode == Keys.I)
{ {
@ -390,16 +377,18 @@ namespace RageCoop.Client
Log.Info(">> Connected <<"); Log.Info(">> Connected <<");
} }
private static readonly object _cleanupLock = new();
public static void CleanUp(string reason) public static void CleanUp(string reason)
{ {
if (reason != "Abort") lock (_cleanupLock)
{ {
Log.Info($">> Disconnected << reason: {reason}");
API.QueueAction(() => { Notification.Show("~r~Disconnected: " + reason); });
}
API.QueueAction(() => if (reason != "Abort")
{ {
Log.Info($">> Disconnected << reason: {reason}");
Notification.Show("~r~Disconnected: " + reason);
}
if (MainChat.Focused) if (MainChat.Focused)
{ {
MainChat.Focused = false; MainChat.Focused = false;
@ -413,8 +402,7 @@ namespace RageCoop.Client
CoopMenu.DisconnectedMenuSetting(); CoopMenu.DisconnectedMenuSetting();
LocalPlayerID = default; LocalPlayerID = default;
MainRes.Unload(); MainRes.Unload();
}); Memory.RestorePatches();
Memory.RestorePatches();
#if CEF #if CEF
if (CefRunning) if (CefRunning)
{ {
@ -422,8 +410,11 @@ namespace RageCoop.Client
} }
#endif #endif
DownloadManager.Cleanup(); DownloadManager.Cleanup();
Voice.ClearAll(); Voice.ClearAll();
Networking.Peer?.Dispose();
Networking.Peer = null;
}
} }
} }

View File

@ -20,7 +20,7 @@ namespace RageCoop.Client.Menus
public static NativeMenu Menu = new NativeMenu("RAGECOOP", "MAIN") public static NativeMenu Menu = new NativeMenu("RAGECOOP", "MAIN")
{ {
UseMouse = false, UseMouse = false,
Alignment = Main.Settings.FlipMenu ? Alignment.Right : Alignment.Left Alignment = Settings.FlipMenu ? Alignment.Right : Alignment.Left
}; };
public static PopUp PopUp = new PopUp public static PopUp PopUp = new PopUp
@ -46,7 +46,7 @@ namespace RageCoop.Client.Menus
ServerIpItem.Activated += ServerIpActivated; ServerIpItem.Activated += ServerIpActivated;
_serverConnectItem.Activated += (sender, item) => _serverConnectItem.Activated += (sender, item) =>
{ {
Networking.ToggleConnection(Main.Settings.LastServerAddress); Networking.ToggleConnection(Settings.LastServerAddress);
}; };
@ -122,7 +122,7 @@ namespace RageCoop.Client.Menus
var newUsername = Game.GetUserInput(WindowTitle.EnterMessage20, _usernameItem.AltTitle, 20); var newUsername = Game.GetUserInput(WindowTitle.EnterMessage20, _usernameItem.AltTitle, 20);
if (!string.IsNullOrWhiteSpace(newUsername)) if (!string.IsNullOrWhiteSpace(newUsername))
{ {
Main.Settings.Username = newUsername; Settings.Username = newUsername;
Util.SaveSettings(); Util.SaveSettings();
_usernameItem.AltTitle = newUsername; _usernameItem.AltTitle = newUsername;
@ -132,7 +132,7 @@ namespace RageCoop.Client.Menus
private static void _passwordActivated(object sender, EventArgs e) private static void _passwordActivated(object sender, EventArgs e)
{ {
var newPass = Game.GetUserInput(WindowTitle.EnterMessage20, "", 20); var newPass = Game.GetUserInput(WindowTitle.EnterMessage20, "", 20);
Main.Settings.Password = newPass; Settings.Password = newPass;
Util.SaveSettings(); Util.SaveSettings();
_passwordItem.AltTitle = new string('*', newPass.Length); _passwordItem.AltTitle = new string('*', newPass.Length);
} }
@ -142,7 +142,7 @@ namespace RageCoop.Client.Menus
var newServerIp = Game.GetUserInput(WindowTitle.EnterMessage60, ServerIpItem.AltTitle, 60); var newServerIp = Game.GetUserInput(WindowTitle.EnterMessage60, ServerIpItem.AltTitle, 60);
if (!string.IsNullOrWhiteSpace(newServerIp) && newServerIp.Contains(":")) if (!string.IsNullOrWhiteSpace(newServerIp) && newServerIp.Contains(":"))
{ {
Main.Settings.LastServerAddress = newServerIp; Settings.LastServerAddress = newServerIp;
Util.SaveSettings(); Util.SaveSettings();
ServerIpItem.AltTitle = newServerIp; ServerIpItem.AltTitle = newServerIp;
@ -174,20 +174,20 @@ namespace RageCoop.Client.Menus
#region ITEMS #region ITEMS
private static readonly NativeItem _usernameItem = new NativeItem("Username") private static readonly NativeItem _usernameItem = new NativeItem("Username")
{ AltTitle = Main.Settings.Username }; { AltTitle = Settings.Username };
private static readonly NativeItem _passwordItem = new NativeItem("Password") private static readonly NativeItem _passwordItem = new NativeItem("Password")
{ AltTitle = new string('*', Main.Settings.Password.Length) }; { AltTitle = new string('*', Settings.Password.Length) };
public static readonly NativeItem ServerIpItem = new NativeItem("Server IP") public static readonly NativeItem ServerIpItem = new NativeItem("Server IP")
{ AltTitle = Main.Settings.LastServerAddress }; { AltTitle = Settings.LastServerAddress };
internal static readonly NativeItem _serverConnectItem = new NativeItem("Connect"); internal static readonly NativeItem _serverConnectItem = new NativeItem("Connect");
private static readonly NativeItem _aboutItem = new NativeItem("About", "~y~SOURCE~s~~n~" + private static readonly NativeItem _aboutItem = new NativeItem("About", "~y~SOURCE~s~~n~" +
"https://github.com/RAGECOOP~n~" + "https://github.com/RAGECOOP~n~" +
"~y~VERSION~s~~n~" + "~y~VERSION~s~~n~" +
Main.Version) Main.ModVersion)
{ LeftBadge = new ScaledTexture("commonmenu", "shop_new_star") }; { LeftBadge = new ScaledTexture("commonmenu", "shop_new_star") };
#endregion #endregion

View File

@ -10,13 +10,13 @@ namespace RageCoop.Client
public static NativeMenu Menu = new NativeMenu("RAGECOOP", "Debug", "Debug settings") public static NativeMenu Menu = new NativeMenu("RAGECOOP", "Debug", "Debug settings")
{ {
UseMouse = false, UseMouse = false,
Alignment = Main.Settings.FlipMenu ? Alignment.Right : Alignment.Left Alignment = Settings.FlipMenu ? Alignment.Right : Alignment.Left
}; };
public static NativeMenu DiagnosticMenu = new NativeMenu("RAGECOOP", "Diagnostic", "Performence and Diagnostic") public static NativeMenu DiagnosticMenu = new NativeMenu("RAGECOOP", "Diagnostic", "Performence and Diagnostic")
{ {
UseMouse = false, UseMouse = false,
Alignment = Main.Settings.FlipMenu ? Alignment.Right : Alignment.Left Alignment = Settings.FlipMenu ? Alignment.Right : Alignment.Left
}; };
public static NativeItem SimulatedLatencyItem = public static NativeItem SimulatedLatencyItem =
@ -48,7 +48,7 @@ namespace RageCoop.Client
}; };
ShowOwnerItem.CheckboxChanged += (s, e) => ShowOwnerItem.CheckboxChanged += (s, e) =>
{ {
Main.Settings.ShowEntityOwnerName = ShowOwnerItem.Checked; Settings.ShowEntityOwnerName = ShowOwnerItem.Checked;
Util.SaveSettings(); Util.SaveSettings();
}; };
#if DEBUG #if DEBUG

View File

@ -17,7 +17,7 @@ namespace RageCoop.Client
public static NativeMenu Menu = new NativeMenu("RAGECOOP", "DevTool", "Internal testing tools") public static NativeMenu Menu = new NativeMenu("RAGECOOP", "DevTool", "Internal testing tools")
{ {
UseMouse = false, UseMouse = false,
Alignment = Main.Settings.FlipMenu ? Alignment.Right : Alignment.Left Alignment = Settings.FlipMenu ? Alignment.Right : Alignment.Left
}; };
private static readonly NativeCheckboxItem enableItem = new NativeCheckboxItem("Show weapon bones"); private static readonly NativeCheckboxItem enableItem = new NativeCheckboxItem("Show weapon bones");
@ -40,7 +40,7 @@ namespace RageCoop.Client
var anims = JsonDeserialize<AnimDic[]>(File.ReadAllText(AnimationsDataPath)); var anims = JsonDeserialize<AnimDic[]>(File.ReadAllText(AnimationsDataPath));
foreach (var anim in anims) foreach (var anim in anims)
foreach (var a in anim.Animations) foreach (var a in anim.Animations)
if (Call<bool>(IS_ENTITY_PLAYING_ANIM, Main.P, anim.DictionaryName, a, 3)) if (Call<bool>(IS_ENTITY_PLAYING_ANIM, P, anim.DictionaryName, a, 3))
{ {
Console.PrintInfo(anim.DictionaryName + " : " + a); Console.PrintInfo(anim.DictionaryName + " : " + a);
Notification.Show(anim.DictionaryName + " : " + a); Notification.Show(anim.DictionaryName + " : " + a);

View File

@ -23,7 +23,7 @@ namespace RageCoop.Client.Menus
internal static NativeMenu Menu = new NativeMenu("RAGECOOP", "Servers", "Go to the server list") internal static NativeMenu Menu = new NativeMenu("RAGECOOP", "Servers", "Go to the server list")
{ {
UseMouse = false, UseMouse = false,
Alignment = Main.Settings.FlipMenu ? Alignment.Right : Alignment.Left Alignment = Settings.FlipMenu ? Alignment.Right : Alignment.Left
}; };
internal static NativeItem ResultItem = null; internal static NativeItem ResultItem = null;
@ -56,7 +56,7 @@ namespace RageCoop.Client.Menus
private static void GetAllServers() private static void GetAllServers()
{ {
List<ServerInfo> serverList = null; List<ServerInfo> serverList = null;
var realUrl = Main.Settings.MasterServer; var realUrl = Settings.MasterServer;
serverList = null; serverList = null;
try { serverList = JsonDeserialize<List<ServerInfo>>(DownloadString(realUrl)); } try { serverList = JsonDeserialize<List<ServerInfo>>(DownloadString(realUrl)); }
catch (Exception ex) { Log.Error(ex); } catch (Exception ex) { Log.Error(ex); }
@ -105,7 +105,7 @@ namespace RageCoop.Client.Menus
CoopMenu.Menu.Visible = true; CoopMenu.Menu.Visible = true;
#endif #endif
Main.Settings.LastServerAddress = address; Settings.LastServerAddress = address;
Util.SaveSettings(); Util.SaveSettings();
} }
catch (Exception ex) catch (Exception ex)

View File

@ -13,40 +13,40 @@ namespace RageCoop.Client.Menus
public static NativeMenu Menu = new NativeMenu("RAGECOOP", "Settings", "Go to the settings") public static NativeMenu Menu = new NativeMenu("RAGECOOP", "Settings", "Go to the settings")
{ {
UseMouse = false, UseMouse = false,
Alignment = Main.Settings.FlipMenu ? Alignment.Right : Alignment.Left Alignment = Settings.FlipMenu ? Alignment.Right : Alignment.Left
}; };
private static readonly NativeCheckboxItem _disableTrafficItem = private static readonly NativeCheckboxItem _disableTrafficItem =
new NativeCheckboxItem("Disable Traffic (NPCs/Vehicles)", "Local traffic only", new NativeCheckboxItem("Disable Traffic (NPCs/Vehicles)", "Local traffic only",
Main.Settings.DisableTraffic); Settings.DisableTraffic);
private static readonly NativeCheckboxItem _flipMenuItem = private static readonly NativeCheckboxItem _flipMenuItem =
new NativeCheckboxItem("Flip menu", Main.Settings.FlipMenu); new NativeCheckboxItem("Flip menu", Settings.FlipMenu);
private static readonly NativeCheckboxItem _disablePauseAlt = new NativeCheckboxItem("Disable Alternate Pause", private static readonly NativeCheckboxItem _disablePauseAlt = new NativeCheckboxItem("Disable Alternate Pause",
"Don't freeze game time when Esc pressed", Main.Settings.DisableAlternatePause); "Don't freeze game time when Esc pressed", Settings.DisableAlternatePause);
private static readonly NativeCheckboxItem _disableVoice = new NativeCheckboxItem("Enable voice", private static readonly NativeCheckboxItem _disableVoice = new NativeCheckboxItem("Enable voice",
"Check your GTA:V settings to find the right key on your keyboard for PushToTalk and talk to your friends", "Check your GTA:V settings to find the right key on your keyboard for PushToTalk and talk to your friends",
Main.Settings.Voice); Settings.Voice);
private static readonly NativeCheckboxItem _showBlip = new NativeCheckboxItem("Show player blip", private static readonly NativeCheckboxItem _showBlip = new NativeCheckboxItem("Show player blip",
"Show other player's nametag on your screen, only effective if server didn't disable nametag display", "Show other player's nametag on your screen, only effective if server didn't disable nametag display",
Main.Settings.ShowPlayerBlip); Settings.ShowPlayerBlip);
private static readonly NativeCheckboxItem _showNametag = new NativeCheckboxItem("Show player nametag", private static readonly NativeCheckboxItem _showNametag = new NativeCheckboxItem("Show player nametag",
"Show other player's blip on map, can be overridden by server resource ", "Show other player's blip on map, can be overridden by server resource ",
Main.Settings.ShowPlayerNameTag); Settings.ShowPlayerNameTag);
private static readonly NativeItem _menuKey = private static readonly NativeItem _menuKey =
new NativeItem("Menu Key", "The key to open menu", Main.Settings.MenuKey.ToString()); new NativeItem("Menu Key", "The key to open menu", Settings.MenuKey.ToString());
private static readonly NativeItem _passengerKey = new NativeItem("Passenger Key", private static readonly NativeItem _passengerKey = new NativeItem("Passenger Key",
"The key to enter a vehicle as passenger", Main.Settings.PassengerKey.ToString()); "The key to enter a vehicle as passenger", Settings.PassengerKey.ToString());
private static readonly NativeItem _vehicleSoftLimit = new NativeItem("Vehicle limit (soft)", private static readonly NativeItem _vehicleSoftLimit = new NativeItem("Vehicle limit (soft)",
"The game won't spawn more NPC traffic if the limit is exceeded. \n-1 for unlimited (not recommended).", "The game won't spawn more NPC traffic if the limit is exceeded. \n-1 for unlimited (not recommended).",
Main.Settings.WorldVehicleSoftLimit.ToString()); Settings.WorldVehicleSoftLimit.ToString());
static SettingsMenu() static SettingsMenu()
{ {
@ -62,7 +62,7 @@ namespace RageCoop.Client.Menus
_vehicleSoftLimit.Activated += VehicleSoftLimitActivated; _vehicleSoftLimit.Activated += VehicleSoftLimitActivated;
_showBlip.Activated += (s, e) => _showBlip.Activated += (s, e) =>
{ {
Main.Settings.ShowPlayerBlip = _showBlip.Checked; Settings.ShowPlayerBlip = _showBlip.Checked;
Util.SaveSettings(); Util.SaveSettings();
}; };
_showNametag.Activated += (s, e) => _showNametag.Activated += (s, e) =>
@ -92,13 +92,13 @@ namespace RageCoop.Client.Menus
Voice.ClearAll(); Voice.ClearAll();
} }
Main.Settings.Voice = _disableVoice.Checked; Settings.Voice = _disableVoice.Checked;
Util.SaveSettings(); Util.SaveSettings();
} }
private static void DisablePauseAltCheckboxChanged(object sender, EventArgs e) private static void DisablePauseAltCheckboxChanged(object sender, EventArgs e)
{ {
Main.Settings.DisableAlternatePause = _disablePauseAlt.Checked; Settings.DisableAlternatePause = _disablePauseAlt.Checked;
Util.SaveSettings(); Util.SaveSettings();
} }
@ -106,10 +106,10 @@ namespace RageCoop.Client.Menus
{ {
try try
{ {
Main.Settings.WorldVehicleSoftLimit = int.Parse( Settings.WorldVehicleSoftLimit = int.Parse(
Game.GetUserInput(WindowTitle.EnterMessage20, Game.GetUserInput(WindowTitle.EnterMessage20,
Main.Settings.WorldVehicleSoftLimit.ToString(), 20)); Settings.WorldVehicleSoftLimit.ToString(), 20));
_menuKey.AltTitle = Main.Settings.WorldVehicleSoftLimit.ToString(); _menuKey.AltTitle = Settings.WorldVehicleSoftLimit.ToString();
Util.SaveSettings(); Util.SaveSettings();
} }
catch catch
@ -121,11 +121,11 @@ namespace RageCoop.Client.Menus
{ {
try try
{ {
Main.Settings.MenuKey = (Keys)Enum.Parse( Settings.MenuKey = (Keys)Enum.Parse(
typeof(Keys), typeof(Keys),
Game.GetUserInput(WindowTitle.EnterMessage20, Game.GetUserInput(WindowTitle.EnterMessage20,
Main.Settings.MenuKey.ToString(), 20)); Settings.MenuKey.ToString(), 20));
_menuKey.AltTitle = Main.Settings.MenuKey.ToString(); _menuKey.AltTitle = Settings.MenuKey.ToString();
Util.SaveSettings(); Util.SaveSettings();
} }
catch catch
@ -137,11 +137,11 @@ namespace RageCoop.Client.Menus
{ {
try try
{ {
Main.Settings.PassengerKey = (Keys)Enum.Parse( Settings.PassengerKey = (Keys)Enum.Parse(
typeof(Keys), typeof(Keys),
Game.GetUserInput(WindowTitle.EnterMessage20, Game.GetUserInput(WindowTitle.EnterMessage20,
Main.Settings.PassengerKey.ToString(), 20)); Settings.PassengerKey.ToString(), 20));
_passengerKey.AltTitle = Main.Settings.PassengerKey.ToString(); _passengerKey.AltTitle = Settings.PassengerKey.ToString();
Util.SaveSettings(); Util.SaveSettings();
} }
catch catch
@ -152,7 +152,7 @@ namespace RageCoop.Client.Menus
public static void DisableTrafficCheckboxChanged(object a, EventArgs b) public static void DisableTrafficCheckboxChanged(object a, EventArgs b)
{ {
WorldThread.Traffic(!_disableTrafficItem.Checked); WorldThread.Traffic(!_disableTrafficItem.Checked);
Main.Settings.DisableTraffic = _disableTrafficItem.Checked; Settings.DisableTraffic = _disableTrafficItem.Checked;
Util.SaveSettings(); Util.SaveSettings();
} }
@ -161,7 +161,7 @@ namespace RageCoop.Client.Menus
CoopMenu.Menu.Alignment = _flipMenuItem.Checked ? Alignment.Right : Alignment.Left; CoopMenu.Menu.Alignment = _flipMenuItem.Checked ? Alignment.Right : Alignment.Left;
Menu.Alignment = _flipMenuItem.Checked ? Alignment.Right : Alignment.Left; Menu.Alignment = _flipMenuItem.Checked ? Alignment.Right : Alignment.Left;
Main.Settings.FlipMenu = _flipMenuItem.Checked; Settings.FlipMenu = _flipMenuItem.Checked;
Util.SaveSettings(); Util.SaveSettings();
} }
} }

View File

@ -32,7 +32,7 @@ namespace RageCoop.Client
var msg = Networking.Peer.CreateMessage(); var msg = Networking.Peer.CreateMessage();
new Packets.HolePunch new Packets.HolePunch
{ {
Puncher = Main.LocalPlayerID, Puncher = LocalPlayerID,
Status = p.HolePunchStatus Status = p.HolePunchStatus
}.Pack(msg); }.Pack(msg);
Networking.Peer.SendUnconnectedMessage(msg, Networking.Peer.SendUnconnectedMessage(msg,
@ -75,7 +75,7 @@ namespace RageCoop.Client
{ {
Log.Debug("Connecting to peer: " + from); Log.Debug("Connecting to peer: " + from);
var msg = Networking.Peer.CreateMessage(); var msg = Networking.Peer.CreateMessage();
new Packets.P2PConnect { ID = Main.LocalPlayerID }.Pack(msg); new Packets.P2PConnect { ID = LocalPlayerID }.Pack(msg);
puncher.Connection = Networking.Peer.Connect(from, msg); puncher.Connection = Networking.Peer.Connect(from, msg);
Networking.Peer.FlushSendQueue(); Networking.Peer.FlushSendQueue();
} }

View File

@ -14,24 +14,18 @@ namespace RageCoop.Client
{ {
internal static partial class Networking internal static partial class Networking
{ {
public static CoopPeer Peer;
public static bool ShowNetworkInfo = false;
public static Security Security;
public static NetConnection ServerConnection;
private static readonly Dictionary<int, Action<PacketType, NetIncomingMessage>> PendingResponses =
new Dictionary<int, Action<PacketType, NetIncomingMessage>>();
internal static readonly Dictionary<PacketType, Func<NetIncomingMessage, Packet>> RequestHandlers =
new Dictionary<PacketType, Func<NetIncomingMessage, Packet>>();
internal static float SimulatedLatency = 0;
public static IPEndPoint _targetServerEP; public static IPEndPoint _targetServerEP;
static Networking() public static CoopPeer Peer;
{ public static bool ShowNetworkInfo = false;
Security = new Security(Log); public static Security Security = new();
} public static NetConnection ServerConnection;
private static readonly Dictionary<int, Action<PacketType, NetIncomingMessage>> PendingResponses = new();
internal static readonly Dictionary<PacketType, Func<NetIncomingMessage, Packet>> RequestHandlers = new();
internal static float SimulatedLatency = 0;
public static float Latency => ServerConnection.AverageRoundtripTime / 2; public static float Latency => ServerConnection.AverageRoundtripTime / 2;
public static bool IsConnecting { get; private set; } public static bool IsConnecting { get; private set; }
@ -41,24 +35,25 @@ namespace RageCoop.Client
PublicKey publicKey = null) PublicKey publicKey = null)
{ {
CoopMenu.Menu.Visible = false; CoopMenu.Menu.Visible = false;
Peer?.Shutdown("Bye");
if (IsOnServer) if (IsConnecting)
{
// ?
}
else if (IsConnecting)
{ {
_publicKeyReceived.Set(); _publicKeyReceived.Set();
IsConnecting = false; IsConnecting = false;
Notification.Show("Connection has been canceled"); API.QueueAction(() =>
} Notification.Show("Connection has been canceled"));
else
{
Peer?.Dispose();
Peer.Shutdown("bye");
}
else if (IsOnServer)
{
Peer.Shutdown("bye");
}
else
{
IsConnecting = true; IsConnecting = true;
password = password ?? Main.Settings.Password; password ??= Settings.Password;
username = username ?? Main.Settings.Username; username ??= Settings.Username;
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP // 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
var config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0") var config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
@ -104,7 +99,7 @@ namespace RageCoop.Client
// Ensure static constructor invocation // Ensure static constructor invocation
DownloadManager.Cleanup(); DownloadManager.Cleanup();
Peer = new CoopPeer(config); Peer = new CoopPeer(config,Log);
Peer.OnMessageReceived += (s, m) => Peer.OnMessageReceived += (s, m) =>
{ {
try try
@ -136,9 +131,9 @@ namespace RageCoop.Client
var outgoingMessage = Peer.CreateMessage(); var outgoingMessage = Peer.CreateMessage();
var handshake = new Packets.Handshake var handshake = new Packets.Handshake
{ {
PedID = Main.LocalPlayerID, PedID = LocalPlayerID,
Username = username, Username = username,
ModVersion = Main.Version.ToString(), ModVersion = Main.ModVersion.ToString(),
PasswordEncrypted = Security.Encrypt(password.GetBytes()), PasswordEncrypted = Security.Encrypt(password.GetBytes()),
InternalEndPoint = new IPEndPoint(CoreUtils.GetLocalAddress(ip[0]), Peer.Port) InternalEndPoint = new IPEndPoint(CoreUtils.GetLocalAddress(ip[0]), Peer.Port)
}; };
@ -150,7 +145,7 @@ namespace RageCoop.Client
catch (Exception ex) catch (Exception ex)
{ {
Log.Error("Cannot connect to server: ", ex); Log.Error("Cannot connect to server: ", ex);
API.QueueAction(() => Notification.Show("Cannot connect to server: " + ex.Message)); API.QueueAction(() => Notification.Show("~r~Cannot connect to server: " + ex.Message));
} }
IsConnecting = false; IsConnecting = false;

View File

@ -39,7 +39,7 @@ namespace RageCoop.Client
var p = new Packets.HandshakeSuccess(); var p = new Packets.HandshakeSuccess();
p.Deserialize(response); p.Deserialize(response);
foreach (var player in p.Players) PlayerList.SetPlayer(player.ID, player.Username); foreach (var player in p.Players) PlayerList.SetPlayer(player.ID, player.Username);
Main.Connected(); Connected();
} }
else else
{ {
@ -62,7 +62,7 @@ namespace RageCoop.Client
break; break;
case NetConnectionStatus.Disconnected: case NetConnectionStatus.Disconnected:
if (message.SenderConnection == ServerConnection) Main.CleanUp(reason); if (message.SenderConnection == ServerConnection) API.QueueAction(() => CleanUp(reason));
break; break;
} }
@ -205,7 +205,7 @@ namespace RageCoop.Client
API.QueueAction(() => API.QueueAction(() =>
{ {
Main.MainChat.AddMessage(packet.Username, packet.Message); MainChat.AddMessage(packet.Username, packet.Message);
return true; return true;
}); });
} }
@ -213,7 +213,7 @@ namespace RageCoop.Client
case PacketType.Voice: case PacketType.Voice:
{ {
if (Main.Settings.Voice) if (Settings.Voice)
{ {
var packet = new Packets.Voice(); var packet = new Packets.Voice();
packet.Deserialize(msg); packet.Deserialize(msg);
@ -221,7 +221,7 @@ namespace RageCoop.Client
var player = EntityPool.GetPedByID(packet.ID); var player = EntityPool.GetPedByID(packet.ID);
player.IsSpeaking = true; player.IsSpeaking = true;
player.LastSpeakingTime = Main.Ticked; player.LastSpeakingTime = Ticked;
Voice.AddVoiceData(packet.Buffer, packet.Recorded); Voice.AddVoiceData(packet.Buffer, packet.Recorded);
} }

View File

@ -54,8 +54,8 @@ namespace RageCoop.Client
p.Seat = ped.SeatIndex; p.Seat = ped.SeatIndex;
if (!veh.IsLocal && p.Speed == 4 && p.Seat == VehicleSeat.Driver) if (!veh.IsLocal && p.Speed == 4 && p.Seat == VehicleSeat.Driver)
{ {
veh.OwnerID = Main.LocalPlayerID; veh.OwnerID = LocalPlayerID;
SyncEvents.TriggerChangeOwner(veh.ID, Main.LocalPlayerID); SyncEvents.TriggerChangeOwner(veh.ID, LocalPlayerID);
} }
} }
@ -154,14 +154,14 @@ namespace RageCoop.Client
public static void SendChatMessage(string message) public static void SendChatMessage(string message)
{ {
Peer.SendTo(new Packets.ChatMessage(s => Security.Encrypt(s.GetBytes())) Peer.SendTo(new Packets.ChatMessage(s => Security.Encrypt(s.GetBytes()))
{ Username = Main.Settings.Username, Message = message }, ServerConnection, ConnectionChannel.Chat, { Username = Settings.Username, Message = message }, ServerConnection, ConnectionChannel.Chat,
NetDeliveryMethod.ReliableOrdered); NetDeliveryMethod.ReliableOrdered);
Peer.FlushSendQueue(); Peer.FlushSendQueue();
} }
public static void SendVoiceMessage(byte[] buffer, int recorded) public static void SendVoiceMessage(byte[] buffer, int recorded)
{ {
SendSync(new Packets.Voice { ID = Main.LocalPlayerID, Buffer = buffer, Recorded = recorded }, SendSync(new Packets.Voice { ID = LocalPlayerID, Buffer = buffer, Recorded = recorded },
ConnectionChannel.Voice, NetDeliveryMethod.ReliableOrdered); ConnectionChannel.Voice, NetDeliveryMethod.ReliableOrdered);
} }

View File

@ -9,7 +9,7 @@ namespace RageCoop.Client
{ {
ThreadManager.CreateThread(() => ThreadManager.CreateThread(() =>
{ {
while (!Main.IsUnloading) while (!IsUnloading)
{ {
var bu = Networking.Peer.Statistics.SentBytes; var bu = Networking.Peer.Statistics.SentBytes;
var bd = Networking.Peer.Statistics.ReceivedBytes; var bd = Networking.Peer.Statistics.ReceivedBytes;

View File

@ -29,7 +29,7 @@ namespace RageCoop.Client
if (Util.GetTickCount64() - _lastUpdate >= 1000) Update(); if (Util.GetTickCount64() - _lastUpdate >= 1000) Update();
if (Util.GetTickCount64() - Pressed < 5000 && !Main.MainChat.Focused if (Util.GetTickCount64() - Pressed < 5000 && !MainChat.Focused
#if !NON_INTERACTIVE #if !NON_INTERACTIVE
&& !CoopMenu.MenuPool.AreAnyVisible && !CoopMenu.MenuPool.AreAnyVisible
#endif #endif
@ -160,7 +160,7 @@ namespace RageCoop.Client
/// <summary> /// <summary>
/// Player round-trip time in seconds, will be the rtt to server if not using P2P connection. /// Player round-trip time in seconds, will be the rtt to server if not using P2P connection.
/// </summary> /// </summary>
public float Ping => Main.LocalPlayerID == ID ? Networking.Latency * 2 : public float Ping => LocalPlayerID == ID ? Networking.Latency * 2 :
HasDirectConnection ? Connection.AverageRoundtripTime : _latencyToServer * 2; HasDirectConnection ? Connection.AverageRoundtripTime : _latencyToServer * 2;
public float PacketTravelTime => HasDirectConnection public float PacketTravelTime => HasDirectConnection

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<NoAotCompile>true</NoAotCompile> <NoAotCompile>false</NoAotCompile>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>

View File

@ -53,11 +53,11 @@ namespace RageCoop.Client.Scripting
/// </summary> /// </summary>
public static string Username public static string Username
{ {
get => Main.Settings.Username; get => Settings.Username;
set set
{ {
if (Networking.IsOnServer || string.IsNullOrEmpty(value)) return; if (Networking.IsOnServer || string.IsNullOrEmpty(value)) return;
Main.Settings.Username = value; Settings.Username = value;
} }
} }
@ -83,11 +83,11 @@ namespace RageCoop.Client.Scripting
public static bool ShowPlayerNameTag public static bool ShowPlayerNameTag
{ {
get => Main.Settings.ShowPlayerNameTag; get => Settings.ShowPlayerNameTag;
set set
{ {
if (value == ShowPlayerNameTag) return; if (value == ShowPlayerNameTag) return;
Main.Settings.ShowPlayerNameTag = value; Settings.ShowPlayerNameTag = value;
Util.SaveSettings(); Util.SaveSettings();
} }
} }
@ -183,7 +183,7 @@ namespace RageCoop.Client.Scripting
/// Get the local player's ID /// Get the local player's ID
/// </summary> /// </summary>
/// <returns>PlayerID</returns> /// <returns>PlayerID</returns>
public static int LocalPlayerID => Main.LocalPlayerID; public static int LocalPlayerID => LocalPlayerID;
/// <summary> /// <summary>
/// Check if player is connected to a server /// Check if player is connected to a server
@ -205,7 +205,7 @@ namespace RageCoop.Client.Scripting
/// <summary> /// <summary>
/// Check if the RAGECOOP chat is visible /// Check if the RAGECOOP chat is visible
/// </summary> /// </summary>
public static bool IsChatFocused => Main.MainChat.Focused; public static bool IsChatFocused => MainChat.Focused;
/// <summary> /// <summary>
/// Check if the RAGECOOP list of players is visible /// Check if the RAGECOOP list of players is visible
@ -215,7 +215,7 @@ namespace RageCoop.Client.Scripting
/// <summary> /// <summary>
/// Get the version of RAGECOOP /// Get the version of RAGECOOP
/// </summary> /// </summary>
public static Version CurrentVersion => Main.Version; public static Version CurrentVersion => Main.ModVersion;
/// <summary> /// <summary>
/// Get all players indexed by their ID /// Get all players indexed by their ID
@ -371,7 +371,7 @@ namespace RageCoop.Client.Scripting
public static List<ServerInfo> ListServers() public static List<ServerInfo> ListServers()
{ {
return JsonDeserialize<List<ServerInfo>>( return JsonDeserialize<List<ServerInfo>>(
HttpHelper.DownloadString(Main.Settings.MasterServer)); HttpHelper.DownloadString(Settings.MasterServer));
} }
/// <summary> /// <summary>
@ -382,7 +382,7 @@ namespace RageCoop.Client.Scripting
[Remoting] [Remoting]
public static void LocalChatMessage(string from, string message) public static void LocalChatMessage(string from, string message)
{ {
Main.MainChat.AddMessage(from, message); MainChat.AddMessage(from, message);
} }
/// <summary> /// <summary>

View File

@ -37,9 +37,9 @@ namespace RageCoop.Client.Scripting
e => { Notification.Show($"~h~{e.Args[0]}~h~ died."); }); e => { Notification.Show($"~h~{e.Args[0]}~h~ died."); });
ThreadManager.CreateThread(() => ThreadManager.CreateThread(() =>
{ {
while (!Main.IsUnloading) while (!IsUnloading)
{ {
if (_isHost) if (Networking.IsOnServer && _isHost)
API.QueueAction(() => API.QueueAction(() =>
{ {
unsafe unsafe
@ -56,7 +56,7 @@ namespace RageCoop.Client.Scripting
Thread.Sleep(1000); Thread.Sleep(1000);
} }
},"BaseScript"); }, "BaseScript");
} }
private static void WeatherTimeSync(CustomEventReceivedArgs e) private static void WeatherTimeSync(CustomEventReceivedArgs e)
@ -103,7 +103,7 @@ namespace RageCoop.Client.Scripting
{ {
ID = (int)e.Args[0], ID = (int)e.Args[0],
MainVehicle = veh, MainVehicle = veh,
OwnerID = Main.LocalPlayerID OwnerID = LocalPlayerID
}; };
EntityPool.Add(v); EntityPool.Add(v);
} }
@ -173,7 +173,7 @@ namespace RageCoop.Client.Scripting
EntityPool.ServerProps.Add(id, prop = new SyncedProp(id)); EntityPool.ServerProps.Add(id, prop = new SyncedProp(id));
} }
prop.LastSynced = Main.Ticked + 1; prop.LastSynced = Ticked + 1;
prop.Model = (Model)e.Args[1]; prop.Model = (Model)e.Args[1];
prop.Position = (Vector3)e.Args[2]; prop.Position = (Vector3)e.Args[2];
prop.Rotation = (Vector3)e.Args[3]; prop.Rotation = (Vector3)e.Args[3];

View File

@ -32,12 +32,6 @@ namespace RageCoop.Client.Scripting
Directory.CreateDirectory(TempPath); Directory.CreateDirectory(TempPath);
} }
public Resources()
{
Logger = Log;
}
private Logger Logger { get; }
public void Load(string path, string[] zips) public void Load(string path, string[] zips)
{ {
@ -45,7 +39,7 @@ namespace RageCoop.Client.Scripting
foreach (var zip in zips) foreach (var zip in zips)
{ {
var zipPath = Path.Combine(path, zip); var zipPath = Path.Combine(path, zip);
Logger?.Info($"Loading resource: {Path.GetFileNameWithoutExtension(zip)}"); Log?.Info($"Loading resource: {Path.GetFileNameWithoutExtension(zip)}");
Unpack(zipPath, Path.Combine(path, "Data")); Unpack(zipPath, Path.Combine(path, "Data"));
} }
@ -94,7 +88,7 @@ namespace RageCoop.Client.Scripting
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Warning( Log.Warning(
$"Failed to delete API assembly: {file}. This may or may cause some unexpected behaviours.\n{ex}"); $"Failed to delete API assembly: {file}. This may or may cause some unexpected behaviours.\n{ex}");
} }

View File

@ -6,11 +6,9 @@ namespace RageCoop.Client
{ {
internal class Security internal class Security
{ {
private readonly Logger Logger;
public Security(Logger logger) public Security()
{ {
Logger = logger;
ClientAes.GenerateKey(); ClientAes.GenerateKey();
ClientAes.GenerateIV(); ClientAes.GenerateIV();
} }

View File

@ -27,7 +27,7 @@ namespace RageCoop.Client
p.CanWrithe = false; p.CanWrithe = false;
p.IsOnlyDamagedByPlayer = false; p.IsOnlyDamagedByPlayer = false;
MainPed = p; MainPed = p;
OwnerID = Main.LocalPlayerID; OwnerID = LocalPlayerID;
MainPed.SetConfigFlag((int)PedConfigFlags.CPED_CONFIG_FLAG_DisableHurt, true); MainPed.SetConfigFlag((int)PedConfigFlags.CPED_CONFIG_FLAG_DisableHurt, true);
} }
@ -38,7 +38,7 @@ namespace RageCoop.Client
internal SyncedPed(int id) internal SyncedPed(int id)
{ {
ID = id; ID = id;
LastSynced = Main.Ticked; LastSynced = Ticked;
} }
internal override void Update() internal override void Update()
@ -67,7 +67,7 @@ namespace RageCoop.Client
if (!CreateCharacter()) if (!CreateCharacter())
return; return;
if (!Main.Settings.ShowPlayerBlip && (byte)BlipColor != 255) BlipColor = (BlipColor)255; if (!Settings.ShowPlayerBlip && (byte)BlipColor != 255) BlipColor = (BlipColor)255;
if ((byte)BlipColor == 255 && PedBlip != null) if ((byte)BlipColor == 255 && PedBlip != null)
{ {
PedBlip.Delete(); PedBlip.Delete();
@ -134,7 +134,7 @@ namespace RageCoop.Client
if (IsSpeaking) if (IsSpeaking)
{ {
if (Main.Ticked - LastSpeakingTime < 10) if (Ticked - LastSpeakingTime < 10)
{ {
DisplaySpeaking(true); DisplaySpeaking(true);
} }
@ -147,13 +147,13 @@ namespace RageCoop.Client
} }
} }
LastUpdated = Main.Ticked; LastUpdated = Ticked;
} }
private void RenderNameTag() private void RenderNameTag()
{ {
if (!Owner.DisplayNameTag || !Main.Settings.ShowPlayerNameTag || MainPed == null || !MainPed.IsVisible || if (!Owner.DisplayNameTag || !Settings.ShowPlayerNameTag || MainPed == null || !MainPed.IsVisible ||
!MainPed.IsInRange(Main.PlayerPosition, 40f)) return; !MainPed.IsInRange(PlayerPosition, 40f)) return;
var targetPos = MainPed.Bones[Bone.IKHead].Position + Vector3.WorldUp * 0.5f; var targetPos = MainPed.Bones[Bone.IKHead].Position + Vector3.WorldUp * 0.5f;
Point toDraw = default; Point toDraw = default;
@ -204,7 +204,7 @@ namespace RageCoop.Client
MainPed.CanWrithe = false; MainPed.CanWrithe = false;
MainPed.CanBeDraggedOutOfVehicle = true; MainPed.CanBeDraggedOutOfVehicle = true;
MainPed.IsOnlyDamagedByPlayer = false; MainPed.IsOnlyDamagedByPlayer = false;
MainPed.RelationshipGroup = Main.SyncedPedsGroup; MainPed.RelationshipGroup = SyncedPedsGroup;
MainPed.IsFireProof = false; MainPed.IsFireProof = false;
MainPed.IsExplosionProof = false; MainPed.IsExplosionProof = false;
@ -397,7 +397,7 @@ namespace RageCoop.Client
if (!_lastRagdoll) if (!_lastRagdoll)
{ {
_lastRagdoll = true; _lastRagdoll = true;
_lastRagdollTime = Main.Ticked; _lastRagdollTime = Ticked;
} }
return; return;
@ -599,7 +599,7 @@ namespace RageCoop.Client
MainPed.Velocity = Velocity + 5 * dist * (predicted - MainPed.ReadPosition()); MainPed.Velocity = Velocity + 5 * dist * (predicted - MainPed.ReadPosition());
} }
else if (Main.Ticked - _lastRagdollTime < 10) else if (Ticked - _lastRagdollTime < 10)
{ {
} }
else if (IsRagdoll) else if (IsRagdoll)

View File

@ -16,7 +16,7 @@ namespace RageCoop.Client
/// <summary> /// <summary>
/// Indicates whether the current player is responsible for syncing this entity. /// Indicates whether the current player is responsible for syncing this entity.
/// </summary> /// </summary>
public bool IsLocal => OwnerID == Main.LocalPlayerID; public bool IsLocal => OwnerID == LocalPlayerID;
/// <summary> /// <summary>
/// Network ID for this entity /// Network ID for this entity
@ -41,7 +41,7 @@ namespace RageCoop.Client
/// <summary> /// <summary>
/// </summary> /// </summary>
public bool IsOutOfSync => Main.Ticked - LastSynced > 200 && ID != 0; public bool IsOutOfSync => Ticked - LastSynced > 200 && ID != 0;
internal bool IsReady => LastSynced > 0 || LastFullSynced == 0; internal bool IsReady => LastSynced > 0 || LastFullSynced == 0;
@ -60,7 +60,7 @@ namespace RageCoop.Client
internal void PauseUpdate(ulong frames) internal void PauseUpdate(ulong frames)
{ {
LastUpdated = Main.Ticked + frames; LastUpdated = Ticked + frames;
} }
protected Vector3 Predict(Vector3 input) protected Vector3 Predict(Vector3 input)
@ -93,10 +93,10 @@ namespace RageCoop.Client
public void SetLastSynced(bool full) public void SetLastSynced(bool full)
{ {
LastSyncInterval = LastSentStopWatch.ElapsedMilliseconds; LastSyncInterval = LastSentStopWatch.ElapsedMilliseconds;
LastSynced = Main.Ticked; LastSynced = Ticked;
if (full) if (full)
{ {
LastFullSynced = Main.Ticked; LastFullSynced = Ticked;
} }
LastSyncedStopWatch.Restart(); LastSyncedStopWatch.Restart();
} }

View File

@ -107,7 +107,7 @@ namespace RageCoop.Client
MainProjectile.Velocity = Velocity + 10 * (Predict(Position) - MainProjectile.Position); MainProjectile.Velocity = Velocity + 10 * (Predict(Position) - MainProjectile.Position);
MainProjectile.Rotation = Rotation; MainProjectile.Rotation = Rotation;
LastUpdated = Main.Ticked; LastUpdated = Ticked;
} }
private void CreateProjectile() private void CreateProjectile()

View File

@ -39,7 +39,7 @@ namespace RageCoop.Client
MainProp.Position = Position; MainProp.Position = Position;
MainProp.Rotation = Rotation; MainProp.Rotation = Rotation;
MainProp.SetFrozen(true); MainProp.SetFrozen(true);
LastUpdated = Main.Ticked; LastUpdated = Ticked;
} }
} }
} }

View File

@ -152,7 +152,7 @@ namespace RageCoop.Client
MainVehicle.SetDamageModel(DamageModel); MainVehicle.SetDamageModel(DamageModel);
} }
LastUpdated = Main.Ticked; LastUpdated = Ticked;
} }
private void DisplayVehicle(bool updated) private void DisplayVehicle(bool updated)
@ -226,7 +226,7 @@ namespace RageCoop.Client
ID = EntityPool.RequestNewID(); ID = EntityPool.RequestNewID();
MainVehicle = v; MainVehicle = v;
MainVehicle.CanPretendOccupants = false; MainVehicle.CanPretendOccupants = false;
OwnerID = Main.LocalPlayerID; OwnerID = LocalPlayerID;
SetUpFixedData(); SetUpFixedData();
} }
@ -261,7 +261,7 @@ namespace RageCoop.Client
internal SyncedVehicle(int id) internal SyncedVehicle(int id)
{ {
ID = id; ID = id;
LastSynced = Main.Ticked; LastSynced = Ticked;
} }
#endregion #endregion

View File

@ -49,8 +49,8 @@ namespace RageCoop.Client
{ {
foreach (var ped in PedsByID.Values.ToArray()) foreach (var ped in PedsByID.Values.ToArray())
{ {
if ((keepPlayer && ped.ID == Main.LocalPlayerID) || if ((keepPlayer && ped.ID == LocalPlayerID) ||
(keepMine && ped.OwnerID == Main.LocalPlayerID)) continue; (keepMine && ped.OwnerID == LocalPlayerID)) continue;
RemovePed(ped.ID); RemovePed(ped.ID);
} }
@ -59,7 +59,7 @@ namespace RageCoop.Client
foreach (var id in VehiclesByID.Keys.ToArray()) foreach (var id in VehiclesByID.Keys.ToArray())
{ {
if (keepMine && VehiclesByID[id].OwnerID == Main.LocalPlayerID) continue; if (keepMine && VehiclesByID[id].OwnerID == LocalPlayerID) continue;
RemoveVehicle(id); RemoveVehicle(id);
} }
@ -67,7 +67,7 @@ namespace RageCoop.Client
VehiclesByHandle.Clear(); VehiclesByHandle.Clear();
foreach (var p in ProjectilesByID.Values.ToArray()) foreach (var p in ProjectilesByID.Values.ToArray())
if (p.Shooter.ID != Main.LocalPlayerID && p.MainProjectile != null && p.MainProjectile.Exists()) if (p.Shooter.ID != LocalPlayerID && p.MainProjectile != null && p.MainProjectile.Exists())
p.MainProjectile.Delete(); p.MainProjectile.Delete();
ProjectilesByID.Clear(); ProjectilesByID.Clear();
ProjectilesByHandle.Clear(); ProjectilesByHandle.Clear();
@ -99,15 +99,15 @@ namespace RageCoop.Client
var p = Game.Player.Character; var p = Game.Player.Character;
// var clipset=p.Gender==Gender.Male? "MOVE_M@TOUGH_GUY@" : "MOVE_F@TOUGH_GUY@"; // var clipset=p.Gender==Gender.Male? "MOVE_M@TOUGH_GUY@" : "MOVE_F@TOUGH_GUY@";
// Call(SET_PED_MOVEMENT_CLIPSET,p,clipset,1f); // Call(SET_PED_MOVEMENT_CLIPSET,p,clipset,1f);
var player = GetPedByID(Main.LocalPlayerID); var player = GetPedByID(LocalPlayerID);
if (player == null) if (player == null)
{ {
Log.Debug($"Creating SyncEntity for player, handle:{p.Handle}"); Log.Debug($"Creating SyncEntity for player, handle:{p.Handle}");
var c = new SyncedPed(p); var c = new SyncedPed(p);
Main.LocalPlayerID = c.OwnerID = c.ID; LocalPlayerID = c.OwnerID = c.ID;
Add(c); Add(c);
Log.Debug($"Local player ID is:{c.ID}"); Log.Debug($"Local player ID is:{c.ID}");
PlayerList.SetPlayer(c.ID, Main.Settings.Username); PlayerList.SetPlayer(c.ID, Settings.Username);
return true; return true;
} }
@ -308,8 +308,8 @@ namespace RageCoop.Client
var allPeds = NativeMemory.GetPedHandles(); var allPeds = NativeMemory.GetPedHandles();
var allVehicles = NativeMemory.GetVehicleHandles(); var allVehicles = NativeMemory.GetVehicleHandles();
var allProjectiles = NativeMemory.GetProjectileHandles(); var allProjectiles = NativeMemory.GetProjectileHandles();
vehStatesPerFrame = allVehicles.Length * 2 / (int)Main.FPS + 1; vehStatesPerFrame = allVehicles.Length * 2 / (int)FPS + 1;
pedStatesPerFrame = allPeds.Length * 2 / (int)Main.FPS + 1; pedStatesPerFrame = allPeds.Length * 2 / (int)FPS + 1;
#if BENCHMARK #if BENCHMARK
Debug.TimeStamps[TimeStamp.GetAllEntities] = PerfCounter.ElapsedTicks; Debug.TimeStamps[TimeStamp.GetAllEntities] = PerfCounter.ElapsedTicks;
@ -357,7 +357,7 @@ namespace RageCoop.Client
if (c == null && p != Game.Player.Character.Handle) if (c == null && p != Game.Player.Character.Handle)
{ {
var type = Util.GetPopulationType(p); var type = Util.GetPopulationType(p);
if (allPeds.Length > Main.Settings.WorldPedSoftLimit && if (allPeds.Length > Settings.WorldPedSoftLimit &&
type == EntityPopulationType.RandomAmbient && !Call<bool>(IS_PED_IN_ANY_VEHICLE, p, 0)) type == EntityPopulationType.RandomAmbient && !Call<bool>(IS_PED_IN_ANY_VEHICLE, p, 0))
{ {
Util.DeleteEntity(p); Util.DeleteEntity(p);
@ -417,7 +417,7 @@ namespace RageCoop.Client
#endif #endif
} }
var check = Main.Ticked % 100 == 0; var check = Ticked % 100 == 0;
i = -1; i = -1;
lock (VehiclesLock) lock (VehiclesLock)
{ {
@ -425,7 +425,7 @@ namespace RageCoop.Client
if (!VehiclesByHandle.ContainsKey(veh)) if (!VehiclesByHandle.ContainsKey(veh))
{ {
var cveh = (Vehicle)Entity.FromHandle(veh); var cveh = (Vehicle)Entity.FromHandle(veh);
if (allVehicles.Length > Main.Settings.WorldVehicleSoftLimit) if (allVehicles.Length > Settings.WorldVehicleSoftLimit)
{ {
var type = cveh.PopulationType; var type = cveh.PopulationType;
if (type == EntityPopulationType.RandomAmbient || type == EntityPopulationType.RandomParked) if (type == EntityPopulationType.RandomAmbient || type == EntityPopulationType.RandomParked)
@ -489,7 +489,7 @@ namespace RageCoop.Client
{ {
Networking.Targets = new List<NetConnection>(PlayerList.Players.Count) { Networking.ServerConnection }; Networking.Targets = new List<NetConnection>(PlayerList.Players.Count) { Networking.ServerConnection };
foreach (var p in PlayerList.Players.Values.ToArray()) foreach (var p in PlayerList.Players.Values.ToArray())
if (p.HasDirectConnection && p.Position.DistanceTo(Main.PlayerPosition) < 500) if (p.HasDirectConnection && p.Position.DistanceTo(PlayerPosition) < 500)
Networking.Targets.Add(p.Connection); Networking.Targets.Add(p.Connection);
} }

View File

@ -55,7 +55,7 @@ namespace RageCoop.Client
// I tried without thread but the game will lag without // I tried without thread but the game will lag without
_thread = ThreadManager.CreateThread(() => _thread = ThreadManager.CreateThread(() =>
{ {
while (!_stopping && !Main.IsUnloading) while (!_stopping && !IsUnloading)
using (var wo = new WaveOutEvent()) using (var wo = new WaveOutEvent())
{ {
wo.Init(_waveProvider); wo.Init(_waveProvider);

View File

@ -18,7 +18,7 @@ namespace RageCoop.Client
private static Thread _watcher = new(() => _removeStopped()); private static Thread _watcher = new(() => _removeStopped());
private static void _removeStopped() private static void _removeStopped()
{ {
while (!Main.IsUnloading) while (!IsUnloading)
{ {
lock (_threads) lock (_threads)
{ {
@ -57,6 +57,7 @@ namespace RageCoop.Client
public static void OnUnload() public static void OnUnload()
{ {
Log.Debug("Stopping background threads");
lock (_threads) lock (_threads)
{ {
foreach (var thread in _threads) foreach (var thread in _threads)
@ -69,9 +70,9 @@ namespace RageCoop.Client
} }
} }
_threads.Clear(); _threads.Clear();
_threads = null;
_watcher.Join();
} }
Log.Debug("Stopping thread watcher");
_watcher.Join();
} }
} }
} }

View File

@ -401,7 +401,7 @@ namespace RageCoop.Client
public static Vector3 GetLookingCoord(this Ped p) public static Vector3 GetLookingCoord(this Ped p)
{ {
if (p == Main.P && Call<int>(GET_FOLLOW_PED_CAM_VIEW_MODE) == 4) if (p == P && Call<int>(GET_FOLLOW_PED_CAM_VIEW_MODE) == 4)
return RaycastEverything(default); return RaycastEverything(default);
EntityBone b = p.Bones[Bone.FacialForehead]; EntityBone b = p.Bones[Bone.FacialForehead];
var v = b.UpVector.Normalized; var v = b.UpVector.Normalized;

View File

@ -99,31 +99,31 @@ namespace RageCoop.Client
return false; return false;
} }
public static Settings ReadSettings(string path = null) public static ClientSettings ReadSettings(string path = null)
{ {
path = path ?? SettingsPath; path = path ?? SettingsPath;
Directory.CreateDirectory(Directory.GetParent(path).FullName); Directory.CreateDirectory(Directory.GetParent(path).FullName);
Settings settings; ClientSettings settings;
try try
{ {
settings = JsonDeserialize<Settings>(File.ReadAllText(path)); settings = JsonDeserialize<ClientSettings>(File.ReadAllText(path));
} }
catch (Exception ex) catch (Exception ex)
{ {
Log?.Error(ex); Log?.Error(ex);
File.WriteAllText(path, JsonSerialize(settings = new Settings())); File.WriteAllText(path, JsonSerialize(settings = new ClientSettings()));
} }
return settings; return settings;
} }
public static bool SaveSettings(string path = null, Settings settings = null) public static bool SaveSettings(string path = null, ClientSettings settings = null)
{ {
try try
{ {
path = path ?? SettingsPath; path = path ?? SettingsPath;
settings = settings ?? Main.Settings; settings = settings ?? Settings;
Directory.CreateDirectory(Directory.GetParent(path).FullName); Directory.CreateDirectory(Directory.GetParent(path).FullName);
File.WriteAllText(path, JsonSerialize(settings)); File.WriteAllText(path, JsonSerialize(settings));

View File

@ -35,7 +35,7 @@ namespace RageCoop.Client
Yield(); Yield();
Notification.Show(NotificationIcon.AllPlayersConf, "RAGECOOP", "Welcome!", Notification.Show(NotificationIcon.AllPlayersConf, "RAGECOOP", "Welcome!",
$"Press ~g~{Main.Settings.MenuKey}~s~ to open the menu."); $"Press ~g~{Settings.MenuKey}~s~ to open the menu.");
} }
protected override void OnTick() protected override void OnTick()
{ {
@ -57,12 +57,12 @@ namespace RageCoop.Client
Game.DisableControlThisFrame(Control.FrontendPause); Game.DisableControlThisFrame(Control.FrontendPause);
if (Main.Settings.DisableAlternatePause) Game.DisableControlThisFrame(Control.FrontendPauseAlternate); if (Settings.DisableAlternatePause) Game.DisableControlThisFrame(Control.FrontendPauseAlternate);
// Sets a value that determines how aggressive the ocean waves will be. // Sets a value that determines how aggressive the ocean waves will be.
// Values of 2.0 or more make for very aggressive waves like you see during a thunderstorm. // Values of 2.0 or more make for very aggressive waves like you see during a thunderstorm.
Call(SET_DEEP_OCEAN_SCALER, 0.0f); // Works only ~200 meters around the player Call(SET_DEEP_OCEAN_SCALER, 0.0f); // Works only ~200 meters around the player
if (Main.Settings.ShowEntityOwnerName) if (Settings.ShowEntityOwnerName)
unsafe unsafe
{ {
int handle; int handle;

View File

@ -7,15 +7,17 @@ namespace RageCoop.Core
{ {
internal class CoopPeer : NetPeer, IDisposable internal class CoopPeer : NetPeer, IDisposable
{ {
private readonly Thread ListenerThread; private readonly Logger Log;
private readonly Thread _receiver;
private bool _stopping; private bool _stopping;
public EventHandler<NetIncomingMessage> OnMessageReceived; public EventHandler<NetIncomingMessage> OnMessageReceived;
public CoopPeer(NetPeerConfiguration config) : base(config) public CoopPeer(NetPeerConfiguration config,Logger logger) : base(config)
{ {
Log = logger;
Start(); Start();
NetIncomingMessage msg; NetIncomingMessage msg;
ListenerThread = new Thread(() => _receiver = new Thread(() =>
{ {
while (!_stopping) while (!_stopping)
{ {
@ -23,7 +25,7 @@ namespace RageCoop.Core
if (msg != null) OnMessageReceived?.Invoke(this, msg); if (msg != null) OnMessageReceived?.Invoke(this, msg);
} }
}); });
ListenerThread.Start(); _receiver.Start();
} }
/// <summary> /// <summary>
@ -32,9 +34,18 @@ namespace RageCoop.Core
public void Dispose() public void Dispose()
{ {
_stopping = true; _stopping = true;
Shutdown("Bye!"); if (Status == NetPeerStatus.Running)
ListenerThread.Join(); {
Shutdown("Bye!");
}
if (_receiver.IsAlive)
{
Log?.Debug("Stopping message thread");
_receiver.Join();
}
Log?.Debug("Stopping network thread");
Join(); Join();
Log?.Debug("CoopPeer disposed");
} }
public void SendTo(Packet p, NetConnection connection, ConnectionChannel channel = ConnectionChannel.Default, public void SendTo(Packet p, NetConnection connection, ConnectionChannel channel = ConnectionChannel.Default,

View File

@ -1,4 +1,5 @@
using System; using Newtonsoft.Json;
using System;
using System.IO; using System.IO;
namespace RageCoop.Core.Scripting namespace RageCoop.Core.Scripting
@ -20,6 +21,7 @@ namespace RageCoop.Core.Scripting
/// <summary> /// <summary>
/// Get a stream that can be used to read file content. /// Get a stream that can be used to read file content.
/// </summary> /// </summary>
[JsonIgnore]
public Func<Stream> GetStream { get; internal set; } public Func<Stream> GetStream { get; internal set; }
} }
} }