Multiple server instances in one process is now possible
This commit is contained in:
@ -128,7 +128,7 @@ namespace RageCoop.Client.Scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a <see cref="Core.Logging.Logger"/> that RAGECOOP is currently using.
|
/// Get a <see cref="Core.Logger"/> that RAGECOOP is currently using.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Logger GetLogger()
|
public static Logger GetLogger()
|
||||||
|
@ -21,7 +21,7 @@ namespace RageCoop.Client.Scripting
|
|||||||
public override void OnStop()
|
public override void OnStop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void SetAutoRespawn(CustomEventReceivedArgs args)
|
private void SetAutoRespawn(CustomEventReceivedArgs args)
|
||||||
{
|
{
|
||||||
API.Config.EnableAutoRespawn=(bool)args.Args[0];
|
API.Config.EnableAutoRespawn=(bool)args.Args[0];
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace RageCoop.Core
|
|||||||
|
|
||||||
public override void Pack(NetOutgoingMessage message)
|
public override void Pack(NetOutgoingMessage message)
|
||||||
{
|
{
|
||||||
|
Args= Args ?? new List<object>(0);
|
||||||
message.Write((byte)PacketTypes.CustomEvent);
|
message.Write((byte)PacketTypes.CustomEvent);
|
||||||
|
|
||||||
List<byte> result = new List<byte>();
|
List<byte> result = new List<byte>();
|
||||||
|
@ -48,7 +48,7 @@ namespace RageCoop.Core.Scripting
|
|||||||
var r = new Resource()
|
var r = new Resource()
|
||||||
{
|
{
|
||||||
Scripts = new List<IScriptable>(),
|
Scripts = new List<IScriptable>(),
|
||||||
Name=Path.GetDirectoryName(path),
|
Name=Path.GetFileName(path),
|
||||||
Directory=path,
|
Directory=path,
|
||||||
};
|
};
|
||||||
foreach (var f in Directory.GetFiles(path, "*.dll"))
|
foreach (var f in Directory.GetFiles(path, "*.dll"))
|
||||||
|
@ -42,6 +42,11 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
public class Client
|
public class Client
|
||||||
{
|
{
|
||||||
|
private readonly Server Server;
|
||||||
|
internal Client(Server server)
|
||||||
|
{
|
||||||
|
Server=server;
|
||||||
|
}
|
||||||
internal long NetID = 0;
|
internal long NetID = 0;
|
||||||
public NetConnection Connection { get;internal set; }
|
public NetConnection Connection { get;internal set; }
|
||||||
public ServerPed Player { get; internal set; }
|
public ServerPed Player { get; internal set; }
|
||||||
@ -111,7 +116,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -127,13 +132,13 @@ namespace RageCoop.Server
|
|||||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
||||||
if (userConnection == null)
|
if (userConnection == null)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[Client->SendNativeCall(ulong hash, params object[] args)]: Connection \"{NetID}\" not found!");
|
Server.Logger?.Error($"[Client->SendNativeCall(ulong hash, params object[] args)]: Connection \"{NetID}\" not found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args != null && args.Length == 0)
|
if (args != null && args.Length == 0)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
Server.Logger?.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +154,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -166,13 +171,13 @@ namespace RageCoop.Server
|
|||||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
||||||
if (userConnection == null)
|
if (userConnection == null)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[Client->SendNativeResponse(Action<object> callback, ulong hash, Type type, params object[] args)]: Connection \"{NetID}\" not found!");
|
Server.Logger?.Error($"[Client->SendNativeResponse(Action<object> callback, ulong hash, Type type, params object[] args)]: Connection \"{NetID}\" not found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args != null && args.Length == 0)
|
if (args != null && args.Length == 0)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
Server.Logger?.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing arguments!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +207,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing return type!");
|
Server.Logger?.Error($"[Client->SendNativeCall(ulong hash, Dictionary<string, object> args)]: Missing return type!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +223,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -246,7 +251,7 @@ namespace RageCoop.Server
|
|||||||
{
|
{
|
||||||
var argsList = new List<object>(args);
|
var argsList = new List<object>(args);
|
||||||
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty,(ulong)hash});
|
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty,(ulong)hash});
|
||||||
// Program.Logger.Debug(argsList.DumpWithType());
|
// Server.Logger?.Debug(argsList.DumpWithType());
|
||||||
SendCustomEvent(CustomEvents.NativeCall, argsList);
|
SendCustomEvent(CustomEvents.NativeCall, argsList);
|
||||||
}
|
}
|
||||||
private int RequestNativeCallID<T>(Action<object> callback)
|
private int RequestNativeCallID<T>(Action<object> callback)
|
||||||
@ -273,7 +278,7 @@ namespace RageCoop.Server
|
|||||||
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
NetConnection userConnection = Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == NetID);
|
||||||
if (userConnection == null)
|
if (userConnection == null)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[Client->SendCleanUpWorld()]: Connection \"{NetID}\" not found!");
|
Server.Logger?.Error($"[Client->SendCleanUpWorld()]: Connection \"{NetID}\" not found!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||||
@ -285,7 +290,7 @@ namespace RageCoop.Server
|
|||||||
{
|
{
|
||||||
if (!IsReady)
|
if (!IsReady)
|
||||||
{
|
{
|
||||||
Program.Logger.Warning($"Player \"{Username}\" is not ready!");
|
Server.Logger?.Warning($"Player \"{Username}\" is not ready!");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -302,7 +307,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Program.Logger.Error(ex);
|
Server.Logger?.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -9,10 +9,9 @@ namespace RageCoop.Server
|
|||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
public static bool ReadyToStop = false;
|
public static bool ReadyToStop = false;
|
||||||
public static Core.Logger Logger;
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Logger=new Core.Logger()
|
var mainLogger= new Core.Logger()
|
||||||
{
|
{
|
||||||
LogPath="RageCoop.Server.log",
|
LogPath="RageCoop.Server.log",
|
||||||
UseConsole=true,
|
UseConsole=true,
|
||||||
@ -49,13 +48,15 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = new Server();
|
_ = new Server(mainLogger);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error(e);
|
mainLogger.Error(e);
|
||||||
Logger.Error($"Fatal error occurred, server shutting down.");
|
mainLogger.Error($"Fatal error occurred, server shutting down.");
|
||||||
|
Thread.Sleep(3000);
|
||||||
}
|
}
|
||||||
|
mainLogger.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -10,63 +10,60 @@ using System.Net;
|
|||||||
|
|
||||||
namespace RageCoop.Server.Scripting
|
namespace RageCoop.Server.Scripting
|
||||||
{
|
{
|
||||||
public static class API
|
public class APIEvents
|
||||||
{
|
{
|
||||||
#region INTERNAL
|
#region INTERNAL
|
||||||
internal static Dictionary<int, List<Action<CustomEventReceivedArgs>>> CustomEventHandlers = new();
|
internal Dictionary<int, List<Action<CustomEventReceivedArgs>>> CustomEventHandlers = new();
|
||||||
#endregion
|
#endregion
|
||||||
public static class Events
|
public event EventHandler<ChatEventArgs> OnChatMessage;
|
||||||
{
|
public event EventHandler<HandshakeEventArgs> OnPlayerHandshake;
|
||||||
#region DELEGATES
|
/// <summary>
|
||||||
public delegate void EmptyEvent();
|
/// Will be invoked when a player is connected, but this player might not be ready yet(client resources not loaded), using <see cref="OnPlayerReady"/> is recommended.
|
||||||
public delegate void PlayerConnect(Client client);
|
/// </summary>
|
||||||
public delegate void PlayerDisconnect(Client client);
|
public event EventHandler<Client> OnPlayerConnected;
|
||||||
|
/// <summary>
|
||||||
#endregion
|
/// Will be invoked after the client connected and all resources(if any) have been loaded.
|
||||||
public static event EventHandler<ChatEventArgs> OnChatMessage;
|
/// </summary>
|
||||||
public static event EventHandler<HandshakeEventArgs> OnPlayerHandshake;
|
public event EventHandler<Client> OnPlayerReady;
|
||||||
public static event PlayerConnect OnPlayerConnected;
|
public event EventHandler<Client> OnPlayerDisconnected;
|
||||||
public static event PlayerDisconnect OnPlayerDisconnected;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Will be invoked before registered handlers
|
/// Will be invoked before registered handlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static event EventHandler<OnCommandEventArgs> OnCommandReceived;
|
public event EventHandler<OnCommandEventArgs> OnCommandReceived;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked everytime a player's main ped has been updated
|
/// Invoked everytime a player's main ped has been updated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static event EventHandler<Client> OnPlayerUpdate;
|
public event EventHandler<Client> OnPlayerUpdate;
|
||||||
/*
|
internal void ClearHandlers()
|
||||||
/// <summary>
|
|
||||||
/// This will be invoked when a CustomEvent is received from one client.
|
|
||||||
/// </summary>
|
|
||||||
public static event EventHandler<CustomEventReceivedArgs> OnCustomEventReceived;
|
|
||||||
*/
|
|
||||||
internal static void ClearHandlers()
|
|
||||||
{
|
{
|
||||||
OnChatMessage=null;
|
OnChatMessage=null;
|
||||||
OnPlayerHandshake=null;
|
OnPlayerHandshake=null;
|
||||||
OnPlayerConnected=null;
|
OnPlayerConnected=null;
|
||||||
|
OnPlayerReady=null;
|
||||||
OnPlayerDisconnected=null;
|
OnPlayerDisconnected=null;
|
||||||
// OnCustomEventReceived=null;
|
// OnCustomEventReceived=null;
|
||||||
OnCommandReceived=null;
|
OnCommandReceived=null;
|
||||||
OnPlayerUpdate=null;
|
OnPlayerUpdate=null;
|
||||||
}
|
}
|
||||||
#region INVOKE
|
#region INVOKE
|
||||||
internal static void InvokeOnChatMessage(Packets.ChatMessage p,Client sender)
|
internal void InvokeOnChatMessage(Packets.ChatMessage p, Client sender)
|
||||||
|
{
|
||||||
|
OnChatMessage?.Invoke(this, new ChatEventArgs()
|
||||||
{
|
{
|
||||||
OnChatMessage?.Invoke(null,new ChatEventArgs() {
|
|
||||||
Sender=sender,
|
Sender=sender,
|
||||||
Message=p.Message
|
Message=p.Message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
internal static void InvokePlayerConnected(Client client)
|
internal void InvokePlayerConnected(Client client)
|
||||||
{ OnPlayerConnected?.Invoke(client); }
|
{ OnPlayerConnected?.Invoke(this,client); }
|
||||||
internal static void InvokePlayerDisconnected(Client client)
|
internal void InvokePlayerReady(Client client)
|
||||||
{ OnPlayerDisconnected?.Invoke(client); }
|
{ OnPlayerReady?.Invoke(this, client); }
|
||||||
internal static void InvokePlayerHandshake(HandshakeEventArgs args)
|
internal void InvokePlayerDisconnected(Client client)
|
||||||
{ OnPlayerHandshake?.Invoke(null, args); }
|
{ OnPlayerDisconnected?.Invoke(this,client); }
|
||||||
|
internal void InvokePlayerHandshake(HandshakeEventArgs args)
|
||||||
|
{ OnPlayerHandshake?.Invoke(this, args); }
|
||||||
|
|
||||||
internal static void InvokeCustomEventReceived(Packets.CustomEvent p,Client sender)
|
internal void InvokeCustomEventReceived(Packets.CustomEvent p, Client sender)
|
||||||
{
|
{
|
||||||
var args = new CustomEventReceivedArgs() { Hash=p.Hash, Args=p.Args, Sender=sender };
|
var args = new CustomEventReceivedArgs() { Hash=p.Hash, Args=p.Args, Sender=sender };
|
||||||
List<Action<CustomEventReceivedArgs>> handlers;
|
List<Action<CustomEventReceivedArgs>> handlers;
|
||||||
@ -75,7 +72,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
handlers.ForEach((x) => { x.Invoke(args); });
|
handlers.ForEach((x) => { x.Invoke(args); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal static bool InvokeOnCommandReceived(string cname,string[] cargs,Client sender)
|
internal bool InvokeOnCommandReceived(string cname, string[] cargs, Client sender)
|
||||||
{
|
{
|
||||||
var args = new OnCommandEventArgs()
|
var args = new OnCommandEventArgs()
|
||||||
{
|
{
|
||||||
@ -83,16 +80,23 @@ namespace RageCoop.Server.Scripting
|
|||||||
Args=cargs,
|
Args=cargs,
|
||||||
Sender=sender
|
Sender=sender
|
||||||
};
|
};
|
||||||
OnCommandReceived?.Invoke(null,args);
|
OnCommandReceived?.Invoke(this, args);
|
||||||
return args.Cancel;
|
return args.Cancel;
|
||||||
}
|
}
|
||||||
internal static void InvokePlayerUpdate(Client client)
|
internal void InvokePlayerUpdate(Client client)
|
||||||
{
|
{
|
||||||
OnPlayerUpdate?.Invoke(null,client);
|
OnPlayerUpdate?.Invoke(this, client);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
public class API
|
||||||
|
{
|
||||||
|
private readonly Server Server;
|
||||||
|
internal API(Server server)
|
||||||
|
{
|
||||||
|
Server=server;
|
||||||
|
}
|
||||||
|
public APIEvents Events { get; set; }=new APIEvents();
|
||||||
#region FUNCTIONS
|
#region FUNCTIONS
|
||||||
/*
|
/*
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -101,7 +105,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</param>
|
/// <param name="hash">The hash (Example: 0x25223CA6B4D20B7F = GET_CLOCK_HOURS)</param>
|
||||||
/// <param name="args">The arguments (Example: string = int, object = 5)</param>
|
/// <param name="args">The arguments (Example: string = int, object = 5)</param>
|
||||||
public static void SendNativeCallToAll(GTA.Native.Hash hash, params object[] args)
|
public void SendNativeCallToAll(GTA.Native.Hash hash, params object[] args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -112,7 +116,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
|
|
||||||
if (args != null && args.Length == 0)
|
if (args != null && args.Length == 0)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: args is not null!");
|
Server.Logger?.Error($"[ServerScript->SendNativeCallToAll(ulong hash, params object[] args)]: args is not null!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +132,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -136,7 +140,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// Get a list of all Clients
|
/// Get a list of all Clients
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>All clients as a dictionary indexed by NetID</returns>
|
/// <returns>All clients as a dictionary indexed by NetID</returns>
|
||||||
public static Dictionary<long, Client> GetAllClients()
|
public Dictionary<long, Client> GetAllClients()
|
||||||
{
|
{
|
||||||
return new(Server.Clients);
|
return new(Server.Clients);
|
||||||
}
|
}
|
||||||
@ -146,7 +150,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="username">The username to search for (non case-sensitive)</param>
|
/// <param name="username">The username to search for (non case-sensitive)</param>
|
||||||
/// <returns>The Client from this user or null</returns>
|
/// <returns>The Client from this user or null</returns>
|
||||||
public static Client GetClientByUsername(string username)
|
public Client GetClientByUsername(string username)
|
||||||
{
|
{
|
||||||
return Server.Clients.Values.FirstOrDefault(x => x.Username.ToLower() == username.ToLower());
|
return Server.Clients.Values.FirstOrDefault(x => x.Username.ToLower() == username.ToLower());
|
||||||
}
|
}
|
||||||
@ -156,7 +160,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The chat message</param>
|
/// <param name="message">The chat message</param>
|
||||||
/// <param name="username">The username which send this message (default = "Server")</param>
|
/// <param name="username">The username which send this message (default = "Server")</param>
|
||||||
public static void SendChatMessage(string message, List<Client> targets = null, string username = "Server")
|
public void SendChatMessage(string message, List<Client> targets = null, string username = "Server")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -172,10 +176,10 @@ namespace RageCoop.Server.Scripting
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void SendChatMessage(string message, Client target, string username = "Server")
|
public void SendChatMessage(string message, Client target, string username = "Server")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -183,27 +187,29 @@ namespace RageCoop.Server.Scripting
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
Server.Logger?.Error($">> {e.Message} <<>> {e.Source ?? string.Empty} <<>> {e.StackTrace ?? string.Empty} <<");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send CleanUpWorld to all players to delete all objects created by the server
|
/// Send CleanUpWorld to all players to delete all objects created by the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SendCleanUpWorldToAll(List<long> netHandleList = null)
|
public void SendCleanUpWorldToAll(List<Client> clients = null)
|
||||||
{
|
{
|
||||||
if (Server.MainNetServer.ConnectionsCount == 0)
|
if (Server.MainNetServer.ConnectionsCount == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<NetConnection> connections = netHandleList == null
|
|
||||||
? Server.MainNetServer.Connections
|
|
||||||
: Server.MainNetServer.Connections.FindAll(c => netHandleList.Contains(c.RemoteUniqueIdentifier));
|
|
||||||
|
|
||||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||||
outgoingMessage.Write((byte)PacketTypes.CleanUpWorld);
|
outgoingMessage.Write((byte)PacketTypes.CleanUpWorld);
|
||||||
Server.MainNetServer.SendMessage(outgoingMessage, connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Default);
|
if (clients == null)
|
||||||
|
{
|
||||||
|
Server.MainNetServer.SendToAll(outgoingMessage, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Default);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clients.ForEach(client => { Server.MainNetServer.SendMessage(outgoingMessage,client.Connection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Default); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -213,7 +219,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// <param name="usage">How to use this message (argsLength required!)</param>
|
/// <param name="usage">How to use this message (argsLength required!)</param>
|
||||||
/// <param name="argsLength">The length of args (Example: "/message USERNAME MESSAGE" = 2) (usage required!)</param>
|
/// <param name="argsLength">The length of args (Example: "/message USERNAME MESSAGE" = 2) (usage required!)</param>
|
||||||
/// <param name="callback">Create a new function!</param>
|
/// <param name="callback">Create a new function!</param>
|
||||||
public static void RegisterCommand(string name, string usage, short argsLength, Action<CommandContext> callback)
|
public void RegisterCommand(string name, string usage, short argsLength, Action<CommandContext> callback)
|
||||||
{
|
{
|
||||||
Server.RegisterCommand(name, usage, argsLength, callback);
|
Server.RegisterCommand(name, usage, argsLength, callback);
|
||||||
}
|
}
|
||||||
@ -222,7 +228,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the command (Example: "test" for "/test")</param>
|
/// <param name="name">The name of the command (Example: "test" for "/test")</param>
|
||||||
/// <param name="callback">Create a new function!</param>
|
/// <param name="callback">Create a new function!</param>
|
||||||
public static void RegisterCommand(string name, Action<CommandContext> callback)
|
public void RegisterCommand(string name, Action<CommandContext> callback)
|
||||||
{
|
{
|
||||||
Server.RegisterCommand(name, callback);
|
Server.RegisterCommand(name, callback);
|
||||||
}
|
}
|
||||||
@ -231,18 +237,18 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// Register a class of commands
|
/// Register a class of commands
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The name of your class with functions</typeparam>
|
/// <typeparam name="T">The name of your class with functions</typeparam>
|
||||||
public static void RegisterCommands<T>()
|
public void RegisterCommands<T>()
|
||||||
{
|
{
|
||||||
Server.RegisterCommands<T>();
|
Server.RegisterCommands<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send an event and data to the specified clients.
|
/// 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>
|
||||||
/// <param name="eventHash">An unique identifier of the event</param>
|
/// <param name="eventHash">An unique identifier of the event</param>
|
||||||
/// <param name="args">The objects conataing your data, supported types: byte, short, ushort, int, uint, long, ulong, float, bool, string.</param>
|
/// <param name="args">The objects conataing your data, supported types: byte, short, ushort, int, uint, long, ulong, float, bool, string.</param>
|
||||||
/// <param name="targets">The target clients to send.</param>
|
/// <param name="targets">The target clients to send. Leave it null to send to all clients</param>
|
||||||
public static void SendCustomEvent(int eventHash,List<object> args,List<Client> targets=null)
|
public void SendCustomEvent(int eventHash,List<object> args,List<Client> targets=null)
|
||||||
{
|
{
|
||||||
targets ??= new(Server.Clients.Values);
|
targets ??= new(Server.Clients.Values);
|
||||||
var p = new Packets.CustomEvent()
|
var p = new Packets.CustomEvent()
|
||||||
@ -260,25 +266,25 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// </summary>
|
/// </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="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. This will be invoked from main thread.
|
/// <param name="handler">An handler to be invoked when the event is received from the server. This will be invoked from main thread.
|
||||||
public static void RegisterCustomEventHandler(int hash,Action<CustomEventReceivedArgs> handler)
|
public void RegisterCustomEventHandler(int hash,Action<CustomEventReceivedArgs> handler)
|
||||||
{
|
{
|
||||||
List<Action<CustomEventReceivedArgs>> handlers;
|
List<Action<CustomEventReceivedArgs>> handlers;
|
||||||
lock (CustomEventHandlers)
|
lock (Events.CustomEventHandlers)
|
||||||
{
|
{
|
||||||
if (!CustomEventHandlers.TryGetValue(hash,out handlers))
|
if (!Events.CustomEventHandlers.TryGetValue(hash,out handlers))
|
||||||
{
|
{
|
||||||
CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
|
Events.CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
|
||||||
}
|
}
|
||||||
handlers.Add(handler);
|
handlers.Add(handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void RegisterCustomEventHandler(string name, Action<CustomEventReceivedArgs> handler)
|
public void RegisterCustomEventHandler(string name, Action<CustomEventReceivedArgs> handler)
|
||||||
{
|
{
|
||||||
RegisterCustomEventHandler(CustomEvents.Hash(name), handler);
|
RegisterCustomEventHandler(CustomEvents.Hash(name), handler);
|
||||||
}
|
}
|
||||||
public static Logger GetLogger()
|
public Logger GetLogger()
|
||||||
{
|
{
|
||||||
return Program.Logger;
|
return Server.Logger;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,13 @@ namespace RageCoop.Server.Scripting
|
|||||||
{
|
{
|
||||||
internal class Resources : ResourceLoader
|
internal class Resources : ResourceLoader
|
||||||
{
|
{
|
||||||
public Resources() : base("RageCoop.Server.Scripting.ServerScript", Program.Logger) { }
|
private readonly Server Server;
|
||||||
|
public Resources(Server server) : base("RageCoop.Server.Scripting.ServerScript", server.Logger)
|
||||||
|
{
|
||||||
|
Server = server;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool HasClientResources = false;
|
public bool HasClientResources = false;
|
||||||
public void LoadAll()
|
public void LoadAll()
|
||||||
{
|
{
|
||||||
#region CLIENT
|
#region CLIENT
|
||||||
@ -23,7 +27,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
if (clientResources.Length!=0)
|
if (clientResources.Length!=0)
|
||||||
{
|
{
|
||||||
// Pack client side resources as a zip file
|
// Pack client side resources as a zip file
|
||||||
Logger.Info("Packing client-side resources");
|
Logger?.Info("Packing client-side resources");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -41,8 +45,8 @@ namespace RageCoop.Server.Scripting
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error("Failed to pack client resources");
|
Logger?.Error("Failed to pack client resources");
|
||||||
Logger.Error(ex);
|
Logger?.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -52,7 +56,7 @@ namespace RageCoop.Server.Scripting
|
|||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
foreach (var resource in Directory.GetDirectories(path))
|
foreach (var resource in Directory.GetDirectories(path))
|
||||||
{
|
{
|
||||||
Logger.Info($"Loading resource: {Path.GetFileName(resource)}");
|
Logger?.Info($"Loading resource: {Path.GetFileName(resource)}");
|
||||||
LoadResource(resource);
|
LoadResource(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,14 +65,15 @@ namespace RageCoop.Server.Scripting
|
|||||||
{
|
{
|
||||||
foreach (var d in LoadedResources)
|
foreach (var d in LoadedResources)
|
||||||
{
|
{
|
||||||
foreach (var s in d.Scripts)
|
foreach (ServerScript s in d.Scripts)
|
||||||
{
|
{
|
||||||
(s as ServerScript).CurrentResource = d;
|
s.CurrentResource = d;
|
||||||
|
s.API=Server.API;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
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: {d.Name}"); Logger?.Error(ex); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,9 +109,9 @@ namespace RageCoop.Server.Scripting
|
|||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
Logger.Info($"Sending resources to client:{client.Username}");
|
Logger?.Info($"Sending resources to client:{client.Username}");
|
||||||
Server.SendFile(path, "Resources.zip", client);
|
Server.SendFile(path, "Resources.zip", client);
|
||||||
Logger.Info($"Resources sent to:{client.Username}");
|
Logger?.Info($"Resources sent to:{client.Username}");
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
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, 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 :Core.Scripting.IScriptable
|
||||||
{
|
{
|
||||||
@ -20,6 +20,8 @@ namespace RageCoop.Server.Scripting
|
|||||||
/// 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).
|
/// 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>
|
/// </summary>
|
||||||
public Core.Scripting.Resource CurrentResource { get;internal set; }
|
public Core.Scripting.Resource CurrentResource { get;internal set; }
|
||||||
|
|
||||||
|
public API API { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||||
|
@ -26,24 +26,29 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
internal class Server
|
internal class Server
|
||||||
{
|
{
|
||||||
private static readonly string _compatibleVersion = "V0_5";
|
private readonly string _compatibleVersion = "V0_5";
|
||||||
public static BaseScript BaseScript { get; set; }=new BaseScript();
|
public BaseScript BaseScript { get; set; }=new BaseScript();
|
||||||
public static readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
|
public readonly Settings MainSettings = Util.Read<Settings>("Settings.xml");
|
||||||
public static NetServer MainNetServer;
|
public NetServer MainNetServer;
|
||||||
|
|
||||||
public static readonly Dictionary<Command, Action<CommandContext>> Commands = new();
|
public readonly Dictionary<Command, Action<CommandContext>> Commands = new();
|
||||||
public static readonly Dictionary<long,Client> Clients = new();
|
public readonly Dictionary<long,Client> Clients = new();
|
||||||
private static System.Timers.Timer SendPlayerTimer = new System.Timers.Timer(5000);
|
private System.Timers.Timer SendPlayerTimer = new System.Timers.Timer(5000);
|
||||||
|
|
||||||
private static Dictionary<int,FileTransfer> InProgressFileTransfers=new();
|
private Dictionary<int,FileTransfer> InProgressFileTransfers=new();
|
||||||
private static Resources Resources = new Resources();
|
private Resources Resources;
|
||||||
public Server()
|
public API API;
|
||||||
|
public Logger Logger;
|
||||||
|
public Server(Logger logger=null)
|
||||||
{
|
{
|
||||||
Program.Logger.Info("================");
|
Logger=logger;
|
||||||
Program.Logger.Info($"Server bound to: 0.0.0.0:{MainSettings.Port}");
|
API=new API(this);
|
||||||
Program.Logger.Info($"Server version: {Assembly.GetCallingAssembly().GetName().Version}");
|
Resources=new Resources(this);
|
||||||
Program.Logger.Info($"Compatible RAGECOOP versions: {_compatibleVersion.Replace('_', '.')}.x");
|
Logger?.Info("================");
|
||||||
Program.Logger.Info("================");
|
Logger?.Info($"Server bound to: 0.0.0.0:{MainSettings.Port}");
|
||||||
|
Logger?.Info($"Server version: {Assembly.GetCallingAssembly().GetName().Version}");
|
||||||
|
Logger?.Info($"Compatible RAGECOOP versions: {_compatibleVersion.Replace('_', '.')}.x");
|
||||||
|
Logger?.Info("================");
|
||||||
|
|
||||||
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
|
// 623c92c287cc392406e7aaaac1c0f3b0 = RAGECOOP
|
||||||
NetPeerConfiguration config = new("623c92c287cc392406e7aaaac1c0f3b0")
|
NetPeerConfiguration config = new("623c92c287cc392406e7aaaac1c0f3b0")
|
||||||
@ -62,7 +67,7 @@ namespace RageCoop.Server
|
|||||||
SendPlayerTimer.Elapsed+=(s,e) => { SendPlayerInfos(); };
|
SendPlayerTimer.Elapsed+=(s,e) => { SendPlayerInfos(); };
|
||||||
SendPlayerTimer.AutoReset=true;
|
SendPlayerTimer.AutoReset=true;
|
||||||
SendPlayerTimer.Enabled=true;
|
SendPlayerTimer.Enabled=true;
|
||||||
Program.Logger.Info(string.Format("Server listening on {0}:{1}", config.LocalAddress.ToString(), config.Port));
|
Logger?.Info(string.Format("Server listening on {0}:{1}", config.LocalAddress.ToString(), config.Port));
|
||||||
if (MainSettings.AnnounceSelf)
|
if (MainSettings.AnnounceSelf)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -89,11 +94,11 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
string content = await response.Content.ReadAsStringAsync();
|
||||||
info = JsonConvert.DeserializeObject<IpInfo>(content);
|
info = JsonConvert.DeserializeObject<IpInfo>(content);
|
||||||
Program.Logger.Info($"Your public IP is {info.Address}, announcing to master server...");
|
Logger?.Info($"Your public IP is {info.Address}, announcing to master server...");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Program.Logger.Error(ex.InnerException?.Message ?? ex.Message);
|
Logger?.Error(ex.InnerException?.Message ?? ex.Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var realMaster = MainSettings.MasterServer=="[AUTO]" ? Util.DownloadString("https://ragecoop.online/stuff/masterserver") : MainSettings.MasterServer;
|
var realMaster = MainSettings.MasterServer=="[AUTO]" ? Util.DownloadString("https://ragecoop.online/stuff/masterserver") : MainSettings.MasterServer;
|
||||||
@ -115,7 +120,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"MasterServer: {ex.Message}");
|
Logger?.Error($"MasterServer: {ex.Message}");
|
||||||
|
|
||||||
// Sleep for 5s
|
// Sleep for 5s
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
@ -124,19 +129,19 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
if (response == null)
|
if (response == null)
|
||||||
{
|
{
|
||||||
Program.Logger.Error("MasterServer: Something went wrong!");
|
Logger?.Error("MasterServer: Something went wrong!");
|
||||||
}
|
}
|
||||||
else if (response.StatusCode != HttpStatusCode.OK)
|
else if (response.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
if (response.StatusCode == HttpStatusCode.BadRequest)
|
if (response.StatusCode == HttpStatusCode.BadRequest)
|
||||||
{
|
{
|
||||||
string requestContent = await response.Content.ReadAsStringAsync();
|
string requestContent = await response.Content.ReadAsStringAsync();
|
||||||
Program.Logger.Error($"MasterServer: [{(int)response.StatusCode}], {requestContent}");
|
Logger?.Error($"MasterServer: [{(int)response.StatusCode}], {requestContent}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"MasterServer: [{(int)response.StatusCode}]");
|
Logger?.Error($"MasterServer: [{(int)response.StatusCode}]");
|
||||||
Program.Logger.Error($"MasterServer: [{await response.Content.ReadAsStringAsync()}]");
|
Logger?.Error($"MasterServer: [{await response.Content.ReadAsStringAsync()}]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,15 +151,16 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
catch (HttpRequestException ex)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"MasterServer: {ex.InnerException.Message}");
|
Logger?.Error($"MasterServer: {ex.InnerException.Message}");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"MasterServer: {ex.Message}");
|
Logger?.Error($"MasterServer: {ex.Message}");
|
||||||
}
|
}
|
||||||
}).Start();
|
}).Start();
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
BaseScript.API=API;
|
||||||
BaseScript.OnStart();
|
BaseScript.OnStart();
|
||||||
Resources.LoadAll();
|
Resources.LoadAll();
|
||||||
Listen();
|
Listen();
|
||||||
@ -162,20 +168,27 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
private void Listen()
|
private void Listen()
|
||||||
{
|
{
|
||||||
Program.Logger.Info("Listening for clients");
|
Logger?.Info("Listening for clients");
|
||||||
Program.Logger.Info("Please use CTRL + C if you want to stop the server!");
|
Logger?.Info("Please use CTRL + C if you want to stop the server!");
|
||||||
|
|
||||||
|
|
||||||
while (!Program.ReadyToStop)
|
while (!Program.ReadyToStop)
|
||||||
{
|
{
|
||||||
ProcessMessage(MainNetServer.WaitMessage(10));
|
try
|
||||||
|
{
|
||||||
|
ProcessMessage(MainNetServer.WaitMessage(200));
|
||||||
}
|
}
|
||||||
Program.Logger.Warning("Server is shutting down!");
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Logger?.Error("Error processing message");
|
||||||
|
Logger?.Error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger?.Warning("Server is shutting down!");
|
||||||
MainNetServer.Shutdown("Server is shutting down!");
|
MainNetServer.Shutdown("Server is shutting down!");
|
||||||
Program.Logger.Info("Waiting for resources to stop...Press Ctrl+C again to forcibly terminate the program.");
|
Logger?.Info("Waiting for resources to stop...Press Ctrl+C again to forcibly terminate the program.");
|
||||||
BaseScript.OnStop();
|
BaseScript.OnStop();
|
||||||
Resources.StopAll();
|
Resources.StopAll();
|
||||||
Program.Logger.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client sender;
|
Client sender;
|
||||||
@ -186,10 +199,10 @@ namespace RageCoop.Server
|
|||||||
{
|
{
|
||||||
case NetIncomingMessageType.ConnectionApproval:
|
case NetIncomingMessageType.ConnectionApproval:
|
||||||
{
|
{
|
||||||
Program.Logger.Info($"New incoming connection from: [{message.SenderConnection.RemoteEndPoint}]");
|
Logger?.Info($"New incoming connection from: [{message.SenderConnection.RemoteEndPoint}]");
|
||||||
if (message.ReadByte() != (byte)PacketTypes.Handshake)
|
if (message.ReadByte() != (byte)PacketTypes.Handshake)
|
||||||
{
|
{
|
||||||
Program.Logger.Info($"IP [{message.SenderConnection.RemoteEndPoint.Address}] was blocked, reason: Wrong packet!");
|
Logger?.Info($"IP [{message.SenderConnection.RemoteEndPoint.Address}] was blocked, reason: Wrong packet!");
|
||||||
message.SenderConnection.Deny("Wrong packet!");
|
message.SenderConnection.Deny("Wrong packet!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -206,7 +219,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Info($"IP [{message.SenderConnection.RemoteEndPoint.Address}] was blocked, reason: {e.Message}");
|
Logger?.Info($"IP [{message.SenderConnection.RemoteEndPoint.Address}] was blocked, reason: {e.Message}");
|
||||||
message.SenderConnection.Deny(e.Message);
|
message.SenderConnection.Deny(e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,19 +227,27 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
case NetIncomingMessageType.StatusChanged:
|
case NetIncomingMessageType.StatusChanged:
|
||||||
{
|
{
|
||||||
|
// Get sender client
|
||||||
|
if (!Clients.TryGetValue(message.SenderConnection.RemoteUniqueIdentifier, out sender))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
NetConnectionStatus status = (NetConnectionStatus)message.ReadByte();
|
NetConnectionStatus status = (NetConnectionStatus)message.ReadByte();
|
||||||
|
|
||||||
if (status == NetConnectionStatus.Disconnected)
|
if (status == NetConnectionStatus.Disconnected)
|
||||||
{
|
{
|
||||||
long nethandle = message.SenderConnection.RemoteUniqueIdentifier;
|
|
||||||
|
|
||||||
|
SendPlayerDisconnectPacket(sender);
|
||||||
SendPlayerDisconnectPacket(nethandle);
|
|
||||||
}
|
}
|
||||||
else if (status == NetConnectionStatus.Connected)
|
else if (status == NetConnectionStatus.Connected)
|
||||||
{
|
{
|
||||||
SendPlayerConnectPacket(message.SenderConnection);
|
SendPlayerConnectPacket(sender);
|
||||||
Resources.SendTo(Util.GetClientByNetID(message.SenderConnection.RemoteUniqueIdentifier));
|
Resources.SendTo(sender);
|
||||||
|
API.Events.InvokePlayerConnected(sender);
|
||||||
|
if (sender.IsReady)
|
||||||
|
{
|
||||||
|
API.Events.InvokePlayerReady(sender);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -291,7 +312,7 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
Packets.ProjectileSync packet = new();
|
Packets.ProjectileSync packet = new();
|
||||||
packet.Unpack(data);
|
packet.Unpack(data);
|
||||||
ProjectileSync(packet, message.SenderConnection.RemoteUniqueIdentifier);
|
ProjectileSync(packet, sender);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -329,7 +350,8 @@ namespace RageCoop.Server
|
|||||||
toRemove.Cancel=true;
|
toRemove.Cancel=true;
|
||||||
if (toRemove.Name=="Resources.zip")
|
if (toRemove.Name=="Resources.zip")
|
||||||
{
|
{
|
||||||
Clients[message.SenderConnection.RemoteUniqueIdentifier].IsReady=true;
|
sender.IsReady=true;
|
||||||
|
API.Events.InvokePlayerReady(sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,14 +361,14 @@ namespace RageCoop.Server
|
|||||||
{
|
{
|
||||||
// Sync Events
|
// Sync Events
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
var toSend = MainNetServer.Connections.Exclude(message.SenderConnection);
|
||||||
|
if (toSend.Count!=0)
|
||||||
{
|
{
|
||||||
var outgoingMessage = MainNetServer.CreateMessage();
|
var outgoingMessage = MainNetServer.CreateMessage();
|
||||||
outgoingMessage.Write(btype);
|
outgoingMessage.Write(btype);
|
||||||
outgoingMessage.Write(len);
|
outgoingMessage.Write(len);
|
||||||
outgoingMessage.Write(data);
|
outgoingMessage.Write(data);
|
||||||
var toSend = MainNetServer.Connections.Exclude(message.SenderConnection);
|
|
||||||
if (toSend.Count!=0)
|
|
||||||
{
|
|
||||||
MainNetServer.SendMessage(outgoingMessage, toSend, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.SyncEvents);
|
MainNetServer.SendMessage(outgoingMessage, toSend, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.SyncEvents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,7 +379,7 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Program.Logger.Error("Unhandled Data / Packet type");
|
Logger?.Error("Unhandled Data / Packet type");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -370,32 +392,36 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
case NetIncomingMessageType.ConnectionLatencyUpdated:
|
case NetIncomingMessageType.ConnectionLatencyUpdated:
|
||||||
{
|
{
|
||||||
Client client = Util.GetClientByNetID(message.SenderConnection.RemoteUniqueIdentifier);
|
// Get sender client
|
||||||
if (client != null)
|
if (!Clients.TryGetValue(message.SenderConnection.RemoteUniqueIdentifier, out sender))
|
||||||
{
|
{
|
||||||
client.Latency = message.ReadFloat();
|
break;
|
||||||
|
}
|
||||||
|
if (sender != null)
|
||||||
|
{
|
||||||
|
sender.Latency = message.ReadFloat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.ErrorMessage:
|
case NetIncomingMessageType.ErrorMessage:
|
||||||
Program.Logger.Error(message.ReadString());
|
Logger?.Error(message.ReadString());
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.WarningMessage:
|
case NetIncomingMessageType.WarningMessage:
|
||||||
Program.Logger.Warning(message.ReadString());
|
Logger?.Warning(message.ReadString());
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.DebugMessage:
|
case NetIncomingMessageType.DebugMessage:
|
||||||
case NetIncomingMessageType.VerboseDebugMessage:
|
case NetIncomingMessageType.VerboseDebugMessage:
|
||||||
Program.Logger.Debug(message.ReadString());
|
Logger?.Debug(message.ReadString());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Program.Logger.Error(string.Format("Unhandled type: {0} {1} bytes {2} | {3}", message.MessageType, message.LengthBytes, message.DeliveryMethod, message.SequenceChannel));
|
Logger?.Error(string.Format("Unhandled type: {0} {1} bytes {2} | {3}", message.MessageType, message.LengthBytes, message.DeliveryMethod, message.SequenceChannel));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainNetServer.Recycle(message);
|
MainNetServer.Recycle(message);
|
||||||
}
|
}
|
||||||
static object _sendPlayersLock=new object();
|
object _sendPlayersLock=new object();
|
||||||
public static void SendPlayerInfos()
|
public void SendPlayerInfos()
|
||||||
{
|
{
|
||||||
lock (_sendPlayersLock)
|
lock (_sendPlayersLock)
|
||||||
{
|
{
|
||||||
@ -422,9 +448,9 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
private void DisconnectAndLog(NetConnection senderConnection,PacketTypes type, Exception e)
|
private void DisconnectAndLog(NetConnection senderConnection,PacketTypes type, Exception e)
|
||||||
{
|
{
|
||||||
Program.Logger.Error($"Error receiving a packet of type {type}");
|
Logger?.Error($"Error receiving a packet of type {type}");
|
||||||
Program.Logger.Error(e.Message);
|
Logger?.Error(e.Message);
|
||||||
Program.Logger.Error(e.StackTrace);
|
Logger?.Error(e.StackTrace);
|
||||||
senderConnection.Disconnect(e.Message);
|
senderConnection.Disconnect(e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +458,7 @@ namespace RageCoop.Server
|
|||||||
// Before we approve the connection, we must shake hands
|
// Before we approve the connection, we must shake hands
|
||||||
private void GetHandshake(NetConnection connection, Packets.Handshake packet)
|
private void GetHandshake(NetConnection connection, Packets.Handshake packet)
|
||||||
{
|
{
|
||||||
Program.Logger.Debug("New handshake from: [Name: " + packet.Username + " | Address: " + connection.RemoteEndPoint.Address.ToString() + "]");
|
Logger?.Debug("New handshake from: [Name: " + packet.Username + " | Address: " + connection.RemoteEndPoint.Address.ToString() + "]");
|
||||||
|
|
||||||
if (!packet.ModVersion.StartsWith(_compatibleVersion))
|
if (!packet.ModVersion.StartsWith(_compatibleVersion))
|
||||||
{
|
{
|
||||||
@ -476,7 +502,7 @@ namespace RageCoop.Server
|
|||||||
lock (Clients)
|
lock (Clients)
|
||||||
{
|
{
|
||||||
Clients.Add(connection.RemoteUniqueIdentifier,
|
Clients.Add(connection.RemoteUniqueIdentifier,
|
||||||
tmpClient = new Client()
|
tmpClient = new Client(this)
|
||||||
{
|
{
|
||||||
NetID = connection.RemoteUniqueIdentifier,
|
NetID = connection.RemoteUniqueIdentifier,
|
||||||
Connection=connection,
|
Connection=connection,
|
||||||
@ -489,7 +515,7 @@ namespace RageCoop.Server
|
|||||||
);;
|
);;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.Logger.Debug($"Handshake sucess, Player:{packet.Username} PedID:{packet.PedID}");
|
Logger?.Debug($"Handshake sucess, Player:{packet.Username} PedID:{packet.PedID}");
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
|
|
||||||
// Create a new handshake packet
|
// Create a new handshake packet
|
||||||
@ -504,93 +530,68 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The connection has been approved, now we need to send all other players to the new player and the new player to all players
|
// The connection has been approved, now we need to send all other players to the new player and the new player to all players
|
||||||
private static void SendPlayerConnectPacket(NetConnection local)
|
private void SendPlayerConnectPacket(Client newClient)
|
||||||
{
|
{
|
||||||
Client localClient = Util.GetClientByNetID(local.RemoteUniqueIdentifier);
|
|
||||||
if (localClient == null)
|
|
||||||
{
|
|
||||||
local.Disconnect("No data found!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NetConnection> clients=MainNetServer.Connections.Exclude(local);
|
// Send other players to this client
|
||||||
// Send all players to local
|
Clients.Values.ForEach(target =>
|
||||||
|
|
||||||
|
|
||||||
if (clients.Count > 0)
|
|
||||||
{
|
{
|
||||||
clients.ForEach(targetPlayer =>
|
if (target==newClient) { return; }
|
||||||
{
|
|
||||||
long targetNetHandle = targetPlayer.RemoteUniqueIdentifier;
|
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
|
|
||||||
Client targetClient = Util.GetClientByNetID(targetNetHandle);
|
|
||||||
if (targetClient != null)
|
|
||||||
{
|
|
||||||
new Packets.PlayerConnect()
|
new Packets.PlayerConnect()
|
||||||
{
|
{
|
||||||
// NetHandle = targetNetHandle,
|
// NetHandle = targetNetHandle,
|
||||||
Username = targetClient.Username,
|
Username = target.Username,
|
||||||
PedID=targetClient.ID,
|
PedID=target.ID,
|
||||||
|
|
||||||
}.Pack(outgoingMessage);
|
}.Pack(outgoingMessage);
|
||||||
MainNetServer.SendMessage(outgoingMessage, local, NetDeliveryMethod.ReliableOrdered, 0);
|
MainNetServer.SendMessage(outgoingMessage, newClient.Connection, NetDeliveryMethod.ReliableOrdered, 0);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
// Send new client to all players
|
||||||
// Send local to all players
|
var cons = MainNetServer.Connections.Exclude(newClient.Connection);
|
||||||
|
if (cons.Count!=0)
|
||||||
|
{
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
new Packets.PlayerConnect()
|
new Packets.PlayerConnect()
|
||||||
{
|
{
|
||||||
PedID=localClient.ID,
|
PedID=newClient.ID,
|
||||||
Username = localClient.Username
|
Username = newClient.Username
|
||||||
}.Pack(outgoingMessage);
|
}.Pack(outgoingMessage);
|
||||||
if(clients.Count > 0)
|
|
||||||
{
|
|
||||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
API.Events.InvokePlayerConnected(localClient);
|
|
||||||
|
|
||||||
Program.Logger.Info($"Player {localClient.Username} connected!");
|
MainNetServer.SendMessage(outgoingMessage,cons , NetDeliveryMethod.ReliableOrdered, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger?.Info($"Player {newClient.Username} connected!");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(MainSettings.WelcomeMessage))
|
if (!string.IsNullOrEmpty(MainSettings.WelcomeMessage))
|
||||||
{
|
{
|
||||||
SendChatMessage(new Packets.ChatMessage() { Username = "Server", Message = MainSettings.WelcomeMessage }, null,new List<NetConnection>() { local });
|
SendChatMessage(new Packets.ChatMessage() { Username = "Server", Message = MainSettings.WelcomeMessage }, null,new List<NetConnection>() { newClient.Connection });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send all players a message that someone has left the server
|
// Send all players a message that someone has left the server
|
||||||
private static void SendPlayerDisconnectPacket(long nethandle)
|
private void SendPlayerDisconnectPacket(Client localClient)
|
||||||
{
|
{
|
||||||
List<NetConnection> clients = MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != nethandle);
|
var cons = MainNetServer.Connections.Exclude(localClient.Connection);
|
||||||
int playerPedID = Clients[nethandle].ID;
|
if (cons.Count!=0)
|
||||||
if (clients.Count > 0)
|
|
||||||
{
|
{
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
new Packets.PlayerDisconnect()
|
new Packets.PlayerDisconnect()
|
||||||
{
|
{
|
||||||
PedID=playerPedID,
|
PedID=localClient.ID,
|
||||||
|
|
||||||
}.Pack(outgoingMessage);
|
}.Pack(outgoingMessage);
|
||||||
MainNetServer.SendMessage(outgoingMessage, clients, NetDeliveryMethod.ReliableOrdered, 0);
|
MainNetServer.SendMessage(outgoingMessage,cons , NetDeliveryMethod.ReliableOrdered, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Client localClient = Util.GetClientByNetID( nethandle);
|
|
||||||
if (localClient == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clients.Remove(localClient.NetID);
|
|
||||||
|
|
||||||
API.Events.InvokePlayerDisconnected(localClient);
|
API.Events.InvokePlayerDisconnected(localClient);
|
||||||
Program.Logger.Info($"Player {localClient.Username} disconnected! ID:{playerPedID}");
|
Logger?.Info($"Player {localClient.Username} disconnected! ID:{localClient.ID}");
|
||||||
|
Clients.Remove(localClient.NetID);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region SyncEntities
|
#region SyncEntities
|
||||||
private static void PedStateSync(Packets.PedStateSync packet, Client client)
|
private void PedStateSync(Packets.PedStateSync packet, Client client)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@ -604,7 +605,7 @@ namespace RageCoop.Server
|
|||||||
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void VehicleStateSync(Packets.VehicleStateSync packet, Client client)
|
private void VehicleStateSync(Packets.VehicleStateSync packet, Client client)
|
||||||
{
|
{
|
||||||
// Save the new data
|
// Save the new data
|
||||||
if (packet.Passengers.ContainsValue(client.ID))
|
if (packet.Passengers.ContainsValue(client.ID))
|
||||||
@ -620,7 +621,7 @@ namespace RageCoop.Server
|
|||||||
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void PedSync(Packets.PedSync packet, Client client)
|
private void PedSync(Packets.PedSync packet, Client client)
|
||||||
{
|
{
|
||||||
bool isPlayer = packet.ID==client.ID;
|
bool isPlayer = packet.ID==client.ID;
|
||||||
if (isPlayer)
|
if (isPlayer)
|
||||||
@ -654,7 +655,7 @@ namespace RageCoop.Server
|
|||||||
MainNetServer.SendMessage(outgoingMessage,c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
MainNetServer.SendMessage(outgoingMessage,c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void VehicleSync(Packets.VehicleSync packet, Client client)
|
private void VehicleSync(Packets.VehicleSync packet, Client client)
|
||||||
{
|
{
|
||||||
bool isPlayer = packet.ID==client.Player.VehicleID;
|
bool isPlayer = packet.ID==client.Player.VehicleID;
|
||||||
foreach (var c in Clients.Values)
|
foreach (var c in Clients.Values)
|
||||||
@ -678,13 +679,8 @@ namespace RageCoop.Server
|
|||||||
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static void ProjectileSync(Packets.ProjectileSync packet, long ClientID)
|
private void ProjectileSync(Packets.ProjectileSync packet, Client client)
|
||||||
{
|
{
|
||||||
Client client = Util.GetClientByNetID(ClientID);
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var c in Clients.Values)
|
foreach (var c in Clients.Values)
|
||||||
{
|
{
|
||||||
@ -697,7 +693,7 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
// Send a message to targets or all players
|
// Send a message to targets or all players
|
||||||
private static void SendChatMessage(Packets.ChatMessage packet,Client sender=null, List<NetConnection> targets = null)
|
private void SendChatMessage(Packets.ChatMessage packet,Client sender=null, List<NetConnection> targets = null)
|
||||||
{
|
{
|
||||||
if (packet.Message.StartsWith('/'))
|
if (packet.Message.StartsWith('/'))
|
||||||
{
|
{
|
||||||
@ -722,13 +718,8 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
if (command.Key.Usage != null && command.Key.ArgsLength != argsWithoutCmd.Length)
|
if (command.Key.Usage != null && command.Key.ArgsLength != argsWithoutCmd.Length)
|
||||||
{
|
{
|
||||||
NetConnection userConnection = Util.GetConnectionByUsername(packet.Username);
|
|
||||||
if (userConnection == default)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendChatMessage("Server", command.Key.Usage, userConnection);
|
SendChatMessage("Server", command.Key.Usage,sender.Connection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,13 +727,8 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NetConnection userConnection = Util.GetConnectionByUsername(packet.Username);
|
|
||||||
if (userConnection == default)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendChatMessage("Server", "Command not found!", userConnection);
|
SendChatMessage("Server", "Command not found!", sender.Connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -750,25 +736,26 @@ namespace RageCoop.Server
|
|||||||
packet.Message = packet.Message.Replace("~", "");
|
packet.Message = packet.Message.Replace("~", "");
|
||||||
SendChatMessage(packet.Username, packet.Message, targets);
|
SendChatMessage(packet.Username, packet.Message, targets);
|
||||||
|
|
||||||
Program.Logger.Info(packet.Username + ": " + packet.Message);
|
Logger?.Info(packet.Username + ": " + packet.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendChatMessage(string username, string message, List<NetConnection> targets = null)
|
public void SendChatMessage(string username, string message, List<NetConnection> targets = null)
|
||||||
{
|
{
|
||||||
|
if (MainNetServer.Connections.Count==0) { return; }
|
||||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||||
|
|
||||||
new Packets.ChatMessage() { Username = username, Message = message }.Pack(outgoingMessage);
|
new Packets.ChatMessage() { Username = username, Message = message }.Pack(outgoingMessage);
|
||||||
|
|
||||||
MainNetServer.SendMessage(outgoingMessage, targets ?? MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
|
MainNetServer.SendMessage(outgoingMessage, targets ?? MainNetServer.Connections, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Chat);
|
||||||
}
|
}
|
||||||
public static void SendChatMessage(string username, string message, NetConnection target)
|
public 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 static void RegisterCommand(string name, string usage, short argsLength, Action<CommandContext> callback)
|
public 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 };
|
||||||
|
|
||||||
@ -779,7 +766,7 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
Commands.Add(command, callback);
|
Commands.Add(command, callback);
|
||||||
}
|
}
|
||||||
public static void RegisterCommand(string name, Action<CommandContext> callback)
|
public void RegisterCommand(string name, Action<CommandContext> callback)
|
||||||
{
|
{
|
||||||
Command command = new(name);
|
Command command = new(name);
|
||||||
|
|
||||||
@ -791,7 +778,7 @@ namespace RageCoop.Server
|
|||||||
Commands.Add(command, callback);
|
Commands.Add(command, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RegisterCommands<T>()
|
public 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());
|
||||||
|
|
||||||
@ -803,13 +790,13 @@ namespace RageCoop.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendFile(string path,string name,Client client,Action<float> updateCallback=null)
|
public 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);
|
||||||
fs.Seek(0, SeekOrigin.Begin);
|
fs.Seek(0, SeekOrigin.Begin);
|
||||||
var total = fs.Length;
|
var total = fs.Length;
|
||||||
Program.Logger.Debug($"Initiating file transfer:{name}, {total}");
|
Logger?.Debug($"Initiating file transfer:{name}, {total}");
|
||||||
FileTransfer transfer = new()
|
FileTransfer transfer = new()
|
||||||
{
|
{
|
||||||
ID=id,
|
ID=id,
|
||||||
@ -835,7 +822,7 @@ namespace RageCoop.Server
|
|||||||
if (thisRead!=chunk.Length)
|
if (thisRead!=chunk.Length)
|
||||||
{
|
{
|
||||||
if (thisRead==0) { break; }
|
if (thisRead==0) { break; }
|
||||||
Program.Logger.Trace($"Purging chunk:{thisRead}");
|
Logger?.Trace($"Purging chunk:{thisRead}");
|
||||||
Array.Resize(ref chunk, thisRead);
|
Array.Resize(ref chunk, thisRead);
|
||||||
}
|
}
|
||||||
Send(
|
Send(
|
||||||
@ -858,10 +845,10 @@ namespace RageCoop.Server
|
|||||||
);
|
);
|
||||||
fs.Close();
|
fs.Close();
|
||||||
fs.Dispose();
|
fs.Dispose();
|
||||||
Program.Logger.Debug($"All file chunks sent:{name}");
|
Logger?.Debug($"All file chunks sent:{name}");
|
||||||
InProgressFileTransfers.Remove(id);
|
InProgressFileTransfers.Remove(id);
|
||||||
}
|
}
|
||||||
private static int RequestFileID()
|
private int RequestFileID()
|
||||||
{
|
{
|
||||||
int ID = 0;
|
int ID = 0;
|
||||||
while ((ID==0)
|
while ((ID==0)
|
||||||
@ -883,7 +870,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 static void Send(Packet p,Client client, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
public 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);
|
||||||
|
@ -47,7 +47,7 @@ namespace RageCoop.Server
|
|||||||
_ => (0x0, null),
|
_ => (0x0, null),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
public static Client GetClientByNetID(long id)
|
public static Client GetClientByNetID(long id)
|
||||||
{
|
{
|
||||||
Client result = null;
|
Client result = null;
|
||||||
@ -75,17 +75,18 @@ namespace RageCoop.Server
|
|||||||
|
|
||||||
return Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == client.NetID);
|
return Server.MainNetServer.Connections.Find(x => x.RemoteUniqueIdentifier == client.NetID);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// Return a list of all connections but not the local connection
|
// Return a list of all connections but not the local connection
|
||||||
public static List<NetConnection> Exclude(this IEnumerable<NetConnection> connections,NetConnection toExclude)
|
public static List<NetConnection> Exclude(this IEnumerable<NetConnection> connections,NetConnection toExclude)
|
||||||
{
|
{
|
||||||
return new(connections.Where(e => e != toExclude));
|
return new(connections.Where(e => e != toExclude));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
public static List<NetConnection> FilterAllLocal(long local)
|
public static List<NetConnection> FilterAllLocal(long local)
|
||||||
{
|
{
|
||||||
return new(Server.MainNetServer.Connections.Where(e => e.RemoteUniqueIdentifier != local));
|
return new(Server.MainNetServer.Connections.Where(e => e.RemoteUniqueIdentifier != local));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public static T Read<T>(string file) where T : new()
|
public static T Read<T>(string file) where T : new()
|
||||||
{
|
{
|
||||||
XmlSerializer ser = new(typeof(T));
|
XmlSerializer ser = new(typeof(T));
|
||||||
|
Reference in New Issue
Block a user