Reworked on resource loading, Added RegisterCommands overload to register commands from an instance.

This commit is contained in:
Sardelka
2022-06-24 16:49:59 +08:00
parent 82ab9237f5
commit 6167417bf8
19 changed files with 301 additions and 131 deletions

View File

@ -31,6 +31,8 @@ namespace RageCoop.Client.Menus
public static NativeMenu LastMenu { get; set; } = Menu;
#region ITEMS
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 };
private static readonly NativeItem _serverConnectItem = new NativeItem("Connect");
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);
_usernameItem.Activated += UsernameActivated;
_passwordItem.Activated+=_passwordActivated;
ServerIpItem.Activated += ServerIpActivated;
_serverConnectItem.Activated += (sender, item) => { Networking.ToggleConnection(Main.Settings.LastServerAddress); };
@ -58,6 +61,7 @@ namespace RageCoop.Client.Menus
Menu.AddSubMenu(ServersMenu.Menu);
Menu.Add(_usernameItem);
Menu.Add(_passwordItem);
Menu.Add(ServerIpItem);
Menu.Add(_serverConnectItem);
@ -76,6 +80,8 @@ namespace RageCoop.Client.Menus
Menu.Add(_aboutItem);
}
public static bool ShowPopUp(string prompt, string title,string subtitle,string error,bool showbackground)
{
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)
{
string newServerIp = Game.GetUserInput(WindowTitle.EnterMessage60, ServerIpItem.AltTitle, 60);

View File

@ -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)
{
@ -48,6 +48,7 @@ namespace RageCoop.Client
else
{
password = password ?? Main.Settings.Password;
username=username ?? Main.Settings.Username;
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
{
@ -85,7 +86,7 @@ namespace RageCoop.Client
var handshake=new Packets.Handshake()
{
PedID = Main.LocalPlayerID,
Username = Main.Settings.Username,
Username =username,
ModVersion = Main.CurrentVersion,
PassHashEncrypted=Security.Encrypt(password.GetHash())
};

View File

@ -3,7 +3,6 @@
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<OutputPath>D:\Games\Grand Theft Auto V\Scripts\RageCoop</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
@ -13,13 +12,26 @@
<AssemblyVersion>0.5.0</AssemblyVersion>
<FileVersion>0.5.0</FileVersion>
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetZip" Version="1.16.0" />
<Content Include="favicon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SharpZipLib" Version="1.3.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RageCoop.Core\RageCoop.Core.csproj" />

View File

@ -31,11 +31,7 @@ namespace RageCoop.Client.Scripting
List<InputArgument> arguments = new List<InputArgument>();
int i;
var ty = (byte)e.Args[0];
Main.Logger.Debug($"gettype");
Main.Logger.Flush();
TypeCode returnType=(TypeCode)ty;
Main.Logger.Debug($"typeok");
Main.Logger.Flush();
i = returnType==TypeCode.Empty ? 1 : 2;
var hash = (Hash)e.Args[i++];
for(; i<e.Args.Count;i++)

View File

@ -3,21 +3,17 @@
/// <summary>
/// Inherit from this class, constructor will be called automatically, but other scripts might have yet been loaded, you should use <see cref="OnStart"/>. to initiate your script.
/// </summary>
public abstract class ClientScript:Core.Scripting.IScriptable
public abstract class ClientScript:Core.Scripting.Scriptable
{
/// <summary>
/// This method would be called from main thread shortly after all scripts have been loaded.
/// </summary>
public abstract void OnStart();
public override abstract void OnStart();
/// <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.
/// </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; }
}
}

View File

@ -1,6 +1,6 @@
using System.IO;
using RageCoop.Core.Scripting;
using Ionic.Zip;
using ICSharpCode.SharpZipLib.Zip;
namespace RageCoop.Client.Scripting
{
@ -15,7 +15,6 @@ namespace RageCoop.Client.Scripting
{
foreach (var s in d.Scripts)
{
(s as ClientScript).CurrentResource=d;
Main.QueueAction(() => s.OnStart());
}
}
@ -37,23 +36,23 @@ namespace RageCoop.Client.Scripting
/// <summary>
/// Load all resources from the server
/// </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)
{
Unload();
foreach (var d in Directory.GetDirectories(path))
{
Directory.Delete(d, true);
}
using (var zip = ZipFile.Read(Path.Combine(path, "Resources.zip")))
{
zip.ExtractAll(path, ExtractExistingFileAction.OverwriteSilently);
if(Path.GetFileName(d).ToLower() != "data")
{
Directory.Delete(d, true);
}
}
Directory.CreateDirectory(path);
foreach (var resource in Directory.GetDirectories(path))
{
if (Path.GetFileName(resource).ToLower()!="data") { continue; }
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
LoadResource(resource);
LoadResource(resource,Path.Combine(path,"data"));
}
StartAll();
}

BIN
RageCoop.Client/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -22,6 +22,11 @@
<None Include="Lidgren.Network\Lidgren.Network.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\libs\Newtonsoft.Json.dll</HintPath>

View File

@ -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();
}
}

View 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; }
}
}

