1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
18 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <netinet/tcp.h>
24 #include <arpa/inet.h>
33 #define DEFAULTPORT 19503
68 unsigned char realbuf[512], readbuf[BUFLEN], writbuf[BUFLEN];
69 unsigned char *buf = realbuf + 4;
70 int nread = 0, nwrite = 0;
72 /* like memcpy, but guaranteed to handle overlap when s <= t */
73 void copydown(char *s, char *t, int n)
87 fprintf(stderr, "%s.\n", s);
94 tm.tv_sec = i / 1000000;
95 tm.tv_usec = i % 1000000;
96 select(0, NULL, NULL, NULL, &tm);
103 write(sfd, writbuf, nwrite);
108 void sendbuf(int len)
112 realbuf[0] = realbuf[1] = realbuf[2] = 0;
113 realbuf[3] = (unsigned char)len;
115 if (nwrite + 4 + len >= BUFLEN)
116 fatal("Internal error: send buffer overflow");
117 memcpy(writbuf + nwrite, realbuf, 4 + len);
127 options[0] = options[1] = NULL;
129 options[n++] = "-norestart";
131 options[n++] = "-nospeedup";
138 XTRISPATH "/rnd_server",
142 "rnd_server", "-once", "-v", options[0], options[1], NULL);
144 fprintf(stderr, "Can't start server '%s'.\n",
146 XTRISPATH "/rnd_server"
155 fatal("fork() failed");
162 BOOL ConnectToServer(char *host, int port)
165 struct sockaddr_in s;
166 struct protoent *tcpproto;
171 if ((s.sin_addr.s_addr = inet_addr(host)) == -1)
173 hp = gethostbyname(host);
175 fatal("Host not found");
176 s.sin_addr = *(struct in_addr *)(hp->h_addr_list[0]);
180 s.sin_addr.s_addr = inet_addr("127.0.0.1");
185 s.sin_port = htons(port);
186 s.sin_family = AF_INET;
187 sfd = socket(PF_INET, SOCK_STREAM, 0);
189 fatal("Out of file descriptors");
190 if ((tcpproto = getprotobyname("tcp")) != NULL)
191 setsockopt(sfd, tcpproto->p_proto, TCP_NODELAY, (char *)&on, sizeof(int));
193 if (connect(sfd, (struct sockaddr *)&s, sizeof(s)) < 0)
197 printf("No rocksndiamonds server on localhost - starting up one ...\n");
203 sfd = socket(PF_INET, SOCK_STREAM, 0);
205 fatal("Out of file descriptors");
206 setsockopt(sfd, tcpproto->p_proto, TCP_NODELAY, (char *)&on, sizeof(int));
207 if (connect(sfd, (struct sockaddr *)&s, sizeof(s)) >= 0)
211 fatal("Can't connect to server");
214 fatal("Can't connect to server");
220 void SendNicknameToServer(char *nickname)
222 static char msgbuf[300];
225 memcpy(&buf[2], nickname, strlen(nickname));
226 sendbuf(2 + strlen(nickname));
227 sprintf(msgbuf, "you set your nick to \"%s\"", nickname);
231 void SendProtocolVersionToServer()
234 buf[2] = PROT_VERS_1;
235 buf[3] = PROT_VERS_2;
236 buf[4] = PROT_VERS_3;
240 void handlemessages()
243 static char msgbuf[300];
245 while (nread >= 4 && nread >= 4 + readbuf[3])
248 if (readbuf[0] || readbuf[1] || readbuf[2])
249 fatal("Wrong server line length");
251 memcpy(buf, &readbuf[4], len);
253 copydown(readbuf, readbuf + 4 + len, nread);
258 printf("OP_YOUARE: %d\n", buf[0]);
262 printf("OP_NEW: %d\n", buf[0]);
263 sprintf(msgbuf, "new client %d connected", buf[0]);
268 printf("OP_GONE: %d\n", buf[0]);
269 sprintf(msgbuf, "client %d disconnected", buf[0]);
275 static char tmpbuf[128];
277 sprintf(tmpbuf, "Protocol version mismatch: server expects %d.%d.x instead of %d.%d.%d\n", buf[2], buf[3], PROT_VERS_1, PROT_VERS_2, PROT_VERS_3);
283 printf("OP_PLAY: %d\n", buf[0]);
284 sprintf(msgbuf, "client %d starts game", buf[0]);
289 printf("OP_PAUSE: %d\n", buf[0]);
290 sprintf(msgbuf, "client %d pauses game", buf[0]);
295 printf("OP_CONT: %d\n", buf[0]);
296 sprintf(msgbuf, "client %d continues game", buf[0]);
301 printf("OP_WON: %d\n", buf[0]);
302 sprintf(msgbuf, "client %d wins the game", buf[0]);
307 printf("OP_ZERO: %d\n", buf[0]);
308 sprintf(msgbuf, "client %d resets game counters", buf[0]);
313 printf("OP_NICK: %d\n", buf[0]);
314 sprintf(msgbuf, "client %d calls itself \"%s\"", buf[0], &buf[2]);
319 printf("OP_MSG: %d\n", buf[0]);
320 sprintf(msgbuf, "client %d sends message", buf[0]);
324 printf("OP_MSG: %d\n", buf[0]);
325 sprintf(msgbuf, "client %d has lost", buf[0]);
329 printf("OP_MSG: %d\n", buf[0]);
330 sprintf(msgbuf, "client %d sets level to %d", buf[0], buf[2]);
338 void HandleNetworking()
340 static struct timeval tv = { 0, 0 };
352 r = select(sfd + 1, &rfds, NULL, NULL, &tv);
354 if (r < 0 && errno != EINTR)
357 fatal("fatal: select() failed");
363 if (FD_ISSET(sfd, &rfds))
367 r = read(sfd, readbuf + nread, BUFLEN - nread);
370 fatal("Error reading from server");
372 fatal("Connection to server lost");