Cache character pictures and songs on disk
Character pictures are kept in characters/ next to the settings, with an index.json of when the server last changed each one and when it was downloaded. Only new or changed pictures are downloaded, using the server's new /character/details. Older servers fall back to the name list, and pictures are downloaded again after 7 days. Downloaded songs are written to songs/ and only their paths are kept in memory. The folder is emptied when the game starts and when the playlist resets.
This commit is contained in:
1 parent
62fa63fd8b
commit
240c331ab2
17 files changed
+912
-48
No files matched your search
+58
-3
@@ -3,6 +3,12 @@ extends Node
|
||||
## played, answered and playing.
|
||||
##
|
||||
## Registered as the [code]Playlist[/code] autoload.
|
||||
##
|
||||
## Downloaded songs are kept on disk in the [code]songs[/code] folder next to the
|
||||
## settings, not in memory. The folder only holds the current playlist: it is emptied when
|
||||
## the game starts and when the playlist is reset.
|
||||
|
||||
const SONGS_FOLDER_NAME: String = "songs"
|
||||
|
||||
var song_object_array: Array[SongObject] = []
|
||||
var latest_played_song: int = 0
|
||||
@@ -15,6 +21,18 @@ var is_song_downloading: bool = false
|
||||
## ended with Reset points.
|
||||
var game_start_song: int = 0
|
||||
|
||||
# How many song files have been written, so each gets a name of its own
|
||||
var _song_files_written: int = 0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
clear_song_files()
|
||||
|
||||
|
||||
## The folder downloaded songs are kept in.
|
||||
static func songs_folder() -> String:
|
||||
return Settings.config_dir().path_join(SONGS_FOLDER_NAME)
|
||||
|
||||
|
||||
func get_next_song() -> SongObject:
|
||||
return song_object_array[latest_played_song]
|
||||
@@ -73,6 +91,7 @@ func reset_playlist() -> void:
|
||||
latest_played_song = 0
|
||||
game_start_song = 0
|
||||
clear_song_list()
|
||||
clear_song_files()
|
||||
|
||||
|
||||
func clear_song_list() -> void:
|
||||
@@ -116,12 +135,48 @@ func remove_player_from_list(player_id: String) -> void:
|
||||
song_object.remove_point(player_id)
|
||||
|
||||
|
||||
## The song of [param song_no], read from its file. Returns null if the file is gone, so
|
||||
## the song can be downloaded again.
|
||||
func get_song(song_no: int) -> AudioStream:
|
||||
return song_object_array[song_no].song
|
||||
var song_object: SongObject = song_object_array[song_no]
|
||||
if song_object.song_path.is_empty():
|
||||
return song_object.song
|
||||
if !FileAccess.file_exists(song_object.song_path):
|
||||
return null
|
||||
return AudioStreamMP3.load_from_file(song_object.song_path)
|
||||
|
||||
|
||||
func add_song_to_song_object(song_no: int, sound: AudioStream) -> void:
|
||||
song_object_array[song_no].song = sound
|
||||
func add_song_to_song_object(song_no: int, mp3: PackedByteArray) -> void:
|
||||
store_song(song_object_array[song_no], mp3)
|
||||
|
||||
|
||||
## Keeps a downloaded song in a file in [method songs_folder]. If the file can't be
|
||||
## written, the song is kept in memory instead.
|
||||
func store_song(song_object: SongObject, mp3: PackedByteArray) -> void:
|
||||
DirAccess.make_dir_recursive_absolute(songs_folder())
|
||||
var path: String = songs_folder().path_join("song_%d.mp3" % _song_files_written)
|
||||
_song_files_written += 1
|
||||
var file: FileAccess = FileAccess.open(path, FileAccess.WRITE)
|
||||
if file == null:
|
||||
GameLog.warning("Could not save a song to ", path, ", keeping it in memory: ",
|
||||
error_string(FileAccess.get_open_error()))
|
||||
var sound: AudioStreamMP3 = AudioStreamMP3.new()
|
||||
sound.data = mp3
|
||||
song_object.song = sound
|
||||
song_object.song_path = ""
|
||||
return
|
||||
file.store_buffer(mp3)
|
||||
file.close()
|
||||
song_object.song = null
|
||||
song_object.song_path = path
|
||||
|
||||
|
||||
## Deletes the files of the songs downloaded so far.
|
||||
func clear_song_files() -> void:
|
||||
if !DirAccess.dir_exists_absolute(songs_folder()):
|
||||
return
|
||||
for file_name: String in DirAccess.get_files_at(songs_folder()):
|
||||
DirAccess.remove_absolute(songs_folder().path_join(file_name))
|
||||
|
||||
|
||||
func song_has_played(song_no: int = latest_played_song) -> void:
|
||||
|
||||
@@ -12,6 +12,10 @@ var players_given_point: Array[String] = []
|
||||
var is_answered: bool = false
|
||||
var has_played: bool = false
|
||||
var is_playing: bool = false
|
||||
## The song's file in [method Playlist.songs_folder]. Read the song with
|
||||
## [method Playlist.get_song].
|
||||
var song_path: String = ""
|
||||
## The song itself, only when it could not be saved to a file.
|
||||
var song: AudioStream
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user