View File

@ -5,23 +5,13 @@ using System.Reflection;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using ICSharpCode.SharpZipLib.Zip;
[assembly: InternalsVisibleTo("RageCoop.Server")]
[assembly: InternalsVisibleTo("RageCoop.Client")]
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
{
protected List<string> ToIgnore = new List<string>
@ -40,20 +30,77 @@ namespace RageCoop.Core.Scripting
Logger = logger;
}
/// <summary>
/// Load all assemblies inside the resource directory.
/// Load a resource from a directory.
/// </summary>
/// <param name="path">Path of the directory.</param>
protected void LoadResource(string path)
protected void LoadResource(string path,string dataFolderRoot)
{
var r = new Resource()
{
Scripts = new List<IScriptable>(),
Scripts = new List<Scriptable>(),
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);
}
@ -62,31 +109,38 @@ namespace RageCoop.Core.Scripting
/// </summary>
/// <param name="path">The path to the assembly file to load.</param>
/// <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)
{
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;
try
{
var temp = Path.GetTempFileName();
File.Copy(path, temp, true);
assembly = Assembly.LoadFrom(temp);
if (shadowCopy)
{
var temp = Path.GetTempFileName();
File.Copy(path, temp, true);
assembly = Assembly.LoadFrom(temp);
}
else
{
assembly = Assembly.LoadFrom(path);
}
}
catch (Exception ex)
{
Logger?.Error("Unable to load "+Path.GetFileName(path));
Logger?.Error("Unable to load "+file.Name);
Logger?.Error(ex);
return false;
}
return LoadScriptsFromAssembly(assembly, path, domain);
return LoadScriptsFromAssembly(file,assembly, path, resource);
}
}
/// <summary>
@ -95,7 +149,7 @@ namespace RageCoop.Core.Scripting
/// <param name="filename">The path to the file associated with this assembly.</param>
/// <param name="assembly">The assembly to load.</param>
/// <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;
@ -110,7 +164,10 @@ namespace RageCoop.Core.Scripting
try
{
// 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++;
}
catch (Exception ex)
@ -127,7 +184,7 @@ namespace RageCoop.Core.Scripting
}
catch (ReflectionTypeLoadException ex)
{
Logger?.Error($"Failed to load assembly {Path.GetFileName(filename)}: ");
Logger?.Error($"Failed to load assembly {rfile.Name}: ");
Logger?.Error(ex);
foreach (var e in ex.LoaderExceptions)
{
@ -136,7 +193,7 @@ namespace RageCoop.Core.Scripting
return false;
}
Logger?.Info($"Loaded {count} script(s) in {Path.GetFileName(filename)}");
Logger?.Info($"Loaded {count} script(s) in {rfile.Name}");
return count != 0;
}
private bool IsManagedAssembly(string filename)

View 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; }
}
}

View File

@ -9,11 +9,14 @@
<PackageProjectUrl>https://ragecoop.online/</PackageProjectUrl>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Product>$(AssemblyName)-V</Product>
<PackageId>RAGECOOP-V</PackageId>
<Product>$(AssemblyName)</Product>
<PackageId>RageCoop.Server</PackageId>
<Authors>RAGECOOP</Authors>
<Version>0.5</Version>
<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>
<ItemGroup>
@ -23,7 +26,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DotNetZip" Version="1.16.0" />
<Content Include="favicon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SharpZipLib" Version="1.3.3" />
</ItemGroup>
<ItemGroup>

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Lidgren.Network;
using RageCoop.Core;
using RageCoop.Core.Scripting;
using System.Reflection;
using System.Net;
namespace RageCoop.Server.Scripting
@ -221,14 +222,30 @@ namespace RageCoop.Server.Scripting
}
/// <summary>
/// Register a class of commands
/// Register all commands in a static class
/// </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>()
{
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>
/// 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>

View File

@ -34,7 +34,7 @@ namespace RageCoop.Server.Scripting
public string Username { get; set; }
/// <summary>
/// The hashed value of client password, sent with RSA asymmetric encryption.
/// The client password hashed with SHA256 algorithm.
/// </summary>
public string PasswordHash { get; set; }
public IPEndPoint EndPoint { get; set; }

View File

@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using RageCoop.Core.Scripting;
using System.IO;
using Ionic.Zip;
using ICSharpCode.SharpZipLib.Zip;
using System.Reflection;
namespace RageCoop.Server.Scripting
{
@ -16,64 +16,95 @@ namespace RageCoop.Server.Scripting
{
Server = server;
}
public bool HasClientResources = false;
private List<string> ClientResourceZips=new List<string>();
public bool HasClientResources { get; private set; }
public void LoadAll()
{
#region CLIENT
var path = Path.Combine("Resources", "Client");
var tmp = Path.Combine("Resources", "ClientTemp");
Directory.CreateDirectory(path);
var clientResources = Directory.GetDirectories(path);
if (clientResources.Length!=0)
if (Directory.Exists(tmp))
{
foreach(var dir in Directory.GetDirectories(tmp))
{
Directory.Delete(dir, true);
}
}
else
{
Directory.CreateDirectory(tmp);
}
var resourceFolders = Directory.GetDirectories(path,"*",SearchOption.TopDirectoryOnly);
if (resourceFolders.Length!=0)
{
// Pack client side resources as a zip file
Logger?.Info("Packing client-side resources");
try
{
var zippath = Path.Combine(path, "Resources.zip");
if (File.Exists(zippath))
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
{
File.Delete(zippath);
using (ZipFile zip = ZipFile.Create(zipPath))
{
foreach (var dir in Directory.GetDirectories(resourceFolder, "*", SearchOption.AllDirectories))
{
zip.AddDirectory(dir.Substring(resourceFolder.Length+1));
}
foreach (var file in Directory.GetFiles(resourceFolder, "*", SearchOption.AllDirectories))
{
zip.Add(file,file.Substring(resourceFolder.Length+1));
}
zip.Close();
ClientResourceZips.Add(zipPath);
}
}
using (ZipFile zip = new ZipFile())
catch (Exception ex)
{
zip.AddDirectory(path);
zip.Save(zippath);
Logger?.Error($"Failed to pack client resource:{resourceFolder}");
Logger?.Error(ex);
}
HasClientResources=true;
}
catch (Exception ex)
{
Logger?.Error("Failed to pack client resources");
Logger?.Error(ex);
}
}
#endregion
var packed = Directory.GetFiles(path, "*.zip", SearchOption.TopDirectoryOnly);
if (packed.Length>0)
{
HasClientResources =true;
ClientResourceZips.AddRange(packed);
}
#endregion
#region SERVER
path = Path.Combine("Resources", "Server");
#region SERVER
path = Path.Combine("Resources", "Server");
var dataFolder = Path.Combine(path, "data");
Directory.CreateDirectory(path);
foreach (var resource in Directory.GetDirectories(path))
{
if (Path.GetFileName(resource).ToLower()=="data") { continue; }
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
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;
try
{
Logger?.Debug("Starting script:"+s.CurrentFile.Name);
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); }
}
}
}

