OSDN Git Service

bd509e7aa9c23cc9110bb8e66f8f2bb826e75959
[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 //#define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/scoretest/score.cgi"
37
38 /*
39   simple buffer library
40  */
41
42 typedef struct _buf{
43   size_t max_size;
44   size_t size;
45   char *data;
46 } BUF;
47
48 #define BUFSIZE (65536)
49
50 #if defined(WINDOWS) || defined(SUNOS4) || defined(MACINTOSH) || defined(SGI)
51 #define vasprintf       Vasprintf
52 #endif
53
54 #ifdef SUNOS4
55 static int Vasprintf(char **buf, const char *fmt, va_list ap)
56 {
57     int ret;
58
59     *buf = malloc(BUFSIZE);
60
61     ret = vsnprintf(*buf, BUFSIZE, fmt, ap);
62
63     return ret;
64 }
65 #endif
66
67 #if defined(WINDOWS) || defined(MACINTOSH) || defined(SGI)
68 static int Vasprintf(char **buf, const char *fmt, va_list ap)
69 {
70     int ret;
71     *buf = malloc(BUFSIZE * 4);
72
73     ret = vsprintf(*buf, fmt, ap);
74
75     return ret;
76 }
77 #endif
78
79 static BUF* buf_new(void)
80 {
81     BUF *p;
82
83     p = malloc(sizeof(BUF));
84     if((p = malloc(sizeof(BUF))) == NULL)
85         return NULL;
86
87     p->size = 0;
88     p->max_size = BUFSIZE;
89     if((p->data = malloc(BUFSIZE)) == NULL){
90         free(p);
91         return NULL;
92     }
93     return p;
94 }
95
96 #if 0
97 static void buf_delete(BUF *b)
98 {
99     free(b->data);
100     free(b);
101 }
102 #endif
103
104 static int buf_append(BUF *buf, const char *data, size_t size)
105 {
106     while(buf->size + size > buf->max_size){
107         char *tmp;
108         if((tmp = malloc(buf->max_size * 2)) == NULL) return -1;
109
110         memcpy(tmp, buf->data, buf->max_size);
111         free(buf->data);
112
113         buf->data = tmp;
114
115         buf->max_size *= 2;
116     }
117     memcpy(buf->data + buf->size, data, size);
118     buf->size += size;
119
120     return buf->size;
121 }
122
123 static int buf_sprintf(BUF *buf, const char *fmt, ...)
124 {
125     int         ret;
126     char        *tmpbuf;
127     va_list     ap;
128
129     va_start(ap, fmt);
130     vasprintf(&tmpbuf, fmt, ap);
131     va_end(ap);
132
133     if(!tmpbuf)
134         return -1;
135
136     ret = buf_append(buf, tmpbuf, strlen(tmpbuf));
137
138     free(tmpbuf);
139
140     return ret;
141 }
142
143 #if 0
144 static int buf_read(BUF *buf, int fd)
145 {
146     int len;
147 #ifndef MACINTOSH
148     char tmp[BUFSIZE];
149 #else
150         char *tmp;
151         
152         tmp = calloc( BUFSIZE , sizeof(char) );
153 #endif
154
155     while((len = read(fd, tmp, BUFSIZE)) > 0)
156         buf_append(buf, tmp, len);
157
158     return buf->size;
159 }
160 #endif
161
162 #if 0
163 static int buf_write(BUF *buf, int fd)
164 {
165     write(fd, buf->data, buf->size);
166
167     return buf->size;
168 }
169
170 static int buf_search(BUF *buf, const char *str)
171 {
172     char *ret;
173
174     ret = strstr(buf->data, str);
175
176     if(!ret)
177         return -1;
178
179     return ret - buf->data;
180 }
181
182 static BUF * buf_subbuf(BUF *buf, int pos1, size_t sz)
183 {
184     BUF *ret;
185
186     if(pos1 < 0)
187         return NULL;
188
189     ret = buf_new();
190
191     if(sz <= 0)
192         sz = buf->size - pos1;
193
194     buf_append(ret, buf->data + pos1, sz);
195
196     return ret;
197 }
198 #endif
199
200 static void http_post(int sd, char *url, BUF *buf)
201 {
202   BUF *output;
203
204   output = buf_new();
205   buf_sprintf(output, "POST %s HTTP/1.0\r\n", url);
206   buf_sprintf(output, "User-Agent: Hengband %d.%d.%d\r\n",
207               FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
208
209   buf_sprintf(output, "Content-Length: %d\r\n", buf->size);
210   buf_sprintf(output, "Content-Encoding: binary\r\n");
211   buf_sprintf(output, "Content-Type: application/octet-stream\r\n");
212   buf_sprintf(output, "\r\n");
213   buf_append(output, buf->data, buf->size);
214
215   soc_write(sd, output->data, output->size);
216 }
217
218
219 /* ¥­¥ã¥é¥¯¥¿¥À¥ó¥×¤òºî¤Ã¤Æ BUF¤ËÊݸ */
220 static errr make_dump(BUF* dumpbuf)
221 {
222         errr make_character_dump(FILE *fff);
223
224         char            buf[1024];
225         FILE *fff;
226         char file_name[1024];
227
228         /* Open a new file */
229         fff = my_fopen_temp(file_name, 1024);
230         if (!fff) {
231 #ifdef JP
232             msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
233 #else
234             msg_format("Failed to create temporary file %s.", file_name);
235 #endif
236             msg_print(NULL);
237             return 1;
238         }
239
240         /* °ìö°ì»þ¥Õ¥¡¥¤¥ë¤òºî¤ë¡£Ä̾ï¤Î¥À¥ó¥×½ÐÎϤȶ¦Ä̲½¤¹¤ë¤¿¤á¡£ */
241         (void)make_character_dump(fff);
242
243         /* Close the file */
244         my_fclose(fff);
245
246         /* Open for read */
247         fff = my_fopen(file_name, "r");
248
249         while (fgets(buf, 1024, fff))
250         {
251                 (void)buf_append(dumpbuf, buf, strlen(buf));
252         }
253
254         /* Remove the file */
255         fd_kill(file_name);
256
257         /* Success */
258         return (0);
259 }
260
261 errr report_score(void)
262 {
263 #ifdef MACINTOSH
264         OSStatus err;
265 #else
266         errr err = 0;
267 #endif
268
269 #ifdef WINDOWS
270     WSADATA wsaData;
271     WORD wVersionRequested =(WORD) (( 1) |  ( 1 << 8));
272 #endif
273
274
275   BUF *score;
276   int sd;
277   char date[10];
278   char seikakutmp[128];
279   time_t ct = time(NULL);
280
281   score = buf_new();
282
283 #ifdef JP
284   sprintf(seikakutmp, "%s%s", ap_ptr->title, (ap_ptr->no ? "¤Î" : ""));
285 #else
286   sprintf(seikakutmp, "%s ", ap_ptr->title);
287 #endif
288
289   /* HiperMegaHack -- Ê¸»ú¥³¡¼¥É¤òÁ÷¤ë */
290 #if defined(EUC)
291   buf_sprintf(score, "code: 0\n");
292 #elif defined(SJIS)
293   buf_sprintf(score, "code: 1\n");
294 #elif defined(JIS)
295   buf_sprintf(score, "code: 2\n");
296 #endif
297   buf_sprintf(score, "name: %s\n", player_name);
298 #ifdef JP
299   buf_sprintf(score, "version: ÊѶòÈÚÅÜ %d.%d.%d\n",
300               FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
301 #else
302   buf_sprintf(score, "version: Hengband %d.%d.%d\n",
303               FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
304 #endif
305   buf_sprintf(score, "score: %d\n", total_points());
306   buf_sprintf(score, "level: %d\n", p_ptr->lev);
307   buf_sprintf(score, "depth: %d\n", dun_level);
308   buf_sprintf(score, "maxlv: %d\n", p_ptr->max_plv);
309   buf_sprintf(score, "maxdp: %d\n", max_dlv[DUNGEON_ANGBAND]);
310   buf_sprintf(score, "au: %d\n", p_ptr->au);
311   buf_sprintf(score, "turns: %d\n", turn_real(turn));
312   buf_sprintf(score, "sex: %d\n", p_ptr->psex);
313   buf_sprintf(score, "race: %s\n", rp_ptr->title);
314   buf_sprintf(score, "class: %s\n", cp_ptr->title);
315   buf_sprintf(score, "seikaku: %s\n", seikakutmp);
316   buf_sprintf(score, "realm1: %s\n", realm_names[p_ptr->realm1]);
317   buf_sprintf(score, "realm2: %s\n", realm_names[p_ptr->realm2]);
318   buf_sprintf(score, "killer: %s\n", died_from);
319   strftime(date, 9, "%y/%m/%d", localtime(&ct));
320   buf_sprintf(score, "date: %s\n", date);
321   buf_sprintf(score, "-----charcter dump-----\n");
322
323   make_dump(score);
324
325 #ifdef WINDOWS
326     if(WSAStartup(wVersionRequested, &wsaData)){
327         msg_print("Report: WSAStartup failed.");
328         goto report_end;
329     }
330 #endif
331
332 #ifdef MACINTOSH
333 #if TARGET_API_MAC_CARBON
334         err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
335 #else
336         err = InitOpenTransport();
337 #endif
338         if (err != noErr){
339                 msg_print("Report: OpenTransport failed.");
340                 return 1;
341         }
342 #endif
343
344         Term_clear();
345
346         while(1)
347         {
348                 char buff[160];
349 #ifdef JP
350                 prt("ÀܳÃæ...", 0, 0);
351 #else
352                 prt("connecting...", 0, 0);
353 #endif
354                 Term_fresh();
355                 
356                 sd = connect_scoreserver();
357                 if (!(sd < 0)) break;
358 #ifdef JP
359                 sprintf(buff, "¥¹¥³¥¢¡¦¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£(%s)", soc_err());
360 #else
361                 sprintf(buff, "Failed to connect to the score server.(%s)", soc_err());
362 #endif
363                 prt(buff, 0, 0);
364                 (void)inkey();
365                 
366 #ifdef JP
367                 if(!get_check("¤â¤¦°ìÅÙÀܳ¤ò»î¤ß¤Þ¤¹¤«? "))
368 #else
369                 if(!get_check("Try again? "))
370 #endif
371                 {
372                         err = 1;
373                         goto report_end;
374                 }
375         }
376 #ifdef JP
377         prt("¥¹¥³¥¢Á÷¿®Ãæ...", 0, 0);
378 #else
379         prt("Sending the score...", 0, 0);
380 #endif
381         Term_fresh();
382         http_post(sd, SCORE_PATH, score);
383         
384         disconnect_server(sd);
385  report_end:
386 #ifdef WINDOWS
387         WSACleanup();
388 #endif
389
390 #ifdef MACINTOSH
391 #if TARGET_API_MAC_CARBON
392         CloseOpenTransportInContext(NULL);
393 #else
394         CloseOpenTransport();
395 #endif
396 #endif
397
398         return err;
399 }
400
401 #endif /* WORLD_SCORE */
402
403
404
405