diff --git a/CHANGELOG.md b/CHANGELOG.md index 433c580..58c1871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Latest Changelog -- Added OSC parameter option: 'ToN_MasterChange' - - You can use this parameter to detect when the instance master has changed. -- Updated Simplified Chinese localization (Thank you @Fallen-ice) -- Updated Japanese localization (Thank you @nomlasvrc) \ No newline at end of file +- Updated 'ToN_Item' OSC parameter to include Nicomal & バ亀⁄bakame's contributor items. +- Added a warning for when you're about to parse large log files from VRChat that might slow down the program on first launch. +- Added some log parsing logic improvements. +- Automatic Updates will no longer open the Save Manager program automatically after downloading. This is to prevent more false positives. +- Added some language strings for Update related dialogs. \ No newline at end of file diff --git a/Docs/OSC/OSC_Items.md b/Docs/OSC/OSC_Items.md index 9a0fdd4..ec3602e 100644 --- a/Docs/OSC/OSC_Items.md +++ b/Docs/OSC/OSC_Items.md @@ -89,9 +89,10 @@ | ID | Item | | - | - | | `71` | Wave Coil -| `72` | Shape +| `72` | Shape & ??? | `73` | Overseer Plush | `74` | Darkheart | `75` | Knife (SABOTAGE) -| `76` | + Mara -| `77` | + Wispy WISPYYY!!! \ No newline at end of file +| `76` | [Carrot (Mara)](https://terror.moe/items/carrot) +| `77` | [Wispy WISPYYY!!!](https://terror.moe/items/wispy_plush) +| `79` | [Judia (Nicomal)](https://terror.moe/items/judia) & [Memoria (バ亀⁄bakame)](https://terror.moe/items/memoria) \ No newline at end of file diff --git a/Localization/Language/en-US.json b/Localization/Language/en-US.json index e0840b4..54785e7 100644 --- a/Localization/Language/en-US.json +++ b/Localization/Language/en-US.json @@ -18,6 +18,11 @@ "MESSAGE.UPDATE_AVAILABLE.TITLE": "New update available", "MESSAGE.UPDATE_UNAVAILABLE": "No updates are currently available.", "MESSAGE.UPDATE_UNAVAILABLE.TITLE": "No updates available", + "MESSAGE.UPDATE_SUCCESS": "Successfully downloaded update: {0}\nOpen 'ToNSaveManager' again to continue...", + "MESSAGE.UPDATE_FAILED": "Automatic update has failed. Try using the file 'update.bat' instead.\nPlease report this error on the GitHub page.", + + "MESSAGE.LARGE_LOG_WARNING": "You are about to parse a very large VRChat log file!\nFile Name: {0}\nFile Size: {1}\n\nScanning this log file for save codes will take some extra time.\nWould you like to continue reading this file?", + "MESSAGE.LARGE_LOG_WARNING.TITLE": "PARSING LARGE LOG FILE!", "MESSAGE.COPY_TO_CLIPBOARD": "Copied to clipboard!\n\nYou can now paste the code in game.", "MESSAGE.COPY_TO_CLIPBOARD.TITLE": "Copied", diff --git a/Program.cs b/Program.cs index 29f765f..1ec3153 100644 --- a/Program.cs +++ b/Program.cs @@ -18,17 +18,16 @@ internal static class Program internal static readonly string ProgramDirectory = AppContext.BaseDirectory ?? string.Empty; internal static readonly string ProgramLocation = Path.Combine(ProgramDirectory, ProgramFile); - internal static readonly string ProgramLocationTemporary = Path.Combine(ProgramDirectory, "__" + ProgramFile); + internal static readonly string ProgramLocationTemporary = Path.Combine(ProgramDirectory, "_" + ProgramFile.ToLowerInvariant() + ".old"); + internal static readonly string ProgramLocationTemporaryLegacy = Path.Combine(ProgramDirectory, "__" + ProgramFile); internal const string ProgramFile = ProgramName + ".exe"; internal static readonly string DataLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ProgramName); internal static readonly string LegacyDataLocation = Path.Combine(LogWatcher.GetVRChatDataLocation(), ProgramName); internal static Mutex? AppMutex = new Mutex(true, ProgramName); - internal static void ReleaseMutex() - { - if (AppMutex != null) - { + internal static void ReleaseMutex() { + if (AppMutex != null) { AppMutex.ReleaseMutex(); AppMutex.Dispose(); AppMutex = null; diff --git a/Updater.cs b/Updater.cs index 289df4f..ba60062 100644 --- a/Updater.cs +++ b/Updater.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using ToNSaveManager.Models; using ICSharpCode.SharpZipLib.Zip; +using ToNSaveManager.Localization; namespace ToNSaveManager { internal static class Updater { @@ -9,7 +10,7 @@ internal static class Updater { [return: MarshalAs(UnmanagedType.Bool)] static extern bool AllocConsole(); - const string POST_UPDATE_ARG = "--clean-update"; + static string POST_UPDATE_FILE => Program.ProgramLocationTemporary; internal static void Start(GitHubRelease release, GitHubRelease.Asset asset) { AllocConsole(); @@ -22,7 +23,7 @@ internal static void Start(GitHubRelease release, GitHubRelease.Asset asset) { if (File.Exists(TempFileLocation)) File.Delete(TempFileLocation); - Console.Write($"Downloading '{asset.name}' . . . "); + Console.WriteLine($"Downloading '{asset.name}' . . . "); string downloadUrl = asset.browser_download_url; using (HttpClient client = new HttpClient()) { @@ -46,21 +47,19 @@ internal static void Start(GitHubRelease release, GitHubRelease.Asset asset) { Console.WriteLine("Finishing update . . ."); File.Delete(TempFileLocation); // .zip file cleanup - Console.WriteLine("Update complete, restarting . . ."); + Console.WriteLine("Update complete . . ."); Program.ReleaseMutex(); // Release mutex so downloaded app opens properly - // Start new process with --post-update - ProcessStartInfo processInfo = new ProcessStartInfo(Program.ProgramFile, POST_UPDATE_ARG); - Process.Start(processInfo); - // Exit this app + + MessageBox.Show(string.Format(LANG.S("MESSAGE.UPDATE_SUCCESS") ?? "Successfully downloaded update: {0}\nOpen 'ToNSaveManager' again to continue...", release.tag_name), + Program.ProgramName, MessageBoxButtons.OK, MessageBoxIcon.Information); Application.Exit(); return; } catch (Exception ex) { Logger.Error("Automatic update failed."); Logger.Error(ex); - - MessageBox.Show("Automatic update has failed. Try using the file 'update.bat' instead.\nPlease report this error to on the GitHub page.\n\n" + ex, "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show((LANG.S("MESSAGE.UPDATE_FAILED") ?? "Automatic update has failed. Try using the file 'update.bat' instead.\nPlease report this error to on the GitHub page.") + "\n\n" + ex, "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (File.Exists(Program.ProgramLocationTemporary)) { @@ -71,23 +70,11 @@ internal static void Start(GitHubRelease release, GitHubRelease.Asset asset) { const string LEGACY_POST_UPDATE_ARG = "--post-update"; internal static void CheckPostUpdate(string[] args) { bool updateLegacy = Program.ContainsArg(LEGACY_POST_UPDATE_ARG); - if (!updateLegacy && !Program.ContainsArg(POST_UPDATE_ARG)) return; + bool isPostUpdate = File.Exists(POST_UPDATE_FILE) || Program.ContainsArg("--clean-update"); + if (!updateLegacy && !isPostUpdate) return; Logger.Info("Running post-update cleanup."); try { - using (Process currentProcess = Process.GetCurrentProcess()) { - Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName); - foreach (Process process in processes) { - using (process) { - if (process.Id != currentProcess.Id) { - Logger.Info("Killing old running process: " + process.Id); - process.Kill(); - process.WaitForExit(); - } - } - } - } - if (updateLegacy) { // Run legacy cleanup, old to new transition Logger.Info("Updated from legacy version, running legacy cleanup..."); @@ -123,8 +110,12 @@ internal static void CheckPostUpdate(string[] args) { File.Delete(Program.ProgramLocationTemporary); } - Logger.Info("Post-update success."); - // MessageBox.Show("Successfully updated to version " + Program.GetVersion(), Program.ProgramName, MessageBoxButtons.OK, MessageBoxIcon.Information); + if (File.Exists(Program.ProgramLocationTemporaryLegacy)) { + Logger.Info("Deleting old program files again."); + File.Delete(Program.ProgramLocationTemporaryLegacy); + } + + Logger.Info("Post-update success. I always knew."); } catch (Exception ex) { Logger.Error("Failed to run post-update."); Logger.Error(ex); diff --git a/Utils/LogParser/LogContext.cs b/Utils/LogParser/LogContext.cs index 623f24d..f8ba1b5 100644 --- a/Utils/LogParser/LogContext.cs +++ b/Utils/LogParser/LogContext.cs @@ -124,6 +124,10 @@ public virtual void Drop(string name) { } + public virtual bool Validate(long position, FileInfo fileInfo) { + return true; + } + /// /// Get's a list of players in this room as a string. /// diff --git a/Utils/LogParser/LogWatcher.cs b/Utils/LogParser/LogWatcher.cs index 867717a..21ecf06 100644 --- a/Utils/LogParser/LogWatcher.cs +++ b/Utils/LogParser/LogWatcher.cs @@ -112,7 +112,11 @@ private void LogTick(object? sender, EventArgs? e) continue; } - ParseLog(fileInfo, logContext, sender == null); + if (firstRun && logContext.Authenticated && !logContext.Validate(logContext.Position, fileInfo)) { + logContext.RoomReadPos = logContext.Position = fileInfo.Length; + } else { + ParseLog(fileInfo, logContext, sender == null); + } if (!logContext.Initialized) { diff --git a/Utils/LogParser/ToNLogContext.cs b/Utils/LogParser/ToNLogContext.cs index aaff5e7..c42dc99 100644 --- a/Utils/LogParser/ToNLogContext.cs +++ b/Utils/LogParser/ToNLogContext.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using System.Xml.Linq; +using ToNSaveManager.Localization; using ToNSaveManager.Models; using ToNSaveManager.Models.Index; using ToNSaveManager.Utils.API; @@ -163,6 +164,35 @@ public void SetRoundResult(ToNRoundResult result) { Result = result; } + #region File Size Warnings + const long PLEASE_DONT_SLEEP_ON_VRCHAT = 200_000_000; + private static readonly string[] Units = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; + + public override bool Validate(long position, FileInfo fileInfo) { + long remainingSize = fileInfo.Length - position; + if (remainingSize > PLEASE_DONT_SLEEP_ON_VRCHAT) { + DialogResult result = MessageBox.Show( + string.Format(LANG.S("MESSAGE.LARGE_LOG_WARNING") ?? "You are about to parse a very large VRChat log file!\nFile Name: {0}\nFile Size: {1}\n\nParsing this log file will take some extra time.\nWould you like to continue reading this file?", fileInfo.Name, GetReadableFileSize(fileInfo.Length)), + LANG.S("MESSAGE.LARGE_LOG_WARNING.TITLE") ?? "Parsing large log file!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + return result == DialogResult.Yes || result != DialogResult.No; + } + + return true; + } + + private static string GetReadableFileSize(long size) + { + int unitIndex = 0; + while (size >= 1024) { + size /= 1024; + ++unitIndex; + } + + string unit = Units[unitIndex]; + return string.Format("{0:0.#} {1}", size, unit); + } + #endregion + #region Pickup Parsing private string? LastItemKey; public override void Pickup(string name) { diff --git a/Windows/MainWindow.cs b/Windows/MainWindow.cs index 330201e..5381e8e 100644 --- a/Windows/MainWindow.cs +++ b/Windows/MainWindow.cs @@ -630,6 +630,10 @@ internal void SetBackupButton(bool enabled) { private void LogWatcher_OnLine(object? sender, OnLineArgs e) { DateTime timestamp = e.Timestamp; ToNLogContext context = e.Context; +#if !DEBUG + if (!context.IsHomeWorld) return; // Don't read logs not from ToN. +#endif + string line = e.Content.Substring(34); if (HandleSaveCode(line, timestamp, context) || @@ -933,7 +937,7 @@ private bool HandleStatCollection(string line, DateTime timestamp, ToNLogContext return false; } - #endregion +#endregion #region Data private Entry? RecentData;