View File

@ -1,25 +1,22 @@
using System;
using RageCoop.Core.Scripting;
namespace RageCoop.Server.Scripting
{
/// <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.
/// </summary>
public abstract class ServerScript :Core.Scripting.IScriptable
public abstract class ServerScript : Scriptable
{
/// <summary>
/// This method would be called from main thread after all scripts have been loaded.
/// </summary>
public abstract void OnStart();
public override abstract void OnStart();
/// <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.
/// </summary>
public 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 override abstract void OnStop();
public API API { get; set; }
}

View File

@ -24,21 +24,21 @@ namespace RageCoop.Server
public string Address { get; set; }
}
internal class Server
public class Server
{
private readonly string _compatibleVersion = "V0_5";
public BaseScript BaseScript { get; set; }=new BaseScript();
public readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
public NetServer MainNetServer;
internal BaseScript BaseScript { get; set; }=new BaseScript();
internal readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
internal NetServer MainNetServer;
public readonly Dictionary<Command, Action<CommandContext>> Commands = new();
public readonly Dictionary<long,Client> Clients = new();
internal readonly Dictionary<Command, Action<CommandContext>> Commands = new();
internal readonly Dictionary<long,Client> Clients = new();
private System.Timers.Timer SendPlayerTimer = new System.Timers.Timer(5000);
private Dictionary<int,FileTransfer> InProgressFileTransfers=new();
private Resources Resources;
public API API;
public Logger Logger;
public API API { get; private set; }
internal Logger Logger;
private Security Security;
public Server(Logger logger=null)
{
@ -58,8 +58,7 @@ namespace RageCoop.Server
Port = MainSettings.Port,
MaximumConnections = MainSettings.MaxPlayers,
EnableUPnP = false,
AutoFlushSendQueue = true,
MaximumTransmissionUnit=2000, // PublicKeyResponse
AutoFlushSendQueue = true
};
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
@ -436,7 +435,7 @@ namespace RageCoop.Server
MainNetServer.Recycle(message);
}
object _sendPlayersLock=new object();
public void SendPlayerInfos()
internal void SendPlayerInfos()
{
lock (_sendPlayersLock)
{
@ -499,7 +498,7 @@ namespace RageCoop.Server
try
{
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)
{
@ -759,7 +758,7 @@ namespace RageCoop.Server
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; }
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
@ -768,14 +767,14 @@ namespace RageCoop.Server
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 });
}
#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 };
@ -786,7 +785,7 @@ namespace RageCoop.Server
Commands.Add(command, callback);
}
public void RegisterCommand(string name, Action<CommandContext> callback)
internal void RegisterCommand(string name, Action<CommandContext> callback)
{
Command command = new(name);
@ -798,7 +797,7 @@ namespace RageCoop.Server
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());
@ -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();
var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
@ -890,7 +889,7 @@ namespace RageCoop.Server
/// <param name="p"></param>
/// <param name="channel"></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();
p.Pack(outgoingMessage);

BIN
RageCoop.Server/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB