OSDN Git Service

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