private IModData GetModData(IModManifest manifest) { var storage = new ModStorage(manifest); var config = storage.Load <ModConfig>("config.json"); var defaultConfig = storage.Load <ModConfig>("default-config.json"); if (config == null && defaultConfig == null) { config = new ModConfig(); defaultConfig = new ModConfig(); } else if (defaultConfig != null && config == null) { config = defaultConfig; } else if (defaultConfig != null) { foreach (var setting in defaultConfig.Settings) { if (!config.Settings.ContainsKey(setting.Key)) { config.Settings.Add(setting.Key, setting.Value); } } } storage.Save(config, "config.json"); return(new ModData(manifest, config, defaultConfig)); }
private IModHelper CreateModHelper(IModData modData) { var logger = new ModLogger(_owmlConfig, modData.Manifest); var console = OutputFactory.CreateOutput(_owmlConfig, _logger, modData.Manifest); var assets = new ModAssets(console, modData.Manifest); var storage = new ModStorage(console, modData.Manifest); var events = new ModEvents(logger, console, _harmonyHelper); var interaction = new ModInteraction(_modList, new InterfaceProxyFactory(), modData.Manifest); return(new ModHelper.ModHelper(logger, console, _harmonyHelper, events, assets, storage, _menus, modData.Manifest, modData.Config, _owmlConfig, interaction)); }
private static void DownloadPack() { using (Pack p = Modifi.DefaultPack) { ILogger log = Modifi.DefaultLogger; log.Information("Downloading modpack."); log.Information(Environment.NewLine); IDomain curseforge; try { curseforge = DomainHelper.LoadDomain(p, "curseforge"); } catch (DllNotFoundException) { log.Error("Cannot install mods; curseforge domain handler not found."); return; } IDomainHandler handler = curseforge.GetDomainHandler(); using (ModStorage storage = new ModStorage(p.Installed, curseforge)) { IEnumerable <ModMetadata> mods = storage.GetAllMods(); foreach (ModMetadata mod in mods) { log.Information("Installing: {0:l}", mod.GetName()); ModStatus status; try { status = storage.GetModStatus(mod); } catch (Exception) { log.Error("Error: Mod marked installed but checksum did not match."); log.Error("Please use the remove command and re-add it, or download the version manually."); continue; } switch (status) { case ModStatus.Installed: log.Information("Skipping, already installed."); log.Information(Environment.NewLine); continue; case ModStatus.Requested: ModVersion version = storage.GetMod(mod); log.Information("Requested Version: {0:l} ({1})", version.GetVersionName(), version.GetModVersion()); try { ModDownloadResult result = handler.DownloadMod(version, Settings.ModPath).Result; storage.MarkInstalled(mod, version, result); log.Information("Downloaded to {0}.", result.Filename); log.Information(Environment.NewLine); } catch (Exception e) { log.Error(e.Message); log.Error(Environment.NewLine); } break; } } } } }
public static void HandleModRemove(IDomain domain, string modIdentifier) { IDomainHandler handler = domain.GetDomainHandler(); ModStorage storage = new ModStorage(Modifi.DefaultPack.Installed, domain); ModMetadata meta = storage.GetMetadata(modIdentifier); if (meta == null) { Modifi.DefaultLogger.Error("Cannot uninstall {0}; it is not installed.", modIdentifier); return; } ModVersion installed = storage.GetMod(meta); ModStatus status = storage.GetModStatus(meta); switch (status) { case ModStatus.NotInstalled: Modifi.DefaultLogger.Error("Cannot uninstall {0}; it is not installed.", meta.GetName()); return; case ModStatus.Requested: Modifi.DefaultLogger.Information("Removing {0}...", meta.GetName()); storage.Delete(meta); Modifi.DefaultLogger.Information("Done."); return; case ModStatus.Installed: Modifi.DefaultLogger.Information("Removing {0} and deleting files...", meta.GetName()); storage.Delete(meta); string filePath = Path.Combine(Settings.ModPath, installed.Filename); bool correctChecksum = ModUtilities.ChecksumMatches(filePath, installed.Checksum); if (correctChecksum) { try { File.Delete(filePath); } catch (Exception e) { Modifi.DefaultLogger.Error("Error deleting {0}, please delete it manually.", filePath); Modifi.DefaultLogger.Error(e.Message); } } else { Modifi.DefaultLogger.Information("File for {0} found at {1}, but the checksum did not match. Delete?", meta.GetName(), filePath); Menu <string> delete = new Menu <string>(); delete.AddItem("Delete"); delete.AddItem("Leave"); delete.DrawMenu(); switch (delete.SelectedOption.ToLower()) { case "delete": File.Delete(filePath); Modifi.DefaultLogger.Information("File deleted."); break; case "leave": Modifi.DefaultLogger.Information("File left in place."); break; } } break; } storage.Dispose(); }
public static void HandleModAdd(IDomain domain, string modIdentifier, string modVersion = null) { IDomainHandler handler = domain.GetDomainHandler(); ModMetadata meta = handler.GetModMetadata(Modifi.DefaultPack.MinecraftVersion, modIdentifier).Result; // Check mod installation status, error out if already requested/installed using (IModStorage storage = new ModStorage(Modifi.DefaultPack.Installed, domain)) { try { ModStatus status = storage.GetModStatus(meta); switch (status) { case ModStatus.Requested: case ModStatus.Installed: Modifi.DefaultLogger.Error("Mod {0} is already marked as requested, or already installed.", meta.GetName()); return; case ModStatus.Disabled: Modifi.DefaultLogger.Information("Mod {0} is marked at disabled. Please either delete it, or re-enable it."); return; } } catch (Exception e) { Modifi.DefaultLogger.Error(e.Message); return; } } // If the version is already specified, don't ask, just add it if (!String.IsNullOrEmpty(modVersion)) { ModVersion v = handler.GetModVersion(meta, modVersion).Result; // Connect to storage and mark the mod as requested using (ModStorage storage = new ModStorage(Modifi.DefaultPack.MinecraftVersion, domain)) { storage.MarkRequested(meta, v); return; } } // ============================================================ // TODO: ModHelper.PrintModInformation(meta); Menu <ModVersion> menu = new Menu <ModVersion>(); menu.OptionFormatter = (opt) => { Console.ForegroundColor = ConsoleColor.Green; Console.Write(opt.GetVersionName()); Console.ForegroundColor = ConsoleColor.DarkMagenta; Console.Write(" ["); Console.ForegroundColor = ConsoleColor.White; Console.Write(opt.GetModVersion()); Console.ForegroundColor = ConsoleColor.DarkMagenta; Console.Write("]"); Console.ForegroundColor = ConsoleColor.Gray; Console.Write(" [{0}]", opt.GetReleaseType()); Console.WriteLine(); }; ModVersion latestRelease = handler.GetRecentVersions(meta, 1, ModReleaseType.Release).Result.First(); ModVersion latestVersion = handler.GetRecentVersions(meta, 1, ModReleaseType.Any).Result.First(); IEnumerable <ModVersion> versions = handler.GetRecentVersions(meta, 6, ModReleaseType.Any).Result.Skip(1); menu.AddItem(latestRelease); if (latestVersion.GetModVersion() != latestRelease.GetModVersion()) { menu.AddItem(latestVersion); } menu.AddSpacer(); foreach (ModVersion v in versions.Take(5)) { menu.AddItem(v); } menu.DrawMenu(); Console.ResetColor(); Console.WriteLine(); ModVersion version = menu.SelectedOption; Console.WriteLine("Selected Version: " + version.GetModVersion()); // Create a storage handler for the domain and mark the version as requested using (ModStorage storage = new ModStorage(Modifi.DefaultPack.Installed, domain)) { storage.MarkRequested(meta, version); } }
public override void Load() { base.Load(); RecentChatters = new List <string>(); #if DEBUG //Used for debugging RecentChatters.AddRange(new[] { "Nightbot", "KarmikKoalla", "Moobot", "SomeoneFromChat" }); #endif Instance = this; BossCommands = new Dictionary <string, Action>(); EventsPool = new List <WorldEvent>(); LastStatus.Value = $"[c/{TwitchColor}: Client not connected]"; OldConfig = new TwitchOldConfig(Storage = new ModStorage(@"Twitch")); Store = new ResourceStore <byte[]>(new StorageBackedResourceStore(Storage)); if (ModLoader.version.Major == 10) { Store.AddStore(new OnlineStore()); } else { Store.AddStore(new WebStore("image/png")); } Textures = new Texture2DStore(Store); EmoticonHandler.store = new EmoticonsStore(Store); if (Storage.Exists("EmoteIDs.json")) { using (Stream p = Storage.GetStream("EmoteIDs.json")) using (StreamReader s = new StreamReader(p)) { try { EmoticonHandler.convertingEmotes = JsonConvert.DeserializeObject <Dictionary <string, int> >(s.ReadToEnd()); } catch (Exception e) { Logger.Warn($"Failed to load emotes id:\n{e}"); } } } // Just to create file OldConfig.Save(); Irc = new IrcClient(); // This client used in my twitch bot so class know all info about twitch irc server so we don't need to provide what info here //Start migrating to new configs //ShowDebug = OldConfig.Get<bool>(TwitchCfg.ShowAllIrc); //IgnoreCommands = OldConfig.Get<bool>(TwitchCfg.IgnoreCommands); //CommandPrefix = OldConfig.Get<string>(TwitchCfg.IgnoreCommandPrefix); Username = OldConfig.Get <string>(TwitchCfg.Username); Fun = OldConfig.Get <bool>(TwitchCfg.EnableFun); Channel = OldConfig.Get <string>(TwitchCfg.Channel); if (ShowDebug) { Razorwing.Framework.Logging.Logger.Storage = Storage; //Thx tML 0.11 for adding "Mod.Logger" <3 Breaking all as all ways } if (Fun) { //Since it not work on server (Not affect clients) until i write packets for this Twitch boss is disabled for server if (Main.netMode == NetmodeID.Server || Main.netMode == NetmodeID.SinglePlayer) { TwitchBoss.InitialiseDefault(); } //Register inner world event invasions foreach (Mod mod in ModLoader.Mods) { foreach (TypeInfo it in mod.GetType().Assembly.DefinedTypes) { if (!it.IsAbstract && ( it.BaseType != typeof(object) && it.BaseType == typeof(WorldEvent) || it.BaseType?.BaseType != typeof(object) && it.BaseType?.BaseType == typeof(WorldEvent)) ) //In case if WorldEvent is second parent { try { EventsPool.Add((WorldEvent)Activator.CreateInstance(it)); } catch (Exception e) { Logger.Error( "Exception caught in Events register loop. Report mod author with related stacktrace: \n" + $"{e.Message}\n" + $"{e.StackTrace}\n"); } } } } } if (ShowDebug) { Irc.ServerMessage += (s, m) => { try { Text(m); } catch (Exception) { Logger.Warn("Failed to post message"); } } } ; Irc.OnConnect += (s, e) => { LastStatus.Value = $"[c/{TwitchColor}:Connected]"; Irc.SendRaw("CAP REQ :twitch.tv/tags"); Thread.Sleep(500); Irc.SendRaw("CAP REQ :twitch.tv/commands"); Thread.Sleep(500); Irc.JoinChannel(Channel); inRestoringState = false; }; Irc.ConnectionClosed += (s, e) => { if (!inRestoringState) { LastStatus.Value = $"[c/{TwitchColor}:Connection lost!]"; inRestoringState = true; Thread.Sleep(5000); Irc.Connect(); } else { LastStatus.Value = $"[c/{TwitchColor}:Connection terminated! Client now offline]"; } }; Irc.ChannelMessage += (s, e) => { if (Main.netMode != NetmodeID.Server && !Main.gameMenu) { //If we ignore commands, we also want ignore bots messages if (IgnoreCommands) { if (e.Message.StartsWith(CommandPrefix)) { return; } //In case you self bot, we ignore your own messages if (e.From == Username) { return; } //if message was send by known bot, we ignore it if (KnownBots.Contains(e.From)) { return; } } var result = e.Message; var parsed = new List <SEmote>(); foreach (var it in e.Badge.emotes) { if (it == string.Empty) { break; } string[] pair = it.Split(':'); string[] ind = pair[1].Split(','); parsed.AddRange(ind.Select(p => { string[] ip = p.Split('-'); return(new SEmote(ip[0], ip[1], pair[0])); })); } if (parsed.Count != 0) { var list = new Dictionary <int, string>(); foreach (SEmote it in parsed) { if (list.ContainsKey(it.Emote)) { continue; } var st = e.Message.Substring(it.Start, it.End - it.Start + 1); //Not perfect because if Kappa mentioned in msg KappaPride get broken, //but it way faster what per glyph concat result = result.Replace(st, $"[e:{it.Emote}]"); list.Add(it.Emote, st); } foreach (KeyValuePair <int, string> em in list) { if (!EmoticonHandler.convertingEmotes.ContainsKey(em.Value)) { EmoticonHandler.convertingEmotes.Add(em.Value, em.Key); } } } else { result = e.Message; } var prefix = ""; if (e.Badge.sub) { prefix += $"[i:{ItemID.Star}] "; } if (e.Badge.mod) { prefix += $"[i:{ItemID.Arkhalis}]"; } //String format Main.NewText($@"{prefix} [c/{TwitchColor}:{e.Badge.DisplayName}]: {result}"); if (!RecentChatters.Contains(e.Badge.DisplayName)) { RecentChatters.Add(e.Badge.DisplayName); } } if ((Main.netMode == NetmodeID.Server || Main.netMode == NetmodeID.SinglePlayer) && Fun) { if (e.Message.StartsWith(CommandPrefix)) { return; } //In case you self bot, we ignore your own messages #if !DEBUG if (e.From == Username) { return; } #endif //if message was sent by known bot, we ignore it if (KnownBots.Contains(e.From)) { return; } //var word = e.Message.ToLower().Split(' ').First(); //if (CurrentPool?.ContainsKey(word) ?? false) //{ // CurrentPool[word]?.Invoke(e); //} if (e.From == TwitchBoss.Boss && TwitchBoss.Cooldown < DateTimeOffset.Now) { TwitchBoss.ProcessCommand(e); } } }; if (OldConfig.Get <bool>(TwitchCfg.AutoConnect) && OldConfig.Get <string>(TwitchCfg.OAToken) != "https://twitchapps.com/tmi/" && OldConfig.Get <string>(TwitchCfg.Username) != "missingno") { Irc.Username = OldConfig.Get <string>(TwitchCfg.Username); Irc.AuthToken = OldConfig.Get <string>(TwitchCfg.OAToken); Irc.Connect(); } WorldGen.SpawnTownNPC += SpawnTownNpcHook; }