KF3_TranslationUpdater/UpdateHandler.cs

366 lines
11 KiB
C#
Raw Permalink Normal View History

using System.IO.Compression;
2023-10-11 08:33:27 +08:00
using System.IO;
using System;
2023-10-11 08:33:27 +08:00
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine;
using System.Collections;
using System.Reflection;
2023-10-11 08:33:27 +08:00
public class UpdateHandler : MonoBehaviour
{
private string _serverVersion = "";
private float _messageTime = 0;
private bool _readyForDeletion = false;
private const string PluginVersion = "1.1.0";
private const string defaultRepositoryUrl = "https://git.japari.cafe/api/v1/repos/Vorked/VorkedTranslationPack";
//playerprefs keys
private const string translationVersionKey = "lastVersion";
private const string repositoryUrlKey = "customRepositoryUrl";
private const string customRepositoryKey = "customRepository";
public static void Create()
{
#if UNITY_EDITOR
var prefab = AssetBundle.LoadFromFile(@"R:\Unity\KF3Modder2\Assets\AssetBundles\UpdateHandler");
#else
var prefab = AssetBundle.LoadFromMemory(LoadResource("UpdateHandler.asset"));
#endif
Instantiate(prefab.LoadAsset("UpdateHandler"));
prefab.Unload(false);
}
public static byte[] LoadResource(string fileName)
{
Assembly asm = Assembly.GetExecutingAssembly();
fileName = asm.GetName().Name + "." + fileName;
var bytes = new byte[0];
using (Stream resFilestream = asm.GetManifestResourceStream(fileName))
{
if (resFilestream == null) return null;
byte[] byteArray = new byte[resFilestream.Length];
resFilestream.Read(byteArray, 0, byteArray.Length);
bytes = byteArray;
}
Console.WriteLine(bytes.Length);
return bytes;
}
2023-10-11 08:33:27 +08:00
public IEnumerator Start()
{
yield return 0;
transform.SetAsLastSibling();
PanelUpdateChecker.SetActive(true);
string repositoryUrl = PlayerPrefs.GetInt(customRepositoryKey, 0) == 0 ? defaultRepositoryUrl : PlayerPrefs.GetString(repositoryUrlKey, defaultRepositoryUrl);
string currentVersion = PlayerPrefs.GetString(translationVersionKey, "undefined");
2023-10-11 08:33:27 +08:00
string newVersion = currentVersion;
string downloadError = "";
bool updateSuccess = false;
2023-10-11 08:33:27 +08:00
yield return DownloadText(repositoryUrl,
(json) =>
{
try
{
if (string.IsNullOrEmpty(json))
{
throw new System.Exception("No response from " + repositoryUrl);
}
var newData = JsonUtility.FromJson<JsonSmall>(json);
newVersion = newData.updated_at;
updateSuccess = true;
}
catch (System.Exception e)
{
downloadError = e.Message;
updateSuccess = false;
}
2023-10-11 08:33:27 +08:00
}
);
if (!updateSuccess)
{
PanelUpdateChecker.SetActive(false);
yield return SetAwaitableMessage("Failed to check for update!\nError: " + downloadError, 5);
OpenSettings();
_readyForDeletion = true;
yield break;
}
2023-10-11 08:33:27 +08:00
Debug.Log("local version: " + currentVersion);
Debug.Log("server version: " + newVersion);
if (newVersion != currentVersion)
{
OpenUpdateAvailable();
2023-10-11 08:33:27 +08:00
_serverVersion = newVersion;
PanelUpdateChecker.SetActive(false);
2023-10-11 08:33:27 +08:00
}
else
{
float time = 0;
while (time < 3 || PanelSettings.activeInHierarchy)
2023-10-11 08:33:27 +08:00
{
time += Time.deltaTime;
yield return 0;
2023-10-11 08:33:27 +08:00
}
Destroy(this.gameObject);
2023-10-11 08:33:27 +08:00
}
}
private void Update()
{
if (_messageTime > 0)
{
_messageTime -= Time.deltaTime;
if (_messageTime <= 0)
{
PanelMessage.SetActive(false);
}
2023-10-11 08:33:27 +08:00
}
else if (_readyForDeletion && !PanelSettings.activeInHierarchy)
2023-10-11 08:33:27 +08:00
{
Destroy(this.gameObject);
}
}
public IEnumerator UpdateTranslation()
{
PanelUpdateProgress.SetActive(true);
SlUpdateProgress.value = 0;
2023-10-11 08:33:27 +08:00
byte[] bytes = null;
string repositoryUrl = PlayerPrefs.GetInt(customRepositoryKey, 0) == 0 ? defaultRepositoryUrl : PlayerPrefs.GetString(repositoryUrlKey, defaultRepositoryUrl);
2023-10-11 08:33:27 +08:00
yield return DownloadBytes(repositoryUrl + "/archive/master.zip",
(newBytes) =>
{
bytes = newBytes;
},
SetUpdateProgress
2023-10-11 08:33:27 +08:00
);
if (bytes.Length <= 0)
{
PanelUpdateProgress.SetActive(false);
yield return SetAwaitableMessage("Failed to download the update!\nCheck your settings.", 5);
OpenSettings();
_readyForDeletion = true;
2023-10-11 08:33:27 +08:00
yield break;
}
try
2023-10-11 08:33:27 +08:00
{
using (var compressedFileStream = new MemoryStream(bytes))
2023-10-11 08:33:27 +08:00
{
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Read, false))
2023-10-11 08:33:27 +08:00
{
foreach (var file in zipArchive.Entries)
2023-10-11 08:33:27 +08:00
{
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);
}
2023-10-11 08:33:27 +08:00
}
}
}
}
catch (System.Exception e)
{
SetMessage("Failed to install the update!\nError:" + e.Message, 5);
_readyForDeletion = true;
yield break;
}
2023-10-11 08:33:27 +08:00
PlayerPrefs.SetString(translationVersionKey, _serverVersion);
PlayerPrefs.Save();
PanelUpdateProgress.SetActive(false);
2023-10-11 08:33:27 +08:00
SetMessage("Update completed! Please restart the game to apply it.", 5);
_readyForDeletion = true;
2023-10-11 08:33:27 +08:00
}
#region Message
[Header("Message")]
public GameObject PanelMessage;
public Text TextMessage;
2023-10-11 08:33:27 +08:00
private void SetMessage(string message, float time = 2)
{
PanelMessage.SetActive(true);
TextMessage.text = message;
2023-10-11 08:33:27 +08:00
_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
2023-10-11 08:33:27 +08:00
public static IEnumerator DownloadBytes(string url, System.Action<byte[]> callback, System.Action<float> onProgressChanged = null)
{
UnityWebRequest www = UnityWebRequest.Get(url);
var request = www.SendWebRequest();
while (!request.isDone)
{
onProgressChanged?.Invoke(request.progress);
yield return 0;
}
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(url);
Debug.Log(www.error);
callback(null);
}
else
{
callback(www.downloadHandler.data);
}
}
public static IEnumerator DownloadText(string url, System.Action<string> callback)
{
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log(url);
Debug.Log(www.error);
callback(null);
}
else
{
callback(www.downloadHandler.text);
}
}
public class JsonSmall
{
public string updated_at;
}
}