1
0
mirror of synced 2024-11-27 15:30:49 +01:00

Merge branch 'release/v2.1.0'

This commit is contained in:
Fluto 2022-02-11 19:37:28 +11:00
commit 9ed3bfdb68
24 changed files with 256 additions and 374 deletions

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="2" />
</component>
</project>

View File

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="60ebaf1c-1dab-40a1-8bf8-3441a6a2ec2d" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/MusicPatch.cs" beforeDir="false" afterPath="$PROJECT_DIR$/MusicPatch.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/TaikoMods.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/TaikoMods.csproj" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/Taiko-Mod/obj/Debug/net48/PluginInfo.cs" root0="SKIP_HIGHLIGHTING" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="24dLyJ1Va0ctK1BymSu6FiSfNMK" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="rider.run.widget.enabled.cache" value="false" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RunManager">
<configuration name="Attach to Unity Editor" type="UNITY_DEBUG_RUN_CONFIGURATION" factoryName="Unity Debug" show_console_on_std_err="false" show_console_on_std_out="false" port="50000" address="localhost">
<option name="allowRunningInParallel" value="false" />
<option name="listenPortForConnections" value="false" />
<option name="pid" />
<option name="projectPathOnTarget" />
<option name="selectedOptions">
<list />
</option>
<method v="2" />
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="60ebaf1c-1dab-40a1-8bf8-3441a6a2ec2d" name="Changes" comment="" />
<created>1643955770420</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1643955770420</updated>
<workItem from="1643955775940" duration="810000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnityProjectConfiguration" hasMinimizedUI="null" />
<component name="UnityUnitTestConfiguration" currentTestLauncher="NUnit" />
<component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
</component>
</project>

View File

@ -1,5 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005CXboxGames_005CT_0020Tablet_005CContent_005CTaiko_0020no_0020Tatsujin_005FData_005CManaged_005CAssembly_002DCSharp_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;&#xD;
&lt;Assembly Path="C:\git\public-git\taiko-mods\Taiko-Mod\bin\Debug\net48\Assembly-CSharp-firstpass.dll" /&gt;&#xD;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>

View File

