chart editor song id option + manifest id fix

This commit is contained in:
cyn0x8 2025-04-04 15:07:51 -07:00
parent d31ef12363
commit 5ea128a79b
No known key found for this signature in database
GPG key ID: D73EE844A93D1FCE
6 changed files with 63 additions and 7 deletions

2
assets

@ -1 +1 @@
Subproject commit 0303a03f43b078d5263b541de1ff504fd7cfcde5
Subproject commit f5da0b2be2a7f64e5fcff7909ccb576ee3a9a1cb

View file

@ -10,6 +10,8 @@ class ChartManifestData
*/
public static final CHART_MANIFEST_DATA_VERSION:thx.semver.Version = "1.0.0";
public static final invalidIdChars:Array<String> = ['/', '\\', ':', '*', '?', '"', '<', '>', '|'];
@:default(funkin.data.song.importer.ChartManifestData.CHART_MANIFEST_DATA_VERSION)
@:jcustomparse(funkin.data.DataParse.semverVersion)
@:jcustomwrite(funkin.data.DataWrite.semverVersion)
@ -19,7 +21,13 @@ class ChartManifestData
* The internal song ID for this chart.
* The metadata and chart data file names are derived from this.
*/
public var songId:String;
public var songId(default, set):String;
public function set_songId(value:String):String
{
value = value.trim();
for (invalidChar in invalidIdChars) value = value.replace(invalidChar, "");
return songId = value;
}
public function new(songId:String)
{

View file

@ -30,6 +30,7 @@ import funkin.data.song.SongData.SongNoteData;
import funkin.data.song.SongData.SongOffsets;
import funkin.data.song.SongData.NoteParamData;
import funkin.data.song.SongDataUtils;
import funkin.data.song.importer.ChartManifestData;
import funkin.graphics.FunkinCamera;
import funkin.graphics.FunkinSprite;
import funkin.input.Cursor;
@ -1198,6 +1199,24 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
*/
// ==============================
/**
* The song manifest data.
* If none already exists, it's intialized with the current song name in lower-kebab-case.
*/
var _songManifestData:Null<ChartManifestData> = null;
var songManifestData(get, set):ChartManifestData;
function get_songManifestData():ChartManifestData
{
if (_songManifestData != null) return _songManifestData;
return _songManifestData = new ChartManifestData(getDefaultSongId());
}
function set_songManifestData(value:ChartManifestData):ChartManifestData
{
return _songManifestData = value;
}
/**
* The song metadata.
* - Keys are the variation IDs. At least one (`default`) must exist.
@ -1471,7 +1490,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
function get_currentSongId():String
{
return currentSongName.toLowerKebabCase().replace(' ', '-').sanitize();
return songManifestData.songId;
}
function getDefaultSongId():String
{
var defaultSongId:String = currentSongName.trim().toLowerKebabCase().sanitize();
if (defaultSongId == '') defaultSongId = 'new-song';
return defaultSongId;
}
var currentSongArtist(get, set):String;

View file

@ -692,6 +692,7 @@ class ChartEditorDialogHandler
{
state.songMetadata.clear();
state.songChartData.clear();
state._songManifestData = null;
}
state.songMetadata.set(targetVariation, newSongMetadata);

View file

@ -53,7 +53,7 @@ class ChartEditorImportExportHandler
if (chartData != null) songChartData.set(variation, chartData);
}
loadSong(state, songMetadata, songChartData);
loadSong(state, songMetadata, songChartData, new ChartManifestData(songId));
state.sortChartData();
@ -113,10 +113,14 @@ class ChartEditorImportExportHandler
* @param newSongMetadata The song metadata to load.
* @param newSongChartData The song chart data to load.
*/
public static function loadSong(state:ChartEditorState, newSongMetadata:Map<String, SongMetadata>, newSongChartData:Map<String, SongChartData>):Void
public static function loadSong(state:ChartEditorState, newSongMetadata:Map<String, SongMetadata>, newSongChartData:Map<String, SongChartData>, ?newSongManifestData:ChartManifestData):Void
{
state.songMetadata = newSongMetadata;
state.songChartData = newSongChartData;
if (newSongManifestData != null)
{
state.songManifestData = newSongManifestData;
}
Conductor.instance.forceBPM(null); // Disable the forced BPM.
Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata.
@ -388,8 +392,7 @@ class ChartEditorImportExportHandler
if (state.audioInstTrackData != null) zipEntries = zipEntries.concat(state.makeZIPEntriesFromInstrumentals());
if (state.audioVocalTrackData != null) zipEntries = zipEntries.concat(state.makeZIPEntriesFromVocals());
var manifest:ChartManifestData = new ChartManifestData(state.currentSongId);
zipEntries.push(FileUtil.makeZIPEntry('manifest.json', manifest.serialize()));
zipEntries.push(FileUtil.makeZIPEntry('manifest.json', state.songManifestData.serialize()));
trace('Exporting ${zipEntries.length} files to ZIP...');

View file

@ -2,6 +2,7 @@ package funkin.ui.debug.charting.toolboxes;
import funkin.play.character.BaseCharacter.CharacterType;
import funkin.play.character.CharacterData;
import funkin.data.song.importer.ChartManifestData;
import funkin.data.stage.StageRegistry;
import funkin.ui.debug.charting.commands.ChangeStartingBPMCommand;
import funkin.ui.debug.charting.util.ChartEditorDropdowns;
@ -23,6 +24,7 @@ import haxe.ui.events.UIEvent;
@:build(haxe.ui.ComponentBuilder.build("assets/exclude/data/ui/chart-editor/toolboxes/metadata.xml"))
class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox
{
var inputSongId:TextField;
var inputSongName:TextField;
var inputSongArtist:TextField;
var inputSongCharter:TextField;
@ -58,6 +60,21 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox
this.x = 150;
this.y = 250;
inputSongId.onChange = function(event:UIEvent) {
var valid:Bool = event.target.text != null && event.target.text != '';
for (invalidChar in ChartManifestData.invalidIdChars) valid = valid && !event.target.text.contains(invalidChar);
if (valid)
{
inputSongId.removeClass('invalid-value');
chartEditorState.songManifestData.songId = event.target.text;
}
else
{
chartEditorState._songManifestData = null;
}
};
inputSongName.onChange = function(event:UIEvent) {
var valid:Bool = event.target.text != null && event.target.text != '';
@ -187,6 +204,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox
{
super.refresh();
inputSongId.value = chartEditorState.songManifestData.songId;
inputSongName.value = chartEditorState.currentSongMetadata.songName;
inputSongArtist.value = chartEditorState.currentSongMetadata.artist;
inputSongCharter.value = chartEditorState.currentSongMetadata.charter;