Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sealed classes, refactored code, added more debugs, better errors. #22

Merged
merged 1 commit into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions LethalNetworkAPI/Event/LNetworkEvent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace LethalNetworkAPI;

/// <summary>
/// Internal Class
/// Internal class.
/// </summary>
public abstract class LNetworkEvent(string identifier) : LethalNetwork($"evt.{identifier}");
public abstract class LNetworkEvent(string identifier) : LethalNetwork($"evt.{identifier}", "Event");
48 changes: 35 additions & 13 deletions LethalNetworkAPI/Event/LethalClientEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@

namespace LethalNetworkAPI;

public class LethalClientEvent : LNetworkEvent
public sealed class LethalClientEvent : LNetworkEvent
{
#region Public Constructors

/// <summary>
/// Create a new network event for clients.
/// </summary>
///
/// <param name="identifier">(<see cref="string"/>) An identifier for the event.</param>
/// <param name="onReceived">Opt. (<see cref="Action">Action</see>) The method to run when an event is received from the server.</param>
/// <param name="onReceivedFromClient">Opt. (<see cref="Action{T}">Action&lt;ulong&gt;</see>) The method to run when an event is received from another client.</param>
///
/// <param name="onReceived">Opt. (<see cref="Action">Action</see>)
/// The method to run when an event is received from the server.</param>
///
/// <param name="onReceivedFromClient">Opt. (<see cref="Action{T}">Action&lt;ulong&gt;</see>)
/// The method to run when an event is received from another client.</param>
///
/// <remarks>Identifiers are specific to a per-mod basis.</remarks>
public LethalClientEvent(string identifier,
Action? onReceived = null,
Expand All @@ -25,7 +31,8 @@ public LethalClientEvent(string identifier,
OnReceivedFromClient += onReceivedFromClient;

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"NetworkEvent with identifier \"{Identifier}\" has been created.");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"NetworkEvent with identifier \"{Identifier}\" has been created.");
#endif
}

Expand All @@ -45,9 +52,16 @@ public void InvokeServer()
/// <summary>
/// Invoke event to all clients.
/// </summary>
/// <param name="includeLocalClient">Opt. (<see cref="bool"/>) If the local client event should be invoked.</param>
/// <param name="waitForServerResponse">Opt. (<see cref="bool"/>) If the local client should wait for a server response before invoking the <see cref="OnReceivedFromClient"/> event.</param>
/// <remarks><paramref name="waitForServerResponse"/> will only be considered if <paramref name="includeLocalClient"/> is set to true.</remarks>
///
/// <param name="includeLocalClient">Opt. (<see cref="bool"/>)
/// If the local client event should be invoked.</param>
///
/// <param name="waitForServerResponse">Opt. (<see cref="bool"/>)
/// If the local client should wait for a server response before
/// invoking the <see cref="OnReceivedFromClient"/> event.</param>
///
/// <remarks><paramref name="waitForServerResponse"/> will only be considered
/// if <paramref name="includeLocalClient"/> is set to true.</remarks>
public void InvokeAllClients(bool includeLocalClient = true, bool waitForServerResponse = false)
{
if (IsNetworkHandlerNull()) return;
Expand All @@ -59,7 +73,9 @@ public void InvokeAllClients(bool includeLocalClient = true, bool waitForServerR
OnReceivedFromClient?.Invoke(NetworkManager.Singleton.LocalClientId);

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Attempted to invoke Event to All Clients {includeLocalClient} with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Attempted to invoke Event to All Clients {includeLocalClient}" +
$" with identifier: {Identifier}");
#endif
}

Expand All @@ -78,7 +94,8 @@ public void InvokeAllClientsSynced()
ReceiveClientEvent(Identifier, NetworkManager.Singleton.LocalClientId);

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Attempted to invoke Synced Event to Other Clients with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Attempted to invoke Synced Event to Other Clients with identifier: {Identifier}");
#endif
}

Expand All @@ -91,6 +108,7 @@ public void InvokeAllClientsSynced()
/// <summary>
/// The callback to invoke when an event is received from another client.
/// </summary>
///
/// <typeparam name="ulong">The origin client ID.</typeparam>
public event Action<ulong>? OnReceivedFromClient;

Expand All @@ -108,7 +126,8 @@ private void ReceiveClientEvent(string identifier, ulong originatorClientId)
OnReceivedFromClient?.Invoke(originatorClientId);

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Received event with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Received event with identifier: {Identifier}");
#endif
}

Expand All @@ -118,10 +137,12 @@ private void ReceiveSyncedClientEvent(string identifier, double time, ulong orig

var timeToWait = time - NetworkManager.Singleton.ServerTime.Time;

NetworkHandler.Instance.StartCoroutine(WaitAndInvokeEvent((float)timeToWait, originatorClientId));
NetworkHandler.Instance.StartCoroutine(
WaitAndInvokeEvent((float)timeToWait, originatorClientId));

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Received synced event with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Received synced event with identifier: {Identifier}");
#endif
}

Expand All @@ -133,7 +154,8 @@ private IEnumerator WaitAndInvokeEvent(float timeToWait, ulong originatorClientI
ReceiveClientEvent(Identifier, originatorClientId);

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Invoked event with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Invoked event with identifier: {Identifier}");
#endif
}

