API remoting

This commit is contained in:
sardelka9515
2022-10-08 23:49:48 +08:00
parent 54c7f4ce92
commit 5585876005
34 changed files with 41235 additions and 262 deletions

View File

@ -1,4 +1,5 @@
using System;
using RageCoop.Core;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -11,7 +12,6 @@ using System.Windows.Input;
using MessageBox = System.Windows.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
using Path = System.IO.Path;
using RageCoop.Core;
namespace RageCoop.Client.Installer
{

View File

@ -1,5 +1,6 @@
using GTA;
using GTA.Math;
using RageCoop.Client.Scripting;
using System;
using System.Drawing;
using System.Threading;
@ -16,6 +17,7 @@ namespace RageCoop.Client
public static MuzzleDir Direction = MuzzleDir.Forward;
public DevTool()
{
if (!Main.IsPrimaryDomain) { return; }
Tick += OnTick;
KeyDown += OnKeyDown;
}
@ -75,7 +77,6 @@ namespace RageCoop.Client
}
private void OnTick(object sender, EventArgs e)
{
if (!Util.ShouldBeRunning) { Abort(); }
if (ToMark == null || !ToMark.Exists()) { return; }
Update();
Draw(Current);

View File

@ -21,6 +21,8 @@ namespace RageCoop.Client
/// </summary>
internal class Main : Script
{
public static bool IsPrimaryDomain => (AppDomain.CurrentDomain.GetData("Primary") as bool?) != false;
public static API API = API.GetInstance();
private static bool _gameLoaded = false;
internal static Version Version = typeof(Main).Assembly.GetName().Version;
@ -29,7 +31,7 @@ namespace RageCoop.Client
internal static RelationshipGroup SyncedPedsGroup;
internal static new Settings Settings = null;
internal static Scripting.BaseScript BaseScript = new Scripting.BaseScript();
internal static BaseScript BaseScript = new BaseScript();
#if !NON_INTERACTIVE
#endif
@ -38,18 +40,18 @@ namespace RageCoop.Client
internal static Logger Logger = null;
internal static ulong Ticked = 0;
internal static Vector3 PlayerPosition;
internal static Scripting.Resources Resources = null;
internal static Resources Resources = null;
private static readonly ConcurrentQueue<Action> TaskQueue = new ConcurrentQueue<Action>();
private static readonly List<Func<bool>> QueuedActions = new List<Func<bool>>();
public static Worker Worker;
public static string ScriptPath;
internal static SHVDN.Console Console => AppDomain.CurrentDomain.GetData("Console") as SHVDN.Console;
/// <summary>
/// Don't use it!
/// </summary>
public Main()
{
ScriptPath = Filename;
if (!Util.ShouldBeRunning) { return; }
Console.PrintInfo($"Starting {typeof(Main).FullName}, domain: {AppDomain.CurrentDomain.Id}, {IsPrimaryDomain}");
if (!IsPrimaryDomain) { Console.PrintInfo("Ignored loading in scondary domain"); return; }
try
{
Settings = Util.ReadSettings();
@ -106,6 +108,7 @@ namespace RageCoop.Client
Util.NativeMemory();
Counter.Restart();
}
private static void OnAborted(object sender, EventArgs e)
@ -115,7 +118,7 @@ namespace RageCoop.Client
ResourceDomain.Unload();
SHVDN.ScriptDomain.CurrentDomain.Tick -= DomainTick;
}
catch(Exception ex)
catch (Exception ex)
{
Logger.Error(ex);
}
@ -123,13 +126,13 @@ namespace RageCoop.Client
private static void DomainTick(object sender, EventArgs e)
{
while(TaskQueue.TryDequeue(out var task))
while (TaskQueue.TryDequeue(out var task))
{
try
{
task.Invoke();
}
catch(Exception ex)
catch (Exception ex)
{
Logger.Error(ex);
}
@ -221,7 +224,7 @@ namespace RageCoop.Client
}
else if (P.IsDead && !_lastDead)
{
Scripting.API.Events.InvokePlayerDied();
API.Events.InvokePlayerDied();
}
_lastDead = P.IsDead;

View File

@ -1,5 +1,6 @@
using GTA.UI;
using Lidgren.Network;
using RageCoop.Client.Scripting;
using RageCoop.Core;
using System;
using System.Collections.Generic;
@ -12,6 +13,7 @@ namespace RageCoop.Client
{
internal static partial class Networking
{
static API API = Main.API;
public static CoopPeer Peer;
public static float Latency => ServerConnection.AverageRoundtripTime / 2;
public static bool ShowNetworkInfo = false;

View File

@ -266,13 +266,13 @@ namespace RageCoop.Client
recycle = false;
Main.QueueAction(() =>
{
Scripting.API.Events.InvokeCustomEventReceived(packet);
API.Events.InvokeCustomEventReceived(packet);
Peer.Recycle(msg);
});
}
else
{
Scripting.API.Events.InvokeCustomEventReceived(packet);
API.Events.InvokeCustomEventReceived(packet);
}
}
break;

View File

@ -90,9 +90,9 @@ namespace RageCoop.Client
Blip b;
if (sp.IsPlayer)
{
p.BlipColor = Scripting.API.Config.BlipColor;
p.BlipSprite = Scripting.API.Config.BlipSprite;
p.BlipScale = Scripting.API.Config.BlipScale;
p.BlipColor = API.Config.BlipColor;
p.BlipSprite = API.Config.BlipSprite;
p.BlipScale = API.Config.BlipScale;
}
else if ((b = ped.AttachedBlip) != null)
{

View File

@ -2,6 +2,7 @@
using GTA.Math;
using GTA.Native;
using Lidgren.Network;
using RageCoop.Client.Scripting;
using RageCoop.Core;
using System.Collections.Generic;
using System.Linq;
@ -11,6 +12,7 @@ namespace RageCoop.Client
{
internal static class PlayerList
{
static readonly API API = Main.API;
private const float LEFT_POSITION = 0.122f;
private const float RIGHT_POSITION = 0.9f;
private static readonly Scaleform _mainScaleform = new Scaleform("mp_mm_card_freemode");
@ -95,9 +97,9 @@ namespace RageCoop.Client
}
else
{
p.FakeBlip.Color = Scripting.API.Config.BlipColor;
p.FakeBlip.Scale = Scripting.API.Config.BlipScale;
p.FakeBlip.Sprite = Scripting.API.Config.BlipSprite;
p.FakeBlip.Color = API.Config.BlipColor;
p.FakeBlip.Scale = API.Config.BlipScale;
p.FakeBlip.Sprite = API.Config.BlipSprite;
p.FakeBlip.DisplayType = BlipDisplayType.Default;
p.FakeBlip.Position = p.Position;
}

View File

@ -16,7 +16,7 @@ using System.Resources;
// Version informationr(
[assembly: AssemblyVersion("1.5.4.105")]
[assembly: AssemblyFileVersion("1.5.4.105")]
[assembly: AssemblyVersion("1.5.4.141")]
[assembly: AssemblyFileVersion("1.5.4.141")]
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]

View File

@ -23,185 +23,213 @@ namespace RageCoop.Client.Scripting
/// </summary>
public object[] Args { get; set; }
}
/// <summary>
/// Client configuration, this will conflict with server-side config.
/// </summary>
public class ClientConfig
{
/// <summary>
/// Get or set local player's username, set won't be effective if already connected to a server.
/// </summary>
public string Username
{
get => Main.Settings.Username;
set
{
if (Networking.IsOnServer || string.IsNullOrEmpty(value))
{
return;
}
Main.Settings.Username = value;
}
}
/// <summary>
/// Enable automatic respawn for this player.
/// </summary>
public bool EnableAutoRespawn { get; set; } = true;
/// <summary>
/// Get or set player's blip color
/// </summary>
public BlipColor BlipColor { get; set; } = BlipColor.White;
/// <summary>
/// Get or set player's blip sprite
/// </summary>
public BlipSprite BlipSprite { get; set; } = BlipSprite.Standard;
/// <summary>
/// Get or set scale of player's blip
/// </summary>
public float BlipScale { get; set; } = 1;
}
/// <summary>
/// Base events for RageCoop
/// </summary>
public class ClientEvents
{
internal Dictionary<int, List<Action<CustomEventReceivedArgs>>> CustomEventHandlers = new Dictionary<int, List<Action<CustomEventReceivedArgs>>>();
#region DELEGATES
/// <summary>
///
/// </summary>
public delegate void EmptyEvent();
/// <summary>
///
/// </summary>
/// <param name="hash"></param>
/// <param name="args"></param>
public delegate void CustomEvent(int hash, List<object> args);
#endregion
/// <summary>
/// The local player is dead
/// </summary>
public event EmptyEvent OnPlayerDied;
/// <summary>
/// A local vehicle is spawned
/// </summary>
public event EventHandler<SyncedVehicle> OnVehicleSpawned;
/// <summary>
/// A local vehicle is deleted
/// </summary>
public event EventHandler<SyncedVehicle> OnVehicleDeleted;
/// <summary>
/// A local ped is spawned
/// </summary>
public event EventHandler<SyncedPed> OnPedSpawned;
/// <summary>
/// A local ped is deleted
/// </summary>
public event EventHandler<SyncedPed> OnPedDeleted;
/// <summary>
/// This is equivalent of <see cref="GTA.Script.Tick"/>.
/// </summary>
public event EmptyEvent OnTick;
/// <summary>
/// This is equivalent of <see cref="Script.KeyDown"/>
/// </summary>
public KeyEventHandler OnKeyDown;
/// <summary>
/// This is equivalent of <see cref="Script.KeyUp"/>
/// </summary>
public KeyEventHandler OnKeyUp;
#region INVOKE
internal void InvokeVehicleSpawned(SyncedVehicle v) { OnVehicleSpawned?.Invoke(null, v); }
internal void InvokeVehicleDeleted(SyncedVehicle v) { OnVehicleDeleted?.Invoke(null, v); }
internal void InvokePedSpawned(SyncedPed p) { OnPedSpawned?.Invoke(null, p); }
internal void InvokePedDeleted(SyncedPed p) { OnPedDeleted?.Invoke(null, p); }
internal void InvokePlayerDied() { OnPlayerDied?.Invoke(); }
internal void InvokeTick() { OnTick?.Invoke(); }
internal void InvokeKeyDown(object s, KeyEventArgs e) { OnKeyDown?.Invoke(s, e); }
internal void InvokeKeyUp(object s, KeyEventArgs e) { OnKeyUp?.Invoke(s, e); }
internal void InvokeCustomEventReceived(Packets.CustomEvent p)
{
var args = new CustomEventReceivedArgs() { Hash = p.Hash, Args = p.Args };
// Main.Logger.Debug($"CustomEvent:\n"+args.Args.DumpWithType());
if (CustomEventHandlers.TryGetValue(p.Hash, out List<Action<CustomEventReceivedArgs>> handlers))
{
handlers.ForEach((x) => { x.Invoke(args); });
}
}
#endregion
}
/// <summary>
/// Provides vital functionality to interact with RAGECOOP
/// </summary>
public class API
public class API : MarshalByRefObject
{
#region INTERNAL
internal static Dictionary<int, List<Action<CustomEventReceivedArgs>>> CustomEventHandlers = new Dictionary<int, List<Action<CustomEventReceivedArgs>>>();
#endregion
static API Instance;
private API() { }
/// <summary>
/// Client configuration, this will conflict with server-side config.
/// Get an instance to bridge data between domains
/// </summary>
public static class Config
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public static API GetInstance()
{
/// <summary>
/// Get or set local player's username, set won't be effective if already connected to a server.
/// </summary>
public static string Username
if (Instance != null) { return Instance; }
if (Main.IsPrimaryDomain)
{
get => Main.Settings.Username;
set
{
if (Networking.IsOnServer || string.IsNullOrEmpty(value))
{
return;
}
Main.Settings.Username = value;
}
Instance = new API();
}
/// <summary>
/// Enable automatic respawn for this player.
/// </summary>
public static bool EnableAutoRespawn { get; set; } = true;
/// <summary>
/// Get or set player's blip color
/// </summary>
public static BlipColor BlipColor { get; set; } = BlipColor.White;
/// <summary>
/// Get or set player's blip sprite
/// </summary>
public static BlipSprite BlipSprite { get; set; } = BlipSprite.Standard;
/// <summary>
/// Get or set scale of player's blip
/// </summary>
public static float BlipScale { get; set; } = 1;
}
/// <summary>
/// Base events for RageCoop
/// </summary>
public static class Events
{
#region DELEGATES
/// <summary>
///
/// </summary>
public delegate void EmptyEvent();
/// <summary>
///
/// </summary>
/// <param name="hash"></param>
/// <param name="args"></param>
public delegate void CustomEvent(int hash, List<object> args);
#endregion
/// <summary>
/// The local player is dead
/// </summary>
public static event EmptyEvent OnPlayerDied;
/// <summary>
/// A local vehicle is spawned
/// </summary>
public static event EventHandler<SyncedVehicle> OnVehicleSpawned;
/// <summary>
/// A local vehicle is deleted
/// </summary>
public static event EventHandler<SyncedVehicle> OnVehicleDeleted;
/// <summary>
/// A local ped is spawned
/// </summary>
public static event EventHandler<SyncedPed> OnPedSpawned;
/// <summary>
/// A local ped is deleted
/// </summary>
public static event EventHandler<SyncedPed> OnPedDeleted;
/// <summary>
/// This is equivalent of <see cref="GTA.Script.Tick"/>.
/// </summary>
public static event EmptyEvent OnTick;
/// <summary>
/// This is equivalent of <see cref="Script.KeyDown"/>
/// </summary>
public static KeyEventHandler OnKeyDown;
/// <summary>
/// This is equivalent of <see cref="Script.KeyUp"/>
/// </summary>
public static KeyEventHandler OnKeyUp;
#region INVOKE
internal static void InvokeVehicleSpawned(SyncedVehicle v) { OnVehicleSpawned?.Invoke(null, v); }
internal static void InvokeVehicleDeleted(SyncedVehicle v) { OnVehicleDeleted?.Invoke(null, v); }
internal static void InvokePedSpawned(SyncedPed p) { OnPedSpawned?.Invoke(null, p); }
internal static void InvokePedDeleted(SyncedPed p) { OnPedDeleted?.Invoke(null, p); }
internal static void InvokePlayerDied() { OnPlayerDied?.Invoke(); }
internal static void InvokeTick() { OnTick?.Invoke(); }
internal static void InvokeKeyDown(object s, KeyEventArgs e) { OnKeyDown?.Invoke(s, e); }
internal static void InvokeKeyUp(object s, KeyEventArgs e) { OnKeyUp?.Invoke(s, e); }
internal static void InvokeCustomEventReceived(Packets.CustomEvent p)
else
{
var args = new CustomEventReceivedArgs() { Hash = p.Hash, Args = p.Args };
// Main.Logger.Debug($"CustomEvent:\n"+args.Args.DumpWithType());
if (CustomEventHandlers.TryGetValue(p.Hash, out List<Action<CustomEventReceivedArgs>> handlers))
{
handlers.ForEach((x) => { x.Invoke(args); });
}
Instance = AppDomain.CurrentDomain.GetData("RageCoop.Client.API") as API;
}
#endregion
return Instance;
}
public ClientEvents Events = new ClientEvents();
public ClientConfig Config = new ClientConfig();
#region PROPERTIES
/// <summary>
/// Get the local player's ID
/// </summary>
/// <returns>PlayerID</returns>
public static int LocalPlayerID => Main.LocalPlayerID;
public int LocalPlayerID => Main.LocalPlayerID;
/// <summary>
/// Check if player is connected to a server
/// </summary>
public static bool IsOnServer => Networking.IsOnServer;
public bool IsOnServer => Networking.IsOnServer;
/// <summary>
/// Get an <see cref="System.Net.IPEndPoint"/> that the player is currently connected to, or null if not connected to the server
/// </summary>
public static System.Net.IPEndPoint ServerEndPoint => Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null;
public System.Net.IPEndPoint ServerEndPoint => Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null;
/// <summary>
/// Check if a RAGECOOP menu is visible
/// </summary>
public static bool IsMenuVisible => Menus.CoopMenu.MenuPool.AreAnyVisible;
public bool IsMenuVisible => Menus.CoopMenu.MenuPool.AreAnyVisible;
/// <summary>
/// Check if the RAGECOOP chat is visible
/// </summary>
public static bool IsChatFocused => Main.MainChat.Focused;
public bool IsChatFocused => Main.MainChat.Focused;
/// <summary>
/// Check if the RAGECOOP list of players is visible
/// </summary>
public static bool IsPlayerListVisible => Util.GetTickCount64() - PlayerList.Pressed < 5000;
public bool IsPlayerListVisible => Util.GetTickCount64() - PlayerList.Pressed < 5000;
/// <summary>
/// Get the version of RAGECOOP
/// </summary>
public static Version CurrentVersion => Main.Version;
public Version CurrentVersion => Main.Version;
/// <summary>
/// Get a <see cref="Core.Logger"/> that RAGECOOP is currently using.
/// </summary>
/// <returns></returns>
public static Logger Logger => Main.Logger;
public Logger Logger => Main.Logger;
/// <summary>
/// Get all players indexed by their ID
/// </summary>
public static Dictionary<int, Player> Players => new Dictionary<int, Player>(PlayerList.Players);
public Dictionary<int, Player> Players => new Dictionary<int, Player>(PlayerList.Players);
#endregion
@ -211,7 +239,7 @@ namespace RageCoop.Client.Scripting
/// </summary>
/// <param name="address">Address of the server, e.g. 127.0.0.1:4499</param>
/// <exception cref="InvalidOperationException">When a connection is active or being established</exception>
public static void Connect(string address)
public void Connect(string address)
{
if (Networking.IsOnServer || Networking.IsConnecting)
{
@ -222,7 +250,7 @@ namespace RageCoop.Client.Scripting
/// <summary>
/// Disconnect from current server or cancel the connection attempt.
/// </summary>
public static void Disconnect()
public void Disconnect()
{
if (Networking.IsOnServer || Networking.IsConnecting)
{
@ -234,7 +262,7 @@ namespace RageCoop.Client.Scripting
/// List all servers from master server address
/// </summary>
/// <returns></returns>
public static List<ServerInfo> ListServers()
public List<ServerInfo> ListServers()
{
return JsonConvert.DeserializeObject<List<ServerInfo>>(HttpHelper.DownloadString(Main.Settings.MasterServer));
}
@ -244,7 +272,7 @@ namespace RageCoop.Client.Scripting
/// </summary>
/// <param name="from">Name of the sender</param>
/// <param name="message">The player's message</param>
public static void LocalChatMessage(string from, string message)
public void LocalChatMessage(string from, string message)
{
Main.MainChat.AddMessage(from, message);
}
@ -253,7 +281,7 @@ namespace RageCoop.Client.Scripting
/// Send a chat message or command to server/other players
/// </summary>
/// <param name="message"></param>
public static void SendChatMessage(string message)
public void SendChatMessage(string message)
{
Networking.SendChatMessage(message);
}
@ -262,7 +290,7 @@ namespace RageCoop.Client.Scripting
/// Queue an action to be executed on next tick.
/// </summary>
/// <param name="a"></param>
public static void QueueAction(Action a)
public void QueueAction(Action a)
{
Main.QueueAction(a);
}
@ -271,7 +299,7 @@ namespace RageCoop.Client.Scripting
/// Queue an action to be executed on next tick, allowing you to call scripting API from another thread.
/// </summary>
/// <param name="a"> An <see cref="Func{T, TResult}"/> to be executed with a return value indicating whether it can be removed after execution.</param>
public static void QueueAction(Func<bool> a)
public void QueueAction(Func<bool> a)
{
Main.QueueAction(a);
}
@ -281,7 +309,7 @@ namespace RageCoop.Client.Scripting
/// </summary>
/// <param name="eventHash">An unique identifier of the event</param>
/// <param name="args">The objects conataing your data, see <see cref="CustomEventReceivedArgs"/> for a list of supported types</param>
public static void SendCustomEvent(CustomEventHash eventHash, params object[] args)
public void SendCustomEvent(CustomEventHash eventHash, params object[] args)
{
Networking.Peer.SendTo(new Packets.CustomEvent()
@ -296,7 +324,7 @@ namespace RageCoop.Client.Scripting
/// <param name="flags"></param>
/// <param name="eventHash">An unique identifier of the event</param>
/// <param name="args">The objects conataing your data, see <see cref="CustomEventReceivedArgs"/> for a list of supported types</param>
public static void SendCustomEvent(CustomEventFlags flags,CustomEventHash eventHash, params object[] args)
public void SendCustomEvent(CustomEventFlags flags, CustomEventHash eventHash, params object[] args)
{
Networking.Peer.SendTo(new Packets.CustomEvent(flags)
{
@ -310,13 +338,13 @@ namespace RageCoop.Client.Scripting
/// </summary>
/// <param name="hash">An unique identifier of the event, you can hash your event name with <see cref="Core.Scripting.CustomEvents.Hash(string)"/></param>
/// <param name="handler">An handler to be invoked when the event is received from the server. </param>
public static void RegisterCustomEventHandler(CustomEventHash hash, Action<CustomEventReceivedArgs> handler)
public void RegisterCustomEventHandler(CustomEventHash hash, Action<CustomEventReceivedArgs> handler)
{
lock (CustomEventHandlers)
lock (Events.CustomEventHandlers)
{
if (!CustomEventHandlers.TryGetValue(hash, out List<Action<CustomEventReceivedArgs>> handlers))
if (!Events.CustomEventHandlers.TryGetValue(hash, out List<Action<CustomEventReceivedArgs>> handlers))
{
CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
Events.CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
}
handlers.Add(handler);
}
@ -326,7 +354,7 @@ namespace RageCoop.Client.Scripting
///
/// </summary>
/// <returns></returns>
public static void RequestSharedFile(string name, Action<string> callback)
public void RequestSharedFile(string name, Action<string> callback)
{
EventHandler<string> handler = (s, e) =>
{

View File

@ -11,6 +11,7 @@ namespace RageCoop.Client.Scripting
{
internal class BaseScript : ClientScript
{
readonly API API = Main.API;
private bool _isHost = false;
public override void OnStart()
{

View File

@ -1,41 +1,41 @@
using System;
using System.Collections.Generic;
using SHVDN;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SHVDN;
using RageCoop.Core;
using GTA.Native;
using System.Reflection;
using System.Windows.Forms;
namespace RageCoop.Client.Scripting
{
public class ResourceDomain : MarshalByRefObject, IDisposable
internal class ResourceDomain : MarshalByRefObject, IDisposable
{
public static ResourceDomain Instance;
readonly ScriptDomain RootDomain;
ScriptDomain CurrentDomain => ScriptDomain.CurrentDomain;
internal ResourceDomain(ScriptDomain root)
public static ScriptDomain PrimaryDomain;
public static string blah = "blah";
private ScriptDomain CurrentDomain => ScriptDomain.CurrentDomain;
private ResourceDomain(ScriptDomain primary)
{
RootDomain = root;
PrimaryDomain = primary;
// Bridge to current ScriptDomain
root.Tick += Tick;
root.KeyEvent += KeyEvent;
primary.Tick += Tick;
primary.KeyEvent += KeyEvent;
AppDomain.CurrentDomain.SetData("Primary",false);
Main.Console.PrintInfo("Loaded scondary domain: " + AppDomain.CurrentDomain.Id + " " + Main.IsPrimaryDomain);
}
public static void Load()
public static void Load(string dir = @"RageCoop\Scripts")
{
if (Instance != null)
{
throw new Exception("Already loaded");
}
else if (!Main.IsPrimaryDomain)
{
throw new InvalidOperationException("Cannot load in another domain");
}
ScriptDomain domain = null;
try
{
var dir = Path.GetFullPath(@"RageCoop\Scripts");
dir = Path.GetFullPath(dir);
if (Directory.Exists(dir))
{
@ -63,7 +63,8 @@ namespace RageCoop.Client.Scripting
Main.QueueToMainThread(() =>
{
domain = ScriptDomain.Load(Directory.GetParent(typeof(ScriptDomain).Assembly.Location).FullName, dir);
domain.AppDomain.SetData("Console",ScriptDomain.CurrentDomain.AppDomain.GetData("Console"));
domain.AppDomain.SetData("Console", ScriptDomain.CurrentDomain.AppDomain.GetData("Console"));
domain.AppDomain.SetData("RageCoop.Client.API", API.GetInstance());
Instance = (ResourceDomain)domain.AppDomain.CreateInstanceFromAndUnwrap(typeof(ResourceDomain).Assembly.Location, typeof(ResourceDomain).FullName, false, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { ScriptDomain.CurrentDomain }, null, null);
domain.Start();
});
@ -81,6 +82,7 @@ namespace RageCoop.Client.Scripting
}
}
}
public static void Unload()
{
if (Instance == null)
@ -91,19 +93,21 @@ namespace RageCoop.Client.Scripting
ScriptDomain.Unload(Instance.CurrentDomain);
Instance = null;
}
void Tick(object sender, EventArgs args)
private void Tick(object sender, EventArgs args)
{
CurrentDomain.DoTick();
}
void KeyEvent(Keys keys, bool status)
private void KeyEvent(Keys keys, bool status)
{
CurrentDomain.DoKeyEvent(keys, status);
}
public void Dispose()
{
RootDomain.Tick -= Tick;
RootDomain.KeyEvent -= KeyEvent;
PrimaryDomain.Tick -= Tick;
PrimaryDomain.KeyEvent -= KeyEvent;
}
}
}

View File

@ -38,6 +38,7 @@ namespace RageCoop.Client.Scripting
}
internal class Resources
{
static readonly API API = Main.API;
private readonly List<ClientResource> LoadedResources = new List<ClientResource>();
private const string BaseScriptType = "RageCoop.Client.Scripting.ClientScript";
private Logger Logger { get; set; }

View File

@ -145,7 +145,7 @@ namespace RageCoop.Client
private string LoadAnim(string anim)
{
if(!Function.Call<bool>(Hash.HAS_ANIM_DICT_LOADED, anim))
if (!Function.Call<bool>(Hash.HAS_ANIM_DICT_LOADED, anim))
{
Function.Call(Hash.REQUEST_ANIM_DICT, anim);
return null;

View File

@ -11,6 +11,7 @@ namespace RageCoop.Client
{
internal class EntityPool
{
static readonly API API = Main.API;
public static object PedsLock = new object();
#if BENCHMARK
private static Stopwatch PerfCounter=new Stopwatch();

View File

@ -1,9 +1,4 @@
using GTA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RageCoop.Client
{

View File

@ -1,6 +1,7 @@
using GTA;
using GTA.Math;
using GTA.Native;
using mscoree;
using RageCoop.Core;
using System;
using System.Collections.Generic;
@ -11,15 +12,12 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Xml.Serialization;
using mscoree;
using System.Runtime.InteropServices.ComTypes;
[assembly: InternalsVisibleTo("RageCoop.Client.Installer")]
namespace RageCoop.Client
{
internal static class Util
{
public static bool ShouldBeRunning => Main.ScriptPath == null || Main.ScriptPath.ToLower() == Path.Combine(Directory.GetCurrentDirectory(), @"Scripts\RageCoop\RageCoop.Client.dll").ToLower();
public static IList<AppDomain> GetAppDomains()
{
IList<AppDomain> _IList = new List<AppDomain>();
@ -186,8 +184,8 @@ namespace RageCoop.Client
}
catch (Exception ex)
{
Main.Logger?.Error(ex);
return false;
// GTA.UI.Notification.Show("Error saving player settings: " + ex.Message);
}
}

View File

@ -1,5 +1,6 @@
using GTA;
using GTA.Native;
using RageCoop.Client.Scripting;
using System;
namespace RageCoop.Client
@ -7,7 +8,7 @@ namespace RageCoop.Client
/// <summary>
/// Don't use it!
/// </summary>
public class WorldThread : Script
internal class WorldThread : Script
{
/// <summary>
@ -15,6 +16,7 @@ namespace RageCoop.Client
/// </summary>
public WorldThread()
{
if (!Main.IsPrimaryDomain) { return; }
Tick += OnTick;
Aborted += (sender, e) =>
{
@ -25,7 +27,6 @@ namespace RageCoop.Client
private static bool _trafficEnabled;
private void OnTick(object sender, EventArgs e)
{
if (!Util.ShouldBeRunning) { Abort(); }
if (Game.IsLoading || !Networking.IsOnServer)
{
return;

View File

@ -14,7 +14,6 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
[assembly: InternalsVisibleTo("RageCoop.Server")]
[assembly: InternalsVisibleTo("RageCoop.Client")]
@ -292,7 +291,7 @@ namespace RageCoop.Core
{
return (flags & flag) != 0;
}
public static bool HasEventFlag(this CustomEventFlags flags,CustomEventFlags flag)
public static bool HasEventFlag(this CustomEventFlags flags, CustomEventFlags flag)
{
return (flags & flag) != 0;

View File

@ -1,8 +1,5 @@
using GTA.Math;
using Lidgren.Network;
using System;
using System.Collections.Generic;
using System.Text;
namespace RageCoop.Core
{

View File

@ -1,5 +1,4 @@
using GTA.Native;
using System;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
@ -11,17 +10,17 @@ namespace RageCoop.Core.Scripting
/// </summary>
public enum CustomEventFlags : byte
{
None=0,
None = 0,
/// <summary>
/// Data will be encrypted and decrypted on target client
/// </summary>
Encrypted=1,
Encrypted = 1,
/// <summary>
/// Event will be queued and fired in script thread, specify this flag if your handler will call native functions.
/// </summary>
Queued=2,
Queued = 2,
}

View File

@ -3,7 +3,6 @@ using RageCoop.Core;
using RageCoop.Core.Scripting;
using RageCoop.Server.Scripting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Security.Cryptography;
@ -173,7 +172,7 @@ namespace RageCoop.Server
/// <param name="flags"></param>
/// <param name="hash">An unique identifier of the event</param>
/// <param name="args">Arguments</param>
public void SendCustomEvent(CustomEventFlags flags,CustomEventHash hash, params object[] args)
public void SendCustomEvent(CustomEventFlags flags, CustomEventHash hash, params object[] args)
{
if (!IsReady)
{
@ -197,7 +196,8 @@ namespace RageCoop.Server
Server.Logger?.Error(ex);
}
}
public void SendCustomEventQueued(CustomEventHash hash, params object[] args) {
public void SendCustomEventQueued(CustomEventHash hash, params object[] args)
{
SendCustomEvent(CustomEventFlags.Queued, hash, args);
}
public void SendCustomEvent(CustomEventHash hash, params object[] args)

View File

@ -82,7 +82,7 @@ namespace RageCoop.Server
if (!CanAnnounce)
{
var existing = JsonConvert.DeserializeObject<List<ServerInfo>>(HttpHelper.DownloadString(Util.GetFinalRedirect(Settings.MasterServer))).Where(x => x.address == IpInfo.Address).FirstOrDefault();
if(existing != null)
if (existing != null)
{
Logger.Warning("Server info already present in master server, waiting for 10 seconds...");
return;

View File

@ -2,7 +2,6 @@
using RageCoop.Core;
using RageCoop.Server.Scripting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;

View File

@ -1,7 +1,5 @@

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;
// General Information
@ -15,7 +13,7 @@ using System.Resources;
[assembly: AssemblyCulture("")]
// Version information
[assembly: AssemblyVersion("1.5.4.40")]
[assembly: AssemblyFileVersion("1.5.4.40")]
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
[assembly: AssemblyVersion("1.5.4.41")]
[assembly: AssemblyFileVersion("1.5.4.41")]
[assembly: NeutralResourcesLanguageAttribute("en-US")]

View File

@ -2,7 +2,6 @@
using RageCoop.Core;
using RageCoop.Core.Scripting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

View File

@ -1,6 +1,5 @@
using RageCoop.Core.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
namespace RageCoop.Server.Scripting

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Net;
namespace RageCoop.Server.Scripting

View File

@ -1,7 +1,6 @@
using ICSharpCode.SharpZipLib.Zip;
using RageCoop.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace RageCoop.Server.Scripting

View File

@ -3,7 +3,6 @@ using McMaster.NETCore.Plugins;
using RageCoop.Core;
using RageCoop.Core.Scripting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

View File

@ -1,5 +1,4 @@
using RageCoop.Core;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;

View File

@ -1,19 +0,0 @@
using System;
using GTA;
using GTA.UI;
namespace TestScript
{
public class Test : Script
{
public Test()
{
Tick += OnTick;
}
private void OnTick(object sender, EventArgs e)
{
Screen.ShowHelpTextThisFrame("bruh");
}
}
}

View File

@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutDir>..\bin\Debug</OutDir>
</PropertyGroup>
<ItemGroup>
<Reference Include="ScriptHookVDotNet">
<HintPath>..\libs\ScriptHookVDotNet.dll</HintPath>
</Reference>
<Reference Include="ScriptHookVDotNet3">
<HintPath>..\libs\ScriptHookVDotNet3.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

16293
libs/ScriptHookVDotNet2.xml Normal file

File diff suppressed because it is too large Load Diff

24693
libs/ScriptHookVDotNet3.xml Normal file

File diff suppressed because it is too large Load Diff