using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Threading; using System.Windows.Controls; using Global.API.Discord; using Global.API.Util; using Global.Config; using Global.Patches; using Global.Shared.Config; using Global.Shared.Logging; using Global.Shared.Patching; using Global.Shared.Plugin; using HarmonyLib; using Sandbox.Game.GameSystems; using SENetworkAPI; using Torch; using Torch.API; using Torch.API.Managers; using Torch.API.Plugins; using Torch.Managers; using Torch.Managers.PatchManager; using Torch.Views; using Timer = System.Timers.Timer; namespace Global { public class GlobalPlugin : TorchPluginBase, IGlobalPlugin, IWpfPlugin { private const ushort ModId = 21031; private const string ModName = "GlobalClientMod"; public static Persistent PersistentConfig; private bool _init; public static LegacyConfig LegacyConfig { get; private set; } public IPluginConfig Config => WpfConfig; public static WpfConfig WpfConfig => PersistentConfig?.Data; public static AudioSendManager AudioManager { get; private set; } public long LastSent { get; private set; } = -1; public bool SentDiscord { get; private set; } public long Tick { get; private set; } public bool Started { get; private set; } public IPluginLogger Log { get; } = new TorchLogger("GlobalTorch"); public void Run(Action action) { Torch.Invoke(action); } public UserControl GetControl() { return new PropertyGrid { DataContext = WpfConfig }; } public override void Init(ITorchBase torch) { #if DEBUG // Allow the debugger some time to connect once the plugin assembly is loaded Thread.Sleep(100); #endif base.Init(torch); if (!File.Exists("opus.dll")) using (var destination = File.Create("opus.dll")) { using (var manifestResourceStream = typeof(GlobalPlugin).Assembly.GetManifestResourceStream("Global.opus.dll")) { if (manifestResourceStream != null) manifestResourceStream.CopyTo(destination); else throw new Exception("Could not find opus.dll"); } } SetupConfig(); if (LegacyConfig.OverwriteLogs) { // GlobalLogManager.PatchToUseCustomFileLogger("Keen"); // GlobalLogManager.PatchToUseCustomFileLogger("Torch"); } GlobalInstance.SetPlugin(this); // AudioManager = new AudioSendManager(Torch, Config); // Torch.Managers.AddManager(AudioManager); // Torch.Managers.AddManager(new ConsoleManager(Torch)); Patcher.InitilizePatcherContext(Torch.Managers.GetManager().AcquireContext()); if (!PatchHelpers.PatchAll(Log, new Harmony("Draconis.GlobalTorch"))) { Log.Error("Failed to patch all"); return; } MyScriptManagerPatch.ApplyPluginAPIPatch(); Log.Info("GlobalTorch Plugin Initialized"); if (LegacyConfig.EnableNexusIntegration) { var pluginManager = Torch.Managers.GetManager(); if (pluginManager.Plugins.TryGetValue(NexusIntegration.NexusId, out _)) { Log.Info("Nexus Plugin Found, Loading Nexus Integration"); NexusIntegration.Load(); } else { Log.Info("Nexus Plugin Not Found, Nexus Integration Not Loaded"); } } var timer = new Timer(15000); timer.Elapsed += (sender, args) => { if (!Started || Torch.GameState > TorchGameState.Loaded) return; if (!string.IsNullOrWhiteSpace(WpfConfig.HeartbeatUrl)) { if (LastSent != Tick) try { var request = WebRequest.Create(WpfConfig.HeartbeatUrl); using (var res = request.GetResponse()) { } } catch (Exception e) { Log.Error(e, $"Error sending heartbeat to {WpfConfig.HeartbeatUrl}"); } else Log.Error("Game crashed, not sending."); } if (LastSent == Tick && WpfConfig.SendDiscordStatus && !SentDiscord) try { var discordWebhook = new DiscordWebhook { Url = "https://discord.com/api/webhooks/966330173303689297/9-71wWH7XQjXKVg92kFIaFQl8lFdtjsCWfsEWLQH2SeZP2Zc7tA_AbbovSGeN4asFCwZ" }; var discordMessage = new DiscordMessage { Content = $"<@&671423106102853642> {Torch.Config.InstanceName} HAS GONE DOWN!", Username = Torch.Config.InstanceName, AllowedMentions = new DiscordAllowedMentions { Parse = new List { "roles" } } }; discordWebhook.Send(discordMessage); SentDiscord = true; } catch (Exception e) { Log.Error(e, "Error sending discord status"); } LastSent = Tick; }; timer.Enabled = true; } public override void Update() { Tick++; if (!_init) { GlobalStatic.Init(); // if (Config.EnableBoundingPatches) // MyAPIGateway.Entities = new MyEntitiesButBetter(MyAPIGateway.Entities); _init = true; if (!NetworkAPI.IsInitialized) NetworkAPI.Init(ModId, ModName); Traverse.Create().Field("MAX_DISTANCE_RELATIVE_DAMPENING") .SetValue(LegacyConfig.PatchesConfig.MaxDistanceRelativeDamping); Traverse.Create().Field("MAX_DISTANCE_RELATIVE_DAMPENING_SQ").SetValue( LegacyConfig.PatchesConfig.MaxDistanceRelativeDamping * LegacyConfig.PatchesConfig.MaxDistanceRelativeDamping); Log.Info("GlobalTorch Plugin Initialized"); Started = true; } GlobalStatic.Update(); } public void SetupConfig() { var wpfConfigPath = Path.Combine(StoragePath, "Global2.cfg"); PersistentConfig = Persistent.Load(wpfConfigPath); var configPath = $"{StoragePath}\\GlobalTorch.xml"; LegacyConfig = File.Exists(configPath) ? FileUtils.ReadFromXmlFile(configPath) : new LegacyConfig(); FileUtils.WriteToXmlFile(configPath, LegacyConfig); } public static bool IsLoggingLevel(LoggingLevel level) { if (WpfConfig == null) return level.IsOfLevel(LoggingLevel.Info); return WpfConfig.Level.IsOfLevel(level); } } }