1 #include "main/info-initializer.h"
2 #include "dungeon/dungeon.h"
3 #include "grid/feature.h"
4 #include "info-reader/artifact-reader.h"
5 #include "info-reader/dungeon-reader.h"
6 #include "info-reader/ego-reader.h"
7 #include "info-reader/feature-reader.h"
8 #include "info-reader/fixed-map-parser.h"
9 #include "info-reader/general-parser.h"
10 #include "info-reader/kind-reader.h"
11 #include "info-reader/magic-reader.h"
12 #include "info-reader/race-reader.h"
13 #include "info-reader/skill-reader.h"
14 #include "info-reader/vault-reader.h"
15 #include "io/files-util.h"
16 #include "io/uid-checker.h"
17 #include "main/angband-headers.h"
18 #include "main/init-error-messages-table.h"
19 #include "monster-race/monster-race.h"
20 #include "object-enchant/object-ego.h"
21 #include "object/object-kind.h"
22 #include "player/player-class.h"
23 #include "player/player-skill.h"
24 #include "room/rooms-vault.h"
25 #include "system/angband-version.h"
26 #include "system/artifact-type-definition.h"
27 #include "util/angband-files.h"
28 #include "view/display-messages.h"
29 #include "world/world.h"
32 #include <sys/types.h>
36 * @brief 基本情報読み込みのメインルーチン /
37 * Initialize misc. values
38 * @param player_ptr プレーヤーへの参照ポインタ
41 errr init_misc(player_type *player_ptr) { return parse_fixed_map(player_ptr, "misc.txt", 0, 0, 0, 0); }
44 * @brief rawファイルからのデータの読み取り処理
45 * Initialize the "*_info" array, by parsing a binary "image" file
46 * @param fd ファイルディスクリプタ
47 * @param head rawファイルのヘッダ
50 static errr init_info_raw(int fd, angband_header *head)
53 if (fd_read(fd, (char *)(&test), sizeof(angband_header)) || (test.v_major != head->v_major) || (test.v_minor != head->v_minor)
54 || (test.v_patch != head->v_patch) || (test.info_num != head->info_num) || (test.info_len != head->info_len) || (test.head_size != head->head_size)
55 || (test.info_size != head->info_size)) {
60 C_MAKE(head->info_ptr, head->info_size, char);
61 fd_read(fd, head->info_ptr, head->info_size);
62 if (head->name_size) {
63 C_MAKE(head->name_ptr, head->name_size, char);
64 fd_read(fd, head->name_ptr, head->name_size);
67 if (head->text_size) {
68 C_MAKE(head->text_ptr, head->text_size, char);
69 fd_read(fd, head->text_ptr, head->text_size);
73 C_MAKE(head->tag_ptr, head->tag_size, char);
74 fd_read(fd, head->tag_ptr, head->tag_size);
80 static void update_header(angband_header *head, void **info, char **name, char **text, char **tag)
83 *info = head->info_ptr;
86 *name = head->name_ptr;
89 *text = head->text_ptr;
97 * Initialize the header of an *_info.raw file.
98 * @param head rawファイルのヘッダ
103 static void init_header(angband_header *head, IDX num, int len)
105 head->v_major = FAKE_VER_MAJOR;
106 head->v_minor = FAKE_VER_MINOR;
107 head->v_patch = FAKE_VER_PATCH;
110 head->info_num = (IDX)num;
111 head->info_len = len;
113 head->head_size = sizeof(angband_header);
114 head->info_size = head->info_num * head->info_len;
118 * @brief テキストファイルとrawファイルの更新時刻を比較する
119 * Find the default paths to all of our important sub-directories.
120 * @param fd ファイルディスクリプタ
121 * @param template_file ファイル名
122 * @return テキストの方が新しいか、rawファイルがなく更新の必要がある場合-1、更新の必要がない場合0。
124 static errr check_modification_date(int fd, concptr template_file)
126 struct stat txt_stat, raw_stat;
128 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, template_file);
129 if (stat(buf, &txt_stat))
132 if (fstat(fd, &raw_stat))
135 if (txt_stat.st_mtime > raw_stat.st_mtime)
143 * Initialize the "*_info" array
144 * @param filename ファイル名(拡張子txt/raw)
145 * @param head 処理に用いるヘッダ構造体
146 * @param info データ保管先の構造体ポインタ
147 * @param name 名称用可変文字列の保管先
148 * @param text テキスト用可変文字列の保管先
149 * @param tag タグ用可変文字列の保管先
152 * Note that we let each entry have a unique "name" and "text" string,
153 * even if the string happens to be empty (everyone has a unique '\0').
155 static errr init_info(player_type *player_ptr, concptr filename, angband_header *head, void **info, char **name, char **text, char **tag)
158 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename));
159 int fd = fd_open(buf, O_RDONLY);
162 err = check_modification_date(fd, format("%s.txt", filename));
164 err = init_info_raw(fd, head);
169 BIT_FLAGS file_permission = 0644;
171 update_header(head, info, name, text, tag);
175 C_MAKE(head->info_ptr, head->info_size, char);
177 C_MAKE(head->name_ptr, FAKE_NAME_SIZE, char);
180 C_MAKE(head->text_ptr, FAKE_TEXT_SIZE, char);
183 C_MAKE(head->tag_ptr, FAKE_TAG_SIZE, char);
186 *info = head->info_ptr;
189 *name = head->name_ptr;
192 *text = head->text_ptr;
195 *tag = head->tag_ptr;
197 path_build(buf, sizeof(buf), ANGBAND_DIR_EDIT, format("%s.txt", filename));
199 fp = angband_fopen(buf, "r");
201 quit(format(_("'%s.txt'ファイルをオープンできません。", "Cannot open '%s.txt' file."), filename));
203 err = init_info_txt(fp, buf, head, head->parse_info_txt);
206 concptr oops = (((err > 0) && (err < PARSE_ERROR_MAX)) ? err_str[err] : _("未知の", "unknown"));
208 msg_format("'%s.txt'ファイルの %d 行目にエラー。", filename, error_line);
210 msg_format("Error %d at line %d of '%s.txt'.", err, error_line, filename);
212 msg_format(_("レコード %d は '%s' エラーがあります。", "Record %d contains a '%s' error."), error_idx, oops);
213 msg_format(_("構文 '%s'。", "Parsing '%s'."), buf);
215 quit(format(_("'%s.txt'ファイルにエラー", "Error in '%s.txt' file."), filename));
219 (*head->retouch)(head);
221 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename));
222 safe_setuid_grab(player_ptr);
224 fd = fd_make(buf, file_permission);
227 fd_write(fd, (concptr)(head), head->head_size);
228 fd_write(fd, head->info_ptr, head->info_size);
229 fd_write(fd, head->name_ptr, head->name_size);
230 fd_write(fd, head->text_ptr, head->text_size);
231 fd_write(fd, head->tag_ptr, head->tag_size);
235 C_KILL(head->info_ptr, head->info_size, char);
237 C_KILL(head->name_ptr, FAKE_NAME_SIZE, char);
240 C_KILL(head->text_ptr, FAKE_TEXT_SIZE, char);
243 C_KILL(head->tag_ptr, FAKE_TAG_SIZE, char);
245 path_build(buf, sizeof(buf), ANGBAND_DIR_DATA, format(_("%s_j.raw", "%s.raw"), filename));
246 fd = fd_open(buf, O_RDONLY);
248 quit(format(_("'%s_j.raw'ファイルをロードできません。", "Cannot load '%s.raw' file."), filename));
250 err = init_info_raw(fd, head);
253 quit(format(_("'%s_j.raw'ファイルを解析できません。", "Cannot parse '%s.raw' file."), filename));
255 update_header(head, info, name, text, tag);
260 * @brief 地形情報読み込みのメインルーチン /
261 * Initialize the "f_info" array
264 errr init_f_info(player_type *player_ptr)
266 init_header(&f_head, max_f_idx, sizeof(feature_type));
267 f_head.parse_info_txt = parse_f_info;
268 f_head.retouch = retouch_f_info;
269 return init_info(player_ptr, "f_info", &f_head, (void *)&f_info, &f_name, NULL, &f_tag);
273 * @brief ベースアイテム情報読み込みのメインルーチン /
274 * Initialize the "k_info" array
277 errr init_k_info(player_type *player_ptr)
279 init_header(&k_head, max_k_idx, sizeof(object_kind));
280 k_head.parse_info_txt = parse_k_info;
281 return init_info(player_ptr, "k_info", &k_head, (void *)&k_info, &k_name, &k_text, NULL);
285 * @brief 固定アーティファクト情報読み込みのメインルーチン /
286 * Initialize the "a_info" array
289 errr init_a_info(player_type *player_ptr)
291 init_header(&a_head, max_a_idx, sizeof(artifact_type));
292 a_head.parse_info_txt = parse_a_info;
293 return init_info(player_ptr, "a_info", &a_head, (void *)&a_info, &a_name, &a_text, NULL);
297 * @brief 固定アーティファクト情報読み込みのメインルーチン /
298 * Initialize the "e_info" array
301 errr init_e_info(player_type *player_ptr)
303 init_header(&e_head, max_e_idx, sizeof(ego_item_type));
304 e_head.parse_info_txt = parse_e_info;
305 return init_info(player_ptr, "e_info", &e_head, (void *)&e_info, &e_name, &e_text, NULL);
309 * @brief モンスター種族情報読み込みのメインルーチン /
310 * Initialize the "r_info" array
313 errr init_r_info(player_type *player_ptr)
315 init_header(&r_head, max_r_idx, sizeof(monster_race));
316 r_head.parse_info_txt = parse_r_info;
317 return init_info(player_ptr, "r_info", &r_head, (void *)&r_info, &r_name, &r_text, NULL);
321 * @brief ダンジョン情報読み込みのメインルーチン /
322 * Initialize the "d_info" array
325 errr init_d_info(player_type *player_ptr)
327 init_header(&d_head, current_world_ptr->max_d_idx, sizeof(dungeon_type));
328 d_head.parse_info_txt = parse_d_info;
329 return init_info(player_ptr, "d_info", &d_head, (void *)&d_info, &d_name, &d_text, NULL);
333 * @brief Vault情報読み込みのメインルーチン /
334 * Initialize the "v_info" array
337 * Note that we let each entry have a unique "name" and "text" string,
338 * even if the string happens to be empty (everyone has a unique '\0').
340 errr init_v_info(player_type *player_ptr)
342 init_header(&v_head, max_v_idx, sizeof(vault_type));
343 v_head.parse_info_txt = parse_v_info;
344 return init_info(player_ptr, "v_info", &v_head, (void *)&v_info, &v_name, &v_text, NULL);
348 * @brief 職業技能情報読み込みのメインルーチン /
349 * Initialize the "s_info" array
352 errr init_s_info(player_type *player_ptr)
354 init_header(&s_head, MAX_CLASS, sizeof(skill_table));
355 s_head.parse_info_txt = parse_s_info;
356 return init_info(player_ptr, "s_info", &s_head, (void *)&s_info, NULL, NULL, NULL);
360 * @brief 職業魔法情報読み込みのメインルーチン /
361 * Initialize the "m_info" array
364 errr init_m_info(player_type *player_ptr)
366 init_header(&m_head, MAX_CLASS, sizeof(player_magic));
367 m_head.parse_info_txt = parse_m_info;
368 return init_info(player_ptr, "m_info", &m_head, (void *)&m_info, NULL, NULL, NULL);