Files
infinitefusion-e18/Data/Scripts/002_Save data/001_SaveData.rb

99 lines
3.4 KiB
Ruby

#===============================================================================
# The SaveData module is used to manipulate save data. It contains the {Value}s
# that make up the save data and {Conversion}s for resolving incompatibilities
# between Essentials and game versions.
# @see SaveData.register
# @see SaveData.register_conversion
#===============================================================================
module SaveData
DIRECTORY = (File.directory?(System.data_directory)) ? System.data_directory : "./"
FILENAME_REGEX = /Game(\d*)\.rxdata$/
# @return [Boolean] whether any save files exist
def self.exists?
return !all_save_files.empty?
end
# @return[Array] array of filenames in the save folder that are save files
def self.all_save_files
files = Dir.get(DIRECTORY, "*", false)
ret = []
files.each do |file|
next if !file[FILENAME_REGEX]
ret.push([$~[1].to_i, file])
end
ret.sort! { |a, b| a[0] <=> b[0] }
ret.map! { |val| val[1] }
return ret
end
# Fetches the save data from the given file.
# Returns an Array in the case of a pre-v19 save file.
# @param file_path [String] path of the file to load from
# @return [Hash, Array] loaded save data
# @raise [IOError, SystemCallError] if file opening fails
def self.get_data_from_file(file_path)
validate file_path => String
save_data = nil
File.open(file_path) do |file|
data = Marshal.load(file)
if data.is_a?(Hash)
save_data = data
next
end
save_data = [data]
save_data << Marshal.load(file) until file.eof?
end
return save_data
end
# Fetches save data from the given file. If it needed converting, resaves it.
# @param file_path [String] path of the file to read from
# @return [Hash] save data in Hash format
# @raise (see .get_data_from_file)
def self.read_from_file(file_path)
validate file_path => String
save_data = get_data_from_file(file_path)
save_data = to_hash_format(save_data) if save_data.is_a?(Array) # Pre-v19 save file support
if !save_data.empty? && run_conversions(save_data)
File.open(file_path, "wb") { |file| Marshal.dump(save_data, file) }
end
return save_data
end
# Compiles the save data and saves a marshaled version of it into
# the given file.
# @param file_path [String] path of the file to save into
# @raise [InvalidValueError] if an invalid value is being saved
def self.save_to_file(file_path)
validate file_path => String
save_data = self.compile_save_hash
File.open(file_path, "wb") { |file| Marshal.dump(save_data, file) }
end
# Deletes the save file (and a possible .bak backup file if one exists)
# @raise [Error::ENOENT]
def self.delete_file(filename)
File.delete(DIRECTORY + filename)
File.delete(DIRECTORY + filename + ".bak") if File.file?(DIRECTORY + filename + ".bak")
end
def self.filename_from_index(index = 0)
return "Game.rxdata" if index <= 0
return "Game#{index}.rxdata"
end
# Converts the pre-v19 format data to the new format.
# @param old_format [Array] pre-v19 format save data
# @return [Hash] save data in new format
def self.to_hash_format(old_format)
validate old_format => Array
hash = {}
@values.each do |value|
data = value.get_from_old_format(old_format)
hash[value.id] = data unless data.nil?
end
return hash
end
end