Compare commits
3 Commits
1.0.0-pre.
...
main
Author | SHA1 | Date | |
---|---|---|---|
afe095286b | |||
e7c0dad0d7 | |||
9c180657b4 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
*.dll
|
*.dll
|
||||||
*.csproj
|
*.csproj
|
||||||
bin/
|
bin/
|
||||||
obj/
|
obj/
|
||||||
|
dist/
|
47
Inohara.DT/BatchManual.cs
Normal file
47
Inohara.DT/BatchManual.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Inohara.DT;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManual {
|
||||||
|
public BatchManualMeta meta;
|
||||||
|
public BatchManualScore[] scores;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualMeta {
|
||||||
|
public string game;
|
||||||
|
public string playtype;
|
||||||
|
public string service;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualScore {
|
||||||
|
public int score;
|
||||||
|
public string difficulty;
|
||||||
|
public UInt64 timeAchieved;
|
||||||
|
public string noteLamp;
|
||||||
|
public string bellLamp;
|
||||||
|
public string matchType;
|
||||||
|
public string identifier;
|
||||||
|
public BatchManualJudgements judgements;
|
||||||
|
public BatchManualOptional optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualJudgements {
|
||||||
|
public int cbreak;
|
||||||
|
public int breakMyBonesIWill;
|
||||||
|
public int hit;
|
||||||
|
public int miss;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualOptional {
|
||||||
|
public int fast;
|
||||||
|
public int slow;
|
||||||
|
public int bellCount;
|
||||||
|
public int totalBellCount;
|
||||||
|
public int damage;
|
||||||
|
public int platScore;
|
||||||
|
}
|
34
Inohara.DT/BatchManualPB.cs
Normal file
34
Inohara.DT/BatchManualPB.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Inohara.DT;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualPB {
|
||||||
|
public BatchManualPBMeta meta;
|
||||||
|
public BatchManualPBScore[] scores;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualPBMeta {
|
||||||
|
public string game;
|
||||||
|
public string playtype;
|
||||||
|
public string service;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualPBScore {
|
||||||
|
public int score;
|
||||||
|
public string difficulty;
|
||||||
|
public string noteLamp;
|
||||||
|
public string bellLamp;
|
||||||
|
public string matchType;
|
||||||
|
public string identifier;
|
||||||
|
public BatchManualPBJudgements judgements;
|
||||||
|
public BatchManualPBOptional optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualPBJudgements {}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchManualPBOptional {}
|
19
Inohara.DT/BatchResponse.cs
Normal file
19
Inohara.DT/BatchResponse.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Inohara.DT;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchResponse {
|
||||||
|
public bool success;
|
||||||
|
public BatchResponseBody body;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchResponseBody {
|
||||||
|
public string url;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct BatchResponse2 {
|
||||||
|
public bool success;
|
||||||
|
}
|
16
Inohara.DT/StatusResponse.cs
Normal file
16
Inohara.DT/StatusResponse.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Inohara.DT;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct StatusResponse {
|
||||||
|
public bool success;
|
||||||
|
public StatusBody body;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct StatusBody {
|
||||||
|
public string version;
|
||||||
|
public string whoami;
|
||||||
|
public string[] permissions;
|
||||||
|
}
|
@ -16,4 +16,10 @@
|
|||||||
<Reference Include="UnityEngine.UI"><HintPath></HintPath></Reference>
|
<Reference Include="UnityEngine.UI"><HintPath></HintPath></Reference>
|
||||||
<Reference Include="Mu3Assembly"><HintPath></HintPath></Reference>
|
<Reference Include="Mu3Assembly"><HintPath></HintPath></Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="Dist" AfterTargets="Build">
|
||||||
|
<Copy SourceFiles="$(TargetDir)$(AssemblyName).dll" DestinationFolder="dist" />
|
||||||
|
<Copy SourceFiles="$(TargetDir)$(AssemblyName).dll" DestinationFolder="dist/BepInEx/monomod" />
|
||||||
|
<ZipDirectory SourceDirectory="dist/BepInEx" DestinationFile="dist/inohara.zip" Overwrite="true" />
|
||||||
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Inohara;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Batch manual
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchManual {
|
|
||||||
public BatchMeta meta;
|
|
||||||
public BatchScore[] scores;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchMeta {
|
|
||||||
public string game;
|
|
||||||
public string playtype;
|
|
||||||
public string service;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchScore {
|
|
||||||
public int score;
|
|
||||||
public string difficulty;
|
|
||||||
public UInt64 timeAchieved;
|
|
||||||
public string noteLamp;
|
|
||||||
public string bellLamp;
|
|
||||||
public string matchType;
|
|
||||||
public string identifier;
|
|
||||||
public BatchJudgements judgements;
|
|
||||||
public BatchOptional optional;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchJudgements {
|
|
||||||
public int cbreak;
|
|
||||||
public int breakMyBonesIWill;
|
|
||||||
public int hit;
|
|
||||||
public int miss;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchOptional {
|
|
||||||
public int fast;
|
|
||||||
public int slow;
|
|
||||||
public int bellCount;
|
|
||||||
public int totalBellCount;
|
|
||||||
public int damage;
|
|
||||||
public int platScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BM response 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchResponse {
|
|
||||||
public bool success;
|
|
||||||
public BatchResponseBody body;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchResponseBody {
|
|
||||||
public string url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BM response 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct BatchResponse2 {
|
|
||||||
public bool success;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API status response
|
|
||||||
*/
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct StatusResponse {
|
|
||||||
public bool success;
|
|
||||||
public StatusBody body;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct StatusBody {
|
|
||||||
public string version;
|
|
||||||
public string whoami;
|
|
||||||
public string[] permissions;
|
|
||||||
}
|
|
@ -11,6 +11,7 @@ using MU3.Util;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
using UnityEngine.Networking;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
using Inohara.DT;
|
||||||
|
|
||||||
namespace Inohara;
|
namespace Inohara;
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ public class Exporter: SingletonMonoBehaviour<Exporter> {
|
|||||||
public string StatusPoint;
|
public string StatusPoint;
|
||||||
public string ImportPoint;
|
public string ImportPoint;
|
||||||
public bool EnableText;
|
public bool EnableText;
|
||||||
|
public bool ExportPBs;
|
||||||
}
|
}
|
||||||
static readonly float REQ2_DELAY = 4f;
|
static readonly float REQ2_DELAY = 4f;
|
||||||
static readonly float DRAW_DURATION = 4f;
|
static readonly float DRAW_DURATION = 4f;
|
||||||
@ -30,11 +32,11 @@ public class Exporter: SingletonMonoBehaviour<Exporter> {
|
|||||||
private readonly Dictionary<string, string> _tokens = new();
|
private readonly Dictionary<string, string> _tokens = new();
|
||||||
private string _currToken = "";
|
private string _currToken = "";
|
||||||
private readonly Font _arial = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
private readonly Font _arial = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||||
private List<BatchScore> _scores = new();
|
private List<BatchManualScore> _scores = new();
|
||||||
|
|
||||||
private void Log(object o, bool text) {
|
private void Log(object o, bool drawText) {
|
||||||
Debug.Log("[Inohara] " + o.ToString());
|
Debug.Log("[Inohara] " + o.ToString());
|
||||||
if(_cfg.EnableText && text) {
|
if(_cfg.EnableText && drawText) {
|
||||||
StartCoroutine(DrawMessage(o.ToString(), new Color(1f, 1f, 1f, 1.0f)));
|
StartCoroutine(DrawMessage(o.ToString(), new Color(1f, 1f, 1f, 1.0f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,6 +56,7 @@ public class Exporter: SingletonMonoBehaviour<Exporter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void LoadCfg() {
|
public void LoadCfg() {
|
||||||
|
_cfg.Enable = false;
|
||||||
try {
|
try {
|
||||||
using StreamReader reader = new(Path.Combine(Application.dataPath, "../inohara.cfg"));
|
using StreamReader reader = new(Path.Combine(Application.dataPath, "../inohara.cfg"));
|
||||||
Dictionary<string, string> options = new();
|
Dictionary<string, string> options = new();
|
||||||
@ -81,6 +84,9 @@ public class Exporter: SingletonMonoBehaviour<Exporter> {
|
|||||||
if(!options.ContainsKey("enableosd") || !bool.TryParse(options["enableosd"], out _cfg.EnableText)) {
|
if(!options.ContainsKey("enableosd") || !bool.TryParse(options["enableosd"], out _cfg.EnableText)) {
|
||||||
_cfg.EnableText = false;
|
_cfg.EnableText = false;
|
||||||
}
|
}
|
||||||
|
if(!options.ContainsKey("exportpbs") || !bool.TryParse(options["exportpbs"], out _cfg.ExportPBs)) {
|
||||||
|
_cfg.ExportPBs = false;
|
||||||
|
}
|
||||||
if(!options.ContainsKey("timeout") || !int.TryParse(options["timeout"], out _cfg.Timeout)) {
|
if(!options.ContainsKey("timeout") || !int.TryParse(options["timeout"], out _cfg.Timeout)) {
|
||||||
_cfg.Timeout = 3;
|
_cfg.Timeout = 3;
|
||||||
}
|
}
|
||||||
@ -136,6 +142,7 @@ public class Exporter: SingletonMonoBehaviour<Exporter> {
|
|||||||
using var req = new UnityWebRequest(_cfg.BaseUrl + _cfg.StatusPoint, "GET");
|
using var req = new UnityWebRequest(_cfg.BaseUrl + _cfg.StatusPoint, "GET");
|
||||||
req.SetRequestHeader("Authorization", "Bearer " + tmpBearer);
|
req.SetRequestHeader("Authorization", "Bearer " + tmpBearer);
|
||||||
req.downloadHandler = new DownloadHandlerBuffer();
|
req.downloadHandler = new DownloadHandlerBuffer();
|
||||||
|
req.timeout = _cfg.Timeout;
|
||||||
|
|
||||||
yield return req.Send();
|
yield return req.Send();
|
||||||
|
|
||||||
@ -221,6 +228,27 @@ public class Exporter: SingletonMonoBehaviour<Exporter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ExportPBs() {
|
||||||
|
if(!_cfg.ExportPBs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var userMusic = Singleton<UserManager>.instance.userMusic;
|
||||||
|
var scores = new List<BatchManualPBScore>();
|
||||||
|
foreach(var x in userMusic.Values) {
|
||||||
|
foreach(var y in x.UserFumen) {
|
||||||
|
if(y != null) {
|
||||||
|
scores.Add(Util.CreatePB(y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var batch = Util.CreatePBBatch(scores);
|
||||||
|
using StreamWriter writer = new(Path.Combine(Application.dataPath, "../batch-manual.json"));
|
||||||
|
writer.Write(batch);
|
||||||
|
|
||||||
|
Log("Exported PBs to batch-manual.json", false);
|
||||||
|
}
|
||||||
|
|
||||||
// This is just for fun
|
// This is just for fun
|
||||||
private IEnumerator DrawMessage(string message, Color color) {
|
private IEnumerator DrawMessage(string message, Color color) {
|
||||||
GameObject canvasGO = new() {
|
GameObject canvasGO = new() {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Inohara.DT;
|
||||||
using MU3.Battle;
|
using MU3.Battle;
|
||||||
using MU3.DataStudio;
|
using MU3.DataStudio;
|
||||||
using MU3.Game;
|
using MU3.Game;
|
||||||
|
using MU3.User;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Inohara;
|
namespace Inohara;
|
||||||
@ -35,9 +37,9 @@ class Util {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BatchScore CreateScore(BattleResult result, SessionInfo info) {
|
public static BatchManualScore CreateScore(BattleResult result, SessionInfo info) {
|
||||||
var timestampSec = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
var timestampSec = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
|
||||||
return new BatchScore {
|
return new BatchManualScore {
|
||||||
score = result.technicalScore,
|
score = result.technicalScore,
|
||||||
difficulty = GetStringDiff(info.musicLevel),
|
difficulty = GetStringDiff(info.musicLevel),
|
||||||
timeAchieved = (ulong)timestampSec * 1000,
|
timeAchieved = (ulong)timestampSec * 1000,
|
||||||
@ -45,7 +47,7 @@ class Util {
|
|||||||
identifier = info.musicData.id.ToString(),
|
identifier = info.musicData.id.ToString(),
|
||||||
bellLamp = result.bellComboResult == BellComboResult.None ? "NONE" : "FULL BELL",
|
bellLamp = result.bellComboResult == BellComboResult.None ? "NONE" : "FULL BELL",
|
||||||
noteLamp = GetLamp(result),
|
noteLamp = GetLamp(result),
|
||||||
optional = new BatchOptional() {
|
optional = new BatchManualOptional() {
|
||||||
fast = result.numNotesFast,
|
fast = result.numNotesFast,
|
||||||
slow = result.numNotesLate,
|
slow = result.numNotesLate,
|
||||||
bellCount = result.numBellCatch,
|
bellCount = result.numBellCatch,
|
||||||
@ -53,7 +55,7 @@ class Util {
|
|||||||
damage = result.countDamage,
|
damage = result.countDamage,
|
||||||
platScore = result.platinumScore
|
platScore = result.platinumScore
|
||||||
},
|
},
|
||||||
judgements = new BatchJudgements() {
|
judgements = new BatchManualJudgements() {
|
||||||
cbreak = result.numNotesCBreak,
|
cbreak = result.numNotesCBreak,
|
||||||
breakMyBonesIWill = result.numNotesBreak,
|
breakMyBonesIWill = result.numNotesBreak,
|
||||||
hit = result.numNotesHit,
|
hit = result.numNotesHit,
|
||||||
@ -62,9 +64,28 @@ class Util {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string CreateBatch(List<BatchScore> scores) {
|
public static BatchManualPBScore CreatePB(UserFumen fumen) {
|
||||||
|
return new BatchManualPBScore {
|
||||||
|
score = fumen.TechScoreMax,
|
||||||
|
difficulty = GetStringDiff(fumen.Level),
|
||||||
|
matchType = "inGameID",
|
||||||
|
identifier = fumen.MusicId.ToString(),
|
||||||
|
bellLamp = fumen.IsFullBell ? "FULL BELL" : "NONE",
|
||||||
|
noteLamp =
|
||||||
|
fumen.IsAllBreak ? "ALL BREAK" :
|
||||||
|
fumen.IsFullCombo ? "FULL COMBO" :
|
||||||
|
// fumen.isClear is a bool that seems to flag battle victory. Useless
|
||||||
|
// basing this on score is ass but for the most part it will be accurate.
|
||||||
|
fumen.TechScoreMax >= 940000 ? "CLEAR" :
|
||||||
|
"LOSS",
|
||||||
|
optional = new BatchManualPBOptional() {},
|
||||||
|
judgements = new BatchManualPBJudgements() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CreateBatch(List<BatchManualScore> scores) {
|
||||||
var bm = new BatchManual {
|
var bm = new BatchManual {
|
||||||
meta = new BatchMeta {
|
meta = new BatchManualMeta {
|
||||||
game = "ongeki",
|
game = "ongeki",
|
||||||
playtype = "Single",
|
playtype = "Single",
|
||||||
service = "inohara"
|
service = "inohara"
|
||||||
@ -74,4 +95,17 @@ class Util {
|
|||||||
|
|
||||||
return JsonUtility.ToJson(bm).Replace("breakMyBonesIWill", "break");
|
return JsonUtility.ToJson(bm).Replace("breakMyBonesIWill", "break");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string CreatePBBatch(List<BatchManualPBScore> scores) {
|
||||||
|
var bm = new BatchManualPB {
|
||||||
|
meta = new BatchManualPBMeta {
|
||||||
|
game = "ongeki",
|
||||||
|
playtype = "Single",
|
||||||
|
service = "inohara-pb"
|
||||||
|
},
|
||||||
|
scores = scores.ToArray()
|
||||||
|
};
|
||||||
|
|
||||||
|
return JsonUtility.ToJson(bm);
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,16 +9,16 @@ using MU3.Util;
|
|||||||
namespace MU3.App;
|
namespace MU3.App;
|
||||||
|
|
||||||
public class patch_ApplicationMU3 : ApplicationMU3 {
|
public class patch_ApplicationMU3 : ApplicationMU3 {
|
||||||
private extern void orig_Execute_WaitAMDaemonReady();
|
private extern void orig_initializeAfterAMDaemonReady();
|
||||||
|
|
||||||
private void Execute_WaitAMDaemonReady() {
|
private void initializeAfterAMDaemonReady() {
|
||||||
GameObject go = new() {
|
GameObject go = new() {
|
||||||
name = "Inohara"
|
name = "Inohara"
|
||||||
};
|
};
|
||||||
go.AddComponent<Inohara.Exporter>();
|
go.AddComponent<Inohara.Exporter>();
|
||||||
|
|
||||||
DontDestroyOnLoad(go);
|
DontDestroyOnLoad(go);
|
||||||
orig_Execute_WaitAMDaemonReady();
|
orig_initializeAfterAMDaemonReady();
|
||||||
SingletonMonoBehaviour<Inohara.Exporter>.instance.LoadCfg();
|
SingletonMonoBehaviour<Inohara.Exporter>.instance.LoadCfg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,15 @@ namespace MU3;
|
|||||||
public class patch_Scene_25_Login : Scene_25_Login {
|
public class patch_Scene_25_Login : Scene_25_Login {
|
||||||
|
|
||||||
private extern void orig_finishAime();
|
private extern void orig_finishAime();
|
||||||
|
private extern void orig_GetUserRival_Init();
|
||||||
|
|
||||||
private void finishAime() {
|
private void finishAime() {
|
||||||
orig_finishAime();
|
orig_finishAime();
|
||||||
SingletonMonoBehaviour<Inohara.Exporter>.instance.Authorize();
|
SingletonMonoBehaviour<Inohara.Exporter>.instance.Authorize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GetUserRival_Init() {
|
||||||
|
orig_GetUserRival_Init();
|
||||||
|
SingletonMonoBehaviour<Inohara.Exporter>.instance.ExportPBs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
52
README.md
52
README.md
@ -8,31 +8,55 @@ A µ3 score exporter for [Tachi](https://github.com/zkldi/Tachi).
|
|||||||
- 1.45
|
- 1.45
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
Get the config file [here](https://kamai.tachi.ac/client-file-flow/CIa914320cd344a8db712cf0c99254c205ca940463), download the DLL [here](https://gitea.tendokyu.moe/akanyan/inohara/releases) and follow one of the methods below.
|
First, get the config file [here](https://kamai.tachi.ac/client-file-flow/CIa914320cd344a8db712cf0c99254c205ca940463) and put it in the base game directory (next to `mu3.exe`), then follow one of the methods below.
|
||||||
|
|
||||||
#### The BepInEx method (recommended)
|
#### The simple method
|
||||||
- Download [BepInEx](https://github.com/BepInEx/BepInEx/releases/)
|
- Update [segatools](https://gitea.tendokyu.moe/Dniel97/segatools).
|
||||||
- Copy the `BepInEx` directory into the base game directory (where `mu3.exe` is); omit `winhttp.dll`
|
- Download `inohara.zip` from [releases](https://gitea.tendokyu.moe/akanyan/inohara/releases) and extract it into the base game directory.
|
||||||
- Modify this entry in `segatools.ini`:
|
- Modify this entry in `segatools.ini`:
|
||||||
```ini
|
```ini
|
||||||
[unity]
|
[unity]
|
||||||
targetAssembly=BepInEx\core\BepInEx.Preloader.dll
|
targetAssembly=BepInEx\core\BepInEx.Preloader.dll
|
||||||
```
|
```
|
||||||
|
- The game directory should look like this (abridged):
|
||||||
|
```
|
||||||
|
├── BepInEx
|
||||||
|
├── mu3_Data
|
||||||
|
├── inohara.cfg
|
||||||
|
├── mu3.exe
|
||||||
|
└── segatools.ini
|
||||||
|
```
|
||||||
|
|
||||||
|
#### The manual BepInEx method
|
||||||
|
- Download [BepInEx 5](https://github.com/BepInEx/BepInEx/releases/) and [BepInEx.MonoMod.Loader](https://github.com/BepInEx/BepInEx.MonoMod.Loader).
|
||||||
|
- Copy both `BepInEx` directories into the base game directory; omit `winhttp.dll`.
|
||||||
|
- Modify this entry in `segatools.ini`:
|
||||||
|
```ini
|
||||||
|
[unity]
|
||||||
|
targetAssembly=BepInEx\core\BepInEx.Preloader.dll
|
||||||
|
```
|
||||||
- If you don't have this entry, update segatools.
|
- If you don't have this entry, update segatools.
|
||||||
- If you insist on not updating segatools, instead copy `winhttp.dll` and rename it to `version.dll`.
|
- If you insist on not updating segatools, instead copy `winhttp.dll` and rename it to `version.dll`.
|
||||||
- Move `Assembly-CSharp.Inohara.mm.dll` to `BepInEx\monomod`
|
- Download `Assembly-CSharp.Inohara.mm.dll` from [releases](https://gitea.tendokyu.moe/akanyan/inohara/releases) and put it in `BepInEx\monomod`.
|
||||||
- Put `inohara.cfg` in the base game directory (next to `mu3.exe`)
|
|
||||||
|
|
||||||
#### The MonoMod method
|
|
||||||
- Download [MonoMod](https://github.com/MonoMod/MonoMod/releases)
|
#### The hardpatch method
|
||||||
- Copy `Assembly-CSharp.Inohara.mm.dll` into `mu3_Data\Managed`
|
- Download [MonoMod](https://github.com/MonoMod/MonoMod/releases).
|
||||||
- Run `MonoMod.exe mu3_Data\Managed\Assembly-CSharp.dll`
|
- Download `Assembly-CSharp.Inohara.mm.dll` from [releases](https://gitea.tendokyu.moe/akanyan/inohara/releases) and put it in `mu3_Data\Managed`.
|
||||||
- Backup `Assembly-CSharp.dll`
|
- Run:
|
||||||
- Rename `MONOMODDED_Assembly-CSharp.dll` to `Assembly-CSharp.dll`
|
```
|
||||||
- Move `inohara.cfg` to the base game directory (next to `mu3.exe`)
|
MonoMod.exe mu3_Data\Managed\Assembly-CSharp.dll
|
||||||
|
```
|
||||||
|
- Backup `Assembly-CSharp.dll`.
|
||||||
|
- Rename `MONOMODDED_Assembly-CSharp.dll` to `Assembly-CSharp.dll`.
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
Scores are sent after each play and that's it. You can nonetheless make sure it's running by checking the console or toggling `EnableOSD`.
|
Scores are sent after each play and that's it. You can nonetheless make sure it's running by enabling the console in `BepInEx\config\BepInEx.cfg` or the OSD in `inohara.cfg`.
|
||||||
|
|
||||||
|
#### Uploading older scores
|
||||||
|
Use [this script](https://gist.github.com/nyairobi/ffdf9e674f31987b1ffbd38d31b55f6c). You only have to do this once as Inohara will handle all future scores. If you are on a remote server, contact the admin.
|
||||||
|
|
||||||
|
**As a last resort**, you can toggle `ExportPBs` and upload the generated `batch-manual.json` [here](https://kamai.tachi.ac/import/batch-manual). Those PBs are industrial grade dogshit. Should the server admin provide you access to the playlog down the line, delete the `inohara-pb` import.
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
Provide your own `Assembly-CSharp.dll` (or `_unpacked`) and `UnityEngine.UI.dll`, then `dotnet restore`, `dotnet build`.
|
Provide your own `Assembly-CSharp.dll` (or `_unpacked`) and `UnityEngine.UI.dll`, then `dotnet restore`, `dotnet build`.
|
@ -1,18 +1,29 @@
|
|||||||
[Options]
|
[Options]
|
||||||
|
|
||||||
# Whether to enable score submissions
|
# Whether to enable score submissions
|
||||||
Enable = true
|
Enable = true
|
||||||
|
|
||||||
# Timeout for web requests, in seconds
|
# Timeout for web requests, in seconds
|
||||||
Timeout = 3
|
Timeout = 3
|
||||||
|
|
||||||
# Tachi instance base URL
|
# Tachi instance base URL
|
||||||
BaseUrl =
|
BaseUrl = https://kamai.tachi.ac
|
||||||
|
|
||||||
# Tachi status endpoint
|
# Tachi status endpoint
|
||||||
Status = /api/v1/status
|
Status = /api/v1/status
|
||||||
|
|
||||||
# Tachi score import endpoint
|
# Tachi score import endpoint
|
||||||
Import = /ir/direct-manual/import
|
Import = /ir/direct-manual/import
|
||||||
# Display status on-screen (rudimentarily)
|
|
||||||
|
# Whether to display status on-screen (rudimentarily)
|
||||||
EnableOSD = false
|
EnableOSD = false
|
||||||
|
|
||||||
|
# Whether to export your PBs for batch-manual (saved to batch-manual.json)
|
||||||
|
# This is very, very bad and should only be used as last resort
|
||||||
|
ExportPBs = false
|
||||||
|
|
||||||
[Keys]
|
[Keys]
|
||||||
|
|
||||||
* = %%TACHI_KEY%%
|
* = %%TACHI_KEY%%
|
||||||
|
|
||||||
# If you have a multi-user setup, you can configure
|
# If you have a multi-user setup, you can configure
|
||||||
|
Loading…
Reference in New Issue
Block a user