Load in client in seperate domain
Rewrote logger for more flexible options Complete client resource loading
This commit is contained in:
@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RageCoop.Client", "RageCoop
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RageCoop.Client.Installer", "RageCoop.Client.Installer\RageCoop.Client.Installer.csproj", "{576D8610-0C28-4B60-BE2B-8657EA7CEE1B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RageCoop.Client.Loader", "RageCoop.Client.Loader\RageCoop.Client.Loader.csproj", "{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -51,6 +53,14 @@ Global
|
||||
{576D8610-0C28-4B60-BE2B-8657EA7CEE1B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{576D8610-0C28-4B60-BE2B-8657EA7CEE1B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{576D8610-0C28-4B60-BE2B-8657EA7CEE1B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D2A39C1C-2454-4411-8BA1-BE34EEB9042F}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
200
RageCoop.Client.Loader/DomainLoader.cs
Normal file
200
RageCoop.Client.Loader/DomainLoader.cs
Normal file
@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Console = GTA.Console;
|
||||
using SHVDN;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RageCoop.Client.Loader
|
||||
{
|
||||
|
||||
public class DomainContext : MarshalByRefObject, IDisposable
|
||||
{
|
||||
#region PRIMARY-LOADING-LOGIC
|
||||
public static ConcurrentDictionary<string, DomainContext> LoadedDomains => new ConcurrentDictionary<string, DomainContext>(_loadedDomains);
|
||||
static readonly ConcurrentDictionary<string, DomainContext> _loadedDomains = new ConcurrentDictionary<string, DomainContext>();
|
||||
|
||||
public bool UnloadRequested;
|
||||
public string BaseDirectory => AppDomain.CurrentDomain.BaseDirectory;
|
||||
private ScriptDomain CurrentDomain => ScriptDomain.CurrentDomain;
|
||||
public static void CheckForUnloadRequest()
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
foreach (var p in _loadedDomains.Values)
|
||||
{
|
||||
if (p.UnloadRequested)
|
||||
{
|
||||
Unload(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsLoaded(string dir)
|
||||
{
|
||||
return _loadedDomains.ContainsKey(Path.GetFullPath(dir).ToLower());
|
||||
}
|
||||
public static DomainContext Load(string dir)
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
dir = Path.GetFullPath(dir).ToLower();
|
||||
if (IsLoaded(dir))
|
||||
{
|
||||
throw new Exception("Already loaded");
|
||||
}
|
||||
ScriptDomain newDomain = null;
|
||||
try
|
||||
{
|
||||
dir = Path.GetFullPath(dir);
|
||||
Directory.CreateDirectory(dir);
|
||||
Exception e = null;
|
||||
// Load domain in main thread
|
||||
Main.QueueToMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
/*
|
||||
var assemblies = new List<string>();
|
||||
assemblies.Add(typeof(DomainLoader).Assembly.Location);
|
||||
assemblies.AddRange(typeof(DomainLoader).Assembly.GetReferencedAssemblies()
|
||||
.Select(x => Assembly.Load(x.FullName).Location)
|
||||
.Where(x => !string.IsNullOrEmpty(x)));
|
||||
*/
|
||||
|
||||
// Delete API assemblies
|
||||
Directory.GetFiles(dir, "ScriptHookVDotNet*", SearchOption.AllDirectories).ToList().ForEach(x => File.Delete(x));
|
||||
var ctxAsm = Path.Combine(dir, "RageCoop.Client.Loader.dll");
|
||||
if (File.Exists(ctxAsm)) { File.Delete(ctxAsm); }
|
||||
|
||||
newDomain = ScriptDomain.Load(
|
||||
Directory.GetParent(typeof(ScriptDomain).Assembly.Location).FullName, dir);
|
||||
newDomain.AppDomain.SetData("Primary", ScriptDomain.CurrentDomain);
|
||||
newDomain.AppDomain.SetData("Console", ScriptDomain.CurrentDomain.AppDomain.GetData("Console"));
|
||||
var context = (DomainContext)newDomain.AppDomain.CreateInstanceFromAndUnwrap(
|
||||
typeof(DomainContext).Assembly.Location,
|
||||
typeof(DomainContext).FullName, ignoreCase: false,
|
||||
BindingFlags.Instance | BindingFlags.NonPublic,
|
||||
null,
|
||||
new object[] { }
|
||||
, null, null);
|
||||
newDomain.AppDomain.SetData("RageCoop.Client.LoaderContext", context);
|
||||
newDomain.Start();
|
||||
_loadedDomains.TryAdd(dir,context );
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e = ex;
|
||||
}
|
||||
});
|
||||
// Wait till next tick
|
||||
GTA.Script.Yield();
|
||||
if (e != null) { throw e; }
|
||||
return _loadedDomains[dir];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GTA.UI.Notification.Show(ex.ToString());
|
||||
Console.Error(ex);
|
||||
if (newDomain != null)
|
||||
{
|
||||
ScriptDomain.Unload(newDomain);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Unload(DomainContext domain)
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
Exception ex = null;
|
||||
var name = domain.CurrentDomain.Name;
|
||||
Console.Info("Unloading domain: " + name);
|
||||
Main.QueueToMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_loadedDomains.TryRemove(domain.BaseDirectory, out _))
|
||||
{
|
||||
throw new Exception("Failed to remove domain from list");
|
||||
}
|
||||
domain.Dispose();
|
||||
ScriptDomain.Unload(domain.CurrentDomain);
|
||||
}
|
||||
catch (Exception e) { ex = e; }
|
||||
});
|
||||
GTA.Script.Yield();
|
||||
if (ex != null) { throw ex; }
|
||||
Console.Info("Unloaded domain: " + name);
|
||||
}
|
||||
}
|
||||
public static void Unload(string dir)
|
||||
{
|
||||
Unload(_loadedDomains[Path.GetFullPath(dir).ToLower()]);
|
||||
}
|
||||
public static void UnloadAll()
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
foreach (var d in _loadedDomains.Values.ToArray())
|
||||
{
|
||||
Unload(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region LOAD-CONTEXT
|
||||
|
||||
|
||||
private DomainContext()
|
||||
{
|
||||
AppDomain.CurrentDomain.DomainUnload += (s, e) => Dispose();
|
||||
PrimaryDomain.Tick += Tick;
|
||||
PrimaryDomain.KeyEvent += KeyEvent;
|
||||
Console.Info($"Loaded domain: {AppDomain.CurrentDomain.FriendlyName}, {AppDomain.CurrentDomain.BaseDirectory}");
|
||||
}
|
||||
public static ScriptDomain PrimaryDomain=> (ScriptDomain)AppDomain.CurrentDomain.GetData("Primary");
|
||||
public static DomainContext CurrentContext => (DomainContext)AppDomain.CurrentDomain.GetData("RageCoop.Client.LoaderContext");
|
||||
/// <summary>
|
||||
/// Request the current domain to be unloaded
|
||||
/// </summary>
|
||||
public static void RequestUnload()
|
||||
{
|
||||
if (PrimaryDomain == null)
|
||||
{
|
||||
throw new NotSupportedException("Current domain not loaded by the loader therfore cannot be unloaded automatically");
|
||||
}
|
||||
CurrentContext.UnloadRequested = true;
|
||||
}
|
||||
private void Tick(object sender, EventArgs args)
|
||||
{
|
||||
CurrentDomain.DoTick();
|
||||
}
|
||||
|
||||
private void KeyEvent(Keys keys, bool status)
|
||||
{
|
||||
CurrentDomain.DoKeyEvent(keys, status);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (PrimaryDomain == null) { return; }
|
||||
PrimaryDomain.Tick -= Tick;
|
||||
PrimaryDomain.KeyEvent -= KeyEvent;
|
||||
AppDomain.CurrentDomain.SetData("Primary", null);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
64
RageCoop.Client.Loader/Main.cs
Normal file
64
RageCoop.Client.Loader/Main.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using GTA;
|
||||
using Console = GTA.Console;
|
||||
namespace RageCoop.Client.Loader
|
||||
{
|
||||
public class Main : Script
|
||||
{
|
||||
static readonly string GameDir = Directory.GetParent(typeof(SHVDN.ScriptDomain).Assembly.Location).FullName;
|
||||
|
||||
static readonly string ScriptsLocation = Path.Combine(GameDir, "RageCoop", "Scripts");
|
||||
private static readonly ConcurrentQueue<Action> TaskQueue = new ConcurrentQueue<Action>();
|
||||
public Main()
|
||||
{
|
||||
Tick += OnTick;
|
||||
SHVDN.ScriptDomain.CurrentDomain.Tick += DomainTick;
|
||||
KeyDown += OnKeyDown;
|
||||
}
|
||||
|
||||
private void OnKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnTick(object sender, EventArgs e)
|
||||
{
|
||||
while (Game.IsLoading)
|
||||
{
|
||||
Script.Yield();
|
||||
}
|
||||
DomainContext.CheckForUnloadRequest();
|
||||
if (!DomainContext.IsLoaded(ScriptsLocation))
|
||||
{
|
||||
if (!File.Exists(Path.Combine(ScriptsLocation, "RageCoop.Client.dll")))
|
||||
{
|
||||
GTA.UI.Notification.Show("~r~Main assembly is missing, please re-install the client");
|
||||
Abort();
|
||||
}
|
||||
DomainContext.Load(ScriptsLocation);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void QueueToMainThread(Action task)
|
||||
{
|
||||
TaskQueue.Enqueue(task);
|
||||
}
|
||||
|
||||
private static void DomainTick(object sender, EventArgs e)
|
||||
{
|
||||
while (TaskQueue.TryDequeue(out var task))
|
||||
{
|
||||
try
|
||||
{
|
||||
task.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
RageCoop.Client.Loader/Properties/AssemblyInfo.cs
Normal file
36
RageCoop.Client.Loader/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("RageCoop.Client.Loader")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("RageCoop.Client.Loader")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2022")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("fc8cbdbb-6dc3-43af-b34d-092e476410a5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
60
RageCoop.Client.Loader/RageCoop.Client.Loader.csproj
Normal file
60
RageCoop.Client.Loader/RageCoop.Client.Loader.csproj
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{FC8CBDBB-6DC3-43AF-B34D-092E476410A5}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>RageCoop.Client.Loader</RootNamespace>
|
||||
<AssemblyName>RageCoop.Client.Loader</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
|
||||
<OutDir>..\bin\Debug\Client.Loader</OutDir>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutDir>..\bin\Release\Client.Loader</OutDir>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ScriptHookVDotNet">
|
||||
<HintPath>..\libs\ScriptHookVDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScriptHookVDotNet3">
|
||||
<HintPath>..\libs\ScriptHookVDotNet3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DomainLoader.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
@ -20,7 +20,6 @@ namespace RageCoop.Client
|
||||
public DevTool()
|
||||
{
|
||||
Instance = this;
|
||||
if (!Util.IsPrimaryDomain) { Abort(); return; }
|
||||
Tick += OnTick;
|
||||
KeyDown += OnKeyDown;
|
||||
Pause();
|
||||
|
@ -25,7 +25,6 @@ namespace RageCoop.Client
|
||||
[ScriptAttributes(Author = "RageCoop", NoDefaultInstance = false, SupportURL = "https://github.com/RAGECOOP/RAGECOOP-V")]
|
||||
internal class Main : Script
|
||||
{
|
||||
public static API API = API.GetInstance();
|
||||
private static bool _gameLoaded = false;
|
||||
internal static Version Version = typeof(Main).Assembly.GetName().Version;
|
||||
|
||||
@ -45,21 +44,20 @@ namespace RageCoop.Client
|
||||
internal static Vector3 PlayerPosition;
|
||||
internal static Resources Resources = null;
|
||||
private static readonly ConcurrentQueue<Action> TaskQueue = new ConcurrentQueue<Action>();
|
||||
public static Worker Worker;
|
||||
public static string LogPath => $"{Settings.DataDirectory}\\RageCoop.Client.log";
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
public Main()
|
||||
{
|
||||
Console.WriteLine($"Starting {typeof(Main).FullName}, domain: {AppDomain.CurrentDomain.Id}, {Util.IsPrimaryDomain}");
|
||||
if (!Util.IsPrimaryDomain) { Console.WriteLine("Ignored loading in scondary domain"); Abort(); return; }
|
||||
Console.Info($"Starting {typeof(Main).FullName}, domain: {AppDomain.CurrentDomain.Id} {AppDomain.CurrentDomain.FriendlyName}");
|
||||
try
|
||||
{
|
||||
Settings = Util.ReadSettings();
|
||||
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("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));
|
||||
@ -78,16 +76,34 @@ namespace RageCoop.Client
|
||||
Directory.CreateDirectory(Settings.DataDirectory);
|
||||
Logger = new Logger()
|
||||
{
|
||||
LogPath = $"{Settings.DataDirectory}\\RageCoop.Client.log",
|
||||
UseConsole = false,
|
||||
Writers = new List<StreamWriter> { CoreUtils.OpenWriter(LogPath)},
|
||||
#if DEBUG
|
||||
LogLevel = 0,
|
||||
#else
|
||||
LogLevel = Settings.LogLevel,
|
||||
#endif
|
||||
};
|
||||
Logger.OnFlush += (s, d) => Console.WriteLine(d);
|
||||
Worker = new Worker("RageCoop.Client.Main.Worker", Logger);
|
||||
Logger.OnFlush += (line, formatted) =>
|
||||
{
|
||||
switch (line.LogLevel)
|
||||
{
|
||||
#if DEBUG
|
||||
// case LogLevel.Trace:
|
||||
case LogLevel.Debug:
|
||||
Console.Info(line.Message);
|
||||
break;
|
||||
#endif
|
||||
case LogLevel.Info:
|
||||
Console.Info(line.Message);
|
||||
break;
|
||||
case LogLevel.Warning:
|
||||
Console.Warning(line.Message);
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
Console.Error(line.Message);
|
||||
break;
|
||||
}
|
||||
};
|
||||
ScriptDomain.CurrentDomain.Tick += DomainTick;
|
||||
Resources = new Resources();
|
||||
if (Game.Version < GameVersion.v1_0_1290_1_Steam)
|
||||
@ -163,9 +179,17 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
internal static void QueueToMainThread(Action task)
|
||||
|
||||
/// <summary>
|
||||
/// Queue an action to main thread and wait for execution to complete, must be called from script thread.
|
||||
/// </summary>
|
||||
/// <param name="task"></param>
|
||||
internal static void QueueToMainThreadAndWait(Action task)
|
||||
{
|
||||
TaskQueue.Enqueue(task);
|
||||
Exception e = null;
|
||||
TaskQueue.Enqueue(() => { try { task(); } catch (Exception ex) { e = ex; } });
|
||||
Yield();
|
||||
if (e != null) { throw e; }
|
||||
}
|
||||
|
||||
public static Ped P;
|
||||
|
@ -9,7 +9,6 @@ namespace RageCoop.Client
|
||||
{
|
||||
internal static class DebugMenu
|
||||
{
|
||||
public static string DebugLocation => Path.Combine(Main.Settings.DataDirectory, @"Debug");
|
||||
public static NativeMenu Menu = new NativeMenu("RAGECOOP", "Debug", "Debug settings")
|
||||
{
|
||||
UseMouse = false,
|
||||
@ -20,7 +19,7 @@ namespace RageCoop.Client
|
||||
UseMouse = false,
|
||||
Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
|
||||
};
|
||||
public static NativeItem DebugScriptsItem = new NativeItem("Load debug scripts", $"Load scripts from {DebugLocation}");
|
||||
public static NativeItem ReloadItem = new NativeItem("Reload","Reload RAGECOOP and associated scripts");
|
||||
public static NativeItem SimulatedLatencyItem = new NativeItem("Simulated network latency", "Simulated network latency in ms (one way)", "0");
|
||||
public static NativeCheckboxItem ShowOwnerItem = new NativeCheckboxItem("Show entity owner", "Show the owner name of the entity you're aiming at", false);
|
||||
private static readonly NativeCheckboxItem ShowNetworkInfoItem = new NativeCheckboxItem("Show Network Info", Networking.ShowNetworkInfo);
|
||||
@ -50,29 +49,18 @@ namespace RageCoop.Client
|
||||
};
|
||||
ShowNetworkInfoItem.CheckboxChanged += (s, e) => { Networking.ShowNetworkInfo = ShowNetworkInfoItem.Checked; };
|
||||
ShowOwnerItem.CheckboxChanged += (s, e) => { Main.Settings.ShowEntityOwnerName = ShowOwnerItem.Checked; Util.SaveSettings(); };
|
||||
DebugScriptsItem.Activated += ToggleScripts;
|
||||
ReloadItem.Activated += ReloadDomain;
|
||||
Menu.Add(SimulatedLatencyItem);
|
||||
Menu.Add(ShowNetworkInfoItem);
|
||||
Menu.Add(ShowOwnerItem);
|
||||
Menu.Add(DebugScriptsItem);
|
||||
Menu.Add(ReloadItem);
|
||||
Menu.AddSubMenu(DiagnosticMenu);
|
||||
|
||||
}
|
||||
|
||||
private static void ToggleScripts(object sender, EventArgs e)
|
||||
private static void ReloadDomain(object sender, EventArgs e)
|
||||
{
|
||||
if (ResourceDomain.IsLoaded(DebugLocation))
|
||||
{
|
||||
ResourceDomain.Unload(DebugLocation);
|
||||
DebugScriptsItem.Title = "Load debug scripts";
|
||||
DebugScriptsItem.Description = $"Load scripts from {DebugLocation}";
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceDomain.Load(DebugLocation);
|
||||
DebugScriptsItem.Title = "Unload debug scripts";
|
||||
DebugScriptsItem.Description = $"Unload scripts from {DebugLocation}";
|
||||
}
|
||||
Loader.DomainContext.RequestUnload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ namespace RageCoop.Client.Menus
|
||||
/// </summary>
|
||||
internal static class ServersMenu
|
||||
{
|
||||
static API API = Main.API;
|
||||
private static Thread GetServersThread;
|
||||
internal static NativeMenu Menu = new NativeMenu("RAGECOOP", "Servers", "Go to the server list")
|
||||
{
|
||||
|
@ -11,7 +11,6 @@ namespace RageCoop.Client.Menus
|
||||
{
|
||||
internal class UpdateMenu
|
||||
{
|
||||
static readonly API API = Main.API;
|
||||
public static bool IsUpdating { get; private set; } = false;
|
||||
private static readonly NativeItem _updatingItem = new NativeItem("Updating...");
|
||||
private static readonly NativeItem _downloadItem = new NativeItem("Download", "Download and update to latest nightly");
|
||||
|
@ -13,7 +13,6 @@ 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;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using GTA;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Client.Menus;
|
||||
using RageCoop.Client.Scripting;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
|
@ -3,6 +3,7 @@ using GTA.Math;
|
||||
using GTA.Native;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Client.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
@ -12,7 +12,6 @@ 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");
|
||||
|
@ -16,7 +16,7 @@ using System.Resources;
|
||||
|
||||
|
||||
// Version informationr(
|
||||
[assembly: AssemblyVersion("1.5.4.244")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.244")]
|
||||
[assembly: AssemblyVersion("1.5.4.291")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.291")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -1,314 +1,317 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>RageCoop.Client</RootNamespace>
|
||||
<AssemblyName>RageCoop.Client</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<OutPutPath>..\bin\Debug\Client</OutPutPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<OutPutPath>..\bin\Release\Client</OutPutPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Debug.cs" />
|
||||
<Compile Include="DevTools\DevTool.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Menus\CoopMenu.cs" />
|
||||
<Compile Include="Menus\Sub\DebugMenu.cs" />
|
||||
<Compile Include="Menus\Sub\DevToolMenu.cs" />
|
||||
<Compile Include="Menus\Sub\ServersMenu.cs" />
|
||||
<Compile Include="Menus\Sub\SettingsMenu.cs" />
|
||||
<Compile Include="Menus\Sub\UpdateMenu.cs" />
|
||||
<Compile Include="Networking\Chat.cs" />
|
||||
<Compile Include="Networking\DownloadManager.cs" />
|
||||
<Compile Include="Networking\HolePunch.cs" />
|
||||
<Compile Include="Networking\Networking.cs" />
|
||||
<Compile Include="Networking\Receive.cs" />
|
||||
<Compile Include="Networking\Send.cs" />
|
||||
<Compile Include="Networking\Statistics.cs" />
|
||||
<Compile Include="PlayerList.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>AssemblyInfo.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Scripting\API.cs" />
|
||||
<Compile Include="Scripting\BaseScript.cs" />
|
||||
<Compile Include="Scripting\ClientScript.cs" />
|
||||
<Compile Include="Scripting\ResourceDomain.cs" />
|
||||
<Compile Include="Scripting\Resources.cs" />
|
||||
<Compile Include="Security.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.Members.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.Animations.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedEntity.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedProjectile.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedProp.cs" />
|
||||
<Compile Include="Sync\Entities\Vehicle\SyncedVehicle.cs" />
|
||||
<Compile Include="Sync\Entities\Vehicle\SyncedVehicle.Members.cs" />
|
||||
<Compile Include="Sync\EntityPool.cs" />
|
||||
<Compile Include="Sync\SyncEvents.cs" />
|
||||
<Compile Include="Sync\Voice.cs" />
|
||||
<Compile Include="Util\AddOnDataProvider.cs" />
|
||||
<Compile Include="Util\Memory.cs" />
|
||||
<Compile Include="Util\NativeCaller.cs" />
|
||||
<Compile Include="Util\PedConfigFlags.cs" />
|
||||
<Compile Include="Util\PedExtensions.cs" />
|
||||
<Compile Include="Util\TaskType.cs" />
|
||||
<Compile Include="Util\Util.cs" />
|
||||
<Compile Include="Util\VehicleExtensions.cs" />
|
||||
<Compile Include="Util\WeaponUtil.cs" />
|
||||
<Compile Include="WorldThread.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RageCoop.Core\RageCoop.Core.csproj">
|
||||
<Project>{cc2e8102-e568-4524-aa1f-f8e0f1cfe58a}</Project>
|
||||
<Name>RageCoop.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Costura, Version=5.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="LemonUI.SHVDN3, Version=1.7.0.0, Culture=neutral, processorArchitecture=AMD64">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\LemonUI.SHVDN3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lidgren.Network, Version=2012.1.7.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\Lidgren.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Extensions.ObjectPool, Version=6.0.8.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.ObjectPool.6.0.8\lib\net461\Microsoft.Extensions.ObjectPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Registry, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Win32.Registry.4.7.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.2.1.0\lib\net472\NAudio.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Asio, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Asio.2.1.0\lib\netstandard2.0\NAudio.Asio.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Core.2.1.0\lib\netstandard2.0\NAudio.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Midi, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Midi.2.1.0\lib\netstandard2.0\NAudio.Midi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Wasapi, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Wasapi.2.1.0\lib\netstandard2.0\NAudio.Wasapi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.WinForms, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.WinForms.2.1.0\lib\net472\NAudio.WinForms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.WinMM, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.WinMM.2.1.0\lib\netstandard2.0\NAudio.WinMM.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScriptHookVDotNet">
|
||||
<HintPath>..\libs\ScriptHookVDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScriptHookVDotNet3">
|
||||
<HintPath>..\libs\ScriptHookVDotNet3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.AccessControl, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.AccessControl.4.7.0\lib\net461\System.Security.AccessControl.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal.Windows, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Principal.Windows.4.7.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="FodyWeavers.xml" />
|
||||
<Content Include="Properties\AssemblyInfo.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>AssemblyInfo.cs</LastGenOutput>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Fody.6.6.3\build\Fody.targets" Condition="Exists('..\packages\Fody.6.6.3\build\Fody.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Fody.6.6.3\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.6.3\build\Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" />
|
||||
<PropertyGroup Condition=" '$(DevEnvDir)' != '*Undefined*'">
|
||||
<PostBuildEvent>"$(DevEnvDir)TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{EF56D109-1F22-43E0-9DFF-CFCFB94E0681}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>RageCoop.Client</RootNamespace>
|
||||
<AssemblyName>RageCoop.Client</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<OutPutPath>..\bin\Debug\Client</OutPutPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<OutPutPath>..\bin\Release\Client</OutPutPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Debug.cs" />
|
||||
<Compile Include="DevTools\DevTool.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Menus\CoopMenu.cs" />
|
||||
<Compile Include="Menus\Sub\DebugMenu.cs" />
|
||||
<Compile Include="Menus\Sub\DevToolMenu.cs" />
|
||||
<Compile Include="Menus\Sub\ServersMenu.cs" />
|
||||
<Compile Include="Menus\Sub\SettingsMenu.cs" />
|
||||
<Compile Include="Menus\Sub\UpdateMenu.cs" />
|
||||
<Compile Include="Networking\Chat.cs" />
|
||||
<Compile Include="Networking\DownloadManager.cs" />
|
||||
<Compile Include="Networking\HolePunch.cs" />
|
||||
<Compile Include="Networking\Networking.cs" />
|
||||
<Compile Include="Networking\Receive.cs" />
|
||||
<Compile Include="Networking\Send.cs" />
|
||||
<Compile Include="Networking\Statistics.cs" />
|
||||
<Compile Include="PlayerList.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>AssemblyInfo.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Scripting\API.cs" />
|
||||
<Compile Include="Scripting\BaseScript.cs" />
|
||||
<Compile Include="Scripting\ClientScript.cs" />
|
||||
<Compile Include="Scripting\Resources.cs" />
|
||||
<Compile Include="Security.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.Members.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.Animations.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedEntity.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedProjectile.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedProp.cs" />
|
||||
<Compile Include="Sync\Entities\Vehicle\SyncedVehicle.cs" />
|
||||
<Compile Include="Sync\Entities\Vehicle\SyncedVehicle.Members.cs" />
|
||||
<Compile Include="Sync\EntityPool.cs" />
|
||||
<Compile Include="Sync\SyncEvents.cs" />
|
||||
<Compile Include="Sync\Voice.cs" />
|
||||
<Compile Include="Util\AddOnDataProvider.cs" />
|
||||
<Compile Include="Util\Memory.cs" />
|
||||
<Compile Include="Util\NativeCaller.cs" />
|
||||
<Compile Include="Util\PedConfigFlags.cs" />
|
||||
<Compile Include="Util\PedExtensions.cs" />
|
||||
<Compile Include="Util\TaskType.cs" />
|
||||
<Compile Include="Util\Util.cs" />
|
||||
<Compile Include="Util\VehicleExtensions.cs" />
|
||||
<Compile Include="Util\WeaponUtil.cs" />
|
||||
<Compile Include="WorldThread.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RageCoop.Client.Loader\RageCoop.Client.Loader.csproj">
|
||||
<Project>{d2a39c1c-2454-4411-8ba1-be34eeb9042f}</Project>
|
||||
<Name>RageCoop.Client.Loader</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\RageCoop.Core\RageCoop.Core.csproj">
|
||||
<Project>{cc2e8102-e568-4524-aa1f-f8e0f1cfe58a}</Project>
|
||||
<Name>RageCoop.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Costura, Version=5.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="LemonUI.SHVDN3, Version=1.7.0.0, Culture=neutral, processorArchitecture=AMD64">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\LemonUI.SHVDN3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lidgren.Network, Version=2012.1.7.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\Lidgren.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Extensions.ObjectPool, Version=6.0.8.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Extensions.ObjectPool.6.0.8\lib\net461\Microsoft.Extensions.ObjectPool.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Registry, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Win32.Registry.4.7.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.2.1.0\lib\net472\NAudio.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Asio, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Asio.2.1.0\lib\netstandard2.0\NAudio.Asio.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Core.2.1.0\lib\netstandard2.0\NAudio.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Midi, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Midi.2.1.0\lib\netstandard2.0\NAudio.Midi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.Wasapi, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.Wasapi.2.1.0\lib\netstandard2.0\NAudio.Wasapi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.WinForms, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.WinForms.2.1.0\lib\net472\NAudio.WinForms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NAudio.WinMM, Version=2.1.0.0, Culture=neutral, PublicKeyToken=e279aa5131008a41, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NAudio.WinMM.2.1.0\lib\netstandard2.0\NAudio.WinMM.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScriptHookVDotNet">
|
||||
<HintPath>..\libs\ScriptHookVDotNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ScriptHookVDotNet3">
|
||||
<HintPath>..\libs\ScriptHookVDotNet3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.AccessControl, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.AccessControl.4.7.0\lib\net461\System.Security.AccessControl.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal.Windows, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Principal.Windows.4.7.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Serialization" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="FodyWeavers.xml" />
|
||||
<Content Include="Properties\AssemblyInfo.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>AssemblyInfo.cs</LastGenOutput>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Fody.6.6.3\build\Fody.targets" Condition="Exists('..\packages\Fody.6.6.3\build\Fody.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Fody.6.6.3\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.6.3\build\Fody.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.5.7.0\build\Costura.Fody.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" />
|
||||
<PropertyGroup Condition=" '$(DevEnvDir)' != '*Undefined*'">
|
||||
<PostBuildEvent>"$(DevEnvDir)TextTransform.exe" -a !!BuildConfiguration!$(Configuration) "$(ProjectDir)Properties\AssemblyInfo.tt"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
@ -26,160 +26,137 @@ namespace RageCoop.Client.Scripting
|
||||
/// </summary>
|
||||
public object[] Args { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Client configuration, this will conflict with server-side config.
|
||||
/// </summary>
|
||||
public class ClientConfig : MarshalByRefObject
|
||||
{
|
||||
/// <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 : MarshalByRefObject
|
||||
{
|
||||
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;
|
||||
|
||||
#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 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); });
|
||||
}
|
||||
|
||||
if (Util.IsPrimaryDomain)
|
||||
{
|
||||
ResourceDomain.DoCallBack("CustomEvent",p);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides vital functionality to interact with RAGECOOP
|
||||
/// </summary>
|
||||
public class API : MarshalByRefObject
|
||||
public static class API
|
||||
{
|
||||
static API()
|
||||
{
|
||||
if (!Util.IsPrimaryDomain)
|
||||
{
|
||||
ResourceDomain.RegisterCallBackForCurrentDomain("CustomEvent",
|
||||
(data) => {
|
||||
Events.InvokeCustomEventReceived(data as Packets.CustomEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
static API Instance;
|
||||
private API() { }
|
||||
|
||||
#region INTERNAL
|
||||
internal static Dictionary<int, List<Action<CustomEventReceivedArgs>>> CustomEventHandlers = new Dictionary<int, List<Action<CustomEventReceivedArgs>>>();
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Get an instance to bridge data between domains
|
||||
/// Client configuration, this will conflict with server-side config.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public static API GetInstance()
|
||||
public static class Config
|
||||
{
|
||||
if (Instance != null) { return Instance; }
|
||||
if (Util.IsPrimaryDomain)
|
||||
/// <summary>
|
||||
/// Get or set local player's username, set won't be effective if already connected to a server.
|
||||
/// </summary>
|
||||
public static string Username
|
||||
{
|
||||
Instance = new API();
|
||||
get => Main.Settings.Username;
|
||||
set
|
||||
{
|
||||
if (Networking.IsOnServer || string.IsNullOrEmpty(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Main.Settings.Username = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance = AppDomain.CurrentDomain.GetData("RageCoop.Client.API") as API;
|
||||
}
|
||||
return Instance;
|
||||
}
|
||||
/// <summary>
|
||||
/// Enable automatic respawn for this player.
|
||||
/// </summary>
|
||||
public static bool EnableAutoRespawn { get; set; } = true;
|
||||
|
||||
public static ClientEvents Events = new ClientEvents();
|
||||
public ClientConfig Config = new ClientConfig();
|
||||
/// <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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
#region PROPERTIES
|
||||
|
||||
@ -187,65 +164,57 @@ namespace RageCoop.Client.Scripting
|
||||
/// Get the local player's ID
|
||||
/// </summary>
|
||||
/// <returns>PlayerID</returns>
|
||||
public int LocalPlayerID => Main.LocalPlayerID;
|
||||
public static int LocalPlayerID => Main.LocalPlayerID;
|
||||
|
||||
/// <summary>
|
||||
/// Check if player is connected to a server
|
||||
/// </summary>
|
||||
public bool IsOnServer => Networking.IsOnServer;
|
||||
public static 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 System.Net.IPEndPoint ServerEndPoint => Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null;
|
||||
public static System.Net.IPEndPoint ServerEndPoint => Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null;
|
||||
|
||||
/// <summary>
|
||||
/// Check if a RAGECOOP menu is visible
|
||||
/// </summary>
|
||||
public bool IsMenuVisible => Menus.CoopMenu.MenuPool.AreAnyVisible;
|
||||
public static bool IsMenuVisible => Menus.CoopMenu.MenuPool.AreAnyVisible;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the RAGECOOP chat is visible
|
||||
/// </summary>
|
||||
public bool IsChatFocused => Main.MainChat.Focused;
|
||||
public static bool IsChatFocused => Main.MainChat.Focused;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the RAGECOOP list of players is visible
|
||||
/// </summary>
|
||||
public bool IsPlayerListVisible => Util.GetTickCount64() - PlayerList.Pressed < 5000;
|
||||
public static bool IsPlayerListVisible => Util.GetTickCount64() - PlayerList.Pressed < 5000;
|
||||
|
||||
/// <summary>
|
||||
/// Get the version of RAGECOOP
|
||||
/// </summary>
|
||||
public Version CurrentVersion => Main.Version;
|
||||
public static Version CurrentVersion => Main.Version;
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="Core.Logger"/> that RAGECOOP is currently using.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Logger Logger => Main.Logger;
|
||||
public static Logger Logger => Main.Logger;
|
||||
/// <summary>
|
||||
/// Get all players indexed by their ID
|
||||
/// </summary>
|
||||
public Dictionary<int, Player> Players => new Dictionary<int, Player>(PlayerList.Players);
|
||||
public static Dictionary<int, Player> Players => new Dictionary<int, Player>(PlayerList.Players);
|
||||
|
||||
#endregion
|
||||
|
||||
#region FUNCTIONS
|
||||
public ClientResource GetResource(string name)
|
||||
{
|
||||
if (Main.Resources.LoadedResources.TryGetValue(name.ToLower(), out var res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Connect to a server
|
||||
/// </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 void Connect(string address)
|
||||
public static void Connect(string address)
|
||||
{
|
||||
if (Networking.IsOnServer || Networking.IsConnecting)
|
||||
{
|
||||
@ -256,7 +225,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// <summary>
|
||||
/// Disconnect from current server or cancel the connection attempt.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
public static void Disconnect()
|
||||
{
|
||||
if (Networking.IsOnServer || Networking.IsConnecting)
|
||||
{
|
||||
@ -268,7 +237,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// List all servers from master server address
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ServerInfo> ListServers()
|
||||
public static List<ServerInfo> ListServers()
|
||||
{
|
||||
return JsonConvert.DeserializeObject<List<ServerInfo>>(HttpHelper.DownloadString(Main.Settings.MasterServer));
|
||||
}
|
||||
@ -278,7 +247,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// </summary>
|
||||
/// <param name="from">Name of the sender</param>
|
||||
/// <param name="message">The player's message</param>
|
||||
public void LocalChatMessage(string from, string message)
|
||||
public static void LocalChatMessage(string from, string message)
|
||||
{
|
||||
Main.MainChat.AddMessage(from, message);
|
||||
}
|
||||
@ -287,20 +256,97 @@ namespace RageCoop.Client.Scripting
|
||||
/// Send a chat message or command to server/other players
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public void SendChatMessage(string message)
|
||||
public static void SendChatMessage(string message)
|
||||
{
|
||||
Networking.SendChatMessage(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send an event and data to the server.
|
||||
/// </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)
|
||||
{
|
||||
|
||||
Networking.Peer.SendTo(new Packets.CustomEvent()
|
||||
{
|
||||
Args = args,
|
||||
Hash = eventHash
|
||||
}, Networking.ServerConnection, ConnectionChannel.Event, Lidgren.Network.NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
/// <summary>
|
||||
/// Send an event and data to the server
|
||||
/// </summary>
|
||||
/// <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)
|
||||
{
|
||||
Networking.Peer.SendTo(new Packets.CustomEvent(flags)
|
||||
{
|
||||
Args = args,
|
||||
Hash = eventHash
|
||||
}, 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 static void RegisterCustomEventHandler(CustomEventHash hash, Action<CustomEventReceivedArgs> handler)
|
||||
{
|
||||
lock (CustomEventHandlers)
|
||||
{
|
||||
if (!CustomEventHandlers.TryGetValue(hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
|
||||
}
|
||||
handlers.Add(handler);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static void RequestSharedFile(string name, Action<string> callback)
|
||||
{
|
||||
EventHandler<string> handler = (s, e) =>
|
||||
{
|
||||
if (e.EndsWith(name))
|
||||
{
|
||||
callback(e);
|
||||
}
|
||||
};
|
||||
DownloadManager.DownloadCompleted += handler;
|
||||
Networking.GetResponse<Packets.FileTransferResponse>(new Packets.FileTransferRequest()
|
||||
{
|
||||
Name = name,
|
||||
},
|
||||
(p) =>
|
||||
{
|
||||
if (p.Response != FileResponse.Loaded)
|
||||
{
|
||||
DownloadManager.DownloadCompleted -= handler;
|
||||
throw new ArgumentException("Requested file was not found on the server: " + name);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Queue an action to be executed on next tick.
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
public void QueueAction(Action a)
|
||||
public static void QueueAction(Action a)
|
||||
{
|
||||
WorldThread.QueueAction(a);
|
||||
}
|
||||
public void QueueActionAndWait(Action a, int timeout = 15000)
|
||||
public static void QueueActionAndWait(Action a, int timeout = 15000)
|
||||
{
|
||||
var done = new AutoResetEvent(false);
|
||||
Exception e = null;
|
||||
@ -325,75 +371,5 @@ namespace RageCoop.Client.Scripting
|
||||
{
|
||||
WorldThread.QueueAction(a);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send an event and data to the server.
|
||||
/// </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 void SendCustomEvent(CustomEventHash eventHash, params object[] args)
|
||||
{
|
||||
|
||||
Networking.Peer.SendTo(new Packets.CustomEvent()
|
||||
{
|
||||
Args = args,
|
||||
Hash = eventHash
|
||||
}, Networking.ServerConnection, ConnectionChannel.Event, Lidgren.Network.NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
/// <summary>
|
||||
/// Send an event and data to the server
|
||||
/// </summary>
|
||||
/// <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 void SendCustomEvent(CustomEventFlags flags, CustomEventHash eventHash, params object[] args)
|
||||
{
|
||||
Networking.Peer.SendTo(new Packets.CustomEvent(flags)
|
||||
{
|
||||
Args = args,
|
||||
Hash = eventHash
|
||||
}, Networking.ServerConnection, ConnectionChannel.Event, Lidgren.Network.NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public void RequestSharedFile(string name, Action<string> callback)
|
||||
{
|
||||
EventHandler<string> handler = (s, e) =>
|
||||
{
|
||||
if (e.EndsWith(name))
|
||||
{
|
||||
callback(e);
|
||||
}
|
||||
};
|
||||
DownloadManager.DownloadCompleted += handler;
|
||||
Networking.GetResponse<Packets.FileTransferResponse>(new Packets.FileTransferRequest()
|
||||
{
|
||||
Name = name,
|
||||
},
|
||||
(p) =>
|
||||
{
|
||||
if (p.Response != FileResponse.Loaded)
|
||||
{
|
||||
DownloadManager.DownloadCompleted -= handler;
|
||||
throw new ArgumentException("Requested file was not found on the server: " + name);
|
||||
}
|
||||
});
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,9 @@ namespace RageCoop.Client.Scripting
|
||||
/// </summary>
|
||||
public abstract class ClientScript : GTA.Script
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="Scripting.API"/> instance to communicate with RageCoop
|
||||
/// </summary>
|
||||
protected static API API => Main.API;
|
||||
|
||||
/// <summary>
|
||||
/// This method would be called from main thread, right after the constructor.
|
||||
/// This method would be called from main thread, right after all script constructors are invoked.
|
||||
/// </summary>
|
||||
public abstract void OnStart();
|
||||
|
||||
|
@ -1,218 +0,0 @@
|
||||
using RageCoop.Core;
|
||||
using Console = GTA.Console;
|
||||
using SHVDN;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Concurrent;
|
||||
using static System.Net.WebRequestMethods;
|
||||
|
||||
namespace RageCoop.Client.Scripting
|
||||
{
|
||||
internal class ResourceDomain : MarshalByRefObject, IDisposable
|
||||
{
|
||||
public static ConcurrentDictionary<string, ResourceDomain> LoadedDomains => new ConcurrentDictionary<string, ResourceDomain>(_loadedDomains);
|
||||
static readonly ConcurrentDictionary<string, ResourceDomain> _loadedDomains = new ConcurrentDictionary<string, ResourceDomain>();
|
||||
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
|
||||
{
|
||||
Assembly.LoadFrom(apiPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
PrimaryDomain = primary;
|
||||
primary.Tick += Tick;
|
||||
primary.KeyEvent += KeyEvent;
|
||||
CurrentDomain.Start();
|
||||
SetupScripts();
|
||||
Console.WriteLine($"Loaded domain: {AppDomain.CurrentDomain.FriendlyName}, {AppDomain.CurrentDomain.BaseDirectory}");
|
||||
}
|
||||
public static bool IsLoaded(string dir)
|
||||
{
|
||||
return _loadedDomains.ContainsKey(Path.GetFullPath(dir).ToLower());
|
||||
}
|
||||
public void SetupScripts()
|
||||
{
|
||||
foreach (var s in GetClientScripts())
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
API.Logger.Debug("Starting script: " + s.GetType().FullName);
|
||||
var script = (ClientScript)s;
|
||||
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.ScriptsDirectory.Length + 1).Replace('\\', '/')).FirstOrDefault();
|
||||
res.Scripts.Add(script);
|
||||
s.GetType().Assembly.GetReferencedAssemblies().ForEach(x => Assembly.Load(x.FullName));
|
||||
script.OnStart();
|
||||
}
|
||||
catch (Exception 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().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)
|
||||
{
|
||||
dir = Path.GetFullPath(dir).ToLower();
|
||||
if (!Util.IsPrimaryDomain)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot load in another domain");
|
||||
}
|
||||
if (IsLoaded(dir))
|
||||
{
|
||||
throw new Exception("Already loaded");
|
||||
}
|
||||
ScriptDomain sDomain = null;
|
||||
try
|
||||
{
|
||||
dir = Path.GetFullPath(dir);
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
// Copy test script
|
||||
// File.Copy(@"M:\SandBox-Shared\repos\RAGECOOP\RAGECOOP-V\bin\Debug\TestScript.dll", Path.Combine(dir, Path.GetFileName("TestScript.dll")), true);
|
||||
|
||||
// Load domain in main thread
|
||||
Main.QueueToMainThread(() =>
|
||||
{
|
||||
|
||||
var api = new List<string>();
|
||||
api.Add(typeof(ResourceDomain).Assembly.Location);
|
||||
api.AddRange(typeof(ResourceDomain).Assembly.GetReferencedAssemblies()
|
||||
.Select(x => Assembly.Load(x.FullName).Location)
|
||||
.Where(x => !string.IsNullOrEmpty(x)));
|
||||
|
||||
sDomain = ScriptDomain.Load(Directory.GetParent(typeof(ScriptDomain).Assembly.Location).FullName, dir);
|
||||
sDomain.AppDomain.SetData("Console", ScriptDomain.CurrentDomain.AppDomain.GetData("Console"));
|
||||
sDomain.AppDomain.SetData("RageCoop.Client.API", API.GetInstance());
|
||||
_loadedDomains.TryAdd(dir, (ResourceDomain)sDomain.AppDomain.CreateInstanceFromAndUnwrap(typeof(ResourceDomain).Assembly.Location, typeof(ResourceDomain).FullName, false, BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { ScriptDomain.CurrentDomain, api.ToArray() }, null, null));
|
||||
});
|
||||
|
||||
// Wait till next tick
|
||||
GTA.Script.Yield();
|
||||
return _loadedDomains[dir];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GTA.UI.Notification.Show(ex.ToString());
|
||||
Main.Logger.Error(ex);
|
||||
if (sDomain != null)
|
||||
{
|
||||
ScriptDomain.Unload(sDomain);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Unload(ResourceDomain domain)
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
Exception ex = null;
|
||||
Main.QueueToMainThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
domain.Dispose();
|
||||
ScriptDomain.Unload(domain.CurrentDomain);
|
||||
_loadedDomains.TryRemove(domain.BaseDirectory, out _);
|
||||
}
|
||||
catch (Exception e) { ex = e; }
|
||||
});
|
||||
GTA.Script.Yield();
|
||||
if (ex != null) { throw ex; }
|
||||
}
|
||||
}
|
||||
public static void Unload(string dir)
|
||||
{
|
||||
Unload(_loadedDomains[Path.GetFullPath(dir).ToLower()]);
|
||||
}
|
||||
public static void UnloadAll()
|
||||
{
|
||||
lock (_loadedDomains)
|
||||
{
|
||||
foreach (var d in _loadedDomains.Values.ToArray())
|
||||
{
|
||||
Unload(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Tick(object sender, EventArgs args)
|
||||
{
|
||||
CurrentDomain.DoTick();
|
||||
}
|
||||
|
||||
private void KeyEvent(Keys keys, bool status)
|
||||
{
|
||||
CurrentDomain.DoKeyEvent(keys, status);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
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)
|
||||
{
|
||||
API.Logger.Error($"Failed to stop {s.GetType().FullName}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using SHVDN;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@ -14,7 +15,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ClientResource : MarshalByRefObject
|
||||
public class ClientResource
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the resource
|
||||
@ -59,19 +60,31 @@ namespace RageCoop.Client.Scripting
|
||||
Logger?.Info($"Loading resource: {Path.GetFileNameWithoutExtension(zip)}");
|
||||
Unpack(zipPath, Path.Combine(path, "Data"));
|
||||
}
|
||||
Main.API.QueueActionAndWait(() => ResourceDomain.Load(path));
|
||||
Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories).Where(x => x.CanBeIgnored()).ForEach(x => File.Delete(x));
|
||||
|
||||
// Load it in main thread
|
||||
API.QueueActionAndWait(() =>
|
||||
{
|
||||
Main.QueueToMainThreadAndWait(() =>
|
||||
{
|
||||
Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories).ForEach(x => ScriptDomain.CurrentDomain.StartScripts(x));
|
||||
SetupScripts();
|
||||
});
|
||||
});
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
ResourceDomain.UnloadAll();
|
||||
|
||||
StopScripts();
|
||||
LoadedResources.Clear();
|
||||
Loader.DomainContext.RequestUnload();
|
||||
}
|
||||
|
||||
private void Unpack(string zipPath, string dataFolderRoot)
|
||||
{
|
||||
var r = new ClientResource()
|
||||
{
|
||||
Logger = Main.API.Logger,
|
||||
Logger = API.Logger,
|
||||
Scripts = new List<ClientScript>(),
|
||||
Name = Path.GetFileNameWithoutExtension(zipPath),
|
||||
DataFolder = Path.Combine(dataFolderRoot, Path.GetFileNameWithoutExtension(zipPath)),
|
||||
@ -108,7 +121,58 @@ namespace RageCoop.Client.Scripting
|
||||
r.Files.Add(relativeName, rfile);
|
||||
}
|
||||
|
||||
LoadedResources.TryAdd(r.Name.ToLower(), r);
|
||||
LoadedResources.TryAdd(r.Name, r);
|
||||
}
|
||||
|
||||
void SetupScripts()
|
||||
{
|
||||
foreach (var s in GetClientScripts())
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
API.Logger.Debug("Starting script: " + s.GetType().FullName);
|
||||
var script = (ClientScript)s;
|
||||
if (LoadedResources.TryGetValue(Directory.GetParent(script.Filename).Name, out var r))
|
||||
{
|
||||
script.CurrentResource = r;
|
||||
}
|
||||
else
|
||||
{
|
||||
API.Logger.Warning("Failed to locate resource for script: " + script.Filename);
|
||||
}
|
||||
var res = script.CurrentResource;
|
||||
script.CurrentFile = res?.Files.Values.Where(x => x.Name.ToLower() == script.Filename.Substring(res.ScriptsDirectory.Length + 1).Replace('\\', '/')).FirstOrDefault();
|
||||
res?.Scripts.Add(script);
|
||||
script.OnStart();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
API.Logger.Error($"Failed to start {s.GetType().FullName}", ex);
|
||||
}
|
||||
|
||||
API.Logger.Debug("Started script: " + s.GetType().FullName);
|
||||
}
|
||||
}
|
||||
void StopScripts()
|
||||
{
|
||||
foreach (var s in GetClientScripts())
|
||||
{
|
||||
try
|
||||
{
|
||||
API.Logger.Debug("Stopping script: " + s.GetType().FullName);
|
||||
((ClientScript)s).OnStop();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
API.Logger.Error($"Failed to stop {s.GetType().FullName}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static object[] GetClientScripts()
|
||||
{
|
||||
return ScriptDomain.CurrentDomain.RunningScripts.Where(x =>
|
||||
x.ScriptInstance.GetType().IsScript(typeof(ClientScript))).Select(x => x.ScriptInstance).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ 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();
|
||||
|
@ -8,7 +8,6 @@ namespace RageCoop.Client
|
||||
{
|
||||
internal static class SyncEvents
|
||||
{
|
||||
static readonly Scripting.API API = Main.API;
|
||||
|
||||
#region TRIGGER
|
||||
public static void TriggerPedKilled(SyncedPed victim)
|
||||
|
@ -20,12 +20,6 @@ namespace RageCoop.Client
|
||||
{
|
||||
internal static class Util
|
||||
{
|
||||
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
|
||||
@ -249,11 +243,11 @@ namespace RageCoop.Client
|
||||
// Move log file so it doesn't get deleted
|
||||
Main.Logger.Dispose();
|
||||
|
||||
var path = Main.Logger.LogPath + ".last.log";
|
||||
var path = Main.LogPath + ".last.log";
|
||||
try
|
||||
{
|
||||
if (File.Exists(path)) { File.Delete(path); }
|
||||
if (File.Exists(Main.Logger.LogPath)) { File.Move(Main.Logger.LogPath, path); }
|
||||
if (File.Exists(Main.LogPath)) { File.Move(Main.LogPath, path); }
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -23,7 +23,6 @@ namespace RageCoop.Client
|
||||
public WorldThread()
|
||||
{
|
||||
Instance = this;
|
||||
if (!Util.IsPrimaryDomain) { Abort(); return; }
|
||||
Tick += OnTick;
|
||||
Aborted += (sender, e) =>
|
||||
{
|
||||
|
@ -231,6 +231,11 @@ namespace RageCoop.Core
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public static StreamWriter OpenWriter(string path, FileMode mode = FileMode.Create, FileAccess access = FileAccess.Write, FileShare share = FileShare.ReadWrite)
|
||||
{
|
||||
return new StreamWriter(File.Open(path, mode, access, share));
|
||||
}
|
||||
}
|
||||
internal class IpInfo
|
||||
{
|
||||
@ -412,13 +417,11 @@ namespace RageCoop.Core
|
||||
return output;
|
||||
}
|
||||
|
||||
public static bool IsSubclassOf(this Type type, string baseTypeName)
|
||||
public static bool IsScript(this Type type,Type scriptType)
|
||||
{
|
||||
for (Type t = type.BaseType; t != null; t = t.BaseType)
|
||||
if (t.FullName == baseTypeName)
|
||||
return true;
|
||||
return false;
|
||||
return !type.IsAbstract && type.IsSubclassOf(scriptType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,4 +1,7 @@
|
||||
using System;
|
||||
using GTA.NaturalMotion;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
@ -6,12 +9,28 @@ using System.Threading;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
Trace = 0,
|
||||
Debug = 1,
|
||||
Info = 2,
|
||||
Warning = 3,
|
||||
Error = 4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Logger : MarshalByRefObject,IDisposable
|
||||
public class Logger : MarshalByRefObject, IDisposable
|
||||
{
|
||||
|
||||
public class LogLine
|
||||
{
|
||||
internal LogLine() { }
|
||||
public DateTime TimeStamp;
|
||||
public LogLevel LogLevel;
|
||||
public string Message;
|
||||
}
|
||||
/// <summary>
|
||||
/// 0:Trace, 1:Debug, 2:Info, 3:Warning, 4:Error
|
||||
/// </summary>
|
||||
@ -19,40 +38,29 @@ namespace RageCoop.Core
|
||||
/// <summary>
|
||||
/// Name of this logger
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Path to log file.
|
||||
/// </summary>
|
||||
public string LogPath;
|
||||
/// <summary>
|
||||
/// Whether to flush messages to console instead of log file
|
||||
/// </summary>
|
||||
public bool UseConsole = false;
|
||||
private StreamWriter logWriter;
|
||||
public string Name = "Logger";
|
||||
public readonly string DateTimeFormat = "HH:mm:ss";
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use UTC time for timestamping the log
|
||||
/// </summary>
|
||||
public readonly bool UseUtc = false;
|
||||
public List<StreamWriter> Writers = new List<StreamWriter> { new StreamWriter(Console.OpenStandardOutput()) };
|
||||
public int FlushInterval = 1000;
|
||||
public event FlushDelegate OnFlush;
|
||||
public bool FlushImmediately = false;
|
||||
public delegate void FlushDelegate(LogLine line, string fomatted);
|
||||
|
||||
private string Buffer = "";
|
||||
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)
|
||||
private readonly ConcurrentQueue<LogLine> _queuedLines = new ConcurrentQueue<LogLine>();
|
||||
internal Logger()
|
||||
{
|
||||
FlushImmediately = flushImmediately;
|
||||
if (File.Exists(LogPath) && overwrite) { File.Delete(LogPath); }
|
||||
Name = Process.GetCurrentProcess().Id.ToString();
|
||||
if (!flushImmediately)
|
||||
if (!FlushImmediately)
|
||||
{
|
||||
LoggerThread = new Thread(() =>
|
||||
{
|
||||
if (!UseConsole)
|
||||
{
|
||||
while (LogPath == default)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
if (File.Exists(LogPath) && overwrite) { File.Delete(LogPath); }
|
||||
}
|
||||
while (!Stopping)
|
||||
{
|
||||
Flush();
|
||||
@ -69,17 +77,7 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Info(string message)
|
||||
{
|
||||
if (LogLevel > 2) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [INF] {1}", Date(), message, Name);
|
||||
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
Enqueue(2, message);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -87,18 +85,7 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Warning(string message)
|
||||
{
|
||||
if (LogLevel > 3) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [WRN] {1}", Date(), message, Name);
|
||||
|
||||
Buffer += msg + "\r\n";
|
||||
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
Enqueue(3, message);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -106,17 +93,7 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Error(string message)
|
||||
{
|
||||
if (LogLevel > 4) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}", Date(), message, Name);
|
||||
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
Enqueue(4, message);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -125,18 +102,7 @@ namespace RageCoop.Core
|
||||
/// <param name="error"></param>
|
||||
public void Error(string message, Exception error)
|
||||
{
|
||||
if (LogLevel > 4) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}:{3}", Date(), message, Name, error.Message);
|
||||
Buffer += msg + "\r\n";
|
||||
Trace(error.ToString());
|
||||
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
Enqueue(4, $"{message}:\n {error}");
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -144,17 +110,7 @@ namespace RageCoop.Core
|
||||
/// <param name="ex"></param>
|
||||
public void Error(Exception ex)
|
||||
{
|
||||
if (LogLevel > 4) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}", Date(), "\r\n" + ex.Message, Name);
|
||||
Buffer += msg + "\r\n";
|
||||
Trace(ex.ToString());
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
Enqueue(4, ex.ToString());
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -162,18 +118,7 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Debug(string message)
|
||||
{
|
||||
|
||||
if (LogLevel > 1) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [DBG] {1}", Date(), message, Name);
|
||||
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
Enqueue(1, message);
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -181,51 +126,43 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Trace(string message)
|
||||
{
|
||||
if (LogLevel > 0) { return; }
|
||||
lock (Buffer)
|
||||
Enqueue(0, message);
|
||||
}
|
||||
public void Enqueue(int level, string message)
|
||||
{
|
||||
if (level < LogLevel) { return; }
|
||||
_queuedLines.Enqueue(new LogLine()
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [TRC] {1}", Date(), message, Name);
|
||||
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
Message = message,
|
||||
TimeStamp = UseUtc ? DateTime.UtcNow : DateTime.Now,
|
||||
LogLevel = (LogLevel)level
|
||||
});
|
||||
if (FlushImmediately)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
}
|
||||
|
||||
private string Date()
|
||||
string Format(LogLine line)
|
||||
{
|
||||
return DateTime.Now.ToString("HH:mm:ss");
|
||||
return string.Format("[{0}][{2}] [{3}] {1}", line.TimeStamp.ToString(DateTimeFormat), line.Message, Name, line.LogLevel.ToString());
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Flush()
|
||||
{
|
||||
lock (Buffer)
|
||||
lock (_queuedLines)
|
||||
{
|
||||
if (Buffer != "")
|
||||
try
|
||||
{
|
||||
if (UseConsole)
|
||||
while (_queuedLines.TryDequeue(out var line))
|
||||
{
|
||||
Console.Write(Buffer);
|
||||
Buffer = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
logWriter = new StreamWriter(LogPath, true, Encoding.UTF8);
|
||||
logWriter.Write(Buffer);
|
||||
logWriter.Close();
|
||||
OnFlush?.Invoke(this,Buffer);
|
||||
Buffer = "";
|
||||
}
|
||||
catch { }
|
||||
var formatted = Format(line);
|
||||
Writers.ForEach(x => { x.WriteLine(formatted); x.Flush(); });
|
||||
OnFlush?.Invoke(line, formatted);
|
||||
}
|
||||
}
|
||||
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -144,7 +144,7 @@ namespace RageCoop.Core
|
||||
void Deserialize(NetIncomingMessage m);
|
||||
}
|
||||
|
||||
internal abstract class Packet : MarshalByRefObject, IPacket
|
||||
internal abstract class Packet : 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 class CustomEventHash : MarshalByRefObject
|
||||
public struct CustomEventHash
|
||||
{
|
||||
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 : MarshalByRefObject
|
||||
public class ResourceFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Full name with relative path of this file
|
||||
|
@ -38,10 +38,9 @@ namespace RageCoop.Server
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
|
||||
mainLogger = new Logger()
|
||||
{
|
||||
LogPath = "RageCoop.Server.log",
|
||||
UseConsole = true,
|
||||
Name = "Server"
|
||||
};
|
||||
mainLogger.Writers.Add(CoreUtils.OpenWriter("RageCoop.Server.log"));
|
||||
try
|
||||
{
|
||||
Console.Title = "RAGECOOP";
|
||||
|
@ -15,7 +15,7 @@ using System.Resources;
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information
|
||||
[assembly: AssemblyVersion("1.5.4.45")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.45")]
|
||||
[assembly: AssemblyVersion("1.5.4.66")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.66")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user