OSDN Git Service

106bda7c11c046b1f9a6cc629dc2a16942415568
[hengbandforosx/hengbandosx.git] / src / chuukei.c
1 /* chuukei.c */
2
3 #include "angband.h"
4
5 #ifdef CHUUKEI
6
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <ctype.h>
10
11 #if defined(WINDOWS)
12 #include <winsock.h>
13 #elif defined(MACINTOSH)
14 #include <OpenTransport.h>
15 #include <OpenTptInternet.h>
16 #else
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netdb.h>
21 #include <sys/time.h>
22 #include <arpa/inet.h>
23
24 #include <setjmp.h>
25 #include <signal.h>
26 #endif
27
28 #define MAX_HOSTNAME 256
29 #define RINGBUF_SIZE 65536*8
30 #define FRESH_QUEUE_SIZE 1024
31 #define WAIT 100*1000 /* ¥Ö¥é¥¦¥ºÂ¦¤Î¥¦¥¨¥¤¥È(usñ°Ì) */
32 #define DEFAULT_DELAY 50
33
34 static int sd; /* ¥½¥±¥Ã¥È¤Î¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿ */
35 static long epoch_time;  /* ³«»Ï»þ¹ï */
36 static long time_diff;   /* ¥×¥ì¥¤Â¦¤È¤Î»þ´Ö¤Î¤º¤ì(¤³¤ì¤ò¸«¤Ê¤¬¤é¥Ç¥£¥ì¥¤¤òÄ´À°¤·¤Æ¤¤¤¯) */
37 static int browse_delay; /* É½¼¨¤¹¤ë¤Þ¤Ç¤Î»þ´Ö(100msñ°Ì)(¤³¤Î´Ö¤Ë¥é¥°¤òµÛ¼ý¤¹¤ë) */
38 static int server_port;
39 static char server_name[MAX_HOSTNAME];
40
41
42 #ifdef WINDOWS
43 #define close closesocket
44 #endif
45
46 #ifdef MACINTOSH
47 static InetSvcRef inet_services = nil;
48 static EndpointRef ep                   = kOTInvalidEndpointRef;
49 #endif
50
51 /* ÉÁ²è¤¹¤ë»þ¹ï¤ò³Ð¤¨¤Æ¤ª¤¯¥­¥å¡¼¹½Â¤ÂΠ*/
52 static struct
53 {
54         int time[FRESH_QUEUE_SIZE];
55         int next;
56         int tail;
57 }fresh_queue;
58
59
60 /* ¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¹½Â¤ÂΠ*/
61 static struct
62 {
63         char *buf;
64         int wptr;
65         int rptr;
66         int inlen;
67 }ring;
68
69 #ifdef MACINTOSH
70 int recv(int s, char *buffer, size_t buflen, int flags)
71 {
72         OTFlags         junkFlags;
73         int n = OTRcv(ep, (void *) buffer, buflen, &junkFlags);
74         if( n <= 0 )
75                 return n;
76         return n;
77 }
78 #endif
79
80 /* ANSI C¤Ë¤è¤ì¤ÐstaticÊÑ¿ô¤Ï0¤Ç½é´ü²½¤µ¤ì¤ë¤¬°ì±þ½é´ü²½¤¹¤ë */
81 static errr init_chuukei(void)
82 {
83         fresh_queue.next = fresh_queue.tail = 0;
84         ring.wptr = ring.rptr = ring.inlen = 0;
85         fresh_queue.time[0] = 0;
86         ring.buf = malloc(RINGBUF_SIZE);
87         if (ring.buf == NULL) return (-1);
88
89         return (0);
90 }
91
92 /* ¸½ºß¤Î»þ´Ö¤ò100msñ°Ì¤Ç¼èÆÀ¤¹¤ë */
93 static long get_current_time(void)
94 {
95 #ifdef WINDOWS
96         return GetTickCount() / 100;
97 #elif defined(MACINTOSH)
98         return TickCount();
99 #else
100         struct timeval tv;
101         gettimeofday(&tv, NULL);
102
103         return (tv.tv_sec * 10 + tv.tv_usec / 100000);
104 #endif
105 }
106
107
108 /* ¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¹½Â¤ÂΤˠbuf ¤ÎÆâÍƤò²Ã¤¨¤ë */
109 static errr insert_ringbuf(char *buf)
110 {
111         int len;
112         len = strlen(buf) + 1; /* +1¤Ï½ªÃ¼Ê¸»úʬ */
113
114         /* ¥Ð¥Ã¥Õ¥¡¤ò¥ª¡¼¥Ð¡¼ */
115         if (ring.inlen + len >= RINGBUF_SIZE)
116         {
117                 chuukei_server = FALSE;
118                 chuukei_client = FALSE;
119
120                 prt("¥Ð¥Ã¥Õ¥¡¤¬°î¤ì¤Þ¤·¤¿¡£¥µ¡¼¥Ð¤È¤ÎÀܳ¤òÀÚÃǤ·¤Þ¤¹¡£", 0, 0);
121                 inkey();
122
123                 close(sd);
124
125                 return (-1);
126         }
127
128         /* ¥Ð¥Ã¥Õ¥¡¤Î½ªÃ¼¤Þ¤Ç¤Ë¼ý¤Þ¤ë */
129         if (ring.wptr + len < RINGBUF_SIZE)
130         {
131                 memcpy(ring.buf + ring.wptr, buf, len);
132                 ring.wptr += len;
133         }
134         /* ¥Ð¥Ã¥Õ¥¡¤Î½ªÃ¼¤Þ¤Ç¤Ë¼ý¤Þ¤é¤Ê¤¤(¥Ô¥Ã¥¿¥ê¼ý¤Þ¤ë¾ì¹ç¤â´Þ¤à) */
135         else
136         {
137                 int head = RINGBUF_SIZE - ring.wptr;  /* Á°È¾ */
138                 int tail = len - head;               /* ¸åȾ */
139
140                 memcpy(ring.buf + ring.wptr, buf, head);
141                 memcpy(ring.buf, buf + head, tail);
142                 ring.wptr = tail;
143         }
144
145         ring.inlen += len;
146
147         /* Success */
148         return (0);
149 }
150
151 void flush_ringbuf(void)
152 {
153 #ifndef MACINTOSH
154         fd_set fdset;
155         struct timeval tv;
156         int writen = 0;
157
158         if (!chuukei_server) return;
159
160         if (ring.inlen == 0) return;
161
162         tv.tv_sec = 0;
163         tv.tv_usec = 0;
164
165         FD_ZERO(&fdset);
166         FD_SET(sd, &fdset);
167
168         while (1)
169         {
170                 fd_set tmp_fdset;
171                 struct timeval tmp_tv;
172                 int result;
173
174                 tmp_fdset = fdset;
175                 tmp_tv = tv;
176
177                 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤ò½ñ¤­¹þ¤á¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
178                 select(sd+1, (fd_set *)NULL, &tmp_fdset, (fd_set *)NULL, &tv);
179
180                 /* ½ñ¤­¹þ¤á¤Ê¤±¤ì¤ÐÌá¤ë */
181                 if (FD_ISSET(sd, &tmp_fdset) == 0) break;
182
183                 result = send(sd, ring.buf + ring.rptr, ((ring.wptr > ring.rptr ) ? ring.wptr : RINGBUF_SIZE) - ring.rptr, 0);
184
185                 if (result <= 0)
186                 {
187                         /* ¥µ¡¼¥Ð¤È¤ÎÀܳÃÇ¡© */
188                         chuukei_server = FALSE;
189
190                         prt("¥µ¡¼¥Ð¤È¤ÎÀܳ¤¬ÀÚÃǤµ¤ì¤Þ¤·¤¿¡£", 0, 0);
191                         inkey();
192                         close(sd);
193
194                         return;
195                 }
196
197                 ring.rptr += result;
198                 ring.inlen -= result;
199                 writen += result;
200
201                 if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
202                 if (ring.inlen == 0) break;
203         }
204 #else
205         struct timeval tv;
206         int writen = 0;
207
208         if (!chuukei_server) return;
209
210         if (ring.inlen == 0) return;
211
212         tv.tv_sec = 0;
213         tv.tv_usec = 0;
214
215         while (1)
216         {
217                 struct timeval tmp_tv;
218                 int result;
219
220                 tmp_tv = tv;
221
222                 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤ò½ñ¤­¹þ¤á¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
223                 result = OTSnd(ep, ring.buf + ring.rptr, ((ring.wptr > ring.rptr ) ? ring.wptr : RINGBUF_SIZE) - ring.rptr, 0);
224
225                 if (result <= 0)
226                 {
227                         /* ¥µ¡¼¥Ð¤È¤ÎÀܳÃÇ¡© */
228                         chuukei_server = FALSE;
229
230                         prt("¥µ¡¼¥Ð¤È¤ÎÀܳ¤¬ÀÚÃǤµ¤ì¤Þ¤·¤¿¡£", 0, 0);
231                         inkey();
232                         close(sd);
233
234                         return;
235                 }
236
237                 ring.rptr += result;
238                 ring.inlen -= result;
239                 writen += result;
240
241                 if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
242                 if (ring.inlen == 0) break;
243         }
244 #endif
245 }
246
247 static int read_chuukei_prf(cptr prf_name)
248 {
249         char buf[1024];
250         FILE *fp;
251
252         path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA, prf_name);
253         fp = my_fopen(buf, "r");
254
255         if (!fp) return (-1);
256
257         /* ½é´ü²½ */
258         server_port = -1;
259         server_name[0] = 0;
260         browse_delay = DEFAULT_DELAY;
261
262         while (0 == my_fgets(fp, buf, sizeof(buf)))
263         {
264                 /* ¥µ¡¼¥Ð̾ */
265                 if (!strncmp(buf, "server:", 7))
266                 {
267                         strncpy(server_name, buf + 7, MAX_HOSTNAME - 1);
268                         server_name[MAX_HOSTNAME - 1] = '\0';
269                 }
270
271                 /* ¥Ý¡¼¥ÈÈÖ¹æ */
272                 if (!strncmp(buf, "port:", 5))
273                 {
274                         server_port = atoi(buf + 5);
275                 }
276
277                 /* ¥Ç¥£¥ì¥¤ */
278                 if (!strncmp(buf, "delay:", 6))
279                 {
280                         browse_delay = atoi(buf + 6);
281                 }
282         }
283
284         my_fclose(fp);
285
286         /* prf¥Õ¥¡¥¤¥ë¤¬´°Á´¤Ç¤Ê¤¤ */
287         if (server_port == -1 || server_name[0] == 0) return (-1);
288
289         return (0);
290 }
291
292 int connect_chuukei_server(char *prf_name)
293 {
294 #ifndef MACINTOSH
295
296 #ifdef WINDOWS
297         WSADATA wsaData;
298         WORD wVersionRequested = (WORD) (( 1) |  ( 1 << 8));
299 #endif
300
301         struct sockaddr_in ask;
302         struct hostent *hp;
303
304         if (read_chuukei_prf(prf_name) < 0)
305         {
306                 printf("Wrong prf file\n");
307                 return (-1);
308         }
309
310         if (init_chuukei() < 0)
311         {
312                 printf("Malloc error\n");
313                 return (-1);
314         }
315
316 #ifdef WINDOWS
317         if (WSAStartup(wVersionRequested, &wsaData))
318         {
319                 msg_print("Report: WSAStartup failed.");
320                 return (-1);
321         }
322 #endif
323
324         printf("server = %s\nport = %d\n", server_name, server_port);
325
326         if ((hp = gethostbyname(server_name)) != NULL)
327         {
328                 memset(&ask, 0, sizeof(ask));
329                 memcpy(&ask.sin_addr, hp->h_addr_list[0], hp->h_length);
330         }
331         else
332         {
333                 if ((ask.sin_addr.s_addr=inet_addr(server_name)) == 0)
334                 {
335                         printf("Bad hostname\n");
336                         return (-1);
337                 }
338         }
339
340         ask.sin_family = AF_INET;
341         ask.sin_port = htons((unsigned short)server_port);
342
343 #ifndef WINDOWS
344         if ((sd=socket(PF_INET,SOCK_STREAM, 0)) < 0)
345 #else
346         if ((sd=socket(PF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET)
347 #endif
348         {
349                 printf("Can't create socket\n");
350                 return (-1);
351         }
352
353         if (connect(sd, (struct sockaddr *)&ask, sizeof(ask)) < 0)
354         {
355                 close(sd);
356                 printf("Can't connect %s port %d\n", server_name, server_port);
357                 return (-1);
358         }
359
360         epoch_time = get_current_time();
361
362         return (0);
363 #else   /* MACINTOSH */
364         OSStatus err;
365         InetHostInfo    response;
366         InetHost                host_addr;
367         InetAddress     inAddr;
368         TCall                   sndCall;
369         Boolean                 bind    = false;
370         OSStatus        junk;
371
372         if (read_chuukei_prf(prf_name) < 0){
373                 printf("Wrong prf file\n");
374                 return (-1);
375         }
376         
377         init_chuukei();
378         
379         printf("server = %s\nport = %d\n", server_name, server_port);
380
381
382 #if TARGET_API_MAC_CARBON
383         err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
384 #else
385         err = InitOpenTransport();
386 #endif
387
388         memset(&response, 0, sizeof(response));
389
390
391 #if TARGET_API_MAC_CARBON
392         inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
393 #else
394         inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
395 #endif
396         
397         if (err == noErr) {
398                 err = OTInetStringToAddress(inet_services, (char *)server_name, &response);
399                 
400                 if (err == noErr) {
401                         host_addr = response.addrs[0];
402                 } else {
403                         printf("Bad hostname\n");
404                 }
405                 
406 #if TARGET_API_MAC_CARBON
407                 ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
408 #else
409                 ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
410 #endif
411
412                 if (err == noErr) {
413                         err = OTBind(ep, nil, nil);
414                         bind = (err == noErr);
415             }
416             if (err == noErr){
417                 OTInitInetAddress(&inAddr, server_port, host_addr);
418                         
419                         sndCall.addr.len        = sizeof(InetAddress);                          
420                         sndCall.addr.buf        = (unsigned char*) &inAddr;
421                         sndCall.opt.buf         = nil;        /* no connection options */
422                         sndCall.opt.len         = 0;
423                         sndCall.udata.buf       = nil;        /* no connection data */
424                         sndCall.udata.len       = 0;
425                         sndCall.sequence        = 0;          /* ignored by OTConnect */
426                         
427                         err = OTConnect(ep, &sndCall, NULL);
428                         
429                         if( err != noErr ){
430                                 printf("Can't connect %s port %d\n", server_name, server_port);
431                         }
432                 }
433                 
434                 err = OTSetSynchronous(ep);
435                 if (err == noErr)               
436                         err = OTSetBlocking(ep);
437                 
438         }
439         
440         if( err != noErr ){
441                 if( bind ){
442                         OTUnbind(ep);
443                 }
444                 /* Clean up. */
445                 if (ep != kOTInvalidEndpointRef) {
446                         OTCloseProvider(ep);
447                         ep = nil;
448                 }
449                 if (inet_services != nil) {
450                         OTCloseProvider(inet_services);
451                         inet_services = nil;
452                 }
453         
454                 return -1;
455         }
456         
457         return 0;
458
459 #endif
460 }
461
462 #ifdef SJIS
463 static void sjis2euc(char *str)
464 {
465         int i, l;
466         unsigned char c1, c2;
467         int kanji = 0;
468         int iseuc = 1;
469         l = strlen(str);
470
471         for (i = 0; i < l; i++)
472         {
473                 c1 = str[i];
474                 if (c1 & 0x80) kanji = 1;
475                 if (c1>=0x80 && (c1 < 0xa1 || c1 > 0xfe)) iseuc = 0;
476         }
477
478         if (kanji && !iseuc)
479         {
480                 unsigned char tmp[256];
481
482                 for (i = 0; i < l; i++)
483                 {
484                         c1 = str[i];
485                         if (c1 & 0x80)
486                         {
487                                 i++;
488                                 c2 = str[i];
489                                 if (c2 >= 0x9f)
490                                 {
491                                         c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe0 : 0x60);
492                                         c2 += 2;
493                                 }
494                                 else
495                                 {
496                                         c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe1 : 0x61);
497                                         c2 += 0x60 + (c2 < 0x7f);
498                                 }
499                                 tmp[i - 1] = c1;
500                                 tmp[i] = c2;
501                         }
502                         else
503                                 tmp[i] = c1;
504                 }
505                 tmp[l] = 0;
506                 strcpy(str, tmp);
507         }
508 }  
509
510 static void euc2sjis(char *str)
511 {
512         int i, l;
513         unsigned char c1, c2;
514         int kanji = 0;
515         int iseuc = 1;
516         l = strlen(str);
517
518         for (i = 0; i < l; i++)
519         {
520                 c1 = str[i];
521                 if (c1 & 0x80)  kanji = 1;
522                 if (c1>=0x80 && (c1 < 0xa1 || c1 > 0xfe)) iseuc = 0;
523         }
524         if (kanji && iseuc)
525         {
526                 unsigned char   tmp[256];
527
528                 for (i = 0; i < l; i++)
529                 {
530                         c1 = str[i];
531                         if (c1 & 0x80)
532                         {
533                                 i++;
534                                 c2 = str[i];
535                                 if (c1 % 2)
536                                 {
537                                         c1 = (c1 >> 1) + (c1 < 0xdf ? 0x31 : 0x71);
538                                         c2 -= 0x60 + (c2 < 0xe0);
539                                 }
540                                 else
541                                 {
542                                         c1 = (c1 >> 1) + (c1 < 0xdf ? 0x30 : 0x70);
543                                         c2 -= 2;
544                                 }
545
546                                 tmp[i - 1] = c1;
547                                 tmp[i] = c2;
548                         }
549                         else
550                                 tmp[i] = c1;
551                 }
552                 tmp[l] = 0;
553                 strcpy(str, tmp);
554         }
555 }  
556 #endif
557
558 /* str¤¬Æ±¤¸Ê¸»ú¤Î·«¤êÊÖ¤·¤«¤É¤¦¤«Ä´¤Ù¤ë */
559 static bool string_is_repeat(char *str, int len)
560 {
561         char c = str[0];
562         int i;
563
564         if (len < 2) return (FALSE);
565 #ifdef JP
566         if (iskanji(c)) return (FALSE);
567 #endif
568
569         for (i = 1; i < len; i++)
570         {
571 #ifdef JP
572                 if(c != str[i] || iskanji(str[i])) return (FALSE);
573 #else
574                 if(c != str[i]) return (FALSE);
575 #endif
576         }
577
578         return (TRUE);
579 }
580
581 void send_text_to_chuukei_server(int x, int y, int len, int col, char *str)
582 {
583         char buf[1024];
584         char buf2[1024];
585
586         if (!chuukei_server || Term != angband_term[0]) return;
587
588         strncpy(buf2, str, len);
589         buf2[len] = '\0';
590
591         if (len == 1)
592         {
593                 sprintf(buf, "s%c%c%c%c", x+1, y+1, col, buf2[0]);
594         }
595         else if(string_is_repeat(buf2, len))
596         {
597                 sprintf(buf, "n%c%c%c%c%c", x+1, y+1, len, col, buf2[0]);
598         }
599         else
600         {
601 #ifdef SJIS
602                 sjis2euc(buf2);
603 #endif
604                 sprintf(buf, "t%c%c%c%c%s", x+1, y+1, len, col, buf2);
605         }
606
607         insert_ringbuf(buf);
608 }
609
610 void send_wipe_to_chuukei_server(int x, int y, int len)
611 {
612         char buf[1024];
613
614         if (!chuukei_server || Term != angband_term[0]) return;
615
616         sprintf(buf, "w%c%c%c", x+1, y+1, len);
617
618         insert_ringbuf(buf);
619 }
620
621 void send_xtra_to_chuukei_server(int n)
622 {
623         char buf[1024];
624
625         if (!chuukei_server || Term != angband_term[0]) return;
626         sprintf(buf, "x%c", n+1);
627
628         insert_ringbuf(buf);
629
630         if (n == TERM_XTRA_FRESH)
631         {
632                 sprintf(buf, "d%ld", get_current_time() - epoch_time);
633                 insert_ringbuf(buf);
634         }
635 }
636
637 void send_curs_to_chuukei_server(int x, int y)
638 {
639         char buf[1024];
640
641         if (!chuukei_server || Term != angband_term[0]) return;
642         sprintf(buf, "c%c%c", x+1, y+1);
643
644         insert_ringbuf(buf);
645 }
646
647 static int read_sock(void)
648 {
649         char buf[1024];
650         int i;
651
652         for (i = 0;; i++)
653         {
654                 if (recv(sd, buf+i, 1, 0) <= 0) 
655                         return -1;
656
657                 if (buf[i] == '\0')
658                 {
659                         if (buf[0] == 'd')
660                         {
661                                 int timestamp = atoi(buf + 1);
662                                 long current_time = get_current_time();
663
664                                 /* ºÇ½é¤Î»þ´Ö¤òÊݸ¤·¤Æ¤ª¤¯ */
665                                 if (!fresh_queue.time[0])
666                                 {
667                                         epoch_time = current_time;
668                                         epoch_time += browse_delay;
669                                         epoch_time -= timestamp;
670                                         time_diff = current_time - timestamp;
671                                 }
672
673                                 fresh_queue.time[fresh_queue.tail] = timestamp;
674                                 fresh_queue.tail ++;
675
676                                 if (fresh_queue.tail == FRESH_QUEUE_SIZE)
677                                         fresh_queue.tail = 0;
678
679                                 /* ¥×¥ì¥¤Â¦¤È¤Î¥Ç¥£¥ì¥¤¤òÄ´À° */
680                                 if (time_diff > current_time - timestamp)
681                                 {
682                                         long old_time_diff = time_diff;
683                                         time_diff = current_time - timestamp;
684                                         epoch_time -= (old_time_diff - time_diff);
685                                 }
686
687                                 if (fresh_queue.tail == fresh_queue.next)
688                                 {
689                                         /* queue°î¤ì */
690                                         close(sd);
691                                         exit(1);
692                                 }
693
694                         }
695
696                         if (insert_ringbuf(buf) < 0) 
697                                 return -1;
698                         return (i);
699                 }
700         }
701 }
702
703
704 #ifndef WINDOWS
705 /* WinÈǤÎÃæÅÀ¤ÈÊɤÎƦÉå¤ò¥Ô¥ê¥ª¥É¤È¥·¥ã¡¼¥×¤Ë¤¹¤ë¡£ */
706 static void win2unix(int col, char *buf)
707 {
708         char kabe;
709         if ( col == 9 ) kabe = '%';
710         else            kabe = '#';
711
712         while (*buf)
713         {
714 #ifdef JP
715                 if (iskanji(*buf))
716                 {
717                         buf += 2;
718                         continue;
719                 }
720 #endif
721                 if (*buf == 127) *buf = kabe;
722                 else if(*buf == 31) *buf = '.';
723                 buf++;
724         }
725 }
726 #endif
727
728 static bool get_nextbuf(char *buf)
729 {
730         char *ptr = buf;
731
732         while (1)
733         {
734                 *ptr = ring.buf[ring.rptr ++];
735                 ring.inlen --;
736                 if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
737                 if (*ptr++ == '\0') break;
738         }
739
740         if (buf[0] == 'd') return (FALSE);
741
742         return (TRUE);
743 }
744
745 static bool flush_ringbuf_client(void)
746 {
747         char buf[1024];
748
749         /* ½ñ¤¯¥Ç¡¼¥¿¤Ê¤· */
750         if (fresh_queue.next == fresh_queue.tail) return (FALSE);
751
752         /* ¤Þ¤À½ñ¤¯¤Ù¤­»þ¤Ç¤Ê¤¤ */
753         if (fresh_queue.time[fresh_queue.next] > get_current_time() - epoch_time) return (FALSE);
754
755         /* »þ´Ö¾ðÊó(¶èÀÚ¤ê)¤¬ÆÀ¤é¤ì¤ë¤Þ¤Ç½ñ¤¯ */
756         while (get_nextbuf(buf))
757         {
758                 char id;
759                 int x, y, len, col;
760                 int i;
761                 char tmp1, tmp2, tmp3, tmp4;
762                 char *mesg;
763
764                 sscanf(buf, "%c%c%c%c%c", &id, &tmp1, &tmp2, &tmp3, &tmp4);
765                 x = tmp1-1; y = tmp2-1; len = tmp3; col = tmp4;
766                 if (id == 's')
767                 {
768                         col = tmp3;
769                         mesg = &buf[4];
770                 }
771                 else mesg = &buf[5];
772 #ifndef WINDOWS
773                 win2unix(col, mesg);
774 #endif
775
776                 switch (id)
777                 {
778                 case 't': /* Ä̾ï */
779 #ifdef SJIS
780                         euc2sjis(mesg);
781 #endif
782                         (void)((*angband_term[0]->text_hook)(x, y, len, (byte)col, mesg));
783                         strncpy(&Term->scr->c[y][x], mesg, len);
784                         for (i = x; i < x+len; i++)
785                         {
786                                 Term->scr->a[y][i] = col;
787                         }
788                         break;
789
790                 case 'n': /* ·«¤êÊÖ¤· */
791                         for (i = 1; i < len; i++)
792                         {
793                                 mesg[i] = mesg[0];
794                         }
795                         mesg[i] = '\0';
796                         (void)((*angband_term[0]->text_hook)(x, y, len, (byte)col, mesg));
797                         strncpy(&Term->scr->c[y][x], mesg, len);
798                         for (i = x; i < x+len; i++)
799                         {
800                                 Term->scr->a[y][i] = col;
801                         }
802                         break;
803
804                 case 's': /* °ìʸ»ú */
805                         (void)((*angband_term[0]->text_hook)(x, y, 1, (byte)col, mesg));
806                         strncpy(&Term->scr->c[y][x], mesg, 1);
807                         Term->scr->a[y][x] = col;
808                         break;
809
810                 case 'w':
811                         (void)((*angband_term[0]->wipe_hook)(x, y, len));
812                         break;
813
814                 case 'x':
815                         if (x == TERM_XTRA_CLEAR) Term_clear();
816                         (void)((*angband_term[0]->xtra_hook)(x, 0));
817                         break;
818
819                 case 'c':
820                         (void)((*angband_term[0]->curs_hook)(x, y));
821                         break;
822                 }
823         }
824
825         fresh_queue.next++;
826         if (fresh_queue.next == FRESH_QUEUE_SIZE) fresh_queue.next = 0;
827         return (TRUE);
828 }
829
830 void browse_chuukei()
831 {
832 #ifndef MACINTOSH
833         fd_set fdset;
834         struct timeval tv;
835
836         tv.tv_sec = 0;
837         tv.tv_usec = WAIT;
838
839         FD_ZERO(&fdset);
840         FD_SET(sd, &fdset);
841
842         Term_clear();
843         Term_fresh();
844         Term_xtra(TERM_XTRA_REACT, 0);
845
846         while (1)
847         {
848                 fd_set tmp_fdset;
849                 struct timeval tmp_tv;
850
851                 if (flush_ringbuf_client()) continue;
852
853                 tmp_fdset = fdset;
854                 tmp_tv = tv;
855
856                 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤¬Íè¤Æ¤¤¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
857                 select(sd+1, &tmp_fdset, (fd_set *)NULL, (fd_set *)NULL, &tmp_tv);
858                 if (FD_ISSET(sd, &tmp_fdset) == 0)
859                 {
860                         Term_xtra(TERM_XTRA_FLUSH, 0);
861                         continue;
862                 }
863
864                 if (read_sock() < 0)
865                 {
866                         chuukei_client = FALSE;
867                 }
868
869                 /* Àܳ¤¬Àڤ줿¾õÂ֤ǽñ¤¯¤Ù¤­¥Ç¡¼¥¿¤¬¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤¿¤é½ªÎ» */
870                 if (!chuukei_client && fresh_queue.next == fresh_queue.tail ) break;
871         }
872 #else
873         struct timeval tv;
874
875         tv.tv_sec = 0;
876         tv.tv_usec = WAIT;
877
878         Term_clear();
879         Term_fresh();
880         Term_xtra(TERM_XTRA_REACT, 0);
881
882         while (1)
883         {
884                 struct timeval tmp_tv;
885                 UInt32  unreadData = 0;
886                 int n;
887                 
888                 if (flush_ringbuf_client()) continue;
889
890                 tmp_tv = tv;
891
892                 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤¬Íè¤Æ¤¤¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
893                 
894                 OTCountDataBytes(ep, &unreadData);
895                 if(unreadData <= 0 ){
896                         Term_xtra(TERM_XTRA_FLUSH, 0);
897                         continue;
898                 }
899                 if (read_sock() < 0)
900                 {
901                         chuukei_client = FALSE;
902                 }
903
904                 /* Àܳ¤¬Àڤ줿¾õÂ֤ǽñ¤¯¤Ù¤­¥Ç¡¼¥¿¤¬¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤¿¤é½ªÎ» */
905                 if (!chuukei_client && fresh_queue.next == fresh_queue.tail ) break;
906         }
907 #endif /*MACINTOSH*/
908 }
909
910 #endif /* CHUUKEI */