diff --git a/CLre.sln b/CLre.sln index 02426c3..f8f3807 100644 --- a/CLre.sln +++ b/CLre.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.29609.76 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLre", "CLre\CLre.csproj", "{E0EEA15D-AB3C-4C73-A000-C49B5AE9EA66}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLre_server", "CLre_server\CLre_server.csproj", "{89B354CF-C654-4E48-8166-5E20BC6E4836}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,10 +15,6 @@ Global {E0EEA15D-AB3C-4C73-A000-C49B5AE9EA66}.Debug|Any CPU.Build.0 = Debug|Any CPU {E0EEA15D-AB3C-4C73-A000-C49B5AE9EA66}.Release|Any CPU.ActiveCfg = Release|Any CPU {E0EEA15D-AB3C-4C73-A000-C49B5AE9EA66}.Release|Any CPU.Build.0 = Release|Any CPU - {89B354CF-C654-4E48-8166-5E20BC6E4836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {89B354CF-C654-4E48-8166-5E20BC6E4836}.Debug|Any CPU.Build.0 = Debug|Any CPU - {89B354CF-C654-4E48-8166-5E20BC6E4836}.Release|Any CPU.ActiveCfg = Release|Any CPU - {89B354CF-C654-4E48-8166-5E20BC6E4836}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CLre/API/App/Client.cs b/CLre/API/App/Client.cs index e1c2db9..51d4bcf 100644 --- a/CLre/API/App/Client.cs +++ b/CLre/API/App/Client.cs @@ -1,7 +1,6 @@ using System; using System.Reflection; using HarmonyLib; -using User; namespace CLre.API.App { @@ -54,12 +53,6 @@ namespace CLre.API.App add => GameFrameworkEngine.gameFrameworkExit += value; remove => GameFrameworkEngine.gameFrameworkExit += value; } - - public static event EventHandler GameJoin - { - add => ClientGameJoinSequence_OnUserValidated_Patch.gameJoin += value; - remove => ClientGameJoinSequence_OnUserValidated_Patch.gameJoin += value; - } public static string Version { @@ -121,27 +114,4 @@ namespace CLre.API.App return AccessTools.Method("FrontEnd.FrontEndGuiEngine:SetMainMenuEnabled"); } } - - // TODO patch OnUserValidationFailed as well - [HarmonyPatch] - class ClientGameJoinSequence_OnUserValidated_Patch - { - internal static event EventHandler gameJoin; - - [HarmonyPostfix] - public static void AfterMethodCall(object __instance, ref SerializedAccountInfo validated) - { - if (gameJoin != null) gameJoin(__instance, new GameJoin - { - Success = true, - Data = validated, - }); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("MultiplayerClient.ClientGameJoinSequence:OnUserValidated"); - } - } } \ No newline at end of file diff --git a/CLre/API/App/ClientEngines.cs b/CLre/API/App/ClientEngines.cs index 173df17..b699fad 100644 --- a/CLre/API/App/ClientEngines.cs +++ b/CLre/API/App/ClientEngines.cs @@ -14,6 +14,9 @@ namespace CLre.API.App if (gameEngineReady != null) gameEngineReady(this, new GameReady { }); } + public override IEntitiesDB entitiesDB { get; set; } + public override IEntityFactory entityFactory { get; set; } + public void OnFrameworkInitialized() { // TODO framework init event @@ -30,6 +33,9 @@ namespace CLre.API.App { } + public override IEntitiesDB entitiesDB { get; set; } + public override IEntityFactory entityFactory { get; set; } + public void OnFrameworkInitialized() { if (gameFrameworkReady != null) gameFrameworkReady(this, new GameReady { }); @@ -49,5 +55,8 @@ namespace CLre.API.App { if (menuEngineReady != null) menuEngineReady(this, new MenuReady { }); } + + public override IEntitiesDB entitiesDB { get; set; } + public override IEntityFactory entityFactory { get; set; } } } \ No newline at end of file diff --git a/CLre/API/App/ClientEventArgs.cs b/CLre/API/App/ClientEventArgs.cs index c6bd59c..6dc25b9 100644 --- a/CLre/API/App/ClientEventArgs.cs +++ b/CLre/API/App/ClientEventArgs.cs @@ -1,5 +1,3 @@ -using User; - namespace CLre.API.App { @@ -10,10 +8,4 @@ namespace CLre.API.App public struct GameExit{} public struct MenuReady{} - - public struct GameJoin - { - public bool Success; - public SerializedAccountInfo Data; - } } \ No newline at end of file diff --git a/CLre/API/Characters/Character.cs b/CLre/API/Characters/Character.cs index 02e83e1..a16c05b 100644 --- a/CLre/API/Characters/Character.cs +++ b/CLre/API/Characters/Character.cs @@ -54,6 +54,9 @@ namespace CLre.API.Characters { } + public override IEntitiesDB entitiesDB { get; set; } + public override IEntityFactory entityFactory { get; set; } + public bool GetGodModeRequested() { if (entitiesDB == null) return false; diff --git a/CLre/API/Engines/FrontEndEngines.cs b/CLre/API/Engines/FrontEndEngines.cs index cd68bd1..62b8cf7 100644 --- a/CLre/API/Engines/FrontEndEngines.cs +++ b/CLre/API/Engines/FrontEndEngines.cs @@ -21,8 +21,8 @@ namespace CLre.API.Engines } public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } + public abstract IEntitiesDB entitiesDB { get; set; } + public abstract IEntityFactory entityFactory { get; set; } } /// @@ -41,8 +41,8 @@ namespace CLre.API.Engines } public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } + public abstract IEntitiesDB entitiesDB { get; set; } + public abstract IEntityFactory entityFactory { get; set; } } /// @@ -60,8 +60,8 @@ namespace CLre.API.Engines } public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } + public abstract IEntitiesDB entitiesDB { get; set; } + public abstract IEntityFactory entityFactory { get; set; } } /// @@ -79,16 +79,16 @@ namespace CLre.API.Engines } public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } + public abstract IEntitiesDB entitiesDB { get; set; } + public abstract IEntityFactory entityFactory { get; set; } } [HarmonyPatch(typeof(FrontEnd.MainFrontEnd), "BuildEngines")] class MainFrontEnd_BuildEngines_Patch { - internal static FasterList beforeBuildEngines = new FasterList(); + internal static FasterList beforeBuildEngines = new FasterList(); - internal static FasterList afterBuildEngines = new FasterList(); + internal static FasterList afterBuildEngines = new FasterList(); internal static MethodInfo addEngine = AccessTools.Method(typeof(FrontEnd.MainFrontEnd), "AddEngine"); diff --git a/CLre/API/Engines/GameEngines.cs b/CLre/API/Engines/GameEngines.cs index 7a5a6a3..0c776ee 100644 --- a/CLre/API/Engines/GameEngines.cs +++ b/CLre/API/Engines/GameEngines.cs @@ -12,8 +12,8 @@ namespace CLre.API.Engines } public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } + public abstract IEntitiesDB entitiesDB { get; set; } + public abstract IEntityFactory entityFactory { get; set; } } public abstract class GameObsoleteEnginePostBuild : ICLreEngine @@ -24,16 +24,16 @@ namespace CLre.API.Engines } public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } + public abstract IEntitiesDB entitiesDB { get; set; } + public abstract IEntityFactory entityFactory { get; set; } } [HarmonyPatch(typeof(GameFramework.MainLevel), "BuildDeprecatedEngines")] class MainLevel_BuildDeprecatedEngines_Patch { - internal static FasterList beforeBuildEngines = new FasterList(); + internal static FasterList beforeBuildEngines = new FasterList(); - internal static FasterList afterBuildEngines = new FasterList(); + internal static FasterList afterBuildEngines = new FasterList(); [HarmonyPrefix] public static void BeforeMethodCall(GameFramework.MainLevel __instance) diff --git a/CLre/API/Synergy/ClientHandshakeEngine.cs b/CLre/API/Synergy/ClientHandshakeEngine.cs deleted file mode 100644 index 545afa2..0000000 --- a/CLre/API/Synergy/ClientHandshakeEngine.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections; -using CLre.API.Engines; -using GameNetworkLayer.Shared; -using HarmonyLib; -using Svelto.ECS; -using VoxelFarm.GameServer; - -namespace CLre.API.Synergy -{ - public class ClientHandshakeEngine : GameObsoleteEnginePreBuild - { - internal static ClientHandshakeEngine Instance = null; - - internal const NetworkDispatcherCode CLre_HANDSHAKE_NETCODE = (NetworkDispatcherCode) 218; - - private Utility.Reflection.INetMsgClientSender_SendMessage _sendMessage; - - private Utility.Reflection.INetMsgClientListener_RegisterListener _registerListener; - - public override void Ready() - { - //Utility.Logging.MetaLog("Building send message delegate"); - _sendMessage = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Client.NetMessageClientSender:SendMessage", - generics: new [] {typeof(SerializedCLreHandshake)}, - instance: MainLevel_BuildClasses_Patch.netMessageSender); - - //Utility.Logging.MetaLog("Building register listener delegate"); - _registerListener = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Client.NetMessageClientListener:RegisterListener", - generics: new [] {typeof(SerializedCLreHandshake)}, - instance: MainLevel_BuildClasses_Patch.netMessageListener); - _registerListener(CLre_HANDSHAKE_NETCODE, OnHandshakeReceived); - } - - public void OnHandshakeReceived(ref SerializedCLreHandshake p) - { - // TODO validate handshake msg - Utility.Logging.MetaLog($"Received CLre handshake! {p}"); - } - - public IEnumerator Sender(SerializedCLreHandshake payload) - { - yield return null; - Utility.Logging.MetaLog("Sending Client CLre handshake"); - _sendMessage(CLre_HANDSHAKE_NETCODE, ref payload); - yield return null; - } - - internal static void Init() - { - Instance = new ClientHandshakeEngine(); - } - - public ClientHandshakeEngine(): base() - { - App.Client.GameJoin += (_, __) => - { - SerializedCLreHandshake payload = SerializedCLreHandshake.Current(); - Sender(payload).Run(); - }; - } - } - - [HarmonyPatch(typeof(GameFramework.MainLevel), "BuildClasses")] - class MainLevel_BuildClasses_Patch - { - internal static object netMessageListener; - - internal static object netMessageSender; - - internal static TerrainModelClientServer tmcs; - - [HarmonyPostfix] - public static void AfterMethodCall(object ____netMessageListener, object ____netMessageSender, TerrainModelClientServer ____terrainModelServerPrediction) - { - netMessageListener = ____netMessageListener; - netMessageSender = ____netMessageSender; - tmcs = ____terrainModelServerPrediction; - } - } -} \ No newline at end of file diff --git a/CLre/API/Synergy/ClientMessagingEngine.cs b/CLre/API/Synergy/ClientMessagingEngine.cs deleted file mode 100644 index 1bbb632..0000000 --- a/CLre/API/Synergy/ClientMessagingEngine.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using GameNetworkLayer.Shared; -using Svelto.Context; -using Svelto.ECS; - -namespace CLre.API.Synergy -{ - class ClientMessagingEngine: Engines.GameObsoleteEnginePostBuild, IWaitForFrameworkDestruction, IWaitForFrameworkInitialization - { - private struct MessageQueueItem - { - public SerializedCLreMessage msg; - public NetworkDispatcherCode code; - } - - private Utility.Reflection.INetMsgClientSender_SendMessage _sendMessage; - - private Utility.Reflection.INetMsgClientListener_RegisterListener _registerListener; - - private Queue _messageQueue = new Queue(10); - - private bool _isRunning = false; - - public override void Ready() - { - //Utility.Logging.MetaLog("Building send message delegate"); - _sendMessage = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Client.NetMessageClientSender:SendMessage", - generics: new [] {typeof(SerializedCLreMessage)}, - instance: MainLevel_BuildClasses_Patch.netMessageSender); - - //Utility.Logging.MetaLog("Building register listener delegate"); - _registerListener = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Client.NetMessageClientListener:RegisterListener", - generics: new [] {typeof(SerializedCLreMessage)}, - instance: MainLevel_BuildClasses_Patch.netMessageListener); - _registerListener(Message.CLre_MESSAGE_NETCODE, OnMessageReceived); - } - - private void OnMessageReceived(ref SerializedCLreMessage data) - { - Message.HandleMessageReceive(ref data); - } - - internal void EnqueueMessage(ref SerializedCLreMessage msg) - { - _messageQueue.Enqueue(new MessageQueueItem - { - msg = msg, - code = Message.CLre_MESSAGE_NETCODE, - }); - } - - public ClientMessagingEngine(): base() - { - App.Client.GameJoin += (_, __) => { MessageSender().Run(); }; - } - - public IEnumerator MessageSender() - { - while (!_isRunning) - { - yield return null; - } - while (_isRunning) - { - while (_messageQueue.Count != 0) - { - MessageQueueItem item = _messageQueue.Dequeue(); - API.Utility.Logging.MetaLog($"Sending message with id {item.msg.Id}"); - _sendMessage(item.code, ref item.msg); - } - - yield return null; - } - } - - public void OnFrameworkDestroyed() - { - _isRunning = false; - } - - public void OnFrameworkInitialized() - { - _isRunning = true; - } - } -} \ No newline at end of file diff --git a/CLre/API/Synergy/Message.cs b/CLre/API/Synergy/Message.cs deleted file mode 100644 index 75b623a..0000000 --- a/CLre/API/Synergy/Message.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using GameNetworkLayer.Shared; - -namespace CLre.API.Synergy -{ - public static class Message - { - internal const NetworkDispatcherCode CLre_MESSAGE_NETCODE = (NetworkDispatcherCode) 219; - - private static readonly Dictionary> handlers = - new Dictionary>(); - - private static readonly ClientMessagingEngine msgEngine = new ClientMessagingEngine(); - - public static void SendCLreMessage(ref SerializedCLreMessage message) - { - msgEngine.EnqueueMessage(ref message); - } - - public static void RegisterListener(uint id, Action handler) - { - if (handlers.TryGetValue(id, out Action existing)) - { - existing += handler; - handlers[id] = existing; - } - else - { - handlers[id] = handler; - } - } - - internal static void HandleMessageReceive(ref SerializedCLreMessage msg) - { - ReceiveMessageArgs payload = new ReceiveMessageArgs - { - Message = msg, - }; - if (handlers.TryGetValue(msg.Id, out Action h)) - { - h(payload); - } - } - } - - public struct ReceiveMessageArgs - { - public SerializedCLreMessage Message; - } -} \ No newline at end of file diff --git a/CLre/API/Synergy/SerializedCLreHandshake.cs b/CLre/API/Synergy/SerializedCLreHandshake.cs deleted file mode 100644 index 845effb..0000000 --- a/CLre/API/Synergy/SerializedCLreHandshake.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using NetworkFramework.Shared; - -namespace CLre.API.Synergy -{ - public struct SerializedCLreHandshake: ISerializedNetData - { - private byte major; - private byte minor; - private byte patch; - - private HandshakeFlag flags; - - private List modInfo; - - public Version Version - { - get => new Version(major, minor, patch); - set - { - major = (byte)value.Major; - minor = (byte)value.Minor; - patch = (byte)value.Build; - } - } - - public IEnumerable Mods - { - get => modInfo.ToArray(); - set - { - modInfo.Clear(); - foreach (var mod in value) - { - modInfo.Add(mod); - } - } - } - - public byte[] Serialize() - { - using (MemoryStream stream = new MemoryStream()) - { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - // version - writer.Write(major); - writer.Write(minor); - writer.Write(patch); - writer.Write((uint)flags); - writer.Write(modInfo.Count); - foreach (string mod in modInfo) - { - writer.Write(mod); - } - return stream.ToArray(); - } - } - } - - public void Deserialize(byte[] data) - { - using (MemoryStream stream = new MemoryStream(data)) - { - using (BinaryReader reader = new BinaryReader(stream)) - { - // version - major = reader.ReadByte(); - minor = reader.ReadByte(); - patch = reader.ReadByte(); - flags = (HandshakeFlag) reader.ReadUInt32(); - int modCount = reader.ReadInt32(); - modInfo = new List(modCount); - for (int i = 0; i < modCount; i++) - { - modInfo.Add(reader.ReadString()); - } - } - } - } - - public bool HasFlag(HandshakeFlag f) - { - return (flags & f) != HandshakeFlag.None; - } - - public void SetFlag(HandshakeFlag f) - { - flags |= f; - } - - public void UnsetFlag(HandshakeFlag f) - { - flags &= ~f; - } - - public static SerializedCLreHandshake Current() - { - Version v = Assembly.GetExecutingAssembly().GetName().Version; - List mods = new List(); - foreach (var plugin in IllusionInjector.PluginManager.Plugins) - { - mods.Add(plugin.Name); - } - - return new SerializedCLreHandshake - { - major = (byte) v.Major, - minor = (byte) v.Minor, - patch = (byte) v.Build, - flags = HandshakeFlag.Client, - modInfo = mods, - }; - } - - public static SerializedCLreHandshake RequireCLre() - { - Version v = Assembly.GetExecutingAssembly().GetName().Version; - List mods = new List(new []{Assembly.GetExecutingAssembly().GetName().Name}); - - return new SerializedCLreHandshake - { - major = (byte) v.Major, - minor = (byte) v.Minor, - patch = (byte) v.Build, - flags = HandshakeFlag.Client | HandshakeFlag.RequireAll, - modInfo = mods, - }; - } - - public static SerializedCLreHandshake Empty() - { - return new SerializedCLreHandshake - { - major = 0, - minor = 0, - patch = 0, - modInfo = new List(), - }; - } - - public override string ToString() - { - return $"CLre {Version} ({modInfo.Count} mods)"; - } - } - - [Flags] - public enum HandshakeFlag : uint - { - None = 0, - Client = 1, - Server = 1 << 1, - RequireAll = 1 << 2, - OptionalAll = 1 << 3, - Confirm = 1 << 4, - } -} \ No newline at end of file diff --git a/CLre/API/Synergy/SerializedCLreMessage.cs b/CLre/API/Synergy/SerializedCLreMessage.cs deleted file mode 100644 index 95de808..0000000 --- a/CLre/API/Synergy/SerializedCLreMessage.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.IO; -using NetworkFramework.Shared; - -namespace CLre.API.Synergy -{ - public struct SerializedCLreMessage: ISerializedNetData - { - public uint Id; - public byte[] Data; - - public byte[] Serialize() - { - using (MemoryStream stream = new MemoryStream()) - { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(Id); - writer.Write(Data.Length); - foreach (byte b in Data) - { - writer.Write(b); - } - return stream.ToArray(); - } - } - } - - public void Deserialize(byte[] data) - { - using (MemoryStream stream = new MemoryStream(data)) - { - using (BinaryReader reader = new BinaryReader(stream)) - { - Id = reader.ReadUInt32(); - Data = new byte[reader.ReadInt32()]; - for (int i = 0; i < Data.Length; i++) - { - Data[i] = reader.ReadByte(); - } - } - } - } - } -} \ No newline at end of file diff --git a/CLre/API/Synergy/Tweaks/SerializedCLreTerrainModifyRejection.cs b/CLre/API/Synergy/Tweaks/SerializedCLreTerrainModifyRejection.cs deleted file mode 100644 index 20c127d..0000000 --- a/CLre/API/Synergy/Tweaks/SerializedCLreTerrainModifyRejection.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.IO; -using System.Runtime.CompilerServices; -using Game.Handhelds; -using NetworkFramework.Shared; -using UnityEngine; - -namespace CLre.API.Synergy.Tweaks -{ - public struct SerializedCLreTerrainModifyRejection: ISerializedNetData - { - public RejectionFlag Flags; - - public uint resourceId; - - public Vector3 hit; - - public string toolKey; - - public ToolModeType toolMode; - - public byte[] Serialize() - { - using (MemoryStream stream = new MemoryStream()) - { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write((byte)Flags); - writer.Write(resourceId); - writer.Write(hit.x); - writer.Write(hit.y); - writer.Write(hit.z); - writer.Write(toolKey); - writer.Write((byte)toolMode); - return stream.ToArray(); - } - } - } - - public void Deserialize(byte[] data) - { - using (MemoryStream stream = new MemoryStream(data)) - { - using (BinaryReader reader = new BinaryReader(stream)) - { - Flags = (RejectionFlag)reader.ReadByte(); - resourceId = reader.ReadUInt32(); - float x = reader.ReadSingle(); - float y = reader.ReadSingle(); - float z = reader.ReadSingle(); - hit = new Vector3(x, y, z); - toolKey = reader.ReadString(); - toolMode = (ToolModeType)reader.ReadByte(); - } - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Ok() - { - return (Flags & RejectionFlag.Rejection) == RejectionFlag.None; - } - } - - [Flags] - public enum RejectionFlag : byte - { - None = 0, - Rejection = 1, - Proximity = 1 << 1, - Permission = 1 << 2, - AccountNotFound = 1 << 3, - InitError = 1 << 4, - } -} diff --git a/CLre/API/Tools/AccessToolsWarnings.cs b/CLre/API/Tools/AccessToolsWarnings.cs deleted file mode 100644 index b57e002..0000000 --- a/CLre/API/Tools/AccessToolsWarnings.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Diagnostics; -using System.Reflection; -using HarmonyLib; - -#if DEBUG -namespace CLre.API.Tools -{ - public static class AccessToolsWarnings - { - internal static bool isEnabled = false; - - public static void Enable() - { - isEnabled = true; - } - - public static void Disable() - { - isEnabled = false; - } - } - - [HarmonyPatch(typeof(AccessTools), "TypeByName")] - class AccessTools_TypeByName_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(Type __result, string name) - { - if (!AccessToolsWarnings.isEnabled) return; - if (__result == null) - { - var method = (new StackTrace()).GetFrame(2).GetMethod(); - Utility.Logging.LogWarning($"[{method.DeclaringType.FullName}.{method.Name}] AccessTools.TypeByName(\"{name}\") returned null result"); - } - } - } - - [HarmonyPatch(typeof(AccessTools), "Method", - new Type[] {typeof(string), typeof(Type[]), typeof(Type[])})] - class AccessTools_Method_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(MethodInfo __result, string typeColonMethodname) - { - if (!AccessToolsWarnings.isEnabled) return; - if (__result == null) - { - var method = (new StackTrace()).GetFrame(2).GetMethod(); - Utility.Logging.LogWarning($"[{method.DeclaringType.FullName}.{method.Name}] AccessTools.Method(\"{typeColonMethodname}\") returned null result"); - } - } - } -} -#endif \ No newline at end of file diff --git a/CLre/API/Tools/NetClientListener.cs b/CLre/API/Tools/NetClientListener.cs deleted file mode 100644 index a326fe2..0000000 --- a/CLre/API/Tools/NetClientListener.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Reflection; -using System.Text; -using GameNetworkLayer.Shared; -using HarmonyLib; -using Svelto.DataStructures; -using Svelto.DataStructures.Experimental; - -namespace CLre.API.Tools -{ - public class NetClientListener - { - internal static bool isEnabled = false; - - private static FasterDictionary> callbacks = new FasterDictionary>(); - - public delegate void NetReceiveMessageCallback(NetworkDispatcherCode code, byte[] data, int playerId); - - public static void Enable() - { - isEnabled = true; - } - - public static void Disable() - { - isEnabled = false; - } - - public static void DebugReceiveMessage(NetworkDispatcherCode code, NetReceiveMessageCallback callback) - { - short key = (short)code; - if (callbacks.TryGetValue(key, out FasterList handlers)) - { - handlers.Add(callback); - } - else - { - FasterList newHandlers = new FasterList(new [] {callback}); - callbacks.Add(key, newHandlers); - } - } - - internal static bool RunDebugCallbacks(NetworkDispatcherCode code, byte[] data, int playerId) - { - short key = (short)code; - if (callbacks.TryGetValue(key, out FasterList handlers)) - { - foreach (NetReceiveMessageCallback callback in handlers) - { - callback(code, data, playerId); - } - - return true; - } - else - { - return false; - } - } - - public static void Log(NetworkDispatcherCode code, byte[] data, int playerId) - { - StringBuilder sb = new StringBuilder("Received "); - sb.Append(code.ToString()); - sb.Append(" for player #"); - sb.Append(playerId); - sb.Append(": 0x"); - foreach (byte b in data) - { - sb.Append(b.ToString("X")); - } - Utility.Logging.Log(sb.ToString()); - } - } - - [HarmonyPatch] - class NetMessageClientListener_HandleAllMessages_Patch - { - [HarmonyPrefix] - public static void BeforeMethodCall(object ____deserializer, int playerId, object value) - { - if (!NetClientListener.isEnabled) return; - // TODO optimize this to not use Traverse - Traverse result = Traverse.Create(____deserializer).Method("Deserialize", value); - NetworkDispatcherCode code = result.Field("dispatcherCode").Value; - byte[] data = result.Field("bytes").Value; - if (data == null) - { - Utility.Logging.LogWarning("Network message data was deserialized as null"); - return; - } - bool isHandled = NetClientListener.RunDebugCallbacks(code, data, playerId); - if (!isHandled) Utility.Logging.Log($"Received network message for player {playerId} (code: {code.ToString()}, len: {data.Length})"); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameNetworkLayer.Client.NetMessageClientListener:HandleAllMessages"); - } - } -} \ No newline at end of file diff --git a/CLre/API/Tools/NetClientSender.cs b/CLre/API/Tools/NetClientSender.cs deleted file mode 100644 index bf54398..0000000 --- a/CLre/API/Tools/NetClientSender.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Reflection; -using System.Text; -using GameNetworkLayer.Shared; -using HarmonyLib; -using NetworkFramework.Shared; - -namespace CLre.API.Tools -{ - public class NetClientSender - { - private struct DummyNetDataStruct : ISerializedNetData - { - public byte[] Serialize() - { - return new byte[0]; - } - - public void Deserialize(byte[] data) - { - } - } - - private static readonly MethodInfo _genericSendMessage = AccessTools.Method("GameNetworkLayer.Client.NetMessageClientSender:SendMessage"); - - private static readonly MethodInfo _genericGetSendMessageMethod = - AccessTools.Method(typeof(NetClientSender), "GetSendMessageMethod",parameters: new Type[0]);/* - /*((Func) GetSendMessageMethod).Method - .GetBaseDefinition() - .GetGenericMethodDefinition();*/ - - private static readonly MethodInfo _genericLog = - AccessTools.Method(typeof(NetClientSender), "Log");/* - ((Action) Log).Method - .GetBaseDefinition() - .GetGenericMethodDefinition();*/ - - private static readonly MethodInfo _genericGetLogMethod = - AccessTools.Method(typeof(NetClientSender), "GetLogMethod", new Type[0]);/* - ((Func) GetLogMethod).Method - .GetBaseDefinition() - .GetGenericMethodDefinition();*/ - - public static MethodInfo GetSendMessageMethod(Type t) - { - return (MethodInfo) _genericGetSendMessageMethod.MakeGenericMethod(t) - .Invoke(null, new object[0]); - } - - public static MethodInfo GetSendMessageMethod() where T : struct, ISerializedNetData - { - return _genericSendMessage.MakeGenericMethod(typeof(T)); - } - - public static MethodInfo DebugSendMessage(Harmony instance = null, MethodInfo before = null, MethodInfo after = null, MethodInfo transpiler = null, MethodInfo finalizer = null) where T : struct, ISerializedNetData - { - return DebugSendMessage(typeof(T), instance, before, after, transpiler, finalizer); - } - - public static MethodInfo DebugSendMessage(Type generic, Harmony instance = null, MethodInfo before = null, MethodInfo after = null, MethodInfo transpiler = null, MethodInfo finalizer = null) - { - return DebugSendMessage( - generic, instance, - before == null ? null : new HarmonyMethod(before), - after == null ? null : new HarmonyMethod(after), - transpiler == null ? null : new HarmonyMethod(transpiler), - finalizer == null ? null : new HarmonyMethod(finalizer)); - } - - public static MethodInfo DebugSendMessage(Harmony instance = null, HarmonyMethod before = null, HarmonyMethod after = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null) where T : struct, ISerializedNetData - { - return DebugSendMessage(typeof(T), instance, before, after, transpiler, finalizer); - } - - public static MethodInfo DebugSendMessage(Type generic, Harmony instance = null, HarmonyMethod before = null, HarmonyMethod after = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null) - { - if (instance == null) instance = CLre.harmonyInstance; - MethodInfo target = GetSendMessageMethod(generic); - return instance.Patch(target, - before, - after, - transpiler, - finalizer); - } - - public static MethodInfo GetLogMethod(Type t) - { - return (MethodInfo) _genericGetLogMethod.MakeGenericMethod(t) - .Invoke(null, new object[0]); - } - - public static MethodInfo GetLogMethod() where T : struct, ISerializedNetData - { - return _genericLog.MakeGenericMethod(typeof(T)); - } - - private static void Log(NetworkDispatcherCode code, ref T data) where T : struct, ISerializedNetData - { - //Utility.Logging.Log($"Sending ISerializedNetData {data.GetType().FullName} (code: {code.ToString()})"); - Traverse d = Traverse.Create(data); - string codeName = (short) code > 217 ? "CUSTOM" : code.ToString(); - StringBuilder sb = new StringBuilder($"Sending ISerializedNetData {data.GetType().FullName} (code: {codeName} {(short)code})"); - foreach (string fieldName in d.Fields()) - { - Traverse field = d.Field(fieldName); - sb.Append("\n"); - sb.Append("\""); - int start = fieldName.IndexOf('<'); - int len = fieldName.LastIndexOf('>'); - if (start != -1 && len > 0) - { - sb.Append(fieldName.Substring(start+1, len-1)); - } - else - { - sb.Append(fieldName); - } - sb.Append("\": "); - sb.Append(field.GetValue()); - } - Utility.Logging.Log(sb.ToString()); - } - } -} \ No newline at end of file diff --git a/CLre/API/Utility/Reflection.cs b/CLre/API/Utility/Reflection.cs index 7ebf278..edcc6af 100644 --- a/CLre/API/Utility/Reflection.cs +++ b/CLre/API/Utility/Reflection.cs @@ -1,12 +1,6 @@ using System; -using System.Collections.Generic; using System.Reflection; -using Game.DataLoader; -using GameNetworkLayer.Client; -using GameNetworkLayer.Shared; using HarmonyLib; -using NetworkFramework.Shared; -using OpenCVForUnity; using Svelto.DataStructures; using Svelto.ECS; @@ -31,16 +25,6 @@ namespace CLre.API.Utility public delegate T[] QueryEntitiesV1(ExclusiveGroup.ExclusiveGroupStruct group, out int count) where T : IEntityStruct; - public delegate object[] SendMessage(NetworkDispatcherCode dispatcherCode, ref T value) where T : struct, ISerializedNetData; - - public delegate void INetMsgClientSender_SendMessage(NetworkDispatcherCode code, ref T value) where T : struct, ISerializedNetData; - - public delegate void INetMsgClientListener_RegisterListener(NetworkDispatcherCode code, NetCBClient proc) where T: struct, ISerializedNetData; - - public delegate void DeprecatedDispatcher_Dispatch(ref T value); - - public delegate Dictionary IDataDB_GetValues(); - // useful reflection functions public static TFuncProto BuildDelegate(MethodInfo method) where TFuncProto : Delegate { diff --git a/CLre/CLre.cs b/CLre/CLre.cs index 2df63d9..86e80e3 100644 --- a/CLre/CLre.cs +++ b/CLre/CLre.cs @@ -1,13 +1,9 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using CLre.API.Characters; -using CLre.API.Synergy; -using CLre.API.Tools; -using GameNetworkLayer.Shared; using HarmonyLib; using Svelto.ECS; using UnityEngine; @@ -18,14 +14,9 @@ namespace CLre { public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; - public override string Version { get; } = "21Q3 " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); - - internal static Harmony harmonyInstance = null; - - internal static bool _isInidicatorActive = true; - - internal static string _indicatorMsg = " CLre loading..."; + public override string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + private Harmony harmonyInstance = null; // called when Cardlife shuts down public override void OnApplicationQuit() { @@ -38,9 +29,6 @@ namespace CLre #if DEBUG FileLog.Reset(); Harmony.DEBUG = true; - // enable CLre debug functionality - AccessToolsWarnings.Enable(); - NetClientListener.Enable(); Stopwatch startup = Stopwatch.StartNew(); #endif // init all Harmony patches in project @@ -49,56 +37,19 @@ namespace CLre // patches for bugs Fixes.InitLogSooner.Init(); - Fixes.MiniScreenHelper.Init(); - Fixes.UnderStructureCollider.Init(); - Fixes.TerrainModifyReset.Init(); - //Fixes.FloatLanguageFix.Init(); - - // API init - API.Synergy.ClientHandshakeEngine.Init(); // misc LogIPAPlugins(); Fixes.BugfixAttributeUtility.LogBugfixes(); - BuildIndicatorMessage(); - API.App.Client.MenuReady += (_, __) => { _isInidicatorActive = false; }; // dismiss CLre msg // Log info API.Utility.Logging.MetaLog($"{Name} init complete."); #if DEBUG - // configure CLre debug functionality - Type netData = AccessTools.TypeByName("Game.Handhelds.DrawingStateMessage"); - NetClientSender.DebugSendMessage(netData, harmonyInstance, - NetClientSender.GetLogMethod(netData)); - API.Utility.Logging.MetaLog("Patched SendMessage"); - - netData = AccessTools.TypeByName("Shared.Inventory.HandheldEquipmentRequest"); - NetClientSender.DebugSendMessage(netData, harmonyInstance, - NetClientSender.GetLogMethod(netData)); - API.Utility.Logging.MetaLog("Patched SendMessage"); - - netData = typeof(API.Synergy.SerializedCLreHandshake); - NetClientSender.DebugSendMessage(netData, harmonyInstance, - NetClientSender.GetLogMethod(netData)); - API.Utility.Logging.MetaLog("Patched SendMessage"); - - NetClientListener.DebugReceiveMessage(NetworkDispatcherCode.EACMessageServerToClient, - NetClientListener.Log); - - NetClientListener.DebugReceiveMessage(API.Synergy.ClientHandshakeEngine.CLre_HANDSHAKE_NETCODE, - NetClientListener.Log); - - NetClientListener.DebugReceiveMessage(NetworkDispatcherCode.SendIsPvEToClient, - NetClientListener.Log); - - API.Utility.Logging.MetaLog($"Highest NetworkDispatcherCode number is {(int) NetworkDispatcherCode.StructureDestroyed} damn it Photon"); - - // API debug and testing API.App.Client.InitComplete += (_, __) => { startup.Stop(); - API.Utility.Logging.Log($"Startup took {startup.ElapsedMilliseconds}ms"); + API.Utility.Logging.MetaLog($"Startup took {startup.ElapsedMilliseconds}ms"); API.Utility.Logging.Log( $"EAC has detected code mods? {EasyAntiCheat.Client.Hydra.Runtime.Integrity.Violated}" + (EasyAntiCheat.Client.Hydra.Runtime.Integrity.Violated @@ -108,11 +59,7 @@ namespace CLre API.App.Client.MenuReady += (_, __) => { API.Utility.Logging.MetaLog("Menu engine ready event fired!"); }; API.App.Client.GameReady += (_, __) => { API.Utility.Logging.MetaLog("Game engine ready event fired!"); }; - API.App.Client.GameFrameworkReady += (_, __) => - { - API.Utility.Logging.MetaLog("Game framework ready event fired!"); - API.Utility.Logging.MetaLog($"PhotonChat Connection Protocol: {PhotonChatUI.Chat.Instance.ConnectionProtocol}"); - }; + API.App.Client.GameFrameworkReady += (_, __) => { API.Utility.Logging.MetaLog("Game framework ready event fired!"); }; API.App.Client.GameFrameworkExit += (_, __) => { API.Utility.Logging.MetaLog("Game framework exit event fired!"); }; Character c = Character.Local(); @@ -136,36 +83,12 @@ namespace CLre sb.AppendFormat("-----------------------------\n"); API.Utility.Logging.Log(sb.ToString()); } - - private void BuildIndicatorMessage() - { - int fixCount = Fixes.BugfixAttributeUtility.Count; - int modCount = IllusionInjector.PluginManager.Plugins.Count(); - StringBuilder sb = new StringBuilder(); - sb.AppendFormat(" {0} {1}\n", Name, Version); - sb.AppendFormat(" {0} bugfixes, {1} plugins, no frills\n", fixCount, modCount); -#if DEBUG - sb.AppendFormat(" DEBUG version\n"); -#endif -#if RELEASE - sb.AppendFormat(" RELEASE version\n"); -#endif - sb.AppendFormat(" Starting up...\n"); - _indicatorMsg = sb.ToString(); - } public override void OnGUI() { - // CLre startup inidicator - if (_isInidicatorActive) + if (GUI.Button(new Rect(10, 10, 50, 50), "TEST")) { - GUILayout.BeginVertical(); - GUILayout.Label(_indicatorMsg); - if (GUILayout.Button("Hide")) - { - _isInidicatorActive = false; - } - GUILayout.EndVertical(); + } } } diff --git a/CLre/CLre.csproj b/CLre/CLre.csproj index 314259a..68c98a3 100644 --- a/CLre/CLre.csproj +++ b/CLre/CLre.csproj @@ -3,7 +3,7 @@ net472 true - 0.0.3 + 0.0.2 NGnius MIT https://git.exmods.org/NGnius/CLre @@ -11,7 +11,7 @@ - + @@ -281,6 +281,9 @@ ..\..\cl\Cardlife_Data\Managed\IllusionPlugin.dll + + + diff --git a/CLre/Fixes/BugfixAttribute.cs b/CLre/Fixes/BugfixAttribute.cs index fc2d1da..f406374 100644 --- a/CLre/Fixes/BugfixAttribute.cs +++ b/CLre/Fixes/BugfixAttribute.cs @@ -29,33 +29,9 @@ namespace CLre.Fixes internal static class BugfixAttributeUtility { - public static int Count { get; private set; } - public static void LogBugfixes() { - API.Utility.Logging.Log(BugfixMessage()); - } - - public static string BugfixMessage() - { - Dictionary fixes = Bugfixes(); - List keys = new List(fixes.Keys); - keys.Sort(); - //keys.Sort((u, u1) => u.CompareTo(u1)); - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("Applying {0} CLre fixes\n", keys.Count); - sb.AppendFormat("-----------------------------\n"); - foreach (uint i in keys) - { - sb.Append(fixes[i].ToString()); - sb.Append("\n"); - } - sb.AppendFormat("-----------------------------\n"); - return sb.ToString(); - } - - public static Dictionary Bugfixes() - { + List keys = new List(); Dictionary fixes = new Dictionary(); foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) { @@ -67,6 +43,7 @@ namespace CLre.Fixes BugfixStruct bugfixStruct = new BugfixStruct{id = b.id}; bugfixStruct.Merge(b); fixes[b.id] = bugfixStruct; + keys.Add(b.id); } else { @@ -76,12 +53,21 @@ namespace CLre.Fixes } } } - - Count = fixes.Count; - return fixes; + keys.Sort(); + //keys.Sort((u, u1) => u.CompareTo(u1)); + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Applying {0} CLre fixes\n", keys.Count); + sb.AppendFormat("-----------------------------\n"); + foreach (uint i in keys) + { + sb.Append(fixes[i].ToString()); + sb.Append("\n"); + } + sb.AppendFormat("-----------------------------\n"); + API.Utility.Logging.Log(sb.ToString()); } - public struct BugfixStruct + private struct BugfixStruct { public string name; public string description; diff --git a/CLre/Fixes/CooldownCrossSlotSync.cs b/CLre/Fixes/CooldownCrossSlotSync.cs index a25c08a..5e5235f 100644 --- a/CLre/Fixes/CooldownCrossSlotSync.cs +++ b/CLre/Fixes/CooldownCrossSlotSync.cs @@ -78,11 +78,15 @@ namespace CLre.Fixes return; } - //object wcevOriginal = queryWCEV(toolId, baseGroup); + object wcevOriginal = queryWCEV(toolId, baseGroup); + float cooldownLeft = + Traverse.Create(wcevOriginal).Field("weaponCooldownComponent").Property("cooldownLeft").Value; + bool isInCooldown = + Traverse.Create(wcevOriginal).Field("weaponCooldownComponent").Property("isInCooldown").Value; //API.Utility.Logging.MetaLog($"Cooling down? {isInCooldown} for {cooldownLeft}s"); // build functions for querying all Game.Handhelds.WeaponCooldownEntityView objects Type protoRaw = - typeof(Reflection.QueryEntityViews<>) + typeof(Reflection.QueryEntityViews).GetGenericTypeDefinition() .MakeGenericType( AccessTools.TypeByName("Game.Handhelds.WeaponCooldownEntityView")); Delegate queryAllWCEV = @@ -96,14 +100,30 @@ namespace CLre.Fixes object collectionStruct = queryAllWCEV.DynamicInvoke((int) baseGroup); int count = Traverse.Create(collectionStruct).Field("_count").Value; - PropertyInfo indexer = typeof(Svelto.DataStructures.ReadOnlyCollectionStruct<>) + PropertyInfo indexer = typeof(Svelto.DataStructures.ReadOnlyCollectionStruct).GetGenericTypeDefinition() .MakeGenericType(AccessTools.TypeByName("Game.Handhelds.WeaponCooldownEntityView")) .GetIndexer(); - + object[] indexParams = {0}; + for (int index = 0; index < count; index++) + { +#if DEBUG + API.Utility.Logging.MetaLog("Syncing cooldown with another weapon"); +#endif + indexParams[0] = index; + object wcev = indexer.GetValue(collectionStruct, indexParams); + Traverse.Create(wcev) + .Field("weaponCooldownComponent") + .Property("cooldownLeft") + .Value = cooldownLeft; + + Traverse.Create(wcev) + .Field("weaponCooldownComponent") + .Property("isInCooldown").Value = isInCooldown; + } + if (!isRunningTick) { - isRunningTick = true; - cooldownTickEverything(characterId, cwcevExists, queryCWCEV, queryWCEV, queryAllWCEV, indexer, baseGroup).Run(); + cooldownTickEverything(characterId, entitiesDB, cwcevExists, queryCWCEV, queryWCEV, queryAllWCEV, indexer, baseGroup).Run(); } } @@ -114,10 +134,14 @@ namespace CLre.Fixes new[] {typeof(int), typeof(bool)}); } - private static IEnumerator cooldownTickEverything(int characterId, Reflection.ExistsV2 cwcevExists, Reflection.QueryEntityViewV2 cwcevQuery, Reflection.QueryEntityViewV2 wcevQuery, Delegate wcevQueryAll, PropertyInfo indexer, ExclusiveGroup baseGroup) + private static IEnumerator cooldownTickEverything(int characterId, IEntitiesDB entitiesDb, Reflection.ExistsV2 cwcevExists, Reflection.QueryEntityViewV2 cwcevQuery, Reflection.QueryEntityViewV2 wcevQuery, Delegate wcevQueryAll, PropertyInfo indexer, ExclusiveGroup baseGroup) { + isRunningTick = true; while (cwcevExists(characterId, (int) DEPRECATED_SveltoExtensions.DEPRECATED_GROUP)) { +#if DEBUG + API.Utility.Logging.MetaLog("Doing cooldown tick for all weapons"); +#endif // get equipped handheld info object cwcevOriginal = cwcevQuery(characterId, (ExclusiveGroup.ExclusiveGroupStruct) DEPRECATED_SveltoExtensions.DEPRECATED_GROUP); @@ -133,11 +157,9 @@ namespace CLre.Fixes Traverse.Create(wcevOriginal).Field("weaponCooldownComponent").Property("cooldownLeft").Value; bool isInCooldown = Traverse.Create(wcevOriginal).Field("weaponCooldownComponent").Property("isInCooldown").Value; + if (!isInCooldown) break; object[] indexParams = {0}; // iterate over other handhelds and sync their cooldowns to the held item -#if DEBUG - API.Utility.Logging.MetaDebugLog($"Syncing {count} weapon cooldowns with the held item {toolId}"); -#endif for (int index = 0; index < count; index++) { indexParams[0] = index; @@ -151,14 +173,10 @@ namespace CLre.Fixes .Field("weaponCooldownComponent") .Property("isInCooldown").Value = isInCooldown; } - // stop running this task after one final sync to set every handheld to non-cooldown state - if (!isInCooldown && cooldownLeft <= 0) break; + yield return null; } // cleanup -#if DEBUG - API.Utility.Logging.MetaDebugLog("Custom cooldown ticks complete"); -#endif isRunningTick = false; yield return null; } diff --git a/CLre/Fixes/EnchantmentTableFloatParseFix.cs b/CLre/Fixes/EnchantmentTableFloatParseFix.cs index c51a5c9..d40cb5a 100644 --- a/CLre/Fixes/EnchantmentTableFloatParseFix.cs +++ b/CLre/Fixes/EnchantmentTableFloatParseFix.cs @@ -30,7 +30,7 @@ namespace CLre.Fixes NumberFormatInfo.InvariantInfo, out result); #if DEBUG - API.Utility.Logging.Log($"Parsed \"{s}\" into {result} (successfully? {__result})\n{Environment.StackTrace}"); + API.Utility.Logging.Log($"Parsed \"{s}\" into {result}"); #endif } @@ -58,7 +58,7 @@ namespace CLre.Fixes NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent, NumberFormatInfo.InvariantInfo, out __result); #if DEBUG - API.Utility.Logging.Log($"Parsed \"{s}\" into {__result} (successfully? {success})"); + API.Utility.Logging.Log($"Parsed \"{s}\" into {__result}"); #endif return !success; } diff --git a/CLre/Fixes/FloatLanguageFix.cs b/CLre/Fixes/FloatLanguageFix.cs deleted file mode 100644 index 1980bec..0000000 --- a/CLre/Fixes/FloatLanguageFix.cs +++ /dev/null @@ -1,91 +0,0 @@ -/*using System; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using HarmonyLib; - -namespace CLre.Fixes -{ - [Bugfix(name = "AntiStupidFloats", - description = "Force language-agnostic float->string behaviour internally, like all programs should (DISABLED BY DEFAULT)", - component = BugfixType.Initialiser, id = 10)] - public static class FloatLanguageFix - { - public static bool Enabled { private set; get; } = false; - - public static void Init() - { - string[] args = Environment.GetCommandLineArgs(); - if (args.Contains("-ff", StringComparer.InvariantCultureIgnoreCase) - || args.Contains("--float-fix", StringComparer.InvariantCultureIgnoreCase) - || File.Exists("floatFix.txt") - || File.Exists("whateverFloatsYourBoat")) - { - Enabled = true; - API.Utility.Logging.LogWarning("AntiStupidFloats fix enabled, this may cause issues"); - API.Utility.Logging.MetaLog(args.ToString()); - } - else - { - CultureInfo ci = CultureInfo.CurrentUICulture; - if (ci.TwoLetterISOLanguageName.ToLower() != "en") - { - API.Utility.Logging.LogWarning( - $"CLre detected non-English language {ci.DisplayName} ({ci.Name}/{ci.TwoLetterISOLanguageName}). " + - "CardLife works best with the Windows language set to English. " + - "If you run into bugs, try launching CardLife with the launch options set to \"%command% --float-fix\", without quotes. " + - "Please also report the issue to NGnius (ngniusness@gmail.com or NGnius#0864 on the CL Discord server) or on Trello (https://trello.com/b/EGKEpfBF/cardlife-bugs), so the problem can be fixed properly."); - } - } - } - } - - [Bugfix(name = "AntiStupidFloats", - description = "Force language-agnostic float->string behaviour internally, like all programs should (DISABLED BY DEFAULT)", - component = BugfixType.HarmonyPatch, id = 10)] - [HarmonyPatch] - class Float_ToString0_Patch - { - [HarmonyPostfix] // prefix causes a crash for some reason... - public static void AfterMethodCall(ref float __instance, ref string __result) - { -#if DEBUG - API.Utility.Logging.MetaLog("Float_ToString0_Patch"); -#endif - if (!FloatLanguageFix.Enabled) return; - API.Utility.Logging.LogWarning($"Intercepting float.ToString() to InvariantCulture equivalent\nStackTrace: {Environment.StackTrace}"); - __result = __instance.ToString(CultureInfo.InvariantCulture); - } - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method(typeof(float), "ToString"); - } - - } - - [Bugfix(name = "AntiStupidFloats", - description = "Force language-agnostic float->string behaviour internally, like all programs should (DISABLED BY DEFAULT)", - component = BugfixType.HarmonyPatch, id = 10)] - [HarmonyPatch] - class Float_ToString1_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(ref string format, ref float __instance, ref string __result) - { -#if DEBUG - API.Utility.Logging.MetaLog("Float_ToString1_Patch"); -#endif - if (!FloatLanguageFix.Enabled) return; - API.Utility.Logging.LogWarning($"Intercepting float.ToString(\"{format}\") to InvariantCulture equivalent\nStackTrace: {Environment.StackTrace}"); - __result = __instance.ToString(format, CultureInfo.InvariantCulture); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method(typeof(float), "ToString", new[] {typeof(string)}); - } - } -}*/ \ No newline at end of file diff --git a/CLre/Fixes/InitLogSooner.cs b/CLre/Fixes/InitLogSooner.cs index 2c56939..b6c3b44 100644 --- a/CLre/Fixes/InitLogSooner.cs +++ b/CLre/Fixes/InitLogSooner.cs @@ -22,7 +22,7 @@ namespace CLre.Fixes CustomLoggerThread_CreateGameObject_Patch.allowed = true; CustomLoggerThread.CreateGameObject(); CustomLoggerThread_CreateGameObject_Patch.allowed = false; - API.Utility.Logging.Log("Completed early log init"); + API.Utility.Logging.Log($"Completed early log init"); //System.IO.File.WriteAllText("InitLogSooner.log", $"Done at " + System.DateTime.Now.ToString()); } catch (Exception e) @@ -65,12 +65,10 @@ namespace CLre.Fixes FieldInfo quitThreadField = AccessTools.Field(typeof(CustomLoggerThread), "_quitThread"); MethodInfo flushLoggerMethod = AccessTools.Method(typeof(CustomLoggerThread), "FlushLogger"); - Flusher flushLogger = API.Utility.Reflection.BuildDelegate(flushLoggerMethod, null); - //Flusher flushLogger = (Flusher) Delegate.CreateDelegate(typeof(Action), null, flushLoggerMethod); + Flusher flushLogger = (Flusher) Delegate.CreateDelegate(typeof(Action), null, flushLoggerMethod); MethodInfo forceFlushMethod = AccessTools.Method("CustomLogger:ForceFlush"); - Flusher forceFlush = API.Utility.Reflection.BuildDelegate(forceFlushMethod, null); - //Flusher forceFlush = (Flusher) Delegate.CreateDelegate(typeof(Action), null, forceFlushMethod); + Flusher forceFlush = (Flusher) Delegate.CreateDelegate(typeof(Action), null, forceFlushMethod); Thread.MemoryBarrier(); IsLogStarted = true; diff --git a/CLre/Fixes/InventoryPanelScrollEngineFix.cs b/CLre/Fixes/InventoryPanelScrollEngineFix.cs index b3744f1..37448bc 100644 --- a/CLre/Fixes/InventoryPanelScrollEngineFix.cs +++ b/CLre/Fixes/InventoryPanelScrollEngineFix.cs @@ -9,7 +9,7 @@ namespace CLre.Fixes [Bugfix(name = "ScrollSpeedImprovement", description = "Improve mouse wheel scroll speed in inventory", more = "https://trello.com/c/elL8IVdn/4-scroll-menus-are-insensitive", - component = BugfixType.HarmonyPatch, id = 5)] + component = BugfixType.HarmonyPatch, id = 4)] [HarmonyPatch] class InventoryPanelScrollEngine_ScrollPanelByMouseWheel_Patch { @@ -32,7 +32,7 @@ namespace CLre.Fixes public static MethodBase Target() { MethodInfo methodtopatch = AccessTools.Method("Game.UI.InventoryPanelScrollEngine:ScrollPanelByMouseWheel"); - //if (null == methodtopatch) API.Utility.Logging.MetaLog("Intercepting Game.UI.InventoryPanelScrollEngine:ScrollPanelByMouseWheel() failed"); + if (null == methodtopatch) API.Utility.Logging.MetaLog("Intercepting Game.UI.InventoryPanelScrollEngine:ScrollPanelByMouseWheel() failed"); return methodtopatch; } } diff --git a/CLre/Fixes/MapPinPointsFloatFix.cs b/CLre/Fixes/MapPinPointsFloatFix.cs deleted file mode 100644 index a6511db..0000000 --- a/CLre/Fixes/MapPinPointsFloatFix.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Globalization; -using System.Reflection; -using System.Text; -using Game.UI.WorldMapScreen; -using HarmonyLib; -using Svelto.DataStructures; - -namespace CLre.Fixes -{ - public class MapPinPointsFloatFix - { - - } - - [Bugfix(name = "OfflineMapPointsFloatFix", - description = "Make map pin points save properly for everyone, even when floats contain a comma", - more = "https://trello.com/c/fEcNBLbZ/29-map-markers-reset-on-re-log", - component = BugfixType.HarmonyPatch, id = 12)] - [HarmonyPatch] - class WorldMapPinPointsMessage_InjectValues_Patch - { - private static StringBuilder sb = new StringBuilder(); - - [HarmonyPrefix] - public static bool BeforeMethodCall(WorldMapPinPointsMessage __instance, - FasterList pinPositions) - { -#if DEBUG - API.Utility.Logging.Log("Intercepting Game.UI.WorldMapScreen.WorldMapPinPointsMessage:InjectValues"); -#endif - sb.Length = 0; - for (int i = 0; i < pinPositions.Count; i++) - { - if (pinPositions[i].IsOnMap) - { - // force culture invariant float format (with a . as decimal point) - sb.AppendFormat("{0};{1};", - pinPositions[i].PinPosition.x.ToString("0.0", CultureInfo.InvariantCulture), - pinPositions[i].PinPosition.y.ToString("0.0", CultureInfo.InvariantCulture)); - } - else - { - sb.AppendFormat("{0};{1};", "x", "x"); - } - } - __instance.pinPoints = sb.ToString(); -#if DEBUG - API.Utility.Logging.Log($"Corrected pin point string to culture invariant: {sb.ToString()}"); -#endif - return false; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method(typeof(WorldMapPinPointsMessage), "InjectValues"); - } - } -} \ No newline at end of file diff --git a/CLre/Fixes/MiniScreenEmbiggener.cs b/CLre/Fixes/MiniScreenEmbiggener.cs deleted file mode 100644 index 2862010..0000000 --- a/CLre/Fixes/MiniScreenEmbiggener.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Runtime.CompilerServices; -using UnityEngine; - -namespace CLre.Fixes -{ - [Bugfix(name = "MiniScreenEmbiggener", - more = "https://trello.com/c/NAls3XaE/17-game-starts-minimized-and-wont-restore", - description = "Go into fullscreen when Unity does dumb display stuff", - component = BugfixType.Initialiser, id = 6)] - public static class MiniScreenHelper - { - private const int WIDTH_MINIMUM = 200; - private const int HEIGHT_MINIMUM = 200; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Init() - { - if (Screen.width < WIDTH_MINIMUM || Screen.height < HEIGHT_MINIMUM) - { - // fix screen that's too small - API.Utility.Logging.LogWarning($"Window is too small! (detected: {Screen.width}x{Screen.height})"); - if (Screen.resolutions.Length > 0) - { - Resolution r = Screen.resolutions[Screen.resolutions.Length - 1]; - Screen.SetResolution(r.width, r.height, true); - API.Utility.Logging.MetaLog($"Set screen resolution to {r.width}x{r.height} (fullscreen)"); - } - else - { - // no resolutions, try some stuff to fix this (this is basically a bunch of random guesses) - API.Utility.Logging.LogError("No screen resolutions available, hopefully it'll be ok eventually..."); - Screen.fullScreen = true; - Display.onDisplaysUpdated += () => // hope displays update fixes things - { - API.Utility.Logging.MetaLog("Displays updated"); - if (Screen.resolutions.Length > 0) - { - Resolution r = Screen.resolutions[Screen.resolutions.Length - 1]; - Screen.SetResolution(r.width, r.height, true); - API.Utility.Logging.MetaLog($"Set screen resolution to {r.width}x{r.height} (fullscreen)"); - } - }; - // log displays to help debug this issue - foreach (var display in Display.displays) - { - API.Utility.Logging.MetaLog($"Display: {display.renderingWidth}x{display.renderingHeight} (sys: {display.systemWidth}x{display.systemHeight}) Active? {display.active}"); - } - } - } - } - } -} \ No newline at end of file diff --git a/CLre/Fixes/OfflineGameTimeSavingFloatFix.cs b/CLre/Fixes/OfflineGameTimeSavingFloatFix.cs deleted file mode 100644 index 72a9b55..0000000 --- a/CLre/Fixes/OfflineGameTimeSavingFloatFix.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; -using SQL; -using Svelto.DataStructures; - -namespace CLre.Fixes -{ - public class OfflineGameTimeSavingFloatFix - { - - } - - [Bugfix(name = "OfflineGameTimeSavingFloatFix", - description = "Make game time save properly for everyone, even when floats contain a comma", - component = BugfixType.HarmonyPatch, id = 11)] - [HarmonyPatch] - class OfflineSaveServerGameTimeRequest_DoRequest_Patch - { - private const string QUERY = "INSERT OR REPLACE INTO gametime (gameId, gameTime) VALUES (@GameId, @GameTime)"; - - [HarmonyPrefix] - public static bool BeforeMethodCall(object __instance, ref object ____dependency) - { - //API.Utility.Logging.Log("Intercepting OfflineSaveServerGameTimeRequest.DoRequest"); - //if (____dependency == null) return true; -#if DEBUG - API.Utility.Logging.Log( - "Replacing OfflineSaveServerGameTimeRequest.DoRequest SQL query with safer alternative"); -#endif - // TODO optimise - ISQL sql = Traverse.Create(__instance).Property("sql").Value; - Traverse dep = Traverse.Create(____dependency); - // populate params - FasterList sqlParams = new FasterList(); - sqlParams.Add(new SQLParam("@GameId", dep.Field("gameId").Value)); - sqlParams.Add(new SQLParam("@GameTime", dep.Field("gameTime").Value)); - // actually perform query - sql.ExecuteSaveQuery(QUERY, OnComplete, OnError, sqlParams); -#if DEBUG - API.Utility.Logging.Log("Executed corrected game time saving SQL query"); -#endif - return false; - } - - private static void OnComplete(int numberRowsEdited) - { -#if DEBUG - API.Utility.Logging.Log( - $"Completed OfflineSaveServerGameTimeRequest_DoRequest_Patch SQL Query ({numberRowsEdited} rows)"); -#endif - } - - private static void OnError(Exception e) - { -#if DEBUG - API.Utility.Logging.LogError( - $"Error in OfflineSaveServerGameTimeRequest_DoRequest_Patch SQL Query: {e}\n{e.StackTrace}"); -#endif - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method( - "Requests.ServerSaving.ServerLoginTime.OfflineSaveServerGameTimeRequest:DoRequest"); - } - } -} \ No newline at end of file diff --git a/CLre/Fixes/OfflineSpawnpointSavingFloatFix.cs b/CLre/Fixes/OfflineSpawnpointSavingFloatFix.cs deleted file mode 100644 index 2daeb7e..0000000 --- a/CLre/Fixes/OfflineSpawnpointSavingFloatFix.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; -using SQL; -using Svelto.DataStructures; - -namespace CLre.Fixes -{ - public class OfflineSpawnpointSavingFloatFix - { - - } - - [Bugfix(name = "OfflineSpawnpointSavingFloatFix", - description = "Make spawnpoints save properly for everyone, even when floats contain a comma", - more = "https://trello.com/c/hpADhDhQ/21-login-goes-to-original-spawn", - component = BugfixType.HarmonyPatch, id = 9)] - [HarmonyPatch] - class OfflineSavePlayerSpawnPointRequest_DoRequest_Patch - { - private const string QUERY = "INSERT OR REPLACE INTO spawnpoints (gameId, uniqueId, PublicID, x, y, z, selected) VALUES (@GameId, @UniqueId, @PublicId, @X, @Y, @Z, @Selected)"; - - [HarmonyPrefix] - public static bool BeforeMethodCall(object __instance, object ____dependency) - { - //API.Utility.Logging.Log("Intercepting OfflineSavePlayerSpawnPointRequest.DoRequest"); - if (____dependency == null) return true; -#if DEBUG - API.Utility.Logging.Log("Replacing OfflineSavePlayerSpawnPointRequest.DoRequest SQL squery with safer alternative"); -#endif - // TODO optimise - ISQL sql = Traverse.Create(__instance).Property("sql").Value; - Traverse dep = Traverse.Create(____dependency); - // populate params - FasterList sqlParams = new FasterList(); - sqlParams.Add(new SQLParam("@GameId", dep.Field("gameId").Value)); - sqlParams.Add(new SQLParam("@UniqueId", dep.Field("uniqueId").Value)); - sqlParams.Add(new SQLParam("@PublicId", dep.Field("PublicId").Value)); - sqlParams.Add(new SQLParam("@X", dep.Field("x").Value)); - sqlParams.Add(new SQLParam("@Y", dep.Field("y").Value)); - sqlParams.Add(new SQLParam("@Z", dep.Field("z").Value)); - sqlParams.Add(new SQLParam("@Selected", dep.Field("selected").Value? 1 : 0)); - // actually perform query - sql.ExecuteSaveQuery(QUERY, OnComplete, OnError, sqlParams); -#if DEBUG - API.Utility.Logging.Log("Executed corrected spawnpoint saving SQL query"); -#endif - return false; - } - - private static void OnComplete(int numberRowsEdited) - { -#if DEBUG - API.Utility.Logging.Log($"Completed OfflineSavePlayerSpawnPointRequest_DoRequest_Patch SQL Query ({numberRowsEdited} rows)"); -#endif - } - - private static void OnError(Exception e) - { -#if DEBUG - API.Utility.Logging.LogError($"Error in OfflineSavePlayerSpawnPointRequest_DoRequest_Patch SQL Query: {e}\n{e.StackTrace}"); -#endif - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("Requests.Offline.Server.OfflineSavePlayerSpawnPointRequest:DoRequest"); - } - } -} \ No newline at end of file diff --git a/CLre/Fixes/StartupSpeedup.cs b/CLre/Fixes/StartupSpeedup.cs index 0dc5280..3fb94ca 100644 --- a/CLre/Fixes/StartupSpeedup.cs +++ b/CLre/Fixes/StartupSpeedup.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Reflection; using HarmonyLib; -#if DEBUG namespace CLre.Fixes { public class StartupSpeedup @@ -55,5 +54,4 @@ namespace CLre.Fixes Speedup_Benchmark.test = Stopwatch.StartNew(); } } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/CLre/Fixes/TerrainModifyReset.cs b/CLre/Fixes/TerrainModifyReset.cs deleted file mode 100644 index 9292eb8..0000000 --- a/CLre/Fixes/TerrainModifyReset.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using CLre.API.Synergy; -using CLre.API.Utility; -using Game.DataLoader; -using Game.Handhelds; -using GameNetworkLayer.Shared; -using HarmonyLib; -using NetworkFramework.Shared; -using Svelto.ECS; -using UnityEngine; -using VoxelFarm.GameServer; - -namespace CLre.Fixes -{ - [Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.Initialiser, id = 8)] - public class TerrainModifyReset - { - private static TerrainModifyResetEngine _tmrEngine = null; - - public static void Init() - { - _tmrEngine = new TerrainModifyResetEngine(); - } - } - - [Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.Workaround, id = 8)] - public class TerrainModifyResetEngine : API.Engines.GameObsoleteEnginePostBuild, IDataAccess - { - private Reflection.INetMsgClientListener_RegisterListener _registerListener; - - public override void Ready() - { - _registerListener = - Reflection.MethodAsDelegate>( - "GameNetworkLayer.Client.NetMessageClientListener:RegisterListener", - generics: new [] {typeof(API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection)}, - instance: MainLevel_BuildClasses_Patch.netMessageListener); - _registerListener(NetworkDispatcherCode.TerrainModificationFailed, OnMessageReceived); - } - - private void OnMessageReceived(ref API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection data) - { - if (!data.Ok()) - { - // reset terrain visuals - // TODO optimise -#if DEBUG - API.Utility.Logging.MetaLog($"data.resourceId: {data.resourceId}"); -#endif - AddTerrain(ref data); - - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void GetTerrainRelativePosition(ref Vector3 pos) - { - // This uses decompiled code from VoxelFarm.Shared.VoxelFarmGameUtils:GetTerrainRelativePosition - // there's no point in calling that simple function when I have to jump through hoops with reflection - // - // there's also nothing particularly unique (ie copyrightable) about this code, - // so the lawyers can suck it (also suing a benevolent project is a shitty move) - pos.x /= 0.083333336f; - pos.y /= 0.041666668f; - pos.z /= 0.083333336f; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AddTerrain(ref API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection data) - { - // This uses decompiled code from VoxelFarm.GameServer.TerrainModelClientServer:AddTerrain - // there's no point in calling that simple function when I have to jump through hoops with reflection - // to supply the parameters to it - // - // Also this is not unique functionality, and comes from the logic of how the placement modes work - switch (data.toolMode) - { - case ToolModeType.Block: - MainLevel_BuildClasses_Patch.tmcs.AddDisc(0, data.hit, (int)data.resourceId, 5, 5); - break; - case ToolModeType.Disc: - MainLevel_BuildClasses_Patch.tmcs.AddDisc(0, data.hit, (int)data.resourceId, 1, 5); - break; - case ToolModeType.Voxel: - MainLevel_BuildClasses_Patch.tmcs.AddSingleVoxel(0, data.hit, (int)data.resourceId); - break; - } - } - - public IDataDB dataDB { get; set; } - } - - [Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.HarmonyPatch, id = 8)] - [HarmonyPatch] - class TerrainPendingModificationEngineClient_Add_Patch - { - internal static object _terrainModifyInputNode = null; - - [HarmonyPrefix] - public static void BeforeMethodCall(object node) - { -#if DEBUG - API.Utility.Logging.MetaLog("Intercepting VoxelFarm.Client.TerrainPendingModificationEngineClient:Add()"); -#endif - _terrainModifyInputNode = node; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("VoxelFarm.Client.TerrainPendingModificationEngineClient:Add", new []{ AccessTools.TypeByName("VoxelFarm.Shared.TerrainModifyInputNode")}); - } - } - - /*[Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.HarmonyPatch, id = 8)] - [HarmonyPatch] - class TerrainPendingModificationEngineClient_OnBlockRemoved_Patch - { - [HarmonyPrefix] - public static bool BeforeMethodCall(int sender, ref ISerializedNetData terrainModifyInputData) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Intercepting VoxelFarm.Client.TerrainPendingModificationEngineClient:OnBlockRemoved({sender}, {terrainModifyInputData})"); -#endif - return false; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("VoxelFarm.Client.TerrainPendingModificationEngineClient:OnBlockRemoved"); - } - }*/ - - [Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.Debug, id = 8)] - [HarmonyPatch] - class SpadeEngine_FinishDigging_Patch - { - internal static int CurrentMaterialId = 0; - [HarmonyPrefix] - public static void BeforeMethodCall(object toolNode, int ____currentMaterialId) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Intercepting Game.Handhelds.SpadeEngine:FinishDigging:GetTerrainMaterial(...) material:{____currentMaterialId}"); -#endif - CurrentMaterialId = ____currentMaterialId; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("Game.Handhelds.SpadeEngine:FinishDigging"); - } - } - - [Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.Debug, id = 8)] - [HarmonyPatch] - class TerrainModifyInputData_InjectValues_Patch - { - [HarmonyPrefix] - public static void BeforeMethodCall(ref uint resourceId) - { -#if DEBUG - API.Utility.Logging.MetaLog($"VoxelFarm.Shared.TerrainModifyInputData:InjectValues({resourceId}, ...)"); -#endif - if (resourceId == 0) resourceId = (uint) SpadeEngine_FinishDigging_Patch.CurrentMaterialId; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("VoxelFarm.Shared.TerrainModifyInputData:InjectValues"); - } - } - - [Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.HarmonyPatch, id = 8)] - [HarmonyPatch] - class NetMessageClientListener_RegisterListener_Patch - { - [HarmonyPrefix] - public static bool BeforeMethodCall(NetworkDispatcherCode code) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Intercepting GameNetworkLayer.Client.NetMessageClientListener:RegisterListener({code}, ...)"); -#endif - // don't allow for standard TerrainModificationFailed listener to be registered - // because it's a different type and that's illegal - return code != NetworkDispatcherCode.TerrainModificationFailed; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameNetworkLayer.Client.NetMessageClientListener:RegisterListener", generics: new []{ typeof(SerializedEmptyNetData)}); - } - } - - // this disables terrain destruction - /*[Bugfix(name = "TerrainModificationFailedHandler", - description = "Actually handle TerrainModificationFailed network messages", - more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools", - component = BugfixType.Debug, id = 8)] - [HarmonyPatch] - class TerrainModificationEngineServer_RemoveTerrainInput_Patch - { - [HarmonyPrefix] - public static bool BeforeMethodCall(int senderPlayerId, ref ISerializedNetData data) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Intercepting client-side GameServer.VoxelFarm.Server.TerrainModificationEngineServer:RemoveTerrainInput({senderPlayerId}, {data})"); -#endif - return false; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameServer.VoxelFarm.Server.TerrainModificationEngineServer:RemoveTerrainInput"); - } - }*/ -} \ No newline at end of file diff --git a/CLre/Fixes/UnderStructureCollider.cs b/CLre/Fixes/UnderStructureCollider.cs deleted file mode 100644 index 03d7a95..0000000 --- a/CLre/Fixes/UnderStructureCollider.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System.Collections; -using System.Reflection; -using CLre.API.Engines; -using Game.Building; -using Game.Character; -using Game.Utilities; -using HarmonyLib; -using Svelto.ECS; -using Svelto.Tasks; -using UnityEngine; -using voxelfarm.VFCol; - -namespace CLre.Fixes -{ - [Bugfix(name = "UnderStructureCollider", - description = "Prevent passing through structures from below a bit better", - more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", - component = BugfixType.Initialiser, id = 7)] - public static class UnderStructureCollider - { - public static void Init() - { -#if DEBUG - MainLevel_BuildDeprecatedEngines_Patch.afterBuildEngines.Add(new CharacterGroundedCheckEngine()); -#endif - MainLevel_BuildDeprecatedEngines_Patch.afterBuildEngines.Add(new CharacterUnderStructureRaycastEngine()); - } - } - - [Bugfix(name = "UnderStructureCollider", - description = "Prevent passing through structures from below a bit better", - more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", - component = BugfixType.HarmonyPatch, id = 7)] - [HarmonyPatch(typeof(VFColUtility), "Move")] - class VFCOlUtility_Move_Patch - { - internal static bool Override = false; - - [HarmonyPostfix] - public static void AfterMethodCall(ref Vector3 __result) - { -#if DEBUG - API.Utility.Logging.MetaLog("Intercepting CharacterMovementEngine.ApplyForces(...)"); -#endif - if (Override) - { - if (__result.y > 0) - { - __result = Vector3.zero; - } - } - } - } - -#if DEBUG - [Bugfix(name = "UnderStructureCollider", - description = "Prevent passing through structures from below a bit better", - more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", - component = BugfixType.Debug, id = 7)] - public class CharacterGroundedCheckEngine : SingleEntityViewEngine, ICLreEngine - { - private CharacterOnStructureNode _characterOnStructureNode; - - public void Ready() {} - - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } - - protected override void Add(CharacterOnStructureNode entityView) - { - _characterOnStructureNode = entityView; - CheckNode().Run(); - } - - protected override void Remove(CharacterOnStructureNode entityView) - { - _characterOnStructureNode = null; - } - - public IEnumerator CheckNode() - { - while (_characterOnStructureNode != null) - { - if (_characterOnStructureNode.characterGroundedRaycastComponent.didHit) - { - if (_characterOnStructureNode.characterGroundedRaycastComponent.hitResult.transform != null) - { - API.Utility.Logging.MetaLog($"HIT: {_characterOnStructureNode.characterGroundedRaycastComponent.hitResult.transform.tag} (audio: '{_characterOnStructureNode.characterOnStructureComponent.characterPositionStructureAudioSwitch.value}')"); - RaycastHit raycastHitInfo = _characterOnStructureNode.characterGroundedRaycastComponent.hitResult; - if (raycastHitInfo.transform.tag == GameTags.STRUCTURE_TAG) - { - int instanceID = raycastHitInfo.transform.GetComponentInParent().gameObject.GetInstanceID(); - if (entitiesDB.TryQueryEntityView(instanceID, DEPRECATED_SveltoExtensions.DEPRECATED_GROUP, - out PlacedStructureNode entityView)) - { - API.Utility.Logging.MetaLog($"Structure: {entityView.structureNameComponent.resourceName}"); - } - } - } - else - { - API.Utility.Logging.MetaLog("No transform (not on a structure?)"); - } - - } - else - { - API.Utility.Logging.MetaLog("No hit"); - } - yield return null; - } - } - } -#endif - - [Bugfix(name = "UnderStructureCollider", - description = "Prevent passing through structures from below a bit better", - more = "https://trello.com/c/nfuaZWQZ/10-passing-through-structures", - component = BugfixType.Miscellaneous, id = 7)] - public class CharacterUnderStructureRaycastEngine : SingleEntityViewEngine, ICLreEngine - { - private bool _playerExists = false; - - private int _layer = GameLayers.CARD_INTERACTABLE; - - public void Ready() - { - } - - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } - - protected override void Add(CharacterMovementNode entityView) - { - _playerExists = true; - RaycastStructureCheck(entityView.ID.entityID).RunOnScheduler(StandardSchedulers.physicScheduler); - } - - protected override void Remove(CharacterMovementNode entityView) - { - _playerExists = false; - } - - public IEnumerator RaycastStructureCheck(int playerId) - { - while (_playerExists) - { - CharacterMovementNode cmn; - while (entitiesDB.TryQueryEntityView(playerId, DEPRECATED_SveltoExtensions.DEPRECATED_GROUP, out cmn)) - { - Vector3 position = cmn.characterMovementComponent.characterController.transform.position; - CharacterController cc = cmn.characterMovementComponent.characterController; - RaycastHit rayInfo; - bool didHit = Physics.SphereCast( - position, //+ Vector3.up * (cc.height * 0.5f), // center of player - cc.radius, - Vector3.up, - out rayInfo, - cc.height, //* 0.5f - cc.radius * 0.05f, - _layer); - if (didHit && rayInfo.transform != null) - { - if (rayInfo.transform.CompareTag(GameTags.STRUCTURE_TAG)) - { -#if DEBUG - API.Utility.Logging.MetaLog("Structure is above me!"); -#endif - VFCOlUtility_Move_Patch.Override = true; - } - } - else - { -#if DEBUG - API.Utility.Logging.MetaLog("No structure above :("); -#endif - VFCOlUtility_Move_Patch.Override = false; - } - yield return null; - } - - yield return null; - } - - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Config/CLreConfig.cs b/CLre_server/API/Config/CLreConfig.cs deleted file mode 100644 index 9560d15..0000000 --- a/CLre_server/API/Config/CLreConfig.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.IO; -using System.Text; - -namespace CLre_server.API.Config -{ - [Serializable] - public struct CLreConfig - { - public bool clre_clients_only; - public bool web_server; - public bool terrain_exclusion_zone; - public bool chat_commands; - public string email_address; - public string password; - public string[] bans; - public string[] moderators; - - public static CLreConfig Default() - { - return new CLreConfig - { - clre_clients_only = false, - web_server = false, - terrain_exclusion_zone = false, - chat_commands = false, - email_address = "email@address.com", - password = "s3cur3-password", - bans = new string[0], - moderators = new []{ "NGuiness", "NGnius", "Zhang"}, - }; - } - - public static CLreConfig FromString(string s) - { - return UnityEngine.JsonUtility.FromJson(s); - } - - public static CLreConfig FromFile(string path) - { - string s = File.ReadAllText(path); - return FromString(s); - } - - public static CLreConfig FromFileSafely(string path) - { - // try to load config file - CLreConfig conf = Default(); - try - { - string s = File.ReadAllText(path); - conf = FromString(s); - } - catch (Exception e) - { - Utility.Logging.LogWarning($"Failed to load {path}: {e}\n{e.StackTrace}"); - try - { - File.WriteAllText(path, conf.ToString()); - } - catch (Exception e2) - { - Utility.Logging.LogWarning($"Failed to write {path}: {e2}\n{e2.StackTrace}"); - } - } - - return conf; - } - - public override string ToString() - { - return UnityEngine.JsonUtility.ToJson(this, true); - } - - public void ToFile(string path) - { - File.WriteAllText(path, this.ToString()); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Engines/ICLreEngine.cs b/CLre_server/API/Engines/ICLreEngine.cs deleted file mode 100644 index 9224a1c..0000000 --- a/CLre_server/API/Engines/ICLreEngine.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Game.DataLoader; -using Svelto.ECS; - -namespace CLre_server.API.Engines -{ - public interface ICLreEngine : IQueryingEntitiesEngine, IEngine, IDataAccess - { - IEntityFactory entityFactory { get; set; } - } -} \ No newline at end of file diff --git a/CLre_server/API/Engines/ServerEngines.cs b/CLre_server/API/Engines/ServerEngines.cs deleted file mode 100644 index fabc9ed..0000000 --- a/CLre_server/API/Engines/ServerEngines.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Game.DataLoader; -using HarmonyLib; -using Svelto.DataStructures; -using Svelto.ECS; - -namespace CLre_server.API.Engines -{ - public abstract class ServerEnginePreBuild : ICLreEngine - { - public ServerEnginePreBuild() - { - MainGameServer_BuildDeprecatedEngines_Patch.beforeBuildEngines.Add(this); - } - - public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } - public IDataDB dataDB { get; set; } - } - - public abstract class ServerEnginePostBuild : ICLreEngine - { - public ServerEnginePostBuild() - { - MainGameServer_BuildDeprecatedEngines_Patch.afterBuildEngines.Add(this); - } - - public abstract void Ready(); - public IEntitiesDB entitiesDB { get; set; } - public IEntityFactory entityFactory { get; set; } - public IDataDB dataDB { get; set; } - } - - [HarmonyPatch(typeof(GameServer.GameFramework.MainGameServer), "BuildDeprecatedEngines")] - class MainGameServer_BuildDeprecatedEngines_Patch - { - internal static FasterList beforeBuildEngines = new FasterList(); - - internal static FasterList afterBuildEngines = new FasterList(); - - [HarmonyPrefix] - public static void BeforeMethodCall(GameServer.GameFramework.MainGameServer __instance, IEntityFactory ____entityFactory) - { - foreach (ICLreEngine e in beforeBuildEngines) - { - e.entityFactory = ____entityFactory; - __instance.AddEngine(e); - } - } - - [HarmonyPostfix] - public static void AfterMethodCall(GameServer.GameFramework.MainGameServer __instance, IEntityFactory ____entityFactory) - { - foreach (ICLreEngine e in afterBuildEngines) - { - e.entityFactory = ____entityFactory; - __instance.AddEngine(e); - } - } - } -} \ No newline at end of file diff --git a/CLre_server/API/MainServer/ModerationEngine.cs b/CLre_server/API/MainServer/ModerationEngine.cs deleted file mode 100644 index 6221301..0000000 --- a/CLre_server/API/MainServer/ModerationEngine.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Reflection; -using HarmonyLib; -using Svelto.Context; -using Svelto.DataStructures; -using Svelto.ECS; -using User.Server; - -namespace CLre_server.API.MainServer -{ - class ModerationEngine : Engines.ServerEnginePostBuild - { - public override void Ready() - { - } - - public int? FindConnectedPlayerById(string publicId) - { - FieldInfo f = AccessTools.Field(AccessTools.TypeByName("User.Server.AccountExclusiveGroups"), "accountGroup"); - ExclusiveGroup accountGroup = (ExclusiveGroup) f.GetValue(null); - ReadOnlyCollectionStruct accounts = - entitiesDB.QueryEntityViews(accountGroup); - for (int i = 0; i < accounts.Count; i++) - { - if (accounts[i].accountId.publicId.ToString() == publicId) - { - return i; - } - } - - return null; - } - - public int? FindConnectedPlayerByName(string displayName) - { - FieldInfo f = AccessTools.Field(AccessTools.TypeByName("User.Server.AccountExclusiveGroups"), "accountGroup"); - ExclusiveGroup accountGroup = (ExclusiveGroup) f.GetValue(null); - ReadOnlyCollectionStruct accounts = - entitiesDB.QueryEntityViews(accountGroup); - for (int i = 0; i < accounts.Count; i++) - { - if (String.Equals(accounts[i].accountId.displayName, displayName, StringComparison.InvariantCultureIgnoreCase)) - { - return i; - } - } - - return null; - } - - public Guid? FindConnectedPlayerGuidByName(string displayName) - { - FieldInfo f = AccessTools.Field(AccessTools.TypeByName("User.Server.AccountExclusiveGroups"), "accountGroup"); - ExclusiveGroup accountGroup = (ExclusiveGroup) f.GetValue(null); - ReadOnlyCollectionStruct accounts = - entitiesDB.QueryEntityViews(accountGroup); - for (int i = 0; i < accounts.Count; i++) - { - if (String.Equals(accounts[i].accountId.displayName, displayName, StringComparison.InvariantCultureIgnoreCase)) - { - return accounts[i].accountId.publicId; - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/CLre_server/API/MainServer/Moderator.cs b/CLre_server/API/MainServer/Moderator.cs deleted file mode 100644 index 580fc63..0000000 --- a/CLre_server/API/MainServer/Moderator.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using GameNetworkLayer.Shared; - -namespace CLre_server.API.MainServer -{ - public class Moderator - { - private static Moderator _instance = null; - - public static Moderator Instance - { - get - { - if (_instance == null) Init(); - return _instance; - } - } - - internal static void Init() - { - if (_instance == null) _instance = new Moderator(); - } - - private ModerationEngine _moderationEngine; - - private Moderator() - { - _moderationEngine = new ModerationEngine(); - Server.Instance.PlayerConnect += (sender, args) => - { -#if DEBUG - Utility.Logging.MetaLog($"Player {args.PlayerId} is connecting, starting ban checker"); -#endif - CheckConnectingPlayerAsap(args.PlayerId).Run(); - }; - } - - public bool DisconnectPlayerById(string publicId) - { - int? playerId = _moderationEngine.FindConnectedPlayerById(publicId); - if (playerId.HasValue) - { - UserVerification.Instance.DisconnectPlayer(playerId.Value, NetworkDispatcherCode.GameDataVerificationFail); - return true; - } - - return false; - } - - public bool DisconnectPlayerByName(string name) - { - int? playerId = _moderationEngine.FindConnectedPlayerByName(name); - if (playerId.HasValue) - { - UserVerification.Instance.DisconnectPlayer(playerId.Value, NetworkDispatcherCode.GameDataVerificationFail); - return true; - } - - return false; - } - - public bool BanPlayerById(string publicId) - { - List bans = new List(CLre.Config.bans); - if (!bans.Contains(publicId)) - { - bans.Add(publicId); - CLre.Config.bans = bans.ToArray(); - } - return DisconnectPlayerById(publicId); - } - - public bool BanPlayerByName(string name) - { - List bans = new List(CLre.Config.bans); - if (!bans.Contains(name)) - { - bans.Add(name); - CLre.Config.bans = bans.ToArray(); - } - return DisconnectPlayerByName(name); - } - - public bool IsModerator(string name) - { - foreach (string modName in CLre.Config.moderators) - { - if (string.Compare(name, modName, StringComparison.InvariantCultureIgnoreCase) == 0) - { - return true; - } - } - - Guid? publicId = _moderationEngine.FindConnectedPlayerGuidByName(name); - if (publicId.HasValue) - { - foreach (string modGuid in CLre.Config.moderators) - { - if (modGuid == publicId.ToString()) - { - return true; - } - } - } - - return false; - } - - public IEnumerator CheckConnectingPlayerAsap(int playerId) - { - while (Server.Instance.Players.Length <= playerId) - { - yield return null; - yield return null; - yield return null; - yield return null; - } - var connector = Server.Instance.Players[playerId]; - if (CLre.Config.bans.Contains(connector.accountId.displayName) - || CLre.Config.bans.Contains(connector.accountId.publicId.ToString())) - { -#if DEBUG - Utility.Logging.MetaLog($"Banned player {connector.accountId.displayName} ({connector.accountId.publicId}) tried to connect, kicking"); -#endif - UserVerification.Instance.DisconnectPlayer(playerId, NetworkDispatcherCode.GameDataVerificationFail); - } -#if DEBUG - else - { - Utility.Logging.MetaLog($"Player {connector.accountId.displayName} ({connector.accountId.publicId}) is not banned, skipping auto-kick"); - } -#endif - } - } -} \ No newline at end of file diff --git a/CLre_server/API/MainServer/Server.cs b/CLre_server/API/MainServer/Server.cs deleted file mode 100644 index f06cdf4..0000000 --- a/CLre_server/API/MainServer/Server.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System; -using System.Reflection; -using GameNetworkLayer.Shared; -using GameServer; -using HarmonyLib; -using NetworkFramework.Server; -using Svelto.Context; -using User.Server; - -namespace CLre_server.API.MainServer -{ - public class Server - { - // static - - private static Server _instance = null; - - public static Server Instance - { - get - { - if (_instance == null) Init(); - return _instance; - } - } - - internal static void Init() - { - if (_instance == null) _instance = new Server(); - } - - // instance events - public event EventHandler InitStart - { - add => MainGameServer_Constructor_Patch.preConstructor += value; - remove => MainGameServer_Constructor_Patch.preConstructor -= value; - } - - public event EventHandler InitComplete - { - add => ServerReadyEngine.serverEngineReady += value; - remove => ServerReadyEngine.serverEngineReady -= value; - } - - public event EventHandler FrameworkReady - { - add => ServerReadyEngine.serverFrameworkReady += value; - remove => ServerReadyEngine.serverFrameworkReady -= value; - } - - public event EventHandler FrameworkExit - { - add => ServerReadyEngine.serverFrameworkDestroyed += value; - remove => ServerReadyEngine.serverFrameworkDestroyed -= value; - } - - public event EventHandler Connected - { - add => PhotonNetwork_ConnectUsingSettings_Patch.postConnect += value; - remove => PhotonNetwork_ConnectUsingSettings_Patch.postConnect -= value; - } - - public event EventHandler PlayerConnect - { - add => MainGameServer_SetupContainer_Patch.playerConnected += value; - remove => MainGameServer_SetupContainer_Patch.playerConnected -= value; - } - - public event EventHandler PlayerDisconnect - { - add => MainGameServer_SetupContainer_Patch.playerDisconnected += value; - remove => MainGameServer_SetupContainer_Patch.playerDisconnected -= value; - } - - // properties - - public GameServerSettings GameServerSettings - { - get => MainGameServer_SetupMods_Patch._gameServerSettings; - - set - { - MainGameServer_SetupMods_Patch._gameServerSettings = value; - Traverse.Create(MainGameServer_Constructor_Patch.mgs).Field("_gameServerSettings").Value = value; - } - } - - public AccountIdServerNode[] Players - { - get => _serverDatabaseQueryEngine.GetConnectedAccounts(); - } - - // fields - - private ServerDatabaseQueryEngine _serverDatabaseQueryEngine; - private ServerReadyEngine _serverReadyEngine; - - private Server() - { - _serverReadyEngine = new ServerReadyEngine(); - _serverDatabaseQueryEngine = new ServerDatabaseQueryEngine(); - } - } - - [HarmonyPatch] - class MainGameServer_SetupMods_Patch - { - internal static GameServerSettings _gameServerSettings; - - [HarmonyPostfix] - public static void AfterMethodCall(GameServerSettings ____gameServerSettings) - { -#if DEBUG - Utility.Logging.MetaLog("Got GameServerSettings"); -#endif - _gameServerSettings = ____gameServerSettings; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameServer.GameFramework.MainGameServer:SetupMods"); - } - } - - [HarmonyPatch] - class MainGameServer_Constructor_Patch - { - - internal static ICompositionRoot mgs = null; - - internal static event EventHandler preConstructor; - - internal static event EventHandler postConstructor; - - [HarmonyPrefix] - public static void BeforeMethodCall() - { - if (preConstructor != null) preConstructor(null, default(StartingEventArgs)); - } - - [HarmonyPostfix] - public static void AfterMethodCall(ICompositionRoot __instance) - { - mgs = __instance; - if (postConstructor != null) postConstructor(__instance, default(StartingEventArgs)); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Constructor(AccessTools.TypeByName("GameServer.GameFramework.MainGameServer")); - } - } - - [HarmonyPatch(typeof(PhotonNetwork), "ConnectUsingSettings")] - class PhotonNetwork_ConnectUsingSettings_Patch - { - internal static event EventHandler preConnect; - - internal static event EventHandler postConnect; - - [HarmonyPostfix] - public static void AfterMethodCall(string gameVersion) - { - if (postConnect != null) postConnect(null, new StartedEventArgs - { - photonVersion = gameVersion, - photonRegion = PhotonNetwork.CloudRegion, - worldName = MainGameServer_SetupMods_Patch._gameServerSettings.GetWorldName(), - gameGuid = MainGameServer_SetupMods_Patch._gameServerSettings.GetGameGuid(), - }); - } - - [HarmonyPrefix] - public static void BeforeMethodCall(string gameVersion) - { - if (preConnect != null) preConnect(null, new StartedEventArgs - { - photonVersion = gameVersion, - photonRegion = PhotonNetwork.CloudRegion, - worldName = MainGameServer_SetupMods_Patch._gameServerSettings.GetWorldName(), - gameGuid = MainGameServer_SetupMods_Patch._gameServerSettings.GetGameGuid(), - }); - } - } - - [HarmonyPatch(typeof(GameServer.GameFramework.MainGameServer), "SetupContainer")] - class MainGameServer_SetupContainer_Patch - { - internal static event EventHandler playerConnected; - - internal static event EventHandler playerDisconnected; - - private static GameServer.GameFramework.MainGameServer mgs = null; - - [HarmonyPostfix] - public static void AfterMethodCall(GameServer.GameFramework.MainGameServer __instance, ref IPlayerConnectedCallbacks ____playerConnectedCallbacks) - { - mgs = __instance; - ____playerConnectedCallbacks.OnPlayerConnected += OnConnect; - ____playerConnectedCallbacks.OnPlayerDisconnected += OnDisconnect; - } - - public static void OnConnect(int playerId) - { - Synergy.Clients.RegisterClient(playerId); - if (playerConnected != null) playerConnected(mgs, new PlayerConnectArgs - { - PlayerId = playerId, - }); - } - - public static void OnDisconnect(int playerId) - { - Synergy.Clients.RemoveClient(playerId); - if (playerDisconnected != null) playerDisconnected(mgs, new PlayerConnectArgs - { - PlayerId = playerId, - }); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/MainServer/ServerEngines.cs b/CLre_server/API/MainServer/ServerEngines.cs deleted file mode 100644 index 571b2ef..0000000 --- a/CLre_server/API/MainServer/ServerEngines.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using CLre_server.API.Engines; -using Game.DataLoader; -using GameServer; -using HarmonyLib; -using Svelto.Context; -using Svelto.DataStructures; -using Svelto.ECS; -using User.Server; - -namespace CLre_server.API.MainServer -{ - class ServerReadyEngine : ServerEnginePostBuild, IWaitForFrameworkInitialization, IWaitForFrameworkDestruction - { - internal static event EventHandler serverEngineReady; - - internal static event EventHandler serverFrameworkReady; - - internal static event EventHandler serverFrameworkDestroyed; - - public override void Ready() - { - GameServerSettings gss = Server.Instance.GameServerSettings; - if (serverEngineReady != null) serverEngineReady(this, new StartedEventArgs - { - photonVersion = PhotonNetwork.gameVersion, - photonRegion = PhotonNetwork.CloudRegion, - gameGuid = gss == null ? "" : gss.GetGameGuid(), - worldName = gss == null ? "" : gss.GetWorldName(), - }); - } - - public void OnFrameworkInitialized() - { - GameServerSettings gss = Server.Instance.GameServerSettings; - if (serverFrameworkReady != null) serverFrameworkReady(this, new StartedEventArgs - { - photonVersion = PhotonNetwork.gameVersion, - photonRegion = PhotonNetwork.CloudRegion, - gameGuid = gss == null ? "" : gss.GetGameGuid(), - worldName = gss == null ? "" : gss.GetWorldName(), - }); - } - - public void OnFrameworkDestroyed() - { - if (serverFrameworkDestroyed != null) serverFrameworkDestroyed(this, new StopEventArgs{}); - } - } - - class ServerDatabaseQueryEngine : ServerEnginePostBuild - { - public override void Ready() - { - } - - public AccountIdServerNode[] GetConnectedAccounts() - { - FieldInfo f = AccessTools.Field(AccessTools.TypeByName("User.Server.AccountExclusiveGroups"), "accountGroup"); - ExclusiveGroup accountGroup = (ExclusiveGroup) f.GetValue(null); - ReadOnlyCollectionStruct accounts = - entitiesDB.QueryEntityViews(accountGroup); - List list = new List(); - foreach (var a in accounts) - { - list.Add(a); - } - return list.ToArray(); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/MainServer/ServerEventArgs.cs b/CLre_server/API/MainServer/ServerEventArgs.cs deleted file mode 100644 index 7103640..0000000 --- a/CLre_server/API/MainServer/ServerEventArgs.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace CLre_server.API.MainServer -{ - public struct StartingEventArgs{} - - public struct StartedEventArgs - { - public string photonVersion; - public CloudRegionCode photonRegion; - public string worldName; - public string gameGuid; - } - - public struct StopEventArgs{} - - public struct PlayerConnectArgs - { - public int PlayerId; - } -} \ No newline at end of file diff --git a/CLre_server/API/MainServer/UserVerification.cs b/CLre_server/API/MainServer/UserVerification.cs deleted file mode 100644 index b2cbf62..0000000 --- a/CLre_server/API/MainServer/UserVerification.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Reflection; -using GameNetworkLayer.Shared; -using HarmonyLib; -using Svelto.Context; -using Svelto.ECS; - -namespace CLre_server.API.MainServer -{ - public class UserVerification - { - public static UserVerification Instance { get; internal set; } - - private delegate void DisconnectPlayer_VerificationFailedProto(int playerId, string error); - private delegate void DisconnectPlayerProto(int playerId, NetworkDispatcherCode code); - - private readonly DisconnectPlayer_VerificationFailedProto _disconnectPlayerVerificationFailed; - private readonly DisconnectPlayerProto _disconnectPlayer; - - // This doesn't seem to do actually generate a popup, but it will stop the player from loading in - /*public void DisconnectPlayer_VerificationFailed(int playerId, string error) - { - _disconnectPlayerVerificationFailed(playerId, error); - }*/ - - public void DisconnectPlayer(int playerId, NetworkDispatcherCode code = NetworkDispatcherCode.ModVerificationFail) - { - _disconnectPlayer(playerId, code); - } - - internal UserVerification(IQueryingEntitiesEngine uvs) - { - Type uvsType = AccessTools.TypeByName("User.Server.UserVerificationServer"); - _disconnectPlayerVerificationFailed = - Utility.Reflection.MethodAsDelegate(uvsType, - "DisconnectPlayer_VerificationFailed", - //parameters: new [] {typeof(int), typeof(string)}, - instance: uvs); - - _disconnectPlayer = - Utility.Reflection.MethodAsDelegate(uvsType, "DisconnectPlayer", instance: uvs); - } - } - - // This seems to think that __instance is always simply a System.Object (caused by Harmony?), which doesn't work - /*[HarmonyPatch] - class UserVerificationServer_Constructor_Patch - { - - private static IQueryingEntitiesEngine uvs = null; - - [HarmonyPrefix] - public static void BeforeMethodCall() - { - } - - [HarmonyPostfix] - public static void AfterMethodCall(IQueryingEntitiesEngine __instance) - { - uvs = __instance; - UserVerification.Instance = new UserVerification(__instance); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Constructor(AccessTools.TypeByName("User.Server.UserVerificationServer")); - } - }*/ - - [HarmonyPatch] - class MainGameServer_CreatePlayerDisconnectionSequence_Patch - { - - private static IQueryingEntitiesEngine uvs = null; - - [HarmonyPrefix] - public static void BeforeMethodCall() - { - } - - [HarmonyPostfix] - public static void AfterMethodCall(IQueryingEntitiesEngine userVerificationEng) - { - uvs = userVerificationEng; - UserVerification.Instance = new UserVerification(userVerificationEng); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameServer.GameFramework.MainGameServer:CreatePlayerDisconnectionSequence"); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/CLreEnforcer.cs b/CLre_server/API/Synergy/CLreEnforcer.cs deleted file mode 100644 index 6dc28ad..0000000 --- a/CLre_server/API/Synergy/CLreEnforcer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections; -using UnityEngine; - -namespace CLre_server.API.Synergy -{ - internal static class CLreEnforcer - { - private const float _waitTime = 10.0f; - - public static IEnumerator WaitABitForHandshakeThenKick(int playerId) - { - float elapsedTime = 0.0f; - while (elapsedTime < _waitTime) - { - yield return null; - elapsedTime += Time.deltaTime; - } - yield return null; - if (Clients.IsConnected(playerId) && !Clients.IsCLreClient(playerId)) - { - MainServer.UserVerification.Instance.DisconnectPlayer(playerId); - } - } - - internal static void Init() - { - if (CLre_server.CLre.Config.clre_clients_only) - { - MainServer.Server.Instance.PlayerConnect += (_, playerData) => - { - WaitABitForHandshakeThenKick(playerData.PlayerId).Run(); - }; - } - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/Clients.cs b/CLre_server/API/Synergy/Clients.cs deleted file mode 100644 index 635b341..0000000 --- a/CLre_server/API/Synergy/Clients.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; - -namespace CLre_server.API.Synergy -{ - public static class Clients - { - private static readonly List clrePlayers = new List(); - private static readonly List players = new List(); - - internal static void RegisterCLreClient(int playerId) - { - clrePlayers.Add(playerId); - } - - internal static void RegisterClient(int playerId) - { - players.Add(playerId); - } - - internal static void RemoveClient(int playerId) - { - if (IsCLreClient(playerId)) - { - clrePlayers.Remove(playerId); - } - players.Remove(playerId); - } - - public static bool IsCLreClient(int playerId) - { - return clrePlayers.Contains(playerId); - } - - public static bool IsConnected(int playerId) - { - return players.Contains(playerId); - } - - public static IEnumerator CLreClients() - { - return clrePlayers.GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/Message.cs b/CLre_server/API/Synergy/Message.cs deleted file mode 100644 index 0f4b273..0000000 --- a/CLre_server/API/Synergy/Message.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using GameNetworkLayer.Shared; - -namespace CLre_server.API.Synergy -{ - public static class Message - { - internal const NetworkDispatcherCode CLre_MESSAGE_NETCODE = (NetworkDispatcherCode) 219; - - private static readonly Dictionary> handlers = - new Dictionary>(); - - private static readonly ServerMessagingEngine msgEngine = new ServerMessagingEngine(); - - private static readonly List clrePlayers = new List(); - - public static void SendToAllCLreClients(ref SerializedCLreMessage message) - { - foreach (var playerId in clrePlayers) - { - SendCLreMessage(playerId, ref message); - } - } - - public static void SendCLreMessage(int playerId, ref SerializedCLreMessage message) - { - msgEngine.EnqueueMessage(playerId, ref message); - } - - public static void RegisterListener(uint id, Action handler) - { - if (handlers.TryGetValue(id, out Action existing)) - { - existing += handler; - handlers[id] = existing; - } - else - { - handlers[id] = handler; - } - } - - internal static void HandleMessageReceive(int playerId, ref SerializedCLreMessage msg) - { - ReceiveMessageArgs payload = new ReceiveMessageArgs - { - Message = msg, - PlayerId = playerId, - }; - if (handlers.TryGetValue(msg.Id, out Action h)) - { - h(payload); - } - } - } - - public struct ReceiveMessageArgs - { - public SerializedCLreMessage Message; - public int PlayerId; - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/SerializedCLreHandshake.cs b/CLre_server/API/Synergy/SerializedCLreHandshake.cs deleted file mode 100644 index 0c20669..0000000 --- a/CLre_server/API/Synergy/SerializedCLreHandshake.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using NetworkFramework.Shared; - -namespace CLre_server.API.Synergy -{ - struct SerializedCLreHandshake: ISerializedNetData - { - private byte major; - private byte minor; - private byte patch; - - private HandshakeFlag flags; - - private List modInfo; - - public Version Version - { - get => new Version(major, minor, patch); - set - { - major = (byte)value.Major; - minor = (byte)value.Minor; - patch = (byte)value.Build; - } - } - - public IEnumerable Mods - { - get => modInfo.ToArray(); - set - { - modInfo.Clear(); - foreach (var mod in value) - { - modInfo.Add(mod); - } - } - } - - public byte[] Serialize() - { - using (MemoryStream stream = new MemoryStream()) - { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - // version - writer.Write(major); - writer.Write(minor); - writer.Write(patch); - writer.Write((uint)flags); - writer.Write(modInfo.Count); - foreach (string mod in modInfo) - { - writer.Write(mod); - } - return stream.ToArray(); - } - } - } - - public void Deserialize(byte[] data) - { - using (MemoryStream stream = new MemoryStream(data)) - { - using (BinaryReader reader = new BinaryReader(stream)) - { - // version - major = reader.ReadByte(); - minor = reader.ReadByte(); - patch = reader.ReadByte(); - flags = (HandshakeFlag) reader.ReadUInt32(); - int modCount = reader.ReadInt32(); - modInfo = new List(modCount); - for (int i = 0; i < modCount; i++) - { - modInfo.Add(reader.ReadString()); - } - } - } - } - - public bool HasFlag(HandshakeFlag f) - { - return (flags & f) != HandshakeFlag.None; - } - - public void SetFlag(HandshakeFlag f) - { - flags |= f; - } - - public void UnsetFlag(HandshakeFlag f) - { - flags &= ~f; - } - - public static SerializedCLreHandshake Current() - { - Version v = Assembly.GetExecutingAssembly().GetName().Version; - List mods = new List(); - foreach (var plugin in IllusionInjector.PluginManager.Plugins) - { - mods.Add(plugin.Name); - } - - return new SerializedCLreHandshake - { - major = (byte) v.Major, - minor = (byte) v.Minor, - patch = (byte) v.Build, - flags = HandshakeFlag.Server, - modInfo = mods, - }; - } - - public static SerializedCLreHandshake RequireCLre() - { - Version v = Assembly.GetExecutingAssembly().GetName().Version; - List mods = new List(new []{Assembly.GetExecutingAssembly().GetName().Name}); - - return new SerializedCLreHandshake - { - major = (byte) v.Major, - minor = (byte) v.Minor, - patch = (byte) v.Build, - flags = HandshakeFlag.Client | HandshakeFlag.RequireAll, - modInfo = mods, - }; - } - - public static SerializedCLreHandshake Empty() - { - return new SerializedCLreHandshake - { - major = 0, - minor = 0, - patch = 0, - modInfo = new List(), - }; - } - - public override string ToString() - { - return $"CLre {Version} ({modInfo.Count} mods)"; - } - } - - [Flags] - enum HandshakeFlag : uint - { - None = 0, - Client = 1, - Server = 1 << 1, - RequireAll = 1 << 2, - OptionalAll = 1 << 3, - Confirm = 1 << 4, - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/SerializedCLreMessage.cs b/CLre_server/API/Synergy/SerializedCLreMessage.cs deleted file mode 100644 index 325285d..0000000 --- a/CLre_server/API/Synergy/SerializedCLreMessage.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.IO; -using NetworkFramework.Shared; - -namespace CLre_server.API.Synergy -{ - public struct SerializedCLreMessage: ISerializedNetData - { - public uint Id; - public byte[] Data; - - public byte[] Serialize() - { - using (MemoryStream stream = new MemoryStream()) - { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(Id); - writer.Write(Data.Length); - foreach (byte b in Data) - { - writer.Write(b); - } - return stream.ToArray(); - } - } - } - - public void Deserialize(byte[] data) - { - using (MemoryStream stream = new MemoryStream(data)) - { - using (BinaryReader reader = new BinaryReader(stream)) - { - Id = reader.ReadUInt32(); - Data = new byte[reader.ReadInt32()]; - for (int i = 0; i < Data.Length; i++) - { - Data[i] = reader.ReadByte(); - } - } - } - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/ServerHandshakeEngine.cs b/CLre_server/API/Synergy/ServerHandshakeEngine.cs deleted file mode 100644 index eccb155..0000000 --- a/CLre_server/API/Synergy/ServerHandshakeEngine.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Collections; -using System.Linq; -using GameNetworkLayer.Shared; -using HarmonyLib; -using Svelto.ECS; - -namespace CLre_server.API.Synergy -{ - class ServerHandshakeEngine : Engines.ServerEnginePreBuild - { - internal static ServerHandshakeEngine Instance = null; - - internal const NetworkDispatcherCode CLre_HANDSHAKE_NETCODE = (NetworkDispatcherCode) 218; - - private Utility.Reflection.INetMsgServerSender_SendMessage _sendMessage; - - private Utility.Reflection.INetMsgServerListener_RegisterListener _registerListener; - - public override void Ready() - { - Utility.Logging.MetaLog("Building send message delegate"); - _sendMessage = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Server.NetMessageServerSender:SendMessage", - generics: new [] {typeof(SerializedCLreHandshake)}, - instance: MainGameServer_SetupContainer_Patch.netMessageSender); - - Utility.Logging.MetaLog("Building register listener delegate"); - _registerListener = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Server.NetMessageServerListener:RegisterListener", - generics: new [] {typeof(SerializedCLreHandshake)}, - instance: MainGameServer_SetupContainer_Patch.netMessageListener); - _registerListener(CLre_HANDSHAKE_NETCODE, OnHandshakeReceived); - } - - public void OnHandshakeReceived(int playerId, ref SerializedCLreHandshake p) - { - // validate handshake msg - if (!(p.HasFlag(HandshakeFlag.Client) - || p.Mods.Contains("CLre"))) - { - Utility.Logging.LogWarning($"Received invalid CLre handshake from player {playerId}! {p}"); - return; - } - Utility.Logging.MetaLog($"Received CLre handshake from player {playerId}! {p}"); - Clients.RegisterCLreClient(playerId); - SerializedCLreHandshake payload = SerializedCLreHandshake.Current(); - payload.SetFlag(HandshakeFlag.Confirm); - Sender(payload, playerId).Run(); - } - - public IEnumerator Sender(SerializedCLreHandshake payload, int playerId) - { - yield return null; - Utility.Logging.MetaLog("Sending Server CLre handshake"); - _sendMessage(CLre_HANDSHAKE_NETCODE, ref payload, playerId); - yield return null; - } - - internal static void Init() - { - Instance = new ServerHandshakeEngine(); - } - } - - [HarmonyPatch(typeof(GameServer.GameFramework.MainGameServer), "SetupContainer")] - class MainGameServer_SetupContainer_Patch - { - internal static object netMessageListener; - - internal static object netMessageSender; - - [HarmonyPostfix] - public static void AfterMethodCall(object ____netMessageListener, object ____netMessageSender) - { - Utility.Logging.MetaLog($"Got NetMessage objects"); - netMessageListener = ____netMessageListener; - netMessageSender = ____netMessageSender; - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/ServerMessagingEngine.cs b/CLre_server/API/Synergy/ServerMessagingEngine.cs deleted file mode 100644 index 8dd863d..0000000 --- a/CLre_server/API/Synergy/ServerMessagingEngine.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using GameNetworkLayer.Shared; -using Svelto.Context; -using Svelto.ECS; - -namespace CLre_server.API.Synergy -{ - class ServerMessagingEngine: Engines.ServerEnginePreBuild, IWaitForFrameworkDestruction, IWaitForFrameworkInitialization - { - private struct MessageQueueItem - { - public SerializedCLreMessage msg; - public int playerId; - public NetworkDispatcherCode code; - } - - private Utility.Reflection.INetMsgServerSender_SendMessage _sendMessage; - - private Utility.Reflection.INetMsgServerListener_RegisterListener _registerListener; - - private Queue _messageQueue = new Queue(10); - - private bool _isRunning = false; - - public override void Ready() - { - //Utility.Logging.MetaLog("Building send message delegate"); - _sendMessage = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Server.NetMessageServerSender:SendMessage", - generics: new [] {typeof(SerializedCLreMessage)}, - instance: MainGameServer_SetupContainer_Patch.netMessageSender); - - //Utility.Logging.MetaLog("Building register listener delegate"); - _registerListener = - Utility.Reflection.MethodAsDelegate>( - "GameNetworkLayer.Server.NetMessageServerListener:RegisterListener", - generics: new [] {typeof(SerializedCLreMessage)}, - instance: MainGameServer_SetupContainer_Patch.netMessageListener); - _registerListener(Message.CLre_MESSAGE_NETCODE, OnMessageReceived); - } - - private void OnMessageReceived(int playerId, ref SerializedCLreMessage data) - { - Message.HandleMessageReceive(playerId, ref data); - } - - internal void EnqueueMessage(int playerId, ref SerializedCLreMessage msg) - { - _messageQueue.Enqueue(new MessageQueueItem - { - msg = msg, - playerId = playerId, - code = Message.CLre_MESSAGE_NETCODE, - }); - } - - public ServerMessagingEngine(): base() - { - MainServer.Server.Instance.Connected += (_, __) => { MessageSender().Run(); }; - } - - public IEnumerator MessageSender() - { - while (!_isRunning) - { - yield return null; - } - while (_isRunning) - { - while (_messageQueue.Count != 0) - { - MessageQueueItem item = _messageQueue.Dequeue(); - API.Utility.Logging.MetaLog($"Sending message with id {item.msg.Id}"); - _sendMessage(item.code, ref item.msg, item.playerId); - } - - yield return null; - } - } - - public void OnFrameworkDestroyed() - { - _isRunning = false; - } - - public void OnFrameworkInitialized() - { - _isRunning = true; - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Synergy/Tweaks/SerializedCLreTerrainModifyRejection.cs b/CLre_server/API/Synergy/Tweaks/SerializedCLreTerrainModifyRejection.cs deleted file mode 100644 index b4c4ea3..0000000 --- a/CLre_server/API/Synergy/Tweaks/SerializedCLreTerrainModifyRejection.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.IO; -using System.Runtime.CompilerServices; -using Game.Handhelds; -using NetworkFramework.Shared; -using UnityEngine; - -namespace CLre_server.API.Synergy.Tweaks -{ - public struct SerializedCLreTerrainModifyRejection: ISerializedNetData - { - public RejectionFlag Flags; - - public uint resourceId; - - public Vector3 hit; - - public string toolKey; - - public ToolModeType toolMode; - - public byte[] Serialize() - { - using (MemoryStream stream = new MemoryStream()) - { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write((byte)Flags); - writer.Write(resourceId); - writer.Write(hit.x); - writer.Write(hit.y); - writer.Write(hit.z); - writer.Write(toolKey); - writer.Write((byte)toolMode); - return stream.ToArray(); - } - } - } - - public void Deserialize(byte[] data) - { - using (MemoryStream stream = new MemoryStream(data)) - { - using (BinaryReader reader = new BinaryReader(stream)) - { - Flags = (RejectionFlag)reader.ReadByte(); - resourceId = reader.ReadUInt32(); - float x = reader.ReadSingle(); - float y = reader.ReadSingle(); - float z = reader.ReadSingle(); - hit = new Vector3(x, y, z); - toolKey = reader.ReadString(); - toolMode = (ToolModeType)reader.ReadByte(); - } - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Ok() - { - return (Flags & RejectionFlag.Rejection) == RejectionFlag.None; - } - } - - [Flags] - public enum RejectionFlag : byte - { - None = 0, - Rejection = 1, - Proximity = 1 << 1, - Permission = 1 << 2, - AccountNotFound = 1 << 3, - InitError = 1 << 4, - } -} diff --git a/CLre_server/API/Tools/AccessToolsWarnings.cs b/CLre_server/API/Tools/AccessToolsWarnings.cs deleted file mode 100644 index 2eb1384..0000000 --- a/CLre_server/API/Tools/AccessToolsWarnings.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Diagnostics; -using System.Reflection; -using HarmonyLib; - -#if DEBUG -namespace CLre_server.API.Tools -{ - public static class AccessToolsWarnings - { - internal static bool isEnabled = false; - - public static void Enable() - { - isEnabled = true; - } - - public static void Disable() - { - isEnabled = false; - } - } - - [HarmonyPatch(typeof(AccessTools), "TypeByName")] - class AccessTools_TypeByName_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(Type __result, string name) - { - if (!AccessToolsWarnings.isEnabled) return; - if (__result == null) - { - var method = (new StackTrace()).GetFrame(2).GetMethod(); - Utility.Logging.LogWarning($"[{method.DeclaringType.FullName}.{method.Name}] AccessTools.TypeByName(\"{name}\") returned null result"); - } - } - } - - [HarmonyPatch(typeof(AccessTools), "Method", - new Type[] {typeof(string), typeof(Type[]), typeof(Type[])})] - class AccessTools_Method_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(MethodInfo __result, string typeColonMethodname) - { - if (!AccessToolsWarnings.isEnabled) return; - if (__result == null) - { - var method = (new StackTrace()).GetFrame(2).GetMethod(); - Utility.Logging.LogWarning($"[{method.DeclaringType.FullName}.{method.Name}] AccessTools.Method(\"{typeColonMethodname}\") returned null result"); - } - } - } - - [HarmonyPatch(typeof(AccessTools), "Method", - new Type[] {typeof(Type), typeof(string), typeof(Type[]), typeof(Type[])})] - class AccessTools_Method2_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(MethodInfo __result, Type type, string name) - { - if (!AccessToolsWarnings.isEnabled) return; - if (__result == null) - { - var method = (new StackTrace()).GetFrame(2).GetMethod(); - Utility.Logging.LogWarning($"[{method.DeclaringType.FullName}.{method.Name}] AccessTools.Method(\"{type}\", \"{name}\") returned null result"); - } - } - } -} -#endif \ No newline at end of file diff --git a/CLre_server/API/Tools/NetServerListener.cs b/CLre_server/API/Tools/NetServerListener.cs deleted file mode 100644 index 0fe381c..0000000 --- a/CLre_server/API/Tools/NetServerListener.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Reflection; -using System.Text; -using GameNetworkLayer.Shared; -using HarmonyLib; -using Svelto.DataStructures; -using Svelto.DataStructures.Experimental; - -namespace CLre_server.API.Tools -{ - public class NetServerListener - { - internal static bool isEnabled = false; - - private static FasterDictionary> callbacks = new FasterDictionary>(); - - public delegate void NetReceiveMessageCallback(NetworkDispatcherCode code, byte[] data, int playerId); - - public static void Enable() - { - isEnabled = true; - } - - public static void Disable() - { - isEnabled = false; - } - - public static void DebugReceiveMessage(NetworkDispatcherCode code, NetReceiveMessageCallback callback) - { - short key = (short)code; - if (callbacks.TryGetValue(key, out FasterList handlers)) - { - handlers.Add(callback); - } - else - { - FasterList newHandlers = new FasterList(new [] {callback}); - callbacks.Add(key, newHandlers); - } - } - - internal static bool RunDebugCallbacks(NetworkDispatcherCode code, byte[] data, int playerId) - { - short key = (short)code; - if (callbacks.TryGetValue(key, out FasterList handlers)) - { - foreach (NetReceiveMessageCallback callback in handlers) - { - callback(code, data, playerId); - } - - return true; - } - else - { - return false; - } - } - - public static void Log(NetworkDispatcherCode code, byte[] data, int playerId) - { - StringBuilder sb = new StringBuilder("Received "); - sb.Append(code.ToString()); - sb.Append(" for player #"); - sb.Append(playerId); - sb.Append(": 0x"); - foreach (byte b in data) - { - sb.Append(b.ToString("X")); - } - Utility.Logging.Log(sb.ToString()); - } - } - - [HarmonyPatch] - class NetMessageClientListener_HandleAllMessages_Patch - { - [HarmonyPrefix] - public static void BeforeMethodCall(object ____deserializer, int playerId, object value) - { - if (!NetServerListener.isEnabled) return; - // TODO optimize this to not use Traverse - Traverse result = Traverse.Create(____deserializer).Method("Deserialize", value); - NetworkDispatcherCode code = result.Field("dispatcherCode").Value; - byte[] data = result.Field("bytes").Value; - if (data == null) - { - Utility.Logging.LogWarning("Network message data was deserialized as null"); - return; - } - bool isHandled = NetServerListener.RunDebugCallbacks(code, data, playerId); - if (!isHandled) Utility.Logging.Log($"Received network message for player {playerId} (code: {code.ToString()}, len: {data.Length})"); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameNetworkLayer.Server.NetMessageServerListener:HandleAllMessages"); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Tools/NetServerSender.cs b/CLre_server/API/Tools/NetServerSender.cs deleted file mode 100644 index f4633a6..0000000 --- a/CLre_server/API/Tools/NetServerSender.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Reflection; -using System.Text; -using GameNetworkLayer.Shared; -using HarmonyLib; -using NetworkFramework.Shared; - -namespace CLre_server.API.Tools -{ - public class NetServerSender - { - private struct DummyNetDataStruct : ISerializedNetData - { - public byte[] Serialize() - { - return new byte[0]; - } - - public void Deserialize(byte[] data) - { - } - } - - private static readonly MethodInfo _genericSendMessage = AccessTools.Method("GameNetworkLayer.Server.NetMessageServerSender:SendMessage"); - - private static readonly MethodInfo _genericGetSendMessageMethod = - AccessTools.Method(typeof(NetServerSender), "GetSendMessageMethod",parameters: new Type[0]);/* - /*((Func) GetSendMessageMethod).Method - .GetBaseDefinition() - .GetGenericMethodDefinition();*/ - - private static readonly MethodInfo _genericLog = - AccessTools.Method(typeof(NetServerSender), "Log");/* - ((Action) Log).Method - .GetBaseDefinition() - .GetGenericMethodDefinition();*/ - - private static readonly MethodInfo _genericGetLogMethod = - AccessTools.Method(typeof(NetServerSender), "GetLogMethod", new Type[0]);/* - ((Func) GetLogMethod).Method - .GetBaseDefinition() - .GetGenericMethodDefinition();*/ - - public static MethodInfo GetSendMessageMethod(Type t) - { - return (MethodInfo) _genericGetSendMessageMethod.MakeGenericMethod(t) - .Invoke(null, new object[0]); - } - - public static MethodInfo GetSendMessageMethod() where T : struct, ISerializedNetData - { - return _genericSendMessage.MakeGenericMethod(typeof(T)); - } - - public static MethodInfo DebugSendMessage(Harmony instance = null, MethodInfo before = null, MethodInfo after = null, MethodInfo transpiler = null, MethodInfo finalizer = null) where T : struct, ISerializedNetData - { - return DebugSendMessage(typeof(T), instance, before, after, transpiler, finalizer); - } - - public static MethodInfo DebugSendMessage(Type generic, Harmony instance = null, MethodInfo before = null, MethodInfo after = null, MethodInfo transpiler = null, MethodInfo finalizer = null) - { - return DebugSendMessage( - generic, instance, - before == null ? null : new HarmonyMethod(before), - after == null ? null : new HarmonyMethod(after), - transpiler == null ? null : new HarmonyMethod(transpiler), - finalizer == null ? null : new HarmonyMethod(finalizer)); - } - - public static MethodInfo DebugSendMessage(Harmony instance = null, HarmonyMethod before = null, HarmonyMethod after = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null) where T : struct, ISerializedNetData - { - return DebugSendMessage(typeof(T), instance, before, after, transpiler, finalizer); - } - - public static MethodInfo DebugSendMessage(Type generic, Harmony instance = null, HarmonyMethod before = null, HarmonyMethod after = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null) - { - if (instance == null) instance = CLre.harmonyInstance; - MethodInfo target = GetSendMessageMethod(generic); - return instance.Patch(target, - before, - after, - transpiler, - finalizer); - } - - public static MethodInfo GetLogMethod(Type t) - { - return (MethodInfo) _genericGetLogMethod.MakeGenericMethod(t) - .Invoke(null, new object[0]); - } - - public static MethodInfo GetLogMethod() where T : struct, ISerializedNetData - { - return _genericLog.MakeGenericMethod(typeof(T)); - } - - private static void Log(NetworkDispatcherCode code, ref T data) where T : struct, ISerializedNetData - { - //Utility.Logging.Log($"Sending ISerializedNetData {data.GetType().FullName} (code: {code.ToString()})"); - Traverse d = Traverse.Create(data); - string codeName = (short) code > 217 ? "CUSTOM" : code.ToString(); - StringBuilder sb = new StringBuilder($"Sending ISerializedNetData {data.GetType().FullName} (code: {codeName} {(short)code})"); - foreach (string fieldName in d.Fields()) - { - Traverse field = d.Field(fieldName); - sb.Append("\n"); - sb.Append("\""); - int start = fieldName.IndexOf('<'); - int len = fieldName.LastIndexOf('>'); - if (start != -1 && len > 0) - { - sb.Append(fieldName.Substring(start+1, len-1)); - } - else - { - sb.Append(fieldName); - } - sb.Append("\": "); - sb.Append(field.GetValue()); - } - Utility.Logging.Log(sb.ToString()); - } - } -} \ No newline at end of file diff --git a/CLre_server/API/Utility/CardLifeUserAuthentication.cs b/CLre_server/API/Utility/CardLifeUserAuthentication.cs deleted file mode 100644 index 11baf6a..0000000 --- a/CLre_server/API/Utility/CardLifeUserAuthentication.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using UnityEngine; -using UnityEngine.Networking; - -namespace CLre_server.API.Utility -{ - public static class CardLifeUserAuthentication - { - [Serializable] - private struct AuthPayload - { - public string EmailAddress; - public string Password; - } - - private const string LOGIN_URL = "https://live-auth.cardlifegame.com/api/auth/authenticate"; - - public delegate void OnResponse(AuthenticationResponse data); - - public static IEnumerator Authenticate(string email, string password, OnResponse then) - { - UnityWebRequest req = new UnityWebRequest(LOGIN_URL, "POST"); - AuthPayload payload = new AuthPayload - { - EmailAddress = email, - Password = password, - }; - byte[] bytes = Encoding.UTF8.GetBytes(JsonUtility.ToJson(payload)); - req.uploadHandler = new UploadHandlerRaw(bytes); - req.downloadHandler = new DownloadHandlerBuffer(); - req.SetRequestHeader("Content-Type", "application/json"); - AsyncOperation op = req.SendWebRequest(); - while (!op.isDone) - { - yield return null; - } - - if (req.responseCode != 200) - { - Logging.LogError($"Authentication with email {email} returned code {req.responseCode} and was aborted. Response:\n{req.downloadHandler.text}"); - yield break; - } - - AuthenticationResponse resp = JsonUtility.FromJson(req.downloadHandler.text); - then(resp); - } - } - - [Serializable] - public struct AuthenticationResponse - { - public string PublicId; - public string EmailAddress; - public string DisplayName; - public bool Confirmed; - public string Token; - public uint ID; - } -} \ No newline at end of file diff --git a/CLre_server/API/Utility/Logging.cs b/CLre_server/API/Utility/Logging.cs deleted file mode 100644 index b5e3e43..0000000 --- a/CLre_server/API/Utility/Logging.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Diagnostics; - -namespace CLre_server.API.Utility -{ - /// - /// Utility class to access Cardlife's built-in logging capabilities. - /// The log is saved to outputLog#.Log - /// - public static class Logging - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Log(string msg) - { - Svelto.Console.Log(msg); - } - - /// - /// Write a regular message to Cardlife's log - /// - /// The object to log - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Log(object obj) - { - Svelto.Console.Log(obj.ToString()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogError(string msg, Dictionary extraData = null) - { - Svelto.Console.LogError(msg, extraData); - } - - /// - /// Write an error message to Cardlife's log - /// - /// The object to log - /// The extra data to pass to the ILogger - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogError(object obj, Dictionary extraData = null) - { - Svelto.Console.LogError(obj.ToString(), extraData); - } - - /// - /// Write an exception to Cardlife's log and to the screen and exit game - /// - /// The exception to log - /// The extra data to pass to the ILogger. - /// This is automatically populated with "OuterException#" and "OuterStacktrace#" entries - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogException(Exception e, string msg = null, Dictionary extraData = null) - { - Svelto.Console.LogException(msg, e, extraData); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogWarning(string msg) - { - Svelto.Console.LogWarning(msg); - } - - /// - /// Write a warning message to Cardlife's log - /// - /// The object to log - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void LogWarning(object obj) - { - Svelto.Console.LogWarning(obj.ToString()); - } - - // descriptive logging - - /// - /// Write a descriptive message to Cardlife's log including the calling method's name - /// - /// The object to log - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void MetaLog(object obj) - { - var method = (new StackTrace()).GetFrame(1).GetMethod(); - Log($"[{method.DeclaringType.FullName}.{method.Name}] {obj.ToString()}"); - } - } -} diff --git a/CLre_server/API/Utility/Reflection.cs b/CLre_server/API/Utility/Reflection.cs deleted file mode 100644 index b9fe7cb..0000000 --- a/CLre_server/API/Utility/Reflection.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using Game.DataLoader; -using GameNetworkLayer.Shared; -using HarmonyLib; -using NetworkFramework.Shared; -using Svelto.DataStructures; -using Svelto.ECS; - -namespace CLre_server.API.Utility -{ - public static class Reflection - { - // useful function & method prototypes - public delegate T Getter(); - - public delegate bool ExistsV1(EGID egid); - - public delegate bool ExistsV2(int id, int groupid); - - public delegate T QueryEntityViewV1(EGID egid); - - public delegate T QueryEntityViewV2(int id, ExclusiveGroup.ExclusiveGroupStruct groupid); - - public delegate ReadOnlyCollectionStruct QueryEntityViews(int group) where T : class, IEntityViewStruct; - - public delegate T[] QueryEntitiesV2(int group, out int count) where T : IEntityStruct; - - public delegate T[] QueryEntitiesV1(ExclusiveGroup.ExclusiveGroupStruct group, out int count) where T : IEntityStruct; - - public delegate object[] SendMessage(NetworkDispatcherCode dispatcherCode, ref T value) where T : struct, ISerializedNetData; - - public delegate void INetMsgServerSender_SendMessage(NetworkDispatcherCode code, ref T value, int playerId) where T : struct, ISerializedNetData; - - public delegate void INetMsgServerListener_RegisterListener(NetworkDispatcherCode code, NetCBServer proc) where T: struct, ISerializedNetData; - - public delegate Dictionary IDataDB_GetValues(); - - // useful reflection functions - public static TFuncProto BuildDelegate(MethodInfo method) where TFuncProto : Delegate - { - return (TFuncProto) Delegate.CreateDelegate(typeof(TFuncProto), method); - } - - public static Delegate BuildDelegateRaw(MethodInfo method, Type TFuncProto) - { - return Delegate.CreateDelegate(TFuncProto, method); - } - - public static TFuncProto BuildDelegate(MethodInfo method, object instance) where TFuncProto : Delegate - { - return (TFuncProto) Delegate.CreateDelegate(typeof(TFuncProto), instance, method, true); - } - - public static Delegate BuildDelegateRaw(MethodInfo method, object instance, Type TFuncProto) - { - return Delegate.CreateDelegate(TFuncProto, instance, method, true); - } - - public static TFuncProto MethodAsDelegate(Type class_, string methodName, Type[] parameters = null, Type[] generics = null, object instance = null) where TFuncProto : Delegate - { - MethodInfo method = AccessTools.Method(class_, methodName, parameters, generics); - if (instance != null) - { - return BuildDelegate(method, instance); - } - return BuildDelegate(method); - } - - public static Delegate MethodAsDelegateRaw(Type class_, Type TFuncProto, string methodName, Type[] parameters = null, Type[] generics = null, object instance = null) - { - MethodInfo method = AccessTools.Method(class_, methodName, parameters, generics); - if (instance != null) - { - return BuildDelegateRaw(method, instance, TFuncProto); - } - return BuildDelegateRaw(method, TFuncProto); - } - - public static TFuncProto MethodAsDelegate(string typeColonName, Type[] parameters = null, Type[] generics = null, object instance = null) where TFuncProto : Delegate - { - MethodInfo method = AccessTools.Method(typeColonName, parameters, generics); - if (instance != null) - { - return BuildDelegate(method, instance); - } - return BuildDelegate(method); - } - - public static Delegate MethodAsDelegateRaw(string typeColonName, Type TFuncProto, Type[] parameters = null, Type[] generics = null, object instance = null) - { - MethodInfo method = AccessTools.Method(typeColonName, parameters, generics); - if (instance != null) - { - return BuildDelegateRaw(method, instance, TFuncProto); - } - return BuildDelegateRaw(method, TFuncProto); - } - - public static PropertyInfo GetIndexer(this Type type, Type[] arguments = null, BindingFlags bindingFlags = BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.Static) - { - foreach (PropertyInfo p in type.GetProperties(bindingFlags)) - { - if (arguments == null && p.GetIndexParameters().Length != 0) return p; - if (arguments != null) - { - uint count = 0; - foreach (ParameterInfo param in p.GetIndexParameters()) - { - if (param.ParameterType != arguments[count]) - { - break; - } - - count++; - } - if (count == arguments.Length) - { - return p; - } - } - } - return null; - } - } -} \ No newline at end of file diff --git a/CLre_server/CLre_server.cs b/CLre_server/CLre_server.cs deleted file mode 100644 index 43fadee..0000000 --- a/CLre_server/CLre_server.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using CLre_server.API.Config; -using CLre_server.API.Tools; -using CLre_server.WebStatus; -using GameNetworkLayer.Shared; -using HarmonyLib; -using Svelto.ECS; -using UnityEngine; - -namespace CLre_server -{ - public class CLre : IllusionPlugin.IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin - { - public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; - - public override string Version { get; } = "21Q3 " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); - - internal static Harmony harmonyInstance = null; - - private const string CONFIG_PATH = "CLre_server.json"; - - public static CLreConfig Config = CLreConfig.Default(); - - public static CLre Instance = null; - - // called when Cardlife shuts down - public override void OnApplicationQuit() - { - Config.ToFile(CONFIG_PATH); - WebServer.Deinit(); - harmonyInstance.UnpatchAll(); - } - - // called when Cardlife starts up - public override void OnApplicationStart() - { - Instance = this; -#if DEBUG - FileLog.Reset(); - Harmony.DEBUG = true; - // enable CLre debug functionality - AccessToolsWarnings.Enable(); - NetServerListener.Enable(); -#endif - // init all Harmony patches in project - harmonyInstance = new Harmony(Name); - harmonyInstance.PatchAll(); - - // patches for bugs - Fixes.InitLogSooner.Init(); - - // API init - API.Synergy.ServerHandshakeEngine.Init(); - - // misc - LogIPAPlugins(); // log plugins again so they show up in the log, and not just stdout - Fixes.BugfixAttributeUtility.LogBugfixes(); // log bugfixes that are applied - -#if DEBUG - // test CLre debug functionality - Type netData = AccessTools.TypeByName("Game.Handhelds.DrawingStateMessage"); - NetServerSender.DebugSendMessage(netData, harmonyInstance, - NetServerSender.GetLogMethod(netData)); - API.Utility.Logging.MetaLog("Patched SendMessage"); - - netData = AccessTools.TypeByName("Shared.Inventory.HandheldEquipmentRequest"); - NetServerSender.DebugSendMessage(netData, harmonyInstance, - NetServerSender.GetLogMethod(netData)); - API.Utility.Logging.MetaLog("Patched SendMessage"); - - netData = typeof(API.Synergy.SerializedCLreHandshake); - NetServerSender.DebugSendMessage(netData, harmonyInstance, - NetServerSender.GetLogMethod(netData)); - API.Utility.Logging.MetaLog("Patched SendMessage"); - - NetServerListener.DebugReceiveMessage(NetworkDispatcherCode.EACMessageServerToClient, - NetServerListener.Log); - - NetServerListener.DebugReceiveMessage(NetworkDispatcherCode.SendIsPvEToClient, - NetServerListener.Log); - - NetServerListener.DebugReceiveMessage(API.Synergy.ServerHandshakeEngine.CLre_HANDSHAKE_NETCODE, - NetServerListener.Log); - - // API debug and testing - API.MainServer.Server.Instance.FrameworkReady += (_, __) => API.Utility.Logging.MetaLog("(!) Server framework ready for business"); - API.MainServer.Server.Instance.FrameworkExit += (_, __) => API.Utility.Logging.MetaLog("(!) Server framework shutting down"); // this seems to never happen - API.MainServer.Server.Instance.InitStart += (_, __) => API.Utility.Logging.MetaLog("(!) Server initialising"); - API.MainServer.Server.Instance.InitComplete += (_, __) => API.Utility.Logging.MetaLog("(!) Server successfully initialised"); -#endif - // try to load config file - Config = CLreConfig.FromFileSafely(CONFIG_PATH); - // init config-dependent functionality - WebServer.Init(); - API.Synergy.CLreEnforcer.Init(); - Tweaks.TerrainModificationExclusionZone.Init(); - Tweaks.Chat.ChatHandler.Init(); - API.MainServer.Server.Init(); - API.MainServer.Moderator.Init(); - // Log info - API.Utility.Logging.MetaLog($"{Name} init complete."); - } - - private static void LogIPAPlugins() - { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("Running on Unity {0}\n", Application.unityVersion); - sb.AppendFormat("Running on CardLife Server {0} (aka {1})\n", Game.Utilities.VersionReader.GetVersion(), Application.version); - sb.AppendFormat("-----------------------------\n"); - sb.AppendFormat("Loading plugins from {0} and found {1}\n", System.IO.Path.Combine(Environment.CurrentDirectory, "Plugins"), IllusionInjector.PluginManager.Plugins.Count()); - sb.AppendFormat("-----------------------------\n"); - foreach (IllusionPlugin.IPlugin plugin in IllusionInjector.PluginManager.Plugins) - { - - sb.AppendFormat(" {0}: {1}\n", plugin.Name, plugin.Version); - } - sb.AppendFormat("-----------------------------\n"); - API.Utility.Logging.Log(sb.ToString()); - } - -#if DEBUG - public override void OnGUI() - { - if (GUI.Button(new Rect(10, 10, 50, 50), "QUIT")) - { - Application.Quit(); // yeet - } - } -#endif - } -} diff --git a/CLre_server/CLre_server.csproj b/CLre_server/CLre_server.csproj deleted file mode 100644 index d5bc888..0000000 --- a/CLre_server/CLre_server.csproj +++ /dev/null @@ -1,292 +0,0 @@ - - - - net472 - true - 0.0.3 - NGnius - MIT - https://git.exmods.org/NGnius/CLre - en-CA - - - - - - - - - - - - - - - - ..\..\cl\CardlifeGameServer_Data\Managed\Accessibility.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Assembly-CSharp-firstpass.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Assembly-CSharp.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\BehaviorDesignerRuntime.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\DOTween.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\EasyAntiCheat.Client.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\EasyAntiCheat.Server.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Fabric.AudioSpline.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Fabric.Core.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\log4net.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\mscorlib.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Novell.Directory.Ldap.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Photon3Unity3D.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Rewired_Core.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Rewired_Windows_Lib.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Svelto.Common.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Svelto.ECS.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Svelto.Tasks.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Unity.Postprocessing.Runtime.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\Unity.TextMeshPro.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.AccessibilityModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.AIModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.AnimationModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ARModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.AssetBundleModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.AudioModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.BaselibModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ClothModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ClusterInputModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ClusterRendererModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.CoreModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.CrashReportingModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.DirectorModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.FileSystemHttpModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.GameCenterModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.GridModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.HotReloadModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ImageConversionModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.IMGUIModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.InputModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.JSONSerializeModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.LocalizationModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.Networking.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ParticleSystemModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.PerformanceReportingModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.Physics2DModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.PhysicsModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ProfilerModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.ScreenCaptureModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.SharedInternalsModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.SpatialTracking.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.SpriteMaskModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.SpriteShapeModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.StreamingModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.StyleSheetsModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.SubstanceModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TerrainModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TextCoreModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TextRenderingModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TilemapModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.Timeline.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TimelineModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.TLSModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UI.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UIElementsModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UIModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UmbraModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UNETModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityConnectModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityWebRequestModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.VehiclesModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.VFXModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.VideoModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.VRModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.WindModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\UnityEngine.XRModule.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\IllusionInjector.dll - - - ..\..\cl\CardlifeGameServer_Data\Managed\IllusionPlugin.dll - - - - - - - - - - - diff --git a/CLre_server/Fixes/BugfixAttribute.cs b/CLre_server/Fixes/BugfixAttribute.cs deleted file mode 100644 index 490f8c5..0000000 --- a/CLre_server/Fixes/BugfixAttribute.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; - -namespace CLre_server.Fixes -{ - [AttributeUsage(AttributeTargets.Class)] - public class BugfixAttribute : Attribute - { - public string name { get; set; } - public string description { get; set; } - public Type target { get; set; } - public string more { get; set; } - public uint id { get; set; } - public BugfixType component { get; set; } - } - - public enum BugfixType : byte - { - Miscellaneous = 0x00, - HarmonyPatch, - Initialiser, - Workaround, - API, - Debug - } - - internal static class BugfixAttributeUtility - { - public static void LogBugfixes() - { - List keys = new List(); - Dictionary fixes = new Dictionary(); - foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) - { - BugfixAttribute b = t.GetCustomAttribute(true); - if (b != null) - { - if (!fixes.ContainsKey(b.id)) - { - BugfixStruct bugfixStruct = new BugfixStruct{id = b.id}; - bugfixStruct.Merge(b); - fixes[b.id] = bugfixStruct; - keys.Add(b.id); - } - else - { - BugfixStruct bugfixStruct = fixes[b.id]; - bugfixStruct.Merge(b); - fixes[b.id] = bugfixStruct; - } - } - } - keys.Sort(); - //keys.Sort((u, u1) => u.CompareTo(u1)); - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("Applying {0} CLre fixes\n", keys.Count); - sb.AppendFormat("-----------------------------\n"); - foreach (uint i in keys) - { - sb.Append(fixes[i].ToString()); - sb.Append("\n"); - } - sb.AppendFormat("-----------------------------\n"); - API.Utility.Logging.Log(sb.ToString()); - } - - private struct BugfixStruct - { - public string name; - public string description; - public Type target; - public string more; - public uint id; - private uint total; - private uint[] bugfixTypeCount; - - public void Merge(BugfixAttribute b) - { - if (name == null && b.name != null) name = b.name; - if (description == null && b.description != null) description = b.description; - if (target == null && b.target != null) target = b.target; - if (more == null && b.more != null) more = b.more; - total++; - if (bugfixTypeCount == null) bugfixTypeCount = new uint[Enum.GetNames(typeof(BugfixType)).Length]; - bugfixTypeCount[(byte) b.component]++; - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat(" {0}: ", name); - if (more != null) - { - sb.AppendFormat("[MORE: {0}] ", more); - } - else if (description != null) - { - sb.Append(description); - sb.Append(" "); - } - - if (target != null) - { - sb.AppendFormat("[TARGET: {0}] ", target.FullName); - } - sb.AppendFormat("[ID: {0}] ", id); - sb.AppendFormat("({0}M/{1}P/{2}I/{3}W/{4}A/{5}D/{6}T)", - bugfixTypeCount[(byte) BugfixType.Miscellaneous], bugfixTypeCount[(byte) BugfixType.HarmonyPatch], - bugfixTypeCount[(byte) BugfixType.Initialiser], bugfixTypeCount[(byte) BugfixType.Workaround], - bugfixTypeCount[(byte) BugfixType.API], bugfixTypeCount[(byte) BugfixType.Debug], total); - return sb.ToString(); - } - } - } -} \ No newline at end of file diff --git a/CLre_server/Fixes/InitLogSooner.cs b/CLre_server/Fixes/InitLogSooner.cs deleted file mode 100644 index 0e94a5b..0000000 --- a/CLre_server/Fixes/InitLogSooner.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Diagnostics; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Threading; -using HarmonyLib; - -namespace CLre_server.Fixes -{ - [Bugfix(name = "InitLogSooner", - description = "Start the logger slightly sooner than Cardlife does", - component = BugfixType.Initialiser, id = 0)] - public static class InitLogSooner - { - public static int millisecondsTimeout = 5000; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Init() - { - try - { - CustomLoggerThread_CreateGameObject_Patch.allowed = true; - CustomLoggerThread.CreateGameObject(); - CustomLoggerThread_CreateGameObject_Patch.allowed = false; - API.Utility.Logging.Log($"Completed early log init, hello!"); - //System.IO.File.WriteAllText("InitLogSooner.log", $"Done at " + System.DateTime.Now.ToString()); - } - catch (Exception e) - { - API.Utility.Logging.Log($"Failed to initialise log sooner, reason:\n" + e); - System.IO.File.WriteAllText("InitLogSooner.log", e.ToString()); - } - - } - - [Bugfix(name = "InitLogSooner", - target = typeof(CustomLoggerThread), - component = BugfixType.HarmonyPatch, id = 0)] - [HarmonyPatch(typeof(CustomLoggerThread), "CreateGameObject")] - class CustomLoggerThread_CreateGameObject_Patch - { - internal static bool allowed = false; - - public static bool Prefix() - { - return allowed; - } - } - - [Bugfix(name = "InitLogSooner", - component = BugfixType.HarmonyPatch, id = 0)] - [HarmonyPatch(typeof(CustomLoggerThread), "StartQueue")] - class CustomLoggerThread_StartQueue_Patch - { - internal static volatile bool IsLogStarted = false; - - private delegate void Flusher(); - - public static bool Prefix() - { - // setup thru reflection - FieldInfo quitThreadField = AccessTools.Field(typeof(CustomLoggerThread), "_quitThread"); - - MethodInfo flushLoggerMethod = AccessTools.Method(typeof(CustomLoggerThread), "FlushLogger"); - Flusher flushLogger = (Flusher) Delegate.CreateDelegate(typeof(Action), null, flushLoggerMethod); - - MethodInfo forceFlushMethod = AccessTools.Method("CustomLogger:ForceFlush"); - Flusher forceFlush = (Flusher) Delegate.CreateDelegate(typeof(Action), null, forceFlushMethod); - - Thread.MemoryBarrier(); - IsLogStarted = true; - while (!(bool) quitThreadField.GetValue(null)) - { - flushLogger(); - forceFlush(); - Thread.Sleep(millisecondsTimeout); - } - - IsLogStarted = false; - return false; - } - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/Attributes.cs b/CLre_server/Tweaks/Chat/Attributes.cs deleted file mode 100644 index 7483614..0000000 --- a/CLre_server/Tweaks/Chat/Attributes.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.Reflection; -using System.Text.RegularExpressions; - - -namespace CLre_server.Tweaks.Chat -{ - public class Attributes - { - - } - - [System.AttributeUsage(System.AttributeTargets.Method)] - public class ChatCommandAttribute : System.Attribute - { - public readonly string Name; - private readonly Regex _pattern; - private readonly Regex _usernamePattern; - - public ChatCommandAttribute(string name, string pattern, - string usernamePattern = null, - RegexOptions options = RegexOptions.Compiled | RegexOptions.IgnoreCase) - { - this.Name = name; - this._pattern = new Regex(pattern, options); - this._usernamePattern = usernamePattern == null ? null : new Regex(pattern, options); - Assembly asm = Assembly.GetCallingAssembly(); - if (!ChatConnectionEngine._assembliesToCheck.Contains(asm)) - { - ChatConnectionEngine._assembliesToCheck.Add(asm); - } - - if (ChatHandler.IsAuthenticationReady && CLre.Config.chat_commands) - { - // Chat system is already started - // TODO - } - } - - public Regex GetPattern() - { - return _pattern; - } - - public Match RegexMatch(string sender, string message) - { - if (this._usernamePattern != null) - { - if (this._usernamePattern.IsMatch(sender)) - { - return _pattern.Match(message); - } - } - else - { - return _pattern.Match(message); - } - return System.Text.RegularExpressions.Match.Empty; - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/AuthenticationEngine.cs b/CLre_server/Tweaks/Chat/AuthenticationEngine.cs deleted file mode 100644 index fffdbf0..0000000 --- a/CLre_server/Tweaks/Chat/AuthenticationEngine.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace CLre_server.Tweaks.Chat -{ - public class AuthenticationEngine: API.Engines.ServerEnginePostBuild - { - public API.Utility.AuthenticationResponse response = default; - public bool IsAuthenticated = false; - - public override void Ready() - { - API.Utility.CardLifeUserAuthentication.Authenticate( - CLre.Config.email_address, - CLre.Config.password, - (data) => - { - this.IsAuthenticated = true; - this.response = data; - API.Utility.Logging.Log("CLre chat credentials successfully authenticated"); - }).Run(); - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/ChatConfig.cs b/CLre_server/Tweaks/Chat/ChatConfig.cs deleted file mode 100644 index 859f328..0000000 --- a/CLre_server/Tweaks/Chat/ChatConfig.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace CLre_server.Tweaks.Chat -{ - [Serializable] - public struct ChatConfig - { - public bool commands_enabled; - public string email_address; - public string password; - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/ChatConnectionEngine.cs b/CLre_server/Tweaks/Chat/ChatConnectionEngine.cs deleted file mode 100644 index 946ec18..0000000 --- a/CLre_server/Tweaks/Chat/ChatConnectionEngine.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Text.RegularExpressions; -using ExitGames.Client.Photon; -using ExitGames.Client.Photon.Chat; -using HarmonyLib; -using Svelto.Context; - -namespace CLre_server.Tweaks.Chat -{ - public class ChatConnectionEngine: API.Engines.ServerEnginePostBuild, IWaitForFrameworkInitialization, IWaitForFrameworkDestruction - { - private bool _running = false; - private ChatClient _chatClient; - private ChatListener _chatListener; - - public delegate void CommandHandler(Match messageMatch, ChatClient connection, string username); - - private Dictionary _handlers; - - internal static List _assembliesToCheck = new List(new []{typeof(CLre).Assembly}); - - public override void Ready() - { - _running = true; - } - - private IEnumerator connectify() - { - LoadHandlers(); // find & load commands - // wait for login to succeed (it may never) - while (!ChatHandler.IsAuthenticationReady && _running) - { - yield return null; - } - // login with authenticated credentials - // shout-out to however made an identical AuthenticationValues struct in the global namespace - ExitGames.Client.Photon.Chat.AuthenticationValues auth = new ExitGames.Client.Photon.Chat.AuthenticationValues(); - auth.AuthType = ExitGames.Client.Photon.Chat.CustomAuthenticationType.Custom; - auth.AddAuthParameter("publicId", ChatHandler.PublicId); - auth.AddAuthParameter("token", ChatHandler.Token); - auth.UserId = ChatHandler.PublicId; - _chatListener= new ChatListener(_handlers); - _chatClient = new ChatClient(_chatListener, ConnectionProtocol.Udp); - _chatListener.ChatClient = _chatClient; - _chatClient.Connect(Game.Utilities.CardLifePhotonSettings.PhotonChatAppID, "1.0", auth); - // run forever (until server shutsdown) - while (_running) - { - _chatClient.Service(); - yield return null; - } - } - - public void OnFrameworkInitialized() - { - connectify().Run(); - } - - public void OnFrameworkDestroyed() - { - _running = false; - } - - private void LoadHandlers() - { - _handlers = new Dictionary(); - foreach (Assembly asm in _assembliesToCheck.ToArray()) - { - foreach (Type t in asm.GetTypes()) - { - foreach (MethodInfo m in t.GetMethods(AccessTools.all)) - { - ChatCommandAttribute attr = m.GetCustomAttribute(); - if (attr != null) - { - // TODO validate that method signature matches that of CommandHandler - API.Utility.Logging.MetaLog($"{t.FullName}:{m.Name} is handling {attr.Name}"); - _handlers.Add(attr, (CommandHandler) Delegate.CreateDelegate(typeof(CommandHandler), m)); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/ChatHandler.cs b/CLre_server/Tweaks/Chat/ChatHandler.cs deleted file mode 100644 index 6d666c2..0000000 --- a/CLre_server/Tweaks/Chat/ChatHandler.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.Generic; -using System.Reflection; - -namespace CLre_server.Tweaks.Chat -{ - public static class ChatHandler - { - private static AuthenticationEngine _chatAuthEngine = null; - private static ChatConnectionEngine _chatConnectionEngine = null; - - internal static bool IsAuthenticationReady - { - get => _chatAuthEngine.IsAuthenticated; - } - - internal static string PublicId - { - get => _chatAuthEngine.response.PublicId; - } - - internal static string Token - { - get => _chatAuthEngine.response.Token; - } - - public static void Init() - { - if (!CLre.Config.chat_commands) return; - _chatAuthEngine = new AuthenticationEngine(); - _chatConnectionEngine = new ChatConnectionEngine(); - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/ChatListener.cs b/CLre_server/Tweaks/Chat/ChatListener.cs deleted file mode 100644 index a327f5f..0000000 --- a/CLre_server/Tweaks/Chat/ChatListener.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using ExitGames.Client.Photon; -using ExitGames.Client.Photon.Chat; - -namespace CLre_server.Tweaks.Chat -{ - public class ChatListener: IChatClientListener - { - internal ChatClient ChatClient; - public static string ChatName; - private Dictionary _handlers; - - public ChatListener(Dictionary handlers) - { - _handlers = handlers; - } - - public void DebugReturn(DebugLevel level, string message) - { -#if DEBUG - API.Utility.Logging.Log($"ServerChatLog<{level}>: {message}"); -#endif - } - - public void OnDisconnected() - { -#if DEBUG - API.Utility.Logging.MetaLog("Chat disconnected"); -#endif - } - - public void OnConnected() - { - API.Utility.Logging.MetaLog("Chat connected"); - // autoconnect to server's chat room - Room room = PhotonNetwork.room; - ChatName = ""; - if (room != null) - { - ChatName = $"{room.Name}_chat_"; - } - else - { - return; - } - - bool result = ChatClient.Subscribe(new[] {ChatName}, 10); -#if DEBUG - API.Utility.Logging.MetaLog($"Subscribed to chat: {result}"); -#endif - } - - public void OnChatStateChange(ChatState state) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Chat state changed to {state}"); -#endif - } - - public void OnGetMessages(string channelName, string[] senders, object[] messages) - { - if (channelName != ChatName) return; // just in case the server somehow gets subscribed to the wrong chat - for (int i = 0; i < senders.Length; i++) - { - string message = messages[i].ToString(); - string username = stripUsernameTag(senders[i]); -#if DEBUG - API.Utility.Logging.MetaLog($"Chat: `{username}` said `{messages[i]}` in `{channelName}`"); -#endif - if (message.StartsWith("/")) - { - string command = message.Substring(1); - - foreach (ChatCommandAttribute cca in _handlers.Keys) - { - var match = cca.RegexMatch(senders[i], command); - if (match.Success) - { - _handlers[cca](match, ChatClient, username); - } - } - } - - } - } - - public void OnPrivateMessage(string sender, object message, string channelName) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Chat (private): `{sender}` said `{message}` in `{channelName}`"); -#endif - } - - public void OnSubscribed(string[] channels, bool[] results) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Subscribed"); -#endif - } - - public void OnUnsubscribed(string[] channels) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Unsubscribed"); -#endif - } - - public void OnStatusUpdate(string user, int status, bool gotMessage, object message) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Status update: {user}->{status} ({gotMessage}:{message})"); -#endif - } - - private string stripUsernameTag(string sender) - { - if (!sender.Contains("]")) return sender; - return sender.Split(']')[1].Trim(); - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/ModeratorCommands.cs b/CLre_server/Tweaks/Chat/ModeratorCommands.cs deleted file mode 100644 index f6fabac..0000000 --- a/CLre_server/Tweaks/Chat/ModeratorCommands.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using ExitGames.Client.Photon.Chat; - -namespace CLre_server.Tweaks.Chat -{ - public static class ModeratorCommands - { - [ChatCommand("KICK", "kick ([\\w\\d\\-_]+)")] - public static void KickInButt(Match messageMatch, ChatClient connection, string sender) - { - if (!API.MainServer.Moderator.Instance.IsModerator(sender)) - { - connection.PublishMessage(ChatListener.ChatName, "Ban failure: You're not a mod :("); - return; - } - string target = messageMatch.Groups[1].Value; -#if DEBUG - API.Utility.Logging.MetaLog($"/kick {target}"); -#endif - if (API.MainServer.Moderator.Instance.DisconnectPlayerById(target)) - { - connection.PublishMessage(ChatListener.ChatName, $"Adios {target}"); - } - else if (API.MainServer.Moderator.Instance.DisconnectPlayerByName(target)) - { - connection.PublishMessage(ChatListener.ChatName, $"Bye bye {target}"); - } - else - { - connection.PublishMessage(ChatListener.ChatName, "Kick failure: User not found :("); - } - } - - [ChatCommand("BAN", "ban ([\\w\\d\\-_]+)")] - public static void BanishIdiot(Match messageMatch, ChatClient connection, string sender) - { - if (!API.MainServer.Moderator.Instance.IsModerator(sender)) - { - connection.PublishMessage(ChatListener.ChatName, "Ban failure: You're not a mod :("); - return; - } - string target = messageMatch.Groups[1].Value; -#if DEBUG - API.Utility.Logging.MetaLog($"/ban {target}"); -#endif - if (API.MainServer.Moderator.Instance.BanPlayerById(target)) - { - connection.PublishMessage(ChatListener.ChatName, $"And {target} is no more!"); - } - else if (API.MainServer.Moderator.Instance.BanPlayerByName(target)) - { - connection.PublishMessage(ChatListener.ChatName, $"And {target} was never seen again..."); - } - else - { - connection.PublishMessage(ChatListener.ChatName, $"Ban warning: {target} was added to ban list but was not connected to this server..."); - } - } - - [ChatCommand("(SH)OPIFY", "(mod|op) ([\\w\\d\\-_]+)")] - public static void GoPro(Match messageMatch, ChatClient connection, string sender) - { - if (!API.MainServer.Moderator.Instance.IsModerator(sender)) - { - connection.PublishMessage(ChatListener.ChatName, "Op failure: You're not a mod :("); - return; - } - string target = messageMatch.Groups[2].Value; -#if DEBUG - API.Utility.Logging.MetaLog($"/op {target}"); -#endif - List moderators = new List(CLre.Config.moderators); - moderators.Add(target); - CLre.Config.moderators = moderators.ToArray(); - connection.PublishMessage(ChatListener.ChatName, $"Promoted {target} to moderator"); - } - - [ChatCommand("De(SH)OPIFY", "(demod|deop) ([\\w\\d\\-_]+)")] - public static void AntiProton(Match messageMatch, ChatClient connection, string sender) - { - if (!API.MainServer.Moderator.Instance.IsModerator(sender)) - { - connection.PublishMessage(ChatListener.ChatName, "DeOp failure: You're not a mod :("); - return; - } - string target = messageMatch.Groups[2].Value; -#if DEBUG - API.Utility.Logging.MetaLog($"/deop {target}"); -#endif - List moderators = new List(CLre.Config.moderators); - if (moderators.Remove(target)) - { - CLre.Config.moderators = moderators.ToArray(); - connection.PublishMessage(ChatListener.ChatName, $"Demoted {target} to regular user"); - } - connection.PublishMessage(ChatListener.ChatName, "DeOp failure: User not found :("); - } - - [ChatCommand("ECHO", "echo (.+)$")] - public static void EchoEchoEcho(Match messageMatch, ChatClient connection, string sender) - { - string target = messageMatch.Groups[1].Value; -#if DEBUG - API.Utility.Logging.MetaLog($"/echo {target}"); -#endif - connection.PublishMessage(ChatListener.ChatName, target); - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/Chat/UserCommands.cs b/CLre_server/Tweaks/Chat/UserCommands.cs deleted file mode 100644 index a166ce6..0000000 --- a/CLre_server/Tweaks/Chat/UserCommands.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text; -using System.Text.RegularExpressions; -using ExitGames.Client.Photon.Chat; - -namespace CLre_server.Tweaks.Chat -{ - public static class UserCommands - { - private const string HELP_STRING = "CLre chat commands:\n" + - "/echo - say \n" + - "/help - show this message\n" + - "/list - display online users\n" + - "/version - display version information\n\n" + - - "CLre moderation commands:\n" + - "/ban - permanently remove from this server\n" + - "/deop - revoke moderator permissions\n" + - "/kick - disconnect from this server\n" + - "/op - grant moderator permissions"; - - - - [ChatCommand("ONLINE", "(list|online)")] - public static void WhoIsOnline(Match messageMatch, ChatClient connection, string sender) - { - var players = API.MainServer.Server.Instance.Players; - StringBuilder sb = new StringBuilder($"Online Users ({players.Length}):\n"); - foreach (var p in players) - { - sb.AppendFormat("{0} ({1})\n", p.accountId.displayName, p.accountId.publicId); - } - - connection.PublishMessage(ChatListener.ChatName, sb.ToString().TrimEnd()); - } - - [ChatCommand("VERSION", "version")] - public static void CeleryVersion(Match messageMatch, ChatClient connection, string sender) - { - string versionStr = $"CLre {CLre.Instance.Version}\nCardLife {Game.Utilities.VersionReader.GetVersion()}\nUnity {UnityEngine.Application.version}"; - connection.PublishMessage(ChatListener.ChatName, versionStr); - } - - [ChatCommand("HELP", "help")] - public static void Halp(Match messageMatch, ChatClient connection, string sender) - { - connection.PublishMessage(ChatListener.ChatName, HELP_STRING); - } - } -} \ No newline at end of file diff --git a/CLre_server/Tweaks/TerrainModificationExclusionZone.cs b/CLre_server/Tweaks/TerrainModificationExclusionZone.cs deleted file mode 100644 index 86000e1..0000000 --- a/CLre_server/Tweaks/TerrainModificationExclusionZone.cs +++ /dev/null @@ -1,265 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.CompilerServices; -using CLre_server.API.Synergy.Tweaks; -using CLre_server.API.Utility; -using Game.DataLoader; -using GameNetworkLayer.Shared; -using HarmonyLib; -using NetworkFramework.Shared; -using Svelto.DataStructures; -using Svelto.ECS; -using UnityEngine; -using User.Server; -using voxelfarm; - -namespace CLre_server.Tweaks -{ - public class TerrainModificationExclusionZone - { - private static TerrainExclusionZoneEngine teze = null; - - internal static object _serverStructureExclusionZoneNode = null; - - internal static void Init() - { - if (!CLre.Config.terrain_exclusion_zone) return; - teze = new TerrainExclusionZoneEngine(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static SerializedCLreTerrainModifyRejection HasExclusionZoneAtLocationWithMember(ref Vector3 location, int playerId) - { - if (_serverStructureExclusionZoneNode == null) - { - SerializedCLreTerrainModifyRejection result = default; - result.Flags = RejectionFlag.InitError | RejectionFlag.Rejection; - return result; // this shouldn't happen (I hope...) - } - return teze.HasExclusionZoneAtLocationWithMember(ref location, playerId, _serverStructureExclusionZoneNode); - } - } - - public class TerrainExclusionZoneEngine : API.Engines.ServerEnginePostBuild - { - public override void Ready() - { - } - - public SerializedCLreTerrainModifyRejection HasExclusionZoneAtLocationWithMember(ref Vector3 digPosition, int playerId, object exclusionZonesNode) - { - SerializedCLreTerrainModifyRejection result = default; - // Similar to Game.Building.ExclusionZone.ServerStructureExclusionZoneEngine.FindPotentialMatchingExclusionZones - // Match player index to Guid - FieldInfo f = AccessTools.Field(AccessTools.TypeByName("User.Server.AccountExclusiveGroups"), "accountGroup"); - ExclusiveGroup accountGroup = (ExclusiveGroup) f.GetValue(null); - ReadOnlyCollectionStruct accounts = - entitiesDB.QueryEntityViews(accountGroup); - if (playerId >= accounts.Count) - { - // playerId isn't in connected accounts - API.Utility.Logging.LogWarning("PlayerId isn't in connected accounts, denying terrain modification"); - result.Flags = RejectionFlag.AccountNotFound | RejectionFlag.Rejection; - return result; // this shouldn't happen (I hope...) - } - Guid playerGuid = accounts[playerId].accountId.publicId; - // find exclusion zone where terrain modification is happening - float cellSize = dataDB.GetDefaultValue().WorldCellRadius * 0.25f; - object structureCellId = GetCellIdFromPosition(ref digPosition, cellSize); - // TODO optimize - Traverse exclusionNodeData = Traverse.Create(exclusionZonesNode) - .Field("serverStructureExclusionZoneDataComponent"); - Traverse exclusionZoneIdsByWorldCell = exclusionNodeData - .Property("exclusionZoneIdsByWorldCell"); // Dictionary> - Traverse exclusionZonesByUniqueId = exclusionNodeData - .Property("exclusionZonesByUniqueId"); // Dictionary - bool exists = exclusionZoneIdsByWorldCell - .Method("ContainsKey", new[] {structureCellId}).GetValue(); - if (exists) - { -#if DEBUG - API.Utility.Logging.MetaLog("Exclusion zone cell found, iterating over zones..."); -#endif - HashSet zoneIds = exclusionZoneIdsByWorldCell - .Property>("Item", index: new[] {structureCellId}) - .Value; - foreach (uint item in zoneIds) - { - Traverse serverStructureExclusionZone = exclusionZonesByUniqueId - .Property("Item", index: new object[] {item}); - Traverse structureExclusionZone = serverStructureExclusionZone - .Property("structureExclusionZone"); - bool isOwner = serverStructureExclusionZone - .Method("CheckIsOwner", playerGuid) - .GetValue(); -#if DEBUG - API.Utility.Logging.MetaLog($"IsOwner? {isOwner}"); -#endif - Game.Building.AABB aabb = structureExclusionZone.Field("_exclusionZoneAabb") - .Field("_aabb").Value; - bool isPointInAABB = IsWithin(ref digPosition, ref aabb); -#if DEBUG - API.Utility.Logging.MetaLog($"IsPointInAABB? {isPointInAABB}"); - API.Utility.Logging.MetaLog($"AABB max:{aabb.max}, min: {aabb.min} dig: {digPosition}"); -#endif - if (isPointInAABB) - { - if (!isOwner) - { - result.Flags = RejectionFlag.Proximity - | RejectionFlag.Rejection - | RejectionFlag.Permission; - } - return result; - } - } - } -#if DEBUG - API.Utility.Logging.MetaLog("Allowing player to modify terrain"); -#endif - result.Flags = RejectionFlag.None; - return result; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static object GetCellIdFromPosition(ref Vector3 playerPosition, float cellSize) - { - // This uses decompiled code from Game.WorldGrid.StructureGridUtils:GetCellIdFromPosition - // there's no point in calling that simple function when I have to jump through hoops with reflection - // - // there's also nothing particularly unique (ie copyrightable) about this code, - // so the lawyers can suck it (also suing a benevolent project is a shitty move) - float num = 1f / cellSize; - int x = Mathf.CeilToInt((playerPosition.x - cellSize * 0.5f) * num); - int y = Mathf.CeilToInt((playerPosition.y - cellSize * 0.5f) * num); - int z = Mathf.CeilToInt((playerPosition.z - cellSize * 0.5f) * num); - // TODO optimize - // Create StructureCellId by jumping through hoops - return AccessTools.TypeByName("Game.WorldGrid.StructureCellId") - .GetConstructor(AccessTools.all, null, new[] {typeof(int), typeof(int), typeof(int)}, null) - .Invoke(new object[] {x, y, z}); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsWithin(ref Vector3 point, ref Game.Building.AABB bounds) - { - return point.x > bounds.min.x && point.x < bounds.max.x - && point.y > bounds.min.y && point.y < bounds.max.y - && point.z > bounds.min.z && point.x < bounds.max.z; - } - } - - [HarmonyPatch] - class TerrainModificationEngineServer_RemoveTerrainInput_Patch - { - private static object _netMsgServerSender; - - // reflection caching - private static API.Utility.Reflection.INetMsgServerSender_SendMessage - _netMessageSend_CLre = null; - - [HarmonyPrefix] - public static bool BeforeMethodCall(int senderPlayerId, ref ISerializedNetData data, object ____netMsgServerSender) - { - if (!CLre.Config.terrain_exclusion_zone) return true; - _netMsgServerSender = ____netMsgServerSender; - if (_netMessageSend_CLre == null) - { - // cache reflection operations on first run -#if DEBUG - API.Utility.Logging.MetaLog("Building SendMessage delegate optimisation"); -#endif - _netMessageSend_CLre = API.Utility.Reflection - .MethodAsDelegate< - API.Utility.Reflection.INetMsgServerSender_SendMessage - >( - "GameNetworkLayer.Server.INetMsgServerSender:SendMessage", - generics: new [] {typeof(SerializedCLreTerrainModifyRejection)}, - instance: ____netMsgServerSender); - } -#if DEBUG - API.Utility.Logging.MetaLog("Intercepting TerrainModificationEngineServer.RemoveTerrainInput()"); -#endif - Vector3 location = Traverse.Create(data).Property("hit").Value; - API.Utility.Logging.MetaLog($"location is null? {location == Vector3.zero}"); - SerializedCLreTerrainModifyRejection modifyPayload = TerrainModificationExclusionZone.HasExclusionZoneAtLocationWithMember(ref location, senderPlayerId); - if (!modifyPayload.Ok()) - { -#if DEBUG - API.Utility.Logging.MetaLog("Rejecting terrain modification"); -#endif - // TODO optimize - Traverse tmid = Traverse.Create(data); - modifyPayload.resourceId = tmid.Property("resourceId").Value; - modifyPayload.hit = location; - //modifyPayload.materialIndex = tmid.Property("materialIndex").Value; - modifyPayload.toolKey = tmid.Property("toolKey").Value; - modifyPayload.toolMode = tmid.Property("toolMode").Value; - switch (modifyPayload.toolMode) - { - case Game.Handhelds.ToolModeType.Block: - modifyPayload.hit.y -= 0.125f * 2; // each layer is 0.125 thick, block is 3 layers - break; - case Game.Handhelds.ToolModeType.Disc: - break; - case Game.Handhelds.ToolModeType.Voxel: - modifyPayload.toolMode = Game.Handhelds.ToolModeType.Disc; // voxels aren't replaced properly - break; - } - // signal client that stuff failed - _netMessageSend_CLre(NetworkDispatcherCode.TerrainModificationFailed, ref modifyPayload, senderPlayerId); - // build terrain data for terrain replacement -#if DEBUG - API.Utility.Logging.MetaLog("Filling hole left by terrain modification"); -#endif - } - return modifyPayload.Ok(); - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("GameServer.VoxelFarm.Server.TerrainModificationEngineServer:RemoveTerrainInput"); - } - } - - [HarmonyPatch] - class ServerStructureExclusionZoneEngine_Add_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall(object entityView) - { - TerrainModificationExclusionZone._serverStructureExclusionZoneNode = entityView; -#if DEBUG - API.Utility.Logging.MetaLog("Got TerrainModificationExclusionZone._serverStructureExclusionZoneNode"); -#endif - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("Game.Building.ExclusionZone.ServerStructureExclusionZoneEngine:Add", new Type[] {AccessTools.TypeByName("Game.Building.ExclusionZone.ServerStructureExclusionZonesNode")}); - } - } - - [HarmonyPatch] - class ServerStructureExclusionZoneEngine_Remove_Patch - { - [HarmonyPostfix] - public static void AfterMethodCall() - { - TerrainModificationExclusionZone._serverStructureExclusionZoneNode = null; -#if DEBUG - API.Utility.Logging.MetaLog("Yeeted TerrainModificationExclusionZone._serverStructureExclusionZoneNode"); -#endif - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("Game.Building.ExclusionZone.ServerStructureExclusionZoneEngine:Remove", new Type[] {AccessTools.TypeByName("Game.Building.ExclusionZone.ServerStructureExclusionZonesNode")}); - } - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/AssetEndpoints.cs b/CLre_server/WebStatus/AssetEndpoints.cs deleted file mode 100644 index be1af94..0000000 --- a/CLre_server/WebStatus/AssetEndpoints.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.IO; -using System.Net; -using System.Reflection; -using System.Text; - -namespace CLre_server.WebStatus -{ - public static class AssetEndpoints - { - [WebEndpoint("/")] - public static void LandingPage(HttpListenerContext ctx) - { - ctx.Response.Headers.Add("Content-Type", "text/html"); - Asset(ctx, "CLre_server.WebStatus.Assets.index.html"); - } - - [WebEndpoint("/asset")] - public static void AllAssets(HttpListenerContext ctx) - { - ctx.Response.Headers.Add("Content-Type", "text/html"); - Asset(ctx, ""); - } - - [WebEndpoint("/asset/404")] - public static void Asset404(HttpListenerContext ctx) - { - ctx.Response.Headers.Add("Content-Type", "text/html"); - Asset(ctx, "CLre_server.WebStatus.Assets.error404.html"); - } - - private static bool Asset(HttpListenerContext ctx, string name) - { - Assembly asm = Assembly.GetCallingAssembly(); - Stream resource = asm.GetManifestResourceStream(name); - if (resource == null) - { - string assetStr = ListAssetsHtml(asm); - byte[] output = Encoding.UTF8.GetBytes(assetStr); - ctx.Response.OutputStream.Write(output, 0, output.Length); - return false; - } - resource.CopyTo(ctx.Response.OutputStream); - return true; - } - - private static string ListAssetsHtml(Assembly target) - { - StringBuilder sb = new StringBuilder("Asset not found

