1 #include "player/process-name.h"
2 #include "autopick/autopick-reader-writer.h"
3 #include "core/asking-player.h"
4 #include "game-option/birth-options.h"
5 #include "io/files-util.h"
6 #include "player/player-personality.h"
7 #include "system/player-type-definition.h"
8 #include "term/screen-processor.h"
9 #include "term/term-color-types.h"
10 #include "util/angband-files.h"
11 #include "util/finalizer.h"
12 #include "util/string-processor.h"
13 #include "view/display-player-misc-info.h"
14 #include "world/world.h"
16 #ifdef SAVEFILE_USE_UID
17 #include "main-unix/unix-user-ids.h"
21 * @brief プレイヤーの名前をチェックして修正する
22 * Process the player name.
23 * @param player_ptr プレイヤーへの参照ポインタ
24 * @param sf セーブファイル名に合わせた修正を行うならばTRUE
26 * Extract a clean "base name".
27 * Build the savefile name if needed.
29 void process_player_name(PlayerType *player_ptr, bool is_new_savefile)
31 char old_player_base[32] = "";
32 if (w_ptr->character_generated) {
33 strcpy(old_player_base, player_ptr->base_name);
36 for (int i = 0; player_ptr->name[i]; i++) {
38 if (iskanji(player_ptr->name[i])) {
43 if (iscntrl((unsigned char)player_ptr->name[i]))
45 if (iscntrl(player_ptr->name[i]))
48 quit_fmt(_("'%s' という名前は不正なコントロールコードを含んでいます。", "The name '%s' contains control chars!"), player_ptr->name);
53 for (int i = 0; player_ptr->name[i]; i++) {
55 unsigned char c = player_ptr->name[i];
57 char c = player_ptr->name[i];
62 if (k + 2 >= (int)sizeof(player_ptr->base_name) || !player_ptr->name[i + 1]) {
66 player_ptr->base_name[k++] = c;
68 player_ptr->base_name[k++] = player_ptr->name[i];
72 player_ptr->base_name[k++] = c;
76 if (!strncmp(PATH_SEP, player_ptr->name + i, strlen(PATH_SEP))) {
77 player_ptr->base_name[k++] = '_';
78 i += strlen(PATH_SEP);
81 else if (angband_strchr("\"*,/:;<>?\\|", c))
82 player_ptr->base_name[k++] = '_';
84 else if (isprint(c)) {
85 player_ptr->base_name[k++] = c;
89 player_ptr->base_name[k] = '\0';
90 if (!player_ptr->base_name[0]) {
91 strcpy(player_ptr->base_name, "PLAYER");
94 auto is_modified = false;
95 if (is_new_savefile && (savefile.empty() || !keep_savefile)) {
98 #ifdef SAVEFILE_USE_UID
99 ss << UnixUserIds::get_instance().get_user_id();
100 ss << '.' << player_ptr->base_name;
102 ss << player_ptr->base_name;
104 savefile = path_build(ANGBAND_DIR_SAVE, ss.str());
108 if (is_modified || savefile_base.empty()) {
109 #ifdef SAVEFILE_USE_UID
110 const auto &savefile_str = savefile.filename().string();
111 const auto split = str_split(savefile_str, '.');
112 savefile_base = split[1];
114 savefile_base = savefile.filename().string();
118 if (w_ptr->character_generated && !streq(old_player_base, player_ptr->base_name)) {
119 autopick_load_pref(player_ptr, false);
124 * @brief プレイヤーの名前を変更する
125 * @param player_ptr プレイヤーへの参照ポインタ
126 * @details PlayerType::name は32バイトで定義されているが、
127 * スコアファイル(lib/apex/scores.raw)に保存されているプレイヤー名が最大16バイト (ヌル文字含)となっている
130 void get_name(PlayerType *player_ptr)
132 const auto finalizer = util::make_finalizer([player_ptr]() {
133 display_player_misc_info(player_ptr);
136 std::string initial_name(player_ptr->name);
137 const auto max_name_size = 15;
138 const auto copy_size = sizeof(player_ptr->name);
139 constexpr auto prompt = _("キャラクターの名前を入力して下さい: ", "Enter a name for your character: ");
140 const auto name = input_string(prompt, max_name_size, initial_name);
142 if (!name->empty()) {
143 angband_strcpy(player_ptr->name, name.value(), copy_size);
149 if (initial_name.empty()) {
150 angband_strcpy(player_ptr->name, "PLAYER", copy_size);