1
0
mirror of synced 2024-11-23 22:00:56 +01:00

Added TJA support + other things

This commit is contained in:
Fluto 2022-02-04 17:21:30 +11:00
parent 4cc0df9831
commit e95b7c6aa6
45 changed files with 4616 additions and 1252 deletions

View File

@ -1 +0,0 @@
TaikoMods

View File

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

View File

@ -0,0 +1,63 @@
<?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>

5
Folder.DotSettings.user Normal file
View File

@ -0,0 +1,5 @@
<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>

File diff suppressed because it is too large Load Diff

122
README.md
View File

@ -1,41 +1,52 @@
# Taiko no Tatsujin: The Drum Master - Mods
# TakoTako
Hey this modifies version 1.1.0.0 of Taiko no Tatsujin: The Drum Master
Hey this is a mod for Taiko no Tatsujin: The Drum Master
Currently has the features:
- Fixes sign in screen
- Fixes sign in screen for version 1.1.0.0
- Skips splash screen
- Disable fullscreen on application focus
- Allows custom tracks to be loaded into the game
- Disable fullscreen on application focus (worked when in windowed mode)
- Allows custom official tracks or TJAs to be loaded into the game
- Override songs names to a certain language than the default one
----
## Installation
1. Download ![BepInEx](https://github.com/BepInEx/BepInEx/releases) `BepInEx_x64_XXXXX.zip`, as of writing the latest version is 5.4.18. This is a mod to patch Unity Games
2. Find your game's installation directiory, yours might be under `C:\Program Files\ModifiableWindowsApps\Taiko no Tatsujin\`
3. Paste all of the files from the .zip from step 1 into this folder
(It will look something like this, my directory is different because I installed it to a different folder)\
![](https://github.com/Fluto/Taiko-no-Tatsujin-The-Drum-Master-Patch/blob/main/3.png)
4. Run Taiko no Tatusjin The Drum Master once, then close it
5. ![Download my patch](https://github.com/Fluto/TaikoMods/releases)
6. Look in your game's folder again, new files will have been generated under `.\BepInEx\plugins`
7. Paste the .DLL from step 4 into this folder\
![](https://github.com/Fluto/Taiko-no-Tatsujin-The-Drum-Master-Patch/blob/main/4.png)
8. And you're done!
To install mods is a bit tricky this time around as we have to take a few more steps to be able to inject files into the game. !(Swigs did a quick video on it here)[https://youtu.be/WDsWDVbtbbI] but if you want to follow along in text read on ahead.
1. Become an Xbox Insider, to do this open the `Xbox Insider Hub` which you can get from the Microsoft Store if you don't already have it installed. Go to Previews > Windows Gaming, and join it. There should be an update ready for you for the Xbox app, so go ahead and update and relaunch it
2. In the Xbox App go to Settings > General and enable `Use advanced installation and management features`. Feel free to change your installation directory
3. If the game is already installed uninstall it, and reinstall it
4. Download ![BepInEx](https://github.com/BepInEx/BepInEx/releases) `BepInEx_x64_XXXXX.zip`, as of writing the latest version is 5.4.18. This is a mod to patch Unity Games
5. Go to where you installed your game, for example `C:\XboxGames\T Tablet\Content`
6. Paste all of the files from the .zip from step 5 into this folder
(It will look something like this)\
![](https://github.com/Fluto/TakoTako/blob/main/readme-image-0.png)
7. We now need to give special permissions to the `BepInEx` folder. To do this, right click it, click on `Properties`, go to the `Security` tab, Click on the `Advanced` button, Click Change at the top, Under `Enter the object name to select` field type in your username and click `Check Names`. If the text doesn't become underscored that means you have entered the incorrect username. Then press `Ok` on that window to dismiss it. Going back to the `Advanced Security Settings Window` tick `Replace owner on subcontainers and objects` then finally press Apply.
![](https://github.com/Fluto/TakoTako/blob/main/readme-image-1.png)
8. Run Taiko no Tatusjin The Drum Master once, then close it. This will generate some files
9. Look in your game's folder again, new files will have been generated under `.\BepInEx\plugins`
10. ![Download my patch](https://github.com/Fluto/TaikoMods/releases)
11. Paste the .DLL from step 4 into this folder\
![](https://github.com/Fluto/TakoTako/blob/main/readme-image-2.png)
12. And you're done!
## Configuration
After installing the mod, and running the game it will generate files in `.\BepInEx\config`. Open `com.fluto.taikomods.cfg` to configure this mod
After installing the mod, and running the game it will generate files in `.\BepInEx\config`. Open `com.fluto.takotako.cfg` to configure this mod
Here you can enable each individual feature or redirect where custom songs will be loaded from
## Custom Songs
With this feature you can inject custom songs into the game!
To begin place custom songs in `SongDirectory` specified in your configuration file, by default this is `%userprofile%/Documents/TaikoTheDrumMasterMods/customSongs`
Each song must have it's own directory with a unique name. The folder must have this structure
To begin place custom songs in `SongDirectory` specified in your configuration file, by default this is `%userprofile%/Documents/TakoTako/customSongs`
Each song must have it's own directory with a unique name.
These songs can be nested within folders.
The folder must have this structure:
```
CustomSongs
Offical Songs
-- [MUSIC_ID]
---- data.json (this contains the metadata for the track)
---- song_[MUSIC_ID].bin (this is a raw .acb music file, this is a CRIWARE format)
@ -54,8 +65,20 @@ CustomSongs
---- [MUSIC_ID]_x.bin
---- [MUSIC_ID]_x_1.bin
---- [MUSIC_ID]_x_2.bin
TJA
-- [MUSIC_ID]
---- [MUSIC_ID].tja
---- song_[MUSIC_ID].ogg or .wav
Genre override
e.g. this will override the songs to pop
-- 01 Pop
---- [MUSIC_ID]
------ [MUSIC_ID].tja
------ song_[MUSIC_ID].ogg or .wav
```
This format will be updated in the future to remove redundantancy
```
data.json Format
{
@ -95,22 +118,53 @@ data.json Format
int fumenOffsetPos;
// Text Info
TextEntry songName (Song Title - e.g. A Cruel Angel's Thesis)
{
string text;
int font; (0 == Japanese, 1 == English, 2 == Traditional Chinese, 3 == Simplified Chinese, 4 == Korean)
}
TextEntry songName; (Song Title - e.g. A Cruel Angel's Thesis)
TextEntry songSubtitle (Origin of the song - e.g. From \" Neon Genesis EVANGELION \")
{
string text;
int font; (0 == Japanese, 1 == English, 2 == Traditional Chinese, 3 == Simplified Chinese, 4 == Korean)
}
TextEntry songSubtitle; (Origin of the song - e.g. From \" Neon Genesis EVANGELION \")
TextEntry songDetail; (Extra details for the track, sometimes used to say it's Japanese name - e.g. 残酷な天使のテーゼ)
}
TextEntry {
TextEntry songDetail (Extra details for the track, sometimes used to say it's Japanese name - e.g. 残酷な天使のテーゼ)
{
string text;
int font; (0 == Japanese, 1 == English, 2 == Traditional Chinese, 3 == Simplified Chinese, 4 == Korean)
}
// Langauge overrides
string jpText; (langauge override for 日本語 text)
int jpFont; (langauge override for 日本語 text)
string enText; (langauge override for English text)
int enFont; (langauge override for English text)
string frText; (langauge override for Français text)
int frFont; (langauge override for Français text)
string itText; (langauge override for Italiano text)
int itFont; (langauge override for Italiano text)
string deText; (langauge override for Deutsch text)
int deFont; (langauge override for Deutsch text)
string esText; (langauge override for Español text)
int esFont; (langauge override for Español text)
string tcText; (langauge override for 繁體中文 text)
int tcFont; (langauge override for 繁體中文 text)
string scText; (langauge override for 简体中文 text)
int scFont; (langauge override for 简体中文 text)
string krText; (langauge override for 영어 text)
int krFont; (langauge override for 영어 text)
}
```
---
## Supported Versions
<details>
<summary>Supported Versions</summary>
- 1.1.0.0
- 1.2.2.0
</details>
---
## Contributers
(to add!)
---
## Credits
- !(SuperSonicAudio)[https://github.com/blueskythlikesclouds/SonicAudioTools]
- !(VGAudio)[https://github.com/Thealexbarney/VGAudio]
- Pulsar#5356 for the TJA2BIN.exe

View File

@ -1,38 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<AssemblyName>com.fluto.taikomods</AssemblyName>
<Description>Fixes Taiko issues and allows custom songs</Description>
<Version>0.0.1</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<RootNamespace>TaikoMods</RootNamespace>
<PackageId>com.fluto.taikomods</PackageId>
<PackageVersion>1.0.1</PackageVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BepInEx.Analyzers" Version="1.*" PrivateAssets="all" />
<PackageReference Include="BepInEx.Core" Version="5.*" />
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
<PackageReference Include="UnityEngine.Modules" Version="2020.3.19" IncludeAssets="compile" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp, Version=1.0.2.22379, Culture=neutral, PublicKeyToken=null">
<HintPath>D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
</Reference>
</ItemGroup>
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetDir)$(AssemblyName).dll" DestinationFolder="D:\XboxGames\T Tablet\Content\BepInEx\plugins" Condition="Exists('D:\XboxGames\T Tablet\Content\BepInEx\plugins')" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

View File

@ -5,7 +5,7 @@
/contentModel.xml
/modules.xml
/projectSettingsUpdater.xml
/.idea.TaikoMods.iml
/.idea.TakoTako.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files

View File

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

View File

@ -1,6 +1,6 @@
using HarmonyLib;
namespace TaikoMods;
namespace TakoTako;
[HarmonyPatch]
public class DisableScreenChangeOnFocus

Binary file not shown.

8
TakoTako/FodyWeavers.xml Normal file
View File

@ -0,0 +1,8 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura>
<IncludeAssemblies>
TakoTako*
Newtonsoft.Json*
</IncludeAssemblies>
</Costura>
</Weavers>

141
TakoTako/FodyWeavers.xsd Normal file
View File

@ -0,0 +1,141 @@
<?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,4 +1,5 @@
<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/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>

1953
TakoTako/MusicPatch.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,11 @@ using System.Collections;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FlutoTaikoMods;
using HarmonyLib;
using HarmonyLib.Tools;
using UnityEngine;
namespace TaikoMods
namespace TakoTako
{
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
public class Plugin : BaseUnityPlugin
@ -16,60 +16,88 @@ namespace TaikoMods
public ConfigEntry<bool> ConfigDisableScreenChangeOnFocus;
public ConfigEntry<bool> ConfigFixSignInScreen;
public ConfigEntry<bool> ConfigEnableCustomSongs;
public ConfigEntry<string> ConfigSongDirectory;
public ConfigEntry<bool> ConfigSaveEnabled;
public ConfigEntry<string> ConfigSaveDirectory;
public ConfigEntry<bool> ConfigDisableCustomDLCSongs;
public ConfigEntry<string> ConfigOverrideDefaultSongLanguage;
public ConfigEntry<bool> ConfigApplyGenreOverride;
public static Plugin Instance;
private Harmony _harmony;
public static ManualLogSource Log;
private void Awake()
{
Instance = this;
Log = Logger;
Logger.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!");
SetupConfig();
SetupHarmony();
}
private void SetupConfig()
{
var userFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
ConfigFixSignInScreen = Config.Bind("General",
"FixSignInScreen",
true,
"When true this will apply the patch to fix signing into Xbox Live");
ConfigSkipSplashScreen = Config.Bind("General",
"SkipSplashScreen",
true,
"When true this will skip the intro");
ConfigDisableScreenChangeOnFocus = Config.Bind("General",
"DisableScreenChangeOnFocus",
false,
"When focusing this wont do anything jank, I thnk");
ConfigEnableCustomSongs = Config.Bind("CustomSongs",
"EnableCustomSongs",
true,
"When true this will load custom mods");
ConfigSongDirectory = Config.Bind("CustomSongs",
"SongDirectory",
$"{userFolder}/Documents/TaikoTheDrumMasterMods/customSongs",
$"{userFolder}/Documents/{typeof(Plugin).Namespace}/customSongs",
"The directory where custom tracks are stored");
ConfigSaveEnabled = Config.Bind("CustomSongs",
"SaveEnabled",
true,
"Should there be local saves? Disable this if you want to wipe modded saves with every load");
ConfigSaveDirectory = Config.Bind("CustomSongs",
"SaveDirectory",
$"{userFolder}/Documents/TaikoTheDrumMasterMods/saves",
"The directory where saves are stored");
ConfigDisableCustomDLCSongs = Config.Bind("CustomSongs",
"DisableCustomDLCSongs",
false,
"By default, DLC is enabled for custom songs, this is to reduce any hiccups when playing online with other people. " +
"Set this to true if you want DLC to be marked as false, be aware that the fact you're playing a custom song will be sent over the internet");
ConfigOverrideDefaultSongLanguage = Config.Bind("CustomSongs",
"ConfigOverrideDefaultSongLanguage",
string.Empty,
"Set this value to {Japanese, English, French, Italian, German, Spanish, ChineseTraditional, ChineseSimplified, Korean} " +
"to override all music tracks to a certain language, regardless of your applications language");
ConfigApplyGenreOverride = Config.Bind("CustomSongs",
"ConfigApplyGenreOverride",
true,
"Set this value to {01 Pop, 02 Anime, 03 Vocaloid, 04 Children and Folk, 05 Variety, 06 Classical, 07 Game Music, 08 Live Festival Mode, 08 Namco Original} " +
"to override all track's genre in a certain folder. This is useful for TJA files that do not have a genre");
ConfigFixSignInScreen = Config.Bind("General",
"FixSignInScreen",
true,
"When true this will apply the patch to fix signing into Xbox Live");
ConfigSkipSplashScreen = Config.Bind("General",
"SkipSplashScreen",
true,
"When true this will skip the intro");
ConfigDisableScreenChangeOnFocus = Config.Bind("General",
"DisableScreenChangeOnFocus",
false,
"When focusing this wont do anything jank, I thnk");
}
private void SetupHarmony()
{
// Patch methods
@ -77,13 +105,13 @@ namespace TaikoMods
if (ConfigSkipSplashScreen.Value)
_harmony.PatchAll(typeof(SkipSplashScreen));
if (ConfigFixSignInScreen.Value)
_harmony.PatchAll(typeof(SignInPatch));
if (ConfigDisableScreenChangeOnFocus.Value)
_harmony.PatchAll(typeof(DisableScreenChangeOnFocus));
if (ConfigEnableCustomSongs.Value)
{
_harmony.PatchAll(typeof(MusicPatch));

Binary file not shown.

View File

@ -1,10 +1,8 @@
using System.Reflection;
using HarmonyLib;
using Microsoft.Xbox;
using TaikoMods;
using UnityEngine;
namespace FlutoTaikoMods;
namespace TakoTako;
/// <summary>
/// This patch will address the issue where signing with GDK is done correctly
@ -13,14 +11,10 @@ namespace FlutoTaikoMods;
[HarmonyPatch("SignIn")]
public static class SignInPatch
{
// ReSharper disable once InconsistentNaming
private static bool Prefix(GdkHelpers __instance)
{
// Only apply this patch if we're on version 1.0.0
if (Application.version != "1.0.0")
return false;
Plugin.Log.LogInfo("Patching sign in to force the user to be prompted to sign in");
var methodInfo = typeof(GdkHelpers).GetMethod("SignInImpl", BindingFlags.NonPublic | BindingFlags.Instance);
if (methodInfo == null)
@ -32,4 +26,4 @@ public static class SignInPatch
methodInfo.Invoke(__instance, new object[] {true});
return false;
}
}
}

View File

@ -1,7 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using HarmonyLib;
namespace TaikoMods;
namespace TakoTako;
[HarmonyPatch]
[SuppressMessage("ReSharper", "InconsistentNaming")]

72
TakoTako/TakoTako.csproj Normal file
View File

@ -0,0 +1,72 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<AssemblyName>com.fluto.takotako</AssemblyName>
<Description>Fixes Taiko issues and allows custom songs</Description>
<Version>0.0.1</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<RootNamespace>TakoTako</RootNamespace>
<PackageId>com.fluto.takotako</PackageId>
<PackageVersion>2.0.0</PackageVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BepInEx.Analyzers" Version="1.*" PrivateAssets="all" />
<PackageReference Include="BepInEx.Core" Version="5.*" />
<PackageReference Include="BepInEx.PluginInfoProps" Version="1.*" />
<PackageReference Include="Costura.Fody" Version="5.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Fody" Version="6.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="UnityEngine.Modules" Version="2020.3.19" IncludeAssets="compile" />
</ItemGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp, Version=1.0.2.23102, Culture=neutral, PublicKeyToken=null">
<HintPath>D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>D:\XboxGames\T Tablet\Content\Taiko no Tatsujin_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>References\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="TakoTako.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\TakoTakoScripts\TakoTako.Common\bin\Debug\net48\TakoTako.Common.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="References" />
</ItemGroup>
<ItemGroup>
<None Remove="Executables\tja2bin.exe" />
<None Remove="Executables\**" />
<None Remove="Exes\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Executables\**" />
<Compile Remove="Exes\**" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="Executables\**" />
<EmbeddedResource Remove="Exes\**" />
</ItemGroup>
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetDir)$(AssemblyName).dll" DestinationFolder="D:\XboxGames\T Tablet\Content\BepInEx\plugins\$(AssemblyName)" />
<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>

35
TakoTakoScripts/.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
# 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

@ -0,0 +1,13 @@
# 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

@ -0,0 +1,4 @@
<?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

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

View File

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

View File

@ -0,0 +1,133 @@
namespace TJAConvert
{
public class Files
{
public static byte[] TemplateACBData =
{
0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xED, 0x58, 0x7D, 0x6C, 0x14, 0xC7,
0x15, 0x7F, 0x7B, 0xE7, 0xE0, 0x60, 0xC0, 0x04, 0xDA, 0x40, 0x2A, 0x6A, 0x62, 0x92, 0x26, 0x10,
0x04, 0xC4, 0x76, 0x02, 0x05, 0xDB, 0x15, 0x3E, 0xFC, 0x85, 0x8D, 0x4D, 0x4E, 0x77, 0xC6, 0x04,
0x68, 0x80, 0xF5, 0xEE, 0xD8, 0xB7, 0x61, 0x6F, 0xF7, 0xBA, 0xBB, 0x67, 0xB8, 0x04, 0x52, 0x5A,
0xB5, 0x46, 0x6D, 0x49, 0xA9, 0xA2, 0x82, 0xF2, 0x17, 0x41, 0x6A, 0x50, 0xDA, 0x24, 0x82, 0xA4,
0x0D, 0x52, 0x93, 0xB4, 0xA5, 0x2D, 0x85, 0xAA, 0x1F, 0x81, 0xAA, 0x9F, 0x91, 0x50, 0x52, 0x50,
0x2A, 0x25, 0x52, 0x55, 0x3E, 0xDA, 0x2A, 0x4A, 0x93, 0x34, 0xD7, 0xF7, 0x9B, 0xDD, 0xBB, 0x5B,
0x9F, 0xCD, 0x91, 0x56, 0xEA, 0x3F, 0x55, 0x47, 0xBA, 0xDF, 0xBC, 0x99, 0x37, 0xF3, 0x66, 0xE6,
0xBD, 0x37, 0xEF, 0xCD, 0x5E, 0xDB, 0x86, 0x81, 0x2E, 0xA2, 0xD9, 0xEF, 0x10, 0x29, 0xF7, 0x13,
0x45, 0x4E, 0x13, 0x4D, 0xD9, 0x45, 0x28, 0x6D, 0x4A, 0x9A, 0x51, 0x19, 0x60, 0xA8, 0x06, 0xCC,
0x01, 0xCC, 0x8B, 0x33, 0xDC, 0x0E, 0x58, 0xB4, 0x85, 0xE1, 0x6E, 0x50, 0xCD, 0xA0, 0xFA, 0x00,
0x1B, 0x00, 0x43, 0x80, 0x0C, 0xE0, 0x61, 0xC0, 0x18, 0xE0, 0x08, 0xE0, 0x38, 0xE0, 0x25, 0xC0,
0xCF, 0x01, 0xBF, 0x03, 0xBC, 0x01, 0xF8, 0x07, 0x83, 0x32, 0x03, 0xB0, 0x60, 0x33, 0xC3, 0x5D,
0xA0, 0x3E, 0x99, 0x60, 0xE8, 0x01, 0x6C, 0x45, 0xD3, 0x05, 0x40, 0x9E, 0xF2, 0x25, 0xDE, 0xA5,
0x72, 0x18, 0xD4, 0x37, 0x01, 0x2F, 0x02, 0x20, 0x4F, 0x79, 0x0D, 0x73, 0xDF, 0xE2, 0x0D, 0x29,
0x7F, 0xE1, 0x66, 0x24, 0x0A, 0xA8, 0x05, 0xDC, 0x0A, 0x68, 0x04, 0xF4, 0x31, 0x37, 0xB2, 0x95,
0x85, 0x46, 0x2C, 0x34, 0x1F, 0x02, 0xEC, 0x07, 0x40, 0x5E, 0xE4, 0x18, 0xE0, 0x0C, 0xE0, 0x02,
0xE0, 0x5D, 0x1E, 0x1C, 0xAD, 0x05, 0xCC, 0x06, 0xDC, 0xCC, 0x7D, 0xD1, 0x5B, 0x40, 0xE1, 0xF8,
0xD1, 0x3B, 0x01, 0x77, 0x01, 0x96, 0x00, 0xA0, 0x88, 0x68, 0x13, 0x60, 0x39, 0xC6, 0xAD, 0x04,
0x74, 0x00, 0x36, 0x50, 0x50, 0x94, 0x26, 0x85, 0x8A, 0xE5, 0x26, 0x40, 0x3D, 0xFF, 0x2E, 0x30,
0x03, 0x34, 0xEB, 0x56, 0xD9, 0xCE, 0xF5, 0x5B, 0x74, 0xDD, 0x12, 0xE1, 0x71, 0x4A, 0x8A, 0x45,
0xF3, 0x5C, 0xE2, 0xBA, 0x0A, 0xED, 0x4F, 0x10, 0xDD, 0x70, 0x84, 0x6B, 0xF3, 0xDA, 0xF3, 0xAA,
0x79, 0xBD, 0xE8, 0x62, 0xFE, 0x19, 0xE3, 0xFB, 0x6B, 0xB6, 0xFB, 0x1B, 0xAA, 0xD9, 0x5B, 0xD8,
0x18, 0xCA, 0xEA, 0xE5, 0x3F, 0x3E, 0xC0, 0x7D, 0x47, 0x60, 0xDA, 0x6B, 0xCB, 0x8C, 0xEE, 0x9F,
0xA4, 0x73, 0x1A, 0xE0, 0x0B, 0xE5, 0xBD, 0xF9, 0x71, 0x43, 0x20, 0x77, 0x2D, 0xD1, 0x74, 0xAA,
0x2C, 0x3F, 0x54, 0xA6, 0x6F, 0x0F, 0x6F, 0xEF, 0x1A, 0x65, 0xAD, 0x50, 0x75, 0xE1, 0x50, 0x97,
0x61, 0x8A, 0x1E, 0x5D, 0x58, 0x9E, 0x31, 0x6C, 0x70, 0x33, 0x69, 0x3C, 0x24, 0x68, 0x50, 0x38,
0xAE, 0x61, 0x5B, 0x34, 0x90, 0xCB, 0x08, 0x1A, 0x50, 0x9D, 0x11, 0xE1, 0x51, 0x4C, 0x1B, 0xEE,
0xD7, 0x97, 0xAF, 0x55, 0xDD, 0x14, 0xB5, 0xAB, 0x9E, 0x18, 0xB1, 0x9D, 0x5C, 0xE7, 0x2E, 0x4F,
0x58, 0x72, 0x60, 0x7B, 0x56, 0x0C, 0xA8, 0x43, 0xA6, 0x00, 0xB1, 0x5E, 0x4D, 0x07, 0x8D, 0x8D,
0xEA, 0xA8, 0x18, 0xB6, 0x9D, 0xB4, 0xDF, 0x8A, 0x19, 0xAE, 0xAA, 0xF9, 0x64, 0xB7, 0xA3, 0x66,
0x52, 0x01, 0x69, 0xDA, 0x43, 0xAA, 0x29, 0x79, 0x09, 0x31, 0x2C, 0x1C, 0x61, 0x69, 0x22, 0x34,
0xBE, 0x24, 0x2C, 0x99, 0xB3, 0xBC, 0x60, 0x4E, 0x52, 0x7C, 0xA6, 0xDD, 0x4E, 0xA7, 0x55, 0x4B,
0xF7, 0xDB, 0x03, 0x8E, 0xAA, 0xED, 0x28, 0xB2, 0xB2, 0x65, 0x22, 0xDA, 0x6D, 0xCB, 0x73, 0x6C,
0xB3, 0x24, 0x29, 0x96, 0xF5, 0xEC, 0x7E, 0x5B, 0xCF, 0x9A, 0xAA, 0xC7, 0x7B, 0x0F, 0xE6, 0x79,
0x8E, 0x50, 0xD3, 0xB1, 0x9D, 0x43, 0x03, 0xB6, 0xB6, 0xD1, 0x76, 0x76, 0xDC, 0x67, 0xEA, 0xC4,
0x2D, 0x28, 0xA7, 0xA0, 0x0D, 0x1E, 0x62, 0x58, 0x23, 0x38, 0x61, 0x9F, 0x91, 0x36, 0x3C, 0x8C,
0xF2, 0xE7, 0xAE, 0xCF, 0xA6, 0x0B, 0x9D, 0x7D, 0x86, 0x2B, 0x19, 0x6E, 0xB8, 0x73, 0xBD, 0xAD,
0x0B, 0xBF, 0x33, 0xA6, 0x0D, 0x75, 0x67, 0x0D, 0xBD, 0xB4, 0x9A, 0x54, 0x67, 0xF9, 0xDA, 0xDB,
0xE4, 0xE2, 0xDA, 0xD0, 0xA0, 0x6D, 0x66, 0xD3, 0x72, 0x6B, 0xBC, 0xEE, 0xA0, 0x6A, 0x16, 0x74,
0x7C, 0x5F, 0xD6, 0x73, 0x0D, 0x9D, 0x65, 0x5B, 0xC1, 0x06, 0xD6, 0x98, 0xB6, 0xB6, 0x63, 0xFC,
0xC9, 0x65, 0x57, 0xB0, 0x3D, 0x3E, 0x38, 0xB5, 0xA7, 0x54, 0x56, 0x92, 0x27, 0x9C, 0x4E, 0x4B,
0xB3, 0x75, 0x96, 0x27, 0x4D, 0xDB, 0x39, 0xCA, 0x76, 0x0F, 0x94, 0xA2, 0x49, 0x65, 0x94, 0x34,
0xC9, 0xF6, 0x2E, 0x33, 0x48, 0xC1, 0x9C, 0x45, 0xB3, 0x77, 0xA8, 0x9E, 0x1A, 0x2C, 0x27, 0x54,
0x8F, 0x0D, 0xA4, 0xF5, 0x58, 0xC3, 0x76, 0xD1, 0x11, 0xE2, 0x8E, 0x61, 0x3B, 0x86, 0x97, 0x93,
0x4B, 0x85, 0xF4, 0xE1, 0xDB, 0x6B, 0x9C, 0x05, 0xA5, 0x71, 0x27, 0xDA, 0x34, 0xB4, 0x3F, 0x3E,
0x5E, 0x9C, 0x8F, 0x90, 0x16, 0x7C, 0x86, 0xB8, 0x6A, 0x9A, 0xC2, 0x0B, 0x8D, 0x9B, 0x94, 0x23,
0x65, 0x4E, 0xCE, 0xB1, 0xB3, 0x96, 0xDE, 0x2D, 0x2C, 0xE1, 0xA8, 0x9E, 0xED, 0xF8, 0x7D, 0x89,
0xC6, 0x06, 0x4A, 0xAC, 0xA2, 0xC4, 0x4A, 0x8A, 0x3B, 0xF6, 0x83, 0x42, 0xF3, 0xD6, 0x89, 0x1C,
0x25, 0x56, 0x50, 0x62, 0x39, 0x25, 0xEE, 0xA5, 0xC4, 0x3D, 0x94, 0x68, 0xE2, 0x31, 0x94, 0x68,
0xA0, 0xB8, 0xAA, 0x43, 0x81, 0x31, 0x36, 0xDA, 0x04, 0xD3, 0x95, 0x3A, 0x62, 0xC3, 0x6E, 0x53,
0x70, 0xC3, 0x6A, 0x62, 0xED, 0x6B, 0xEA, 0xBB, 0x58, 0x71, 0xAA, 0x77, 0x77, 0xBC, 0xBD, 0x9E,
0xDD, 0x69, 0x59, 0xE3, 0xB2, 0x7B, 0x9A, 0x96, 0x35, 0x34, 0xD6, 0xAF, 0xC9, 0x1A, 0xA6, 0xDE,
0x5C, 0x43, 0xAE, 0x6D, 0x8D, 0x6C, 0xF3, 0x44, 0x3A, 0xD3, 0x50, 0xF1, 0xCA, 0xEE, 0xE9, 0x58,
0x73, 0xFB, 0xE3, 0x8F, 0x9E, 0x18, 0x7B, 0xF1, 0x58, 0xBA, 0xF9, 0xE2, 0x2F, 0xBC, 0xB1, 0x72,
0x7E, 0x9B, 0xCC, 0x4F, 0xF4, 0x2A, 0xC7, 0xC9, 0x4E, 0xAE, 0x11, 0x05, 0x7E, 0x2F, 0x19, 0x53,
0x69, 0x1E, 0x05, 0xF9, 0xA9, 0x0A, 0x69, 0xA8, 0x86, 0xE3, 0x3A, 0xDD, 0xC2, 0x49, 0x80, 0x16,
0x82, 0x6A, 0x40, 0x66, 0x59, 0x05, 0x6E, 0x0F, 0xB8, 0x71, 0x80, 0x8E, 0x79, 0x51, 0x39, 0x3B,
0x1B, 0x5A, 0xA2, 0xF5, 0x4F, 0x16, 0x29, 0x6C, 0x49, 0x18, 0xB8, 0x47, 0xA7, 0x92, 0x8B, 0xC0,
0xC8, 0xC5, 0x56, 0x8F, 0xA5, 0x8B, 0x5D, 0xB4, 0xC1, 0x15, 0x0E, 0x7C, 0x84, 0xA4, 0xF7, 0x23,
0xB0, 0x84, 0x2F, 0x64, 0xBF, 0x9A, 0xA1, 0x3E, 0x61, 0x8D, 0x78, 0x29, 0x38, 0x47, 0x19, 0xC7,
0x0D, 0xC2, 0xD3, 0xA0, 0xE1, 0x1A, 0x43, 0x86, 0xC9, 0x5E, 0x14, 0x3A, 0x5F, 0x1F, 0x9F, 0xEF,
0x36, 0xAE, 0x17, 0x51, 0x21, 0x20, 0x46, 0x68, 0x0A, 0xCE, 0x87, 0x03, 0xDD, 0x98, 0x08, 0x62,
0xDF, 0xC7, 0xA8, 0x10, 0x8D, 0xC2, 0xB5, 0xBF, 0xB3, 0x6B, 0xE8, 0x3B, 0x90, 0x7F, 0x81, 0xE5,
0xF7, 0x72, 0xFD, 0x69, 0xFE, 0xBD, 0x26, 0x19, 0x35, 0x34, 0x1B, 0xF2, 0x21, 0x7A, 0x2A, 0x94,
0x73, 0x33, 0xA0, 0x1E, 0xB0, 0x18, 0xB0, 0x02, 0x8C, 0xD5, 0xD0, 0x5F, 0x1F, 0xA8, 0x8D, 0x00,
0x91, 0xF0, 0x35, 0x17, 0xA1, 0x88, 0xF2, 0x6C, 0x07, 0xF4, 0x96, 0x97, 0xA5, 0x70, 0x8B, 0xA8,
0x5F, 0xA4, 0x39, 0x86, 0xB2, 0xAB, 0xB0, 0x1A, 0xE5, 0xAD, 0xF4, 0x75, 0xE8, 0x7B, 0x10, 0x22,
0x0D, 0xAE, 0x4C, 0x4A, 0xB5, 0x2C, 0x61, 0xBA, 0xD4, 0x67, 0xDB, 0x99, 0x2E, 0x53, 0x1D, 0xA1,
0xA4, 0x9A, 0xCE, 0x98, 0xCC, 0x4D, 0x70, 0x0C, 0xC6, 0x08, 0xD9, 0x16, 0x2E, 0x8D, 0xBB, 0x94,
0x25, 0x37, 0x8C, 0xDB, 0x0E, 0xC7, 0x9F, 0x52, 0xBB, 0x47, 0xAF, 0xE4, 0x5F, 0xFE, 0xF9, 0x39,
0xB9, 0x2A, 0xB4, 0x89, 0x9B, 0xEC, 0x5F, 0xCA, 0x16, 0xC9, 0x98, 0x41, 0x4B, 0x71, 0x7E, 0x9C,
0x75, 0x0A, 0x94, 0x3C, 0x0D, 0x87, 0xC3, 0x5B, 0x81, 0x96, 0x00, 0x5A, 0xD0, 0xEC, 0x06, 0x3C,
0x00, 0xC8, 0x00, 0x3E, 0x07, 0xC6, 0x63, 0xA0, 0x0E, 0x03, 0x8E, 0x01, 0x7E, 0x02, 0x59, 0xBF,
0x2D, 0x2E, 0x57, 0x55, 0x20, 0xF2, 0xE3, 0x12, 0x1E, 0xDA, 0xE8, 0x91, 0x17, 0xD8, 0xCF, 0x41,
0x83, 0xB6, 0xA1, 0xF9, 0xC1, 0xA3, 0xDB, 0xB1, 0xB3, 0x19, 0xDF, 0x98, 0x7E, 0xB8, 0xF0, 0x0D,
0x5A, 0xF2, 0x3C, 0xB6, 0x2A, 0xD4, 0xA5, 0x05, 0x49, 0xC5, 0x0D, 0x67, 0x98, 0xA4, 0xA7, 0x3A,
0x9E, 0x3F, 0x21, 0xD4, 0xCB, 0x5A, 0xE4, 0xE9, 0x2E, 0x05, 0xDE, 0x07, 0x67, 0xC5, 0xE5, 0x6E,
0x2C, 0xEF, 0x68, 0xF2, 0x83, 0x8D, 0x8C, 0xC4, 0x2E, 0x95, 0x45, 0x96, 0x70, 0x00, 0x0D, 0x2D,
0x03, 0xCF, 0x2E, 0x31, 0x5C, 0x0A, 0x9E, 0x30, 0x15, 0xF5, 0x4F, 0xD0, 0x7F, 0x1D, 0xD7, 0x77,
0xF0, 0xEF, 0x53, 0x92, 0xA1, 0xD0, 0x8D, 0x14, 0x18, 0xA3, 0x90, 0xD6, 0x17, 0x14, 0x02, 0x7E,
0xA0, 0x87, 0x82, 0x3E, 0x88, 0x62, 0xBE, 0x5E, 0x37, 0x46, 0xF8, 0xA5, 0xD4, 0x51, 0xB5, 0x7A,
0x2F, 0xD3, 0x9D, 0x55, 0xED, 0xEF, 0x72, 0x65, 0x33, 0x67, 0x61, 0x85, 0x77, 0x41, 0x60, 0xFF,
0x8F, 0xF3, 0x7A, 0x70, 0xE6, 0x51, 0x49, 0xA3, 0x4C, 0x97, 0xF7, 0x4D, 0xFA, 0xFF, 0x14, 0xC0,
0x2C, 0xEC, 0x64, 0x3E, 0xA8, 0xC5, 0x80, 0x36, 0x40, 0x12, 0xDE, 0xA1, 0xC1, 0x3B, 0x2C, 0x4C,
0xCE, 0x81, 0xFA, 0x3C, 0xFA, 0xBE, 0x06, 0xEE, 0xA1, 0xB0, 0x95, 0x41, 0xF9, 0xAD, 0x27, 0x7D,
0x53, 0xD3, 0x51, 0x6E, 0x4B, 0x15, 0xF9, 0x39, 0xC9, 0x57, 0xDE, 0x38, 0x0B, 0xFF, 0x47, 0x26,
0x2D, 0x37, 0x92, 0xFF, 0x96, 0x09, 0x3D, 0x6B, 0xA4, 0x27, 0xF9, 0x24, 0x5F, 0x0D, 0x9F, 0xE0,
0xD4, 0x2B, 0xBB, 0x93, 0x9A, 0x5D, 0x1C, 0x27, 0xF7, 0xC6, 0x17, 0xA9, 0x72, 0x09, 0xF4, 0xA7,
0xB3, 0xFE, 0xB6, 0x72, 0xF3, 0x2B, 0x4C, 0x0F, 0x49, 0x46, 0xAD, 0x7F, 0x7F, 0x64, 0xFC, 0x00,
0xCC, 0x85, 0xFE, 0x16, 0x80, 0x92, 0xF7, 0x67, 0x15, 0xA8, 0x4E, 0xC0, 0x16, 0x80, 0x05, 0x78,
0x04, 0xF0, 0x75, 0x70, 0x9F, 0x84, 0x12, 0x9F, 0x43, 0xF3, 0x04, 0xE0, 0x0C, 0xE9, 0x45, 0x27,
0x8A, 0x94, 0xD6, 0xF6, 0x75, 0x5A, 0x7E, 0x93, 0x8A, 0x0F, 0x22, 0x8A, 0x9B, 0x6A, 0x6E, 0x88,
0x0F, 0x91, 0xC0, 0xAB, 0x07, 0x7E, 0x19, 0x78, 0xA4, 0xAC, 0xFE, 0x5B, 0xFA, 0xFE, 0x70, 0x97,
0x22, 0x7C, 0xAD, 0xA4, 0x6D, 0xAE, 0x7F, 0x13, 0x27, 0x2F, 0xB1, 0xAE, 0x64, 0x93, 0x12, 0x89,
0x48, 0xF5, 0xD4, 0xCB, 0x9E, 0x39, 0xB4, 0x38, 0x5A, 0xE2, 0xAF, 0x6D, 0x8F, 0x41, 0x65, 0xDB,
0x87, 0xD3, 0x1E, 0xD7, 0x1C, 0x95, 0x71, 0xB3, 0xF6, 0x46, 0xF7, 0x68, 0x76, 0x3A, 0x13, 0x79,
0x5A, 0x99, 0xC9, 0x8D, 0xBD, 0x18, 0xA7, 0x19, 0x19, 0xFE, 0x58, 0xC8, 0xA8, 0x15, 0x83, 0xE5,
0x84, 0x32, 0xEB, 0x4C, 0x3E, 0x5F, 0x37, 0xF7, 0xA6, 0xEA, 0x5C, 0x6E, 0xF3, 0xE6, 0xD6, 0xF9,
0x57, 0x5A, 0x0F, 0x44, 0x7F, 0x76, 0x65, 0xF7, 0x63, 0xA7, 0x4E, 0x1C, 0x3A, 0x78, 0x68, 0x57,
0x2A, 0x65, 0xF4, 0xB6, 0x2C, 0xBD, 0xDA, 0x7A, 0x2E, 0xFA, 0xCB, 0x2B, 0xEF, 0xFF, 0xE8, 0x37,
0x2F, 0x1C, 0x3D, 0x78, 0x68, 0x6C, 0x1F, 0xF7, 0xF5, 0xB6, 0xD4, 0x5D, 0x6D, 0xFD, 0x63, 0xF4,
0x95, 0xDA, 0x25, 0x2D, 0xBD, 0x9B, 0x52, 0xA9, 0xD1, 0xB1, 0x2F, 0x1E, 0xFC, 0xC6, 0xB7, 0x7F,
0x78, 0xB9, 0xFA, 0xEC, 0xD5, 0xDD, 0x17, 0x7F, 0x7D, 0xEA, 0x05, 0x1E, 0xF4, 0xDE, 0xC9, 0x4B,
0xFF, 0x7C, 0xF5, 0xD2, 0xBC, 0xCF, 0xFE, 0xF9, 0xE4, 0x13, 0xDA, 0xAD, 0x17, 0x8F, 0xBF, 0x71,
0xA9, 0xE5, 0x83, 0x7B, 0x2F, 0x3F, 0xF2, 0xDE, 0x5F, 0xDF, 0x7E, 0x34, 0xBF, 0xCF, 0x3D, 0xB7,
0xD4, 0x3D, 0xB7, 0xEF, 0xFC, 0xCE, 0x57, 0xDE, 0xAE, 0xDB, 0x33, 0xFA, 0x87, 0x99, 0x9B, 0x9E,
0x3F, 0xFF, 0xD5, 0x07, 0x2E, 0xBF, 0xFE, 0xFD, 0xFC, 0xD9, 0x87, 0xF3, 0x07, 0x5E, 0xFA, 0xDB,
0xA9, 0x15, 0x3F, 0xF8, 0xEE, 0xF3, 0x3B, 0xCF, 0x3F, 0xF3, 0xD4, 0x49, 0xE7, 0xF4, 0xB1, 0xDD,
0x0F, 0x9E, 0x7D, 0x79, 0x24, 0xFD, 0xFA, 0x71, 0x23, 0xBF, 0x70, 0xDB, 0xDF, 0xDF, 0xB9, 0x7A,
0x72, 0xD1, 0xBF, 0x75, 0xB4, 0xFF, 0x97, 0xFF, 0xA9, 0xF2, 0x91, 0xFA, 0xC9, 0xFB, 0xEF, 0x3F,
0xFB, 0x3D, 0xEF, 0xCD, 0xF7, 0x8F, 0xAE, 0x7B, 0xF6, 0x3B, 0x8F, 0xD7, 0x4E, 0xDD, 0xFF, 0xF4,
0x87, 0xF8, 0xC0, 0x1E, 0x5F, 0x82, 0xFC, 0xD5, 0x11, 0xCA, 0x5F, 0x1D, 0x92, 0xA1, 0xC8, 0x5C,
0x1F, 0x91, 0xEF, 0x33, 0xFE, 0x7D, 0x94, 0x7F, 0xF3, 0xFD, 0xEF, 0x1A, 0x37, 0xFC, 0x7D, 0x43,
0xFD, 0xAA, 0xCB, 0xC1, 0x83, 0x3F, 0x70, 0x2A, 0xCA, 0xDF, 0xCD, 0xF2, 0xF0, 0x70, 0x5B, 0x27,
0x69, 0x94, 0x2A, 0x7E, 0xE1, 0xF2, 0x6B, 0x15, 0x81, 0x72, 0x06, 0x16, 0x99, 0xDD, 0xCC, 0x30,
0x97, 0x7F, 0x75, 0x48, 0x45, 0xF3, 0x11, 0x02, 0x16, 0x60, 0x1C, 0x46, 0xDD, 0x89, 0x28, 0x09,
0xA2, 0x01, 0x44, 0xF8, 0x33, 0xC7, 0x0F, 0x3E, 0x32, 0xF6, 0x03, 0x38, 0xCA, 0x70, 0x4E, 0x48,
0xF2, 0x53, 0xF1, 0x7A, 0xFB, 0x2A, 0xDB, 0x5F, 0x5B, 0xE8, 0xFC, 0xCD, 0xC1, 0xF9, 0x8B, 0xF9,
0x7B, 0x46, 0x30, 0xF6, 0x86, 0xF0, 0x37, 0x4F, 0x29, 0x79, 0xDF, 0x16, 0xA1, 0xF2, 0x10, 0x5E,
0x51, 0xBF, 0x2B, 0xCB, 0xE5, 0x4F, 0x0B, 0xC6, 0xD6, 0x94, 0xBE, 0xA0, 0x8A, 0xD2, 0xAB, 0x7F,
0x55, 0x15, 0x4E, 0x19, 0x13, 0xCA, 0xE9, 0x2F, 0xCF, 0x9A, 0xF9, 0xC1, 0x9C, 0x37, 0x7B, 0x0F,
0x7F, 0x6B, 0x5B, 0xF7, 0xCB, 0x3F, 0x7D, 0x62, 0xC2, 0xFF, 0x12, 0xFF, 0x02, 0x1E, 0x7A, 0xF5,
0x14, 0x00, 0x13, 0x00, 0x00
};
}
}

View File

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura />
</Weavers>

View File

@ -0,0 +1,141 @@
<?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>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
<LangVersion>default</LangVersion>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
<ItemGroup>
<Folder Include="References" />
</ItemGroup>
<ItemGroup>
<Reference Include="SonicAudioLib, Version=1.0.11.0, Culture=neutral, PublicKeyToken=null">
<HintPath>References\SonicAudioLib.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="5.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Fody" Version="6.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NAudio.Core" Version="2.0.0" />
<PackageReference Include="NAudio.Vorbis" Version="1.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="VGAudio" Version="2.2.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TakoTako.Common\TakoTako.Common.csproj" />
</ItemGroup>
<Target Name="PostBuildCopy" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetDir)TJAConvert.exe" DestinationFolder="$(ProjectDir)\..\..\TakoTako\Executables" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@ -0,0 +1,415 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace TJAConvert;
internal class TJAMetadata
{
public string Id;
public string Title;
public string TitleJA;
public string TitleEN;
public string TitleCN;
public string TitleTW;
public string TitleKO;
public string Detail;
// dunno what to put in here
#pragma warning disable CS0649
public string DetailJA;
public string DetailEN;
public string DetailCN;
public string DetailTW;
public string DetailKO;
#pragma warning restore CS0649
public string Subtitle;
public string SubtitleJA;
public string SubtitleEN;
public string SubtitleCN;
public string SubtitleTW;
public string SubtitleKO;
public string AudioPath;
public float Offset;
public float PreviewTime;
public SongGenre Genre;
public List<Course> Courses = new();
public TJAMetadata(string tjaPath)
{
Id = Path.GetFileNameWithoutExtension(tjaPath);
var lines = File.ReadLines(tjaPath).ToList();
Title = FindAndGetField("TITLE");
TitleJA = FindAndGetField("TITLEJA");
TitleEN = FindAndGetField("TITLEEN");
TitleCN = FindAndGetField("TITLECN");
TitleTW = FindAndGetField("TITLETW");
TitleKO = FindAndGetField("TITLEKO");
Detail = FindAndGetField("MAKER");
ModifySubtitle("SUBTITLE", x => Subtitle = x);
ModifySubtitle("SUBTITLEJA", x => SubtitleJA = x);
ModifySubtitle("SUBTITLEEN", x => SubtitleEN = x);
ModifySubtitle("SUBTITLECN", x => SubtitleCN = x);
ModifySubtitle("SUBTITLETW", x => SubtitleTW = x);
ModifySubtitle("SUBTITLEKO", x => SubtitleKO = x);
void ModifySubtitle(string key, Action<string> setSubtitle)
{
var entry = FindAndGetField(key);
if (string.IsNullOrEmpty(entry))
return;
var subtitle = FindAndGetField(key).TrimStart('-', '+');
setSubtitle(subtitle);
}
AudioPath = FindAndGetField("WAVE");
Offset = float.Parse(FindAndGetField("OFFSET"));
PreviewTime = float.Parse(FindAndGetField("DEMOSTART"));
var genreEntry = FindAndGetField("GENRE");
Genre = GetGenre(genreEntry);
// start finding courses
Course currentCourse = new Course();
// find the last metadata entry
int courseStartIndex = lines.FindLastIndex(x =>
{
var match = TJAKeyValueRegex.Match(x);
if (!match.Success)
return false;
var type = match.Groups["KEY"].Value;
return MainMetadataKeys.Contains(type.ToUpperInvariant());
});
// find where the track starts
int courseEndIndex = lines.FindIndex(courseStartIndex, x => x.StartsWith("#START", StringComparison.InvariantCultureIgnoreCase));
do
{
bool newContent = false;
for (int i = courseStartIndex + 1; i < courseEndIndex; i++)
{
var line = lines[i];
var match = TJAKeyValueRegex.Match(line);
if (!match.Success)
continue;
newContent = true;
var key = match.Groups["KEY"].Value.ToUpperInvariant().Trim();
var value = match.Groups["VALUE"].Value.Trim();
switch (key)
{
case "COURSE":
{
currentCourse.CourseType = GetCourseType(value);
break;
}
case "LEVEL":
{
currentCourse.Level = int.Parse(value);
break;
}
case "STYLE":
{
currentCourse.PlayStyle = (PlayStyle) Enum.Parse(typeof(PlayStyle), value, true);
break;
}
}
if (key.Equals(nameof(Course.OtherMetadata.Balloon).ToUpperInvariant())) currentCourse.Metadata.Balloon = value;
if (key.Equals(nameof(Course.OtherMetadata.ScoreInit).ToUpperInvariant())) currentCourse.Metadata.ScoreInit = value;
if (key.Equals(nameof(Course.OtherMetadata.ScoreDiff).ToUpperInvariant())) currentCourse.Metadata.ScoreDiff = value;
if (key.Equals(nameof(Course.OtherMetadata.BalloonNor).ToUpperInvariant())) currentCourse.Metadata.BalloonNor = value;
if (key.Equals(nameof(Course.OtherMetadata.BalloonExp).ToUpperInvariant())) currentCourse.Metadata.BalloonExp = value;
if (key.Equals(nameof(Course.OtherMetadata.BalloonMas).ToUpperInvariant())) currentCourse.Metadata.BalloonMas = value;
if (key.Equals(nameof(Course.OtherMetadata.Exam1).ToUpperInvariant())) currentCourse.Metadata.Exam1 = value;
if (key.Equals(nameof(Course.OtherMetadata.Exam2).ToUpperInvariant())) currentCourse.Metadata.Exam2 = value;
if (key.Equals(nameof(Course.OtherMetadata.Exam3).ToUpperInvariant())) currentCourse.Metadata.Exam3 = value;
if (key.Equals(nameof(Course.OtherMetadata.GaugeNcr).ToUpperInvariant())) currentCourse.Metadata.GaugeNcr = value;
if (key.Equals(nameof(Course.OtherMetadata.Total).ToUpperInvariant())) currentCourse.Metadata.Total = value;
if (key.Equals(nameof(Course.OtherMetadata.HiddenBranch).ToUpperInvariant())) currentCourse.Metadata.HiddenBranch = value;
}
currentCourse.CourseDataIndexStart = courseStartIndex + 1;
currentCourse.CourseDataIndexEnd = courseEndIndex;
currentCourse.SongDataIndexStart = courseEndIndex;
// find the next end
if (currentCourse.PlayStyle == PlayStyle.Double)
{
// go through p1 and p2
var index = lines.FindIndex(courseEndIndex, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase));
courseStartIndex = lines.FindIndex(index + 1, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase));
}
else
{
courseStartIndex = lines.FindIndex(courseEndIndex, x => x.StartsWith("#END", StringComparison.InvariantCultureIgnoreCase));
}
currentCourse.SongDataIndexEnd = courseStartIndex;
if (newContent)
Courses.Add(currentCourse);
for (int i = currentCourse.SongDataIndexStart; i < currentCourse.SongDataIndexEnd; i++)
{
var line = lines[i];
if (line.Contains("#BRANCH"))
{
currentCourse.IsBranching = true;
break;
}
}
// duplicate the existing course
currentCourse = new Course(currentCourse);
// find the next start
courseEndIndex = lines.FindIndex(courseStartIndex, x => x.StartsWith("#START", StringComparison.InvariantCultureIgnoreCase));
} while (courseEndIndex > 0);
string FindAndGetField(string fieldName)
{
var tileRegex = new Regex(string.Format(TJAFieldRegexTemplate, fieldName), RegexOptions.IgnoreCase);
var index = lines.FindIndex(x => tileRegex.IsMatch(x));
if (index < 0)
return null;
return tileRegex.Match(lines[index]).Groups["VALUE"].Value;
}
SongGenre GetGenre(string value)
{
if (string.IsNullOrWhiteSpace(value))
return SongGenre.Variety;
switch (value.ToUpperInvariant())
{
case "アニメ":
return SongGenre.Anime;
case "J-POP":
return SongGenre.Pop;
case "どうよう":
return SongGenre.Children;
case "バラエティ":
return SongGenre.Variety;
case "ボーカロイド":
case "VOCALOID":
return SongGenre.Vocaloid;
case "クラシック":
return SongGenre.Classic;
case "ゲームミュージック":
return SongGenre.Game;
case "ナムコオリジナル":
return SongGenre.Namco;
}
return SongGenre.Variety;
}
CourseType GetCourseType(string value)
{
switch (value.ToUpperInvariant())
{
case "EASY":
case "0":
return CourseType.Easy;
case "NORMAL":
case "1":
return CourseType.Normal;
case "HARD":
case "2":
return CourseType.Hard;
case "ONI":
case "3":
return CourseType.Oni;
case "Edit":
case "4":
return CourseType.UraOni;
}
return CourseType.UraOni;
}
}
public const string TJAFieldRegexTemplate = "^{0}:\\s*(?<VALUE>.*?)\\s*$";
public static Regex TJAKeyValueRegex = new("^(?<KEY>.*?):\\s*(?<VALUE>.*?)\\s*$", RegexOptions.IgnoreCase);
public static HashSet<string> MainMetadataKeys = new()
{
"TITLE",
"TITLEEN",
"SUBTITLE",
"SUBTITLEEN",
"BPM",
"WAVE",
"OFFSET",
"DEMOSTART",
"GENRE",
"SCOREMODE",
"MAKER",
"LYRICS",
"SONGVOL",
"SEVOL",
"SIDE",
"LIFE",
"GAME",
"HEADSCROLL",
"BGIMAGE",
"BGMOVIE",
"MOVIEOFFSET",
"TAIKOWEBSKIN",
};
public class Course
{
public CourseType CourseType = CourseType.Oni;
public int Level = 5;
public PlayStyle PlayStyle = PlayStyle.Single;
public bool IsBranching = false;
public OtherMetadata Metadata = new();
public int CourseDataIndexStart;
public int CourseDataIndexEnd;
public int SongDataIndexStart;
public int SongDataIndexEnd;
public Course()
{
}
public Course(Course course)
{
CourseType = course.CourseType;
Level = course.Level;
// PlayStyle = course.PlayStyle;
Metadata = new OtherMetadata(course.Metadata);
}
public class OtherMetadata
{
public string Balloon;
public string ScoreInit;
public string ScoreDiff;
public string BalloonNor;
public string BalloonExp;
public string BalloonMas;
public string Exam1;
public string Exam2;
public string Exam3;
public string GaugeNcr;
public string Total;
public string HiddenBranch;
public OtherMetadata()
{
}
public OtherMetadata(OtherMetadata metadata)
{
Balloon = metadata.Balloon;
ScoreInit = metadata.ScoreInit;
ScoreDiff = metadata.ScoreDiff;
BalloonNor = metadata.BalloonNor;
BalloonExp = metadata.BalloonExp;
BalloonMas = metadata.BalloonMas;
Exam1 = metadata.Exam1;
Exam2 = metadata.Exam2;
Exam3 = metadata.Exam3;
GaugeNcr = metadata.GaugeNcr;
Total = metadata.Total;
HiddenBranch = metadata.HiddenBranch;
}
}
public List<string> MetadataToTJA(PlayStyle? playStyleOverride = null, CourseType? courseTypeOverride = null)
{
List<string> result = new List<string>();
result.Add($"COURSE:{(courseTypeOverride ?? CourseType).ToString()}");
result.Add($"LEVEL:{Level.ToString()}");
result.Add($"STYLE:{(playStyleOverride ?? PlayStyle).ToString()}");
AddIfNotNull(nameof(OtherMetadata.Balloon), Metadata.Balloon);
AddIfNotNull(nameof(OtherMetadata.ScoreInit), Metadata.ScoreInit);
AddIfNotNull(nameof(OtherMetadata.ScoreDiff), Metadata.ScoreDiff);
AddIfNotNull(nameof(OtherMetadata.BalloonNor), Metadata.BalloonNor);
AddIfNotNull(nameof(OtherMetadata.BalloonExp), Metadata.BalloonExp);
AddIfNotNull(nameof(OtherMetadata.BalloonMas), Metadata.BalloonMas);
AddIfNotNull(nameof(OtherMetadata.Exam1), Metadata.Exam1);
AddIfNotNull(nameof(OtherMetadata.Exam2), Metadata.Exam2);
AddIfNotNull(nameof(OtherMetadata.Exam3), Metadata.Exam3);
AddIfNotNull(nameof(OtherMetadata.GaugeNcr), Metadata.GaugeNcr);
AddIfNotNull(nameof(OtherMetadata.Total), Metadata.Total);
AddIfNotNull(nameof(OtherMetadata.HiddenBranch), Metadata.HiddenBranch);
void AddIfNotNull(string name, string value)
{
if (!string.IsNullOrWhiteSpace(value))
result.Add($"{name.ToUpperInvariant()}:{value}");
}
return result;
}
}
public enum PlayStyle
{
None = 0,
Single = 1,
Double = 2,
}
public enum SongGenre
{
Pop,
Anime,
Vocaloid,
Variety,
Children,
Classic,
Game,
Namco,
}
}
public enum CourseType
{
Easy,
Normal,
Hard,
Oni,
UraOni
}
public static class CourseTypeExtensions
{
public static string ToShort(this CourseType courseType)
{
return courseType switch
{
CourseType.Easy => "e",
CourseType.Normal => "n",
CourseType.Hard => "h",
CourseType.Oni => "m",
CourseType.UraOni => "x",
_ => throw new ArgumentOutOfRangeException(nameof(courseType), courseType, null)
};
}
}

View File

@ -0,0 +1,204 @@
using System;
using System.Runtime.Serialization;
using Newtonsoft.Json;
// ReSharper disable InconsistentNaming
namespace TakoTako.Common
{
[DataContract(Name = "CustomSong")]
[Serializable]
public class CustomSong
{
// Song Details
[DataMember] public int uniqueId;
[DataMember] public string id;
[DataMember] public int order;
[DataMember] public int genreNo;
[DataMember] public bool branchEasy;
[DataMember] public bool branchNormal;
[DataMember] public bool branchHard;
[DataMember] public bool branchMania;
[DataMember] public bool branchUra;
[DataMember] public int starEasy;
[DataMember] public int starNormal;
[DataMember] public int starHard;
[DataMember] public int starMania;
[DataMember] public int starUra;
[DataMember] public int shinutiEasy;
[DataMember] public int shinutiNormal;
[DataMember] public int shinutiHard;
[DataMember] public int shinutiMania;
[DataMember] public int shinutiUra;
[DataMember] public int shinutiEasyDuet;
[DataMember] public int shinutiNormalDuet;
[DataMember] public int shinutiHardDuet;
[DataMember] public int shinutiManiaDuet;
[DataMember] public int shinutiUraDuet;
[DataMember] public int scoreEasy;
[DataMember] public int scoreNormal;
[DataMember] public int scoreHard;
[DataMember] public int scoreMania;
[DataMember] public int scoreUra;
// Preview Details
[DataMember] public int previewPos;
[DataMember] public int fumenOffsetPos;
[DataMember] public bool AreFilesGZipped;
// LocalisationDetails
/// <summary>
/// Song Title
/// <example>
/// A Cruel Angel's Thesis
/// </example>
/// </summary>
[DataMember] public TextEntry songName;
/// <summary>
/// Origin of the song
/// <example>
/// From \" Neon Genesis EVANGELION \"
/// </example>
/// </summary>
[DataMember] public TextEntry songSubtitle;
/// <summary>
/// Extra details for the track, sometimes used to say it's Japanese name
/// <example>
/// 残酷な天使のテーゼ
/// </example>
/// </summary>
[DataMember] public TextEntry songDetail;
}
[Serializable]
public class TextEntry
{
/// <summary>
/// The text to display by default, if any override exist, the game will use that text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string text;
/// <summary>
/// font for the default text, if any override exist, the game will use that text
/// 0 == Japanese
/// 1 == English
/// 2 == Traditional Chinese
/// 3 == Simplified Chinese
/// 4 == Korean
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int font;
/// <summary>
/// 日本語 Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string jpText;
/// <summary>
/// 日本語 Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int jpFont;
/// <summary>
/// English Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string enText;
/// <summary>
/// English Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int enFont;
/// <summary>
/// Français Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string frText;
/// <summary>
/// Français Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int frFont;
/// <summary>
/// Italiano Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string itText;
/// <summary>
/// Italiano Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int itFont;
/// <summary>
/// Deutsch Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string deText;
/// <summary>
/// Deutsch Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int deFont;
/// <summary>
/// Español Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string esText;
/// <summary>
/// Español Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int esFont;
/// <summary>
/// 繁體中文 Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string tcText;
/// <summary>
/// 繁體中文 Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int tcFont;
/// <summary>
/// 简体中文 Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string scText;
/// <summary>
/// 简体中文 Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int scFont;
/// <summary>
/// 영어 Text
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public string krText;
/// <summary>
/// 영어 Font
/// </summary>
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public int krFont;
}
}

View File

@ -0,0 +1,16 @@
<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

@ -0,0 +1,16 @@
<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

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
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", "TJAConvert\TJAConvert.csproj", "{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDD2BC9B-15CB-47AE-A104-F45A3C65C7B1}.Release|Any CPU.Build.0 = Release|Any CPU
{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9ED2476B-FB39-4BE9-8661-21311AD9A3E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +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/=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>

View File

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

BIN
readme-image-0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
readme-image-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
readme-image-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB