Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

[English](CHANGELOG_EN.md) | 中文

## v1.8.8

- 新增版本更新检测功能,自动检测是否有新版本可用
- 新增手动检测更新机制,可在设置界面手动触发更新检测
- 新增新版本提示功能,当检测到新版本时会在版本显示处显示提示信息

## v1.8.7

- 新增自定义对话系统,支持在动画状态机中触发对话
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

English | [中文](CHANGELOG.md)

## v1.8.8

- Added version update checking functionality, automatically detects if a new version is available
- Added manual update check mechanism, can manually trigger update check in settings interface
- Added new version notification feature, displays notification information at version display when a new version is detected

## v1.8.7

- Added custom dialogue system, supporting dialogue triggering in animation state machines
Expand Down
37 changes: 37 additions & 0 deletions DuckovCustomModel/Configs/UpdateInfoConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;

namespace DuckovCustomModel.Configs
{
public class UpdateInfoConfig : ConfigBase
{
public string LatestVersion { get; set; } = string.Empty;
public string LatestReleaseName { get; set; } = string.Empty;
public DateTime? LastCheckTime { get; set; }
public DateTime? LatestPublishedAt { get; set; }
public bool HasUpdate { get; set; }

public override void LoadDefault()
{
LatestVersion = string.Empty;
LatestReleaseName = string.Empty;
LastCheckTime = null;
LatestPublishedAt = null;
HasUpdate = false;
}

public override bool Validate()
{
return false;
Comment thread
BAKAOLC marked this conversation as resolved.
}

public override void CopyFrom(IConfigBase other)
{
if (other is not UpdateInfoConfig otherConfig) return;
LatestVersion = otherConfig.LatestVersion;
LatestReleaseName = otherConfig.LatestReleaseName;
LastCheckTime = otherConfig.LastCheckTime;
LatestPublishedAt = otherConfig.LatestPublishedAt;
HasUpdate = otherConfig.HasUpdate;
}
}
}
2 changes: 1 addition & 1 deletion DuckovCustomModel/Constant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public static class Constant
{
public const string ModID = "DuckovCustomModel";
public const string ModName = "Duckov Custom Model";
public const string ModVersion = "1.8.7";
public const string ModVersion = "1.8.8";
public const string HarmonyId = "com.ritsukage.DuckovCustomModel";
}
}
127 changes: 127 additions & 0 deletions DuckovCustomModel/HarmonyPatches/GameVersionDisplayPatches.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using Duckov;
using DuckovCustomModel.Localizations;
using DuckovCustomModel.Managers;
using HarmonyLib;
using TMPro;
using UnityEngine;

