public void createConfig(string uniqueID, string uri = Constants.FALLBACK_URI, string retry = Constants.FALLBACK_HOTKEY) { Debugger.Error("Config.json for DiscordHelper not found!"); Debugger.Module("Creating Config.json.", Name); File.WriteAllText( configPath, "{\n\t\"uri\": \"" + uri + "\",\n\t\"id\": \"" + uniqueID + "\",\n\t\"retry\": \"" + retry + "\"\n}"); }
public void PreloadPlugins() { Stopwatch benchmark = Stopwatch.StartNew(); Debugger.Module("Pre loading modules"); string[] modules = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules")); foreach (string module in modules) { // Skip modules without Module.json if (!File.Exists(Path.Combine(module, "module.json"))) { continue; } try { string serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); PluginInformation modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); PluginSettings modSettings = GetPluginSettings(module); if (File.Exists(Path.Combine(module, modInformation.EntryPoint))) { Debugger.Module($"Compiling plugin: {modInformation.Name}"); if (CompilePlugin(module, modInformation)) { Debugger.Module($"{modInformation.Name} compiled successfully."); } else { continue; } } Stopwatch s = Stopwatch.StartNew(); foreach (string required in modInformation.Dependencies) { AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required))); } Assembly plugin = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll"))); IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null); if (entries.Count() > 0) { dynamic mod = plugin.CreateInstance(entries.First().ToString()); packages.Add(new PluginPackage { plugin = mod, information = modInformation, settings = modSettings, path = module }); } } catch (Exception err) { Debugger.Error(err); continue; } } IsReady = true; benchmark.Stop(); Debugger.Module($"Pre loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms"); if (QueueLoad) { LoadPlugins(); } }
private int SetupWsClient(string uri, string id) { WsClient = new WebSocket(uri + "?uniqueid=" + HttpUtility.UrlEncode(id)); WsClient.OnOpen += (sender, e) => { //Send confirmation message to HunterPie Debugger.Module("Connected to discord server.", Name); }; WsClient.OnClose += (sender, e) => { Debugger.Module("Close code: " + e.Code + " Close reason: " + e.Reason, Name); Debugger.Module("Disconnected from discord server. Press " + config.retry + " to try reconnect.", Name); }; WsClient.OnMessage += (sender, e) => { handleMessage(sender, e); }; WsClient.Connect(); return(1); }
/// <summary> /// Loads a specific plugin /// </summary> /// <param name="plugin">Plugin to be loaded</param> /// <returns>True if it was loaded successfully, false if not</returns> public static bool LoadPlugin(IPlugin plugin) { if (ctx == null) { return(false); } var name = packages.FirstOrDefault(p => p.plugin == plugin).information?.Name; try { plugin.Initialize(ctx); if (!string.IsNullOrEmpty(name)) { failedPlugins.Remove(name); } } catch (Exception ex) { Debugger.Error($"Error on initializing plugin {plugin.Name}: {ex}"); if (!string.IsNullOrEmpty(name)) { failedPlugins.Add(name); } return(false); } return(true); }
public void LoadPlugins() { Stopwatch benchmark = Stopwatch.StartNew(); if (packages.Count > 0) { // Quick load foreach (PluginPackage package in packages) { if (!package.settings.IsEnabled) { continue; } try { package.plugin.Initialize(ctx); } catch (Exception err) { Debugger.Error(err); } } } benchmark.Stop(); Debugger.Module($"Loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms"); }
internal static void LoadRecipes() { try { XmlDocument document = new XmlDocument(); document.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "HunterPie.Resources/Data/CraftingData.xml")); XmlNodeList items = document.SelectNodes("//Crafting/Item"); IEnumerable <Recipe> recipes = items.Cast <XmlNode>() .Select(node => XmlNodeToRecipe(node)); foreach (Recipe recipe in recipes) { AddNewRecipe(recipe.OutputId, recipe); } Debugger.Warn($"Loaded {recipes.Count()} different item crafting recipes!"); document = null; } catch (Exception err) { Debugger.Error($"Failed to load crafting data.\n{err}"); } }
public static async Task <bool> DownloadFileAsync(string URL, string output, string relFilepath) { try { using (HttpClient client = new HttpClient()) { byte[] data = await client.GetByteArrayAsync(new Uri(URL)); if (Path.GetDirectoryName(relFilepath).Length > 0) { string dirs = Path.GetDirectoryName(output); if (!Directory.Exists(dirs)) { Directory.CreateDirectory(dirs); } } File.WriteAllBytes(output, data); return(true); } } catch (Exception err) { Debugger.Error(err); return(false); } }
public bool CompilePlugin(string pluginPath, PluginInformation information) { var compiler = CSharpCompilation.Create($"{nameof(HunterPie)}{information.Name}", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithOptimizationLevel(OptimizationLevel.Release)); var types = new[] { typeof(Hunterpie), // HunterPie typeof(JObject), // Newtonsoft.Json.dll typeof(Object), // mscorlib.dll typeof(UIElement), // PresentationCore.dll typeof(Window), // PresentationFramework.dll typeof(Uri), // System.dll typeof(Enumerable), // System.Core.dll typeof(DataSet), // System.Data.dll typeof(DataTableExtensions), // System.Data.DataSetExtensions.dll typeof(Bitmap), // System.Drawing.dll typeof(HttpClient), // System.Net.Http.dll typeof(BigInteger), // System.Numerics.dll typeof(Form), // System.Windows.Forms.dll typeof(XamlType), // System.Xaml.dll typeof(XmlNode), // System.Xml.dll typeof(XNode), // System.Xml.Linq.dll typeof(Rect), // WindowsBase.dll }; // Load all basic dependencies List <MetadataReference> references = types.Select(type => MetadataReference.CreateFromFile(type.Assembly.Location)).ToList <MetadataReference>(); if (information.Dependencies != null) { foreach (string extDependency in information.Dependencies) { references.Add(MetadataReference.CreateFromFile(Path.Combine(pluginPath, extDependency))); } } compiler = compiler.AddReferences(references); var code = File.ReadAllText(Path.Combine(pluginPath, information.EntryPoint)); var options = CSharpParseOptions.Default.WithLanguageVersion( LanguageVersion.CSharp7_3); var syntaxTree = SyntaxFactory.ParseSyntaxTree(SourceText.From(code, Encoding.UTF8), options, Path.Combine(pluginPath, information.EntryPoint)); compiler = compiler.AddSyntaxTrees(syntaxTree); var result = compiler.Emit(Path.Combine(pluginPath, information.Name) + ".dll"); if (result.Success) { return(true); } else { Debugger.Error($"Failed to compile plugin: {information.Name}"); foreach (var exception in result.Diagnostics) { Debugger.Error(exception); } return(false); } }
public void UnloadPlugins() { foreach (PluginPackage package in packages) { UnloadPlugin(package.plugin); } Debugger.Module("Unloaded all modules."); }
public void UnloadPlugins() { foreach (IPlugin plugin in plugins) { plugin.Unload(); } Debugger.Module("Unloaded all modules."); }
public void LoadPlugins(Game ctx) { Stopwatch benchmark = Stopwatch.StartNew(); if (plugins.Count > 0) { // Quick load foreach (IPlugin plugin in plugins) { plugin.Initialize(ctx); } } else { string[] modules = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules")); foreach (string module in modules) { try { string serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); PluginInformation modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); if (File.Exists(Path.Combine(module, modInformation.EntryPoint))) { Debugger.Module($"Compiling plugin: {modInformation.Name}"); if (CompilePlugin(module, modInformation)) { Debugger.Module($"{modInformation.Name} compiled successfully."); } else { continue; } } foreach (string required in modInformation.Dependencies) { AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required))); } var plugin = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll"))); IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null); if (entries.Count() > 0) { dynamic mod = plugin.CreateInstance(entries.First().ToString()); mod.Initialize(ctx); plugins.Add(mod); } } catch (Exception err) { Debugger.Error(err); continue; } } } benchmark.Stop(); Debugger.Module($"Loaded {plugins.Count} module(s) in {benchmark.ElapsedMilliseconds}ms"); }
/// <summary> /// Turns a sGear list into a charm list string that can be used in Honey Hunters World /// </summary> /// <param name="gear">sGear list with the charm information</param> /// <returns>string structure</returns> public static string ExportCharmsToHoney(sGear[] gear) { if (HoneyGearData == null) { LoadHoneyGearData(); } StringBuilder data = new StringBuilder(); // Filter based on only on charms sGear[] charms = gear.Where(x => x.Type == (uint)GearType.Charm).ToArray(); // Parse charms into a dictionary to make it easier to organize the string structure Dictionary <int, int> sCharms = new Dictionary <int, int>(); foreach (sGear charm in charms) { // Check if player doesn't have that gear if (charm.Category != 2) { continue; } int HoneyCharmId = GetCharmHoneyIdByGameId(charm.Id); int level = GetCharmLevel(charm.Id); // unique charms have level 0, but we need them to become 1 in order to Honey recoginize them level = level == 0 ? level + 1 : level; if (sCharms.ContainsKey(HoneyCharmId)) { //If the level we find is actually larger, use that instead if (sCharms[HoneyCharmId] < level) { sCharms[HoneyCharmId] = level; } } else { sCharms[HoneyCharmId] = level; } } // Now we build the charm string structure const int MaxCharmId = 108; for (int i = 1; i <= MaxCharmId; i++) { data.Append($"{(i != 1 ? "," : "")}{(sCharms.ContainsKey(i) ? sCharms[i] : 0)}"); } Debugger.Debug(data); UnloadHoneyGearData(); return(data.ToString()); }
/// <summary> /// Unloads a specific plugin /// </summary> /// <param name="plugin">The plugin to be unloaded</param> /// <returns>True if the plugin was unloaded successfully, false otherwise</returns> public static bool UnloadPlugin(IPlugin plugin) { if (ctx == null) { return(true); } try { plugin.Unload(); return(true); } catch (Exception err) { Debugger.Error(err); return(false); } }
public async void Delete() { try { if (plugin.IsFailed) { // if plugin loading failed, it can already been loaded into AppDomain, so it isn't safe to delete it right away // because dll's may be in use PluginManager.MarkForRemoval(InternalName); } else if (plugin.IsLoaded && plugin.Package.HasValue) { // begin plugin toggle process in other thread await pluginToggleTask; pluginToggleTask = SetPluginEnabled(false); await pluginToggleTask.ConfigureAwait(false); // NOTE: synchronisation might be helpful here, but I don't anticipate multiple calls to this method // in short succession, so it is kept simpler PluginManager.MarkForRemoval(InternalName); } else { try { PluginManager.DeleteNonPreloadedPlugin(InternalName); } catch (Exception ex) { Dispatch(() => MessageBox.Show(ex.Message)); Debugger.Warn(ex); PluginManager.MarkForRemoval(InternalName); } } Dispatch(() => { pluginList.UpdatePluginsArrangement(); OnPropertyChanged(nameof(IsEnabled)); }); } catch (Exception ex) { Dispatch(() => MessageBox.Show(ex.Message)); } }
static string BuildCustomPartsStructure(int WeaponType, GameStructs.CustomAugment[] CustomAugments, bool ShowError) { StringBuilder[] Structure = new StringBuilder[5]; for (int cAugmentIndex = 0; cAugmentIndex < CustomAugments.Length; cAugmentIndex++) { GameStructs.CustomAugment cAugment = CustomAugments[cAugmentIndex]; // Skip empty slots if (cAugment.ID == byte.MaxValue) { continue; } string AugmentType = HoneyGearData.SelectSingleNode($"//Honey/Weapons/Custom").ChildNodes[WeaponType].SelectSingleNode($"Part[@Level='{cAugment.Level + 1}' and @ID='{cAugment.ID}']/@Type")?.Value; // If we dont find the augment id, then we try the wildcard ones, since there are some // missing IDs if (AugmentType == null) { AugmentType = HoneyGearData.SelectSingleNode($"//Honey/Weapons/Custom").ChildNodes[WeaponType].SelectSingleNode($"Part[@Level='{cAugment.Level + 1}' and @ID='?']/@Type")?.Value; } // If the augment is still null, then it isn't supported yet. In this case we display an error // with the augment ID, so it's easier to map it. if (AugmentType == null && ShowError) { Debugger.Error($"Unsupported custom augment (ID = {cAugment.ID}, Level = {cAugment.Level})"); continue; } // Initializes StringBuilder if it isn't initialized yet int.TryParse(AugmentType, out int parsed); if (Structure[parsed] == null) { Structure[parsed] = new StringBuilder(); } Structure[parsed].Append((cAugment.Level + 1).ToString()); } StringBuilder JoinedResult = new StringBuilder(); foreach (StringBuilder SubBuilder in Structure) { JoinedResult.Append(SubBuilder?.ToString() + ";"); } JoinedResult.Remove(JoinedResult.Length - 1, 1); return(JoinedResult.ToString()); }
static string GetWeaponHoneyID(int WeaponType, int WeaponID) { XmlNodeList nl = HoneyGearData.SelectSingleNode($"//Honey/Weapons").ChildNodes; if (WeaponType > nl.Count) { return("0"); } XmlNode WeaponNode = nl[WeaponType]; string wID = WeaponNode.SelectSingleNode($"Weapon[@ID='{WeaponID}']/@HoneyID")?.Value ?? "0"; if (wID == "0") { Debugger.Error($"Unsupported weapon ID: {WeaponID}"); } return(wID); }
internal static void LoadRecipes() { try { XmlDocument document = new XmlDocument(); document.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "HunterPie.Resources/Data/CraftingData.xml")); XmlNodeList items = document.SelectNodes("//Crafting/Item"); list = items.Cast <XmlNode>() .Select(node => XmlNodeToRecipe(node)) .ToDictionary(m => m.OutputId); Debugger.Warn("Loaded crafting data!"); document = null; } catch (Exception err) { Debugger.Error($"Failed to load crafting data.\n{err}"); } }
internal static async Task <string> ReadOnlineModuleJson(string URL) { string url = URL; if (!URL.EndsWith("module.json")) { url = $"{URL}/module.json"; } try { using (HttpClient client = new HttpClient()) { return(await client.GetStringAsync(new Uri(url))); } } catch (Exception err) { Debugger.Error(err); return(null); } }
public async Task <bool> PreloadPlugins() { Stopwatch benchmark = Stopwatch.StartNew(); Debugger.Module("Pre loading modules"); foreach (string module in IterateModules()) { try { string serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); PluginInformation modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); try { await PreloadPlugin(module, modInformation); failedPlugins.Remove(modInformation.Name); } catch { failedPlugins.Add(modInformation.Name); throw; } } catch (Exception err) { Debugger.Error(err); } } benchmark.Stop(); Debugger.Module($"Pre loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms"); if (!tsc.Task.IsCompleted) { tsc.SetResult(null); } return(true); }
/// <summary> /// Unloads a specific plugin /// </summary> /// <param name="plugin">The plugin to be unloaded</param> /// <returns>True if the plugin was unloaded successfully, false otherwise</returns> public static bool UnloadPlugin(IPlugin plugin) { if (ctx == null) { return(true); } try { // This means this plugin is not loaded, so we skip it if (plugin.Context == null) { return(true); } plugin.Unload(); return(true); } catch (Exception err) { Debugger.Error(err); return(false); } }
public async Task LoadPlugins() { await PreloadTask; Stopwatch benchmark = Stopwatch.StartNew(); if (packages.Count > 0) { // Quick load foreach (PluginPackage package in packages.Where(p => p.settings.IsEnabled)) { try { package.plugin.Initialize(ctx); } catch (Exception err) { Debugger.Error(err); } } } benchmark.Stop(); Debugger.Module($"Loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms"); }
/// <summary> /// Turns a sItem list into a decoration list string that can be used in Honey Hunters World /// </summary> /// <param name="decorations">sItem list with the decorations information</param> /// <returns>string structure</returns> public static string ExportDecorationsToHoney(sItem[] decorations) { if (HoneyGearData == null) { LoadHoneyGearData(); } StringBuilder data = new StringBuilder(); // Parse decorations into a dictionary to make it easier to organize the string structure Dictionary <int, int> sDecorations = new Dictionary <int, int>(); foreach (sItem deco in decorations) { int HoneyDecoId = GetDecorationHoneyIdByGameId(deco.ItemId); if (sDecorations.ContainsKey(HoneyDecoId)) { sDecorations[HoneyDecoId] += deco.Amount; } else { sDecorations[HoneyDecoId] = deco.Amount; } } // Now we build the decoration string structure const int MaxDecoId = 401; for (int i = 1; i <= MaxDecoId; i++) { data.Append($"{(i != 1 ? "," : "")}{(sDecorations.ContainsKey(i) ? GetDecorationAmountLimit(i, sDecorations[i]) : 0)}"); } Debugger.Debug(data); UnloadHoneyGearData(); return(data.ToString()); }
// Integration with Honey Hunter World peepoHappy public static string LinkStructureBuilder(GameStructs.Gear Build) { if (HoneyGearData == null) { LoadHoneyGearData(); } StringBuilder LinkBuilder = new StringBuilder(); LinkBuilder.Append(HoneyLink); // Basic data LinkBuilder.Append(GetWeaponHoneyID(Build.Weapon.Type, Build.Weapon.ID) + ","); LinkBuilder.Append(GetGearHoneyID("Helms", "Helm", Build.Helmet.ID) + ","); LinkBuilder.Append(GetGearHoneyID("Armors", "Armor", Build.Chest.ID) + ","); LinkBuilder.Append(GetGearHoneyID("Arms", "Arm", Build.Hands.ID) + ","); LinkBuilder.Append(GetGearHoneyID("Waists", "Waist", Build.Waist.ID) + ","); LinkBuilder.Append(GetGearHoneyID("Legs", "Leg", Build.Legs.ID) + ","); LinkBuilder.Append(GetGearHoneyID("Charms", "Charm", Build.Charm.ID) + ","); // Augments int AugmentsTotal = 0; for (int AugmentIndex = 0; AugmentIndex < Build.Weapon.NewAugments.Length; AugmentIndex++) { string AugId = GetNewAugment(Build.Weapon.NewAugments[AugmentIndex].ID); if (Build.Weapon.NewAugments[AugmentIndex].Level == 0) { continue; } else { AugmentsTotal++; } if (AugmentsTotal > 1) { LinkBuilder.Append($";{AugId}:{Build.Weapon.NewAugments[AugmentIndex].Level}"); } else { LinkBuilder.Append($"{AugId}:{Build.Weapon.NewAugments[AugmentIndex].Level}"); } } // Custom Augments LinkBuilder.Append("-"); LinkBuilder.Append(BuildCustomPartsStructure(Build.Weapon.Type, Build.Weapon.CustomAugments)); // Awakening Skills LinkBuilder.Append("-"); LinkBuilder.Append(BuildAwakeningSkillsStructure(Build.Weapon.Awakenings)); LinkBuilder.Append(",0,0"); // Decorations int[] ExtraSlotAwakening = new int[3] { 38, 39, 40 }; bool HasExtraSlot = Build.Weapon.Awakenings.Where(deco => ExtraSlotAwakening.Contains(deco.ID)).ToArray().Length > 0; LinkBuilder.Append(BuildDecorationStringStructure(Build.Weapon.Decorations, isWeapon: true, HasDecorationExtraSlot: HasExtraSlot)); LinkBuilder.Append(BuildDecorationStringStructure(Build.Helmet.Decorations)); LinkBuilder.Append(BuildDecorationStringStructure(Build.Chest.Decorations)); LinkBuilder.Append(BuildDecorationStringStructure(Build.Hands.Decorations)); LinkBuilder.Append(BuildDecorationStringStructure(Build.Waist.Decorations)); LinkBuilder.Append(BuildDecorationStringStructure(Build.Legs.Decorations)); // The rest LinkBuilder.Append("," + GetCharmLevel(Build.Charm.ID)); LinkBuilder.Append(":" + GetMantleHoneyID(Build.SpecializedTools[0].ID)); LinkBuilder.Append(":" + GetMantleHoneyID(Build.SpecializedTools[1].ID)); LinkBuilder.Append(BuildDecorationStringStructure(Build.SpecializedTools[0].Decorations, 2).Replace(',', ':')); LinkBuilder.Append(BuildDecorationStringStructure(Build.SpecializedTools[1].Decorations, 2).Replace(',', ':')); // Bowgun mods if (Build.Weapon.Type == 12 || Build.Weapon.Type == 13) { foreach (GameStructs.BowgunMod bowgunMod in Build.Weapon.BowgunMods) { LinkBuilder.Append("," + (HoneyGearData.SelectSingleNode($"//Honey/Weapons/BowgunMods/Mod[@ID='{bowgunMod.ID}']/@HoneyID")?.Value ?? "none")); } } Debugger.Debug(LinkBuilder); UnloadHoneyGearData(); return(LinkBuilder.ToString()); }
public async Task <bool> PreloadPlugins() { Stopwatch benchmark = Stopwatch.StartNew(); Debugger.Module("Pre loading modules"); string[] modules = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules")); foreach (string module in modules) { // Skip modules without Module.json if (!File.Exists(Path.Combine(module, "module.json"))) { continue; } try { string serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); PluginInformation modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); if (modInformation.Update.MinimumVersion is null) { Debugger.Error($"{modInformation.Name.ToUpper()} MIGHT BE OUTDATED! CONSIDER UPDATING IT."); } if (PluginUpdate.PluginSupportsUpdate(modInformation)) { switch (await PluginUpdate.UpdateAllFiles(modInformation, module)) { case UpdateResult.Updated: serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); Debugger.Module($"Updated plugin: {modInformation.Name} (ver {modInformation.Version})"); break; case UpdateResult.Skipped: break; case UpdateResult.Failed: Debugger.Error($"Failed to update plugin: {modInformation.Name}"); continue; case UpdateResult.UpToDate: Debugger.Module($"Plugin {modInformation.Name} is up-to-date (ver {modInformation.Version})"); break; } } PluginSettings modSettings = GetPluginSettings(module); if (!string.IsNullOrEmpty(modInformation.EntryPoint) && File.Exists(Path.Combine(module, modInformation.EntryPoint))) { Debugger.Module($"Compiling plugin: {modInformation.Name}"); if (CompilePlugin(module, modInformation)) { Debugger.Module($"{modInformation.Name} compiled successfully."); } else { continue; } } Stopwatch s = Stopwatch.StartNew(); foreach (string required in modInformation.Dependencies) { AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required))); } Assembly plugin = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll"))); IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null); if (entries.Count() > 0) { dynamic mod = plugin.CreateInstance(entries.First().ToString()); packages.Add(new PluginPackage { plugin = mod, information = modInformation, settings = modSettings, path = module }); } } catch (Exception err) { Debugger.Error(err); continue; } } IsReady = true; benchmark.Stop(); Debugger.Module($"Pre loaded {packages.Count} module(s) in {benchmark.ElapsedMilliseconds}ms"); if (QueueLoad) { LoadPlugins(); } return(true); }
private async Task PreloadPlugin(string module, PluginInformation modInformation) { if (File.Exists(Path.Combine(module, ".remove"))) { Directory.Delete(module, true); Debugger.Module($"Plugin {modInformation.Name} removed."); return; } if (modInformation.Update.MinimumVersion is null) { Debugger.Error($"{modInformation.Name.ToUpper()} MIGHT BE OUTDATED! CONSIDER UPDATING IT."); } if (PluginUpdate.PluginSupportsUpdate(modInformation)) { switch (await PluginUpdate.UpdateAllFiles(modInformation, module)) { case UpdateResult.Updated: var serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); Debugger.Module($"Updated plugin: {modInformation.Name} (ver {modInformation.Version})"); break; case UpdateResult.Skipped: break; case UpdateResult.Failed: Debugger.Error($"Failed to update plugin: {modInformation.Name}"); break; case UpdateResult.UpToDate: Debugger.Module($"Plugin {modInformation.Name} is up-to-date (ver {modInformation.Version})"); break; } } PluginSettings modSettings = GetPluginSettings(module); if (!string.IsNullOrEmpty(modInformation.EntryPoint) && File.Exists(Path.Combine(module, modInformation.EntryPoint))) { Debugger.Module($"Compiling plugin: {modInformation.Name}"); if (CompilePlugin(module, modInformation)) { Debugger.Module($"{modInformation.Name} compiled successfully."); } else { return; } } foreach (string required in modInformation.Dependencies) { AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required))); } Assembly plugin = AppDomain.CurrentDomain.Load( AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll"))); IEnumerable <Type> entries = plugin.ExportedTypes.Where(exp => exp.GetMethod("Initialize") != null); if (entries.Any()) { dynamic mod = plugin.CreateInstance(entries.First().ToString()); packages.Add(new PluginPackage { plugin = mod, information = modInformation, settings = modSettings, path = module }); } }
private async Task PreloadPlugin(string module, PluginInformation modInformation) { if (File.Exists(Path.Combine(module, ".remove"))) { Directory.Delete(module, true); Debugger.Module($"Plugin {modInformation.Name} removed."); return; } if (modInformation.Update.MinimumVersion is null) { Debugger.Error($"{modInformation.Name.ToUpper()} MIGHT BE OUTDATED! CONSIDER UPDATING IT."); } if (PluginUpdate.PluginSupportsUpdate(modInformation)) { switch (await PluginUpdate.UpdateAllFiles(modInformation, module)) { case UpdateResult.Updated: var serializedModule = File.ReadAllText(Path.Combine(module, "module.json")); modInformation = JsonConvert.DeserializeObject <PluginInformation>(serializedModule); Debugger.Module($"Updated plugin: {modInformation.Name} (ver {modInformation.Version})"); break; case UpdateResult.Skipped: break; case UpdateResult.Failed: Debugger.Error($"Failed to update plugin: {modInformation.Name}"); break; case UpdateResult.UpToDate: Debugger.Module($"Plugin {modInformation.Name} is up-to-date (ver {modInformation.Version})"); break; } } PluginSettings modSettings = GetPluginSettings(module); if (!string.IsNullOrEmpty(modInformation.EntryPoint) && File.Exists(Path.Combine(module, modInformation.EntryPoint))) { Debugger.Module($"Compiling plugin: {modInformation.Name}"); if (CompilePlugin(module, modInformation)) { Debugger.Module($"{modInformation.Name} compiled successfully."); } else { return; } } foreach (string required in modInformation.Dependencies) { AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(Path.Combine(module, required))); } var moduleAssembly = AppDomain.CurrentDomain.Load( AssemblyName.GetAssemblyName(Path.Combine(module, $"{modInformation.Name}.dll")) ); var pluginType = moduleAssembly.ExportedTypes.FirstOrDefault(exp => exp.GetMethod("Initialize") != null); if (pluginType != null) { var plugin = (IPlugin)moduleAssembly.CreateInstance(pluginType.FullName); // making sure that name is matching modInformation, e.g. if plugin dev forgot to populate this value plugin.Name = modInformation.Name; var package = new PluginPackage { plugin = plugin, information = modInformation, settings = modSettings, path = module }; packages.Add(package); // if plugin is enabled, adding it's settings if (modSettings.IsEnabled) { AddPackageSettings(package); } } }
/// <summary> /// Turns a sItem list into a decoration list string that can be used in Honey Hunters World /// </summary> /// <param name="decorations">sItem array with the decorations information</param> /// <param name="gears">sGear array with the gear information</param> /// <returns>string structure</returns> public static string ExportDecorationsToHoney(sItem[] decorations, sGear[] gears) { if (HoneyGearData == null) { LoadHoneyGearData(); } StringBuilder data = new StringBuilder(); // Merge decorations in box and decorations in gear List <sItem> decoMerge = decorations.ToList <sItem>(); foreach (sGear gear in gears) { // Skip gear the player does not have anymore if (gear.Category == uint.MaxValue) { continue; } // Skip charms if (gear.Category == 2) { continue; } if (gear.DecorationSlot1 != uint.MaxValue) { decoMerge.Add(new sItem { Amount = 1, ItemId = GetDecorationGameIdById((int)gear.DecorationSlot1) }); } if (gear.DecorationSlot2 != uint.MaxValue) { decoMerge.Add(new sItem { Amount = 1, ItemId = GetDecorationGameIdById((int)gear.DecorationSlot2) }); } if (gear.DecorationSlot3 != uint.MaxValue) { decoMerge.Add(new sItem { Amount = 1, ItemId = GetDecorationGameIdById((int)gear.DecorationSlot3) }); } } decorations = decoMerge.ToArray <sItem>(); // Parse decorations into a dictionary to make it easier to organize the string structure Dictionary <int, int> sDecorations = new Dictionary <int, int>(); foreach (sItem deco in decorations) { int HoneyDecoId = GetDecorationHoneyIdByGameId(deco.ItemId); int StacksWith = GetStacksWithDecorationId(deco.ItemId); if (sDecorations.ContainsKey(HoneyDecoId)) { sDecorations[HoneyDecoId] += deco.Amount; } else { sDecorations[HoneyDecoId] = deco.Amount; } if (StacksWith != int.MaxValue) { StacksWith = GetDecorationHoneyIdByGameId(StacksWith); if (sDecorations.ContainsKey(StacksWith)) { sDecorations[HoneyDecoId] += sDecorations[StacksWith]; sDecorations[StacksWith] += deco.Amount; } } } // Now we build the decoration string structure const int MaxDecoId = 401; for (int i = 1; i <= MaxDecoId; i++) { data.Append($"{(i != 1 ? "," : "")}{(sDecorations.ContainsKey(i) ? GetDecorationAmountLimit(i, sDecorations[i]) : 0)}"); } Debugger.Debug(data); Debugger.Debug($"Total unique decorations found: {sDecorations.Count}"); UnloadHoneyGearData(); return(data.ToString()); }
public static async Task <UpdateResult> UpdateAllFiles(PluginInformation pInformation, string modPath) { var updateUrl = await PluginRegistryService.Instance.GetModuleUpdateUrl(pInformation); string onlineSerializedInformation = await ReadOnlineModuleJson(updateUrl); if (onlineSerializedInformation is null) { //Debugger.Error($"Failed to update plugin: {pInformation.Name}!"); return(UpdateResult.Failed); } PluginInformation onlineInformation = JsonConvert.DeserializeObject <PluginInformation>(onlineSerializedInformation); if (!IsVersionOk(onlineInformation.Update.MinimumVersion)) { Debugger.Warn($"Newest version of {pInformation.Name} requires HunterPie v{onlineInformation.Update.MinimumVersion}!"); return(UpdateResult.Skipped); } UpdateResult result = UpdateResult.UpToDate; foreach (string filePath in onlineInformation.Update.FileHashes.Keys) { string onlineHash = onlineInformation.Update.FileHashes[filePath]; if (onlineHash.ToLower() == "installonly" && File.Exists(Path.Combine(modPath, filePath))) { continue; } if (pInformation.Update.FileHashes.ContainsKey(filePath)) { string localHash = pInformation.Update.FileHashes[filePath]; if (onlineHash.ToLower() != localHash.ToLower() || !File.Exists(Path.Combine(modPath, filePath))) { string outputPath = Path.Combine(modPath, filePath); if (!(await DownloadFileAsync($"{updateUrl}/{filePath}", outputPath, filePath))) { return(UpdateResult.Failed); } result = UpdateResult.Updated; } } else { string outputPath = Path.Combine(modPath, filePath); if (!(await DownloadFileAsync($"{updateUrl}/{filePath}", outputPath, filePath))) { return(UpdateResult.Failed); } result = UpdateResult.Updated; } } return(await DownloadFileAsync($"{updateUrl}/module.json", Path.Combine(modPath, "module.json"), "module.json") ? result : UpdateResult.Failed); }