Expand Down
40 changes: 29 additions & 11 deletions LethalNetworkAPI/Event/LethalServerEvent.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;

namespace LethalNetworkAPI;

public class LethalServerEvent : LNetworkEvent
public sealed class LethalServerEvent : LNetworkEvent
{
#region Public Constructors

/// <summary>
/// Create a new network event for the server.
/// </summary>
///
/// <param name="identifier">(<see cref="string"/>) An identifier for the event.</param>
/// <param name="onReceived">Opt. (<see cref="Action{T}">Action&lt;ulong&gt;</see>) The method to run when an event is received from a client.</param>
///
/// <param name="onReceived">Opt. (<see cref="Action{T}">Action&lt;ulong&gt;</see>)
/// The method to run when an event is received from a client.</param>
///
/// <remarks>Identifiers are specific to a per-mod basis.</remarks>
public LethalServerEvent(string identifier, Action<ulong>? onReceived = null) : base(identifier)
{
Expand All @@ -29,6 +32,7 @@ public LethalServerEvent(string identifier, Action<ulong>? onReceived = null) :
/// <summary>
/// Invoke event to a specific client.
/// </summary>
///
/// <param name="clientId">(<see cref="UInt64">ulong</see>) The client to invoke the event to.</param>
public void InvokeClient(ulong clientId)
{
Expand All @@ -38,14 +42,18 @@ public void InvokeClient(ulong clientId)
clientRpcParams: GenerateClientParams(clientId));

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Attempted to invoke Event to Client {clientId} with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Attempted to invoke Event to Client {clientId}" +
$" with identifier: {Identifier}");
#endif
}

/// <summary>
/// Invoke event to specific clients.
/// </summary>
/// <param name="clientIds">(<see cref="IEnumerable{UInt64}">IEnumerable&lt;ulong&gt;</see>) The clients to invoke the event to.</param>
///
/// <param name="clientIds">(<see cref="IEnumerable{UInt64}">IEnumerable&lt;ulong&gt;</see>)
/// The clients to invoke the event to.</param>
public void InvokeClients(IEnumerable<ulong> clientIds)
{
if (IsNetworkHandlerNull() || !IsHostOrServer()) return;
Expand All @@ -54,14 +62,18 @@ public void InvokeClients(IEnumerable<ulong> clientIds)
clientRpcParams: GenerateClientParams(clientIds));

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Attempted to invoke Event to Clients {clientIds} with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Attempted to invoke Event to Clients {clientIds}" +
$" with identifier: {Identifier}");
#endif
}

/// <summary>
/// Invoke event to all clients.
/// </summary>
/// <param name="receiveOnHost">Opt. (<see cref="bool"/>) Whether the host client should receive as well.</param>
///
/// <param name="receiveOnHost">Opt. (<see cref="bool"/>)
/// Whether the host client should receive as well.</param>
public void InvokeAllClients(bool receiveOnHost = true)
{
if (IsNetworkHandlerNull() || !IsHostOrServer()) return;
Expand All @@ -73,14 +85,17 @@ public void InvokeAllClients(bool receiveOnHost = true)
clientRpcParams: GenerateClientParamsExceptHost());

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Attempted to invoke Event to All Clients {receiveOnHost} with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Attempted to invoke Event to All Clients {receiveOnHost}" +
$" with identifier: {Identifier}");
#endif
}

// ReSharper disable once InvalidXmlDocComment
/// <summary>
/// The callback to invoke when an event is received by the server.
/// </summary>
///
/// <typeparam name="ulong">The origin client ID.</typeparam>
public event Action<ulong>? OnReceived;

Expand All @@ -95,7 +110,8 @@ private void ReceiveServerEvent(string identifier, ulong originClientId)
OnReceived?.Invoke(originClientId);

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Received event with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Received event with identifier: {Identifier}");
#endif
}

Expand All @@ -111,7 +127,8 @@ private void ReceiveSyncedServerEvent(string identifier, double time, ulong orig
NetworkHandler.Instance.StartCoroutine(WaitAndInvokeEvent((float)timeToWait, originatorClientId));

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Received synced event with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Received synced event with identifier: {Identifier}");
#endif
}

Expand All @@ -123,7 +140,8 @@ private IEnumerator WaitAndInvokeEvent(float timeToWait, ulong clientId)
OnReceived?.Invoke(clientId);

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"Invoked event with identifier: {Identifier}");
LethalNetworkAPIPlugin.Logger.LogDebug(
$"Invoked event with identifier: {Identifier}");
#endif
}

Expand Down
25 changes: 16 additions & 9 deletions LethalNetworkAPI/LethalNetwork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@

namespace LethalNetworkAPI;

