forked from akanyan/mu3-mods
feat: implement TestMenuConfig
This commit is contained in:
247
Extras/TestMenuConfig/MU3.Mod/TestModePageModConfig.cs
Normal file
247
Extras/TestMenuConfig/MU3.Mod/TestModePageModConfig.cs
Normal file
@ -0,0 +1,247 @@
|
||||
using MU3.TestMode;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MU3.Mod;
|
||||
|
||||
class TestModePageModConfig: TestModePage {
|
||||
class Option {
|
||||
public int selection;
|
||||
public string sectionName;
|
||||
public string fieldName;
|
||||
public ItemDefine itemDefine;
|
||||
public List<KeyValuePair<string, string>> values;
|
||||
|
||||
public Option(string label, string fieldName, Dictionary<string, string> values, int indexDefault, bool selectable, string sectionName = "Extra") {
|
||||
this.values = values.ToList();
|
||||
this.fieldName = fieldName;
|
||||
this.sectionName = sectionName;
|
||||
|
||||
itemDefine = new ItemDefine {
|
||||
lineNumber = 0,
|
||||
label = label,
|
||||
isSelectable = selectable,
|
||||
hasValueField = true,
|
||||
numValueField = 1,
|
||||
nextPagePrefab = null,
|
||||
isFinishOnSelect = false,
|
||||
isDefaultSelection = false,
|
||||
};
|
||||
|
||||
using IniFile iniFile = new("mu3.ini");
|
||||
var previous = iniFile.getValue(sectionName, fieldName, values.ElementAt(indexDefault).Value);
|
||||
var found = this.values.FindIndex(i => i.Value == previous);
|
||||
if(found == -1) {
|
||||
itemDefine.isSelectable = false;
|
||||
} else {
|
||||
selection = found == -1 ? indexDefault : found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Option> _options;
|
||||
private Dictionary<string, string> _onOff;
|
||||
private bool _isDisableGPActive;
|
||||
private MethodInfo _writeToFile;
|
||||
|
||||
protected new void Awake() {
|
||||
_titles = [
|
||||
"MODS"
|
||||
];
|
||||
_itemNum = 1;
|
||||
_bottomMargin = 0.3f;
|
||||
_leftMargin = 0.12f;
|
||||
_rightMargin = 0f;
|
||||
|
||||
_options = [];
|
||||
_onOff = new Dictionary<string, string>() {
|
||||
{ "OFF", "0" },
|
||||
{ "ON", "1" }
|
||||
};
|
||||
_isDisableGPActive = typeof(UICredit).GetMethod("orig_initialize") != null;
|
||||
_writeToFile = typeof(IniFile).GetMethod("writeToFile", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
writeOtherOptions();
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void createItems() {
|
||||
FieldInfo itemsFi = typeof(TestModePage).GetField("_itemDefines", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
FieldInfo opFi = typeof(TestModePage).GetField("_opType", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
_options.Add(new Option(
|
||||
"BGM",
|
||||
"BGM",
|
||||
new Dictionary<string, string> {
|
||||
{ "ORIGINAL", "1" },
|
||||
{ "SUMMER", "2" },
|
||||
{ "R.E.D.", "3" },
|
||||
{ "bright", "4" },
|
||||
{ "END CHAPTER", "5" },
|
||||
{ "bright MEMORY Act.3", "6" },
|
||||
{ "RANDOM", "0" }
|
||||
},
|
||||
5,
|
||||
typeof(Game.GameBGM).GetMethod("orig_playBGM") != null
|
||||
));
|
||||
|
||||
_options.Add(new Option(
|
||||
"HIDE CREDITS",
|
||||
"HideCredits",
|
||||
_onOff,
|
||||
1,
|
||||
_isDisableGPActive
|
||||
));
|
||||
|
||||
_options.Add(new Option(
|
||||
"HIDE GP",
|
||||
"HideGP",
|
||||
_onOff,
|
||||
1,
|
||||
_isDisableGPActive
|
||||
));
|
||||
|
||||
_options.Add(new Option(
|
||||
"HIDE VERSION",
|
||||
"HideVersion",
|
||||
_onOff,
|
||||
0,
|
||||
_isDisableGPActive
|
||||
));
|
||||
|
||||
_options.Add(new Option(
|
||||
"SKIP WEBCAM INITIALIZATION",
|
||||
"SkipCamera",
|
||||
_onOff,
|
||||
1,
|
||||
typeof(Data.DataStudioManager).GetMethod("orig_IsLoaded") != null,
|
||||
"Sequence"
|
||||
));
|
||||
|
||||
_options.Add(new Option(
|
||||
"SKIP BATTLE INTRO",
|
||||
"QuickStart",
|
||||
_onOff,
|
||||
0,
|
||||
typeof(Sequence.PlayMusic).GetMethod("orig_updateState") != null,
|
||||
"Sequence"
|
||||
));
|
||||
|
||||
_options.Add(new Option(
|
||||
"FRAMERATE",
|
||||
"Framerate",
|
||||
new Dictionary<string, string> {
|
||||
{ "60", "60" },
|
||||
{ "120", "120" },
|
||||
{ "144", "144" },
|
||||
{ "165", "165" },
|
||||
{ "240", "240" },
|
||||
{ "UNLOCKED", "0" },
|
||||
{ "VSYNC", "V" }
|
||||
},
|
||||
0,
|
||||
typeof(Notes.NotesManager).GetMethod("orig_initialize") != null,
|
||||
"Video"
|
||||
));
|
||||
|
||||
var itemDefs = _options.Select((x, idx) => {
|
||||
x.itemDefine.lineNumber = idx;
|
||||
return x.itemDefine;
|
||||
}).ToList();
|
||||
|
||||
itemDefs.Add(new() {
|
||||
lineNumber = 8,
|
||||
label = "終了",
|
||||
isSelectable = true,
|
||||
isFinishOnSelect = true,
|
||||
isDefaultSelection = true
|
||||
});
|
||||
|
||||
itemsFi.SetValue(this, itemDefs.ToArray());
|
||||
opFi.SetValue(this, OpType.Select);
|
||||
|
||||
base.createItems();
|
||||
}
|
||||
|
||||
protected override void onPostCreate(GameObject prefab, object arg) {
|
||||
gameObject.SetActive(true);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
protected override void onInitializeItem(Item item, int index) {
|
||||
if(!item.define.hasValueField) {
|
||||
return;
|
||||
}
|
||||
var op = _options[index];
|
||||
|
||||
if(op.fieldName == "Framerate") {
|
||||
using IniFile iniFile = new("mu3.ini");
|
||||
if(iniFile.getValue(op.sectionName, "VSync", false)) {
|
||||
op.selection = op.values.FindIndex(i => i.Value == "V");
|
||||
} else if(!op.itemDefine.isSelectable) {
|
||||
item.setValueString(iniFile.getValue(op.sectionName, op.fieldName, "???"));
|
||||
}
|
||||
}
|
||||
|
||||
item.setValueString(op.values[op.selection].Key);
|
||||
item.setState(op.itemDefine.isSelectable ? Item.State.Selectable : Item.State.UnselectableTemp);
|
||||
}
|
||||
|
||||
protected override void onSelectItem(Item item, int index) {
|
||||
if(!item.define.hasValueField || !item.define.isSelectable) {
|
||||
return;
|
||||
}
|
||||
var op = _options[index];
|
||||
|
||||
op.selection += 1;
|
||||
op.selection %= op.values.Count();
|
||||
|
||||
item.setValueString(op.values[op.selection].Key);
|
||||
|
||||
using IniFile iniFile = new("mu3.ini");
|
||||
using StreamWriter sw = new("mu3.ini");
|
||||
|
||||
var value = op.values[op.selection].Value;
|
||||
if(op.fieldName == "Framerate") {
|
||||
if(value == "V") {
|
||||
iniFile.setValue(op.sectionName, op.fieldName, 0);
|
||||
iniFile.setValue(op.sectionName, "VSync", 1);
|
||||
} else {
|
||||
iniFile.setValue(op.sectionName, op.fieldName, value);
|
||||
iniFile.setValue(op.sectionName, "VSync", 0);
|
||||
}
|
||||
} else {
|
||||
iniFile.setValue(op.sectionName, op.fieldName, value);
|
||||
}
|
||||
|
||||
_writeToFile.Invoke(iniFile, [sw]);
|
||||
}
|
||||
private void rewriteOption(IniFile ini, string sectionName, string fieldName, string defaultValue) {
|
||||
;
|
||||
ini.setValue(sectionName, fieldName, ini.getValue(sectionName, fieldName, defaultValue));
|
||||
}
|
||||
|
||||
private void writeOtherOptions() {
|
||||
using IniFile iniFile = new("mu3.ini");
|
||||
using StreamWriter sw = new("mu3.ini");
|
||||
|
||||
rewriteOption(iniFile, "Sound", "WasapiExclusive", "0");
|
||||
rewriteOption(iniFile, "AM", "IgnoreError", "1");
|
||||
rewriteOption(iniFile, "Device", "CameraType", "1");
|
||||
|
||||
rewriteOption(iniFile, "Extra", "CacheDir", ".");
|
||||
if(_isDisableGPActive) {
|
||||
rewriteOption(iniFile, "Extra", "GP", "999");
|
||||
}
|
||||
if(typeof(User.UserManager).GetMethod("orig_getUserFumen") != null) {
|
||||
rewriteOption(iniFile, "Extra", "BlacklistMin", "10000");
|
||||
rewriteOption(iniFile, "Extra", "BlacklistMin", "19999");
|
||||
}
|
||||
|
||||
_writeToFile.Invoke(iniFile, [sw]);
|
||||
}
|
||||
}
|
40
Extras/TestMenuConfig/MU3.TestMode/patch_TestModePageTop.cs
Normal file
40
Extras/TestMenuConfig/MU3.TestMode/patch_TestModePageTop.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MU3.TestMode;
|
||||
|
||||
internal class patch_TestModePageTop: TestModePageTop {
|
||||
GameObject _testModePageModConfig;
|
||||
|
||||
protected override void createItems() {
|
||||
_bottomMargin = 0.22f;
|
||||
|
||||
_testModePageModConfig = new("TestModePageModConfig");
|
||||
_testModePageModConfig.SetActive(false);
|
||||
_testModePageModConfig.transform.SetParent(transform.parent);
|
||||
_testModePageModConfig.AddComponent<Mod.TestModePageModConfig>();
|
||||
|
||||
FieldInfo fi = typeof(TestModePage).GetField("_itemDefines", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
var defines = ((ItemDefine[])fi.GetValue(this)).ToList();
|
||||
|
||||
var n = defines.Count;
|
||||
defines.Insert(n - 1, new() {
|
||||
lineNumber = n - 1,
|
||||
label = "MODS",
|
||||
isSelectable = true,
|
||||
hasValueField = false,
|
||||
numValueField = 0,
|
||||
nextPagePrefab = _testModePageModConfig,
|
||||
isFinishOnSelect = false,
|
||||
isDefaultSelection = false,
|
||||
});
|
||||
|
||||
// The exit button
|
||||
defines.Last().lineNumber += 1;
|
||||
|
||||
fi.SetValue(this, defines.ToArray());
|
||||
|
||||
base.createItems();
|
||||
}
|
||||
}
|
8
Extras/TestMenuConfig/TestMenuConfig.csproj
Normal file
8
Extras/TestMenuConfig/TestMenuConfig.csproj
Normal file
@ -0,0 +1,8 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Assembly-CSharp.TestMenuConfig.mm</AssemblyName>
|
||||
<Description>Test menu config</Description>
|
||||
<OutCategory>extras</OutCategory>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\Mu3Mods.csproj" />
|
||||
</Project>
|
Reference in New Issue
Block a user