From 6e9a369ab4d0a04ce943769e2a5bcb109dd5b039 Mon Sep 17 00:00:00 2001 From: katboi01 Date: Fri, 13 Oct 2023 21:14:59 +0800 Subject: [PATCH] UI update Added interface using an embedded assetbundle. Added translation source setting. --- TranslationUpdater.cs | 9 +- TranslationUpdater.csproj | 13 ++ UpdateHandler.asset | Bin 0 -> 195904 bytes UpdateHandler.cs | 296 +++++++++++++++++++++++++++++++------- 4 files changed, 261 insertions(+), 57 deletions(-) create mode 100644 UpdateHandler.asset diff --git a/TranslationUpdater.cs b/TranslationUpdater.cs index 32a1d23..5d76e92 100644 --- a/TranslationUpdater.cs +++ b/TranslationUpdater.cs @@ -1,7 +1,5 @@ using BepInEx; -using HarmonyLib; -using System.Reflection; -using UnityEngine; +using System; namespace TranslationUpdater { @@ -10,11 +8,12 @@ namespace TranslationUpdater { public const string pluginGuid = "katboi01.TranslationUpdater"; public const string pluginName = "KF3 Translation Updater"; - public const string pluginVersion = "1.0.0"; + public const string pluginVersion = "1.1.0"; public void Awake() { - new GameObject(pluginName).AddComponent(); + Console.WriteLine("Loading Updater"); + UpdateHandler.Create(); } } } diff --git a/TranslationUpdater.csproj b/TranslationUpdater.csproj index da6018d..efae0c3 100644 --- a/TranslationUpdater.csproj +++ b/TranslationUpdater.csproj @@ -50,9 +50,15 @@ + + ..\Libs\Unity.TextMeshPro.dll + ..\Libs\UnityEngine.dll + + ..\Libs\UnityEngine.AssetBundleModule.dll + ..\Libs\UnityEngine.CoreModule.dll @@ -65,6 +71,10 @@ ..\Libs\UnityEngine.TextRenderingModule.dll + + False + ..\Libs\UnityEngine.UI.dll + ..\Libs\UnityEngine.UIModule.dll @@ -77,5 +87,8 @@ + + + \ No newline at end of file diff --git a/UpdateHandler.asset b/UpdateHandler.asset new file mode 100644 index 0000000000000000000000000000000000000000..7d8f44d63b17f0de2755d8f53c37286b72929359 GIT binary patch literal 195904 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 bm9y4=KT1|MIjuf { - var newData = JsonUtility.FromJson(json); - newVersion = newData.updated_at; + try + { + if (string.IsNullOrEmpty(json)) + { + throw new System.Exception("No response from " + repositoryUrl); + } + var newData = JsonUtility.FromJson(json); + newVersion = newData.updated_at; + updateSuccess = true; + } + catch (System.Exception e) + { + downloadError = e.Message; + updateSuccess = false; + } } ); + if (!updateSuccess) + { + PanelUpdateChecker.SetActive(false); + yield return SetAwaitableMessage("Failed to check for update!\nError: " + downloadError, 5); + OpenSettings(); + _readyForDeletion = true; + yield break; + } + Debug.Log("local version: " + currentVersion); Debug.Log("server version: " + newVersion); if (newVersion != currentVersion) { + OpenUpdateAvailable(); _serverVersion = newVersion; + PanelUpdateChecker.SetActive(false); } else { - Destroy(this.gameObject); - } - } - - public void OnGUI() - { - if (_updating || _messageTime > 0) - { - var style = GUI.skin.GetStyle("Label"); - style.normal.textColor = Color.black; - style.normal.background = Texture2D.whiteTexture; - style.alignment = TextAnchor.MiddleCenter; - GUI.Label(new Rect(Screen.width / 2 - 10, Screen.height / 2 - 25, 200, 100), _message, style); - } - else - { - var style = GUI.skin.GetStyle("Button"); - style.alignment = TextAnchor.UpperCenter; - if (GUI.Button(new Rect(Screen.width / 2 - 100, 0, 200, 50), "Translation Update Available", style)) + float time = 0; + while (time < 3 || PanelSettings.activeInHierarchy) { - StartCoroutine(UpdateTranslation()); + time += Time.deltaTime; + yield return 0; } + Destroy(this.gameObject); } } @@ -67,8 +118,13 @@ public class UpdateHandler : MonoBehaviour if (_messageTime > 0) { _messageTime -= Time.deltaTime; + + if (_messageTime <= 0) + { + PanelMessage.SetActive(false); + } } - else if (_updateSuccess) + else if (_readyForDeletion && !PanelSettings.activeInHierarchy) { Destroy(this.gameObject); } @@ -76,56 +132,192 @@ public class UpdateHandler : MonoBehaviour public IEnumerator UpdateTranslation() { - _updating = true; + PanelUpdateProgress.SetActive(true); + SlUpdateProgress.value = 0; byte[] bytes = null; + string repositoryUrl = PlayerPrefs.GetInt(customRepositoryKey, 0) == 0 ? defaultRepositoryUrl : PlayerPrefs.GetString(repositoryUrlKey, defaultRepositoryUrl); yield return DownloadBytes(repositoryUrl + "/archive/master.zip", (newBytes) => { bytes = newBytes; }, - (progress) => - { - SetMessage($"Downloading {progress * 100}%"); - } + SetUpdateProgress ); if (bytes.Length <= 0) { - SetMessage("Error. Download failed"); - _updateSuccess = false; + PanelUpdateProgress.SetActive(false); + yield return SetAwaitableMessage("Failed to download the update!\nCheck your settings.", 5); + OpenSettings(); + _readyForDeletion = true; yield break; } - using (var compressedFileStream = new MemoryStream(bytes)) + try { - using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Read, false)) + using (var compressedFileStream = new MemoryStream(bytes)) { - foreach (var file in zipArchive.Entries) + using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Read, false)) { - if (file.Name != "") + foreach (var file in zipArchive.Entries) { - //remove repo name from file path - var outFilePath = file.FullName.Split(new[] { '/' }, 2)[1]; - Directory.CreateDirectory(Path.GetDirectoryName(outFilePath)); - file.ExtractToFile(outFilePath, true); + if (file.Name != "") + { + //remove repo name from file path + var outFilePath = file.FullName.Split(new[] { '/' }, 2)[1]; + Directory.CreateDirectory(Path.GetDirectoryName(outFilePath)); + file.ExtractToFile(outFilePath, true); + } } } } } + catch (System.Exception e) + { + SetMessage("Failed to install the update!\nError:" + e.Message, 5); + _readyForDeletion = true; + yield break; + } - PlayerPrefs.SetString(translationVersion, _serverVersion); + PlayerPrefs.SetString(translationVersionKey, _serverVersion); + PlayerPrefs.Save(); + PanelUpdateProgress.SetActive(false); SetMessage("Update completed! Please restart the game to apply it.", 5); - _updateSuccess = true; - _updating = false; + _readyForDeletion = true; } + #region Message + [Header("Message")] + public GameObject PanelMessage; + public Text TextMessage; + private void SetMessage(string message, float time = 2) { - _message = message; + PanelMessage.SetActive(true); + TextMessage.text = message; _messageTime = time; } + private IEnumerator SetAwaitableMessage(string message, float time) + { + SetMessage(message, time); + do + { + yield return 0; + } + while (PanelMessage.activeInHierarchy); + } + #endregion + + #region UpdateChecker + [Header("UpdateChecker")] + public GameObject PanelUpdateChecker; + #endregion + + #region UpdateProgress + [Header("UpdateProgress")] + public GameObject PanelUpdateProgress; + public Slider SlUpdateProgress; + public Text TextUpdateProgress; + + public void SetUpdateProgress(float value) + { + SlUpdateProgress.value = value; + TextUpdateProgress.text = $"{Mathf.Round(value * 10000) / 100}%"; + } + #endregion + + #region UpdateAvailable + [Header("UpdateAvailable")] + public GameObject PanelUpdateAvailable; + + public void OpenUpdateAvailable() + { + PanelUpdateAvailable.SetActive(true); + } + + public void OnIgnore() + { + Destroy(this.gameObject); + } + + public void OnDownload() + { + PanelUpdateAvailable.SetActive(false); + StartCoroutine(UpdateTranslation()); + } + #endregion + + #region Settings + private bool _settingsChanged = false; + [Header("Settings")] + public GameObject PanelSettings; + public Dropdown DdRepository; + public InputField InRepositoryUrl; + public Text TextUpdaterVersion; + public Text TextTranslationVersion; + + public void OpenSettings() + { + PanelSettings.gameObject.SetActive(true); + int mode = PlayerPrefs.GetInt(customRepositoryKey, 0); + OnSourceDropdown(mode); + DdRepository.SetValueWithoutNotify(mode); + TextUpdaterVersion.text = "Updater Version: " + PluginVersion; + TextTranslationVersion.text = "Translation Version: " + PlayerPrefs.GetString(translationVersionKey, "undefined"); + _settingsChanged = false; + } + + public void OnSourceDropdown(int choice) + { + switch (choice) + { + case 0: + PlayerPrefs.SetInt(customRepositoryKey, 0); + InRepositoryUrl.text = defaultRepositoryUrl; + InRepositoryUrl.interactable = false; + break; + case 1: + PlayerPrefs.SetInt(customRepositoryKey, 1); + InRepositoryUrl.text = PlayerPrefs.GetString(repositoryUrlKey, defaultRepositoryUrl); + InRepositoryUrl.interactable = true; + break; + } + PlayerPrefs.Save(); + _settingsChanged = true; + } + + public void OnSourceEditFinished(string text) + { + PlayerPrefs.SetString(repositoryUrlKey, text); + PlayerPrefs.Save(); + _settingsChanged = true; + } + + public void OnClearButton() + { + PlayerPrefs.SetString(translationVersionKey, "undefined"); + PlayerPrefs.Save(); + OpenSettings(); + _settingsChanged = true; + } + + public void OnSettingsClose() + { + if (_settingsChanged) + { + Destroy(this.gameObject); + Create(); + } + else + { + PanelSettings.SetActive(false); + } + } + + #endregion + public static IEnumerator DownloadBytes(string url, System.Action callback, System.Action onProgressChanged = null) { UnityWebRequest www = UnityWebRequest.Get(url);