"); - sb.Append(target.GetName().Name); - sb.Append(" available assets

"); - foreach (string asset in target.GetManifestResourceNames()) - { - sb.Append("
  • "); - sb.Append(asset); - sb.Append("
  • "); - } - - sb.Append(""); - return sb.ToString(); - } - - private static string ListAssetsText(Assembly target) - { - StringBuilder sb = new StringBuilder(target.FullName); - foreach (string asset in target.GetManifestResourceNames()) - { - sb.Append("\n\t"); - sb.Append(asset); - } - - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/Assets/error404.html b/CLre_server/WebStatus/Assets/error404.html deleted file mode 100644 index 5af6067..0000000 --- a/CLre_server/WebStatus/Assets/error404.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - 404 Not Found - - -

    Page not found

    -
    - Home -
    - - \ No newline at end of file diff --git a/CLre_server/WebStatus/Assets/index.html b/CLre_server/WebStatus/Assets/index.html deleted file mode 100644 index 5b84398..0000000 --- a/CLre_server/WebStatus/Assets/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - CLre Server Status - - -

    Welcome to the CLre HTTP server!

    -
    - View log -
    - -
    - - - \ No newline at end of file diff --git a/CLre_server/WebStatus/Attributes.cs b/CLre_server/WebStatus/Attributes.cs deleted file mode 100644 index 14681a3..0000000 --- a/CLre_server/WebStatus/Attributes.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; - -namespace CLre_server.WebStatus -{ - public class Attributes - { - - } - - [System.AttributeUsage(System.AttributeTargets.Method)] - public class WebEndpointAttribute : System.Attribute - { - private readonly string endpoint; - - public WebEndpointAttribute(string path) - { - endpoint = path; - Assembly asm = Assembly.GetCallingAssembly(); - if (!WebServer._assembliesToCheck.Contains(asm)) - { - WebServer._assembliesToCheck.Add(asm); - } - - if (WebServer.MainInstance != null && WebServer.MainInstance.IsRunning) - { - // Web server is already running - // TODO - } - } - - internal string GetPath() - { - return endpoint; - } - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/ConfigurationEndpoints.cs b/CLre_server/WebStatus/ConfigurationEndpoints.cs deleted file mode 100644 index d3d4874..0000000 --- a/CLre_server/WebStatus/ConfigurationEndpoints.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Net; -using System.Text; - -namespace CLre_server.WebStatus -{ - public class ConfigurationEndpoints - { - [WebEndpoint("/c/game.json")] - public static void GameServerSettings (HttpListenerContext ctx) - { - ctx.Response.Headers.Add("Content-Type", "application/json"); - GameServer.GameServerSettings gss = API.MainServer.Server.Instance.GameServerSettings; - string json = UnityEngine.JsonUtility.ToJson(gss); -#if DEBUG - API.Utility.Logging.MetaLog("JSONified settings: " + json); -#endif - byte[] output = Encoding.UTF8.GetBytes(json); - ctx.Response.OutputStream.Write(output, 0, output.Length); - } - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/DebugEndpoints.cs b/CLre_server/WebStatus/DebugEndpoints.cs deleted file mode 100644 index 9437a1e..0000000 --- a/CLre_server/WebStatus/DebugEndpoints.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Net; -using System.Text; - -namespace CLre_server.WebStatus -{ - public static class DebugEndpoints - { - [WebEndpoint("/d/ping")] - private static void PingPong(HttpListenerContext ctx) - { - byte[] output = Encoding.UTF8.GetBytes("pong"); - ctx.Response.OutputStream.Write(output, 0, output.Length); - } - - [WebEndpoint("/d/version")] - internal static void VersionInfo(HttpListenerContext ctx) - { - StringBuilder sb = new StringBuilder(); - sb.Append("CardLife Version (Unity): \t"); - sb.Append(UnityEngine.Application.version); - sb.Append("\n"); - sb.Append("CardLife Version (Game): \t"); - sb.Append(Game.Utilities.VersionReader.GetVersion()); - sb.Append("\n"); - sb.Append("Unity Version: \t\t\t"); - sb.Append(UnityEngine.Application.unityVersion); - sb.Append("\n"); - sb.Append("CLre Version: \t\t\t"); - sb.Append(System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); - sb.Append("\n"); - byte[] output = Encoding.UTF8.GetBytes(sb.ToString()); - ctx.Response.OutputStream.Write(output, 0, output.Length); - } -#if DEBUG - [WebEndpoint("/d/test")] - internal static void Experiment(HttpListenerContext ctx) - { - string test = ""; - byte[] output = Encoding.UTF8.GetBytes(test); - ctx.Response.OutputStream.Write(output, 0, output.Length); - } -#endif - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/LogEndpoints.cs b/CLre_server/WebStatus/LogEndpoints.cs deleted file mode 100644 index 3f2d1ff..0000000 --- a/CLre_server/WebStatus/LogEndpoints.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.IO; -using System.Net; -using System.Reflection; -using System.Text; -using HarmonyLib; - -namespace CLre_server.WebStatus -{ - public class LogEndpoints - { - [WebEndpoint("/l/current")] - private static void FullLog(HttpListenerContext ctx) - { - if (CustomLogger_GetFileNameToUse_Patch.currentLogFile == null) - { - byte[] output = Encoding.UTF8.GetBytes("No log file available"); - ctx.Response.OutputStream.Write(output, 0, output.Length); - return; - } - // copy file because log is already open for writing - string copyFilename = CustomLogger_GetFileNameToUse_Patch.currentLogFile + ".copy"; - File.Copy(CustomLogger_GetFileNameToUse_Patch.currentLogFile, copyFilename, true); - FileStream logFile = new FileStream(copyFilename, FileMode.Open, FileAccess.Read, FileShare.Read); - logFile.CopyTo(ctx.Response.OutputStream); - logFile.Close(); - } - } - - [HarmonyPatch] - class CustomLogger_GetFileNameToUse_Patch - { - internal static string currentLogFile = null; - - [HarmonyPostfix] - public static void AfterMethodCall(string __result) - { -#if DEBUG - API.Utility.Logging.MetaLog($"Current logfile is {__result}"); -#endif - currentLogFile = __result; - } - - [HarmonyTargetMethod] - public static MethodBase Target() - { - return AccessTools.Method("CustomLogger:GetFileNameToUse"); - } - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/StatusEndpoints.cs b/CLre_server/WebStatus/StatusEndpoints.cs deleted file mode 100644 index 42fefdf..0000000 --- a/CLre_server/WebStatus/StatusEndpoints.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Net; -using System.Reflection; -using System.Text; -using CLre_server.API.Engines; -using CLre_server.API.MainServer; -using Game.CommonComponents; -using HarmonyLib; -using Svelto.DataStructures; -using Svelto.ECS; -using User.Server; - -namespace CLre_server.WebStatus -{ - public static class StatusEndpoints - { - private struct ServerStateCache - { - public List OnlinePlayers; - - public int MaxPlayers; - - public RunState State; - - public static ServerStateCache Empty() - { - return new ServerStateCache - { - OnlinePlayers = new List(), - MaxPlayers = -1, - State = RunState.Initialising, - }; - } - - public string Json() - { - // Unity's built-in JSON serializer does not work with arrays or lists :( - // I miss Newtonsoft... - StringBuilder sb = new StringBuilder($"{{\"PlayersMax\":{MaxPlayers},\"PlayerCount\":{OnlinePlayers.Count},\"Status\":\"{State.ToString()}\",\"OnlinePlayers\":["); - foreach (PlayerData p in OnlinePlayers.ToArray()) - { - sb.Append(UnityEngine.JsonUtility.ToJson(p)); - sb.Append(","); - } - if (OnlinePlayers.Count > 0) sb.Remove(sb.Length - 1, 1); - sb.Append("]}"); - return sb.ToString(); - } - } - - [Serializable] - private struct PlayerData - { - public string id; - public string name; - public bool isDev; - public float x; - public float y; - public float z; - } - - private enum RunState : short - { - Initialising, - Initialised, - Online, - Quitting, - } - - private class StatusPollingEngine : ServerEnginePostBuild - { - public override void Ready() - { - API.Utility.Logging.MetaLog("StatusPolling Engine ready"); - pollLoop().Run(); - } - - private delegate void PlayerPositionFunc(); - - private PlayerPositionFunc _playerPositionFunc = null; - - private IEnumerator pollLoop() - { - FieldInfo f = AccessTools.Field(AccessTools.TypeByName("User.Server.AccountExclusiveGroups"), "accountGroup"); - ExclusiveGroup accountGroup = (ExclusiveGroup) f.GetValue(null); - while (_clState.State != RunState.Quitting) - { - ReadOnlyCollectionStruct accounts = - entitiesDB.QueryEntityViews(accountGroup); - int index = 0; - foreach (AccountIdServerNode user in accounts) - { - if (index < _clState.OnlinePlayers.Count) - { - PlayerData p = _clState.OnlinePlayers[index]; - p.id = user.accountId.publicId.ToString(); - p.name = user.accountId.displayName; - p.isDev = (user.accountId.userFlags & UserFlags.Dev) == UserFlags.Dev; - _clState.OnlinePlayers[index] = p; - } - else - { - PlayerData p = default(PlayerData); - p.id = user.accountId.publicId.ToString(); - p.name = user.accountId.displayName; - p.isDev = (user.accountId.userFlags & UserFlags.Dev) == UserFlags.Dev; - _clState.OnlinePlayers.Add(p); - } - index++; - } - if (index != 0) syncPlayerPositions(); - if (index < _clState.OnlinePlayers.Count) _clState.OnlinePlayers.RemoveRange(index, _clState.OnlinePlayers.Count - index); - //API.Utility.Logging.MetaLog($"Polled {index} Online Users"); - yield return null; - } - } - - private void syncPlayerPositions() - { - if (_playerPositionFunc == null) - { - // build non-generic method using reflection - MethodInfo method = AccessTools.Method(typeof(StatusPollingEngine), "getPlayerPositionsGeneric", - generics: new[] {AccessTools.TypeByName("Game.Character.ServerCharacterPositionNode")}); - _playerPositionFunc = API.Utility.Reflection.BuildDelegate(method, this); - } - - _playerPositionFunc(); - } - - #pragma warning disable 0618 - private void getPlayerPositionsGeneric() where T : EntityView // EntityView is deprecated lol - { - ReadOnlyCollectionStruct scpnCollection = entitiesDB.QueryEntityViews(DEPRECATED_SveltoExtensions.DEPRECATED_GROUP); - //API.Utility.Logging.MetaLog($"Found {scpnCollection.Count} player positions"); - int i = 0; - foreach (T scpn in scpnCollection) - { - PlayerData p = _clState.OnlinePlayers[i]; - UnityEngine.Vector3 pos = Traverse.Create(scpn).Field("positionComponent") - .Value.position; - p.x = pos.x; - p.y = pos.y; - p.z = pos.z; - _clState.OnlinePlayers[i] = p; - i++; - } - } - #pragma warning restore 0618 - } - - private static ServerStateCache _clState = ServerStateCache.Empty(); - - internal static void Init() - { -#if DEBUG - API.Utility.Logging.MetaLog("Status Endpoint initialising"); -#endif - new StatusPollingEngine(); - // register API event callbacks - Server.Instance.InitStart += (_, __) => _clState.State = RunState.Initialising; - Server.Instance.InitComplete += (_, __) => - { - _clState.State = RunState.Initialised; - _clState.MaxPlayers = Server.Instance.GameServerSettings.GetMaxPlayers(); - }; - Server.Instance.FrameworkReady += (_, __) => - { - _clState.State = RunState.Online; - _clState.MaxPlayers = Server.Instance.GameServerSettings.GetMaxPlayers(); - }; - Server.Instance.FrameworkExit += (_, __) => _clState.State = RunState.Quitting; - } - - [WebEndpoint("/status.json")] - internal static void StatusJson(HttpListenerContext ctx) - { - ctx.Response.Headers.Add("Content-Type", "application/json"); - string json = _clState.Json(); -#if DEBUG - API.Utility.Logging.MetaLog("JSONified status: " + json); -#endif - byte[] output = Encoding.UTF8.GetBytes(json); - ctx.Response.OutputStream.Write(output, 0, output.Length); - } - } -} \ No newline at end of file diff --git a/CLre_server/WebStatus/WebServer.cs b/CLre_server/WebStatus/WebServer.cs deleted file mode 100644 index f231e53..0000000 --- a/CLre_server/WebStatus/WebServer.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Reflection; -using System.Text; -using HarmonyLib; -using Svelto.DataStructures; - -namespace CLre_server.WebStatus -{ - public class WebServer - { - private const uint DEFAULT_PORT = 5030; - private const string DEFAULT_IP = "localhost"; - private readonly HttpListener _httpListener; - - public delegate void RequestHandler(HttpListenerContext ctx); - - private Dictionary _handlers = new Dictionary(); - - public bool IsRunning - { - get => _httpListener.IsListening; - } - - private string _ip_addr; - private uint _port; - - public static WebServer MainInstance { get; internal set; } - - internal static List _assembliesToCheck = new List(new []{typeof(CLre).Assembly}); - - public WebServer() : this(DEFAULT_IP, DEFAULT_PORT) - { - } - - public WebServer(string ip, uint port) - { - if (!HttpListener.IsSupported) - { - API.Utility.Logging.LogWarning("HTTP Server is unsupported on earlier Windows versions. CLre webserver will fail to start."); - } - _httpListener = new HttpListener(); - _httpListener.Prefixes.Add($"http://{ip}:{port}/"); - _ip_addr = ip; - _port = port; - } - - internal static void Init() - { - if (CLre.Config.web_server || Environment.GetCommandLineArgs().Contains("-web")) - { - API.Utility.Logging.Log("Starting status web server"); - StatusEndpoints.Init(); - MainInstance = new WebServer(); - MainInstance.Start(); - } - else - { - API.Utility.Logging.Log("Not starting web server (use CLI argument -web to enable)"); - } - } - - internal static void Deinit() - { - if (MainInstance != null) MainInstance.Stop(); - MainInstance = null; - } - - public void Start() - { - LoadHandlers(); - try - { - _httpListener.Start(); - } - catch (Exception e) - { - API.Utility.Logging.LogWarning(e); - return; - } - - HandleAllRequests().Run(); - } - - public void Stop() - { - try - { - _httpListener.Stop(); - _httpListener.Close(); - } - catch (Exception e) - { - API.Utility.Logging.LogWarning(e); - return; - } - } - - private IEnumerator HandleAllRequests() - { - API.Utility.Logging.MetaLog($"Started HTTP web server at http://{_ip_addr}:{_port}/"); - while (_httpListener.IsListening) - { - var awaiter = _httpListener.GetContextAsync(); - awaiter.GetAwaiter().OnCompleted(() => DoRequest(awaiter.Result)); - yield return null; - } - API.Utility.Logging.MetaLog("Terminated HTTP web server"); - } - - private void DoRequest(HttpListenerContext ctx) - { - string endpoint = ctx.Request.Url.LocalPath.ToLower(); -#if DEBUG - API.Utility.Logging.LogWarning($"Handling HTTP request {endpoint}"); -#endif - bool handled = false; - foreach (string path in _handlers.Keys) - { - if (endpoint == path) - { - handled = true; - _handlers[path](ctx); - break; - } - } - - if (!handled) - { - AssetEndpoints.Asset404(ctx); - } - //byte[] output = Encoding.UTF8.GetBytes(endpoint); - //ctx.Response.OutputStream.Write(output, 0, output.Length); - ctx.Response.Close(); - } - - private void LoadHandlers() - { - _handlers = new Dictionary(); - foreach (Assembly asm in _assembliesToCheck.ToArray()) - { - foreach (Type t in asm.GetTypes()) - { - foreach (MethodInfo m in t.GetMethods(AccessTools.all)) - { - WebEndpointAttribute attr = m.GetCustomAttribute(); - if (attr != null) - { - // TODO validate that method signature matches that of RequestHandler - string key = attr.GetPath().ToLower(); - API.Utility.Logging.MetaLog($"{t.FullName}:{m.Name} is handling {key}"); - _handlers.Add(key, (RequestHandler) Delegate.CreateDelegate(typeof(RequestHandler), m)); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/README.md b/README.md index d6e694a..8b2481d 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,22 @@ # CLre Always eat your celery, so you'll grow up to be big and strong like me. -Work-in-progress mod for [Cardlife](http://Cardlifegame.com/). +Work-in-progress mod for [CardLife](http://cardlifegame.com/). -Cardlife has stopped receiving updates, but that doesn't mean it's free from bugs. -CLre is a mod to rejuvenate Cardlife by fixing old bugs and adding some modding sprinkles. +CardLife has stopped receiving updates, but that doesn't mean it's free from bugs. +CLre is a mod to rejuvenate CardLife by fixing old bugs and adding some modding sprinkles. -## Development +## Setup -### Setup - -This project requires most of Cardlife's `.dll` files to function correctly. -Most, but not all, of these files are stored in Cardlife's `Cardlife_Data\Managed` folder. +This project requires most of Cardlife's `.dll` files to function correctly. +Most, but not all, of these files are stored in Cardlife's `Cardlife_Data\Managed` folder. The project is pre-configured to look in a folder called cl in the solution's main directory or one level up from that. -You can make sure CLre can find all of `.dll` files it needs by copying your Cardlife folder beside this repo's folder and renaming it to `cl`, but that's a bit of a waste of disk space. -You can also create a symbolic link to your Cardlife install folder named `cl` in the same spot to avoid having to re-copy files. +You can make sure CLre can find all of `.dll` files it needs by copying your Cardlife folder beside this repo's folder and renaming it to `cl`, but that's a bit of a waste of disk space. +You can also create a symbolic link to your Cardlife install folder named `cl` in the same spot to avoid having to re-copy files. For example, if you cloned the repo into a folder called `CLre_repo`, this is what your folder structure would look like. -If you decide to change the `cl` folder configuration, do not commit changes to your `CLre.csproj` or `CLre_server.csproj` files otherwise your changes will be rejected. +If you decide to change the `cl` folder configuration, do not commit your `CLre.csproj` file otherwise your changes will be rejected. ``` CLre_repo/ <- CLre git project files @@ -26,18 +24,17 @@ CLre_repo/ <- CLre git project files README.md <- This file etc. -cl/ <- Cardlife files +cl/ <- CardLife files Cardlife_Data/ Managed/ <- Cardlife C# Assemblies CardlifeGameServer_Data/ - Managed/ <- Cardlife Server C# Assemblies (optional) + Managed/ <- Cardlife Standalone Server C# Assemblies (optional) ``` -For any game mod to work, you will have to patch your game with the Cardlife adaptation of [CLIPA](https://git.exmods.org/NGnius/CLIPA). -For a server mod to work, you will have to patch the server (CardlifeGameServer.exe). -The installation process is below, or you can follow the instructions for Gamecraft: [GCIPA Gamecraft install guide](https://git.exmods.org/modtainers/GCIPA/src/branch/master/README.md#how-to-install). +For any mod to work, you will have to patch your game with the Cardlife adaptation of [CLIPA](https://git.exmods.org/NGnius/CLIPA). +The installation process is roughly the same as for Gamecraft, except with a different name: [GCIPA Gamecraft install guide](https://git.exmods.org/modtainers/GCIPA/src/branch/master/README.md#how-to-install). -### Building +## Building After you've completed the setup, open the solution file `CLre.sln` in your prefered C# .NET/Mono development environment. I'd recommend Visual Studio Community Edition or JetBrains Rider. @@ -47,118 +44,4 @@ If it doesn't work and you can't figure out why, ask for help on the [Exmods Dis ## Installation -To patch Cardlife to load mods, download the latest version of [CLIPA](https://git.exmods.org/NGnius/CLIPA/releases), extract the contents into the game folder, then drag `Cardlife.exe` onto `IPA.exe`. Once the terminal window closes, drag `CardlifeGameServer.exe` onto `IPA.exe`. -If you haven't turned on "Show file extensions" in Windows, those files may appear to be named `Cardlife`, `CardlifeGameServer`, and `IPA`. -Some antivirus software may (wrongly) claim that `IPA` is a virus, but those warnings can be dismissed. -If you don't believe me, read the [CLIPA source code](https://git.exmods.org/NGnius/CLIPA). - -To install the CLre mod, copy `CLre.dll` and `0Harmony.dll` (from the release zip) into the `Plugins` folder in the Cardlife install directory. -To install the CLre_server mod, copy `CLre_server.dll` and `0Harmony.dll` (from the release zip) into the `Plugins` folder where Cardlife is installed. - -## A Note on CLre and CLre_server mods' (lack of) cooperation - -CLre is designed for the Cardlife client, and cannot be used with the Cardlife server. -Similarly, CLre_server is designed for the Cardlife server, and cannot be used with the Cardlife client. -DO NOT install CLre and CLre_server in the same `Plugins` folder, because both mods will be loaded -- guaranteeing one will break. -To install CLre and CLre_server on the same computer, create a copy of the game installation and use one copy for CLre and one for CLre_server. - -# Functionality - -## CLre - -CLre provides a minimal modding API and useful bugfixes for the Cardlife client. - -### Fixes - -As of v0.0.3, elevent (11) bugfixes are implemented. - - - InitLogSooner: Start the logger slightly sooner than Cardlife does [TARGET: CustomLoggerThread] [ID: 0] (0M/2P/1I/0W/0A/0D/3T) - - EnchantmentTableFloatParseFix: [MORE: https://trello.com/c/qawBFb7P/1-enchantment-table-fails-to-work] [ID: 1] (0M/2P/0I/0W/0A/0D/2T) - - ExclusionImprovement: [MORE: https://trello.com/c/Ue4yIqWQ/11-placing-material-in-restricted-areas] [ID: 2] (0M/2P/0I/0W/0A/0D/2T) - - ClientDurabilityNodeErrorRemover: [MORE: https://trello.com/c/YT3VbXpZ/15-durability-log-error] [ID: 3] (0M/2P/0I/0W/1A/0D/3T) - - CooldownCrossSlotSync: [MORE: https://trello.com/c/65FPrTjK/12-no-cooldown-between-inventory-slots] [ID: 4] (0M/1P/0I/0W/0A/0D/1T) - - ScrollSpeedImprovement: [MORE: https://trello.com/c/elL8IVdn/4-scroll-menus-are-insensitive] [ID: 5] (0M/1P/0I/0W/0A/0D/1T) - - MiniScreenEmbiggener: [MORE: https://trello.com/c/NAls3XaE/17-game-starts-minimized-and-wont-restore] [ID: 6] (0M/0P/1I/0W/0A/0D/1T) - - UnderStructureCollider: [MORE: https://trello.com/c/nfuaZWQZ/10-passing-through-structures] [ID: 7] (1M/1P/1I/0W/0A/0D/3T) - - TerrainModificationFailedHandler: [MORE: https://trello.com/c/Pq5lcB1p/23-moderation-tools] [ID: 8] (0M/2P/1I/1W/0A/2D/6T) - - OfflineSpawnpointSavingFloatFix: [MORE: https://trello.com/c/hpADhDhQ/21-login-goes-to-original-spawn] [ID: 9] (0M/2P/0I/0W/0A/0D/2T) - - OfflineGameTimeSavingFloatFix: Make game time save properly for everyone, even when floats contain a comma [ID: 11] (0M/1P/0I/0W/0A/0D/1T) - -The offline fixes actually correct issues in the game server while running offline, -which is why `CardlifeGameServer.exe` must be patched for CLre to work (not just for CLre_server). - -### API - -Basic engine registration and some events are exposed for modders to use. -Documentation WIP... (read the code files in the `CLre/API` directory for now) - -## CLre_server - -CLre_server provides a minimal modding API, admin HTTP server, and bugfixes for the Cardlife server. - -### Fixes - -As of v0.0.3, one (1) bugfix is implemented. - - - InitLogSooner: Start the logger slightly sooner than Cardlife does [TARGET: CustomLoggerThread] [ID: 0] (0M/2P/1I/0W/0A/0D/3T) - -### API - -Basic engine registration and some events are exposed for modders to use. -Documentation WIP... (read the code files in the `CLre_server/API` directory for now) - -### Tweaks - -CLre_server also offers a few improvements for the Cardlife server. -These are not bugfixes, but are quality-of-life additions to bring server functionality up to par with other game servers. -Improvements can be enabled and customized by modifying the `CLre_server.json` configuration file in Cardlife's install directory. - -#### HTTP Server - -The HTTP server is enabled by the `-web` command line argument, or in `CLre_server.json`. -It is disabled by default to reduce resource usage. -When enabled, the server will listen on http://localhost:5030 and provide basic server status information. -This can be accessed through any standard web browser on the same computer. -If you wish to make this publicly accessible, it is recommended to use Nginx or another web proxy system to proxy traffic to that port securely. - -Useful endpoints - -```text -GET / HTML landing page with some basic server info -GET /l/current Server output log, up-to-date as of last webpage refresh -GET /d/version Cardlife, Unity and CLre version information -GET /status.json Useful status information about players and server state in JSON format -GET /c/game.json Basically GameServerSettings.json for the running Cardlife server -``` - -#### Server Commands - -CLre_server can accept chat commands from connected players. -Chat commands can be enabled in `CLre_server.json`. -For this functionality to work, valid user credentials must also be configured. - -Commands - -```text -/echo - say -/help - show a list of commands -/list - display online users -/version - display version information - -/ban - permanently remove from this server -/deop - revoke moderator permissions -/kick - disconnect from this server -/op - grant moderator permissions -``` - -#### Terrain Modification Exclusion Zone - -This exclusion zone improvement can be enabled in `CLre_server.json`. -This prevents players from digging under a building that they do not own. -This improves on the existing exclusion zone functionality which already prevents a player from placing materials and building structures too close to another player's building. - -#### CLre-only Mode - -To prevent vanilla clients from connecting to this server, enable this restriction in `CLre_server.json`. -Enabling this functionality is not recommended. -This functionality should only be used when other code mods are installed which break compatibility with unmodded Cardlife clients. +To install the CLre mod, copy the build's `CLre.dll` into the `Plugins` folder where Cardlife is installed.