@ -22,6 +22,9 @@ namespace TJAConvert
{
public static class Program
{
public const int PaddedSongTime = 2 * 1000; // in ms
public const float TjaOffsetForPaddingSong = -1.0f; // in ms
public static async Task Main(string[] args)
{
if (args.Length != 1)
@ -100,7 +103,7 @@ namespace TJAConvert
Directory.CreateDirectory(tempOutDirectory);
var originalTjaData = File.ReadAllBytes(tjaPath);
var tjaHash = (int)(MurmurHash2.Hash(originalTjaData) & 0xFFFF_FFF);
var tjaHash = (int) (MurmurHash2.Hash(originalTjaData) & 0xFFFF_FFF);
var passed = await TJAToFumens(metadata, tjaPath, tjaHash, tempOutDirectory);
if (passed >= 0) passed = CreateMusicFile(metadata, tjaHash, tempOutDirectory) ? 0 : -1;
@ -108,14 +111,16 @@ namespace TJAConvert
var copyFilePath = Path.Combine(newDirectory, Path.GetFileName(originalAudioPath));
File.Copy(originalAudioPath, copyFilePath);
int millisecondsAddedSilence = metadata.Offset > TjaOffsetForPaddingSong ? PaddedSongTime : 0;
var audioExtension = Path.GetExtension(copyFilePath).TrimStart('.');
switch (audioExtension.ToLowerInvariant())
{
case "wav":
if (passed >= 0) passed = WavToACB(copyFilePath, tempOutDirectory, tjaHash) ? 0 : -1;
if (passed >= 0) passed = WavToACB(copyFilePath, tempOutDirectory, tjaHash, millisecondsAddedSilence: millisecondsAddedSilence) ? 0 : -1;
break;
case "ogg":
if (passed >= 0) passed = OGGToACB(copyFilePath, tempOutDirectory, tjaHash) ? 0 : -1;
if (passed >= 0) passed = OGGToACB(copyFilePath, tempOutDirectory, tjaHash, millisecondsAddedSilence) ? 0 : -1;
break;
default:
Console.WriteLine($"Do not support {audioExtension} audio files");
@ -202,6 +207,7 @@ namespace TJAConvert
{
try
{
var addedTime = metadata.Offset > TjaOffsetForPaddingSong ? PaddedSongTime : 0;
var musicInfo = new CustomSong
{
id = tjaHash.ToString(),
@ -212,8 +218,8 @@ namespace TJAConvert
branchHard = false,
branchMania = false,
branchUra = false,
previewPos = (int) (metadata.PreviewTime * 1000),
fumenOffsetPos = (int) (metadata.Offset * 10),
previewPos = (int) (metadata.PreviewTime * 1000) + addedTime,
fumenOffsetPos = (int) (metadata.Offset * 10) + (addedTime),
tjaFileHash = tjaHash,
songName = new TextEntry()
{
@ -264,49 +270,91 @@ namespace TJAConvert
foreach (var course in metadata.Courses)
{
var isDouble = course.PlayStyle == TJAMetadata.PlayStyle.Double;
var shinuti = EstimateScoreBasedOnNotes(course);
//todo figure out the best score?
switch (course.CourseType)
{
case CourseType.Easy:
musicInfo.starEasy = course.Level;
musicInfo.shinutiEasy = 10170;
musicInfo.shinutiEasyDuet = 10170;
musicInfo.scoreEasy = 360090;
musicInfo.branchEasy = course.IsBranching;
musicInfo.scoreEasy = 1000000;
musicInfo.branchEasy = musicInfo.branchEasy || course.IsBranching;
if (isDouble)
musicInfo.shinutiEasyDuet = shinuti;
else
musicInfo.shinutiEasy = shinuti;
break;
case CourseType.Normal:
musicInfo.starNormal = course.Level;
musicInfo.shinutiNormal = 6010;
musicInfo.shinutiNormalDuet = 6010;
musicInfo.scoreNormal = 650150;
musicInfo.branchNormal = course.IsBranching;
musicInfo.scoreNormal = 1000000;
musicInfo.branchNormal = musicInfo.branchNormal || course.IsBranching;
if (isDouble)
musicInfo.shinutiNormalDuet = shinuti;
else
musicInfo.shinutiNormal = shinuti;
break;
case CourseType.Hard:
musicInfo.starHard = course.Level;
musicInfo.shinutiHard = 3010;
musicInfo.shinutiHardDuet = 3010;
musicInfo.scoreHard = 800210;
musicInfo.branchHard = course.IsBranching;
musicInfo.scoreHard = 1000000;
musicInfo.branchHard = musicInfo.branchHard || course.IsBranching;
if (isDouble)
musicInfo.shinutiHardDuet = shinuti;
else
musicInfo.shinutiHard = shinuti;
break;
case CourseType.Oni:
musicInfo.starMania = course.Level;
musicInfo.shinutiMania = 1000;
musicInfo.shinutiManiaDuet = 1000;
musicInfo.scoreMania = 10000;
musicInfo.branchMania = course.IsBranching;
musicInfo.scoreMania = 1000000;
musicInfo.branchMania = musicInfo.branchMania || course.IsBranching;
if (isDouble)
musicInfo.shinutiManiaDuet = shinuti;
else
musicInfo.shinutiMania = shinuti;
break;
case CourseType.UraOni:
musicInfo.starUra = course.Level;
musicInfo.shinutiUra = 1000;
musicInfo.shinutiUraDuet = 1000;
musicInfo.scoreUra = 10000;
musicInfo.branchUra = course.IsBranching;
musicInfo.scoreUra = 1000000;
musicInfo.branchUra = musicInfo.branchUra || course.IsBranching;
if (isDouble)
musicInfo.shinutiUraDuet = shinuti;
else
musicInfo.shinutiUra = shinuti;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
// make sure each course as a score
if (musicInfo.shinutiEasy == 0)
musicInfo.shinutiEasy = musicInfo.shinutiEasyDuet != 0 ? musicInfo.shinutiEasyDuet : 7352;
if (musicInfo.shinutiNormal == 0)
musicInfo.shinutiNormal = musicInfo.shinutiNormalDuet != 0 ? musicInfo.shinutiNormalDuet : 4830;
if (musicInfo.shinutiHard == 0)
musicInfo.shinutiHard = musicInfo.shinutiHardDuet != 0 ? musicInfo.shinutiHardDuet : 3144;
if (musicInfo.shinutiMania == 0)
musicInfo.shinutiMania = musicInfo.shinutiManiaDuet != 0 ? musicInfo.shinutiManiaDuet : 2169;
if (musicInfo.shinutiUra == 0)
musicInfo.shinutiUra = musicInfo.shinutiUraDuet != 0 ? musicInfo.shinutiUraDuet : 1420;
if (musicInfo.shinutiEasyDuet == 0)
musicInfo.shinutiEasyDuet = musicInfo.shinutiEasy;
if (musicInfo.shinutiNormalDuet == 0)
musicInfo.shinutiNormalDuet = musicInfo.shinutiNormal;
if (musicInfo.shinutiHardDuet == 0)
musicInfo.shinutiHardDuet = musicInfo.shinutiHard;
if (musicInfo.shinutiManiaDuet == 0)
musicInfo.shinutiManiaDuet = musicInfo.shinutiMania;
if (musicInfo.shinutiUraDuet == 0)
musicInfo.shinutiUraDuet = musicInfo.shinutiUra;
int EstimateScoreBasedOnNotes(TJAMetadata.Course course)
{
return Math.Max(1, 1000000 / course.EstimatedNotes);
}
var json = JsonConvert.SerializeObject(musicInfo, Formatting.Indented);
File.WriteAllText($"{outputPath}/data.json", json);
return true;
@ -637,7 +685,7 @@ namespace TJAConvert
attempts--;
// todo: Not sure how to solve this, so ignore it for now
if (result.Contains("branches must have same measure count") || result.Contains("invalid #BRANCHSTART"))
if (result.Contains("branches must have same measure count"))
return -2;
async Task RunProcess()
@ -816,10 +864,40 @@ namespace TJAConvert
return true;
}
if (result.Contains("invalid #BRANCHSTART"))
{
var currentLines = File.ReadLines(newPath).ToList();
for (var i = 0; i < currentLines.Count; i++)
{
var line = currentLines[i];
if (!line.StartsWith("#BRANCHSTART p,", StringComparison.InvariantCultureIgnoreCase))
continue;
var arguments = line.Substring("#BRANCHSTART ".Length).Split(',');
// This invalid branch start error needs to be manually resolved
if (arguments.Length != 3)
return false;
float number1;
float number2;
if (!float.TryParse(arguments[1], out var test))
return false;
number1 = test;
if (!float.TryParse(arguments[2], out test))
return false;
number2 = test;
currentLines[i] = $"#BRANCHSTART p,{(int) Math.Ceiling(number1)},{(int) Math.Ceiling(number2)}";
}
File.WriteAllLines(newPath, currentLines);
return true;
}
if (result.Contains("#E must be after the #N branch") || result.Contains("#M must be after the #E branch"))
{
var currentLines = File.ReadLines(newPath).ToList();
// var problematicCourse = GetCourseWithProblems();
string currentBranch = "";
int startOfBranch = -1;
@ -988,7 +1066,7 @@ namespace TJAConvert
}
}
private static bool OGGToACB(string oggPath, string outDirectory, int tjaHash)
private static bool OGGToACB(string oggPath, string outDirectory, int tjaHash, int millisecondsAddedSilence = 0)
{
try
{
@ -1001,7 +1079,7 @@ namespace TJAConvert
using (FileStream compressedFileStream = File.Create($"{acbPath}.acb"))
decompressor.CopyTo(compressedFileStream);
var hca = OggToHca(oggPath);
var hca = OggToHca(oggPath, millisecondsAddedSilence);
if (hca == null)
return false;
@ -1021,7 +1099,7 @@ namespace TJAConvert
}
}
private static bool WavToACB(string wavPath, string outDirectory, int tjaHash, bool deleteWav = false)
private static bool WavToACB(string wavPath, string outDirectory, int tjaHash, bool deleteWav = false, int millisecondsAddedSilence = 0)
{
try
{
@ -1034,7 +1112,7 @@ namespace TJAConvert
using (FileStream compressedFileStream = File.Create($"{acbPath}.acb"))
decompressor.CopyTo(compressedFileStream);
var hca = WavToHca(wavPath);
var hca = WavToHca(wavPath, millisecondsAddedSilence);
File.WriteAllBytes($"{acbPath}/00000.hca", hca);
Pack(acbPath);
if (File.Exists($"{outDirectory}/song_{tjaHash}.bin"))
@ -1054,22 +1132,53 @@ namespace TJAConvert
}
}
private static byte[] WavToHca(string path)
private static byte[] WavToHca(string path, int millisecondSilence = 0)
{
var wavReader = new WaveReader();
var hcaWriter = new HcaWriter();
var waveReader = new WaveReader();
var audioData = waveReader.Read(File.ReadAllBytes(path));
return hcaWriter.GetFile(audioData);
if (millisecondSilence > 0)
{
WaveFileReader reader = new WaveFileReader(path);
var memoryStream = new MemoryStream();
var trimmed = new OffsetSampleProvider(reader.ToSampleProvider())
{
DelayBy = TimeSpan.FromMilliseconds(millisecondSilence)
};
WaveFileWriter.WriteWavFileToStream(memoryStream, trimmed.ToWaveProvider16());
var audioData = wavReader.Read(memoryStream.ToArray());
return hcaWriter.GetFile(audioData);
}
else
{
var audioData = wavReader.Read(File.ReadAllBytes(path));
return hcaWriter.GetFile(audioData);
}
}
private static byte[] OggToHca(string inPath)
private static byte[] OggToHca(string inPath, int millisecondSilence = 0)
{
try
{
using FileStream fileIn = new FileStream(inPath, FileMode.Open);
var vorbis = new VorbisWaveReader(fileIn);
var wavProvider = new SampleToWaveProvider16(vorbis);
var memoryStream = new MemoryStream();
WaveFileWriter.WriteWavFileToStream(memoryStream, new SampleToWaveProvider16(vorbis));
if (millisecondSilence > 0)
{
var trimmed = new OffsetSampleProvider(wavProvider.ToSampleProvider())
{
DelayBy = TimeSpan.FromMilliseconds(millisecondSilence)
};
WaveFileWriter.WriteWavFileToStream(memoryStream, trimmed.ToWaveProvider16());
}
else
{
WaveFileWriter.WriteWavFileToStream(memoryStream, wavProvider);
}
var hcaWriter = new HcaWriter();
var waveReader = new WaveReader();
@ -1138,4 +1247,4 @@ namespace TJAConvert
return 3;
}
}
}
}

View File

@ -39,6 +39,7 @@
</ItemGroup>
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetDir)TJAConvert.exe" DestinationFolder="$(ProjectDir)\..\..\TakoTako\Executables" SkipUnchangedFiles="true" />
<Copy SourceFiles="$(ProjectDir)..\TakoTako\Executables\tja2bin.exe" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
<Copy SourceFiles="$(TargetDir)TJAConvert.exe" DestinationFolder="$(ProjectDir)..\TakoTako\Executables" SkipUnchangedFiles="true" />
</Target>
</Project>
</Project>

View File

@ -160,9 +160,7 @@ internal class TJAMetadata
currentCourse.SongDataIndexEnd = courseStartIndex;
if (newContent)
Courses.Add(currentCourse);
// is this branching?
for (int i = currentCourse.SongDataIndexStart; i < currentCourse.SongDataIndexEnd; i++)
{
var line = lines[i];
@ -173,6 +171,52 @@ internal class TJAMetadata
}
}
// calculate roughly the amount of song notes in this course
int noteCount = 0;
int branchNoteCount = 0;
int branches = 0;
bool inBranch = false;
for (int i = currentCourse.SongDataIndexStart; i < currentCourse.SongDataIndexEnd; i++)
{
var line = lines[i].Trim();
if (line.Equals("#N", StringComparison.InvariantCultureIgnoreCase)
|| line.Equals("#E", StringComparison.InvariantCultureIgnoreCase)
|| line.Equals("#M", StringComparison.InvariantCultureIgnoreCase))
branches++;
var branchStart = line.StartsWith("#BRANCHSTART", StringComparison.InvariantCultureIgnoreCase);
if (inBranch && (branchStart || line.StartsWith("#BRANCHEND", StringComparison.InvariantCultureIgnoreCase)))
{
noteCount += branchNoteCount / Math.Max(1, branches);
inBranch = false;
}
if (!inBranch && branchStart)
{
inBranch = true;
branchNoteCount = 0;
branches = 0;
}
if (!line.EndsWith(","))
continue;
var notes = line.Count(x => x is '1' or '2' or '3' or '4');
if (inBranch)
branchNoteCount += notes;
else
noteCount += notes;
}
if (currentCourse.PlayStyle == PlayStyle.Double)
currentCourse.EstimatedNotes = noteCount / 2;
else
currentCourse.EstimatedNotes = noteCount;
if (newContent)
Courses.Add(currentCourse);
// duplicate the existing course
currentCourse = new Course(currentCourse);
// find the next start
@ -241,8 +285,6 @@ internal class TJAMetadata
return CourseType.UraOni;
}
}
public const string TJAFieldRegexTemplate = "^{0}:\\s*(?<VALUE>.*?)\\s*$";
@ -290,6 +332,8 @@ internal class TJAMetadata
public int SongDataIndexStart;
public int SongDataIndexEnd;
public int EstimatedNotes = 0;
public Course()
{
}

View File

@ -203,4 +203,4 @@ namespace TakoTako.Common
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int krFont;
}
}
}

