1
0
forked from akanyan/mu3-mods

feat: implement TestMenuConfig

This commit is contained in:
2025-01-04 02:35:28 +00:00
parent 15f2fe6f57
commit 1f01b460ba
6 changed files with 314 additions and 5 deletions

View 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]);
}
}