migration to tja2fumen
-> Use tja2Fumen instead of tja2bin -> Added logic to grab the latest in a folder -> Removed usage of fumen offset as tja2bin & tja2fumen inject that into the generated file
This commit is contained in:
parent
c269bcab60
commit
f728d694b3
@ -56,6 +56,11 @@ To begin place custom songs in `SongDirectory` specified in your configuration f
|
||||
Each song must have it's own directory with a unique name.
|
||||
These songs can be nested within folders.
|
||||
|
||||
### Updating tja2fumen
|
||||
tja2fumen is developed by [vivaria](https://github.com/vivaria) and may be updated over time. If there is a new update feel free to grab their latest version for their tja conversion program at https://github.com/vivaria/tja2fumen/releases/latest.
|
||||
After downloading the .exe file, place it in your `.\BepInEx\plugins\com.fluto.takotako` folder :)
|
||||
|
||||
### Structure
|
||||
The folder must have this structure:
|
||||
```
|
||||
Offical Songs
|
||||
@ -178,7 +183,8 @@ LANG=ja_JP` followed by `7z x path/to/zip`. This will correct the mojibake (garb
|
||||
## Credits
|
||||
- [SonicAudioTools](https://github.com/blueskythlikesclouds/SonicAudioTools)
|
||||
- [VGAudio](https://github.com/Thealexbarney/VGAudio)
|
||||
- Pulsar#5356 for the TJA2BIN.exe
|
||||
- [tja2fumen](https://github.com/vivaria/tja2fumen) Thank you vivaria for making an open source tja interpreter!
|
||||
- Pulsar#5356 for their previous work on TJA2BIN.exe
|
||||
|
||||
## Licensing
|
||||
Uses the following licensed libraries.
|
||||
|
@ -225,7 +225,7 @@ namespace TJAConvert
|
||||
branchMania = false,
|
||||
branchUra = false,
|
||||
previewPos = (int) (metadata.PreviewTime * 1000) + addedTime,
|
||||
fumenOffsetPos = (int) (metadata.Offset * 10) + (addedTime),
|
||||
fumenOffsetPos = /*(int) (metadata.Offset * 1000) +*/ (addedTime), // tja2bin and tja2fumen use this value, so it can be ignored here :)
|
||||
tjaFileHash = tjaHash,
|
||||
songName = new TextEntry()
|
||||
{
|
||||
|
@ -66,7 +66,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
|
||||
<Copy SourceFiles="$(ProjectDir)..\TakoTako\Executables\tja2bin.exe" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="$(ProjectDir)..\TakoTako\Executables\tja2fumen.exe" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="$(TargetDir)TJAConvert.exe" DestinationFolder="$(ProjectDir)..\TakoTako\Executables" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
Binary file not shown.
BIN
TakoTako/Executables/tja2fumen.exe
Normal file
BIN
TakoTako/Executables/tja2fumen.exe
Normal file
Binary file not shown.
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
@ -174,10 +175,12 @@ public class CustomMusicLoaderPatch
|
||||
Log.LogError(e);
|
||||
}
|
||||
});
|
||||
|
||||
var tjaPaths = Directory.GetFiles(MusicTrackDirectory, "*.tja", SearchOption.AllDirectories).Select(Path.GetDirectoryName).Distinct().ToList();
|
||||
// convert / add TJA songs
|
||||
Parallel.ForEach(tjaPaths, new ParallelOptions() {MaxDegreeOfParallelism = 4}, musicDirectory =>
|
||||
Parallel.ForEach(tjaPaths, new ParallelOptions()
|
||||
{
|
||||
MaxDegreeOfParallelism = 4
|
||||
}, musicDirectory =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -200,11 +203,14 @@ public class CustomMusicLoaderPatch
|
||||
{
|
||||
var pathName = Path.GetFileName(musicDirectory);
|
||||
var pluginDirectory = @$"{Environment.CurrentDirectory}\BepInEx\plugins\{PluginInfo.PLUGIN_GUID}";
|
||||
|
||||
var tjaConvertPath = @$"{pluginDirectory}\TJAConvert.exe";
|
||||
var tja2BinConvertPath = @$"{pluginDirectory}\tja2bin.exe";
|
||||
if (!File.Exists(tjaConvertPath) || !File.Exists(tja2BinConvertPath))
|
||||
var tja2FumenConvertPath = GetTja2FumenPath();
|
||||
|
||||
if (!File.Exists(tjaConvertPath) || string.IsNullOrWhiteSpace(tja2FumenConvertPath) || !File.Exists(tja2FumenConvertPath))
|
||||
throw new Exception("Cannot find .exes in plugin folder");
|
||||
|
||||
Log.LogInfo($"Using {tja2FumenConvertPath} for generating TJAs");
|
||||
Log.LogInfo($"Converting {pathName}");
|
||||
var info = new ProcessStartInfo()
|
||||
{
|
||||
@ -325,6 +331,52 @@ public class CustomMusicLoaderPatch
|
||||
|
||||
return customSongsList;
|
||||
|
||||
string GetTja2FumenPath()
|
||||
{
|
||||
// determine conversion program
|
||||
var pluginDirectory = @$"{Environment.CurrentDirectory}\BepInEx\plugins\{PluginInfo.PLUGIN_GUID}";
|
||||
// var tjaConvertPath = @$"{pluginDirectory}\TJAConvert.exe";
|
||||
var files = Directory
|
||||
.EnumerateFiles(pluginDirectory)
|
||||
.Where(x =>
|
||||
x.Contains("tja2fumen", StringComparison.InvariantCultureIgnoreCase)
|
||||
&& x.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)).ToList();
|
||||
|
||||
// if something is just called tja2fumen.exe use that
|
||||
var foundFile = files.FirstOrDefault(x => x.Contains("tja2fumen.exe", StringComparison.InvariantCultureIgnoreCase));
|
||||
if (!string.IsNullOrWhiteSpace(foundFile))
|
||||
return foundFile;
|
||||
|
||||
var regex = new Regex(@"tja2fumen\-(?<VERSION>\d?.?\d+.\d+.\d+)\.exe");
|
||||
var versionPaths = files
|
||||
.Select(x =>
|
||||
{
|
||||
var match = regex.Match(x);
|
||||
Version version = null;
|
||||
if (match.Success)
|
||||
Version.TryParse(match.Groups["VERSION"].Value, out version);
|
||||
|
||||
return (x, version);
|
||||
})
|
||||
.Where(x => x.version != null)
|
||||
.OrderByDescending(x => x.version)
|
||||
.FirstOrDefault();
|
||||
|
||||
// try and pick the last version
|
||||
if (versionPaths.version != null)
|
||||
return versionPaths.x;
|
||||
|
||||
// just pick the first one
|
||||
if (files.Count > 0)
|
||||
return files[0];
|
||||
|
||||
var originalPath = @$"{pluginDirectory}\tja2bin.exe";
|
||||
if (File.Exists(originalPath))
|
||||
return originalPath;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void SubmitDirectory(string directory, bool isTjaSong)
|
||||
{
|
||||
var dataPath = Path.Combine(directory, "data.json");
|
||||
@ -491,42 +543,11 @@ public class CustomMusicLoaderPatch
|
||||
0,
|
||||
true, // can we capture footage
|
||||
2, // Always mark custom songs as "both players need to have this song to play it"
|
||||
new[]
|
||||
{
|
||||
song.branchEasy,
|
||||
song.branchNormal,
|
||||
song.branchHard,
|
||||
song.branchMania,
|
||||
song.branchUra
|
||||
}, new[]
|
||||
{
|
||||
song.starEasy,
|
||||
song.starNormal,
|
||||
song.starHard,
|
||||
song.starMania,
|
||||
song.starUra
|
||||
}, new[]
|
||||
{
|
||||
song.shinutiEasy,
|
||||
song.shinutiNormal,
|
||||
song.shinutiHard,
|
||||
song.shinutiMania,
|
||||
song.shinutiUra
|
||||
}, new[]
|
||||
{
|
||||
song.shinutiEasyDuet,
|
||||
song.shinutiNormalDuet,
|
||||
song.shinutiHardDuet,
|
||||
song.shinutiManiaDuet,
|
||||
song.shinutiUraDuet
|
||||
}, new[]
|
||||
{
|
||||
song.scoreEasy,
|
||||
song.scoreNormal,
|
||||
song.scoreHard,
|
||||
song.scoreMania,
|
||||
song.scoreUra
|
||||
}
|
||||
new[] { song.branchEasy, song.branchNormal, song.branchHard, song.branchMania, song.branchUra },
|
||||
new[] { song.starEasy, song.starNormal, song.starHard, song.starMania, song.starUra },
|
||||
new[] { song.shinutiEasy, song.shinutiNormal, song.shinutiHard, song.shinutiMania, song.shinutiUra },
|
||||
new[] { song.shinutiEasyDuet, song.shinutiNormalDuet, song.shinutiHardDuet, song.shinutiManiaDuet, song.shinutiUraDuet },
|
||||
new[] { song.scoreEasy, song.scoreNormal, song.scoreHard, song.scoreMania, song.scoreUra }
|
||||
#if TAIKO_IL2CPP
|
||||
, 0, // no idea what this is, going to mark them as default for now :)
|
||||
string.Empty, // no idea what this is, going to mark them as default for now :)
|
||||
@ -534,18 +555,10 @@ public class CustomMusicLoaderPatch
|
||||
false, // no idea what this is, going to mark them as default for now :),
|
||||
new[] // no idea what this is, setting it to shinuti score
|
||||
{
|
||||
song.shinutiEasy,
|
||||
song.shinutiNormal,
|
||||
song.shinutiHard,
|
||||
song.shinutiMania,
|
||||
song.shinutiUra
|
||||
song.shinutiEasy, song.shinutiNormal, song.shinutiHard, song.shinutiMania, song.shinutiUra
|
||||
}, new[] // no idea what this is, setting it to shinuti duet score
|
||||
{
|
||||
song.shinutiEasyDuet,
|
||||
song.shinutiNormalDuet,
|
||||
song.shinutiHardDuet,
|
||||
song.shinutiManiaDuet,
|
||||
song.shinutiUraDuet
|
||||
song.shinutiEasyDuet, song.shinutiNormalDuet, song.shinutiHardDuet, song.shinutiManiaDuet, song.shinutiUraDuet
|
||||
}
|
||||
#endif
|
||||
);
|
||||
@ -1342,7 +1355,8 @@ public class CustomMusicLoaderPatch
|
||||
Animator iconCrown2 = __instance.diffCourseAnims[levelType].IconCrowns[1];
|
||||
if (__instance.status.Is2PActive)
|
||||
{
|
||||
GetPlayerRecordInfo(TaikoSingletonMonoBehaviour<CommonObjects>.Instance.MyDataManager.PlayData, 1, __instance.selectedSongInfo.UniqueId, (EnsoData.EnsoLevelType) levelType, out var dst);
|
||||
GetPlayerRecordInfo(TaikoSingletonMonoBehaviour<CommonObjects>.Instance.MyDataManager.PlayData, 1, __instance.selectedSongInfo.UniqueId,
|
||||
(EnsoData.EnsoLevelType)levelType, out var dst);
|
||||
switch (dst.crown)
|
||||
{
|
||||
case DataConst.CrownType.Silver:
|
||||
@ -1376,7 +1390,8 @@ public class CustomMusicLoaderPatch
|
||||
[HarmonyWrapSafe]
|
||||
public static void UpdateDisplay_Postfix(CourseSelectScoreDisplay __instance, int musicUniqueId, EnsoData.EnsoLevelType levelType)
|
||||
{
|
||||
GetPlayerRecordInfo(TaikoSingletonMonoBehaviour<CommonObjects>.Instance.MyDataManager.PlayData, __instance.playerType == DataConst.PlayerType.Player_1 ? 0 : 1, musicUniqueId, levelType, out var dst);
|
||||
GetPlayerRecordInfo(TaikoSingletonMonoBehaviour<CommonObjects>.Instance.MyDataManager.PlayData, __instance.playerType == DataConst.PlayerType.Player_1 ? 0 : 1,
|
||||
musicUniqueId, levelType, out var dst);
|
||||
var normalHiScore = dst.normalHiScore;
|
||||
for (int index = 0; index < 6; ++index)
|
||||
{
|
||||
@ -1453,7 +1468,8 @@ public class CustomMusicLoaderPatch
|
||||
|
||||
for (int levelType = 0; levelType < num; ++levelType)
|
||||
{
|
||||
GetPlayerRecordInfo(TaikoSingletonMonoBehaviour<CommonObjects>.Instance.MyDataManager.PlayData, playerId, musicUniqueId, (EnsoData.EnsoLevelType) levelType, out var dst);
|
||||
GetPlayerRecordInfo(TaikoSingletonMonoBehaviour<CommonObjects>.Instance.MyDataManager.PlayData, playerId, musicUniqueId, (EnsoData.EnsoLevelType)levelType,
|
||||
out var dst);
|
||||
__instance.bestScores[levelType].RootObject.SetValue(dst.normalHiScore.score);
|
||||
}
|
||||
}
|
||||
@ -1464,9 +1480,14 @@ public class CustomMusicLoaderPatch
|
||||
/// Save scores to custom save data
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(PlayDataManager), "UpdatePlayerScoreRecordInfo",
|
||||
new Type[] {typeof(int), typeof(int), typeof(int), typeof(EnsoData.EnsoLevelType), typeof(bool), typeof(DataConst.SpecialTypes), typeof(HiScoreRecordInfo), typeof(DataConst.ResultType), typeof(bool), typeof(DataConst.CrownType)})]
|
||||
new Type[]
|
||||
{
|
||||
typeof(int), typeof(int), typeof(int), typeof(EnsoData.EnsoLevelType), typeof(bool), typeof(DataConst.SpecialTypes), typeof(HiScoreRecordInfo),
|
||||
typeof(DataConst.ResultType), typeof(bool), typeof(DataConst.CrownType)
|
||||
})]
|
||||
[HarmonyPrefix]
|
||||
public static bool UpdatePlayerScoreRecordInfo(PlayDataManager __instance, int playerId, int charaIndex, int uniqueId, EnsoData.EnsoLevelType levelType, bool isSinuchi, DataConst.SpecialTypes spTypes, HiScoreRecordInfo record,
|
||||
public static bool UpdatePlayerScoreRecordInfo(PlayDataManager __instance, int playerId, int charaIndex, int uniqueId, EnsoData.EnsoLevelType levelType, bool isSinuchi,
|
||||
DataConst.SpecialTypes spTypes, HiScoreRecordInfo record,
|
||||
DataConst.ResultType resultType, bool savemode, DataConst.CrownType crownType)
|
||||
{
|
||||
if (!uniqueIdToSong.ContainsKey(uniqueId))
|
||||
@ -2191,7 +2212,7 @@ public class CustomMusicLoaderPatch
|
||||
|
||||
public class ConversionItem
|
||||
{
|
||||
[JsonIgnore] public const int CurrentVersion = 2;
|
||||
[JsonIgnore] public const int CurrentVersion = 3;
|
||||
[JsonIgnore] public const int MaxAttempts = 3;
|
||||
|
||||
[JsonProperty("f")] public string FolderName;
|
||||
|
@ -77,7 +77,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Executables\tja2bin.exe" />
|
||||
<None Remove="Executables\tja2fumen.exe" />
|
||||
<None Remove="Executables\**" />
|
||||
<None Remove="Exes\**" />
|
||||
</ItemGroup>
|
||||
@ -98,7 +98,7 @@
|
||||
|
||||
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
|
||||
<Copy SourceFiles="$(TargetDir)$(AssemblyName).dll" DestinationFolder="$(GameDir)\BepInEx\plugins\$(AssemblyName)" />
|
||||
<Copy SourceFiles="$(ProjectDir)\Executables\tja2bin.exe" DestinationFolder="$(GameDir)\BepInEx\plugins\$(AssemblyName)" />
|
||||
<Copy SourceFiles="$(ProjectDir)\Executables\tja2fumen.exe" DestinationFolder="$(GameDir)\BepInEx\plugins\$(AssemblyName)" />
|
||||
<Copy SourceFiles="$(ProjectDir)\Executables\TJAConvert.exe" DestinationFolder="$(GameDir)\BepInEx\plugins\$(AssemblyName)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user