[O] ResetTouchAfterTrack -> ResetTouch, add press key to reset (#93)
AquaMai Build / build (push) Has been cancelled Details

* [O] ResetTouchAfterTrack -> ResetTouch, add press key to reset

* fix

* update

* fix: Remove not work

---------

Co-authored-by: Menci <mencici@msn.com>
pull/94/head
凌莞~(=^▽^=) 2024-11-30 05:29:30 +08:00 committed by GitHub
parent bed1b85319
commit d5a9c98ff9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 161 additions and 24 deletions

View File

@ -5,5 +5,7 @@ public interface IConfigView
public void SetValue(string path, object value); public void SetValue(string path, object value);
public T GetValueOrDefault<T>(string path, T defaultValue = default); public T GetValueOrDefault<T>(string path, T defaultValue = default);
public bool TryGetValue<T>(string path, out T resultValue); public bool TryGetValue<T>(string path, out T resultValue);
public bool Remove(string path);
public string ToToml(); public string ToToml();
public IConfigView Clone();
} }

View File

@ -3,6 +3,7 @@ using System.Reflection;
using System.Text; using System.Text;
using AquaMai.Config.Attributes; using AquaMai.Config.Attributes;
using AquaMai.Config.Interfaces; using AquaMai.Config.Interfaces;
using AquaMai.Config.Migration;
using Tomlet.Models; using Tomlet.Models;
namespace AquaMai.Config; namespace AquaMai.Config;
@ -60,7 +61,7 @@ public class ConfigSerializer(IConfigSerializer.Options Options) : IConfigSerial
} }
// Version // Version
AppendEntry(sb, null, "Version", "2.0"); AppendEntry(sb, null, "Version", ConfigMigrationManager.Instance.LatestVersion);
foreach (var section in ((Config)config).reflectionManager.SectionValues) foreach (var section in ((Config)config).reflectionManager.SectionValues)
{ {

View File

@ -59,6 +59,12 @@ public class ConfigView : IConfigView
} }
current = (TomlTable)next; current = (TomlTable)next;
} }
if (value == null)
{
current.Keys.Remove(pathComponents.Last());
return;
}
current.Put(pathComponents.Last(), value); current.Put(pathComponents.Last(), value);
} }
@ -85,6 +91,11 @@ public class ConfigView : IConfigView
resultValue = default; resultValue = default;
return false; return false;
} }
if (typeof(T) == typeof(object))
{
resultValue = (T)(object)value;
return true;
}
try try
{ {
resultValue = Utility.ParseTomlValue<T>(value); resultValue = Utility.ParseTomlValue<T>(value);
@ -98,8 +109,34 @@ public class ConfigView : IConfigView
} }
} }
public bool Remove(string path)
{
var pathComponents = path.Split('.');
var current = root;
foreach (var component in pathComponents.Take(pathComponents.Length - 1))
{
if (!Utility.TomlTryGetValueCaseInsensitive(current, component, out var next) || next is not TomlTable nextTable)
{
return false;
}
current = (TomlTable)next;
}
var keyToRemove = pathComponents.Last();
var keysCaseSensitive = current.Keys.Where(k => string.Equals(k, keyToRemove, StringComparison.OrdinalIgnoreCase));
foreach (var key in keysCaseSensitive)
{
current.Entries.Remove(key);
}
return keysCaseSensitive.Any();
}
public string ToToml() public string ToToml()
{ {
return root.SerializedValue; return root.SerializedValue;
} }
public IConfigView Clone()
{
return new ConfigView(ToToml());
}
} }

View File

@ -12,7 +12,8 @@ public class ConfigMigrationManager : IConfigMigrationManager
private readonly Dictionary<string, IConfigMigration> migrationMap = private readonly Dictionary<string, IConfigMigration> migrationMap =
new List<IConfigMigration> new List<IConfigMigration>
{ {
new ConfigMigration_V1_0_V2_0() new ConfigMigration_V1_0_V2_0(),
new ConfigMigration_V2_0_V2_1()
}.ToDictionary(m => m.FromVersion); }.ToDictionary(m => m.FromVersion);
public string LatestVersion { get; } public string LatestVersion { get; }
@ -39,10 +40,12 @@ public class ConfigMigrationManager : IConfigMigrationManager
config = migration.Migrate(config); config = migration.Migrate(config);
currentVersion = migration.ToVersion; currentVersion = migration.ToVersion;
} }
if (currentVersion != LatestVersion) if (currentVersion != LatestVersion)
{ {
throw new ArgumentException($"Could not migrate the config from v{currentVersion} to v{LatestVersion}"); throw new ArgumentException($"Could not migrate the config from v{currentVersion} to v{LatestVersion}");
} }
return config; return config;
} }
@ -52,7 +55,8 @@ public class ConfigMigrationManager : IConfigMigrationManager
{ {
return version; return version;
} }
// Assume v1.0 if not found // Assume v1.0 if not found
return "1.0"; return "1.0";
} }
} }

View File

@ -0,0 +1,44 @@
using AquaMai.Config.Interfaces;
using Tomlet.Models;
namespace AquaMai.Config.Migration;
public class ConfigMigration_V2_0_V2_1 : IConfigMigration
{
public string FromVersion => "2.0";
public string ToVersion => "2.1";
public IConfigView Migrate(IConfigView src)
{
var dst = src.Clone();
dst.SetValue("Version", ToVersion);
if (IsSectionEnabled(src, "Tweaks.ResetTouchAfterTrack"))
{
dst.Remove("Tweaks.ResetTouchAfterTrack");
dst.SetValue("Tweaks.ResetTouch.AfterTrack", true);
}
return dst;
}
public bool IsSectionEnabled(IConfigView src, string path)
{
if (src.TryGetValue(path, out object section))
{
if (section is bool enabled)
{
return enabled;
}
else if (section is TomlTable table)
{
if (Utility.TomlTryGetValueCaseInsensitive(table, "Disabled", out var disabled))
{
return !Utility.IsTrutyOrDefault(disabled);
}
return true;
}
}
return false;
}
}

