OSDN Git Service

MPWで、-noMapCR オプションは弊害が非常に大きく使用不可なので、ローカルで使う
[hengbandforosx/hengbandosx.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 /*#define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/scoretest/score.cgi" */
37
38 /*
39  * simple buffer library
40  */
41
42 typedef struct {
43         size_t max_size;
44         size_t size;
45         char *data;
46 } BUF;
47
48 #define BUFSIZE (65536)
49
50 #ifndef HAVE_VASPRINTF
51 #define vasprintf       Vasprintf
52
53 static int Vasprintf(char **buf, const char *fmt, va_list ap)
54 {
55         int ret;
56
57         *buf = malloc(1024);
58
59 #if defined(HAVE_VSNPRINTF)
60         ret = vsnprintf(*buf, 1024, fmt, ap);
61 #else
62         ret = vsprintf(*buf, fmt, ap);
63 #endif
64         return ret;
65 }
66
67 #endif /* ifndef HAVE_VASPRINTF */ 
68
69 static BUF* buf_new(void)
70 {
71         BUF *p;
72
73         if ((p = malloc(sizeof(BUF))) == NULL)
74                 return NULL;
75
76         p->size = 0;
77         p->max_size = BUFSIZE;
78         if ((p->data = malloc(BUFSIZE)) == NULL)
79         {
80                 free(p);
81                 return NULL;
82         }
83         return p;
84 }
85
86 static void buf_delete(BUF *b)
87 {
88         free(b->data);
89         free(b);
90 }
91
92 static int buf_append(BUF *buf, const char *data, size_t size)
93 {
94         while (buf->size + size > buf->max_size)
95         {
96                 char *tmp;
97                 if ((tmp = malloc(buf->max_size * 2)) == NULL) return -1;
98
99                 memcpy(tmp, buf->data, buf->max_size);
100                 free(buf->data);
101
102                 buf->data = tmp;
103
104                 buf->max_size *= 2;
105         }
106         memcpy(buf->data + buf->size, data, size);
107         buf->size += size;
108
109         return buf->size;
110 }
111
112 static int buf_sprintf(BUF *buf, const char *fmt, ...)
113 {
114         int             ret;
115         char    *tmpbuf;
116         va_list ap;
117
118         va_start(ap, fmt);
119         vasprintf(&tmpbuf, fmt, ap);
120         va_end(ap);
121
122         if(!tmpbuf) return -1;
123
124 #ifdef MAC_MPW
125         {
126                 /* '\n' is 0x0D and '\r' is 0x0A in MPW. Swap back these. */
127                 char *ptr;
128                 for (ptr = tmpbuf; *ptr; ptr++)
129                         if ('\n' == *ptr) *ptr = '\r';
130         }
131 #endif
132
133         ret = buf_append(buf, tmpbuf, strlen(tmpbuf));
134
135         free(tmpbuf);
136
137         return ret;
138 }
139
140 #if 0
141 static int buf_read(BUF *buf, int fd)
142 {
143         int len;
144 #ifndef MACINTOSH
145         char tmp[BUFSIZE];
146 #else
147         char *tmp;
148         
149         tmp = calloc( BUFSIZE , sizeof(char) );
150 #endif
151
152         while ((len = read(fd, tmp, BUFSIZE)) > 0)
153                 buf_append(buf, tmp, len);
154
155         return buf->size;
156 }
157 #endif
158
159 #if 0
160 static int buf_write(BUF *buf, int fd)
161 {
162         write(fd, buf->data, buf->size);
163
164         return buf->size;
165 }
166
167 static int buf_search(BUF *buf, const char *str)
168 {
169         char *ret;
170
171         ret = strstr(buf->data, str);
172
173         if (!ret) return -1;
174
175         return ret - buf->data;
176 }
177
178 static BUF * buf_subbuf(BUF *buf, int pos1, size_t sz)
179 {
180         BUF *ret;
181
182         if (pos1 < 0) return NULL;
183
184         ret = buf_new();
185
186         if (sz <= 0) sz = buf->size - pos1;
187
188         buf_append(ret, buf->data + pos1, sz);
189
190         return ret;
191 }
192 #endif
193
194 static void http_post(int sd, char *url, BUF *buf)
195 {
196         BUF *output;
197
198         output = buf_new();
199         buf_sprintf(output, "POST %s HTTP/1.0\n", url);
200         buf_sprintf(output, "User-Agent: Hengband %d.%d.%d\n",
201                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
202
203         buf_sprintf(output, "Content-Length: %d\n", buf->size);
204         buf_sprintf(output, "Content-Encoding: binary\n");
205         buf_sprintf(output, "Content-Type: application/octet-stream\n");
206         buf_sprintf(output, "\n");
207         buf_append(output, buf->data, buf->size);
208
209         soc_write(sd, output->data, output->size);
210 }
211
212
213 /* ¥­¥ã¥é¥¯¥¿¥À¥ó¥×¤òºî¤Ã¤Æ BUF¤ËÊݸ */
214 static errr make_dump(BUF* dumpbuf)
215 {
216         errr make_character_dump(FILE *fff);
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 char *html_head[] = {
272                 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
273                 "<pre>",
274                 0,
275         };
276         static char *html_foot[] = {
277                 "</pre>\n",
278                 "</body>\n</html>\n",
279                 0,
280         };
281
282         if (use_graphics)
283                 return NULL;
284
285         /* Alloc buffer */
286         screen_buf = buf_new();
287         if (screen_buf == NULL) return (NULL);
288
289         for (i = 0; html_head[i]; i++)
290                 buf_sprintf(screen_buf, html_head[i]);
291
292         /* Dump the screen */
293         for (y = 0; y < 24; y++)
294         {
295                 /* Start the row */
296                 if (y != 0)
297                         buf_sprintf(screen_buf, "\n");
298
299                 /* Dump each row */
300                 for (x = 0; x < 79; x++)
301                 {
302                         int rv, gv, bv;
303                         char *cc = NULL;
304                         /* Get the attr/char */
305                         (void)(Term_what(x, y, &a, &c));
306
307                         switch (c)
308                         {
309                         case '&': cc = "&amp;"; break;
310                         case '<': cc = "&lt;"; break;
311                         case '>': cc = "&gt;"; break;
312 #ifdef WINDOWS
313                         case 0x1f: c = '.'; break;
314                         case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
315 #endif
316                         }
317
318                         a = a & 0x0F;
319                         if ((y == 0 && x == 0) || a != old_a) {
320                                 rv = angband_color_table[a][1];
321                                 gv = angband_color_table[a][2];
322                                 bv = angband_color_table[a][3];
323                                 buf_sprintf(screen_buf, "%s<font color=\"#%02x%02x%02x\">", 
324                                             ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
325                                 old_a = a;
326                         }
327                         if (cc)
328                                 buf_sprintf(screen_buf, "%s", cc);
329                         else
330                                 buf_sprintf(screen_buf, "%c", c);
331                 }
332         }
333         buf_sprintf(screen_buf, "</font>");
334
335         for (i = 0; html_foot[i]; i++)
336                 buf_sprintf(screen_buf, html_foot[i]);
337
338         /* Screen dump size is too big ? */
339         if (screen_buf->size + 1> SCREEN_BUF_SIZE)
340         {
341                 buf_delete(screen_buf);
342                 return (NULL);
343         }
344
345         /* Terminate string */
346         buf_append(screen_buf, "", 1);
347
348         ret = string_make(screen_buf->data);
349
350         /* Free buffer */
351         buf_delete(screen_buf);
352
353         return ret;
354 }
355
356
357 errr report_score(void)
358 {
359 #ifdef MACINTOSH
360         OSStatus err;
361 #else
362         errr err = 0;
363 #endif
364
365 #ifdef WINDOWS
366         WSADATA wsaData;
367         WORD wVersionRequested =(WORD) (( 1) |  ( 1 << 8));
368 #endif
369
370         BUF *score;
371         int sd;
372         char seikakutmp[128];
373
374         score = buf_new();
375
376 #ifdef JP
377         sprintf(seikakutmp, "%s%s", ap_ptr->title, (ap_ptr->no ? "¤Î" : ""));
378 #else
379         sprintf(seikakutmp, "%s ", ap_ptr->title);
380 #endif
381
382         buf_sprintf(score, "name: %s\n", player_name);
383 #ifdef JP
384         buf_sprintf(score, "version: ÊѶòÈÚÅÜ %d.%d.%d\n",
385                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
386 #else
387         buf_sprintf(score, "version: Hengband %d.%d.%d\n",
388                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
389 #endif
390         buf_sprintf(score, "score: %d\n", total_points());
391         buf_sprintf(score, "level: %d\n", p_ptr->lev);
392         buf_sprintf(score, "depth: %d\n", dun_level);
393         buf_sprintf(score, "maxlv: %d\n", p_ptr->max_plv);
394         buf_sprintf(score, "maxdp: %d\n", max_dlv[DUNGEON_ANGBAND]);
395         buf_sprintf(score, "au: %d\n", p_ptr->au);
396         buf_sprintf(score, "turns: %d\n", turn_real(turn));
397         buf_sprintf(score, "sex: %d\n", p_ptr->psex);
398         buf_sprintf(score, "race: %s\n", rp_ptr->title);
399         buf_sprintf(score, "class: %s\n", cp_ptr->title);
400         buf_sprintf(score, "seikaku: %s\n", seikakutmp);
401         buf_sprintf(score, "realm1: %s\n", realm_names[p_ptr->realm1]);
402         buf_sprintf(score, "realm2: %s\n", realm_names[p_ptr->realm2]);
403         buf_sprintf(score, "killer: %s\n", died_from);
404         buf_sprintf(score, "-----charcter dump-----\n");
405
406         make_dump(score);
407
408         if (screen_dump)
409         {
410                 buf_sprintf(score, "-----screen shot-----\n");
411                 buf_append(score, screen_dump, strlen(screen_dump));
412         }
413         
414 #ifdef WINDOWS
415         if (WSAStartup(wVersionRequested, &wsaData))
416         {
417                 msg_print("Report: WSAStartup failed.");
418                 goto report_end;
419         }
420 #endif
421
422 #ifdef MACINTOSH
423 #if TARGET_API_MAC_CARBON
424         err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
425 #else
426         err = InitOpenTransport();
427 #endif
428         if (err != noErr)
429         {
430                 msg_print("Report: OpenTransport failed.");
431                 return 1;
432         }
433 #endif
434
435         Term_clear();
436
437         while (1)
438         {
439                 char buff[160];
440 #ifdef JP
441                 prt("ÀܳÃæ...", 0, 0);
442 #else
443                 prt("connecting...", 0, 0);
444 #endif
445                 Term_fresh();
446                 
447                 sd = connect_scoreserver();
448                 if (!(sd < 0)) break;
449 #ifdef JP
450                 sprintf(buff, "¥¹¥³¥¢¡¦¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£(%s)", soc_err());
451 #else
452                 sprintf(buff, "Failed to connect to the score server.(%s)", soc_err());
453 #endif
454                 prt(buff, 0, 0);
455                 (void)inkey();
456                 
457 #ifdef JP
458                 if (!get_check("¤â¤¦°ìÅÙÀܳ¤ò»î¤ß¤Þ¤¹¤«? "))
459 #else
460                 if (!get_check("Try again? "))
461 #endif
462                 {
463                         err = 1;
464                         goto report_end;
465                 }
466         }
467 #ifdef JP
468         prt("¥¹¥³¥¢Á÷¿®Ãæ...", 0, 0);
469 #else
470         prt("Sending the score...", 0, 0);
471 #endif
472         Term_fresh();
473         http_post(sd, SCORE_PATH, score);
474
475         disconnect_server(sd);
476  report_end:
477 #ifdef WINDOWS
478         WSACleanup();
479 #endif
480
481 #ifdef MACINTOSH
482 #if TARGET_API_MAC_CARBON
483         CloseOpenTransportInContext(NULL);
484 #else
485         CloseOpenTransport();
486 #endif
487 #endif
488
489         return err;
490 }
491
492 #endif /* WORLD_SCORE */