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