Reworked on resource loading, Added RegisterCommands overload to register commands from an instance.
This commit is contained in:
@ -31,6 +31,8 @@ namespace RageCoop.Client.Menus
|
|||||||
public static NativeMenu LastMenu { get; set; } = Menu;
|
public static NativeMenu LastMenu { get; set; } = Menu;
|
||||||
#region ITEMS
|
#region ITEMS
|
||||||
private static readonly NativeItem _usernameItem = new NativeItem("Username") { AltTitle = Main.Settings.Username };
|
private static readonly NativeItem _usernameItem = new NativeItem("Username") { AltTitle = Main.Settings.Username };
|
||||||
|
private static readonly NativeItem _passwordItem = new NativeItem("Password") { AltTitle = new string('*',Main.Settings.Password.Length) };
|
||||||
|
|
||||||
public static readonly NativeItem ServerIpItem = new NativeItem("Server IP") { AltTitle = Main.Settings.LastServerAddress };
|
public static readonly NativeItem ServerIpItem = new NativeItem("Server IP") { AltTitle = Main.Settings.LastServerAddress };
|
||||||
private static readonly NativeItem _serverConnectItem = new NativeItem("Connect");
|
private static readonly NativeItem _serverConnectItem = new NativeItem("Connect");
|
||||||
private static readonly NativeItem _aboutItem = new NativeItem("About", "~y~SOURCE~s~~n~" +
|
private static readonly NativeItem _aboutItem = new NativeItem("About", "~y~SOURCE~s~~n~" +
|
||||||
@ -51,6 +53,7 @@ namespace RageCoop.Client.Menus
|
|||||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||||
|
|
||||||
_usernameItem.Activated += UsernameActivated;
|
_usernameItem.Activated += UsernameActivated;
|
||||||
|
_passwordItem.Activated+=_passwordActivated;
|
||||||
ServerIpItem.Activated += ServerIpActivated;
|
ServerIpItem.Activated += ServerIpActivated;
|
||||||
_serverConnectItem.Activated += (sender, item) => { Networking.ToggleConnection(Main.Settings.LastServerAddress); };
|
_serverConnectItem.Activated += (sender, item) => { Networking.ToggleConnection(Main.Settings.LastServerAddress); };
|
||||||
|
|
||||||
@ -58,6 +61,7 @@ namespace RageCoop.Client.Menus
|
|||||||
Menu.AddSubMenu(ServersMenu.Menu);
|
Menu.AddSubMenu(ServersMenu.Menu);
|
||||||
|
|
||||||
Menu.Add(_usernameItem);
|
Menu.Add(_usernameItem);
|
||||||
|
Menu.Add(_passwordItem);
|
||||||
Menu.Add(ServerIpItem);
|
Menu.Add(ServerIpItem);
|
||||||
Menu.Add(_serverConnectItem);
|
Menu.Add(_serverConnectItem);
|
||||||
|
|
||||||
@ -76,6 +80,8 @@ namespace RageCoop.Client.Menus
|
|||||||
|
|
||||||
Menu.Add(_aboutItem);
|
Menu.Add(_aboutItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static bool ShowPopUp(string prompt, string title,string subtitle,string error,bool showbackground)
|
public static bool ShowPopUp(string prompt, string title,string subtitle,string error,bool showbackground)
|
||||||
{
|
{
|
||||||
PopUp.Prompt=prompt;
|
PopUp.Prompt=prompt;
|
||||||
@ -113,6 +119,16 @@ namespace RageCoop.Client.Menus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void _passwordActivated(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
string newPass = Game.GetUserInput(WindowTitle.EnterMessage20, "", 20);
|
||||||
|
if (!string.IsNullOrWhiteSpace(newPass))
|
||||||
|
{
|
||||||
|
Main.Settings.Password = newPass;
|
||||||
|
Util.SaveSettings();
|
||||||
|
_passwordItem.AltTitle = new string('*', newPass.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
public static void ServerIpActivated(object a, System.EventArgs b)
|
public static void ServerIpActivated(object a, System.EventArgs b)
|
||||||
{
|
{
|
||||||
string newServerIp = Game.GetUserInput(WindowTitle.EnterMessage60, ServerIpItem.AltTitle, 60);
|
string newServerIp = Game.GetUserInput(WindowTitle.EnterMessage60, ServerIpItem.AltTitle, 60);
|
||||||
|
@ -39,7 +39,7 @@ namespace RageCoop.Client
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ToggleConnection(string address,string password=null)
|
public static void ToggleConnection(string address,string username=null,string password=null)
|
||||||
{
|
{
|
||||||
if (IsOnServer)
|
if (IsOnServer)
|
||||||
{
|
{
|
||||||
@ -48,6 +48,7 @@ namespace RageCoop.Client
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
password = password ?? Main.Settings.Password;
|
password = password ?? Main.Settings.Password;
|
||||||
|
username=username ?? Main.Settings.Username;
|
||||||
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
|
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
|
||||||
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
|
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
|
||||||
{
|
{
|
||||||
@ -85,7 +86,7 @@ namespace RageCoop.Client
|
|||||||
var handshake=new Packets.Handshake()
|
var handshake=new Packets.Handshake()
|
||||||
{
|
{
|
||||||
PedID = Main.LocalPlayerID,
|
PedID = Main.LocalPlayerID,
|
||||||
Username = Main.Settings.Username,
|
Username =username,
|
||||||
ModVersion = Main.CurrentVersion,
|
ModVersion = Main.CurrentVersion,
|
||||||
PassHashEncrypted=Security.Encrypt(password.GetHash())
|
PassHashEncrypted=Security.Encrypt(password.GetHash())
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net48</TargetFramework>
|
<TargetFramework>net48</TargetFramework>
|
||||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
<OutputPath>D:\Games\Grand Theft Auto V\Scripts\RageCoop</OutputPath>
|
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
||||||
@ -13,13 +12,26 @@
|
|||||||
<AssemblyVersion>0.5.0</AssemblyVersion>
|
<AssemblyVersion>0.5.0</AssemblyVersion>
|
||||||
<FileVersion>0.5.0</FileVersion>
|
<FileVersion>0.5.0</FileVersion>
|
||||||
<Version>0.5.0</Version>
|
<Version>0.5.0</Version>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<Authors>RAGECOOP</Authors>
|
||||||
|
<Description>An API reference for developing client-side resource for RAGECOOP</Description>
|
||||||
|
<PackageProjectUrl>https://ragecoop.online/</PackageProjectUrl>
|
||||||
|
<RepositoryUrl>https://github.com/RAGECOOP/RAGECOOP-V</RepositoryUrl>
|
||||||
|
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||||
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
|
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<Optimize>True</Optimize>
|
<Optimize>True</Optimize>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DotNetZip" Version="1.16.0" />
|
<Content Include="favicon.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\RageCoop.Core\RageCoop.Core.csproj" />
|
<ProjectReference Include="..\RageCoop.Core\RageCoop.Core.csproj" />
|
||||||
|
@ -31,11 +31,7 @@ namespace RageCoop.Client.Scripting
|
|||||||
List<InputArgument> arguments = new List<InputArgument>();
|
List<InputArgument> arguments = new List<InputArgument>();
|
||||||
int i;
|
int i;
|
||||||
var ty = (byte)e.Args[0];
|
var ty = (byte)e.Args[0];
|
||||||
Main.Logger.Debug($"gettype");
|
|
||||||
Main.Logger.Flush();
|
|
||||||
TypeCode returnType=(TypeCode)ty;
|
TypeCode returnType=(TypeCode)ty;
|
||||||
Main.Logger.Debug($"typeok");
|
|
||||||
Main.Logger.Flush();
|
|
||||||
i = returnType==TypeCode.Empty ? 1 : 2;
|
i = returnType==TypeCode.Empty ? 1 : 2;
|
||||||
var hash = (Hash)e.Args[i++];
|
var hash = (Hash)e.Args[i++];
|
||||||
for(; i<e.Args.Count;i++)
|
for(; i<e.Args.Count;i++)
|
||||||
|
@ -3,21 +3,17 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Inherit from this class, constructor will be called automatically, but other scripts might have yet been loaded, you should use <see cref="OnStart"/>. to initiate your script.
|
/// Inherit from this class, constructor will be called automatically, but other scripts might have yet been loaded, you should use <see cref="OnStart"/>. to initiate your script.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ClientScript:Core.Scripting.IScriptable
|
public abstract class ClientScript:Core.Scripting.Scriptable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method would be called from main thread shortly after all scripts have been loaded.
|
/// This method would be called from main thread shortly after all scripts have been loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void OnStart();
|
public override abstract void OnStart();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method would be called from main thread when the client disconnected from the server, you MUST terminate all background jobs/threads in this method.
|
/// This method would be called from main thread when the client disconnected from the server, you MUST terminate all background jobs/threads in this method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void OnStop();
|
public override abstract void OnStop();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the <see cref="Core.Scripting.Resource"/> object this script belongs to, this property will be initiated before <see cref="OnStart"/> (will be null if you access it in the constructor).
|
|
||||||
/// </summary>
|
|
||||||
public Core.Scripting.Resource CurrentResource { get; internal set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using RageCoop.Core.Scripting;
|
using RageCoop.Core.Scripting;
|
||||||
using Ionic.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
|
|
||||||
namespace RageCoop.Client.Scripting
|
namespace RageCoop.Client.Scripting
|
||||||
{
|
{
|
||||||
@ -15,7 +15,6 @@ namespace RageCoop.Client.Scripting
|
|||||||
{
|
{
|
||||||
foreach (var s in d.Scripts)
|
foreach (var s in d.Scripts)
|
||||||
{
|
{
|
||||||
(s as ClientScript).CurrentResource=d;
|
|
||||||
Main.QueueAction(() => s.OnStart());
|
Main.QueueAction(() => s.OnStart());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,23 +36,23 @@ namespace RageCoop.Client.Scripting
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load all resources from the server
|
/// Load all resources from the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path to the directory containing the resources.</param>
|
/// <param name="path">The path to the directory containing all resources to load.</param>
|
||||||
public void Load(string path)
|
public void Load(string path)
|
||||||
{
|
{
|
||||||
Unload();
|
Unload();
|
||||||
foreach (var d in Directory.GetDirectories(path))
|
foreach (var d in Directory.GetDirectories(path))
|
||||||
|
{
|
||||||
|
if(Path.GetFileName(d).ToLower() != "data")
|
||||||
{
|
{
|
||||||
Directory.Delete(d, true);
|
Directory.Delete(d, true);
|
||||||
}
|
}
|
||||||
using (var zip = ZipFile.Read(Path.Combine(path, "Resources.zip")))
|
|
||||||
{
|
|
||||||
zip.ExtractAll(path, ExtractExistingFileAction.OverwriteSilently);
|
|
||||||
}
|
}
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
foreach (var resource in Directory.GetDirectories(path))
|
foreach (var resource in Directory.GetDirectories(path))
|
||||||
{
|
{
|
||||||
|
if (Path.GetFileName(resource).ToLower()!="data") { continue; }
|
||||||
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
|
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
|
||||||
LoadResource(resource);
|
LoadResource(resource,Path.Combine(path,"data"));
|
||||||
}
|
}
|
||||||
StartAll();
|
StartAll();
|
||||||
}
|
}
|
||||||
|
BIN
RageCoop.Client/favicon.ico
Normal file
BIN
RageCoop.Client/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@ -22,6 +22,11 @@
|
|||||||
<None Include="Lidgren.Network\Lidgren.Network.csproj" />
|
<None Include="Lidgren.Network\Lidgren.Network.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||||
|
<PackageReference Include="System.Buffers" Version="4.5.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Newtonsoft.Json">
|
<Reference Include="Newtonsoft.Json">
|
||||||
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Linq;
|
|
||||||
namespace RageCoop.Core.Scripting
|
|
||||||
{
|
|
||||||
public interface IScriptable
|
|
||||||
{
|
|
||||||
void OnStart();
|
|
||||||
void OnStop();
|
|
||||||
}
|
|
||||||
}
|
|
27
RageCoop.Core/Scripting/Resource.cs
Normal file
27
RageCoop.Core/Scripting/Resource.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace RageCoop.Core.Scripting
|
||||||
|
{
|
||||||
|
public class Resource
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the resource
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; internal set; }
|
||||||
|
/// <summary>
|
||||||
|
/// A resource-specific folder that can be used to store your files.
|
||||||
|
/// </summary>
|
||||||
|
public string DataFolder { get;internal set; }
|
||||||
|
public List<Scriptable> Scripts { get; internal set; } = new List<Scriptable>();
|
||||||
|
public Dictionary<string,ResourceFile> Files { get; internal set; }=new Dictionary<string,ResourceFile>();
|
||||||
|
}
|
||||||
|
public class ResourceFile
|
||||||
|
{
|
||||||
|
public string Name { get; internal set; }
|
||||||
|
public bool IsDirectory { get; internal set; }
|
||||||
|
public Func<Stream> GetStream { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
@ -5,23 +5,13 @@ using System.Reflection;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("RageCoop.Server")]
|
[assembly: InternalsVisibleTo("RageCoop.Server")]
|
||||||
[assembly: InternalsVisibleTo("RageCoop.Client")]
|
[assembly: InternalsVisibleTo("RageCoop.Client")]
|
||||||
namespace RageCoop.Core.Scripting
|
namespace RageCoop.Core.Scripting
|
||||||
{
|
{
|
||||||
public class Resource
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Name of the resource
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get;internal set; }
|
|
||||||
/// <summary>
|
|
||||||
/// The directory of current resource
|
|
||||||
/// </summary>
|
|
||||||
public string Directory { get;internal set; }
|
|
||||||
public List<IScriptable> Scripts { get; internal set; }=new List<IScriptable>();
|
|
||||||
}
|
|
||||||
internal class ResourceLoader
|
internal class ResourceLoader
|
||||||
{
|
{
|
||||||
protected List<string> ToIgnore = new List<string>
|
protected List<string> ToIgnore = new List<string>
|
||||||
@ -40,20 +30,77 @@ namespace RageCoop.Core.Scripting
|
|||||||
Logger = logger;
|
Logger = logger;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load all assemblies inside the resource directory.
|
/// Load a resource from a directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path of the directory.</param>
|
/// <param name="path">Path of the directory.</param>
|
||||||
protected void LoadResource(string path)
|
protected void LoadResource(string path,string dataFolderRoot)
|
||||||
{
|
{
|
||||||
var r = new Resource()
|
var r = new Resource()
|
||||||
{
|
{
|
||||||
Scripts = new List<IScriptable>(),
|
Scripts = new List<Scriptable>(),
|
||||||
Name=Path.GetFileName(path),
|
Name=Path.GetFileName(path),
|
||||||
Directory=path,
|
DataFolder=Path.Combine(dataFolderRoot, Path.GetFileName(path))
|
||||||
};
|
};
|
||||||
foreach (var f in Directory.GetFiles(path, "*.dll"))
|
Directory.CreateDirectory(r.DataFolder);
|
||||||
|
foreach (var dir in Directory.GetDirectories(path, "*", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
LoadScriptsFromAssembly(f, r);
|
r.Files.Add(dir, new ResourceFile()
|
||||||
|
{
|
||||||
|
IsDirectory=true,
|
||||||
|
Name=dir.Substring(path.Length+1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
foreach (var file in Directory.GetFiles(path,"*",SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
var relativeName = file.Substring(path.Length+1);
|
||||||
|
var rfile = new ResourceFile()
|
||||||
|
{
|
||||||
|
GetStream=() => { return new FileStream(file, FileMode.Open, FileAccess.Read); },
|
||||||
|
IsDirectory=false,
|
||||||
|
Name=relativeName
|
||||||
|
};
|
||||||
|
if (file.EndsWith(".dll"))
|
||||||
|
{
|
||||||
|
LoadScriptsFromAssembly(rfile,file, r);
|
||||||
|
}
|
||||||
|
r.Files.Add(relativeName,rfile);
|
||||||
|
}
|
||||||
|
LoadedResources.Add(r);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Load a resource from a zip
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="file"></param>
|
||||||
|
protected void LoadResource(ZipFile file,string dataFolderRoot)
|
||||||
|
{
|
||||||
|
var r = new Resource()
|
||||||
|
{
|
||||||
|
Scripts = new List<Scriptable>(),
|
||||||
|
Name=Path.GetFileNameWithoutExtension(file.Name),
|
||||||
|
DataFolder=Path.Combine(dataFolderRoot, Path.GetFileNameWithoutExtension(file.Name))
|
||||||
|
};
|
||||||
|
Directory.CreateDirectory(r.DataFolder);
|
||||||
|
|
||||||
|
foreach (ZipEntry entry in file)
|
||||||
|
{
|
||||||
|
ResourceFile rFile;
|
||||||
|
r.Files.Add(entry.Name, rFile=new ResourceFile()
|
||||||
|
{
|
||||||
|
Name=entry.Name,
|
||||||
|
IsDirectory=entry.IsDirectory,
|
||||||
|
});
|
||||||
|
if (!entry.IsDirectory)
|
||||||
|
{
|
||||||
|
rFile.GetStream=() => { return file.GetInputStream(entry); };
|
||||||
|
if (entry.Name.EndsWith(".dll"))
|
||||||
|
{
|
||||||
|
var tmp = Path.GetTempFileName();
|
||||||
|
var f = File.OpenWrite(tmp);
|
||||||
|
rFile.GetStream().CopyTo(f);
|
||||||
|
f.Close();
|
||||||
|
LoadScriptsFromAssembly(rFile, tmp, r, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LoadedResources.Add(r);
|
LoadedResources.Add(r);
|
||||||
}
|
}
|
||||||
@ -62,31 +109,38 @@ namespace RageCoop.Core.Scripting
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path to the assembly file to load.</param>
|
/// <param name="path">The path to the assembly file to load.</param>
|
||||||
/// <returns><see langword="true" /> on success, <see langword="false" /> otherwise</returns>
|
/// <returns><see langword="true" /> on success, <see langword="false" /> otherwise</returns>
|
||||||
protected bool LoadScriptsFromAssembly(string path, Resource domain)
|
private bool LoadScriptsFromAssembly(ResourceFile file,string path, Resource resource,bool shadowCopy=true)
|
||||||
{
|
{
|
||||||
lock (LoadedResources)
|
lock (LoadedResources)
|
||||||
{
|
{
|
||||||
if (!IsManagedAssembly(path)) { return false; }
|
if (!IsManagedAssembly(path)) { return false; }
|
||||||
if (ToIgnore.Contains(Path.GetFileName(path))) { try { File.Delete(path); } catch { }; return false; }
|
if (ToIgnore.Contains(file.Name)) { try { File.Delete(path); } catch { }; return false; }
|
||||||
|
|
||||||
Logger?.Debug($"Loading assembly {Path.GetFileName(path)} ...");
|
Logger?.Debug($"Loading assembly {file.Name} ...");
|
||||||
|
|
||||||
Assembly assembly;
|
Assembly assembly;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (shadowCopy)
|
||||||
{
|
{
|
||||||
var temp = Path.GetTempFileName();
|
var temp = Path.GetTempFileName();
|
||||||
File.Copy(path, temp, true);
|
File.Copy(path, temp, true);
|
||||||
assembly = Assembly.LoadFrom(temp);
|
assembly = Assembly.LoadFrom(temp);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assembly = Assembly.LoadFrom(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger?.Error("Unable to load "+Path.GetFileName(path));
|
Logger?.Error("Unable to load "+file.Name);
|
||||||
Logger?.Error(ex);
|
Logger?.Error(ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LoadScriptsFromAssembly(assembly, path, domain);
|
return LoadScriptsFromAssembly(file,assembly, path, resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -95,7 +149,7 @@ namespace RageCoop.Core.Scripting
|
|||||||
/// <param name="filename">The path to the file associated with this assembly.</param>
|
/// <param name="filename">The path to the file associated with this assembly.</param>
|
||||||
/// <param name="assembly">The assembly to load.</param>
|
/// <param name="assembly">The assembly to load.</param>
|
||||||
/// <returns><see langword="true" /> on success, <see langword="false" /> otherwise</returns>
|
/// <returns><see langword="true" /> on success, <see langword="false" /> otherwise</returns>
|
||||||
private bool LoadScriptsFromAssembly(Assembly assembly, string filename, Resource toload)
|
private bool LoadScriptsFromAssembly(ResourceFile rfile,Assembly assembly, string filename, Resource toload)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
@ -110,7 +164,10 @@ namespace RageCoop.Core.Scripting
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Invoke script constructor
|
// Invoke script constructor
|
||||||
toload.Scripts.Add(constructor.Invoke(null) as IScriptable);
|
var script = constructor.Invoke(null) as Scriptable;
|
||||||
|
script.CurrentResource = toload;
|
||||||
|
script.CurrentFile=rfile;
|
||||||
|
toload.Scripts.Add(script);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -127,7 +184,7 @@ namespace RageCoop.Core.Scripting
|
|||||||
}
|
}
|
||||||
catch (ReflectionTypeLoadException ex)
|
catch (ReflectionTypeLoadException ex)
|
||||||
{
|
{
|
||||||
Logger?.Error($"Failed to load assembly {Path.GetFileName(filename)}: ");
|
Logger?.Error($"Failed to load assembly {rfile.Name}: ");
|
||||||
Logger?.Error(ex);
|
Logger?.Error(ex);
|
||||||
foreach (var e in ex.LoaderExceptions)
|
foreach (var e in ex.LoaderExceptions)
|
||||||
{
|
{
|
||||||
@ -136,7 +193,7 @@ namespace RageCoop.Core.Scripting
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger?.Info($"Loaded {count} script(s) in {Path.GetFileName(filename)}");
|
Logger?.Info($"Loaded {count} script(s) in {rfile.Name}");
|
||||||
return count != 0;
|
return count != 0;
|
||||||
}
|
}
|
||||||
private bool IsManagedAssembly(string filename)
|
private bool IsManagedAssembly(string filename)
|
||||||
|
25
RageCoop.Core/Scripting/Scriptable.cs
Normal file
25
RageCoop.Core/Scripting/Scriptable.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Linq;
|
||||||
|
namespace RageCoop.Core.Scripting
|
||||||
|
{
|
||||||
|
public abstract class Scriptable
|
||||||
|
{
|
||||||
|
public abstract void OnStart();
|
||||||
|
public abstract void OnStop();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the <see cref="ResourceFile"/> instance where this script is loaded from.
|
||||||
|
/// </summary>
|
||||||
|
public ResourceFile CurrentFile { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the <see cref="Resource"/> object this script belongs to, this property will be initiated before <see cref="OnStart"/> (will be null if you access it in the constructor).
|
||||||
|
/// </summary>
|
||||||
|
public Resource CurrentResource { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
@ -9,11 +9,14 @@
|
|||||||
<PackageProjectUrl>https://ragecoop.online/</PackageProjectUrl>
|
<PackageProjectUrl>https://ragecoop.online/</PackageProjectUrl>
|
||||||
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<Product>$(AssemblyName)-V</Product>
|
<Product>$(AssemblyName)</Product>
|
||||||
<PackageId>RAGECOOP-V</PackageId>
|
<PackageId>RageCoop.Server</PackageId>
|
||||||
<Authors>RAGECOOP</Authors>
|
<Authors>RAGECOOP</Authors>
|
||||||
<Version>0.5</Version>
|
<Version>0.5</Version>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<Description>An library for hosting a RAGECOOP server or API reference for developing a resource.</Description>
|
||||||
|
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -23,7 +26,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DotNetZip" Version="1.16.0" />
|
<Content Include="favicon.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using RageCoop.Core;
|
using RageCoop.Core;
|
||||||
using RageCoop.Core.Scripting;
|
using RageCoop.Core.Scripting;
|
||||||
|
using System.Reflection;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace RageCoop.Server.Scripting
|
namespace RageCoop.Server.Scripting
|
||||||
@ -221,14 +222,30 @@ namespace RageCoop.Server.Scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register a class of commands
|
/// Register all commands in a static class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The name of your class with functions</typeparam>
|
/// <typeparam name="T">Your static class with commands</typeparam>
|
||||||
public void RegisterCommands<T>()
|
public void RegisterCommands<T>()
|
||||||
{
|
{
|
||||||
Server.RegisterCommands<T>();
|
Server.RegisterCommands<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register all commands inside an class instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The instance of type containing the commands</param>
|
||||||
|
public void RegisterCommands(object obj)
|
||||||
|
{
|
||||||
|
IEnumerable<MethodInfo> commands = obj.GetType().GetMethods().Where(method => method.GetCustomAttributes(typeof(Command), false).Any());
|
||||||
|
|
||||||
|
foreach (MethodInfo method in commands)
|
||||||
|
{
|
||||||
|
Command attribute = method.GetCustomAttribute<Command>(true);
|
||||||
|
RegisterCommand(attribute.Name, attribute.Usage, attribute.ArgsLength,
|
||||||
|
(ctx) => { method.Invoke(obj, new object[] { ctx }); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send an event and data to the specified clients. Use <see cref="Client.SendCustomEvent(int, List{object})"/> if you want to send event to individual client.
|
/// Send an event and data to the specified clients. Use <see cref="Client.SendCustomEvent(int, List{object})"/> if you want to send event to individual client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,7 +34,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The hashed value of client password, sent with RSA asymmetric encryption.
|
/// The client password hashed with SHA256 algorithm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PasswordHash { get; set; }
|
public string PasswordHash { get; set; }
|
||||||
public IPEndPoint EndPoint { get; set; }
|
public IPEndPoint EndPoint { get; set; }
|
||||||
|
@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using RageCoop.Core.Scripting;
|
using RageCoop.Core.Scripting;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Ionic.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
namespace RageCoop.Server.Scripting
|
namespace RageCoop.Server.Scripting
|
||||||
{
|
{
|
||||||
@ -16,64 +16,95 @@ namespace RageCoop.Server.Scripting
|
|||||||
{
|
{
|
||||||
Server = server;
|
Server = server;
|
||||||
}
|
}
|
||||||
|
private List<string> ClientResourceZips=new List<string>();
|
||||||
public bool HasClientResources = false;
|
public bool HasClientResources { get; private set; }
|
||||||
public void LoadAll()
|
public void LoadAll()
|
||||||
{
|
{
|
||||||
#region CLIENT
|
#region CLIENT
|
||||||
var path = Path.Combine("Resources", "Client");
|
var path = Path.Combine("Resources", "Client");
|
||||||
|
var tmp = Path.Combine("Resources", "ClientTemp");
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
var clientResources = Directory.GetDirectories(path);
|
if (Directory.Exists(tmp))
|
||||||
if (clientResources.Length!=0)
|
|
||||||
{
|
{
|
||||||
// Pack client side resources as a zip file
|
foreach(var dir in Directory.GetDirectories(tmp))
|
||||||
Logger?.Info("Packing client-side resources");
|
{
|
||||||
|
Directory.Delete(dir, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(tmp);
|
||||||
|
}
|
||||||
|
var resourceFolders = Directory.GetDirectories(path,"*",SearchOption.TopDirectoryOnly);
|
||||||
|
if (resourceFolders.Length!=0)
|
||||||
|
{
|
||||||
|
HasClientResources=true;
|
||||||
|
foreach (var resourceFolder in resourceFolders)
|
||||||
|
{
|
||||||
|
// Pack client side resource as a zip file
|
||||||
|
Logger?.Info("Packing client-side resource:"+resourceFolder);
|
||||||
|
var zipPath = Path.Combine(tmp, Path.GetFileName(resourceFolder));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var zippath = Path.Combine(path, "Resources.zip");
|
using (ZipFile zip = ZipFile.Create(zipPath))
|
||||||
if (File.Exists(zippath))
|
|
||||||
{
|
{
|
||||||
File.Delete(zippath);
|
foreach (var dir in Directory.GetDirectories(resourceFolder, "*", SearchOption.AllDirectories))
|
||||||
}
|
|
||||||
using (ZipFile zip = new ZipFile())
|
|
||||||
{
|
{
|
||||||
zip.AddDirectory(path);
|
zip.AddDirectory(dir.Substring(resourceFolder.Length+1));
|
||||||
zip.Save(zippath);
|
}
|
||||||
|
foreach (var file in Directory.GetFiles(resourceFolder, "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
zip.Add(file,file.Substring(resourceFolder.Length+1));
|
||||||
|
}
|
||||||
|
zip.Close();
|
||||||
|
ClientResourceZips.Add(zipPath);
|
||||||
}
|
}
|
||||||
HasClientResources=true;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger?.Error("Failed to pack client resources");
|
Logger?.Error($"Failed to pack client resource:{resourceFolder}");
|
||||||
Logger?.Error(ex);
|
Logger?.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
var packed = Directory.GetFiles(path, "*.zip", SearchOption.TopDirectoryOnly);
|
||||||
|
if (packed.Length>0)
|
||||||
|
{
|
||||||
|
HasClientResources =true;
|
||||||
|
ClientResourceZips.AddRange(packed);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SERVER
|
#region SERVER
|
||||||
path = Path.Combine("Resources", "Server");
|
path = Path.Combine("Resources", "Server");
|
||||||
|
var dataFolder = Path.Combine(path, "data");
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
foreach (var resource in Directory.GetDirectories(path))
|
foreach (var resource in Directory.GetDirectories(path))
|
||||||
{
|
{
|
||||||
|
if (Path.GetFileName(resource).ToLower()=="data") { continue; }
|
||||||
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
|
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
|
||||||
LoadResource(resource);
|
LoadResource(resource,dataFolder);
|
||||||
|
}
|
||||||
|
foreach(var resource in Directory.GetFiles(path, "*.zip", SearchOption.TopDirectoryOnly))
|
||||||
|
{
|
||||||
|
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
|
||||||
|
LoadResource(new ZipFile(resource), dataFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start scripts
|
// Start scripts
|
||||||
lock (LoadedResources)
|
lock (LoadedResources)
|
||||||
{
|
{
|
||||||
foreach (var d in LoadedResources)
|
foreach (var r in LoadedResources)
|
||||||
{
|
{
|
||||||
foreach (ServerScript s in d.Scripts)
|
foreach (ServerScript s in r.Scripts)
|
||||||
{
|
{
|
||||||
s.CurrentResource = d;
|
|
||||||
s.API=Server.API;
|
s.API=Server.API;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Logger?.Debug("Starting script:"+s.CurrentFile.Name);
|
||||||
s.OnStart();
|
s.OnStart();
|
||||||
}
|
}
|
||||||
catch(Exception ex) {Logger?.Error($"Failed to start resource: {d.Name}"); Logger?.Error(ex); }
|
catch(Exception ex) {Logger?.Error($"Failed to start resource: {r.Name}"); Logger?.Error(ex); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using RageCoop.Core.Scripting;
|
||||||
|
|
||||||
namespace RageCoop.Server.Scripting
|
namespace RageCoop.Server.Scripting
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Inherit from this class, constructor will be called automatically, but other scripts might have yet been loaded and <see cref="API"/> will be null, you should use <see cref="OnStart"/>. to initiate your script.
|
/// Inherit from this class, constructor will be called automatically, but other scripts might have yet been loaded and <see cref="API"/> will be null, you should use <see cref="OnStart"/>. to initiate your script.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ServerScript :Core.Scripting.IScriptable
|
public abstract class ServerScript : Scriptable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method would be called from main thread after all scripts have been loaded.
|
/// This method would be called from main thread after all scripts have been loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void OnStart();
|
public override abstract void OnStart();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This method would be called from main thread when the server is shutting down, you MUST terminate all background jobs/threads in this method.
|
/// This method would be called from main thread when the server is shutting down, you MUST terminate all background jobs/threads in this method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void OnStop();
|
public override abstract void OnStop();
|
||||||
/// <summary>
|
|
||||||
/// Get the <see cref="Core.Scripting.Resource"/> object this script belongs to, this property will be initiated before <see cref="OnStart"/> (will be null if you access it in the constructor).
|
|
||||||
/// </summary>
|
|
||||||
public Core.Scripting.Resource CurrentResource { get;internal set; }
|
|
||||||
|
|
||||||
public API API { get; set; }
|
public API API { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -24,21 +24,21 @@ namespace RageCoop.Server
|
|||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Server
|
public class Server
|
||||||
{
|
{
|
||||||
private readonly string _compatibleVersion = "V0_5";
|
private readonly string _compatibleVersion = "V0_5";
|
||||||
public BaseScript BaseScript { get; set; }=new BaseScript();
|
internal BaseScript BaseScript { get; set; }=new BaseScript();
|
||||||
public readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
|
internal readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
|
||||||
public NetServer MainNetServer;
|
internal NetServer MainNetServer;
|
||||||
|
|
||||||
public readonly Dictionary<Command, Action<CommandContext>> Commands = new();
|
internal readonly Dictionary<Command, Action<CommandContext>> Commands = new();
|
||||||
public readonly Dictionary<long,Client> Clients = new();
|
internal readonly Dictionary<long,Client> Clients = new();
|
||||||
private System.Timers.Timer SendPlayerTimer = new System.Timers.Timer(5000);
|
private System.Timers.Timer SendPlayerTimer = new System.Timers.Timer(5000);
|
||||||
|
|
||||||
private Dictionary<int,FileTransfer> InProgressFileTransfers=new();
|
private Dictionary<int,FileTransfer> InProgressFileTransfers=new();
|
||||||
private Resources Resources;
|
private Resources Resources;
|
||||||
public API API;
|
public API API { get; private set; }
|
||||||
public Logger Logger;
|
internal Logger Logger;
|
||||||
private Security Security;
|
private Security Security;
|
||||||
public Server(Logger logger=null)
|
public Server(Logger logger=null)
|
||||||
{
|
{
|
||||||
@ -58,8 +58,7 @@ namespace RageCoop.Server
|
|||||||
Port = MainSettings.Port,
|
Port = MainSettings.Port,
|
||||||
MaximumConnections = MainSettings.MaxPlayers,
|
MaximumConnections = MainSettings.MaxPlayers,
|
||||||
EnableUPnP = false,
|
EnableUPnP = false,
|
||||||
AutoFlushSendQueue = true,
|
AutoFlushSendQueue = true
|
||||||
MaximumTransmissionUnit=2000, // PublicKeyResponse
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||||
@ -436,7 +435,7 @@ namespace RageCoop.Server
|
|||||||
MainNetServer.Recycle(message);
|
MainNetServer.Recycle(message);
|
||||||
}
|
}
|
||||||
object _sendPlayersLock=new object();
|
object _sendPlayersLock=new object();
|
||||||
public void SendPlayerInfos()
|
internal void SendPlayerInfos()
|
||||||
{
|
{
|
||||||
lock (_sendPlayersLock)
|
lock (_sendPlayersLock)
|
||||||
{
|
{
|
||||||
@ -499,7 +498,7 @@ namespace RageCoop.Server
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Security.AddConnection(connection.RemoteEndPoint, packet.AesKeyCrypted,packet.AesIVCrypted);
|
Security.AddConnection(connection.RemoteEndPoint, packet.AesKeyCrypted,packet.AesIVCrypted);
|
||||||
passhash=Security.Decrypt(packet.PassHashEncrypted,connection.RemoteEndPoint).GetString();
|
passhash=BitConverter.ToString(Security.Decrypt(packet.PassHashEncrypted, connection.RemoteEndPoint)).Replace("-", String.Empty);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -759,7 +758,7 @@ namespace RageCoop.Server
|
|||||||
Logger?.Info(packet.Username + ": " + packet.Message);
|
Logger?.Info(packet.Username + ": " + packet.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendChatMessage(string username, string message, List<NetConnection> targets = null)
|
internal void SendChatMessage(string username, string message, List<NetConnection> targets = null)
|
||||||
{
|
{
|
||||||
if (MainNetServer.Connections.Count==0) { return; }
|
if (MainNetServer.Connections.Count==0) { return; }
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
@ -768,14 +767,14 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
MainNetServer.SendMessage(outgoingMessage, targets ?? MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
|
MainNetServer.SendMessage(outgoingMessage, targets ?? MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
|
||||||
}
|
}
|
||||||
public void SendChatMessage(string username, string message, NetConnection target)
|
internal void SendChatMessage(string username, string message, NetConnection target)
|
||||||
{
|
{
|
||||||
SendChatMessage(username, message, new List<NetConnection>() { target });
|
SendChatMessage(username, message, new List<NetConnection>() { target });
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
public void RegisterCommand(string name, string usage, short argsLength, Action<CommandContext> callback)
|
internal void RegisterCommand(string name, string usage, short argsLength, Action<CommandContext> callback)
|
||||||
{
|
{
|
||||||
Command command = new(name) { Usage = usage, ArgsLength = argsLength };
|
Command command = new(name) { Usage = usage, ArgsLength = argsLength };
|
||||||
|
|
||||||
@ -786,7 +785,7 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
Commands.Add(command, callback);
|
Commands.Add(command, callback);
|
||||||
}
|
}
|
||||||
public void RegisterCommand(string name, Action<CommandContext> callback)
|
internal void RegisterCommand(string name, Action<CommandContext> callback)
|
||||||
{
|
{
|
||||||
Command command = new(name);
|
Command command = new(name);
|
||||||
|
|
||||||
@ -798,7 +797,7 @@ namespace RageCoop.Server
|
|||||||
Commands.Add(command, callback);
|
Commands.Add(command, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterCommands<T>()
|
internal void RegisterCommands<T>()
|
||||||
{
|
{
|
||||||
IEnumerable<MethodInfo> commands = typeof(T).GetMethods().Where(method => method.GetCustomAttributes(typeof(Command), false).Any());
|
IEnumerable<MethodInfo> commands = typeof(T).GetMethods().Where(method => method.GetCustomAttributes(typeof(Command), false).Any());
|
||||||
|
|
||||||
@ -810,7 +809,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendFile(string path,string name,Client client,Action<float> updateCallback=null)
|
internal void SendFile(string path,string name,Client client,Action<float> updateCallback=null)
|
||||||
{
|
{
|
||||||
int id = RequestFileID();
|
int id = RequestFileID();
|
||||||
var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
@ -890,7 +889,7 @@ namespace RageCoop.Server
|
|||||||
/// <param name="p"></param>
|
/// <param name="p"></param>
|
||||||
/// <param name="channel"></param>
|
/// <param name="channel"></param>
|
||||||
/// <param name="method"></param>
|
/// <param name="method"></param>
|
||||||
public void Send(Packet p,Client client, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
internal void Send(Packet p,Client client, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||||
{
|
{
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
p.Pack(outgoingMessage);
|
p.Pack(outgoingMessage);
|
||||||
|
BIN
RageCoop.Server/favicon.ico
Normal file
BIN
RageCoop.Server/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user