OSDN Git Service

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