rgss_db 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/COPYING.md +674 -0
- data/README.md +347 -0
- data/bin/rgss-db +4 -0
- data/bin/rgssdb +4 -0
- data/lib/rgss_db/app.rb +928 -0
- data/lib/rgss_db/controller/data_manager.rb +557 -0
- data/lib/rgss_db/model/data_file.rb +516 -0
- data/lib/rgss_db/model/data_file_factory.rb +94 -0
- data/lib/rgss_db/model/debug.rb +199 -0
- data/lib/rgss_db/model/errors.rb +17 -0
- data/lib/rgss_db/model/mixins/jsonable.rb +35 -0
- data/lib/rgss_db/model/mixins/jsonable_constructor.rb +40 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rgss/color.rb +72 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rgss/rect.rb +70 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rgss/table.rb +99 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rgss/tone.rb +72 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rgss.rb +11 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/actor.rb +44 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/animation.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/animation_frame.rb +20 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/animation_timing.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/area.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/armor.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/audio_file.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/base_item.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/bgm.rb +36 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/bgs.rb +36 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/class.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/class_learning.rb +20 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/common_event.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/enemy.rb +44 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/enemy_action.rb +29 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/enemy_drop_item.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event.rb +36 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_command.rb +19 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_page.rb +32 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_page_condition.rb +34 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/event_page_graphic.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/item.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/map.rb +47 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/map_info.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/me.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/move_command.rb +18 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/move_route.rb +20 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/se.rb +21 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/skill.rb +22 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/state.rb +47 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system.rb +43 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system_terms.rb +53 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system_test_battler.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/system_vehicle.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop_member.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop_page.rb +21 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/troop_page_condition.rb +33 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/usable_item.rb +87 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg/weapon.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx/rpg.rb +59 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/color.rb +72 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/rect.rb +70 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/table.rb +99 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss/tone.rb +72 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rgss.rb +11 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/actor.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/animation.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/animation_frame.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/animation_timing.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/armor.rb +20 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/audio_file.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/base_item.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/base_item_feature.rb +29 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/bgm.rb +43 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/bgs.rb +43 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/class.rb +37 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/class_learning.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/common_event.rb +33 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/enemy.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/enemy_action.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/enemy_drop_item.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/equip_item.rb +19 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event.rb +36 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_command.rb +19 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_page.rb +35 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_page_condition.rb +40 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/event_page_graphic.rb +31 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/item.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/map.rb +58 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/map_encounter.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/map_info.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/me.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/move_command.rb +17 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/move_route.rb +19 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/se.rb +21 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/skill.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/state.rb +34 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system.rb +62 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system_terms.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system_test_battler.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/system_vehicle.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/tileset.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop_member.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop_page.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/troop_page_condition.rb +39 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/usable_item.rb +84 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/usable_item_damage.rb +56 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/usable_item_effect.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg/weapon.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/vx_ace/rpg.rb +66 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rgss/color.rb +72 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rgss/rect.rb +70 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rgss/table.rb +99 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rgss/tone.rb +72 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rgss.rb +11 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/actor.rb +44 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/animation.rb +28 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/animation_frame.rb +20 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/animation_timing.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/armor.rb +37 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/audio_file.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/class.rb +28 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/class_learning.rb +20 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/common_event.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/enemy.rb +47 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/enemy_action.rb +28 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event.rb +36 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_command.rb +19 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_page.rb +32 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_page_condition.rb +30 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/event_page_graphic.rb +27 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/item.rb +48 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/map.rb +39 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/map_info.rb +26 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/move_command.rb +18 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/move_route.rb +19 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/skill.rb +47 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/state.rb +51 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/system.rb +56 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/system_test_battler.rb +25 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/system_words.rb +39 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/tileset.rb +39 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop.rb +24 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop_member.rb +23 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop_page.rb +21 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/troop_page_condition.rb +32 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg/weapon.rb +38 -0
- data/lib/rgss_db/model/rpg_maker_data/xp/rpg.rb +52 -0
- data/lib/rgss_db/model/strings.rb +607 -0
- data/lib/rgss_db/model/utilities.rb +90 -0
- data/lib/rgss_db/version.rb +7 -0
- data/lib/rgss_db/view/app_cli.rb +449 -0
- data/lib/rgss_db.rb +41 -0
- data/sig/rgss_db.rbs +5221 -0
- metadata +496 -0
data/lib/rgss_db/app.rb
ADDED
|
@@ -0,0 +1,928 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "./version"
|
|
4
|
+
require_relative "./model/errors"
|
|
5
|
+
require_relative "./model/debug"
|
|
6
|
+
require_relative "./model/strings"
|
|
7
|
+
require_relative "./model/utilities"
|
|
8
|
+
require_relative "./view/app_cli"
|
|
9
|
+
require_relative "./controller/data_manager"
|
|
10
|
+
|
|
11
|
+
module RgssDb
|
|
12
|
+
# App option debug mode
|
|
13
|
+
# @return [Symbol]
|
|
14
|
+
APP_OPTION_DEBUG_MODE = :debug
|
|
15
|
+
|
|
16
|
+
# App option back up flag
|
|
17
|
+
# @return [Symbol]
|
|
18
|
+
APP_OPTION_BACK_UP = :backup
|
|
19
|
+
|
|
20
|
+
# App option action type
|
|
21
|
+
# @return [Symbol]
|
|
22
|
+
APP_OPTION_ACTION = :action
|
|
23
|
+
|
|
24
|
+
# App option file entries
|
|
25
|
+
# @return [Symbol]
|
|
26
|
+
APP_OPTION_FILE_ENTRIES = :files
|
|
27
|
+
|
|
28
|
+
# App option object ids
|
|
29
|
+
# @return [Symbol]
|
|
30
|
+
APP_OPTION_IDS = :ids
|
|
31
|
+
|
|
32
|
+
# App option format
|
|
33
|
+
# @return [Symbol]
|
|
34
|
+
APP_OPTION_FORMAT_TYPE = :type
|
|
35
|
+
|
|
36
|
+
# App option working directory
|
|
37
|
+
# @return [Symbol]
|
|
38
|
+
APP_OPTION_WORKING_DIR = :directory
|
|
39
|
+
|
|
40
|
+
# Export data action command name
|
|
41
|
+
#
|
|
42
|
+
# This action exports all binary files into external files
|
|
43
|
+
# @return [String]
|
|
44
|
+
APP_ACTION_EXPORT = "export"
|
|
45
|
+
|
|
46
|
+
# Export custom data action command name
|
|
47
|
+
#
|
|
48
|
+
# This action exports the supported binary files custom objects into external files
|
|
49
|
+
# @return [String]
|
|
50
|
+
APP_ACTION_EXPORT_CUSTOM = "export_custom"
|
|
51
|
+
|
|
52
|
+
# Import data action command name
|
|
53
|
+
#
|
|
54
|
+
# This action imports external files into binary files
|
|
55
|
+
# @return [String]
|
|
56
|
+
APP_ACTION_IMPORT = "import"
|
|
57
|
+
|
|
58
|
+
# Import custom data action command name
|
|
59
|
+
#
|
|
60
|
+
# This action imports external custom data files into their appropiate binary files
|
|
61
|
+
# @return [String]
|
|
62
|
+
APP_ACTION_IMPORT_CUSTOM = "import_custom"
|
|
63
|
+
|
|
64
|
+
# Default back up mode of the application
|
|
65
|
+
# @return [Boolean]
|
|
66
|
+
APP_DEFAULT_BACK_UP = true
|
|
67
|
+
|
|
68
|
+
# Default debug mode of the application
|
|
69
|
+
# @return [Integer]
|
|
70
|
+
APP_DEFAULT_DEBUG_MODE = 0
|
|
71
|
+
|
|
72
|
+
# Default file format type for the application
|
|
73
|
+
# @return [String]
|
|
74
|
+
APP_DEFAULT_FORMAT_TYPE = "YAML"
|
|
75
|
+
|
|
76
|
+
# Default working directory for the application
|
|
77
|
+
# @return [String]
|
|
78
|
+
APP_DEFAULT_WORKING_DIR = "./rgss-db"
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# Application class
|
|
82
|
+
#
|
|
83
|
+
class App
|
|
84
|
+
include Strings
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# Creates a new app instance
|
|
88
|
+
#
|
|
89
|
+
# @param data_path [String] RPG Maker database folder
|
|
90
|
+
# @param options [Hash<Symbol, Object>] App options hash
|
|
91
|
+
#
|
|
92
|
+
def initialize(data_path, options)
|
|
93
|
+
@options = process_options(options)
|
|
94
|
+
@data_manager = DataManager.new(data_path)
|
|
95
|
+
@cli = AppCli.new(
|
|
96
|
+
data_folder: @data_manager.path,
|
|
97
|
+
rgss_version: @data_manager.rgss_version,
|
|
98
|
+
app_version: RgssDb::VERSION
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Starts the app
|
|
104
|
+
#
|
|
105
|
+
def start
|
|
106
|
+
# Checks for debug usage to start the module or not
|
|
107
|
+
unless Debug.disabled?
|
|
108
|
+
debug_path = File.expand_path(opt_working_dir, @data_manager.path)
|
|
109
|
+
Debug.start(debug_path)
|
|
110
|
+
Debug.update_extra_info(@data_manager.path, @data_manager.rgss_version)
|
|
111
|
+
Debug.write_debug_header
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Start application logic
|
|
115
|
+
begin
|
|
116
|
+
if opt_action
|
|
117
|
+
# An action was given, avoid main menu loop
|
|
118
|
+
Debug.log_info("bypassing app menu")
|
|
119
|
+
|
|
120
|
+
# Logs current options
|
|
121
|
+
Debug.log_info("options: #{@options}")
|
|
122
|
+
|
|
123
|
+
# Creates the data files instances
|
|
124
|
+
data_files = []
|
|
125
|
+
case opt_action
|
|
126
|
+
when APP_ACTION_EXPORT
|
|
127
|
+
data_files = @data_manager.load_database_files
|
|
128
|
+
|
|
129
|
+
# Checks if user selected specific file entries
|
|
130
|
+
unless opt_file_entries.empty?
|
|
131
|
+
data_files = data_files.keep_if do |data_file|
|
|
132
|
+
opt_file_entries.any? { |entry| data_file.file?(entry) }
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
when APP_ACTION_EXPORT_CUSTOM
|
|
136
|
+
data_files = @data_manager.load_database_files.keep_if(&:customizable?)
|
|
137
|
+
|
|
138
|
+
# Checks if user selected specific file entries
|
|
139
|
+
unless opt_file_entries.empty?
|
|
140
|
+
data_files = data_files.keep_if do |data_file|
|
|
141
|
+
opt_file_entries.any? { |entry| data_file.file?(entry) }
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Applies any possible object IDs list for each file entry
|
|
146
|
+
data_files.each do |data_file|
|
|
147
|
+
data_file.object_ids_update(*opt_file_object_ids(data_file.file))
|
|
148
|
+
end
|
|
149
|
+
when APP_ACTION_IMPORT
|
|
150
|
+
data_files = @data_manager.load_extracted_files(opt_working_dir)
|
|
151
|
+
|
|
152
|
+
# Checks if user selected specific file entries
|
|
153
|
+
unless opt_file_entries.empty?
|
|
154
|
+
data_files = data_files.keep_if do |data_file|
|
|
155
|
+
opt_file_entries.any? { |entry| data_file.file?(entry) }
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
when APP_ACTION_IMPORT_CUSTOM
|
|
159
|
+
data_files = @data_manager.load_extracted_files_custom(opt_working_dir).keep_if(&:mergeable?)
|
|
160
|
+
|
|
161
|
+
# Checks if user selected specific file entries
|
|
162
|
+
unless opt_file_entries.empty?
|
|
163
|
+
data_files = data_files.keep_if do |data_file|
|
|
164
|
+
opt_file_entries.any? { |entry| data_file.file?(entry) }
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Perform the action for each data file created
|
|
170
|
+
data_files.each { |data_file| do_action(opt_action, data_file) }
|
|
171
|
+
else
|
|
172
|
+
# No action given, run the app main menu loop
|
|
173
|
+
Debug.log_info("running app menu")
|
|
174
|
+
menu_main
|
|
175
|
+
end
|
|
176
|
+
rescue Error => e
|
|
177
|
+
# Application error
|
|
178
|
+
Debug.log_exception(e, @options)
|
|
179
|
+
@cli.draw_empty_line
|
|
180
|
+
@cli.draw_error(e.message)
|
|
181
|
+
@cli.draw_empty_line
|
|
182
|
+
@cli.prompt_pause
|
|
183
|
+
retry
|
|
184
|
+
rescue StandardError => e
|
|
185
|
+
# Unknown error
|
|
186
|
+
Debug.log_exception(e, @options)
|
|
187
|
+
raise e
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
private
|
|
192
|
+
|
|
193
|
+
#
|
|
194
|
+
# Process the user options
|
|
195
|
+
#
|
|
196
|
+
# @param options_hash [Hash<Symbol, Object>] Options hash
|
|
197
|
+
#
|
|
198
|
+
# @return [Hash<Symbol, Object>]
|
|
199
|
+
#
|
|
200
|
+
def process_options(options_hash)
|
|
201
|
+
options = {}
|
|
202
|
+
options_hash.each_pair do |option_id, option_value|
|
|
203
|
+
case option_id
|
|
204
|
+
when APP_OPTION_DEBUG_MODE
|
|
205
|
+
# Process the debug mode
|
|
206
|
+
debug_mode_id = option_value.to_s.to_i # to 0 if invalid int
|
|
207
|
+
options.store(option_id, debug_mode_id)
|
|
208
|
+
Debug.update_debug_mode(debug_mode_id)
|
|
209
|
+
when APP_OPTION_ACTION
|
|
210
|
+
# Process the action option (case insensitive)
|
|
211
|
+
action = option_value.to_s
|
|
212
|
+
if action.casecmp?(APP_ACTION_IMPORT)
|
|
213
|
+
options.store(option_id, APP_ACTION_IMPORT)
|
|
214
|
+
elsif action.casecmp?(APP_ACTION_IMPORT_CUSTOM)
|
|
215
|
+
options.store(option_id, APP_ACTION_IMPORT_CUSTOM)
|
|
216
|
+
elsif action.casecmp?(APP_ACTION_EXPORT)
|
|
217
|
+
options.store(option_id, APP_ACTION_EXPORT)
|
|
218
|
+
elsif action.casecmp?(APP_ACTION_EXPORT_CUSTOM)
|
|
219
|
+
options.store(option_id, APP_ACTION_EXPORT_CUSTOM)
|
|
220
|
+
else
|
|
221
|
+
# Unknown action value
|
|
222
|
+
options.store(option_id, nil)
|
|
223
|
+
end
|
|
224
|
+
when APP_OPTION_FORMAT_TYPE
|
|
225
|
+
# Process the output file format option (case insensitive)
|
|
226
|
+
type = option_value.to_s.downcase.to_sym
|
|
227
|
+
case type
|
|
228
|
+
when RGSS_FORMAT_TYPE_BINARY
|
|
229
|
+
options.store(option_id, RGSS_FORMAT_TYPE_BINARY)
|
|
230
|
+
when RGSS_FORMAT_TYPE_JSON
|
|
231
|
+
options.store(option_id, RGSS_FORMAT_TYPE_JSON)
|
|
232
|
+
when RGSS_FORMAT_TYPE_YAML
|
|
233
|
+
options.store(option_id, RGSS_FORMAT_TYPE_YAML)
|
|
234
|
+
else
|
|
235
|
+
options.store(option_id, APP_DEFAULT_FORMAT_TYPE)
|
|
236
|
+
end
|
|
237
|
+
when APP_OPTION_WORKING_DIR
|
|
238
|
+
# Process the working directory option
|
|
239
|
+
path = Utilities.valid_path?(option_value) ? option_value : APP_DEFAULT_WORKING_DIR
|
|
240
|
+
options.store(option_id, path)
|
|
241
|
+
when APP_OPTION_FILE_ENTRIES
|
|
242
|
+
# Process the list of pre-selected file entries option
|
|
243
|
+
options.store(option_id, option_value || [])
|
|
244
|
+
when APP_OPTION_IDS
|
|
245
|
+
# Process the list of pre-selected object IDs per file entry option
|
|
246
|
+
options.store(option_id, {})
|
|
247
|
+
# Populate the hash based on the given file entries list
|
|
248
|
+
(options_hash[APP_OPTION_FILE_ENTRIES] || []).each_with_index do |file, index|
|
|
249
|
+
id_list = option_value.at(index)
|
|
250
|
+
options[option_id].store(file, id_list) unless id_list.nil?
|
|
251
|
+
end
|
|
252
|
+
else
|
|
253
|
+
# Option does not need treatment
|
|
254
|
+
options.store(option_id, option_value)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
options
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
#
|
|
261
|
+
# Gets the user's backup flag
|
|
262
|
+
#
|
|
263
|
+
# @return [Boolean]
|
|
264
|
+
#
|
|
265
|
+
def opt_backup_allowed
|
|
266
|
+
@options[APP_OPTION_BACK_UP]
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
#
|
|
270
|
+
# Gets the user's action option
|
|
271
|
+
#
|
|
272
|
+
# @return [Symbol]
|
|
273
|
+
#
|
|
274
|
+
def opt_action
|
|
275
|
+
@options[APP_OPTION_ACTION]
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
#
|
|
279
|
+
# Gets the user's file format type option
|
|
280
|
+
#
|
|
281
|
+
# @return [String]
|
|
282
|
+
#
|
|
283
|
+
def opt_format_type
|
|
284
|
+
@options[APP_OPTION_FORMAT_TYPE]
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
#
|
|
288
|
+
# Gets the user's working directory option
|
|
289
|
+
#
|
|
290
|
+
# @return [String]
|
|
291
|
+
#
|
|
292
|
+
def opt_working_dir
|
|
293
|
+
@options[APP_OPTION_WORKING_DIR]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
#
|
|
297
|
+
# Gets the user's file entries option
|
|
298
|
+
#
|
|
299
|
+
# @return [Array<String>]
|
|
300
|
+
#
|
|
301
|
+
def opt_file_entries
|
|
302
|
+
@options[APP_OPTION_FILE_ENTRIES]
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
#
|
|
306
|
+
# Gets the user's hash of object IDs and file entries
|
|
307
|
+
#
|
|
308
|
+
# @return [Hash<String, Array<Integer>>]
|
|
309
|
+
#
|
|
310
|
+
def opt_object_ids
|
|
311
|
+
@options[APP_OPTION_IDS]
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
#
|
|
315
|
+
# Gets the user's object IDs option
|
|
316
|
+
#
|
|
317
|
+
# @param file_name [String] File entry
|
|
318
|
+
#
|
|
319
|
+
# @return [Array<Integer>]
|
|
320
|
+
#
|
|
321
|
+
def opt_file_object_ids(file_name)
|
|
322
|
+
opt_object_ids.each_pair do |file, object_ids|
|
|
323
|
+
return object_ids if file.casecmp?(file_name)
|
|
324
|
+
end
|
|
325
|
+
[]
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
#
|
|
329
|
+
# Performs the action by ``action_name`` with the given data file
|
|
330
|
+
#
|
|
331
|
+
# @param action_name [String] Action
|
|
332
|
+
# @param data_file [DataFile] Data file
|
|
333
|
+
#
|
|
334
|
+
# @raise [StandardError]
|
|
335
|
+
#
|
|
336
|
+
def do_action(action_name, data_file)
|
|
337
|
+
case action_name
|
|
338
|
+
when APP_ACTION_EXPORT
|
|
339
|
+
Debug.log_info("exporting: #{data_file} (#{data_file.serialize_file_name})")
|
|
340
|
+
@data_manager.save_data_file(data_file, opt_working_dir, opt_format_type)
|
|
341
|
+
Debug.log_info("exporting action finished!")
|
|
342
|
+
when APP_ACTION_EXPORT_CUSTOM
|
|
343
|
+
Debug.log_info("exporting (custom): #{data_file} (#{data_file.serialize_file_name})")
|
|
344
|
+
@data_manager.save_data_file(data_file, opt_working_dir, opt_format_type)
|
|
345
|
+
Debug.log_info("exporting (custom) action finished!")
|
|
346
|
+
when APP_ACTION_IMPORT
|
|
347
|
+
Debug.log_info("importing: #{data_file} (#{data_file.serialize_file_name})")
|
|
348
|
+
|
|
349
|
+
# Checks if the data file is a "full file" to avoid data loss, this error
|
|
350
|
+
# should never trigger since data_file should have all objects selected
|
|
351
|
+
# at this point for import (hardcoded), but it exists as a security measure
|
|
352
|
+
raise "trying to import an incompleted data file: #{data_file.inspect}" unless data_file.all_objects?
|
|
353
|
+
|
|
354
|
+
# Performs a back up creation (if allowed)
|
|
355
|
+
if opt_backup_allowed
|
|
356
|
+
Debug.log_info("creating back up file...")
|
|
357
|
+
@data_manager.save_database_back_up(data_file.file, opt_working_dir)
|
|
358
|
+
Debug.log_info("back up created")
|
|
359
|
+
else
|
|
360
|
+
Debug.log_info("back up creation is disabled!")
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# Performs the import process
|
|
364
|
+
@data_manager.save_data_file(data_file, @data_manager.path, RGSS_FORMAT_TYPE_BINARY)
|
|
365
|
+
Debug.log_info("importing action finished!")
|
|
366
|
+
when APP_ACTION_IMPORT_CUSTOM
|
|
367
|
+
Debug.log("importing (custom): #{data_file} (#{data_file.serialize_file_name})")
|
|
368
|
+
database_file = @data_manager.load_database_file(data_file.type)
|
|
369
|
+
|
|
370
|
+
# Performs a back up creation (if allowed)
|
|
371
|
+
if opt_backup_allowed
|
|
372
|
+
Debug.log_info("creating back up file...")
|
|
373
|
+
@data_manager.save_database_back_up(database_file.file, opt_working_dir)
|
|
374
|
+
Debug.log_info("back up created")
|
|
375
|
+
else
|
|
376
|
+
Debug.log_info("back up creation is disabled!")
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Merges data file contents
|
|
380
|
+
database_file.merge(data_file)
|
|
381
|
+
|
|
382
|
+
# Saves the result of the merge operation
|
|
383
|
+
@data_manager.save_data_file(database_file, @data_manager.path, RGSS_FORMAT_TYPE_BINARY)
|
|
384
|
+
Debug.log_info("importing (custom) action finished!")
|
|
385
|
+
else
|
|
386
|
+
raise "action called with an unknown action name: '#{action_name}'"
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
#
|
|
391
|
+
# Main menu process
|
|
392
|
+
#
|
|
393
|
+
def menu_main
|
|
394
|
+
loop do
|
|
395
|
+
@cli.draw_app_menu(
|
|
396
|
+
StrMenuContents::APP_MENU_MAIN_MENU_TEXT_INFO,
|
|
397
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU]
|
|
398
|
+
)
|
|
399
|
+
option = @cli.prompt_select(
|
|
400
|
+
StrMenu::APP_MENU_ACTIONS,
|
|
401
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
402
|
+
StrMenu::APP_MENU_EXIT
|
|
403
|
+
)
|
|
404
|
+
case option
|
|
405
|
+
when StrMenu::APP_MENU_ACTIONS
|
|
406
|
+
menu_actions
|
|
407
|
+
when StrMenu::APP_MENU_OPTIONS
|
|
408
|
+
menu_options
|
|
409
|
+
when StrMenu::APP_MENU_EXIT
|
|
410
|
+
submenu_exit
|
|
411
|
+
break
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
#
|
|
417
|
+
# Perform actions menu process
|
|
418
|
+
#
|
|
419
|
+
def menu_actions
|
|
420
|
+
loop do
|
|
421
|
+
@cli.draw_app_menu(
|
|
422
|
+
StrMenuContents::APP_MENU_ACTIONS_TEXT_INFO,
|
|
423
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU, StrMenu::APP_MENU_ACTIONS]
|
|
424
|
+
)
|
|
425
|
+
option = @cli.prompt_select(
|
|
426
|
+
StrMenu::APP_MENU_ACTIONS_EXPORT,
|
|
427
|
+
StrMenu::APP_MENU_ACTIONS_EXPORT_CUSTOM,
|
|
428
|
+
StrMenu::APP_MENU_ACTIONS_IMPORT,
|
|
429
|
+
StrMenu::APP_MENU_ACTIONS_IMPORT_CUSTOM,
|
|
430
|
+
StrMenu::APP_MENU_EXIT
|
|
431
|
+
)
|
|
432
|
+
case option
|
|
433
|
+
when StrMenu::APP_MENU_ACTIONS_EXPORT
|
|
434
|
+
submenu_export
|
|
435
|
+
when StrMenu::APP_MENU_ACTIONS_EXPORT_CUSTOM
|
|
436
|
+
submenu_export_custom
|
|
437
|
+
when StrMenu::APP_MENU_ACTIONS_IMPORT
|
|
438
|
+
submenu_import
|
|
439
|
+
when StrMenu::APP_MENU_ACTIONS_IMPORT_CUSTOM
|
|
440
|
+
submenu_import_custom
|
|
441
|
+
when StrMenu::APP_MENU_EXIT
|
|
442
|
+
submenu_exit
|
|
443
|
+
break
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
#
|
|
449
|
+
# Options menu process
|
|
450
|
+
#
|
|
451
|
+
def menu_options
|
|
452
|
+
loop do
|
|
453
|
+
@cli.draw_app_menu(
|
|
454
|
+
StrMenuContents::APP_MENU_OPTIONS_TEXT_INFO,
|
|
455
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU, StrMenu::APP_MENU_OPTIONS]
|
|
456
|
+
)
|
|
457
|
+
option = @cli.prompt_select(
|
|
458
|
+
StrMenu::APP_MENU_OPTIONS_SET_FORMAT_TYPE,
|
|
459
|
+
StrMenu::APP_MENU_OPTIONS_SET_WORKING_DIR,
|
|
460
|
+
StrMenu::APP_MENU_OPTIONS_SET_ENTRIES,
|
|
461
|
+
StrMenu::APP_MENU_OPTIONS_SET_IDS,
|
|
462
|
+
StrMenu::APP_MENU_OPTIONS_SHOW_OPTIONS_PRETTY,
|
|
463
|
+
StrMenu::APP_MENU_OPTIONS_SHOW_OPTIONS_RAW,
|
|
464
|
+
StrMenu::APP_MENU_EXIT
|
|
465
|
+
)
|
|
466
|
+
case option
|
|
467
|
+
when StrMenu::APP_MENU_OPTIONS_SET_FORMAT_TYPE
|
|
468
|
+
submenu_set_format_type
|
|
469
|
+
when StrMenu::APP_MENU_OPTIONS_SET_WORKING_DIR
|
|
470
|
+
submenu_set_working_dir
|
|
471
|
+
when StrMenu::APP_MENU_OPTIONS_SET_ENTRIES
|
|
472
|
+
submenu_set_entries
|
|
473
|
+
when StrMenu::APP_MENU_OPTIONS_SET_IDS
|
|
474
|
+
submenu_set_ids
|
|
475
|
+
when StrMenu::APP_MENU_OPTIONS_SHOW_OPTIONS_PRETTY
|
|
476
|
+
submenu_show_options_pretty
|
|
477
|
+
when StrMenu::APP_MENU_OPTIONS_SHOW_OPTIONS_RAW
|
|
478
|
+
submenu_show_options_raw
|
|
479
|
+
when StrMenu::APP_MENU_EXIT
|
|
480
|
+
submenu_exit
|
|
481
|
+
break
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
#
|
|
487
|
+
# Exit submenu process
|
|
488
|
+
#
|
|
489
|
+
def submenu_exit
|
|
490
|
+
@cli.draw_cancel_operation(StrSubMenu::EXIT_TEXT)
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
#
|
|
494
|
+
# Export submenu process
|
|
495
|
+
#
|
|
496
|
+
# @raise [Error]
|
|
497
|
+
#
|
|
498
|
+
def submenu_export
|
|
499
|
+
@cli.draw_app_submenu(
|
|
500
|
+
StrSubMenu::EXPORT_TEXT, StrPrompts::MULTI_SELECT_TIP_TEXT,
|
|
501
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU, StrMenu::APP_MENU_ACTIONS, StrMenu::APP_MENU_ACTIONS_EXPORT]
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
data_files = []
|
|
505
|
+
@cli.prompt_spinner(StrSubMenu::EXPORT_LOAD_FILES_TEXT) do
|
|
506
|
+
data_files = @data_manager.load_database_files
|
|
507
|
+
end
|
|
508
|
+
raise Error, StrSubMenu::EXPORT_LOAD_ERROR_TEXT if data_files.empty?
|
|
509
|
+
|
|
510
|
+
# Determines the list of pre-selected database files (for TTY select menu)
|
|
511
|
+
data_files_default = Utilities.menu_default_indexes(
|
|
512
|
+
data_files,
|
|
513
|
+
opt_file_entries
|
|
514
|
+
) do |menu_option, menu_index, file_entry|
|
|
515
|
+
menu_option.file?(file_entry)
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
# Ask the user to select the data files
|
|
519
|
+
# @type [Array<DataFile>]
|
|
520
|
+
data_files_selected = @cli.prompt_select_multi(
|
|
521
|
+
*data_files, default: data_files_default
|
|
522
|
+
)
|
|
523
|
+
raise Error, StrSubMenu::EXPORT_NO_FILES_ERROR_TEXT if data_files_selected.empty?
|
|
524
|
+
|
|
525
|
+
# Confirm operation
|
|
526
|
+
unless @cli.prompt_confirm?
|
|
527
|
+
@cli.draw_cancel_operation
|
|
528
|
+
@cli.prompt_pause
|
|
529
|
+
return
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
# Perform operation
|
|
533
|
+
data_files_selected.each do |data_file|
|
|
534
|
+
@cli.prompt_spinner(format(StrSubMenu::EXPORT_ACTION_TEXT, data_file)) do
|
|
535
|
+
do_action(APP_ACTION_EXPORT, data_file)
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
@cli.draw_success_operation
|
|
540
|
+
@cli.prompt_pause
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
#
|
|
544
|
+
# Export custom submenu process
|
|
545
|
+
#
|
|
546
|
+
# @raise [Error]
|
|
547
|
+
#
|
|
548
|
+
def submenu_export_custom
|
|
549
|
+
@cli.draw_app_submenu(
|
|
550
|
+
StrSubMenu::EXPORT_CUSTOM_TEXT, StrPrompts::MULTI_SELECT_TIP_TEXT,
|
|
551
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU, StrMenu::APP_MENU_ACTIONS, StrMenu::APP_MENU_ACTIONS_EXPORT_CUSTOM]
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
data_files = []
|
|
555
|
+
@cli.prompt_spinner(StrSubMenu::EXPORT_LOAD_FILES_TEXT) do
|
|
556
|
+
data_files = @data_manager.load_database_files.keep_if(&:customizable?)
|
|
557
|
+
end
|
|
558
|
+
raise Error, StrSubMenu::EXPORT_LOAD_ERROR_TEXT if data_files.empty?
|
|
559
|
+
|
|
560
|
+
# Determines the list of pre-selected database files (for TTY select menu)
|
|
561
|
+
data_files_default = Utilities.menu_default_indexes(
|
|
562
|
+
data_files,
|
|
563
|
+
opt_file_entries
|
|
564
|
+
) do |menu_option, menu_index, file_entry|
|
|
565
|
+
menu_option.file?(file_entry)
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Ask the user to select the data files
|
|
569
|
+
# @type [Array<DataFile>]
|
|
570
|
+
data_files_selected = @cli.prompt_select_multi(
|
|
571
|
+
*data_files, default: data_files_default
|
|
572
|
+
)
|
|
573
|
+
raise Error, StrSubMenu::EXPORT_NO_FILES_ERROR_TEXT if data_files_selected.empty?
|
|
574
|
+
|
|
575
|
+
# Determine the list of object IDs for each data file that supports it
|
|
576
|
+
data_files_selected.each do |data_file|
|
|
577
|
+
data_file_list = data_file.to_list
|
|
578
|
+
next if data_file_list.nil?
|
|
579
|
+
next unless @cli.prompt_confirm?(format(StrSubMenu::EXPORT_CUSTOM_SELECT_OBJ_ID_TEXT, data_file))
|
|
580
|
+
|
|
581
|
+
data_file_list_default = Utilities.menu_default_indexes(
|
|
582
|
+
data_file_list,
|
|
583
|
+
opt_file_object_ids(data_file.file)
|
|
584
|
+
)
|
|
585
|
+
data_file_list_selected = @cli.prompt_select_multi(
|
|
586
|
+
*data_file_list,
|
|
587
|
+
default: data_file_list_default
|
|
588
|
+
)
|
|
589
|
+
data_file.object_ids_update(data_file.convert_list_to_ids(data_file_list_selected))
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
# Confirm operation
|
|
593
|
+
unless @cli.prompt_confirm?
|
|
594
|
+
@cli.draw_cancel_operation
|
|
595
|
+
@cli.prompt_pause
|
|
596
|
+
return
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
# Perform operation
|
|
600
|
+
data_files_selected.each do |data_file|
|
|
601
|
+
@cli.prompt_spinner(format(StrSubMenu::EXPORT_CUSTOM_ACTION_TEXT, data_file)) do
|
|
602
|
+
do_action(APP_ACTION_EXPORT_CUSTOM, data_file)
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
@cli.draw_success_operation
|
|
607
|
+
@cli.prompt_pause
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
#
|
|
611
|
+
# Import submenu process
|
|
612
|
+
#
|
|
613
|
+
# @raise [Error]
|
|
614
|
+
#
|
|
615
|
+
def submenu_import
|
|
616
|
+
@cli.draw_app_submenu(
|
|
617
|
+
StrSubMenu::IMPORT_TEXT, StrPrompts::MULTI_SELECT_TIP_TEXT,
|
|
618
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU, StrMenu::APP_MENU_ACTIONS, StrMenu::APP_MENU_ACTIONS_IMPORT]
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
data_files = []
|
|
622
|
+
@cli.prompt_spinner(StrSubMenu::IMPORT_LOAD_FILES_TEXT) do
|
|
623
|
+
data_files = @data_manager.load_extracted_files(opt_working_dir)
|
|
624
|
+
end
|
|
625
|
+
raise Error, StrSubMenu::IMPORT_LOAD_ERROR_TEXT if data_files.empty?
|
|
626
|
+
|
|
627
|
+
# Determines the list of pre-selected files (for TTY select menu)
|
|
628
|
+
data_files_default = Utilities.menu_default_indexes(
|
|
629
|
+
data_files,
|
|
630
|
+
opt_file_entries
|
|
631
|
+
) do |menu_option, menu_index, file_entry|
|
|
632
|
+
menu_option.file?(file_entry)
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
# Ask the user to select the data files
|
|
636
|
+
# @type [Array<DataFile>]
|
|
637
|
+
data_files_selected = @cli.prompt_select_multi(
|
|
638
|
+
*data_files, default: data_files_default
|
|
639
|
+
)
|
|
640
|
+
raise Error, StrSubMenu::IMPORT_NO_FILES_ERROR_TEXT if data_files_selected.empty?
|
|
641
|
+
|
|
642
|
+
# Confirm operation
|
|
643
|
+
unless @cli.prompt_confirm?
|
|
644
|
+
@cli.draw_cancel_operation
|
|
645
|
+
@cli.prompt_pause
|
|
646
|
+
return
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
# Perform operation
|
|
650
|
+
data_files_selected.each do |data_file|
|
|
651
|
+
@cli.prompt_spinner(format(StrSubMenu::IMPORT_ACTION_TEXT, data_file)) do
|
|
652
|
+
do_action(APP_ACTION_IMPORT, data_file)
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
@cli.draw_success_operation
|
|
657
|
+
@cli.prompt_pause
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
#
|
|
661
|
+
# Import custom submenu process
|
|
662
|
+
#
|
|
663
|
+
# @raise [Error]
|
|
664
|
+
#
|
|
665
|
+
def submenu_import_custom
|
|
666
|
+
@cli.draw_app_submenu(
|
|
667
|
+
StrSubMenu::IMPORT_CUSTOM_TEXT, StrPrompts::MULTI_SELECT_TIP_TEXT,
|
|
668
|
+
breadcrumbs: [StrMenu::APP_MENU_MAIN_MENU, StrMenu::APP_MENU_ACTIONS, StrMenu::APP_MENU_ACTIONS_IMPORT_CUSTOM]
|
|
669
|
+
)
|
|
670
|
+
|
|
671
|
+
data_files = []
|
|
672
|
+
@cli.prompt_spinner(StrSubMenu::IMPORT_CUSTOM_LOAD_FILES_TEXT) do
|
|
673
|
+
data_files = @data_manager.load_extracted_files_custom(opt_working_dir).keep_if(&:mergeable?)
|
|
674
|
+
end
|
|
675
|
+
raise Error, StrSubMenu::IMPORT_LOAD_ERROR_TEXT if data_files.empty?
|
|
676
|
+
|
|
677
|
+
# Determines the list of pre-selected files (for TTY select menu)
|
|
678
|
+
data_files_default = Utilities.menu_default_indexes(
|
|
679
|
+
data_files,
|
|
680
|
+
opt_file_entries
|
|
681
|
+
) do |menu_option, menu_index, file_entry|
|
|
682
|
+
menu_option.file?(file_entry)
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
# Ask the user to select the data files
|
|
686
|
+
# @type [Array<DataFile>]
|
|
687
|
+
data_files_selected = @cli.prompt_select_multi(
|
|
688
|
+
*data_files, default: data_files_default
|
|
689
|
+
)
|
|
690
|
+
raise Error, StrSubMenu::IMPORT_NO_FILES_ERROR_TEXT if data_files_selected.empty?
|
|
691
|
+
|
|
692
|
+
# Confirm operation
|
|
693
|
+
unless @cli.prompt_confirm?
|
|
694
|
+
@cli.draw_cancel_operation
|
|
695
|
+
@cli.prompt_pause
|
|
696
|
+
return
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
# Perform operation
|
|
700
|
+
data_files_selected.each do |data_file|
|
|
701
|
+
@cli.prompt_spinner(format(StrSubMenu::IMPORT_CUSTOM_ACTION_TEXT, data_file)) do
|
|
702
|
+
do_action(APP_ACTION_IMPORT_CUSTOM, data_file)
|
|
703
|
+
end
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
@cli.draw_success_operation
|
|
707
|
+
@cli.prompt_pause
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
#
|
|
711
|
+
# Set file format type submenu process
|
|
712
|
+
#
|
|
713
|
+
def submenu_set_format_type
|
|
714
|
+
@cli.draw_app_submenu(
|
|
715
|
+
StrSubMenu::SET_FORMAT_TYPE_TEXT, StrPrompts::SELECT_TIP_TEXT,
|
|
716
|
+
breadcrumbs: [
|
|
717
|
+
StrMenu::APP_MENU_MAIN_MENU,
|
|
718
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
719
|
+
StrMenu::APP_MENU_OPTIONS_SET_FORMAT_TYPE
|
|
720
|
+
]
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
# Ask user to select a file format
|
|
724
|
+
file_format = @cli.prompt_select(
|
|
725
|
+
RGSS_FORMAT_TYPE_YAML,
|
|
726
|
+
RGSS_FORMAT_TYPE_JSON,
|
|
727
|
+
RGSS_FORMAT_TYPE_BINARY
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
# Confirm operation
|
|
731
|
+
if @cli.prompt_confirm?
|
|
732
|
+
@options.store(APP_OPTION_FORMAT_TYPE, file_format)
|
|
733
|
+
@cli.draw_success_operation(format(StrSubMenu::SET_FORMAT_TYPE_UPDATE_TEXT, file_format))
|
|
734
|
+
else
|
|
735
|
+
@cli.draw_cancel_operation
|
|
736
|
+
end
|
|
737
|
+
@cli.prompt_pause
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
#
|
|
741
|
+
# Set working directory submenu process
|
|
742
|
+
#
|
|
743
|
+
def submenu_set_working_dir
|
|
744
|
+
@cli.draw_app_submenu(
|
|
745
|
+
StrSubMenu::SET_WORKING_DIR_TEXT, StrPrompts::ASK_TIP_TEXT,
|
|
746
|
+
breadcrumbs: [
|
|
747
|
+
StrMenu::APP_MENU_MAIN_MENU,
|
|
748
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
749
|
+
StrMenu::APP_MENU_OPTIONS_SET_WORKING_DIR
|
|
750
|
+
]
|
|
751
|
+
)
|
|
752
|
+
|
|
753
|
+
# Ask user to type the new app working dir
|
|
754
|
+
working_dir = @cli.prompt_ask(
|
|
755
|
+
StrSubMenu::SET_WORKING_DIR_ASK_TEXT,
|
|
756
|
+
default: APP_DEFAULT_WORKING_DIR,
|
|
757
|
+
value: opt_working_dir,
|
|
758
|
+
validate_text: StrSubMenu::SET_WORKING_DIR_ASK_FAIL_TEXT
|
|
759
|
+
) do |input|
|
|
760
|
+
Utilities.valid_path?(input)
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
# Confirm operation
|
|
764
|
+
if @cli.prompt_confirm?
|
|
765
|
+
@options.store(APP_OPTION_WORKING_DIR, working_dir)
|
|
766
|
+
@cli.draw_success_operation(format(StrSubMenu::SET_WORKING_DIR_UPDATE_TEXT, working_dir))
|
|
767
|
+
else
|
|
768
|
+
@cli.draw_cancel_operation
|
|
769
|
+
end
|
|
770
|
+
@cli.prompt_pause
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
#
|
|
774
|
+
# Set pre-selected file entries submenu process
|
|
775
|
+
#
|
|
776
|
+
def submenu_set_entries
|
|
777
|
+
@cli.draw_app_submenu(
|
|
778
|
+
StrSubMenu::SET_ENTRIES_TEXT, StrPrompts::ASK_TIP_TEXT,
|
|
779
|
+
breadcrumbs: [
|
|
780
|
+
StrMenu::APP_MENU_MAIN_MENU,
|
|
781
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
782
|
+
StrMenu::APP_MENU_OPTIONS_SET_ENTRIES
|
|
783
|
+
]
|
|
784
|
+
)
|
|
785
|
+
|
|
786
|
+
# Ask user to type the list of entries
|
|
787
|
+
# @type [Array<String>]
|
|
788
|
+
entries = @cli.prompt_ask(
|
|
789
|
+
StrSubMenu::SET_ENTRIES_ASK_TEXT,
|
|
790
|
+
default: [],
|
|
791
|
+
value: opt_file_entries.join(","),
|
|
792
|
+
convert: :list
|
|
793
|
+
)
|
|
794
|
+
|
|
795
|
+
# Confirm operation
|
|
796
|
+
if @cli.prompt_confirm?
|
|
797
|
+
entries.uniq! # Make the entries unique before saving it
|
|
798
|
+
@options.store(APP_OPTION_FILE_ENTRIES, entries)
|
|
799
|
+
@cli.draw_success_operation(format(StrSubMenu::SET_ENTRIES_UPDATE_TEXT, entries))
|
|
800
|
+
|
|
801
|
+
# Since the file entries list was updated, we should drop the key-value pairs
|
|
802
|
+
# from the hash of object IDs that doesn't exist in the current file entry list
|
|
803
|
+
@options[APP_OPTION_IDS].delete_if do |file_entry, ids_array|
|
|
804
|
+
!entries.include?(file_entry)
|
|
805
|
+
end
|
|
806
|
+
else
|
|
807
|
+
@cli.draw_cancel_operation
|
|
808
|
+
end
|
|
809
|
+
@cli.prompt_pause
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
#
|
|
813
|
+
# Set pre-selected object IDs submenu process
|
|
814
|
+
#
|
|
815
|
+
# @raise [Error]
|
|
816
|
+
#
|
|
817
|
+
def submenu_set_ids
|
|
818
|
+
@cli.draw_app_submenu(
|
|
819
|
+
StrSubMenu::SET_IDS_TEXT, StrPrompts::MULTI_SELECT_TIP_TEXT, StrPrompts::ASK_TIP_TEXT,
|
|
820
|
+
breadcrumbs: [
|
|
821
|
+
StrMenu::APP_MENU_MAIN_MENU,
|
|
822
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
823
|
+
StrMenu::APP_MENU_OPTIONS_SET_IDS
|
|
824
|
+
]
|
|
825
|
+
)
|
|
826
|
+
|
|
827
|
+
# Checks if the user's file entries list is empty
|
|
828
|
+
raise Error, StrSubMenu::SET_IDS_NO_FILES_ERROR_TEXT if opt_file_entries.empty?
|
|
829
|
+
|
|
830
|
+
# Ask user to type the list of entries
|
|
831
|
+
# @type [Array<String>]
|
|
832
|
+
entries = @cli.prompt_select_multi(
|
|
833
|
+
*opt_file_entries
|
|
834
|
+
)
|
|
835
|
+
raise Error, StrSubMenu::SET_IDS_NO_FILES_SELECTED_ERROR_TEXT if entries.empty?
|
|
836
|
+
|
|
837
|
+
# @type [Hash<String, Array<Integer>>]
|
|
838
|
+
ids = opt_object_ids
|
|
839
|
+
|
|
840
|
+
# Ask the user for the list of object IDs for each file entry selected
|
|
841
|
+
entries.each do |file_entry|
|
|
842
|
+
current_ids = opt_file_object_ids(file_entry)
|
|
843
|
+
# @type [Array<Integer>]
|
|
844
|
+
user_ids = @cli.prompt_ask(
|
|
845
|
+
format(StrSubMenu::SET_IDS_ASK_IDS_TEXT, file_entry),
|
|
846
|
+
default: [],
|
|
847
|
+
value: current_ids.join(","),
|
|
848
|
+
convert: :int_list
|
|
849
|
+
)
|
|
850
|
+
# Process the user input
|
|
851
|
+
if user_ids.empty?
|
|
852
|
+
# Deletes the file entry if the list of IDs is empty
|
|
853
|
+
ids.delete(file_entry)
|
|
854
|
+
else
|
|
855
|
+
# Cleans any item that is not an integer
|
|
856
|
+
user_ids.delete_if { |id| !id.is_a?(Integer) }
|
|
857
|
+
# Removes any dupes
|
|
858
|
+
user_ids.uniq!
|
|
859
|
+
# Saves the list of IDs
|
|
860
|
+
ids.store(file_entry, user_ids)
|
|
861
|
+
end
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
# Confirm operation
|
|
865
|
+
if @cli.prompt_confirm?
|
|
866
|
+
@options.store(APP_OPTION_IDS, ids)
|
|
867
|
+
@cli.draw_success_operation(format(StrSubMenu::SET_IDS_UPDATE_TEXT, ids))
|
|
868
|
+
else
|
|
869
|
+
@cli.draw_cancel_operation
|
|
870
|
+
end
|
|
871
|
+
@cli.prompt_pause
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
#
|
|
875
|
+
# Show app options (pretty) submenu process
|
|
876
|
+
#
|
|
877
|
+
def submenu_show_options_pretty
|
|
878
|
+
@cli.draw_app_submenu(
|
|
879
|
+
StrSubMenu::SHOW_OPTIONS_PRETTY_TEXT,
|
|
880
|
+
breadcrumbs: [
|
|
881
|
+
StrMenu::APP_MENU_MAIN_MENU,
|
|
882
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
883
|
+
StrMenu::APP_MENU_OPTIONS_SHOW_OPTIONS_PRETTY
|
|
884
|
+
]
|
|
885
|
+
)
|
|
886
|
+
|
|
887
|
+
# Prepares the table rows
|
|
888
|
+
rows = []
|
|
889
|
+
@options.each_pair do |option_id, option_value|
|
|
890
|
+
# For some reason, TTY::Table does not like hashes
|
|
891
|
+
# Hence this workaround to convert it into an array
|
|
892
|
+
rows << if option_value.is_a?(Hash)
|
|
893
|
+
[option_id, option_value.to_a]
|
|
894
|
+
else
|
|
895
|
+
[option_id, option_value]
|
|
896
|
+
end
|
|
897
|
+
end
|
|
898
|
+
|
|
899
|
+
# Shows the option in a table
|
|
900
|
+
@cli.draw_table(
|
|
901
|
+
[StrSubMenu::SHOW_OPTIONS_COLUMN_1, StrSubMenu::SHOW_OPTIONS_COLUMN_2],
|
|
902
|
+
*rows
|
|
903
|
+
)
|
|
904
|
+
@cli.draw_success_operation
|
|
905
|
+
@cli.prompt_pause
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
#
|
|
909
|
+
# Show app options (raw) submenu process
|
|
910
|
+
#
|
|
911
|
+
def submenu_show_options_raw
|
|
912
|
+
@cli.draw_app_submenu(
|
|
913
|
+
StrSubMenu::SHOW_OPTIONS_RAW_TEXT,
|
|
914
|
+
breadcrumbs: [
|
|
915
|
+
StrMenu::APP_MENU_MAIN_MENU,
|
|
916
|
+
StrMenu::APP_MENU_OPTIONS,
|
|
917
|
+
StrMenu::APP_MENU_OPTIONS_SHOW_OPTIONS_RAW
|
|
918
|
+
]
|
|
919
|
+
)
|
|
920
|
+
|
|
921
|
+
@options.each_pair do |option_id, option_value|
|
|
922
|
+
@cli.draw("#{option_id} => #{option_value}")
|
|
923
|
+
end
|
|
924
|
+
@cli.draw_success_operation
|
|
925
|
+
@cli.prompt_pause
|
|
926
|
+
end
|
|
927
|
+
end
|
|
928
|
+
end
|