13 #elif defined(MACINTOSH)
14 #include <OpenTransport.h>
15 #include <OpenTptInternet.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
22 #include <arpa/inet.h>
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
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];
43 #define close closesocket
47 static InetSvcRef inet_services = nil;
48 static EndpointRef ep = kOTInvalidEndpointRef;
51 /* ÉÁ²è¤¹¤ë»þ¹ï¤ò³Ð¤¨¤Æ¤ª¤¯¥¥å¡¼¹½Â¤ÂÎ */
54 int time[FRESH_QUEUE_SIZE];
60 /* ¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¹½Â¤ÂÎ */
70 int recv(int s, char *buffer, size_t buflen, int flags)
73 int n = OTRcv(ep, (void *) buffer, buflen, &junkFlags);
80 /* ANSI C¤Ë¤è¤ì¤ÐstaticÊÑ¿ô¤Ï0¤Ç½é´ü²½¤µ¤ì¤ë¤¬°ì±þ½é´ü²½¤¹¤ë */
81 static errr init_chuukei(void)
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);
92 /* ¸½ºß¤Î»þ´Ö¤ò100msñ°Ì¤Ç¼èÆÀ¤¹¤ë */
93 static long get_current_time(void)
96 return GetTickCount() / 100;
97 #elif defined(MACINTOSH)
101 gettimeofday(&tv, NULL);
103 return (tv.tv_sec * 10 + tv.tv_usec / 100000);
108 /* ¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¹½Â¤ÂÎ¤Ë buf ¤ÎÆâÍƤò²Ã¤¨¤ë */
109 static errr insert_ringbuf(char *buf)
112 len = strlen(buf) + 1; /* +1¤Ï½ªÃ¼Ê¸»úʬ */
114 /* ¥Ð¥Ã¥Õ¥¡¤ò¥ª¡¼¥Ð¡¼ */
115 if (ring.inlen + len >= RINGBUF_SIZE)
117 chuukei_server = FALSE;
118 chuukei_client = FALSE;
120 prt("¥Ð¥Ã¥Õ¥¡¤¬°î¤ì¤Þ¤·¤¿¡£¥µ¡¼¥Ð¤È¤ÎÀܳ¤òÀÚÃǤ·¤Þ¤¹¡£", 0, 0);
128 /* ¥Ð¥Ã¥Õ¥¡¤Î½ªÃ¼¤Þ¤Ç¤Ë¼ý¤Þ¤ë */
129 if (ring.wptr + len < RINGBUF_SIZE)
131 memcpy(ring.buf + ring.wptr, buf, len);
134 /* ¥Ð¥Ã¥Õ¥¡¤Î½ªÃ¼¤Þ¤Ç¤Ë¼ý¤Þ¤é¤Ê¤¤(¥Ô¥Ã¥¿¥ê¼ý¤Þ¤ë¾ì¹ç¤â´Þ¤à) */
137 int head = RINGBUF_SIZE - ring.wptr; /* Á°È¾ */
138 int tail = len - head; /* ¸åȾ */
140 memcpy(ring.buf + ring.wptr, buf, head);
141 memcpy(ring.buf, buf + head, tail);
151 void flush_ringbuf(void)
158 if (!chuukei_server) return;
160 if (ring.inlen == 0) return;
171 struct timeval tmp_tv;
177 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤ò½ñ¤¹þ¤á¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
178 select(sd+1, (fd_set *)NULL, &tmp_fdset, (fd_set *)NULL, &tv);
180 /* ½ñ¤¹þ¤á¤Ê¤±¤ì¤ÐÌá¤ë */
181 if (FD_ISSET(sd, &tmp_fdset) == 0) break;
183 result = send(sd, ring.buf + ring.rptr, ((ring.wptr > ring.rptr ) ? ring.wptr : RINGBUF_SIZE) - ring.rptr, 0);
187 /* ¥µ¡¼¥Ð¤È¤ÎÀܳÃÇ¡© */
188 chuukei_server = FALSE;
190 prt("¥µ¡¼¥Ð¤È¤ÎÀܳ¤¬ÀÚÃǤµ¤ì¤Þ¤·¤¿¡£", 0, 0);
198 ring.inlen -= result;
201 if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
202 if (ring.inlen == 0) break;
208 if (!chuukei_server) return;
210 if (ring.inlen == 0) return;
217 struct timeval tmp_tv;
222 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤ò½ñ¤¹þ¤á¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
223 result = OTSnd(ep, ring.buf + ring.rptr, ((ring.wptr > ring.rptr ) ? ring.wptr : RINGBUF_SIZE) - ring.rptr, 0);
227 /* ¥µ¡¼¥Ð¤È¤ÎÀܳÃÇ¡© */
228 chuukei_server = FALSE;
230 prt("¥µ¡¼¥Ð¤È¤ÎÀܳ¤¬ÀÚÃǤµ¤ì¤Þ¤·¤¿¡£", 0, 0);
238 ring.inlen -= result;
241 if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
242 if (ring.inlen == 0) break;
247 static int read_chuukei_prf(cptr prf_name)
252 path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA, prf_name);
253 fp = my_fopen(buf, "r");
255 if (!fp) return (-1);
260 browse_delay = DEFAULT_DELAY;
262 while (0 == my_fgets(fp, buf, sizeof(buf)))
265 if (!strncmp(buf, "server:", 7))
267 strncpy(server_name, buf + 7, MAX_HOSTNAME - 1);
268 server_name[MAX_HOSTNAME - 1] = '\0';
272 if (!strncmp(buf, "port:", 5))
274 server_port = atoi(buf + 5);
278 if (!strncmp(buf, "delay:", 6))
280 browse_delay = atoi(buf + 6);
286 /* prf¥Õ¥¡¥¤¥ë¤¬´°Á´¤Ç¤Ê¤¤ */
287 if (server_port == -1 || server_name[0] == 0) return (-1);
292 int connect_chuukei_server(char *prf_name)
298 WORD wVersionRequested = (WORD) (( 1) | ( 1 << 8));
301 struct sockaddr_in ask;
304 if (read_chuukei_prf(prf_name) < 0)
306 printf("Wrong prf file\n");
310 if (init_chuukei() < 0)
312 printf("Malloc error\n");
317 if (WSAStartup(wVersionRequested, &wsaData))
319 msg_print("Report: WSAStartup failed.");
324 printf("server = %s\nport = %d\n", server_name, server_port);
326 if ((hp = gethostbyname(server_name)) != NULL)
328 memset(&ask, 0, sizeof(ask));
329 memcpy(&ask.sin_addr, hp->h_addr_list[0], hp->h_length);
333 if ((ask.sin_addr.s_addr=inet_addr(server_name)) == 0)
335 printf("Bad hostname\n");
340 ask.sin_family = AF_INET;
341 ask.sin_port = htons((unsigned short)server_port);
344 if ((sd=socket(PF_INET,SOCK_STREAM, 0)) < 0)
346 if ((sd=socket(PF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET)
349 printf("Can't create socket\n");
353 if (connect(sd, (struct sockaddr *)&ask, sizeof(ask)) < 0)
356 printf("Can't connect %s port %d\n", server_name, server_port);
360 epoch_time = get_current_time();
363 #else /* MACINTOSH */
365 InetHostInfo response;
369 Boolean bind = false;
372 if (read_chuukei_prf(prf_name) < 0){
373 printf("Wrong prf file\n");
379 printf("server = %s\nport = %d\n", server_name, server_port);
382 #if TARGET_API_MAC_CARBON
383 err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
385 err = InitOpenTransport();
388 memset(&response, 0, sizeof(response));
391 #if TARGET_API_MAC_CARBON
392 inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
394 inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
398 err = OTInetStringToAddress(inet_services, (char *)server_name, &response);
401 host_addr = response.addrs[0];
403 printf("Bad hostname\n");
406 #if TARGET_API_MAC_CARBON
407 ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
409 ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
413 err = OTBind(ep, nil, nil);
414 bind = (err == noErr);
417 OTInitInetAddress(&inAddr, server_port, host_addr);
419 sndCall.addr.len = sizeof(InetAddress);
420 sndCall.addr.buf = (unsigned char*) &inAddr;
421 sndCall.opt.buf = nil; /* no connection options */
423 sndCall.udata.buf = nil; /* no connection data */
424 sndCall.udata.len = 0;
425 sndCall.sequence = 0; /* ignored by OTConnect */
427 err = OTConnect(ep, &sndCall, NULL);
430 printf("Can't connect %s port %d\n", server_name, server_port);
434 err = OTSetSynchronous(ep);
436 err = OTSetBlocking(ep);
445 if (ep != kOTInvalidEndpointRef) {
449 if (inet_services != nil) {
450 OTCloseProvider(inet_services);
463 static void sjis2euc(char *str)
466 unsigned char c1, c2;
471 for (i = 0; i < l; i++)
474 if (c1 & 0x80) kanji = 1;
475 if (c1>=0x80 && (c1 < 0xa1 || c1 > 0xfe)) iseuc = 0;
480 unsigned char tmp[256];
482 for (i = 0; i < l; i++)
491 c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe0 : 0x60);
496 c1 = c1 * 2 - (c1 >= 0xe0 ? 0xe1 : 0x61);
497 c2 += 0x60 + (c2 < 0x7f);
510 static void euc2sjis(char *str)
513 unsigned char c1, c2;
518 for (i = 0; i < l; i++)
521 if (c1 & 0x80) kanji = 1;
522 if (c1>=0x80 && (c1 < 0xa1 || c1 > 0xfe)) iseuc = 0;
526 unsigned char tmp[256];
528 for (i = 0; i < l; i++)
537 c1 = (c1 >> 1) + (c1 < 0xdf ? 0x31 : 0x71);
538 c2 -= 0x60 + (c2 < 0xe0);
542 c1 = (c1 >> 1) + (c1 < 0xdf ? 0x30 : 0x70);
558 /* str¤¬Æ±¤¸Ê¸»ú¤Î·«¤êÊÖ¤·¤«¤É¤¦¤«Ä´¤Ù¤ë */
559 static bool string_is_repeat(char *str, int len)
564 if (len < 2) return (FALSE);
566 if (iskanji(c)) return (FALSE);
569 for (i = 1; i < len; i++)
572 if(c != str[i] || iskanji(str[i])) return (FALSE);
574 if(c != str[i]) return (FALSE);
581 void send_text_to_chuukei_server(int x, int y, int len, int col, char *str)
586 if (!chuukei_server || Term != angband_term[0]) return;
588 strncpy(buf2, str, len);
593 sprintf(buf, "s%c%c%c%c", x+1, y+1, col, buf2[0]);
595 else if(string_is_repeat(buf2, len))
597 sprintf(buf, "n%c%c%c%c%c", x+1, y+1, len, col, buf2[0]);
604 sprintf(buf, "t%c%c%c%c%s", x+1, y+1, len, col, buf2);
610 void send_wipe_to_chuukei_server(int x, int y, int len)
614 if (!chuukei_server || Term != angband_term[0]) return;
616 sprintf(buf, "w%c%c%c", x+1, y+1, len);
621 void send_xtra_to_chuukei_server(int n)
625 if (!chuukei_server || Term != angband_term[0]) return;
626 sprintf(buf, "x%c", n+1);
630 if (n == TERM_XTRA_FRESH)
632 sprintf(buf, "d%ld", get_current_time() - epoch_time);
637 void send_curs_to_chuukei_server(int x, int y)
641 if (!chuukei_server || Term != angband_term[0]) return;
642 sprintf(buf, "c%c%c", x+1, y+1);
647 static int read_sock(void)
654 if (recv(sd, buf+i, 1, 0) <= 0)
661 int timestamp = atoi(buf + 1);
662 long current_time = get_current_time();
664 /* ºÇ½é¤Î»þ´Ö¤òÊݸ¤·¤Æ¤ª¤¯ */
665 if (!fresh_queue.time[0])
667 epoch_time = current_time;
668 epoch_time += browse_delay;
669 epoch_time -= timestamp;
670 time_diff = current_time - timestamp;
673 fresh_queue.time[fresh_queue.tail] = timestamp;
676 if (fresh_queue.tail == FRESH_QUEUE_SIZE)
677 fresh_queue.tail = 0;
679 /* ¥×¥ì¥¤Â¦¤È¤Î¥Ç¥£¥ì¥¤¤òÄ´À° */
680 if (time_diff > current_time - timestamp)
682 long old_time_diff = time_diff;
683 time_diff = current_time - timestamp;
684 epoch_time -= (old_time_diff - time_diff);
687 if (fresh_queue.tail == fresh_queue.next)
696 if (insert_ringbuf(buf) < 0)
705 /* WinÈǤÎÃæÅÀ¤ÈÊɤÎƦÉå¤ò¥Ô¥ê¥ª¥É¤È¥·¥ã¡¼¥×¤Ë¤¹¤ë¡£ */
706 static void win2unix(int col, char *buf)
709 if ( col == 9 ) kabe = '%';
721 if (*buf == 127) *buf = kabe;
722 else if(*buf == 31) *buf = '.';
728 static bool get_nextbuf(char *buf)
734 *ptr = ring.buf[ring.rptr ++];
736 if (ring.rptr == RINGBUF_SIZE) ring.rptr = 0;
737 if (*ptr++ == '\0') break;
740 if (buf[0] == 'd') return (FALSE);
745 static bool flush_ringbuf_client(void)
750 if (fresh_queue.next == fresh_queue.tail) return (FALSE);
752 /* ¤Þ¤À½ñ¤¯¤Ù¤»þ¤Ç¤Ê¤¤ */
753 if (fresh_queue.time[fresh_queue.next] > get_current_time() - epoch_time) return (FALSE);
755 /* »þ´Ö¾ðÊó(¶èÀÚ¤ê)¤¬ÆÀ¤é¤ì¤ë¤Þ¤Ç½ñ¤¯ */
756 while (get_nextbuf(buf))
761 char tmp1, tmp2, tmp3, tmp4;
764 sscanf(buf, "%c%c%c%c%c", &id, &tmp1, &tmp2, &tmp3, &tmp4);
765 x = tmp1-1; y = tmp2-1; len = tmp3; col = tmp4;
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++)
786 Term->scr->a[y][i] = col;
790 case 'n': /* ·«¤êÊÖ¤· */
791 for (i = 1; i < len; i++)
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++)
800 Term->scr->a[y][i] = col;
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;
811 (void)((*angband_term[0]->wipe_hook)(x, y, len));
815 if (x == TERM_XTRA_CLEAR) Term_clear();
816 (void)((*angband_term[0]->xtra_hook)(x, 0));
820 (void)((*angband_term[0]->curs_hook)(x, y));
826 if (fresh_queue.next == FRESH_QUEUE_SIZE) fresh_queue.next = 0;
830 void browse_chuukei()
844 Term_xtra(TERM_XTRA_REACT, 0);
849 struct timeval tmp_tv;
851 if (flush_ringbuf_client()) continue;
856 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤¬Íè¤Æ¤¤¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
857 select(sd+1, &tmp_fdset, (fd_set *)NULL, (fd_set *)NULL, &tmp_tv);
858 if (FD_ISSET(sd, &tmp_fdset) == 0)
860 Term_xtra(TERM_XTRA_FLUSH, 0);
866 chuukei_client = FALSE;
869 /* Àܳ¤¬Àڤ줿¾õÂ֤ǽñ¤¯¤Ù¤¥Ç¡¼¥¿¤¬¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤¿¤é½ªÎ» */
870 if (!chuukei_client && fresh_queue.next == fresh_queue.tail ) break;
880 Term_xtra(TERM_XTRA_REACT, 0);
884 struct timeval tmp_tv;
885 UInt32 unreadData = 0;
888 if (flush_ringbuf_client()) continue;
892 /* ¥½¥±¥Ã¥È¤Ë¥Ç¡¼¥¿¤¬Íè¤Æ¤¤¤ë¤«¤É¤¦¤«Ä´¤Ù¤ë */
894 OTCountDataBytes(ep, &unreadData);
895 if(unreadData <= 0 ){
896 Term_xtra(TERM_XTRA_FLUSH, 0);
901 chuukei_client = FALSE;
904 /* Àܳ¤¬Àڤ줿¾õÂ֤ǽñ¤¯¤Ù¤¥Ç¡¼¥¿¤¬¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤¿¤é½ªÎ» */
905 if (!chuukei_client && fresh_queue.next == fresh_queue.tail ) break;