blah
This commit is contained in:
@ -59,7 +59,7 @@ namespace RageCoop.Client
|
||||
if (Settings.DataDirectory.StartsWith("Scripts"))
|
||||
{
|
||||
var defaultDir = new Settings().DataDirectory;
|
||||
Console.Warning.WriteLine("Data directory must be outside scripts folder, migrating to default direcoty: "+defaultDir);
|
||||
Console.Warning.WriteLine("Data directory must be outside scripts folder, migrating to default direcoty: " + defaultDir);
|
||||
if (Directory.Exists(Settings.DataDirectory))
|
||||
{
|
||||
CoreUtils.CopyFilesRecursively(new DirectoryInfo(Settings.DataDirectory), new DirectoryInfo(defaultDir));
|
||||
@ -83,9 +83,10 @@ namespace RageCoop.Client
|
||||
#if DEBUG
|
||||
LogLevel = 0,
|
||||
#else
|
||||
LogLevel=Settings.LogLevel,
|
||||
LogLevel = Settings.LogLevel,
|
||||
#endif
|
||||
};
|
||||
Logger.OnFlush += (s, d) => Console.WriteLine(d);
|
||||
Worker = new Worker("RageCoop.Client.Main.Worker", Logger);
|
||||
ScriptDomain.CurrentDomain.Tick += DomainTick;
|
||||
Resources = new Resources();
|
||||
@ -114,7 +115,6 @@ namespace RageCoop.Client
|
||||
Aborted += OnAborted;
|
||||
Tick += OnTick;
|
||||
KeyDown += OnKeyDown;
|
||||
Aborted += (object sender, EventArgs e) => Disconnected("Abort");
|
||||
|
||||
Util.NativeMemory();
|
||||
Counter.Restart();
|
||||
@ -125,11 +125,11 @@ namespace RageCoop.Client
|
||||
{
|
||||
try
|
||||
{
|
||||
WorldThread.DoQueuedActions();
|
||||
WorldThread.Instance?.Abort();
|
||||
DevTool.Instance?.Abort();
|
||||
ResourceDomain.UnloadAll();
|
||||
ScriptDomain.CurrentDomain.Tick -= DomainTick;
|
||||
Disconnected("Abort");
|
||||
WorldThread.DoQueuedActions();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -383,11 +383,11 @@ namespace RageCoop.Client
|
||||
CoopMenu.DisconnectedMenuSetting();
|
||||
GTA.UI.Notification.Show("~r~Disconnected: " + reason);
|
||||
LocalPlayerID = default;
|
||||
Resources.Unload();
|
||||
});
|
||||
Memory.RestorePatches();
|
||||
DownloadManager.Cleanup();
|
||||
Voice.ClearAll();
|
||||
Resources.Unload();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Client.Menus;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
@ -260,19 +261,20 @@ namespace RageCoop.Client
|
||||
case PacketType.CustomEvent:
|
||||
{
|
||||
Packets.CustomEvent packet = new Packets.CustomEvent();
|
||||
packet.Deserialize(msg);
|
||||
if (packet.Flags.HasEventFlag(Core.Scripting.CustomEventFlags.Queued))
|
||||
if (((CustomEventFlags)msg.PeekByte()).HasEventFlag(CustomEventFlags.Queued))
|
||||
{
|
||||
recycle = false;
|
||||
API.QueueAction(() =>
|
||||
{
|
||||
API.Events.InvokeCustomEventReceived(packet);
|
||||
packet.Deserialize(msg);
|
||||
Scripting.API.Events.InvokeCustomEventReceived(packet);
|
||||
Peer.Recycle(msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
API.Events.InvokeCustomEventReceived(packet);
|
||||
packet.Deserialize(msg);
|
||||
Scripting.API.Events.InvokeCustomEventReceived(packet);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -16,7 +16,7 @@ using System.Resources;
|
||||
|
||||
|
||||
// Version informationr(
|
||||
[assembly: AssemblyVersion("1.5.4.186")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.186")]
|
||||
[assembly: AssemblyVersion("1.5.4.244")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.244")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -3,9 +3,11 @@ using GTA;
|
||||
using Newtonsoft.Json;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using SHVDN;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RageCoop.Client.Scripting
|
||||
@ -29,7 +31,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// <summary>
|
||||
/// Client configuration, this will conflict with server-side config.
|
||||
/// </summary>
|
||||
public class ClientConfig
|
||||
public class ClientConfig : MarshalByRefObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Get or set local player's username, set won't be effective if already connected to a server.
|
||||
@ -72,7 +74,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// <summary>
|
||||
/// Base events for RageCoop
|
||||
/// </summary>
|
||||
public class ClientEvents
|
||||
public class ClientEvents : MarshalByRefObject
|
||||
{
|
||||
internal Dictionary<int, List<Action<CustomEventReceivedArgs>>> CustomEventHandlers = new Dictionary<int, List<Action<CustomEventReceivedArgs>>>();
|
||||
|
||||
@ -130,6 +132,11 @@ namespace RageCoop.Client.Scripting
|
||||
{
|
||||
handlers.ForEach((x) => { x.Invoke(args); });
|
||||
}
|
||||
|
||||
if (Util.IsPrimaryDomain)
|
||||
{
|
||||
ResourceDomain.DoCallBack("CustomEvent",p);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@ -139,6 +146,16 @@ namespace RageCoop.Client.Scripting
|
||||
/// </summary>
|
||||
public class API : MarshalByRefObject
|
||||
{
|
||||
static API()
|
||||
{
|
||||
if (!Util.IsPrimaryDomain)
|
||||
{
|
||||
ResourceDomain.RegisterCallBackForCurrentDomain("CustomEvent",
|
||||
(data) => {
|
||||
Events.InvokeCustomEventReceived(data as Packets.CustomEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
static API Instance;
|
||||
private API() { }
|
||||
|
||||
@ -161,7 +178,7 @@ namespace RageCoop.Client.Scripting
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public ClientEvents Events = new ClientEvents();
|
||||
public static ClientEvents Events = new ClientEvents();
|
||||
public ClientConfig Config = new ClientConfig();
|
||||
|
||||
#region PROPERTIES
|
||||
@ -217,7 +234,8 @@ namespace RageCoop.Client.Scripting
|
||||
#region FUNCTIONS
|
||||
public ClientResource GetResource(string name)
|
||||
{
|
||||
if(Main.Resources.LoadedResources.TryGetValue(name.ToLower(), out var res)){
|
||||
if (Main.Resources.LoadedResources.TryGetValue(name.ToLower(), out var res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
@ -282,12 +300,28 @@ namespace RageCoop.Client.Scripting
|
||||
{
|
||||
WorldThread.QueueAction(a);
|
||||
}
|
||||
public void QueueActionAndWait(Action a, int timeout = 15000)
|
||||
{
|
||||
var done = new AutoResetEvent(false);
|
||||
Exception e = null;
|
||||
QueueAction(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
a();
|
||||
done.Set();
|
||||
}
|
||||
catch (Exception ex) { e = ex; }
|
||||
});
|
||||
if (e != null) { throw e; }
|
||||
else if (!done.WaitOne(timeout)) { throw new TimeoutException(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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 void QueueAction(Func<bool> a)
|
||||
public static void QueueAction(Func<bool> a)
|
||||
{
|
||||
WorldThread.QueueAction(a);
|
||||
}
|
||||
@ -321,22 +355,6 @@ namespace RageCoop.Client.Scripting
|
||||
}, Networking.ServerConnection, ConnectionChannel.Event, Lidgren.Network.NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register an handler to the specifed event hash, one event can have multiple handlers. This will be invoked from backgound thread, use <see cref="QueueAction(Action)"/> in the handler to dispatch code to script thread.
|
||||
/// </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 void RegisterCustomEventHandler(CustomEventHash hash, Action<CustomEventReceivedArgs> handler)
|
||||
{
|
||||
lock (Events.CustomEventHandlers)
|
||||
{
|
||||
if (!Events.CustomEventHandlers.TryGetValue(hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
Events.CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
|
||||
}
|
||||
handlers.Add(handler);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -365,6 +383,17 @@ namespace RageCoop.Client.Scripting
|
||||
}
|
||||
});
|
||||
}
|
||||
public static void RegisterCustomEventHandler(CustomEventHash hash, Action<CustomEventReceivedArgs> handler)
|
||||
{
|
||||
lock (Events.CustomEventHandlers)
|
||||
{
|
||||
if (!Events.CustomEventHandlers.TryGetValue(hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
Events.CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
|
||||
}
|
||||
handlers.Add(handler);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ namespace RageCoop.Client.Scripting
|
||||
prop.Model = (Model)e.Args[1];
|
||||
prop.Position = (Vector3)e.Args[2];
|
||||
prop.Rotation = (Vector3)e.Args[3];
|
||||
Main.Logger.Debug("Prop: "+ prop.Model.Request(1000));
|
||||
prop.Model.Request(1000);
|
||||
prop.Update();
|
||||
}
|
||||
private void NativeCall(CustomEventReceivedArgs e)
|
||||
|
@ -1,11 +1,11 @@
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Client.Scripting
|
||||
{
|
||||
/// <summary>
|
||||
/// Inherit from this class, constructor will be called automatically, but other scripts might have yet been loaded, you should use <see cref="OnStart"/>. to initiate your script.
|
||||
/// </summary>
|
||||
[GTA.ScriptAttributes(Author = "RageCoop", NoDefaultInstance = true, SupportURL = "https://github.com/RAGECOOP/RAGECOOP-V")]
|
||||
public abstract class ClientScript : GTA.Script
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -19,8 +19,12 @@ namespace RageCoop.Client.Scripting
|
||||
public static ScriptDomain PrimaryDomain;
|
||||
public string BaseDirectory => AppDomain.CurrentDomain.BaseDirectory;
|
||||
private ScriptDomain CurrentDomain => ScriptDomain.CurrentDomain;
|
||||
private static ConcurrentDictionary<string, Action<object>> _callBacks = new ConcurrentDictionary<string, Action<object>>();
|
||||
API API => API.GetInstance();
|
||||
private ResourceDomain(ScriptDomain primary, string[] apiPaths)
|
||||
{
|
||||
|
||||
AppDomain.CurrentDomain.SetData("Primary", primary);
|
||||
foreach (var apiPath in apiPaths)
|
||||
{
|
||||
try
|
||||
@ -33,14 +37,11 @@ namespace RageCoop.Client.Scripting
|
||||
}
|
||||
}
|
||||
PrimaryDomain = primary;
|
||||
|
||||
// Bridge to current ScriptDomain
|
||||
primary.Tick += Tick;
|
||||
primary.KeyEvent += KeyEvent;
|
||||
primary.KeyEvent += KeyEvent;
|
||||
CurrentDomain.Start();
|
||||
SetupScripts();
|
||||
AppDomain.CurrentDomain.SetData("Primary", false);
|
||||
Console.WriteLine("Loaded scondary domain: " + AppDomain.CurrentDomain.Id + " " + Util.IsPrimaryDomain);
|
||||
Console.WriteLine($"Loaded domain: {AppDomain.CurrentDomain.FriendlyName}, {AppDomain.CurrentDomain.BaseDirectory}");
|
||||
}
|
||||
public static bool IsLoaded(string dir)
|
||||
{
|
||||
@ -53,26 +54,50 @@ namespace RageCoop.Client.Scripting
|
||||
|
||||
try
|
||||
{
|
||||
API.Logger.Debug("Starting script: " + s.GetType().FullName);
|
||||
var script = (ClientScript)s;
|
||||
var res = Main.API.GetResource(Path.GetFileName(Directory.GetParent(script.Filename).FullName));
|
||||
if (res == null) { Main.API.Logger.Warning("Failed to locate resource for script: " + script.Filename); continue; }
|
||||
var res = API.GetResource(Path.GetFileName(Directory.GetParent(script.Filename).FullName));
|
||||
if (res == null) { API.Logger.Warning("Failed to locate resource for script: " + script.Filename); continue; }
|
||||
script.CurrentResource = res;
|
||||
script.CurrentFile = res.Files.Values.Where(x => x.Name.ToLower() == script.Filename.Substring(res.BaseDirectory.Length + 1).Replace('\\', '/')).FirstOrDefault();
|
||||
script.CurrentFile = res.Files.Values.Where(x => x.Name.ToLower() == script.Filename.Substring(res.ScriptsDirectory.Length + 1).Replace('\\', '/')).FirstOrDefault();
|
||||
res.Scripts.Add(script);
|
||||
s.GetType().Assembly.GetReferencedAssemblies().ForEach(x => Assembly.Load(x.FullName));
|
||||
script.OnStart();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Main.API.Logger.Error($"Failed to start {s.GetType().FullName}", ex);
|
||||
API.Logger.Error($"Failed to start {s.GetType().FullName}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public object[] GetClientScripts()
|
||||
{
|
||||
Console.WriteLine("Running scripts: " + ScriptDomain.CurrentDomain.RunningScripts.Select(x => x.ScriptInstance.GetType().FullName).Dump());
|
||||
return ScriptDomain.CurrentDomain.RunningScripts.Where(x =>
|
||||
x.ScriptInstance.GetType().IsAssignableFrom(typeof(ClientScript)) &&
|
||||
x.ScriptInstance.GetType().IsSubclassOf(typeof(ClientScript)) &&
|
||||
!x.ScriptInstance.GetType().IsAbstract).Select(x => x.ScriptInstance).ToArray();
|
||||
}
|
||||
public static void RegisterCallBackForCurrentDomain(string name, Action<object> callback)
|
||||
{
|
||||
if (!_callBacks.TryAdd(name, callback))
|
||||
{
|
||||
throw new Exception("Failed to add callback");
|
||||
}
|
||||
}
|
||||
public void DoCallback(string name,object data)
|
||||
{
|
||||
if(_callBacks.TryGetValue(name, out var callBack))
|
||||
{
|
||||
callBack(data);
|
||||
}
|
||||
}
|
||||
public static void DoCallBack(string name,object data)
|
||||
{
|
||||
foreach(var d in _loadedDomains)
|
||||
{
|
||||
d.Value.DoCallback(name, data);
|
||||
}
|
||||
}
|
||||
public static ResourceDomain Load(string dir = @"RageCoop\Scripts\Debug")
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
@ -132,7 +157,7 @@ namespace RageCoop.Client.Scripting
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
Exception ex=null;
|
||||
Exception ex = null;
|
||||
Main.QueueToMainThread(() =>
|
||||
{
|
||||
try
|
||||
@ -141,10 +166,10 @@ namespace RageCoop.Client.Scripting
|
||||
ScriptDomain.Unload(domain.CurrentDomain);
|
||||
_loadedDomains.TryRemove(domain.BaseDirectory, out _);
|
||||
}
|
||||
catch(Exception e) { ex = e; }
|
||||
catch (Exception e) { ex = e; }
|
||||
});
|
||||
GTA.Script.Yield();
|
||||
if(ex != null) { throw ex; }
|
||||
if (ex != null) { throw ex; }
|
||||
}
|
||||
}
|
||||
public static void Unload(string dir)
|
||||
@ -174,19 +199,20 @@ namespace RageCoop.Client.Scripting
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach(var s in GetClientScripts())
|
||||
PrimaryDomain.Tick -= Tick;
|
||||
PrimaryDomain.KeyEvent -= KeyEvent;
|
||||
foreach (var s in GetClientScripts())
|
||||
{
|
||||
try
|
||||
{
|
||||
API.Logger.Debug("Stopping script: " + s.GetType().FullName);
|
||||
((ClientScript)s).OnStop();
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Main.API.Logger.Error($"Failed to stop {s.GetType().FullName}",ex);
|
||||
API.Logger.Error($"Failed to stop {s.GetType().FullName}", ex);
|
||||
}
|
||||
}
|
||||
PrimaryDomain.Tick -= Tick;
|
||||
PrimaryDomain.KeyEvent -= KeyEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,23 +7,27 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Client.Scripting
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ClientResource
|
||||
public class ClientResource : MarshalByRefObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the resource
|
||||
/// </summary>
|
||||
public string Name { get; internal set; }
|
||||
public string BaseDirectory { get; internal set; }
|
||||
/// <summary>
|
||||
/// Directory where the scripts is loaded from
|
||||
/// </summary>
|
||||
public string ScriptsDirectory { get; internal set; }
|
||||
/// <summary>
|
||||
/// A resource-specific folder that can be used to store your files.
|
||||
/// </summary>
|
||||
public string DataFolder => Path.Combine(BaseDirectory, "Data");
|
||||
public string DataFolder { get; internal set; }
|
||||
/// <summary>
|
||||
/// Get all <see cref="ClientScript"/> instance in this resource.
|
||||
/// </summary>
|
||||
@ -40,9 +44,7 @@ namespace RageCoop.Client.Scripting
|
||||
}
|
||||
internal class Resources
|
||||
{
|
||||
static readonly API API = Main.API;
|
||||
internal readonly ConcurrentDictionary<string, ClientResource> LoadedResources = new ConcurrentDictionary<string, ClientResource>();
|
||||
private const string BaseScriptType = "RageCoop.Client.Scripting.ClientScript";
|
||||
private Logger Logger { get; set; }
|
||||
public Resources()
|
||||
{
|
||||
@ -57,11 +59,12 @@ namespace RageCoop.Client.Scripting
|
||||
Logger?.Info($"Loading resource: {Path.GetFileNameWithoutExtension(zip)}");
|
||||
Unpack(zipPath, Path.Combine(path, "Data"));
|
||||
}
|
||||
ResourceDomain.Load(path);
|
||||
Main.API.QueueActionAndWait(() => ResourceDomain.Load(path));
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
ResourceDomain.UnloadAll();
|
||||
LoadedResources.Clear();
|
||||
}
|
||||
|
||||
private void Unpack(string zipPath, string dataFolderRoot)
|
||||
@ -71,30 +74,31 @@ namespace RageCoop.Client.Scripting
|
||||
Logger = Main.API.Logger,
|
||||
Scripts = new List<ClientScript>(),
|
||||
Name = Path.GetFileNameWithoutExtension(zipPath),
|
||||
BaseDirectory = Path.Combine(Directory.GetParent(zipPath).FullName, Path.GetFileNameWithoutExtension(zipPath))
|
||||
DataFolder = Path.Combine(dataFolderRoot, Path.GetFileNameWithoutExtension(zipPath)),
|
||||
ScriptsDirectory = Path.Combine(Directory.GetParent(zipPath).FullName, Path.GetFileNameWithoutExtension(zipPath))
|
||||
};
|
||||
Directory.CreateDirectory(r.DataFolder);
|
||||
var resDir = r.BaseDirectory;
|
||||
if (Directory.Exists(resDir)) { Directory.Delete(resDir, true); }
|
||||
else if (File.Exists(resDir)) { File.Delete(resDir); }
|
||||
Directory.CreateDirectory(resDir);
|
||||
var scriptsDir = r.ScriptsDirectory;
|
||||
if (Directory.Exists(scriptsDir)) { Directory.Delete(scriptsDir, true); }
|
||||
else if (File.Exists(scriptsDir)) { File.Delete(scriptsDir); }
|
||||
Directory.CreateDirectory(scriptsDir);
|
||||
|
||||
new FastZip().ExtractZip(zipPath, resDir, null);
|
||||
new FastZip().ExtractZip(zipPath, scriptsDir, null);
|
||||
|
||||
|
||||
foreach (var dir in Directory.GetDirectories(resDir, "*", SearchOption.AllDirectories))
|
||||
foreach (var dir in Directory.GetDirectories(scriptsDir, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
r.Files.Add(dir, new ResourceFile()
|
||||
{
|
||||
IsDirectory = true,
|
||||
Name = dir.Substring(resDir.Length + 1).Replace('\\', '/')
|
||||
Name = dir.Substring(scriptsDir.Length + 1).Replace('\\', '/')
|
||||
});
|
||||
}
|
||||
var assemblies = new Dictionary<ResourceFile, Assembly>();
|
||||
foreach (var file in Directory.GetFiles(resDir, "*", SearchOption.AllDirectories))
|
||||
foreach (var file in Directory.GetFiles(scriptsDir, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (Path.GetFileName(file).CanBeIgnored()) { try { File.Delete(file); } catch { } continue; }
|
||||
var relativeName = file.Substring(resDir.Length + 1).Replace('\\', '/');
|
||||
var relativeName = file.Substring(scriptsDir.Length + 1).Replace('\\', '/');
|
||||
var rfile = new ResourceFile()
|
||||
{
|
||||
GetStream = () => { return new FileStream(file, FileMode.Open, FileAccess.Read); },
|
||||
|
@ -36,7 +36,7 @@ namespace RageCoop.Client
|
||||
/// LogLevel for RageCoop.
|
||||
/// 0:Trace, 1:Debug, 2:Info, 3:Warning, 4:Error
|
||||
/// </summary>
|
||||
public int LogLevel = 00;
|
||||
public int LogLevel = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The key to open menu
|
||||
|
@ -258,7 +258,7 @@ namespace RageCoop.Client
|
||||
|
||||
if (!getBulletImpact())
|
||||
{
|
||||
API.QueueAction(getBulletImpact);
|
||||
Scripting.API.QueueAction(getBulletImpact);
|
||||
}
|
||||
}
|
||||
else if (subject.VehicleWeapon == VehicleWeaponHash.Tank && subject.LastWeaponImpactPosition != default)
|
||||
|
@ -13,13 +13,19 @@ using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
using SHVDN;
|
||||
|
||||
[assembly: InternalsVisibleTo("RageCoop.Client.Installer")]
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
internal static class Util
|
||||
{
|
||||
public static bool IsPrimaryDomain => (AppDomain.CurrentDomain?.GetData("Primary") as bool?) != false;
|
||||
public static bool IsPrimaryDomain => AppDomain.CurrentDomain.GetData("Primary") == null;
|
||||
public static ScriptDomain GetPrimaryDomain()
|
||||
{
|
||||
if (IsPrimaryDomain) { return ScriptDomain.CurrentDomain; }
|
||||
else { return AppDomain.CurrentDomain.GetData("Primary") as ScriptDomain; }
|
||||
}
|
||||
public static SizeF ResolutionMaintainRatio
|
||||
{
|
||||
get
|
||||
@ -141,7 +147,7 @@ namespace RageCoop.Client
|
||||
settings = settings ?? Main.Settings;
|
||||
Directory.CreateDirectory(Directory.GetParent(path).FullName);
|
||||
|
||||
File.WriteAllText(path, JsonConvert.SerializeObject(settings,Formatting.Indented));
|
||||
File.WriteAllText(path, JsonConvert.SerializeObject(settings, Formatting.Indented));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -9,7 +9,7 @@ namespace RageCoop.Core
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Logger : IDisposable
|
||||
public class Logger : MarshalByRefObject,IDisposable
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
@ -34,6 +34,7 @@ namespace RageCoop.Core
|
||||
private readonly Thread LoggerThread;
|
||||
private bool Stopping = false;
|
||||
private readonly bool FlushImmediately;
|
||||
public event EventHandler<string> OnFlush;
|
||||
|
||||
internal Logger(bool flushImmediately = false, bool overwrite = true)
|
||||
{
|
||||
@ -195,7 +196,7 @@ namespace RageCoop.Core
|
||||
|
||||
private string Date()
|
||||
{
|
||||
return DateTime.Now.ToString();
|
||||
return DateTime.Now.ToString("HH:mm:ss");
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -218,6 +219,7 @@ namespace RageCoop.Core
|
||||
logWriter = new StreamWriter(LogPath, true, Encoding.UTF8);
|
||||
logWriter.Write(Buffer);
|
||||
logWriter.Close();
|
||||
OnFlush?.Invoke(this,Buffer);
|
||||
Buffer = "";
|
||||
}
|
||||
catch { }
|
||||
|
@ -1,8 +1,11 @@
|
||||
namespace RageCoop.Core
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A json object representing a server's information as annouced to master server.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ServerInfo
|
||||
{
|
||||
#pragma warning disable 1591
|
||||
|
@ -144,7 +144,7 @@ namespace RageCoop.Core
|
||||
void Deserialize(NetIncomingMessage m);
|
||||
}
|
||||
|
||||
internal abstract class Packet : IPacket
|
||||
internal abstract class Packet : MarshalByRefObject, IPacket
|
||||
{
|
||||
public abstract PacketType Type { get; }
|
||||
public void Pack(NetOutgoingMessage m)
|
||||
|
@ -27,7 +27,7 @@ namespace RageCoop.Core.Scripting
|
||||
/// <summary>
|
||||
/// Struct to identify different event using hash
|
||||
/// </summary>
|
||||
public struct CustomEventHash
|
||||
public class CustomEventHash : MarshalByRefObject
|
||||
{
|
||||
private static readonly MD5 Hasher = MD5.Create();
|
||||
private static readonly Dictionary<int, string> Hashed = new Dictionary<int, string>();
|
||||
|
@ -6,7 +6,7 @@ namespace RageCoop.Core.Scripting
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ResourceFile
|
||||
public class ResourceFile : MarshalByRefObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Full name with relative path of this file
|
||||
|
@ -15,7 +15,7 @@ using System.Resources;
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information
|
||||
[assembly: AssemblyVersion("1.5.4.42")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.42")]
|
||||
[assembly: AssemblyVersion("1.5.4.45")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.45")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user