API remoting
This commit is contained in:
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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" )]
|
||||
|
||||
|
@ -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) =>
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
|
@ -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,
|
||||
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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")]
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,6 +1,5 @@
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,4 @@
|
||||
using RageCoop.Core;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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
16293
libs/ScriptHookVDotNet2.xml
Normal file
File diff suppressed because it is too large
Load Diff
24693
libs/ScriptHookVDotNet3.xml
Normal file
24693
libs/ScriptHookVDotNet3.xml
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user