diff --git a/MareSynchronos/Managers/FileCacheManager.cs b/MareSynchronos/Managers/FileCacheManager.cs index f87f11c..39faf12 100644 --- a/MareSynchronos/Managers/FileCacheManager.cs +++ b/MareSynchronos/Managers/FileCacheManager.cs @@ -48,15 +48,19 @@ namespace MareSynchronos.Managers public string WatchedPenumbraDirectory => (_penumbraDirWatcher?.EnableRaisingEvents ?? false) ? _penumbraDirWatcher!.Path : "Not watched"; - public FileCache Create(string file, CancellationToken token) + public FileCache? Create(string file, CancellationToken token) { FileInfo fileInfo = new(file); - while (IsFileLocked(fileInfo)) + int attempt = 0; + while (IsFileLocked(fileInfo) && attempt++ <= 10) { Thread.Sleep(1000); - Logger.Debug("Waiting for file release " + fileInfo.FullName); + Logger.Debug("Waiting for file release " + fileInfo.FullName + " attempt " + attempt); token.ThrowIfCancellationRequested(); } + + if (attempt >= 10) return null; + var sha1Hash = Crypto.GetFileHash(fileInfo.FullName); return new FileCache() { @@ -205,8 +209,11 @@ namespace MareSynchronos.Managers { PluginLog.Verbose("Changed :" + item); var fileCache = Create(item, _rescanTaskCancellationTokenSource.Token); - db.RemoveRange(db.FileCaches.Where(f => f.Hash == fileCache.Hash)); - await db.AddAsync(fileCache, _rescanTaskCancellationTokenSource.Token); + if (fileCache != null) + { + db.RemoveRange(db.FileCaches.Where(f => f.Hash == fileCache.Hash)); + await db.AddAsync(fileCache, _rescanTaskCancellationTokenSource.Token); + } } } @@ -265,8 +272,12 @@ namespace MareSynchronos.Managers } FileInfo fileInfo = new(cache.Filepath); if (fileInfo.LastWriteTimeUtc.Ticks == long.Parse(cache.LastModifiedDate)) return; - fileCachesToAdd.Add(Create(cache.Filepath, ct)); - fileCachesToDelete.Add(cache); + var newCache = Create(cache.Filepath, ct); + if (newCache != null) + { + fileCachesToAdd.Add(newCache); + fileCachesToDelete.Add(cache); + } } var files = CurrentFileProgress; @@ -282,14 +293,18 @@ namespace MareSynchronos.Managers MaxDegreeOfParallelism = _pluginConfiguration.MaxParallelScan, CancellationToken = ct }, - file => - { - fileCachesToAdd.Add(Create(file.Key, ct)); + file => + { + var newCache = Create(file.Key, ct); + if (newCache != null) + { + fileCachesToAdd.Add(newCache); + } - var files = CurrentFileProgress; - Interlocked.Increment(ref files); - CurrentFileProgress = files; - }); + var files = CurrentFileProgress; + Interlocked.Increment(ref files); + CurrentFileProgress = files; + }); if (fileCachesToAdd.Any() || fileCachesToDelete.Any()) { diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index 569fcb4..7040839 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -3,7 +3,7 @@ - 0.1.3.0 + 0.1.4.0 https://github.com/Penumbra-Sync/client diff --git a/MareSynchronos/UI/CompactUI.cs b/MareSynchronos/UI/CompactUI.cs index 010df66..fec39cb 100644 --- a/MareSynchronos/UI/CompactUI.cs +++ b/MareSynchronos/UI/CompactUI.cs @@ -19,10 +19,13 @@ namespace MareSynchronos.UI { private readonly ApiController _apiController; private readonly Configuration _configuration; + private readonly Dictionary _showUidForEntry = new(); private readonly UiShared _uiShared; private readonly WindowSystem _windowSystem; private string _characterOrCommentFilter = string.Empty; + private string _editCharComment = string.Empty; + private string _editNickEntry = string.Empty; private string _pairToAdd = string.Empty; private float _transferPartHeight = 0; @@ -55,42 +58,38 @@ namespace MareSynchronos.UI _windowSystem.RemoveWindow(this); } + public override void Draw() + { + _windowContentWidth = UiShared.GetWindowContentRegionWidth(); + UiShared.DrawWithID("header", DrawUIDHeader); + ImGui.Separator(); + if (_apiController.ServerState is not ServerState.Offline) + { + UiShared.DrawWithID("serverstatus", DrawServerStatus); + } + + if (_apiController.ServerState is ServerState.Connected) + { + ImGui.Separator(); + UiShared.DrawWithID("pairlist", DrawPairList); + ImGui.Separator(); + UiShared.DrawWithID("transfers", DrawTransfers); + _transferPartHeight = ImGui.GetCursorPosY() - _transferPartHeight; + } + } + public override void OnClose() { _editNickEntry = string.Empty; _editCharComment = string.Empty; base.OnClose(); } - - private Dictionary _showUidForEntry = new Dictionary(); - private string _editNickEntry = string.Empty; - - public override void Draw() - { - _windowContentWidth = ImGui.GetWindowContentRegionWidth(); - DrawUIDHeader(); - ImGui.Separator(); - if (_apiController.ServerState is not ServerState.Offline) - { - DrawServerStatus(); - } - - if (_apiController.ServerState is ServerState.Connected) - { - ImGui.Separator(); - DrawPairList(); - ImGui.Separator(); - DrawTransfers(); - _transferPartHeight = ImGui.GetCursorPosY() - _transferPartHeight; - } - } private void DrawAddPair() { - ImGui.PushID("pairs"); - var buttonSize = GetIconButtonSize(FontAwesomeIcon.Plus); - ImGui.SetNextItemWidth(ImGui.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X); + var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Plus); + ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetWindowContentRegionMin().X - buttonSize.X); ImGui.InputTextWithHint("##otheruid", "Other players UID", ref _pairToAdd, 10); - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + ImGui.GetWindowContentRegionWidth() - buttonSize.X); + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X); if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus)) { if (_apiController.PairedClients.All(w => w.OtherUID != _pairToAdd)) @@ -99,16 +98,14 @@ namespace MareSynchronos.UI _pairToAdd = string.Empty; } } - AttachToolTip("Pair with " + (_pairToAdd.IsNullOrEmpty() ? "other user" : _pairToAdd)); + UiShared.AttachToolTip("Pair with " + (_pairToAdd.IsNullOrEmpty() ? "other user" : _pairToAdd)); ImGuiHelpers.ScaledDummy(2); - ImGui.PopID(); } private void DrawFilter() { - ImGui.PushID("filter"); - var buttonSize = GetIconButtonSize(FontAwesomeIcon.ArrowUp); + var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.ArrowUp); if (!_configuration.ReverseUserSort) { if (ImGuiComponents.IconButton(FontAwesomeIcon.ArrowDown)) @@ -116,7 +113,7 @@ namespace MareSynchronos.UI _configuration.ReverseUserSort = true; _configuration.Save(); } - AttachToolTip("Sort by newest additions first"); + UiShared.AttachToolTip("Sort by newest additions first"); } else { @@ -125,24 +122,19 @@ namespace MareSynchronos.UI _configuration.ReverseUserSort = false; _configuration.Save(); } - AttachToolTip("Sort by oldest additions first"); + UiShared.AttachToolTip("Sort by oldest additions first"); } ImGui.SameLine(); ImGui.SetNextItemWidth(_windowContentWidth - buttonSize.X - ImGui.GetStyle().ItemSpacing.X); ImGui.InputTextWithHint("##filter", "Filter for UID/notes", ref _characterOrCommentFilter, 255); - ImGui.PopID(); } - private string _editCharComment = string.Empty; - private void DrawPairedClient(ClientPairDto entry) { - ImGui.PushID(entry.OtherUID); - var pauseIcon = entry.IsPaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause; - var buttonSize = GetIconButtonSize(pauseIcon); - var trashButtonSize = GetIconButtonSize(FontAwesomeIcon.Trash); + var buttonSize = UiShared.GetIconButtonSize(pauseIcon); + var trashButtonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Trash); var textSize = ImGui.CalcTextSize(entry.OtherUID); var originalY = ImGui.GetCursorPosY(); var buttonSizes = buttonSize.Y + trashButtonSize.Y; @@ -155,7 +147,7 @@ namespace MareSynchronos.UI UiShared.ColorText(FontAwesomeIcon.ArrowUp.ToIconString(), ImGuiColors.DalamudRed); ImGui.PopFont(); - AttachToolTip(entry.OtherUID + " has not added you back"); + UiShared.AttachToolTip(entry.OtherUID + " has not added you back"); } else if (entry.IsPaused || entry.IsPausedFromOthers) { @@ -163,7 +155,7 @@ namespace MareSynchronos.UI UiShared.ColorText(FontAwesomeIcon.PauseCircle.ToIconString(), ImGuiColors.DalamudYellow); ImGui.PopFont(); - AttachToolTip("Pairing status with " + entry.OtherUID + " is paused"); + UiShared.AttachToolTip("Pairing status with " + entry.OtherUID + " is paused"); } else { @@ -171,13 +163,12 @@ namespace MareSynchronos.UI UiShared.ColorText(FontAwesomeIcon.Check.ToIconString(), ImGuiColors.ParsedGreen); ImGui.PopFont(); - AttachToolTip("You are paired with " + entry.OtherUID); + UiShared.AttachToolTip("You are paired with " + entry.OtherUID); } - bool textIsUid = true; - var playerText = entry.OtherUID; - _showUidForEntry.TryGetValue(entry.OtherUID, out bool showUidInsteadOfName); - if (!showUidInsteadOfName && _configuration.GetCurrentServerUidComments().TryGetValue(entry.OtherUID, out playerText)) + var textIsUid = true; + _showUidForEntry.TryGetValue(entry.OtherUID, out var showUidInsteadOfName); + if (!showUidInsteadOfName && _configuration.GetCurrentServerUidComments().TryGetValue(entry.OtherUID, out var playerText)) { if (playerText.IsNullOrEmpty()) { @@ -200,11 +191,11 @@ namespace MareSynchronos.UI if (textIsUid) ImGui.PushFont(UiBuilder.MonoFont); ImGui.TextUnformatted(playerText); if (textIsUid) ImGui.PopFont(); - AttachToolTip("Left click to switch between UID display and nick" + Environment.NewLine + + UiShared.AttachToolTip("Left click to switch between UID display and nick" + Environment.NewLine + "Right click to change nick for " + entry.OtherUID); if (ImGui.IsItemClicked(ImGuiMouseButton.Left)) { - bool prevState = textIsUid; + var prevState = textIsUid; if (_showUidForEntry.ContainsKey(entry.OtherUID)) { prevState = _showUidForEntry[entry.OtherUID]; @@ -227,7 +218,7 @@ namespace MareSynchronos.UI { ImGui.SetCursorPosY(originalY); - ImGui.SetNextItemWidth(ImGui.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * 2); + ImGui.SetNextItemWidth(UiShared.GetWindowContentRegionWidth() - ImGui.GetCursorPosX() - buttonSizes - ImGui.GetStyle().ItemSpacing.X * 2); if (ImGui.InputTextWithHint("", "Nick/Notes", ref _editCharComment, 255, ImGuiInputTextFlags.EnterReturnsTrue)) { _configuration.SetCurrentServerUidComment(entry.OtherUID, _editCharComment); @@ -239,10 +230,10 @@ namespace MareSynchronos.UI { _editNickEntry = string.Empty; } - AttachToolTip("Hit ENTER to save\nRight click to cancel"); + UiShared.AttachToolTip("Hit ENTER to save\nRight click to cancel"); } - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + ImGui.GetWindowContentRegionWidth() - buttonSize.X); + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X); ImGui.SetCursorPosY(originalY); if (ImGuiComponents.IconButton(FontAwesomeIcon.Trash)) { @@ -252,51 +243,36 @@ namespace MareSynchronos.UI _apiController.PairedClients.Remove(entry); } } - AttachToolTip("Hold CTRL and click to unpair permanently from " + entry.OtherUID); + UiShared.AttachToolTip("Hold CTRL and click to unpair permanently from " + entry.OtherUID); - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + ImGui.GetWindowContentRegionWidth() - buttonSize.X - ImGui.GetStyle().ItemSpacing.X - trashButtonSize.X); + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X - ImGui.GetStyle().ItemSpacing.X - trashButtonSize.X); ImGui.SetCursorPosY(originalY); if (ImGuiComponents.IconButton(pauseIcon)) { _ = _apiController.SendPairedClientPauseChange(entry.OtherUID, !entry.IsPaused); } - AttachToolTip(entry.IsSynced + UiShared.AttachToolTip(entry.IsSynced ? "Pause pairing with " + entry.OtherUID : "Resume pairing with " + entry.OtherUID); - - - ImGui.PopID(); - } - - private void AttachToolTip(string text) - { - if (ImGui.IsItemHovered()) - { - ImGui.SetTooltip(text); - } } private void DrawPairList() { - ImGui.PushID("pairlist"); - DrawAddPair(); - DrawPairs(); + UiShared.DrawWithID("addpair", DrawAddPair); + UiShared.DrawWithID("pairs", DrawPairs); _transferPartHeight = ImGui.GetCursorPosY(); - DrawFilter(); - ImGui.PopID(); + UiShared.DrawWithID("filter", DrawFilter); } private void DrawPairs() { - ImGui.PushID("pairs"); - var ySize = _transferPartHeight == 0 ? 1 : (ImGui.GetWindowContentRegionMax().Y - ImGui.GetWindowContentRegionMin().Y) - _transferPartHeight - ImGui.GetCursorPosY(); var users = _apiController.PairedClients.Where(p => { if (_characterOrCommentFilter.IsNullOrEmpty()) return true; - _configuration.GetCurrentServerUidComments().TryGetValue(p.OtherUID, out string? comment); + _configuration.GetCurrentServerUidComments().TryGetValue(p.OtherUID, out var comment); return p.OtherUID.ToLower().Contains(_characterOrCommentFilter.ToLower()) || (comment?.ToLower().Contains(_characterOrCommentFilter.ToLower()) ?? false); }); @@ -306,19 +282,16 @@ namespace MareSynchronos.UI ImGui.BeginChild("list", new Vector2(_windowContentWidth, ySize), false); foreach (var entry in users.ToList()) { - DrawPairedClient(entry); + UiShared.DrawWithID("client", () => DrawPairedClient(entry)); } ImGui.EndChild(); - - ImGui.PopID(); } private void DrawServerStatus() { - ImGui.PushID("serverstate"); if (_apiController.ServerAlive) { - var buttonSize = GetIconButtonSize(FontAwesomeIcon.Link); + var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Link); var textSize = ImGui.CalcTextSize(_apiController.SystemInfoDto.CpuUsage.ToString("0.00") + "%"); var originalY = ImGui.GetCursorPosY(); @@ -335,13 +308,13 @@ namespace MareSynchronos.UI ImGui.SameLine(); ImGui.SetCursorPosY(textPos); ImGui.Text("Load"); - AttachToolTip("This is the current servers' CPU load"); + UiShared.AttachToolTip("This is the current servers' CPU load"); - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + ImGui.GetWindowContentRegionWidth() - buttonSize.X); + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X); ImGui.SetCursorPosY(originalY); var serverIsConnected = _apiController.ServerState is ServerState.Connected; var color = UiShared.GetBoolColor(serverIsConnected); - FontAwesomeIcon connectedIcon = serverIsConnected ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink; + var connectedIcon = serverIsConnected ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink; ImGui.PushStyleColor(ImGuiCol.Text, color); if (ImGuiComponents.IconButton(connectedIcon)) @@ -359,18 +332,16 @@ namespace MareSynchronos.UI _ = _apiController.CreateConnections(); } ImGui.PopStyleColor(); - AttachToolTip(_apiController.IsConnected ? "Disconnect from " + _apiController.ServerDictionary[_configuration.ApiUri] : "Connect to " + _apiController.ServerDictionary[_configuration.ApiUri]); + UiShared.AttachToolTip(_apiController.IsConnected ? "Disconnect from " + _apiController.ServerDictionary[_configuration.ApiUri] : "Connect to " + _apiController.ServerDictionary[_configuration.ApiUri]); } else { UiShared.ColorTextWrapped("Server is offline", ImGuiColors.DalamudRed); } - ImGui.PopID(); } private void DrawTransfers() { - ImGui.PushID("transfers"); var currentUploads = _apiController.CurrentUploads.ToList(); ImGui.PushFont(UiBuilder.IconFont); ImGui.Text(FontAwesomeIcon.Upload.ToIconString()); @@ -422,12 +393,10 @@ namespace MareSynchronos.UI } ImGui.SameLine(); - ImGui.PopID(); } private void DrawUIDHeader() { - ImGui.PushID("header"); var uidText = GetUidText(); var buttonSizeX = 0f; @@ -437,28 +406,28 @@ namespace MareSynchronos.UI var originalPos = ImGui.GetCursorPos(); ImGui.SetWindowFontScale(1.5f); - var buttonSize = GetIconButtonSize(FontAwesomeIcon.Cog); + var buttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Cog); buttonSizeX -= buttonSize.X - ImGui.GetStyle().ItemSpacing.X * 2; - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + ImGui.GetWindowContentRegionWidth() - buttonSize.X); + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X); ImGui.SetCursorPosY(originalPos.Y + uidTextSize.Y / 2 - buttonSize.Y / 2); if (ImGuiComponents.IconButton(FontAwesomeIcon.Cog)) { OpenSettingsUi?.Invoke(); } - AttachToolTip("Open the Mare Synchronos Settings"); - + UiShared.AttachToolTip("Open the Mare Synchronos Settings"); + ImGui.SameLine(); //Important to draw the uidText consistently ImGui.SetCursorPos(originalPos); - + if (_apiController.ServerState is ServerState.Connected) { - buttonSizeX += GetIconButtonSize(FontAwesomeIcon.Copy).X - ImGui.GetStyle().ItemSpacing.X * 2; + buttonSizeX += UiShared.GetIconButtonSize(FontAwesomeIcon.Copy).X - ImGui.GetStyle().ItemSpacing.X * 2; ImGui.SetCursorPosY(originalPos.Y + uidTextSize.Y / 2 - buttonSize.Y / 2); if (ImGuiComponents.IconButton(FontAwesomeIcon.Copy)) { ImGui.SetClipboardText(_apiController.UID); } - AttachToolTip("Copy your UID to clipboard"); + UiShared.AttachToolTip("Copy your UID to clipboard"); ImGui.SameLine(); } ImGui.SetWindowFontScale(1f); @@ -473,17 +442,9 @@ namespace MareSynchronos.UI { UiShared.ColorTextWrapped(GetServerError(), GetUidColor()); } - - ImGui.PopID(); } - private Vector2 GetIconButtonSize(FontAwesomeIcon icon) - { - ImGui.PushFont(UiBuilder.IconFont); - var buttonSize = ImGuiHelpers.GetButtonSize(icon.ToIconString()); - ImGui.PopFont(); - return buttonSize; - } + private string GetServerError() { return _apiController.ServerState switch diff --git a/MareSynchronos/UI/IntroUI.cs b/MareSynchronos/UI/IntroUI.cs index fa06ef0..52249d2 100644 --- a/MareSynchronos/UI/IntroUI.cs +++ b/MareSynchronos/UI/IntroUI.cs @@ -48,9 +48,9 @@ namespace MareSynchronos.UI { if (!_pluginConfiguration.AcceptedAgreement && !_readFirstPage) { - ImGui.SetWindowFontScale(1.3f); - ImGui.Text("Welcome to Mare Synchronos!"); - ImGui.SetWindowFontScale(1.0f); + if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont); + ImGui.TextUnformatted("Welcome to Mare Synchronos"); + if (_uiShared.UidFontBuilt) ImGui.PopFont(); ImGui.Separator(); UiShared.TextWrapped("Mare Synchronos is a plugin that will replicate your full current character state including all Penumbra mods to other paired Mare Synchronos users. " + "Note that you will have to have Penumbra as well as Glamourer installed to use this plugin."); @@ -68,15 +68,15 @@ namespace MareSynchronos.UI } else if (!_pluginConfiguration.AcceptedAgreement && _readFirstPage) { - ImGui.SetWindowFontScale(1.3f); - ImGui.Text("Agreement of Usage of Service"); - ImGui.SetWindowFontScale(1.0f); + if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont); + ImGui.TextUnformatted("Agreement of Usage of Service"); + if (_uiShared.UidFontBuilt) ImGui.PopFont(); ImGui.Separator(); ImGui.SetWindowFontScale(1.5f); string readThis = "READ THIS CAREFULLY"; var textSize = ImGui.CalcTextSize(readThis); ImGui.SetCursorPosX(ImGui.GetWindowSize().X / 2 - textSize.X / 2); - ImGui.TextColored(ImGuiColors.DalamudRed, readThis); + UiShared.ColorText(readThis, ImGuiColors.DalamudRed); ImGui.SetWindowFontScale(1.0f); ImGui.Separator(); UiShared.TextWrapped("All of the mod files currently active on your character as well as your current character state will be uploaded to the service you registered yourself at automatically. " + @@ -107,28 +107,29 @@ namespace MareSynchronos.UI } else if (_pluginConfiguration.AcceptedAgreement && (string.IsNullOrEmpty(_pluginConfiguration.CacheFolder) || _pluginConfiguration.InitialScanComplete == false)) { - ImGui.SetWindowFontScale(1.3f); - ImGui.Text("File Cache Setup"); - ImGui.SetWindowFontScale(1.0f); + if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont); + ImGui.TextUnformatted("File Cache Setup"); + if (_uiShared.UidFontBuilt) ImGui.PopFont(); ImGui.Separator(); UiShared.TextWrapped("To not unnecessary download files already present on your computer, Mare Synchronos will have to scan your Penumbra mod directory. " + "Additionally, a local cache folder must be set where Mare Synchronos will download its local file cache to. " + "Once the Cache Folder is set and the scan complete, this page will automatically forward to registration at a service."); UiShared.TextWrapped("Note: The initial scan, depending on the amount of mods you have, might take a while. Please wait until it is completed."); - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow); - UiShared.TextWrapped("Warning: once past this step you should not delete the FileCache.db of Mare Synchronos in the Plugin Configurations folder of Dalamud. " + - "Otherwise on the next launch a full re-scan of the file cache database will be initiated."); - ImGui.PopStyleColor(); + UiShared.ColorTextWrapped("Warning: once past this step you should not delete the FileCache.db of Mare Synchronos in the Plugin Configurations folder of Dalamud. " + + "Otherwise on the next launch a full re-scan of the file cache database will be initiated.", ImGuiColors.DalamudYellow); _uiShared.DrawCacheDirectorySetting(); + if (!_uiShared.HasValidPenumbraModPath) + { + UiShared.ColorTextWrapped("You do not have a valid Penumbra path set. Open Penumbra and set up a valid path for the mod directory.", ImGuiColors.DalamudRed); + } - if (!_fileCacheManager.IsScanRunning && !string.IsNullOrEmpty(_pluginConfiguration.CacheFolder)) + if (!_fileCacheManager.IsScanRunning && !string.IsNullOrEmpty(_pluginConfiguration.CacheFolder) && _uiShared.HasValidPenumbraModPath) { UiShared.TextWrapped("You can adjust how many parallel threads will be used for scanning. Mind that ultimately it will depend on the amount of mods, your disk speed and your CPU. " + "More is not necessarily better, the default of 10 should be fine for most cases."); _uiShared.DrawParallelScansSetting(); - if (ImGui.Button("Start Scan##startScan")) { _fileCacheManager.StartInitialScan(); @@ -141,9 +142,9 @@ namespace MareSynchronos.UI } else { - ImGui.SetWindowFontScale(1.3f); - ImGui.Text("Service registration"); - ImGui.SetWindowFontScale(1.0f); + if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont); + ImGui.TextUnformatted("Service Registration"); + if (_uiShared.UidFontBuilt) ImGui.PopFont(); ImGui.Separator(); if (_pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri) && _uiShared.ShowClientSecret) { @@ -157,13 +158,9 @@ namespace MareSynchronos.UI { ImGui.SetClipboardText(_pluginConfiguration.ClientSecret[_pluginConfiguration.ApiUri]); } - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow); - UiShared.TextWrapped("This is the only time you will be able to see this key in the UI. You can copy it to make a backup somewhere."); - ImGui.PopStyleColor(); + UiShared.ColorTextWrapped("This is the only time you will be able to see this key in the UI. You can copy it to make a backup somewhere.", ImGuiColors.DalamudYellow); ImGui.Separator(); - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen); - UiShared.TextWrapped("You are now ready to go. Press Finish to finalize the settings and open the Mare Synchronos main UI."); - ImGui.PopStyleColor(); + UiShared.ColorTextWrapped("You are now ready to go. Press Finish to finalize the settings and open the Mare Synchronos main UI.", ImGuiColors.ParsedGreen); ImGui.Separator(); if (ImGui.Button("Finish##finishIntro")) { @@ -175,12 +172,10 @@ namespace MareSynchronos.UI { UiShared.TextWrapped("You will now have to register at a service. You can use the provided central service or pick a custom one. " + "There is no support for custom services from the plugin creator. Use at your own risk."); - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); - UiShared.TextWrapped("On registration on a service the plugin will create and save a secret key to your plugin configuration. " + + UiShared.ColorTextWrapped("On registration on a service the plugin will create and save a secret key to your plugin configuration. " + "Make a backup of your secret key. In case of loss, it cannot be restored. The secret key is your identification to the service " + - "to verify who you are. It is directly tied to the UID you will be receiving. In case of loss, you will have to re-register an account."); - UiShared.TextWrapped("Do not ever, under any circumstances, share your secret key to anyone! Likewise do not share your Mare Synchronos plugin configuration to anyone!"); - ImGui.PopStyleColor(); + "to verify who you are. It is directly tied to the UID you will be receiving. In case of loss, you will have to re-register an account.", ImGuiColors.DalamudRed); + UiShared.ColorTextWrapped("Do not ever, under any circumstances, share your secret key to anyone! Likewise do not share your Mare Synchronos plugin configuration to anyone!", ImGuiColors.DalamudRed); _uiShared.DrawServiceSelection(() => SwitchToMainUi?.Invoke(), true); } } diff --git a/MareSynchronos/UI/UIShared.cs b/MareSynchronos/UI/UIShared.cs index 89d0259..d0d2eef 100644 --- a/MareSynchronos/UI/UIShared.cs +++ b/MareSynchronos/UI/UIShared.cs @@ -7,6 +7,7 @@ using Dalamud.Interface; using Dalamud.Interface.Colors; using Dalamud.Interface.ImGuiFileDialog; using Dalamud.Plugin; +using Dalamud.Utility; using ImGuiNET; using MareSynchronos.Managers; using MareSynchronos.Utils; @@ -26,6 +27,7 @@ namespace MareSynchronos.UI public long FileCacheSize => _fileCacheManager.FileCacheSize; public bool ShowClientSecret = true; public string PlayerName => _dalamudUtil.PlayerName; + public bool HasValidPenumbraModPath => !(_ipcManager.PenumbraModDirectory() ?? string.Empty).IsNullOrEmpty() && Directory.Exists(_ipcManager.PenumbraModDirectory()); public bool EditTrackerPosition { get; set; } public ImFontPtr UidFont { get; private set; } public bool UidFontBuilt { get; private set; } @@ -45,6 +47,19 @@ namespace MareSynchronos.UI _pluginInterface.UiBuilder.RebuildFonts(); } + public static float GetWindowContentRegionWidth() + { + return ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X; + } + + public static Vector2 GetIconButtonSize(FontAwesomeIcon icon) + { + ImGui.PushFont(UiBuilder.IconFont); + var buttonSize = ImGuiHelpers.GetButtonSize(icon.ToIconString()); + ImGui.PopFont(); + return buttonSize; + } + private void BuildFont() { var fontFile = Path.Combine(_pluginInterface.DalamudAssetDirectory.FullName, "UIRes", "NotoSansCJKjp-Medium.otf"); @@ -69,6 +84,21 @@ namespace MareSynchronos.UI } } + public static void DrawWithID(string id, Action drawSubSection) + { + ImGui.PushID(id); + drawSubSection.Invoke(); + ImGui.PopID(); + } + + public static void AttachToolTip(string text) + { + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip(text); + } + } + public bool DrawOtherPluginState() { var penumbraExists = _ipcManager.CheckPenumbraApi(); @@ -210,6 +240,7 @@ namespace MareSynchronos.UI private string _customServerName = ""; private string _customServerUri = ""; private bool _enterSecretKey = false; + private bool _cacheDirectoryHasOtherFilesThanCache = false; public void DrawServiceSelection(Action? callBackOnExit = null, bool isIntroUi = false) { @@ -348,21 +379,7 @@ namespace MareSynchronos.UI { ColorTextWrapped("Note: The cache folder should be somewhere close to root (i.e. C:\\MareCache) in a new empty folder. DO NOT point this to your game folder. DO NOT point this to your Penumbra folder.", ImGuiColors.DalamudYellow); var cacheDirectory = _pluginConfiguration.CacheFolder; - if (ImGui.InputText("Cache Folder##cache", ref cacheDirectory, 255)) - { - _isPenumbraDirectory = cacheDirectory.ToLower() == _ipcManager.PenumbraModDirectory()?.ToLower(); - _isDirectoryWritable = IsDirectoryWritable(cacheDirectory); - - if (!string.IsNullOrEmpty(cacheDirectory) - && Directory.Exists(cacheDirectory) - && _isDirectoryWritable - && !_isPenumbraDirectory) - { - _pluginConfiguration.CacheFolder = cacheDirectory; - _pluginConfiguration.Save(); - _fileCacheManager.StartWatchers(); - } - } + ImGui.InputText("Cache Folder##cache", ref cacheDirectory, 255, ImGuiInputTextFlags.ReadOnly); ImGui.SameLine(); ImGui.PushFont(UiBuilder.IconFont); @@ -373,9 +390,15 @@ namespace MareSynchronos.UI { if (!success) return; - _isDirectoryWritable = IsDirectoryWritable(path); _isPenumbraDirectory = path.ToLower() == _ipcManager.PenumbraModDirectory()?.ToLower(); - if (_isDirectoryWritable && !_isPenumbraDirectory) + _isDirectoryWritable = IsDirectoryWritable(path); + _cacheDirectoryHasOtherFilesThanCache = Directory.GetFiles(path, "*", SearchOption.AllDirectories).Any(f => new FileInfo(f).Name.Length != 40); + + if (!string.IsNullOrEmpty(path) + && Directory.Exists(path) + && _isDirectoryWritable + && !_isPenumbraDirectory + && !_cacheDirectoryHasOtherFilesThanCache) { _pluginConfiguration.CacheFolder = path; _pluginConfiguration.Save(); @@ -392,10 +415,11 @@ namespace MareSynchronos.UI else if (!Directory.Exists(cacheDirectory) || !_isDirectoryWritable) { ColorTextWrapped("The folder you selected does not exist or cannot be written to. Please provide a valid path.", ImGuiColors.DalamudRed); + } else if (_cacheDirectoryHasOtherFilesThanCache) + { + ColorTextWrapped("Your selected directory has files inside that are not Mare related. Use an empty directory or a previous Mare cache directory only.", ImGuiColors.DalamudRed); } - - int maxCacheSize = _pluginConfiguration.MaxLocalCacheInGiB; if (ImGui.SliderInt("Maximum Cache Size in GB", ref maxCacheSize, 1, 50, "%d GB")) {