View File

@ -21,6 +21,16 @@ public static class Utility
}; };
} }
public static bool IsTrutyOrDefault(TomlValue value, bool defaultValue = false)
{
return value switch
{
TomlBoolean boolean => boolean.Value,
TomlLong @long => @long.Value != 0,
_ => defaultValue
};
}
public static bool IsIntegerType(Type type) public static bool IsIntegerType(Type type)
{ {
return type == typeof(sbyte) || type == typeof(short) || type == typeof(int) || type == typeof(long) return type == typeof(sbyte) || type == typeof(short) || type == typeof(int) || type == typeof(long)

View File

@ -340,6 +340,15 @@ namespace AquaMai.Core.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Touch panel reset.
/// </summary>
public static string TouchPanelReset {
get {
return ResourceManager.GetString("TouchPanelReset", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to UserAll Upsert Error. /// Looks up a localized string similar to UserAll Upsert Error.
/// </summary> /// </summary>

View File

@ -116,4 +116,7 @@
<data name="PlaylogSaveError" xml:space="preserve"> <data name="PlaylogSaveError" xml:space="preserve">
<value>Playlog save error</value> <value>Playlog save error</value>
</data> </data>
<data name="TouchPanelReset" xml:space="preserve">
<value>Touch panel reset</value>
</data>
</root> </root>

View File

@ -109,4 +109,7 @@
<data name="PlaylogSaveError" xml:space="preserve"> <data name="PlaylogSaveError" xml:space="preserve">
<value>保存 Playlog 失败</value> <value>保存 Playlog 失败</value>
</data> </data>
<data name="TouchPanelReset" xml:space="preserve">
<value>触摸面板已重置</value>
</data>
</root> </root>

View File

@ -5,6 +5,7 @@ using AquaMai.Config.Types;
using AquaMai.Core; using AquaMai.Core;
using AquaMai.Core.Attributes; using AquaMai.Core.Attributes;
using AquaMai.Core.Helpers; using AquaMai.Core.Helpers;
using AquaMai.Mods.Tweaks;
using AquaMai.Mods.UX; using AquaMai.Mods.UX;
using AquaMai.Mods.UX.PracticeMode; using AquaMai.Mods.UX.PracticeMode;
using HarmonyLib; using HarmonyLib;
@ -35,6 +36,7 @@ public class TestProof
(typeof(OneKeyRetrySkip), OneKeyRetrySkip.skipKey), (typeof(OneKeyRetrySkip), OneKeyRetrySkip.skipKey),
(typeof(HideSelfMadeCharts), HideSelfMadeCharts.key), (typeof(HideSelfMadeCharts), HideSelfMadeCharts.key),
(typeof(PracticeMode), PracticeMode.key), (typeof(PracticeMode), PracticeMode.key),
(typeof(ResetTouch), ResetTouch.key),
]; ];
var keyMapEnabled = ConfigLoader.Config.GetSectionState(typeof(KeyMap)).Enabled; var keyMapEnabled = ConfigLoader.Config.GetSectionState(typeof(KeyMap)).Enabled;
return featureKeys.Any(it => return featureKeys.Any(it =>

View File

@ -0,0 +1,43 @@
using AquaMai.Config.Attributes;
using AquaMai.Config.Types;
using AquaMai.Core.Helpers;
using AquaMai.Core.Resources;
using HarmonyLib;
using MAI2.Util;
using Main;
using Manager;
using Process;
namespace AquaMai.Mods.Tweaks;
[ConfigSection(
en: "Reset touch panel manually or after playing track.",
zh: "重置触摸面板")]
public class ResetTouch
{
[ConfigEntry(en: "Reset touch panel after playing track.", zh: "玩完一首歌自动重置")]
private static bool afterTrack = false;
[ConfigEntry(en: "Reset manually.", zh: "按键重置")]
public static readonly KeyCodeOrName key = KeyCodeOrName.None;
[ConfigEntry] private static readonly bool longPress = false;
[HarmonyPostfix]
[HarmonyPatch(typeof(ResultProcess), "OnStart")]
public static void ResultProcessOnStart()
{
if (!afterTrack) return;
SingletonStateMachine<AmManager, AmManager.EState>.Instance.StartTouchPanel();
MelonLoader.MelonLogger.Msg("[TouchResetAfterTrack] Touch panel reset");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameMainObject), "Update")]
public static void OnGameMainObjectUpdate()
{
if (!KeyListener.GetKeyDownOrLongPress(key, longPress)) return;
SingletonStateMachine<AmManager, AmManager.EState>.Instance.StartTouchPanel();
MessageHelper.ShowMessage(Locale.TouchPanelReset);
}
}

View File

@ -1,21 +0,0 @@
using AquaMai.Config.Attributes;
using HarmonyLib;
using MAI2.Util;
using Manager;
using Process;
namespace AquaMai.Mods.Tweaks;
[ConfigSection(
en: "Reset touch panel after playing track.",
zh: "在游玩一首曲目后重置触摸面板")]
public class ResetTouchAfterTrack
{
[HarmonyPostfix]
[HarmonyPatch(typeof(ResultProcess), "OnStart")]
public static void ResultProcessOnStart()
{
SingletonStateMachine<AmManager, AmManager.EState>.Instance.StartTouchPanel();
MelonLoader.MelonLogger.Msg("[TouchResetAfterTrack] Touch panel reset");
}
}