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
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "psych"
|
|
5
|
+
require "fileutils"
|
|
6
|
+
require_relative "../model/errors"
|
|
7
|
+
require_relative "../model/data_file_factory"
|
|
8
|
+
|
|
9
|
+
module RgssDb
|
|
10
|
+
# Relative path within the working directory to store back ups
|
|
11
|
+
# @return [String]
|
|
12
|
+
RGSS_BACK_UP_RELATIVE_PATH = "./Back Ups"
|
|
13
|
+
|
|
14
|
+
# RPG Maker XP RGSS version symbol
|
|
15
|
+
# @return [Symbol]
|
|
16
|
+
RGSS_VERSION_XP = :rpg_maker_xp
|
|
17
|
+
|
|
18
|
+
# RPG Maker VX RGSS version symbol
|
|
19
|
+
# @return [Symbol]
|
|
20
|
+
RGSS_VERSION_VX = :rpg_maker_vx
|
|
21
|
+
|
|
22
|
+
# RPG Maker VX Ace RGSS version symbol
|
|
23
|
+
# @return [Symbol]
|
|
24
|
+
RGSS_VERSION_VX_ACE = :rpg_maker_vx_ace
|
|
25
|
+
|
|
26
|
+
# Binary file format type
|
|
27
|
+
# @return [Symbol]
|
|
28
|
+
RGSS_FORMAT_TYPE_BINARY = :binary
|
|
29
|
+
|
|
30
|
+
# JSON file format type
|
|
31
|
+
# @return [Symbol]
|
|
32
|
+
RGSS_FORMAT_TYPE_JSON = :json
|
|
33
|
+
|
|
34
|
+
# YAML file format type
|
|
35
|
+
# @return [Symbol]
|
|
36
|
+
RGSS_FORMAT_TYPE_YAML = :yaml
|
|
37
|
+
|
|
38
|
+
# JSON file format extension
|
|
39
|
+
# @return [String]
|
|
40
|
+
RGSS_FILE_EXT_JSON = ".json"
|
|
41
|
+
|
|
42
|
+
# Exported YAML data file extension
|
|
43
|
+
# @return [String]
|
|
44
|
+
RGSS_FILE_EXT_YAML = ".yml"
|
|
45
|
+
|
|
46
|
+
# RPG Maker XP binary data file extension
|
|
47
|
+
# @return [String]
|
|
48
|
+
RGSS_FILE_EXT_XP = ".rxdata"
|
|
49
|
+
|
|
50
|
+
# RPG Maker VX binary data file extension
|
|
51
|
+
# @return [String]
|
|
52
|
+
RGSS_FILE_EXT_VX = ".rvdata"
|
|
53
|
+
|
|
54
|
+
# RPG Maker VX Ace binary data file extension
|
|
55
|
+
# @return [String]
|
|
56
|
+
RGSS_FILE_EXT_VX_ACE = ".rvdata2"
|
|
57
|
+
|
|
58
|
+
# Hash of all extracted file extensions
|
|
59
|
+
#
|
|
60
|
+
# The type of external file is used as the key, the value is the file extension string
|
|
61
|
+
# @return [Hash<Symbol, String>]
|
|
62
|
+
RGSS_EXTRACTED_FILE_EXTENSIONS = {
|
|
63
|
+
RGSS_FORMAT_TYPE_JSON => RGSS_FILE_EXT_JSON,
|
|
64
|
+
RGSS_FORMAT_TYPE_YAML => RGSS_FILE_EXT_YAML
|
|
65
|
+
}.freeze
|
|
66
|
+
|
|
67
|
+
# Hash of all database file extensions for each RPG Maker (RGSS) version
|
|
68
|
+
#
|
|
69
|
+
# The RPG Maker version is used as the key, the value is the file extension string
|
|
70
|
+
#
|
|
71
|
+
# This hash is used to detect the RPG Maker database version based on the file extension
|
|
72
|
+
# @return [Hash<Symbol, String>]
|
|
73
|
+
RGSS_DB_FILE_EXTENSIONS = {
|
|
74
|
+
RGSS_VERSION_XP => RGSS_FILE_EXT_XP,
|
|
75
|
+
RGSS_VERSION_VX => RGSS_FILE_EXT_VX,
|
|
76
|
+
RGSS_VERSION_VX_ACE => RGSS_FILE_EXT_VX_ACE
|
|
77
|
+
}.freeze
|
|
78
|
+
|
|
79
|
+
# Hash that contains the appropiate database model (data classes) for each RPG Maker (RGSS) version
|
|
80
|
+
#
|
|
81
|
+
# The RPG Maker version is used as the key, the value is an array of file paths
|
|
82
|
+
# @return [Hash<Symbol, Array<String>>]
|
|
83
|
+
RGSS_DB_MODELS = {
|
|
84
|
+
RGSS_VERSION_XP => [
|
|
85
|
+
"../model/rpg_maker_data/xp/rgss",
|
|
86
|
+
"../model/rpg_maker_data/xp/rpg"
|
|
87
|
+
],
|
|
88
|
+
RGSS_VERSION_VX => [
|
|
89
|
+
"../model/rpg_maker_data/vx/rgss",
|
|
90
|
+
"../model/rpg_maker_data/vx/rpg"
|
|
91
|
+
],
|
|
92
|
+
RGSS_VERSION_VX_ACE => [
|
|
93
|
+
"../model/rpg_maker_data/vx_ace/rgss",
|
|
94
|
+
"../model/rpg_maker_data/vx_ace/rpg"
|
|
95
|
+
]
|
|
96
|
+
}.freeze
|
|
97
|
+
|
|
98
|
+
# Hash of all supported database glob patterns files for each RPG Maker (RGSS) version
|
|
99
|
+
#
|
|
100
|
+
# The RPG Maker version is used as the key, the value is an array of glob patterns file names
|
|
101
|
+
# @return [Hash<Symbol, Array<String>>]
|
|
102
|
+
RGSS_DB_FILES = {
|
|
103
|
+
RGSS_VERSION_XP => [
|
|
104
|
+
DATA_FILE_ACTORS,
|
|
105
|
+
DATA_FILE_ANIMATIONS,
|
|
106
|
+
DATA_FILE_ARMORS,
|
|
107
|
+
DATA_FILE_CLASSES,
|
|
108
|
+
DATA_FILE_COMMON_EVENTS,
|
|
109
|
+
DATA_FILE_ENEMIES,
|
|
110
|
+
DATA_FILE_ITEMS,
|
|
111
|
+
DATA_FILE_MAPS,
|
|
112
|
+
DATA_FILE_MAP_INFOS,
|
|
113
|
+
DATA_FILE_SKILLS,
|
|
114
|
+
DATA_FILE_STATES,
|
|
115
|
+
DATA_FILE_SYSTEM,
|
|
116
|
+
DATA_FILE_TILESETS,
|
|
117
|
+
DATA_FILE_TROOPS,
|
|
118
|
+
DATA_FILE_WEAPONS
|
|
119
|
+
],
|
|
120
|
+
RGSS_VERSION_VX => [
|
|
121
|
+
DATA_FILE_ACTORS,
|
|
122
|
+
DATA_FILE_ANIMATIONS,
|
|
123
|
+
DATA_FILE_AREAS,
|
|
124
|
+
DATA_FILE_ARMORS,
|
|
125
|
+
DATA_FILE_CLASSES,
|
|
126
|
+
DATA_FILE_COMMON_EVENTS,
|
|
127
|
+
DATA_FILE_ENEMIES,
|
|
128
|
+
DATA_FILE_ITEMS,
|
|
129
|
+
DATA_FILE_MAPS,
|
|
130
|
+
DATA_FILE_MAP_INFOS,
|
|
131
|
+
DATA_FILE_SKILLS,
|
|
132
|
+
DATA_FILE_STATES,
|
|
133
|
+
DATA_FILE_SYSTEM,
|
|
134
|
+
DATA_FILE_TROOPS,
|
|
135
|
+
DATA_FILE_WEAPONS
|
|
136
|
+
],
|
|
137
|
+
RGSS_VERSION_VX_ACE => [
|
|
138
|
+
DATA_FILE_ACTORS,
|
|
139
|
+
DATA_FILE_ANIMATIONS,
|
|
140
|
+
DATA_FILE_ARMORS,
|
|
141
|
+
DATA_FILE_CLASSES,
|
|
142
|
+
DATA_FILE_COMMON_EVENTS,
|
|
143
|
+
DATA_FILE_ENEMIES,
|
|
144
|
+
DATA_FILE_ITEMS,
|
|
145
|
+
DATA_FILE_MAPS,
|
|
146
|
+
DATA_FILE_MAP_INFOS,
|
|
147
|
+
DATA_FILE_SKILLS,
|
|
148
|
+
DATA_FILE_STATES,
|
|
149
|
+
DATA_FILE_SYSTEM,
|
|
150
|
+
DATA_FILE_TILESETS,
|
|
151
|
+
DATA_FILE_TROOPS,
|
|
152
|
+
DATA_FILE_WEAPONS
|
|
153
|
+
]
|
|
154
|
+
}.freeze
|
|
155
|
+
|
|
156
|
+
#
|
|
157
|
+
# Data manager class
|
|
158
|
+
#
|
|
159
|
+
class DataManager
|
|
160
|
+
# Data folder path
|
|
161
|
+
# @return [String]
|
|
162
|
+
attr_reader :path
|
|
163
|
+
|
|
164
|
+
# RGSS Version
|
|
165
|
+
#
|
|
166
|
+
# Returns ``nil`` if no version was detected
|
|
167
|
+
# @return [Symbol]
|
|
168
|
+
attr_reader :rgss_version
|
|
169
|
+
|
|
170
|
+
#
|
|
171
|
+
# Creates a data manager instance
|
|
172
|
+
#
|
|
173
|
+
# @param data_folder [String] RPG Maker database folder
|
|
174
|
+
#
|
|
175
|
+
def initialize(data_folder)
|
|
176
|
+
@path = File.expand_path(data_folder)
|
|
177
|
+
database_detect_version
|
|
178
|
+
database_load_model
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
#
|
|
182
|
+
# Checks if a valid RPG Maker version was detected or not
|
|
183
|
+
#
|
|
184
|
+
# @return [Boolean]
|
|
185
|
+
#
|
|
186
|
+
def version?
|
|
187
|
+
!@rgss_version.nil?
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
#
|
|
191
|
+
# Checks if the current RPG Maker version detected matches the given one
|
|
192
|
+
#
|
|
193
|
+
# The argument is automatically casted into a Symbol instance
|
|
194
|
+
#
|
|
195
|
+
# @param version [Symbol] RPG Maker version
|
|
196
|
+
#
|
|
197
|
+
# @return [Boolean]
|
|
198
|
+
#
|
|
199
|
+
def version_is?(version)
|
|
200
|
+
@rgss_version == version.to_s.to_sym
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
#
|
|
204
|
+
# Returns ``true`` if ``file_path`` is a RPG Maker binary data file
|
|
205
|
+
#
|
|
206
|
+
# Returns ``false`` if ``file_path`` is not a binary data file
|
|
207
|
+
#
|
|
208
|
+
# Returns ``false`` if the RGSS version could not be determined
|
|
209
|
+
#
|
|
210
|
+
# @param file_path [String] File path
|
|
211
|
+
#
|
|
212
|
+
# @return [Boolean]
|
|
213
|
+
#
|
|
214
|
+
def database_file?(file_path)
|
|
215
|
+
File.extname(file_path).casecmp?(database_file_extension)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
#
|
|
219
|
+
# Returns ``true`` if the file path is a JSON file
|
|
220
|
+
#
|
|
221
|
+
# @param file_path [String] File path
|
|
222
|
+
#
|
|
223
|
+
# @return [Boolean]
|
|
224
|
+
#
|
|
225
|
+
def json_file?(file_path)
|
|
226
|
+
File.extname(file_path).casecmp?(RGSS_FILE_EXT_JSON)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
#
|
|
230
|
+
# Returns ``true`` if the file path is a YAML file
|
|
231
|
+
#
|
|
232
|
+
# @param file_path [String] File path
|
|
233
|
+
#
|
|
234
|
+
# @return [Boolean]
|
|
235
|
+
#
|
|
236
|
+
def yaml_file?(file_path)
|
|
237
|
+
File.extname(file_path).casecmp?(RGSS_FILE_EXT_YAML)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
#
|
|
241
|
+
# Loads a single database data file based on the given type
|
|
242
|
+
#
|
|
243
|
+
# @param [String] database_file_type
|
|
244
|
+
#
|
|
245
|
+
# @return [DataFile]
|
|
246
|
+
#
|
|
247
|
+
def load_database_file(database_file_type)
|
|
248
|
+
# Formats the database file path
|
|
249
|
+
database_file_path = File.join(@path, database_file_type + database_file_extension)
|
|
250
|
+
|
|
251
|
+
# Creates a data file instance for this database file
|
|
252
|
+
DataFileFactory.create_data_file(database_file_path, load_file(database_file_path))
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
#
|
|
256
|
+
# Gets a list of ``DataFile`` instances based on the current path and detected version
|
|
257
|
+
#
|
|
258
|
+
# This method should be used to read all RPG Maker binary data files
|
|
259
|
+
#
|
|
260
|
+
# Returns an empty array if the operation is not possible
|
|
261
|
+
#
|
|
262
|
+
# @return [Array<DataFile>]
|
|
263
|
+
#
|
|
264
|
+
def load_database_files
|
|
265
|
+
return [] unless version?
|
|
266
|
+
|
|
267
|
+
# Formats the database file names adding the proper file extension
|
|
268
|
+
database_files = database_file_names.map { |file_name| file_name + database_file_extension }
|
|
269
|
+
|
|
270
|
+
# Scans the data folder for files
|
|
271
|
+
detected_files = Dir.glob(database_files, File::FNM_CASEFOLD, base: @path)
|
|
272
|
+
|
|
273
|
+
# Creates an array of data file instances with the detected database files
|
|
274
|
+
detected_files.map do |data_file|
|
|
275
|
+
data_file_path = File.expand_path(data_file, @path)
|
|
276
|
+
DataFileFactory.create_data_file(data_file_path, load_file(data_file_path))
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
#
|
|
281
|
+
# Gets a list of ``DataFile`` instances based on the given directory
|
|
282
|
+
#
|
|
283
|
+
# All extracted files should be inside the given directory
|
|
284
|
+
#
|
|
285
|
+
# This method reads extracted files and returns it as data files (RPG maker data)
|
|
286
|
+
#
|
|
287
|
+
# Returns an empty array if the operation is not possible
|
|
288
|
+
#
|
|
289
|
+
# @param app_directory [String] Application working directory
|
|
290
|
+
#
|
|
291
|
+
# @return [Array<DataFile>]
|
|
292
|
+
#
|
|
293
|
+
def load_extracted_files(app_directory)
|
|
294
|
+
return [] unless version?
|
|
295
|
+
|
|
296
|
+
# Determines the application working folder directory
|
|
297
|
+
base_path = File.expand_path(app_directory, @path)
|
|
298
|
+
|
|
299
|
+
# Creates a glob pattern to detect extracted data files using file extensions
|
|
300
|
+
file_extensions_glob = "{#{RGSS_EXTRACTED_FILE_EXTENSIONS.values.join(",")}}"
|
|
301
|
+
|
|
302
|
+
# Formats all supported database files adding the file extensions glob pattern
|
|
303
|
+
extracted_files = database_file_names.map do |file_name|
|
|
304
|
+
file_name + file_extensions_glob
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Scans the extracted folder for complete extracted files
|
|
308
|
+
detected_files = Dir.glob(extracted_files, File::FNM_CASEFOLD, base: base_path)
|
|
309
|
+
|
|
310
|
+
# Creates an array of data file instances with the detected database files
|
|
311
|
+
detected_files.map do |data_file|
|
|
312
|
+
data_file_path = File.expand_path(data_file, base_path)
|
|
313
|
+
DataFileFactory.create_data_file(data_file_path, load_file(data_file_path))
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
#
|
|
318
|
+
# Gets a list of ``DataFile`` instances based on the given directory
|
|
319
|
+
#
|
|
320
|
+
# All custom extracted files should be inside the given directory
|
|
321
|
+
#
|
|
322
|
+
# This method reads extracted files and returns it as data files (RPG maker data)
|
|
323
|
+
#
|
|
324
|
+
# Returns an empty array if the operation is not possible
|
|
325
|
+
#
|
|
326
|
+
# @param app_directory [String] Application working directory
|
|
327
|
+
#
|
|
328
|
+
# @return [Array<DataFile>]
|
|
329
|
+
#
|
|
330
|
+
def load_extracted_files_custom(app_directory)
|
|
331
|
+
return [] unless version?
|
|
332
|
+
|
|
333
|
+
# Determines the application working folder directory
|
|
334
|
+
base_path = File.expand_path(app_directory, @path)
|
|
335
|
+
|
|
336
|
+
# Creates a glob pattern to detect extracted data files using file extensions
|
|
337
|
+
file_extensions_glob = "{#{RGSS_EXTRACTED_FILE_EXTENSIONS.values.join(",")}}"
|
|
338
|
+
|
|
339
|
+
# Formats all supported database files adding the file extensions glob pattern
|
|
340
|
+
extracted_files = database_file_names.map do |file_name|
|
|
341
|
+
file_name + DATA_FILE_CUSTOM_LABEL + file_extensions_glob
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# Scans the extracted folder for complete extracted files
|
|
345
|
+
detected_files = Dir.glob(extracted_files, File::FNM_CASEFOLD, base: base_path)
|
|
346
|
+
|
|
347
|
+
# Creates an array of data file instances with the detected files
|
|
348
|
+
detected_files.map do |data_file|
|
|
349
|
+
data_file_path = File.expand_path(data_file, base_path)
|
|
350
|
+
DataFileFactory.create_data_file(data_file_path, load_file(data_file_path))
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
#
|
|
355
|
+
# Saves the given data file instance
|
|
356
|
+
#
|
|
357
|
+
# @param data_file [DataFile] Data file instance
|
|
358
|
+
# @param app_directory [String] Application working directory
|
|
359
|
+
# @param output_format_type [String] Output file format type
|
|
360
|
+
#
|
|
361
|
+
# @raise [StandardError] RPG Maker version is not valid
|
|
362
|
+
#
|
|
363
|
+
def save_data_file(data_file, app_directory, output_format_type)
|
|
364
|
+
raise "cannot save data file because rpg maker version is unknown: #{@rgss_version}" unless version?
|
|
365
|
+
|
|
366
|
+
data_file_path = File.join(
|
|
367
|
+
File.expand_path(app_directory, @path),
|
|
368
|
+
data_file.serialize_file_name + determine_file_extension(output_format_type)
|
|
369
|
+
)
|
|
370
|
+
save_file(data_file_path, data_file.serialize)
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
#
|
|
374
|
+
# Saves a back up of the given file
|
|
375
|
+
#
|
|
376
|
+
# If ``file_path`` is a path, the file's base name is auto. extracted
|
|
377
|
+
#
|
|
378
|
+
# If the database file does not exist back up creation is skipped
|
|
379
|
+
#
|
|
380
|
+
# @param [String] file_path File path
|
|
381
|
+
# @param [String] app_directory Application working directory
|
|
382
|
+
#
|
|
383
|
+
# @raise [StandardError] RPG Maker version is not valid
|
|
384
|
+
#
|
|
385
|
+
def save_database_back_up(file_path, app_directory)
|
|
386
|
+
raise "cannot save file backup because rpg maker version is unknown: #{@rgss_version}" unless version?
|
|
387
|
+
|
|
388
|
+
# Gets the file's base name
|
|
389
|
+
database_file = File.basename(file_path, ".*")
|
|
390
|
+
|
|
391
|
+
# Determines the absolute path to the (possible) database file
|
|
392
|
+
database_file_path = File.join(@path, database_file + database_file_extension)
|
|
393
|
+
|
|
394
|
+
# Creates a back up file if the database file exists
|
|
395
|
+
save_back_up(database_file_path, app_directory) if File.file?(database_file_path)
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
private
|
|
399
|
+
|
|
400
|
+
#
|
|
401
|
+
# Detects the RGSS engine version on the current opened data folder
|
|
402
|
+
#
|
|
403
|
+
def database_detect_version
|
|
404
|
+
# Gets all supported RPG Maker data file extensions
|
|
405
|
+
file_extensions = RGSS_DB_FILE_EXTENSIONS.values
|
|
406
|
+
|
|
407
|
+
# Gets all files that matches any data file extension (glob pattern)
|
|
408
|
+
data_files = Dir.glob("*{#{file_extensions.join(",")}}", File::FNM_CASEFOLD, base: @path)
|
|
409
|
+
|
|
410
|
+
# All data files within the data folder must be of the same type (aka the same RGSS version)
|
|
411
|
+
file_extension = file_extensions.find do |file_ext|
|
|
412
|
+
!data_files.empty? && data_files.all? { |data_file| File.extname(data_file).casecmp?(file_ext) }
|
|
413
|
+
end
|
|
414
|
+
@rgss_version = RGSS_DB_FILE_EXTENSIONS.key(file_extension)
|
|
415
|
+
|
|
416
|
+
# Freeze attributes to avoid modifications
|
|
417
|
+
@path.freeze
|
|
418
|
+
@rgss_version.freeze
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
#
|
|
422
|
+
# Loads the appropriate RPG Maker database classes based on the detected RPG Maker version
|
|
423
|
+
#
|
|
424
|
+
# Only one RPG Maker version should be loaded at a time to avoid data corruption
|
|
425
|
+
#
|
|
426
|
+
def database_load_model
|
|
427
|
+
models = RGSS_DB_MODELS[@rgss_version]
|
|
428
|
+
return if models.nil?
|
|
429
|
+
|
|
430
|
+
models.each { |model| require_relative model }
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
#
|
|
434
|
+
# Gets the appropiate file extension based on the detected RGSS version
|
|
435
|
+
#
|
|
436
|
+
# Returns ``nil`` if the RGSS version is invalid
|
|
437
|
+
#
|
|
438
|
+
# @return [String]
|
|
439
|
+
#
|
|
440
|
+
def database_file_extension
|
|
441
|
+
RGSS_DB_FILE_EXTENSIONS[@rgss_version]
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
#
|
|
445
|
+
# Gets a list of all supported database file names based on the detected RGSS version
|
|
446
|
+
#
|
|
447
|
+
# The list of file names has glob patterns
|
|
448
|
+
#
|
|
449
|
+
# Returns ``nil`` if the RGSS version is invalid
|
|
450
|
+
#
|
|
451
|
+
# @return [Array<String>]
|
|
452
|
+
#
|
|
453
|
+
def database_file_names
|
|
454
|
+
RGSS_DB_FILES[@rgss_version]
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
#
|
|
458
|
+
# Determines the file extension based on the file format type
|
|
459
|
+
#
|
|
460
|
+
# Returns ``nil`` if the format type is unknown
|
|
461
|
+
#
|
|
462
|
+
# @param format_type [Symbol]
|
|
463
|
+
#
|
|
464
|
+
# @return [String]
|
|
465
|
+
#
|
|
466
|
+
def determine_file_extension(format_type)
|
|
467
|
+
case format_type
|
|
468
|
+
when RGSS_FORMAT_TYPE_BINARY
|
|
469
|
+
database_file_extension
|
|
470
|
+
when RGSS_FORMAT_TYPE_JSON
|
|
471
|
+
RGSS_FILE_EXT_JSON
|
|
472
|
+
when RGSS_FORMAT_TYPE_YAML
|
|
473
|
+
RGSS_FILE_EXT_YAML
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
#
|
|
478
|
+
# Loads the given file contents
|
|
479
|
+
#
|
|
480
|
+
# Returns ``nil`` if the operation is not possible
|
|
481
|
+
#
|
|
482
|
+
# @param file_path [String] File entry
|
|
483
|
+
#
|
|
484
|
+
# @return [Object]
|
|
485
|
+
#
|
|
486
|
+
def load_file(file_path)
|
|
487
|
+
if database_file?(file_path)
|
|
488
|
+
file_contents = File.read(file_path, mode: "rb")
|
|
489
|
+
Marshal.load(file_contents)
|
|
490
|
+
elsif json_file?(file_path)
|
|
491
|
+
file_contents = File.read(file_path, mode: "r")
|
|
492
|
+
JSON.parse(file_contents, create_additions: true)
|
|
493
|
+
elsif yaml_file?(file_path)
|
|
494
|
+
file_contents = File.read(file_path, mode: "r")
|
|
495
|
+
Psych.unsafe_load(file_contents)
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
#
|
|
500
|
+
# Saves the data file instance
|
|
501
|
+
#
|
|
502
|
+
# The file path will be created if it does not exists
|
|
503
|
+
#
|
|
504
|
+
# @param file_path [String] File path
|
|
505
|
+
# @param object [Object] object
|
|
506
|
+
#
|
|
507
|
+
def save_file(file_path, object)
|
|
508
|
+
# Creates the directory if it does not exists
|
|
509
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
|
510
|
+
|
|
511
|
+
# Perform the write operation
|
|
512
|
+
if database_file?(file_path)
|
|
513
|
+
File.open(file_path, "wb") do |file|
|
|
514
|
+
file << Marshal.dump(object)
|
|
515
|
+
end
|
|
516
|
+
elsif json_file?(file_path)
|
|
517
|
+
File.open(file_path, "w") do |file|
|
|
518
|
+
file << JSON.pretty_generate(object)
|
|
519
|
+
end
|
|
520
|
+
elsif yaml_file?(file_path)
|
|
521
|
+
File.open(file_path, "w") do |file|
|
|
522
|
+
file << Psych.dump(object)
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
#
|
|
528
|
+
# Saves a back up of the given file
|
|
529
|
+
#
|
|
530
|
+
# @param file_path [String] File path
|
|
531
|
+
# @param app_directory [String] Application working directory
|
|
532
|
+
#
|
|
533
|
+
# @raise [StandardError] File path does not exists
|
|
534
|
+
#
|
|
535
|
+
def save_back_up(file_path, app_directory)
|
|
536
|
+
# Determine back up paths
|
|
537
|
+
dest_folder = File.join(File.expand_path(app_directory, @path), RGSS_BACK_UP_RELATIVE_PATH)
|
|
538
|
+
dest_file_name = "#{File.basename(file_path)} - #{current_date}.bak"
|
|
539
|
+
dest_path = File.join(dest_folder, dest_file_name)
|
|
540
|
+
|
|
541
|
+
# Creates (recursively) the back ups folder if it does not exists
|
|
542
|
+
FileUtils.mkdir_p(dest_folder) unless File.directory?(dest_folder)
|
|
543
|
+
|
|
544
|
+
# Creates a copy of the file (throws an error if it does not exists)
|
|
545
|
+
FileUtils.copy_file(file_path, dest_path)
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
#
|
|
549
|
+
# Gets the current date and time as a string
|
|
550
|
+
#
|
|
551
|
+
# @return [String]
|
|
552
|
+
#
|
|
553
|
+
def current_date
|
|
554
|
+
Time.now.strftime("%Y.%m.%d - %H.%M.%S")
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
end
|