private void ParseTeleporterFile(string filePath) { try { const string teleporterLanguageString = "\"teleporterlanguage\":"; var content = File.ReadAllText(filePath).ToLowerInvariant(); var idx = content.IndexOf(teleporterLanguageString); if (idx < 0) { return; } content = content.Substring(idx + teleporterLanguageString.Length).Trim(); if (content.Length < 1) { return; } _teleporterLanguage = content[0] switch { '0' => ClientLanguage.Japanese, '1' => ClientLanguage.English, '2' => ClientLanguage.German, '3' => ClientLanguage.French, _ => _language, }; } catch (Exception e) { PluginLog.Error($"Could not read Teleporter Config:\n{e}"); _teleporterLanguage = _language; } }
internal static void Initialize() { try { uiModuleVtableSig = pluginInterface.TargetModuleScanner.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 48 8B D9 48 89 01 48 8D 05 ?? ?? ?? ?? 48 89 41 08 48 8D 05 ?? ?? ?? ?? 48 89 41 10 48 8D 05 ?? ?? ?? ?? 48 89 41 18 48 81 C1 ?? ?? ?? ??"); GetAgentModuleFunc = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size); MyGetAgentModule = Marshal.GetDelegateForFunctionPointer <GetAgentModuleDelegate>(GetAgentModuleFunc); UiModule = pluginInterface.Framework.Gui.GetUIModule(); if (UiModule == IntPtr.Zero) { PluginLog.Error("null uimodule"); } AgentModule = MyGetAgentModule(UiModule); if (AgentModule == IntPtr.Zero) { PluginLog.Error("null agentmodule"); } for (var i = 0; i < 379; i++) { IntPtr pointer = Marshal.ReadIntPtr(AgentModule, 0x20 + (i * 8)); if (pointer == IntPtr.Zero) { continue; } Agents.Add(new AgentInterface(pointer)); } } catch (Exception e) { PluginLog.Error(e.ToString()); } }
// Attempts to load supplemental bgm data from the csv file // Will always instantiate _bgms with path information private bool LoadSheet(string sheetText) { _bgms = new Dictionary <ushort, BgmInfo>(); foreach (var key in _bgmPaths) { _bgms[key.Key] = new BgmInfo { FilePath = key.Value }; } bool loadSuccess = true; try { var sheetLines = sheetText.Split('\n'); // gdocs provides \n for (int i = 1; i < sheetLines.Length; i++) { var elements = sheetLines[i].Split(new[] { "\"," }, StringSplitOptions.None); var id = ushort.Parse(elements[0].Substring(1)); _bgms.TryGetValue(id, out var info); info.Title = elements[1].Substring(1).Replace("\"\"", "\""); info.Location = elements[2].Substring(1).Replace("\"\"", "\""); info.AdditionalInfo = elements[3].Substring(1, elements[3].Substring(1).Length - 1).Replace("\"\"", "\""); _bgms[id] = info; } } catch (Exception e) { PluginLog.Error(e, "Could not read bgm sheet."); loadSuccess = false; } return(loadSuccess); }
private ResourceHandle *GetResourceHandler(bool isSync, ResourceManager *resourceManager, ResourceCategory *categoryId, ResourceType *resourceType, int *resourceHash, byte *path, void *unk, bool isUnk) { if (!Utf8GamePath.FromPointer(path, out var gamePath)) { PluginLog.Error("Could not create GamePath from resource path."); return(CallOriginalHandler(isSync, resourceManager, categoryId, resourceType, resourceHash, path, unk, isUnk)); } CompareHash(gamePath.Path.Crc32, *resourceHash, gamePath); ResourceRequested?.Invoke(gamePath, isSync); // If no replacements are being made, we still want to be able to trigger the event. var(resolvedPath, data) = ResolvePath(gamePath, *categoryId, *resourceType, *resourceHash); PathResolved?.Invoke(gamePath, resolvedPath, data); if (resolvedPath == null) { var retUnmodified = CallOriginalHandler(isSync, resourceManager, categoryId, resourceType, resourceHash, path, unk, isUnk); ResourceLoaded?.Invoke((Structs.ResourceHandle *)retUnmodified, gamePath, null, data); return(retUnmodified); } // Replace the hash and path with the correct one for the replacement. *resourceHash = resolvedPath.Value.InternalName.Crc32; path = resolvedPath.Value.InternalName.Path; var retModified = CallOriginalHandler(isSync, resourceManager, categoryId, resourceType, resourceHash, path, unk, isUnk); ResourceLoaded?.Invoke((Structs.ResourceHandle *)retModified, gamePath, resolvedPath.Value, data); return(retModified); }
public static void Error(object message, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerName = "", [CallerLineNumber] int lineNumber = -1) { foreach (var m in SplitMessage(message)) { PluginLog.Error($"[{callerPath.Substring(_subStrIndex)}::{callerName}:{lineNumber}] {m}"); } }
public static void Init(string pluginDirectory) { var sheetPath = Path.Join(pluginDirectory, SheetFileName); _songs = new Dictionary <int, Song>(); var existingText = File.ReadAllText(sheetPath); using var client = new WebClient(); try { PluginLog.Log("Checking for updated bgm sheet"); var newText = client.DownloadString(SheetPath); LoadSheet(newText); // would really prefer some kind of proper versioning here if (newText != existingText) { File.WriteAllText(sheetPath, newText); PluginLog.Log("Updated bgm sheet to new version"); } } catch (Exception e) { PluginLog.Error(e, "Orchestrion failed to update bgm sheet; using previous version"); // if this throws, something went horribly wrong and we should just break completely LoadSheet(existingText); } }
public IReadOnlyDictionary <string, object?> GetChangedItemsForCollection(string collectionName) { CheckInitialized(); try { var modManager = Service <ModManager> .Get(); if (!modManager.Collections.Collections.TryGetValue(collectionName, out var collection)) { collection = ModCollection.Empty; } if (collection.Cache != null) { return(collection.Cache.ChangedItems); } PluginLog.Warning($"Collection {collectionName} does not exist or is not loaded."); return(new Dictionary <string, object?>()); } catch (Exception e) { PluginLog.Error($"Could not obtain Changed Items for {collectionName}:\n{e}"); throw; } }
public void AddItem(Gatherable item) { if (!Items?.SetFirstNullItem(this, item) ?? true) { PluginLog.Error($"Could not add additional item {item} to node {Meta?.PointBaseId}, all 9 slots are used."); } }
public void AddOption(Mod mod, int groupIdx, ISubMod option, int priority = 0) { if (option is not SubMod o) { return; } if (mod._groups[groupIdx].Count > 63) { PluginLog.Error( $"Could not add option {option.Name} to {mod._groups[ groupIdx ].Name} for mod {mod.Name}, " + "since only up to 64 options are supported in one group."); return; } switch (mod._groups[groupIdx]) { case SingleModGroup s: s.OptionData.Add(o); break; case MultiModGroup m: m.PrioritizedOptions.Add((o, priority)); break; } ModOptionChanged.Invoke(ModOptionChangeType.OptionAdded, mod, groupIdx, mod._groups[groupIdx].Count - 1, -1); }
public async Task SendItemSaleEvent(SeString name, string iconurl, uint itemId, string message, XivChatType chatType) { var applicableChannels = this.plugin.Config.ChannelConfigs.Where(x => x.Value.ChatTypes.Contains(chatType)); if (!applicableChannels.Any()) { return; } message = this.specialChars.TransformToUnicode(message); PluginLog.Information($"Retainer sold itemID: {itemId} with iconurl: {iconurl}"); this.plugin.Config.PrefixConfigs.TryGetValue(chatType, out var prefix); foreach (var channelConfig in applicableChannels) { var socketChannel = this.socketClient.GetChannel(channelConfig.Key); if (socketChannel == null) { PluginLog.Error("Could not find channel {0} for {1}", channelConfig.Key, chatType); continue; } var webhookClient = await GetOrCreateWebhookClient(socketChannel); await webhookClient.SendMessageAsync($"{prefix} {message}", username : $"Retainer sold {name}", avatarUrl : iconurl); } }
public void Initialize(DalamudPluginInterface pluginInterface) { this.pluginInterface = pluginInterface ?? throw new ArgumentNullException(nameof(pluginInterface), "DalamudPluginInterface cannot be null"); this.config = (Configuration)this.pluginInterface.GetPluginConfig() ?? new Configuration(); this.config.Initialize(this.pluginInterface); this.ui = new PluginUI(config); this.cui = new ConfigUI(config.Opacity, config.isLocked, config); this.pluginInterface.UiBuilder.OnBuildUi += this.ui.Draw; this.pluginInterface.UiBuilder.OnBuildUi += this.cui.Draw; this.commandManager = new PluginCommandManager <Plugin>(this, this.pluginInterface); this.pluginInterface.Framework.OnUpdateEvent += this.GetData; Address = new PluginAddressResolver(); Address.Setup(pluginInterface.TargetModuleScanner); IsActionUnlocked = Marshal.GetDelegateForFunctionPointer <IsActionUnlockedDelegate>(Address.IsActionUnlockedAddress); try { LoadData(); } catch (Exception e) { PluginLog.Error(e, "Boom"); } }
public async Task Start() { if (string.IsNullOrEmpty(this.plugin.Config.DiscordToken)) { this.State = DiscordState.TokenInvalid; PluginLog.Error("Token empty, cannot start bot."); return; } try { await this.socketClient.LoginAsync(TokenType.Bot, this.plugin.Config.DiscordToken); await this.socketClient.StartAsync(); } catch (Exception ex) { PluginLog.Error(ex, "Token invalid, cannot start bot."); } this.MessageQueue.Start(); lodestoneClient = await LodestoneClient.GetClientAsync(); PluginLog.Verbose("DiscordHandler START!!"); }
/// <summary> /// Returns the searched character, or null if not found. /// </summary> /// <param name="name"></param> /// <param name="world"></param> /// <returns></returns> public static async Task <CharacterResult> GetCharacterSearch(string name, string world) { try { dynamic res = await Get("character/search" + $"?name={name}&server={world}"); if (res?.Results?.Count > 0) { for (int i = 0; i < res.Results.Count; i++) { string temp = res.Results[i].Name; if (temp.Equals(name)) { return(new CharacterResult { AvatarUrl = res.Results[i].Avatar, LodestoneId = res.Results[i].ID }); } } } PluginLog.Error($"Couldn't find an icon for {name}@{world}"); } catch (Exception e) { PluginLog.Error($"Encountered an error when searching for {name}@{world}"); PluginLog.Error(e.ToString()); } return(null); }
private static (byte[]?, int, int) GetTexRgbaData(string path, bool fromDisk) { try { if (fromDisk) { var tmp = new TmpTexFile(); using var stream = File.OpenRead(path); using var br = new BinaryReader(stream); tmp.Load(br); return(tmp.RgbaData, tmp.Header.Width, tmp.Header.Height); } var tex = fromDisk ? Dalamud.GameData.GameData.GetFileFromDisk <TexFile>(path) : Dalamud.GameData.GetFile <TexFile>(path); if (tex == null) { return(null, 0, 0); } var rgba = tex.Header.Format == TexFile.TextureFormat.A8R8G8B8 ? ImageParsing.DecodeUncompressedR8G8B8A8(tex.ImageData, tex.Header.Height, tex.Header.Width) : tex.GetRgbaImageData(); return(rgba, tex.Header.Width, tex.Header.Height); } catch (Exception e) { PluginLog.Error($"Could not parse TEX {path} to RGBA:\n{e}"); return(null, 0, 0); } }
// Delete a mod by its index. The event is invoked before the mod is removed from the list. // Deletes from filesystem as well as from internal data. // Updates indices of later mods. public void DeleteMod(int idx) { var mod = this[idx]; if (Directory.Exists(mod.ModPath.FullName)) { try { Directory.Delete(mod.ModPath.FullName, true); PluginLog.Debug("Deleted directory {Directory:l} for {Name:l}.", mod.ModPath.FullName, mod.Name); } catch (Exception e) { PluginLog.Error($"Could not delete the mod {mod.ModPath.Name}:\n{e}"); } } ModPathChanged.Invoke(ModPathChangeType.Deleted, mod, mod.ModPath, null); _mods.RemoveAt(idx); foreach (var remainingMod in _mods.Skip(idx)) { --remainingMod.Index; } PluginLog.Debug("Deleted mod {Name:l}.", mod.Name); }
private void AddAetherytes(Territory territory) { var aetheryteName = territory.NameList[ClientLanguage.English] switch { "The Dravanian Hinterlands" => "Idyllshire", "Limsa Lominsa Upper Decks" => "Limsa Lominsa Lower Decks", "Mist" => "Limsa Lominsa Lower Decks", "Old Gridania" => "New Gridania", "The Lavender Beds" => "New Gridania", "The Goblet" => "Ul'dah - Steps of Nald", "Shirogane" => "Kugane", "The Endeavor" => "Limsa Lominsa Lower Decks", "The Diadem" => "Foundation", _ => null, }; if (aetheryteName == null) { return; } var aetheryte = Aetherytes.Aetherytes.FirstOrDefault(a => a.NameList[ClientLanguage.English] == aetheryteName); if (aetheryte != null) { territory.Aetherytes.Add(aetheryte); } else { PluginLog.Error($"Tried to add {aetheryteName} to {territory.NameList[ClientLanguage.English]}, but aetheryte not found."); } }
private static bool MigrateV1ToV2(Mod mod) { if (mod.FileVersion > 1) { return(false); } foreach (var(group, index) in mod.GroupFiles.WithIndex().ToArray()) { var newName = Regex.Replace(group.Name, "^group_", $"group_{index + 1:D3}_", RegexOptions.Compiled); try { if (newName != group.Name) { group.MoveTo(Path.Combine(group.DirectoryName ?? string.Empty, newName), false); } } catch (Exception e) { PluginLog.Error($"Could not rename group file {group.Name} to {newName} during migration:\n{e}"); } } mod.FileVersion = 2; mod.SaveMeta(); return(true); }
private unsafe void *CallOriginalHandler( bool isSync, IntPtr pFileManager, uint *pCategoryId, char *pResourceType, uint *pResourceHash, char *pPath, void *pUnknown, bool isUnknown ) { if (isSync) { if (GetResourceSyncHook == null) { PluginLog.Error("[GetResourceHandler] GetResourceSync is null."); return(null); } return(GetResourceSyncHook.OriginalFunction(pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown)); } if (GetResourceAsyncHook == null) { PluginLog.Error("[GetResourceHandler] GetResourceAsync is null."); return(null); } return(GetResourceAsyncHook.OriginalFunction(pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown)); }
public static void Error(object message) { foreach (var m in SplitMessage(message)) { PluginLog.Error($"{m}"); } }
private unsafe uint GetIconDetour(IntPtr actionManager, uint actionID) { this.actionManager = actionManager; try { if (Service.ClientState.LocalPlayer == null) { return(this.OriginalHook(actionID)); } var lastComboMove = *(uint *)Service.Address.LastComboMove; var comboTime = *(float *)Service.Address.ComboTimer; var level = Service.ClientState.LocalPlayer?.Level ?? 0; foreach (var combo in this.customCombos) { if (combo.TryInvoke(actionID, level, lastComboMove, comboTime, out var newActionID)) { return(newActionID); } } return(this.OriginalHook(actionID)); } catch (Exception ex) { PluginLog.Error(ex, "Don't crash the game"); return(this.OriginalHook(actionID)); } }
protected override void DrawPopups() { _fileManager.Draw(); DrawHelpPopup(); DrawInfoPopup(); if (ImGuiUtil.OpenNameField("Create New Mod", ref _newModName)) { try { var newDir = Mod.CreateModFolder(Penumbra.ModManager.BasePath, _newModName); Mod.CreateMeta(newDir, _newModName, Penumbra.Config.DefaultModAuthor, string.Empty, "1.0", string.Empty); Mod.CreateDefaultFiles(newDir); Penumbra.ModManager.AddMod(newDir); _newModName = string.Empty; } catch (Exception e) { PluginLog.Error($"Could not create directory for new Mod {_newModName}:\n{e}"); } } while (_modsToAdd.TryDequeue(out var dir)) { Penumbra.ModManager.AddMod(dir); var mod = Penumbra.ModManager.LastOrDefault(); if (mod != null) { MoveModToDefaultDirectory(mod); SelectByValue(mod); } } }
public bool Execute(string message) { // First try to process the command through Dalamud. if (Dalamud.Commands.ProcessCommand(message)) { PluginLog.Verbose("Executed Dalamud command \"{Message:l}\".", message); return(true); } if (_uiModulePtr == IntPtr.Zero) { PluginLog.Error("Can not execute \"{Message:l}\" because no uiModulePtr is available.", message); return(false); } // Then prepare a string to send to the game itself. var(text, length) = PrepareString(message); var payload = PrepareContainer(text, length); _processChatBox.Invoke(_uiModulePtr, payload, IntPtr.Zero, (byte)0); Marshal.FreeHGlobal(payload); Marshal.FreeHGlobal(text); return(false); }
// Rename/Move a mod directory. // Updates all collection settings and sort order settings. public void MoveModDirectory(int idx, string newName) { var mod = this[idx]; var oldName = mod.Name; var oldDirectory = mod.ModPath; switch (NewDirectoryValid(oldDirectory.Name, newName, out var dir)) { case NewDirectoryState.NonExisting: // Nothing to do break; case NewDirectoryState.ExistsEmpty: try { Directory.Delete(dir !.FullName); } catch (Exception e) { PluginLog.Error($"Could not delete empty directory {dir!.FullName} to move {mod.Name} to it:\n{e}"); return; } break; // Should be caught beforehand. case NewDirectoryState.ExistsNonEmpty: case NewDirectoryState.ExistsAsFile: case NewDirectoryState.ContainsInvalidSymbols: // Nothing to do at all. case NewDirectoryState.Identical: default: return; } try { Directory.Move(oldDirectory.FullName, dir !.FullName); } catch (Exception e) { PluginLog.Error($"Could not move {mod.Name} from {oldDirectory.Name} to {dir!.Name}:\n{e}"); return; } dir.Refresh(); mod.ModPath = dir; if (!mod.Reload(out var metaChange)) { PluginLog.Error($"Error reloading moved mod {mod.Name}."); return; } ModPathChanged.Invoke(ModPathChangeType.Moved, mod, oldDirectory, BasePath); if (metaChange != MetaChangeType.None) { ModMetaChanged?.Invoke(metaChange, mod, oldName); } }
private void DrawModAddButton() { if (ImGui.BeginPopupContextItem(LabelAddModPopup)) { if (_keyboardFocus) { ImGui.SetKeyboardFocusHere(); _keyboardFocus = false; } var newName = ""; if (ImGui.InputTextWithHint("##AddMod", "New Mod Name...", ref newName, 64, ImGuiInputTextFlags.EnterReturnsTrue)) { try { var newDir = TexToolsImport.CreateModFolder(new DirectoryInfo(_base._plugin.Configuration !.CurrentCollection), newName); var modMeta = new ModMeta { Author = "Unknown", Name = newName, Description = string.Empty, }; var metaPath = Path.Combine(newDir.FullName, "meta.json"); File.WriteAllText(metaPath, JsonConvert.SerializeObject(modMeta, Formatting.Indented)); _base.ReloadMods(); SelectModByDir(newDir.Name); } catch (Exception e) { PluginLog.Error($"Could not create directory for new Mod {newName}:\n{e}"); } ImGui.CloseCurrentPopup(); } if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(ImGuiKey.Escape))) { ImGui.CloseCurrentPopup(); } ImGui.EndPopup(); } ImGui.PushFont(UiBuilder.IconFont); if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString(), SelectorButtonSizes)) { _keyboardFocus = true; ImGui.OpenPopup(LabelAddModPopup); } ImGui.PopFont(); if (ImGui.IsItemHovered()) { ImGui.SetTooltip(TooltipAdd); } }
public void SetPose(int which, byte toWhat) { if (toWhat == UnchangedPose) return; if (toWhat == DefaultPose) { toWhat = _defaultPoses[which]; } else if (toWhat >= NumPoses[which]) { PluginLog.Error($"Higher pose requested than possible for {PoseNames[which]}: {toWhat} / {NumPoses[which]}."); return; } if (PlayerPointer == IntPtr.Zero) return; var currentState = GetSeatingState(); currentState = TranslateState(currentState, WeaponDrawn); var pose = GetPose(which); if (currentState == which) { if (toWhat == GetCPoseActorState()) { if (pose != toWhat) { WritePose(which, toWhat); PluginLog.Debug("Overwrote {OldPose} with {NewPose} for {WhichPose:l}, currently in {CurrentState:l}.", pose, toWhat, PoseNames[which], PoseNames[currentState]); } } else { Task.Run(() => { var i = 0; do { PluginLog.Debug("Execute /cpose to get from {OldPose} to {NewPose} of {CurrentState:l}.", pose, toWhat, PoseNames[currentState]); _commandManager.Execute("/cpose"); Task.Delay(50); } while (toWhat != GetCPoseActorState() && i++ < 8); if (i > 8) PluginLog.Error("Could not change pose of {CurrentState:l}.", PoseNames[GetCPoseActorState()]); }); } } else if (pose != toWhat) { WritePose(which, toWhat); PluginLog.Debug("Overwrote {OldPose} with {NewPose} for {WhichPose:l}, currently in {CurrentState:l}.", pose, toWhat, PoseNames[which], PoseNames[currentState]); } }
private void LoadStyle(string name, string path, bool isUserStyle) { var fileNames = new[] { "Bar.png", "BarBG.png", "Cast.png", "CastBG.png" }; if (isUserStyle ? UserStyles.ContainsKey(name) : Styles.ContainsKey(name)) { return; } var images = new TextureWrap[4]; for (var i = 0; i != fileNames.Length; ++i) { var filePath = Path.Combine(path, $@"{name}\{fileNames[i]}"); if (!File.Exists(filePath)) { foreach (var image in images) { image?.Dispose(); } PluginLog.Error($"{filePath} was not found."); return; } images[i] = PluginInterface.UiBuilder.LoadImage(filePath); if (images[i] != null) { continue; } foreach (var image in images) { image?.Dispose(); } PluginLog.Error($"Failed to load {filePath}."); return; } if (isUserStyle) { UserStyles[name] = images; } else { Styles[name] = images; } }
private static void ResettleCollectionJson(Configuration config) { var collectionJson = new FileInfo(Path.Combine(config.ModDirectory, "collection.json")); if (!collectionJson.Exists) { return; } var defaultCollection = new ModCollection(); var defaultCollectionFile = defaultCollection.FileName(); if (defaultCollectionFile.Exists) { return; } try { var text = File.ReadAllText(collectionJson.FullName); var data = JArray.Parse(text); var maxPriority = 0; foreach (var setting in data.Cast <JObject>()) { var modName = ( string )setting["FolderName"] !; var enabled = ( bool )setting["Enabled"] !; var priority = ( int )setting["Priority"] !; var settings = setting["Settings"] !.ToObject <Dictionary <string, int> >() ?? setting["Conf"] !.ToObject <Dictionary <string, int> >(); var save = new ModSettings() { Enabled = enabled, Priority = priority, Settings = settings !, }; defaultCollection.Settings.Add(modName, save); maxPriority = Math.Max(maxPriority, priority); } if (!config.InvertModListOrder) { foreach (var setting in defaultCollection.Settings.Values) { setting.Priority = maxPriority - setting.Priority; } } defaultCollection.Save(); } catch (Exception e) { PluginLog.Error($"Could not migrate the old collection file to new collection files:\n{e}"); throw; } }
public static bool RenameModFolder(this ModManager manager, ModData mod, DirectoryInfo newDir, bool move = true) { if (move) { newDir.Refresh(); if (newDir.Exists) { return(false); } var oldDir = new DirectoryInfo(mod.BasePath.FullName); try { oldDir.MoveTo(newDir.FullName); } catch (Exception e) { PluginLog.Error($"Error while renaming directory {oldDir.FullName} to {newDir.FullName}:\n{e}"); return(false); } } manager.Mods.Remove(mod.BasePath.Name); manager.Mods[newDir.Name] = mod; var oldBasePath = mod.BasePath; mod.BasePath = newDir; mod.MetaFile = ModData.MetaFileInfo(newDir); manager.UpdateMod(mod); if (manager.Config.ModSortOrder.ContainsKey(oldBasePath.Name)) { manager.Config.ModSortOrder[newDir.Name] = manager.Config.ModSortOrder[oldBasePath.Name]; manager.Config.ModSortOrder.Remove(oldBasePath.Name); manager.Config.Save(); } foreach (var collection in manager.Collections.Collections.Values) { if (collection.Settings.TryGetValue(oldBasePath.Name, out var settings)) { collection.Settings[newDir.Name] = settings; collection.Settings.Remove(oldBasePath.Name); collection.Save(); } if (collection.Cache != null) { collection.Cache.RemoveMod(newDir); collection.AddMod(mod); } } return(true); }
internal static void Last() { if (currentPlayback != null) { try { var wasplaying = IsPlaying; currentPlayback?.Dispose(); currentPlayback = null; switch ((PlayMode)config.PlayMode) { case PlayMode.Single: case PlayMode.ListOrdered: case PlayMode.SingleRepeat: currentPlayback = PlaylistManager.Filelist[PlaylistManager.CurrentPlaying - 1].GetFilePlayback(); PlaylistManager.CurrentPlaying -= 1; break; case PlayMode.Random: case PlayMode.ListRepeat: var next = PlaylistManager.CurrentPlaying - 1; if (next < 0) { next = PlaylistManager.Filelist.Count - 1; } currentPlayback = PlaylistManager.Filelist[next].GetFilePlayback(); PlaylistManager.CurrentPlaying = next; break; } if (wasplaying) { try { currentPlayback.Start(); } catch (Exception e) { PluginLog.Error(e, "error when try playing next song."); } } Task.Run(SwitchInstrument.WaitSwitchInstrument); } catch (Exception e) { currentPlayback = null; PlaylistManager.CurrentPlaying = -1; } } else { PlaylistManager.CurrentPlaying -= 1; } }
public Plugin(CommandManager command) { this.Config = (Configuration)this.Interface.GetPluginConfig() ?? new Configuration(); this.Config.Initialize(this.Interface); // sanity check - ensure there are no invalid types leftover from past versions. foreach (DiscordChannelConfig config in this.Config.ChannelConfigs.Values) { for (int i = 0; i < config.ChatTypes.Count; i++) { XivChatType xct = config.ChatTypes[i]; if ((int)xct > 127) { config.ChatTypes[i] = (XivChatType)((int)xct & 0x7F); this.Config.Save(); } try { xct.GetInfo(); } catch (ArgumentException) { PluginLog.Error($"Removing invalid chat type before it could cause problems ({(int)xct}){xct}."); config.ChatTypes.RemoveAt(i--); this.Config.Save(); } } } this.DiscordBridgeProvider = new DiscordBridgeProvider(this.Interface, new DiscordBridgeAPI(this)); this.Discord = new DiscordHandler(this); // Task t = this.Discord.Start(); // bot won't start if we just have this Task.Run(async() => // makes the bot actually start { await this.Discord.Start(); }); this.ui = new PluginUI(this); this.Interface.UiBuilder.Draw += this.ui.Draw; this.Chat.ChatMessage += ChatOnOnChatMessage; this.State.CfPop += ClientStateOnCfPop; this.commandManager = new PluginCommandManager <Plugin>(this, command); if (string.IsNullOrEmpty(this.Config.DiscordToken)) { this.Chat.PrintError("The Discord Bridge plugin was installed successfully." + "Please use the \"/pdiscord\" command to set it up."); } }