View File

@ -9,7 +9,7 @@
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\TakoTako\References\Newtonsoft.Json.dll</HintPath>
<HintPath>..\TakoTako\References\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>

View File

@ -1,10 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakoTako.Common", "TakoTakoScripts\TakoTako.Common\TakoTako.Common.csproj", "{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakoTako.Common", "TakoTako.Common\TakoTako.Common.csproj", "{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TJAConvert", "TakoTakoScripts\TJAConvert\TJAConvert.csproj", "{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TJAConvert", "TJAConvert\TJAConvert.csproj", "{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakoTako", "TakoTako\TakoTako.csproj", "{3B286FDB-8AB8-49B0-852E-5180AFBC20D5}"
ProjectSection(ProjectDependencies) = postProject
{9ED2476B-FB39-4BE9-8661-21311AD9A3E8} = {9ED2476B-FB39-4BE9-8661-21311AD9A3E8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -1,7 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ACB/@EntryIndexedValue">ACB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OGG/@EntryIndexedValue">OGG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TJA/@EntryIndexedValue">TJA</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=shinuti/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fluto/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=fumen/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fumens/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taiko/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taiko/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>

View File

@ -192,7 +192,7 @@ public class MusicPatch
{
if (IsTjaConverted(musicDirectory, out var conversionStatus) && conversionStatus != null)
{
foreach (var item in conversionStatus.Items.Where(item => item.Successful))
foreach (var item in conversionStatus.Items.Where(item => item.Successful && item.Version == ConversionStatus.ConversionItem.CurrentVersion))
SubmitDirectory(Path.Combine(musicDirectory, item.FolderName), true);
return;
}
@ -239,14 +239,14 @@ public class MusicPatch
if (!match.Success)
continue;
var resultInt = int.Parse(match.Groups["ID"].Value);
var resultCode = int.Parse(match.Groups["ID"].Value);
var folderPath = match.Groups["PATH"].Value;
folderPath = Path.GetFullPath(folderPath).Replace(Path.GetFullPath(musicDirectory), ".");
var existingEntry = conversionStatus.Items.FirstOrDefault(x => x.FolderName == folderPath);
var asciiFolderPath = Regex.Replace(folderPath, @"[^\u0000-\u007F]+", string.Empty);
if (resultInt >= 0)
if (resultCode >= 0)
Log.LogInfo($"Converted {asciiFolderPath} successfully");
else
Log.LogError($"Could not convert {asciiFolderPath}");
@ -257,13 +257,17 @@ public class MusicPatch
{
Attempts = 1,
FolderName = folderPath,
Successful = resultInt >= 0,
Successful = resultCode >= 0,
ResultCode = resultCode,
Version = ConversionStatus.ConversionItem.CurrentVersion,
});
}
else
{
existingEntry.Attempts++;
existingEntry.Successful = resultInt >= 0;
existingEntry.Successful = resultCode >= 0;
existingEntry.ResultCode = resultCode;
existingEntry.Version = ConversionStatus.ConversionItem.CurrentVersion;
}
}
@ -422,7 +426,7 @@ public class MusicPatch
if (conversionStatus == null)
return false;
return conversionStatus.Items.Count != 0 && conversionStatus.Items.All(x => x.Successful);
return conversionStatus.Items.Count != 0 && conversionStatus.Items.All(x => x.Successful && x.Version == ConversionStatus.ConversionItem.CurrentVersion);
}
catch
{
@ -625,7 +629,7 @@ public class MusicPatch
void Add(string key, TextEntry textEntry)
{
var (text, font) = GetValuesTextEntry(textEntry);
var (text, font) = GetValuesTextEntry(textEntry, languageValue);
musicInfoAccessors.Add(new WordDataInterface.WordListInfoAccesser(key, text, font));
}
}
@ -684,11 +688,11 @@ public class MusicPatch
return (text, font);
}
(string text, int font) GetValuesTextEntry(TextEntry textEntry)
(string text, int font) GetValuesTextEntry(TextEntry textEntry, string selectedLanguage)
{
string text;
int font;
switch (languageValue)
switch (selectedLanguage)
{
case "Japanese":
text = textEntry.jpText;
@ -735,7 +739,31 @@ public class MusicPatch
break;
}
if (!string.IsNullOrEmpty(text)) return (text, font);
// if this text is default, and we're not English / Japanese default to one of them
if (string.IsNullOrEmpty(text) && selectedLanguage != "Japanese" && selectedLanguage != "English")
{
string fallbackLanguage;
switch (selectedLanguage)
{
case "Chinese":
case "ChineseT":
case "ChineseTraditional":
case "ChineseSimplified":
case "ChineseS":
case "Korean":
fallbackLanguage = "Japanese";
break;
default:
fallbackLanguage = "English";
break;
}
return GetValuesTextEntry(textEntry, fallbackLanguage);
}
if (!string.IsNullOrEmpty(text))
return (text, font);
text = textEntry.text;
font = textEntry.font;
@ -1881,13 +1909,14 @@ public class MusicPatch
public class ConversionItem
{
[JsonIgnore] public const int CurrentVersion = 1;
[JsonIgnore] public const int CurrentVersion = 2;
[JsonIgnore] public const int MaxAttempts = 3;
[JsonProperty("f")] public string FolderName;
[JsonProperty("a")] public int Attempts;
[JsonProperty("s")] public bool Successful;
[JsonProperty("v")] public int Version = CurrentVersion;
[JsonProperty("v")] public int Version;
[JsonProperty("e")] public int ResultCode;
public override string ToString()
{
@ -1902,4 +1931,4 @@ public class MusicPatch
public string SongName;
public int UniqueId;
}
}
}

View File

@ -4,12 +4,12 @@
<TargetFramework>net48</TargetFramework>
<AssemblyName>com.fluto.takotako</AssemblyName>
<Description>Fixes Taiko issues and allows custom songs</Description>
<Version>2.0.0</Version>
<Version>2.1.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<RootNamespace>TakoTako</RootNamespace>
<PackageId>com.fluto.takotako</PackageId>
<PackageVersion>2.0.0</PackageVersion>
<PackageVersion>2.1.0</PackageVersion>
</PropertyGroup>
<ItemGroup>
@ -55,7 +55,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TakoTakoScripts\TakoTako.Common\TakoTako.Common.csproj" />
<ProjectReference Include="..\TakoTako.Common\TakoTako.Common.csproj" />
</ItemGroup>
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
@ -63,4 +63,4 @@
<Copy SourceFiles="$(ProjectDir)\Executables\tja2bin.exe" DestinationFolder="D:\XboxGames\T Tablet\Content\BepInEx\plugins\$(AssemblyName)" />
<Copy SourceFiles="$(ProjectDir)\Executables\TJAConvert.exe" DestinationFolder="D:\XboxGames\T Tablet\Content\BepInEx\plugins\$(AssemblyName)" />
</Target>
</Project>
</Project>

View File

@ -1,35 +0,0 @@
# Common IntelliJ Platform excludes
# User specific
**/.idea/**/workspace.xml
**/.idea/**/tasks.xml
**/.idea/shelf/*
**/.idea/dictionaries
**/.idea/httpRequests/
# Sensitive or high-churn files
**/.idea/**/dataSources/
**/.idea/**/dataSources.ids
**/.idea/**/dataSources.xml
**/.idea/**/dataSources.local.xml
**/.idea/**/sqlDataSources.xml
**/.idea/**/dynamic.xml
# Rider
# Rider auto-generates .iml files, and contentModel.xml
**/.idea/**/*.iml
**/.idea/**/contentModel.xml
**/.idea/**/modules.xml
*.suo
*.user
.vs/
[Bb]in/
[Oo]bj/
_UpgradeReport_Files/
[Pp]ackages/
Thumbs.db
Desktop.ini
.DS_Store
ShortcutFolder.lnk

View File

@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/.idea.TakoTakoScripts.iml
/projectSettingsUpdater.xml
/contentModel.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@ -1,141 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<RootNamespace>TakoTako.Common</RootNamespace>
<AssemblyName>TakoTako.Common</AssemblyName>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\TakoTako\References\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -1,7 +0,0 @@
{
"sdk": {
"version": "5.0.0",
"rollForward": "latestMinor",
"allowPrerelease": false
}
}