5 * @author Hengband Team
9 #include "core/asking-player.h"
10 #include "core/stuff-handler.h"
11 #include "core/turn-compensator.h"
12 #include "core/visuals-reseter.h"
13 #include "game-option/special-options.h"
14 #include "io-dump/character-dump.h"
15 #include "io/input-key-acceptor.h"
16 #include "mind/mind-elementalist.h"
17 #include "net/http-client.h"
18 #include "player-base/player-class.h"
19 #include "player-info/class-info.h"
20 #include "player-info/race-info.h"
21 #include "player/player-personality.h"
22 #include "player/player-status.h"
23 #include "realm/realm-names-table.h"
24 #include "system/angband-version.h"
25 #include "system/dungeon-info.h"
26 #include "system/floor-type-definition.h"
27 #include "system/player-type-definition.h"
28 #include "system/redrawing-flags-updater.h"
29 #include "system/system-variables.h"
30 #include "term/gameterm.h"
31 #include "term/screen-processor.h"
32 #include "term/z-form.h"
33 #include "util/angband-files.h"
34 #include "view/display-messages.h"
35 #include "world/world.h"
41 #include <string_view>
46 concptr screen_dump = nullptr;
49 constexpr auto SCORE_POST_URL = "http://mars.kmc.gr.jp/~dis/heng_score/register_score.php"; /*!< スコア開示URL */
52 static constexpr auto get_score_content_type()
56 return "text/plain; charset=SHIFT_JIS";
59 return "text/plain; charset=EUC-JP";
62 return "text/plain; charset=ASCII";
67 * @brief スコアサーバにスコアを送信する
68 * @param score_data 送信するスコアデータ
69 * @return 送信に成功した場合true、失敗した場合false
71 static bool post_score_to_score_server(PlayerType *player_ptr, const std::string &score_data)
74 client.user_agent = format("Hengband %d.%d.%d", H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH);
80 prt(_("スコア送信中...", "Sending the score..."), 0, 0);
83 const auto res = client.post(SCORE_POST_URL, score_data, get_score_content_type());
84 if (res.has_value() && (res->status == 200)) {
88 prt(_("スコア・サーバへの送信に失敗しました。", "Failed to send to the score server."), 0, 0);
90 if (!input_check_strict(player_ptr, _("もう一度接続を試みますか? ", "Try again? "), UserCheck::NO_HISTORY)) {
97 * @brief キャラクタダンプを引数で指定した出力ストリームに書き込む
98 * @param player_ptr プレイヤーへの参照ポインタ
99 * @param stream 書き込む出力ストリーム
102 static errr make_dump(PlayerType *player_ptr, std::ostream &stream)
105 GAME_TEXT file_name[1024];
107 /* Open a new file */
108 fff = angband_fopen_temp(file_name, 1024);
111 msg_format("一時ファイル %s を作成できませんでした。", file_name);
113 msg_format("Failed to create temporary file %s.", file_name);
119 /* 一旦一時ファイルを作る。通常のダンプ出力と共通化するため。 */
120 make_character_dump(player_ptr, fff);
123 // 一時ファイルを削除する前に閉じるためブロックにする
125 std::ifstream ifs(file_name);
126 stream << ifs.rdbuf();
136 * @brief スクリーンダンプを作成する/ Make screen dump to buffer
137 * @return 作成したスクリーンダンプの参照ポインタ
139 concptr make_screen_dump(PlayerType *player_ptr)
141 constexpr auto html_head =
142 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n"
144 constexpr auto html_foot =
146 "</body>\n</html>\n";
148 const auto [wid, hgt] = term_get_size();
149 std::stringstream screen_ss;
151 auto &rfu = RedrawingFlagsUpdater::get_instance();
152 bool old_use_graphics = use_graphics;
153 if (old_use_graphics) {
154 /* Clear -more- prompt first */
157 use_graphics = false;
158 reset_visuals(player_ptr);
160 static constexpr auto flags = {
161 MainWindowRedrawingFlag::WIPE,
162 MainWindowRedrawingFlag::BASIC,
163 MainWindowRedrawingFlag::EXTRA,
164 MainWindowRedrawingFlag::MAP,
165 MainWindowRedrawingFlag::EQUIPPY,
167 rfu.set_flags(flags);
168 handle_stuff(player_ptr);
171 screen_ss << html_head;
173 /* Dump the screen */
174 for (int y = 0; y < hgt; y++) {
181 TERM_COLOR a = 0, old_a = 0;
183 for (int x = 0; x < wid - 1; x++) {
185 concptr cc = nullptr;
186 /* Get the attr/char */
187 (void)(term_what(x, y, &a, &c));
210 c = (a == 0x09) ? '%' : '#';
216 if ((y == 0 && x == 0) || a != old_a) {
217 rv = angband_color_table[a][1];
218 gv = angband_color_table[a][2];
219 bv = angband_color_table[a][3];
220 screen_ss << format("%s<font color=\"#%02x%02x%02x\">", ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
232 screen_ss << "</font>\n";
234 screen_ss << html_foot;
237 if (const auto screen_dump_size = screen_ss.tellp();
238 (0 <= screen_dump_size) && (screen_dump_size < SCREEN_BUF_MAX_SIZE)) {
239 ret = string_make(screen_ss.str().data());
244 if (!old_use_graphics) {
249 reset_visuals(player_ptr);
250 static constexpr auto flags = {
251 MainWindowRedrawingFlag::WIPE,
252 MainWindowRedrawingFlag::BASIC,
253 MainWindowRedrawingFlag::EXTRA,
254 MainWindowRedrawingFlag::MAP,
255 MainWindowRedrawingFlag::EQUIPPY,
257 rfu.set_flags(flags);
258 handle_stuff(player_ptr);
263 * @brief スコア転送処理のメインルーチン
264 * @param player_ptr プレイヤーへの参照ポインタ
265 * @return 正常にスコアを送信できたらtrue、失敗時に送信を中止したらfalse
267 bool report_score(PlayerType *player_ptr)
269 std::stringstream score_ss;
270 std::string personality_desc = ap_ptr->title;
271 personality_desc.append(_(ap_ptr->no ? "の" : "", " "));
273 auto realm1_name = PlayerClass(player_ptr).equals(PlayerClassType::ELEMENTALIST) ? get_element_title(player_ptr->element) : realm_names[player_ptr->realm1];
274 score_ss << format("name: %s\n", player_ptr->name)
275 << format("version: %s\n", get_version().data())
276 << format("score: %ld\n", calc_score(player_ptr))
277 << format("level: %d\n", player_ptr->lev)
278 << format("depth: %d\n", player_ptr->current_floor_ptr->dun_level)
279 << format("maxlv: %d\n", player_ptr->max_plv)
280 << format("maxdp: %d\n", max_dlv[DUNGEON_ANGBAND])
281 << format("au: %d\n", player_ptr->au)
282 << format("turns: %d\n", turn_real(player_ptr, w_ptr->game_turn))
283 << format("sex: %d\n", player_ptr->psex)
284 << format("race: %s\n", rp_ptr->title)
285 << format("class: %s\n", cp_ptr->title)
286 << format("seikaku: %s\n", personality_desc.data())
287 << format("realm1: %s\n", realm1_name)
288 << format("realm2: %s\n", realm_names[player_ptr->realm2])
289 << format("killer: %s\n", player_ptr->died_from.data())
290 << "-----charcter dump-----\n";
292 make_dump(player_ptr, score_ss);
294 score_ss << "-----screen shot-----\n"
298 return post_score_to_score_server(player_ptr, score_ss.str());
301 concptr screen_dump = nullptr;
302 #endif /* WORLD_SCORE */