218 lines
7.4 KiB
GDScript
218 lines
7.4 KiB
GDScript
#extends Object
|
|
extends Node
|
|
var FileHelpers := preload('res://scripts/FileHelpers.gd')
|
|
|
|
var RGT := preload('res://formats/RGT.gd')
|
|
var SM := preload('res://formats/SM.gd')
|
|
var SRT := preload('res://formats/SRT.gd')
|
|
|
|
const NOT_FOUND := ''
|
|
|
|
const default_difficulty_keys = ['Z', 'B', 'A', 'E', 'M', 'R']
|
|
|
|
var userroot := OS.get_user_data_dir().rstrip('/')+'/' if OS.get_name() != 'Android' else '/storage/emulated/0/RhythmGame/'
|
|
var PATHS := PoolStringArray([userroot, '/media/fridge-q/Games/RTG/slow_userdir/']) # Temporary hardcoded testing
|
|
# The following would probably work. One huge caveat is that permission needs to be manually granted by the user in app settings as we can't use OS.request_permission('WRITE_EXTERNAL_STORAGE')
|
|
# '/storage/emulated/0/Android/data/au.ufeff.rhythmgame/'
|
|
# '/sdcard/Android/data/au.ufeff.rhythmgame/'
|
|
func _ready() -> void:
|
|
print('Library paths: ', PATHS)
|
|
|
|
|
|
func find_file(name: String, print_notfound:=false) -> String:
|
|
# Searches through all of the paths to find the file
|
|
var file := File.new()
|
|
for root in PATHS:
|
|
var filename: String = root + name
|
|
if file.file_exists(filename):
|
|
return filename
|
|
if print_notfound:
|
|
print('File not found in any libraries: ', name)
|
|
return NOT_FOUND
|
|
|
|
|
|
var fallback_audiostream: AudioStream = AudioStreamOGGVorbis.new()
|
|
var fallback_videostream: VideoStream = VideoStreamWebm.new()
|
|
var fallback_texture := ImageTexture.new()
|
|
|
|
func load_ogg(name: String) -> AudioStream: # Searches through all of the paths to find the file
|
|
match find_file(name):
|
|
NOT_FOUND: return fallback_audiostream
|
|
var filename: return FileHelpers.load_ogg(filename)
|
|
|
|
func load_video(name: String) -> VideoStream: # Searches through all of the paths to find the file
|
|
match find_file(name):
|
|
NOT_FOUND: return fallback_videostream
|
|
var filename: return FileHelpers.load_video(filename)
|
|
|
|
func load_image(name: String) -> ImageTexture: # Searches through all of the paths to find the file
|
|
match find_file(name, true):
|
|
NOT_FOUND: return fallback_texture
|
|
var filename: return FileHelpers.load_image(filename)
|
|
|
|
|
|
func scan_library() -> Dictionary:
|
|
print('Scanning library')
|
|
var song_defs = {}
|
|
var collections = {}
|
|
var genres = {}
|
|
|
|
for root in PATHS:
|
|
var rootdir = root + 'songs'
|
|
var dir = Directory.new()
|
|
var err = dir.make_dir_recursive(rootdir)
|
|
if err != OK:
|
|
print_debug('An error occurred while trying to create the songs directory: ', err)
|
|
return err
|
|
|
|
var songslist = FileHelpers.directory_list(rootdir, false)
|
|
if songslist.err != OK:
|
|
print('An error occurred when trying to access the songs directory: ', songslist.err)
|
|
return songslist.err
|
|
|
|
dir.open(rootdir)
|
|
for folder in songslist.folders:
|
|
var full_folder := '%s/%s' % [rootdir, folder]
|
|
|
|
if dir.file_exists(folder + '/song.json'):
|
|
# Our format
|
|
song_defs[folder] = FileLoader.load_folder(full_folder)
|
|
print('Loaded song directory: %s' % folder)
|
|
if song_defs[folder]['genre'] in genres:
|
|
genres[song_defs[folder]['genre']].append(folder)
|
|
else:
|
|
genres[song_defs[folder]['genre']] = [folder]
|
|
if typeof(song_defs[folder]['chart_difficulties']) == TYPE_ARRAY:
|
|
var diffs = song_defs[folder]['chart_difficulties']
|
|
var chart_difficulties = {}
|
|
for i in min(len(diffs), len(default_difficulty_keys)):
|
|
chart_difficulties[default_difficulty_keys[i]] = diffs[i]
|
|
song_defs[folder]['chart_difficulties'] = chart_difficulties
|
|
|
|
elif dir.file_exists(folder + '/collection.json'):
|
|
var collection = FileLoader.load_folder(full_folder, 'collection')
|
|
collections[folder] = collection
|
|
var base_dict = {'filepath': folder+'/'} # Top level of the collection dict contains defaults for every song in it
|
|
for key in collection.keys():
|
|
if key != 'songs':
|
|
base_dict[key] = collection[key]
|
|
for song_key in collection['songs'].keys():
|
|
var song_dict = collection['songs'][song_key]
|
|
var song_def = base_dict.duplicate()
|
|
for key in song_dict.keys():
|
|
song_def[key] = song_dict[key]
|
|
Library.add_song(song_key, song_def)
|
|
# Legacy compat stuff
|
|
song_defs[song_key] = song_def
|
|
if song_defs[song_key]['genre'] in genres:
|
|
genres[song_defs[song_key]['genre']].append(song_key)
|
|
else:
|
|
genres[song_defs[song_key]['genre']] = [song_key]
|
|
|
|
else:
|
|
var files_by_ext = FileHelpers.find_by_extensions(FileHelpers.directory_list(full_folder, false).files)
|
|
if 'sm' in files_by_ext:
|
|
var sm_filename = files_by_ext['sm'][0]
|
|
print(sm_filename)
|
|
var thing = SM.load_file(full_folder + '/' + sm_filename)
|
|
print(thing)
|
|
pass
|
|
else:
|
|
print('Found non-song directory: ' + folder)
|
|
for file in songslist.files:
|
|
print('Found file: ' + file)
|
|
|
|
return {song_defs=song_defs, genres=genres}
|
|
|
|
|
|
func load_folder(folder, filename='song'):
|
|
var file = File.new()
|
|
var err = file.open('%s/%s.json' % [folder, filename], File.READ)
|
|
if err != OK:
|
|
print(err)
|
|
return err
|
|
var result_json = JSON.parse(file.get_as_text())
|
|
file.close()
|
|
if result_json.error != OK:
|
|
print('Error: ', result_json.error)
|
|
print('Error Line: ', result_json.error_line)
|
|
print('Error String: ', result_json.error_string)
|
|
return result_json.error
|
|
var result = result_json.result
|
|
result.directory = folder
|
|
return result
|
|
|
|
|
|
func load_filelist(filelist: Array, directory=''):
|
|
var charts = {}
|
|
var key := 0
|
|
for name in filelist:
|
|
var extension: String = name.rsplit('.', true, 1)[-1]
|
|
name = directory.rstrip('/') + '/' + name
|
|
var filename = find_file(name)
|
|
if filename != NOT_FOUND:
|
|
match extension:
|
|
'rgtm': # multiple charts
|
|
var res = RGT.load_file(filename)
|
|
for k in res:
|
|
charts[Library.difficulty_translations.get(k, k)] = res[k]
|
|
'rgts', 'rgtx': # single chart - The keys for this should be translated afterwards
|
|
charts[key] = RGT.load_file(filename)
|
|
key += 1
|
|
'srt': # maimai, single chart
|
|
var metadata_and_notes = SRT.load_file(filename)
|
|
Note.process_note_list(metadata_and_notes[1]) # SRT doesn't handle doubles
|
|
charts[key] = metadata_and_notes
|
|
key += 1
|
|
'sm': # Stepmania, multiple charts
|
|
var res = SM.load_file(filename)
|
|
for chart in res[1]:
|
|
var diff = chart.difficulty_str
|
|
charts[diff] = chart.notes
|
|
_:
|
|
pass
|
|
return charts
|
|
|
|
|
|
func save_json(filename: String, data: Dictionary):
|
|
filename = userroot + filename
|
|
var dir = filename.rsplit('/', true, 1)[0]
|
|
match FileHelpers.init_directory(dir):
|
|
OK:
|
|
pass
|
|
var err:
|
|
print_debug('Error making directory for JSON file: ', err, FileHelpers.ERROR_CODES[err])
|
|
return err
|
|
var json = JSON.print(data)
|
|
var file = File.new()
|
|
match file.open(filename, File.WRITE):
|
|
OK:
|
|
file.store_string(json)
|
|
file.close()
|
|
return OK
|
|
var err:
|
|
print_debug('Error saving JSON file: ', err, FileHelpers.ERROR_CODES[err])
|
|
return err
|
|
|
|
|
|
func load_json(filename: String):
|
|
var file = File.new()
|
|
var err
|
|
for root in PATHS:
|
|
var filename1 = root + filename
|
|
if file.file_exists(filename1):
|
|
err = file.open(filename1, File.READ)
|
|
if err != OK:
|
|
print('An error occurred while trying to open file: ', filename1, err, FileHelpers.ERROR_CODES[err])
|
|
continue # return err
|
|
var result_json = JSON.parse(file.get_as_text())
|
|
file.close()
|
|
if result_json.error != OK:
|
|
print('Error: ', result_json.error)
|
|
print('Error Line: ', result_json.error_line)
|
|
print('Error String: ', result_json.error_string)
|
|
return result_json.error
|
|
return result_json.result
|
|
print('File not found in any libraries: ', filename)
|
|
return ERR_FILE_NOT_FOUND
|