namespace DuckovCustomModel.HarmonyPatches
{
[HarmonyPatch]
internal static class GameVersionDisplayPatches
{
private const string UpdateColorHex = "#FF9900";
private const string VersionObjectName = "DCMVersionDisplay";
private static TextMeshProUGUI? _versionTextComponent;
private static GameObject? _versionObject;

public static void Initialize()
{
var gameVersionDisplay = Object.FindFirstObjectByType<GameVersionDisplay>();
if (gameVersionDisplay == null)
return;

var parentTransform = gameVersionDisplay.transform.parent;
if (parentTransform == null)
return;

CreateVersionObject(parentTransform, gameVersionDisplay.gameObject);
UpdateVersionText();
}

[HarmonyPatch(typeof(GameVersionDisplay), "Start")]
[HarmonyPostfix]
// ReSharper disable once InconsistentNaming
private static void GameVersionDisplay_Start_Postfix(GameVersionDisplay __instance)
{
if (__instance == null)
return;

if (IsVersionObjectValid())
{
UpdateVersionText();
return;
}

var parentTransform = __instance.transform.parent;
if (parentTransform == null)
return;

if (CreateVersionObject(parentTransform, __instance.gameObject))
UpdateVersionText();
}

private static bool IsVersionObjectValid()
{
return _versionObject != null && _versionTextComponent != null;
}

private static bool CreateVersionObject(Transform parentTransform, GameObject templateObject)
{
var cloneObject = Object.Instantiate(templateObject, parentTransform);
if (cloneObject == null)
return false;

cloneObject.name = VersionObjectName;

DeleteComponent(cloneObject, cloneObject.GetComponent<GameVersionDisplay>());

var textComponent = cloneObject.GetComponent<TextMeshProUGUI>();
if (textComponent == null)
{
Object.Destroy(cloneObject);
return false;
}

_versionObject = cloneObject;
_versionTextComponent = textComponent;
textComponent.richText = true;
textComponent.text = $"{Constant.ModName} v{Constant.ModVersion}";
return true;
}

private static void UpdateVersionText()
{
if (_versionTextComponent == null)
return;

var updateChecker = UpdateChecker.Instance;
if (updateChecker == null)
{
_versionTextComponent.text = $"{Constant.ModName} v{Constant.ModVersion}";
return;
}

var hasUpdate = updateChecker.HasUpdate();
var latestVersion = updateChecker.GetLatestVersion();

_versionTextComponent.text = hasUpdate && !string.IsNullOrEmpty(latestVersion)
? $"{Constant.ModName} v{Constant.ModVersion} - <color={UpdateColorHex}>{Localization.UpdateAvailable} v{latestVersion}</color>"
: $"{Constant.ModName} v{Constant.ModVersion}";
}

public static void RefreshUpdateVersionDisplay()
{
if (!IsVersionObjectValid())
return;

UpdateVersionText();
}

public static void Cleanup()
{
if (_versionObject != null)
{
Object.Destroy(_versionObject);
_versionObject = null;
}

_versionTextComponent = null;
}

private static void DeleteComponent(GameObject gameObject, Component? component)
{
if (component != null) Object.Destroy(component);
}
}
}
12 changes: 11 additions & 1 deletion DuckovCustomModel/Localizations/Chinese.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
"BottomCenter": "下中",
"BottomRight": "右下",
"OffsetX": "偏移 X",
"OffsetY": "偏移 Y"
"OffsetY": "偏移 Y",
"UpdateAvailable": "有可用更新",
"CheckForUpdate": "检查更新",
"LatestVersion": "最新版本",
"LastCheckTime": "上次检查",
"UpdateCheckNotAvailable": "更新检查不可用",
"NeverChecked": "从未检查",
"JustNow": "刚刚",
"MinutesAgo": "分钟前",
"HoursAgo": "小时前",
"DaysAgo": "天前"
}

12 changes: 11 additions & 1 deletion DuckovCustomModel/Localizations/ChineseTraditional.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
"BottomCenter": "下中",
"BottomRight": "右下",
"OffsetX": "偏移 X",
"OffsetY": "偏移 Y"
"OffsetY": "偏移 Y",
"UpdateAvailable": "有可用更新",
"CheckForUpdate": "檢查更新",
"LatestVersion": "最新版本",
"LastCheckTime": "上次檢查",
"UpdateCheckNotAvailable": "更新檢查不可用",
"NeverChecked": "從未檢查",
"JustNow": "剛剛",
"MinutesAgo": "分鐘前",
"HoursAgo": "小時前",
"DaysAgo": "天前"
}

12 changes: 11 additions & 1 deletion DuckovCustomModel/Localizations/English.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
"BottomCenter": "Bottom-Center",
"BottomRight": "Bottom-Right",
"OffsetX": "Offset X",
"OffsetY": "Offset Y"
"OffsetY": "Offset Y",
"UpdateAvailable": "Update Available",
"CheckForUpdate": "Check for Update",
"LatestVersion": "Latest Version",
"LastCheckTime": "Last Check",
"UpdateCheckNotAvailable": "Update check not available",
"NeverChecked": "Never checked",
"JustNow": "Just now",
"MinutesAgo": "minutes ago",
"HoursAgo": "hours ago",
"DaysAgo": "days ago"
}