/// <summary>
/// Internal class.
/// </summary>
public abstract class LethalNetwork
{
protected LethalNetwork(string identifier, int frameIndex = 3)

internal readonly string Identifier = null!;
private readonly string _networkType = null!;

protected LethalNetwork(string identifier, string networkType, int frameIndex = 3)
{
try
{
Expand All @@ -18,14 +25,15 @@ protected LethalNetwork(string identifier, int frameIndex = 3)
var pluginType = AccessTools.GetTypesFromAssembly(assembly).First(type => type.GetCustomAttributes(typeof(BepInPlugin), false).Any());

Identifier = $"{MetadataHelper.GetMetadata(pluginType).GUID}.{identifier}";
_networkType = networkType;

#if DEBUG
LethalNetworkAPIPlugin.Logger.LogDebug($"LethalNetwork with identifier \"{Identifier}\" has been created.");
LethalNetworkAPIPlugin.Logger.LogDebug($"LethalNetwork {_networkType} with identifier \"{Identifier}\" has been created.");
#endif
}
catch (Exception e)
{
LethalNetworkAPIPlugin.Logger.LogError($"Unable to find plugin info for calling mod with identifier {identifier}. Are you using BepInEx? \n Stacktrace: {e}");
LethalNetworkAPIPlugin.Logger.LogError(string.Format(TextDefinitions.UnableToFindGuid, _networkType.ToLower(), Identifier, e));
}
}

Expand All @@ -37,19 +45,19 @@ protected bool IsNetworkHandlerNull(bool log = true)
if (NetworkHandler.Instance != null) return false;

if (log) LethalNetworkAPIPlugin.Logger.LogError(string.Format(
TextDefinitions.NotInLobbyEvent, Identifier));
TextDefinitions.NotInLobbyEvent, _networkType.ToLower(), Identifier));
return true;
}

/// <returns>true if it is host</returns>
protected bool IsHostOrServer(bool log = true)
{
if (NetworkManager.Singleton == null) return false;

if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) return true;

if (log) LethalNetworkAPIPlugin.Logger.LogError(string.Format(
TextDefinitions.NotServerInfo, NetworkManager.Singleton.LocalClientId, Identifier));
TextDefinitions.NotServerInfo, NetworkManager.Singleton.LocalClientId, _networkType, Identifier));

return false;
}

Expand All @@ -59,7 +67,8 @@ private bool DoClientsExist(IEnumerable<ulong> clientIds, bool log = true)
if (clientIds.Any()) return true;

if (log) LethalNetworkAPIPlugin.Logger.LogError(string.Format(
TextDefinitions.TargetClientsNotConnected, clientIds, Identifier));
TextDefinitions.TargetClientsNotConnected, clientIds, _networkType, Identifier));

return false;
}

Expand Down Expand Up @@ -103,6 +112,4 @@ private ClientRpcParams GenerateClientParams(IEnumerable<ulong> clientIds, bool
protected ClientRpcParams GenerateClientParamsExceptHost() => GenerateClientParams([], true);

#endregion

internal readonly string Identifier = null!;
}
9 changes: 4 additions & 5 deletions LethalNetworkAPI/LethalNetworkExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using GameNetcodeStuff;
using LethalNetworkAPI;

namespace LethalNetworkAPI;

Expand Down Expand Up @@ -64,12 +63,12 @@ public static ulong GetClientId(this PlayerControllerB player)
/// <returns>(<see cref="LethalNetworkVariable{TData}"/>) The network variable.</returns>
/// <remarks>The variable is set to only allow writing by the object's owner client. In order to sync on all clients, the host must also run this method on the same GameObject with the same identifier.</remarks>
public static LethalNetworkVariable<TData>? GetNetworkVariable<TData>(this GameObject gameObject, string identifier, bool serverOwned = false) => gameObject.NetworkVariable<TData>(identifier, serverOwned);
internal static LethalNetworkVariable<TData>? NetworkVariable<TData>(this GameObject gameObject, string identifier, bool serverOwned)

private static LethalNetworkVariable<TData>? NetworkVariable<TData>(this GameObject gameObject, string identifier, bool serverOwned)
{
if (gameObject.TryGetComponent(out NetworkObject networkObjectComp) == false)
{
LethalNetworkAPIPlugin.Logger.LogError(TextDefinitions.UnableToLocateNetworkObjectComponent);
LethalNetworkAPIPlugin.Logger.LogError(string.Format(TextDefinitions.UnableToLocateNetworkObjectComponent, identifier));
return null;
}

Expand All @@ -81,7 +80,7 @@ public static ulong GetClientId(this PlayerControllerB player)
return networkVariable;

networkVariable = new LethalNetworkVariable<TData>($"{identifier}.{networkObjectComp.GlobalObjectIdHash}", networkObjectComp, serverOwned, 3);
NetworkHandler.Instance!.ObjectNetworkVariableList.Add(networkVariable);
NetworkHandler.Instance.ObjectNetworkVariableList.Add(networkVariable);

return networkVariable;
}
Expand Down
4 changes: 2 additions & 2 deletions LethalNetworkAPI/Message/LNetworkMessage.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace LethalNetworkAPI;

/// <summary>
/// Internal Class
/// Internal class.
/// </summary>
public abstract class LNetworkMessage(string identifier) : LethalNetwork($"msg.{identifier}");
public abstract class LNetworkMessage(string identifier) : LethalNetwork($"msg.{identifier}", "Message");
Loading