OSDN Git Service

Add Doxygen comment to monster1.c.
[hengband/hengband.git] / src / tmp / report.c
1 /* File: report.c */
2
3 #define _GNU_SOURCE
4 #include "angband.h"
5
6 #ifdef WORLD_SCORE
7
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <ctype.h>
11 #include <string.h>
12
13 #if defined(WINDOWS)
14 #include <winsock.h>
15 #elif defined(MACINTOSH)
16 #include <OpenTransport.h>
17 #include <OpenTptInternet.h>
18 #else
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netdb.h>
23 #include <sys/time.h>
24
25 #include <setjmp.h>
26 #include <signal.h>
27 #endif
28
29 /*
30  * internet resource value
31  */
32 #define HTTP_PROXY ""                   /* Default proxy url */
33 #define HTTP_PROXY_PORT 0               /* Default proxy port */
34 #define HTTP_TIMEOUT    20              /* Timeout length (second) */
35 #define SCORE_SERVER "www.kmc.gr.jp"    /* Default score server url */
36 #define SCORE_PORT 80                   /* Default score server port */
37
38 #ifdef JP
39 #define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/hengscore/score.cgi"
40 #else
41 #define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/hengscore-en/score.cgi"
42 #endif
43
44 /* for debug */
45 #if 0
46 #define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/scoretest/score.cgi"
47 #endif
48
49 /*
50  * simple buffer library
51  */
52
53 typedef struct {
54         size_t max_size;
55         size_t size;
56         char *data;
57 } BUF;
58
59 #define BUFSIZE (65536)
60
61 static BUF* buf_new(void)
62 {
63         BUF *p;
64
65         if ((p = malloc(sizeof(BUF))) == NULL)
66                 return NULL;
67
68         p->size = 0;
69         p->max_size = BUFSIZE;
70         if ((p->data = malloc(BUFSIZE)) == NULL)
71         {
72                 free(p);
73                 return NULL;
74         }
75         return p;
76 }
77
78 static void buf_delete(BUF *b)
79 {
80         free(b->data);
81         free(b);
82 }
83
84 static int buf_append(BUF *buf, const char *data, size_t size)
85 {
86         while (buf->size + size > buf->max_size)
87         {
88                 char *tmp;
89                 if ((tmp = malloc(buf->max_size * 2)) == NULL) return -1;
90
91                 memcpy(tmp, buf->data, buf->max_size);
92                 free(buf->data);
93
94                 buf->data = tmp;
95
96                 buf->max_size *= 2;
97         }
98         memcpy(buf->data + buf->size, data, size);
99         buf->size += size;
100
101         return buf->size;
102 }
103
104 static int buf_sprintf(BUF *buf, const char *fmt, ...)
105 {
106         int             ret;
107         char    tmpbuf[8192];
108         va_list ap;
109
110         va_start(ap, fmt);
111 #if defined(HAVE_VSNPRINTF)
112         ret = vsnprintf(tmpbuf, sizeof(tmpbuf), fmt, ap);
113 #else
114         ret = vsprintf(tmpbuf, fmt, ap);
115 #endif
116         va_end(ap);
117
118         if (ret < 0) return -1;
119
120 #if ('\r' == 0x0a && '\n' == 0x0d)
121         {
122                 /*
123                  * Originally '\r'= CR (= 0x0d) and '\n'= LF (= 0x0a)
124                  * But for MPW (Macintosh Programers Workbench), these
125                  * are reversed so that '\r'=LF and '\n'=CR unless the
126                  * -noMapCR option is not defined.
127                  *
128                  * We need to swap back these here since the score
129                  * dump text should be written using LF as the end of
130                  * line.
131                  */
132                 char *ptr;
133                 for (ptr = tmpbuf; *ptr; ptr++)
134                 {
135                         if (0x0d == *ptr) *ptr = 0x0a;
136                 }
137         }
138 #endif
139
140         ret = buf_append(buf, tmpbuf, strlen(tmpbuf));
141
142         return ret;
143 }
144
145 #if 0
146 static int buf_read(BUF *buf, int fd)
147 {
148         int len;
149 #ifndef MACINTOSH
150         char tmp[BUFSIZE];
151 #else
152         char *tmp;
153         
154         tmp = calloc( BUFSIZE , sizeof(char) );
155 #endif
156
157         while ((len = read(fd, tmp, BUFSIZE)) > 0)
158                 buf_append(buf, tmp, len);
159
160         return buf->size;
161 }
162 #endif
163
164 #if 0
165 static int buf_write(BUF *buf, int fd)
166 {
167         write(fd, buf->data, buf->size);
168
169         return buf->size;
170 }
171
172 static int buf_search(BUF *buf, const char *str)
173 {
174         char *ret;
175
176         ret = my_strstr(buf->data, str);
177
178         if (!ret) return -1;
179
180         return ret - buf->data;
181 }
182
183 static BUF * buf_subbuf(BUF *buf, int pos1, size_t sz)
184 {
185         BUF *ret;
186
187         if (pos1 < 0) return NULL;
188
189         ret = buf_new();
190
191         if (sz <= 0) sz = buf->size - pos1;
192
193         buf_append(ret, buf->data + pos1, sz);
194
195         return ret;
196 }
197 #endif
198
199 static void http_post(int sd, cptr url, BUF *buf)
200 {
201         BUF *output;
202
203         output = buf_new();
204         buf_sprintf(output, "POST %s HTTP/1.0\n", url);
205         buf_sprintf(output, "User-Agent: Hengband %d.%d.%d\n",
206                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
207
208         buf_sprintf(output, "Content-Length: %d\n", buf->size);
209         buf_sprintf(output, "Content-Encoding: binary\n");
210         buf_sprintf(output, "Content-Type: application/octet-stream\n");
211         buf_sprintf(output, "\n");
212         buf_append(output, buf->data, buf->size);
213
214         soc_write(sd, output->data, output->size);
215 }
216
217
218 /* ¥­¥ã¥é¥¯¥¿¥À¥ó¥×¤òºî¤Ã¤Æ BUF¤ËÊݸ */
219 static errr make_dump(BUF* dumpbuf)
220 {
221         char            buf[1024];
222         FILE *fff;
223         char file_name[1024];
224
225         /* Open a new file */
226         fff = my_fopen_temp(file_name, 1024);
227         if (!fff)
228         {
229 #ifdef JP
230                 msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
231 #else
232                 msg_format("Failed to create temporary file %s.", file_name);
233 #endif
234                 msg_print(NULL);
235                 return 1;
236         }
237
238         /* °ìö°ì»þ¥Õ¥¡¥¤¥ë¤òºî¤ë¡£Ä̾ï¤Î¥À¥ó¥×½ÐÎϤȶ¦Ä̲½¤¹¤ë¤¿¤á¡£ */
239         (void)make_character_dump(fff);
240
241         /* Close the file */
242         my_fclose(fff);
243
244         /* Open for read */
245         fff = my_fopen(file_name, "r");
246
247         while (fgets(buf, 1024, fff))
248         {
249                 (void)buf_sprintf(dumpbuf, "%s", buf);
250         }
251
252         /* Close the file */
253         my_fclose(fff);
254
255         /* Remove the file */
256         fd_kill(file_name);
257
258         /* Success */
259         return (0);
260 }
261
262 /*
263  * Make screen dump to buffer
264  */
265 cptr make_screen_dump(void)
266 {
267         BUF *screen_buf;
268         int y, x, i;
269         cptr ret;
270
271         byte a = 0, old_a = 0;
272         char c = ' ';
273
274         static cptr html_head[] = {
275                 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
276                 "<pre>",
277                 0,
278         };
279         static cptr html_foot[] = {
280                 "</pre>\n",
281                 "</body>\n</html>\n",
282                 0,
283         };
284
285         bool old_use_graphics = use_graphics;
286
287         int wid, hgt;
288
289         Term_get_size(&wid, &hgt);
290
291         /* Alloc buffer */
292         screen_buf = buf_new();
293         if (screen_buf == NULL) return (NULL);
294
295         if (old_use_graphics)
296         {
297                 /* Clear -more- prompt first */
298                 msg_print(NULL);
299
300                 use_graphics = FALSE;
301                 reset_visuals();
302
303                 /* Redraw everything */
304                 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
305
306                 /* Hack -- update */
307                 handle_stuff();
308         }
309
310         for (i = 0; html_head[i]; i++)
311                 buf_sprintf(screen_buf, html_head[i]);
312
313         /* Dump the screen */
314         for (y = 0; y < hgt; y++)
315         {
316                 /* Start the row */
317                 if (y != 0)
318                         buf_sprintf(screen_buf, "\n");
319
320                 /* Dump each row */
321                 for (x = 0; x < wid - 1; x++)
322                 {
323                         int rv, gv, bv;
324                         cptr cc = NULL;
325                         /* Get the attr/char */
326                         (void)(Term_what(x, y, &a, &c));
327
328                         switch (c)
329                         {
330                         case '&': cc = "&amp;"; break;
331                         case '<': cc = "&lt;"; break;
332                         case '>': cc = "&gt;"; break;
333 #ifdef WINDOWS
334                         case 0x1f: c = '.'; break;
335                         case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
336 #endif
337                         }
338
339                         a = a & 0x0F;
340                         if ((y == 0 && x == 0) || a != old_a) {
341                                 rv = angband_color_table[a][1];
342                                 gv = angband_color_table[a][2];
343                                 bv = angband_color_table[a][3];
344                                 buf_sprintf(screen_buf, "%s<font color=\"#%02x%02x%02x\">", 
345                                             ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
346                                 old_a = a;
347                         }
348                         if (cc)
349                                 buf_sprintf(screen_buf, "%s", cc);
350                         else
351                                 buf_sprintf(screen_buf, "%c", c);
352                 }
353         }
354         buf_sprintf(screen_buf, "</font>");
355
356         for (i = 0; html_foot[i]; i++)
357                 buf_sprintf(screen_buf, html_foot[i]);
358
359         /* Screen dump size is too big ? */
360         if (screen_buf->size + 1> SCREEN_BUF_SIZE)
361         {
362                 ret = NULL;
363         }
364         else
365         {
366                 /* Terminate string */
367                 buf_append(screen_buf, "", 1);
368
369                 ret = string_make(screen_buf->data);
370         }
371
372         /* Free buffer */
373         buf_delete(screen_buf);
374
375         if (old_use_graphics)
376         {
377                 use_graphics = TRUE;
378                 reset_visuals();
379
380                 /* Redraw everything */
381                 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
382
383                 /* Hack -- update */
384                 handle_stuff();
385         }
386
387         return ret;
388 }
389
390
391 errr report_score(void)
392 {
393 #ifdef MACINTOSH
394         OSStatus err;
395 #else
396         errr err = 0;
397 #endif
398
399 #ifdef WINDOWS
400         WSADATA wsaData;
401         WORD wVersionRequested =(WORD) (( 1) |  ( 1 << 8));
402 #endif
403
404         BUF *score;
405         int sd;
406         char seikakutmp[128];
407
408         score = buf_new();
409
410 #ifdef JP
411         sprintf(seikakutmp, "%s%s", ap_ptr->title, (ap_ptr->no ? "¤Î" : ""));
412 #else
413         sprintf(seikakutmp, "%s ", ap_ptr->title);
414 #endif
415
416         buf_sprintf(score, "name: %s\n", player_name);
417 #ifdef JP
418         buf_sprintf(score, "version: ÊѶòÈÚÅÜ %d.%d.%d\n",
419                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
420 #else
421         buf_sprintf(score, "version: Hengband %d.%d.%d\n",
422                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
423 #endif
424         buf_sprintf(score, "score: %d\n", total_points());
425         buf_sprintf(score, "level: %d\n", p_ptr->lev);
426         buf_sprintf(score, "depth: %d\n", dun_level);
427         buf_sprintf(score, "maxlv: %d\n", p_ptr->max_plv);
428         buf_sprintf(score, "maxdp: %d\n", max_dlv[DUNGEON_ANGBAND]);
429         buf_sprintf(score, "au: %d\n", p_ptr->au);
430         buf_sprintf(score, "turns: %d\n", turn_real(turn));
431         buf_sprintf(score, "sex: %d\n", p_ptr->psex);
432         buf_sprintf(score, "race: %s\n", rp_ptr->title);
433         buf_sprintf(score, "class: %s\n", cp_ptr->title);
434         buf_sprintf(score, "seikaku: %s\n", seikakutmp);
435         buf_sprintf(score, "realm1: %s\n", realm_names[p_ptr->realm1]);
436         buf_sprintf(score, "realm2: %s\n", realm_names[p_ptr->realm2]);
437         buf_sprintf(score, "killer: %s\n", p_ptr->died_from);
438         buf_sprintf(score, "-----charcter dump-----\n");
439
440         make_dump(score);
441
442         if (screen_dump)
443         {
444                 buf_sprintf(score, "-----screen shot-----\n");
445                 buf_append(score, screen_dump, strlen(screen_dump));
446         }
447         
448 #ifdef WINDOWS
449         if (WSAStartup(wVersionRequested, &wsaData))
450         {
451                 msg_print("Report: WSAStartup failed.");
452                 goto report_end;
453         }
454 #endif
455
456 #ifdef MACINTOSH
457 #if TARGET_API_MAC_CARBON
458         err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
459 #else
460         err = InitOpenTransport();
461 #endif
462         if (err != noErr)
463         {
464                 msg_print("Report: OpenTransport failed.");
465                 return 1;
466         }
467 #endif
468
469         Term_clear();
470
471         while (1)
472         {
473                 char buff[160];
474 #ifdef JP
475                 prt("ÀܳÃæ...", 0, 0);
476 #else
477                 prt("connecting...", 0, 0);
478 #endif
479                 Term_fresh();
480                 
481                 /* ¥×¥í¥­¥·¤òÀßÄꤹ¤ë */
482                 set_proxy(HTTP_PROXY, HTTP_PROXY_PORT);
483
484                 /* Connect to the score server */
485                 sd = connect_server(HTTP_TIMEOUT, SCORE_SERVER, SCORE_PORT);
486
487
488                 if (!(sd < 0)) break;
489 #ifdef JP
490                 sprintf(buff, "¥¹¥³¥¢¡¦¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£(%s)", soc_err());
491 #else
492                 sprintf(buff, "Failed to connect to the score server.(%s)", soc_err());
493 #endif
494                 prt(buff, 0, 0);
495                 (void)inkey();
496                 
497 #ifdef JP
498                 if (!get_check_strict("¤â¤¦°ìÅÙÀܳ¤ò»î¤ß¤Þ¤¹¤«? ", CHECK_NO_HISTORY))
499 #else
500                 if (!get_check_strict("Try again? ", CHECK_NO_HISTORY))
501 #endif
502                 {
503                         err = 1;
504                         goto report_end;
505                 }
506         }
507 #ifdef JP
508         prt("¥¹¥³¥¢Á÷¿®Ãæ...", 0, 0);
509 #else
510         prt("Sending the score...", 0, 0);
511 #endif
512         Term_fresh();
513         http_post(sd, SCORE_PATH, score);
514
515         disconnect_server(sd);
516  report_end:
517 #ifdef WINDOWS
518         WSACleanup();
519 #endif
520
521 #ifdef MACINTOSH
522 #if TARGET_API_MAC_CARBON
523         CloseOpenTransportInContext(NULL);
524 #else
525         CloseOpenTransport();
526 #endif
527 #endif
528
529         return err;
530 }
531
532 #endif /* WORLD_SCORE */