12 changes: 11 additions & 1 deletion DuckovCustomModel/Localizations/Japanese.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@
"BottomCenter": "下中央",
"BottomRight": "右下",
"OffsetX": "オフセット X",
"OffsetY": "オフセット Y"
"OffsetY": "オフセット Y",
"UpdateAvailable": "更新あり",
"CheckForUpdate": "更新を確認",
"LatestVersion": "最新バージョン",
"LastCheckTime": "最終確認",
"UpdateCheckNotAvailable": "更新確認が利用できません",
"NeverChecked": "未確認",
"JustNow": "たった今",
"MinutesAgo": "分前",
"HoursAgo": "時間前",
"DaysAgo": "日前"
}

20 changes: 20 additions & 0 deletions DuckovCustomModel/Localizations/Localization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ private static string LocalizationDirectory
{ "BottomRight", "Bottom-Right" },
{ "OffsetX", "Offset X" },
{ "OffsetY", "Offset Y" },
{ "UpdateAvailable", "Update Available" },
{ "CheckForUpdate", "Check for Update" },
{ "LatestVersion", "Latest Version" },
{ "LastCheckTime", "Last Check" },
{ "UpdateCheckNotAvailable", "Update check not available" },
{ "NeverChecked", "Never checked" },
{ "JustNow", "Just now" },
{ "MinutesAgo", "minutes ago" },
{ "HoursAgo", "hours ago" },
{ "DaysAgo", "days ago" },
};

public static string Title => GetText("Title");
Expand Down Expand Up @@ -138,6 +148,16 @@ private static string LocalizationDirectory
public static string BottomRight => GetText("BottomRight");
public static string OffsetX => GetText("OffsetX");
public static string OffsetY => GetText("OffsetY");
public static string UpdateAvailable => GetText("UpdateAvailable");
public static string CheckForUpdate => GetText("CheckForUpdate");
public static string LatestVersion => GetText("LatestVersion");
public static string LastCheckTime => GetText("LastCheckTime");
public static string UpdateCheckNotAvailable => GetText("UpdateCheckNotAvailable");
public static string NeverChecked => GetText("NeverChecked");
public static string JustNow => GetText("JustNow");
public static string MinutesAgo => GetText("MinutesAgo");
public static string HoursAgo => GetText("HoursAgo");
public static string DaysAgo => GetText("DaysAgo");

public static event Action<SystemLanguage>? OnLanguageChangedEvent;

Expand Down
6 changes: 3 additions & 3 deletions DuckovCustomModel/Localizations/LocalizedDropdown.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace DuckovCustomModel.Localizations
{
public class LocalizedDropdown : MonoBehaviour
{
private Dropdown? _dropdown;
private TMP_Dropdown? _dropdown;
private bool _isRegistered;
private Action? _refreshAction;

Expand All @@ -20,7 +20,7 @@ private void OnDestroy()
Unregister();
}

public void SetDropdown(Dropdown dropdown)
public void SetDropdown(TMP_Dropdown dropdown)
{
_dropdown = dropdown;
if (_dropdown != null && _refreshAction != null && !_isRegistered) Register();
Expand Down
17 changes: 8 additions & 9 deletions DuckovCustomModel/Localizations/LocalizedText.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace DuckovCustomModel.Localizations
{
public class LocalizedText : MonoBehaviour
{
private bool _isRegistered;
private Text? _text;
private TextMeshProUGUI? _text;
private Func<string>? _textGetter;

private void Awake()
{
_text = GetComponent<Text>();
_text = GetComponent<TextMeshProUGUI>();
if (_text == null)
ModLogger.LogWarning($"LocalizedText component on {gameObject.name} requires a Text component.");
ModLogger.LogWarning(
$"LocalizedText component on {gameObject.name} requires a TextMeshProUGUI component.");
}

private void Start()
{
if (_text != null && _textGetter != null)
{
Register();
RefreshText();
}
if (_text == null || _textGetter == null) return;
Register();
RefreshText();
}

private void OnDestroy()
Expand Down
Loading