]> jfr.im git - irc/gameservirc.git/blame - gameserv/tcpclient.cpp
P10 is now functional. The game is playable, but it does not display text nicknames...
[irc/gameservirc.git] / gameserv / tcpclient.cpp
CommitLineData
85ce9d3e 1/*
2 * This file is provided for use with the unix-socket-faq. It is public
3 * domain, and may be copied freely. There is no copyright on it. The
4 * original work was by Vic Metcalfe (vic@brutus.tlug.org), and any
5 * modifications made to that work were made with the understanding that
6 * the finished work would be in the public domain.
7 *
8 * If you have found a bug, please pass it on to me at the above address
9 * acknowledging that there will be no copyright on your work.
10 *
11 * The most recent version of this file, and the unix-socket-faq can be
12 * found at http://www.interlog.com/~vic/sock-faq/.
13 */
14
15#include "sockhelp.h"
c7340cbd 16#include "options.h"
85ce9d3e 17#include "list.h"
18#include "aClient.h"
19#include "extern.h"
20#include <stdio.h>
21#include <unistd.h>
22#include <string.h>
fb37ecc7 23#include <fstream>
85ce9d3e 24#include <stdlib.h>
25
fb37ecc7 26using std::ofstream;
27using std::ifstream;
28
91c0b563 29char *PACKAGE = "GameServ";
c62d75be 30char *VERSION = "1.1.8";
173302fe 31
85ce9d3e 32int sock;
44ea29f7 33long timestamp;
34
85ce9d3e 35List<aClient> clients;
36
44ea29f7 37void save_timestamp();
38void load_timestamp();
39
c62d75be 40int main()
85ce9d3e 41{
28f552b8 42 char buffer[1024], buf[1024];
85ce9d3e 43 int connected = 1;
44 char *cmd, *source = NULL;
45 srand(time(NULL));
44ea29f7 46
324ab87f 47
c62d75be 48 load_config_file(); // default = gameserv.conf
324ab87f 49
85ce9d3e 50 ignore_pipe();
324ab87f 51 sock = make_connection(remoteport, SOCK_STREAM, remoteserver);
85ce9d3e 52 if (sock == -1) {
53 fprintf(stderr,"make_connection failed.\n");
54 unload_config_file();
55 return -1;
56 }
57
c7340cbd 58#ifdef UNREAL
85ce9d3e 59 raw("PROTOCTL NICKv2 VHP");
60 raw("PASS :%s", remotepass);
c7340cbd 61 raw("SERVER %s 1 :%s", servername, servername);
173302fe 62 raw("NICK %S 1 %d %S %s %s %d +owghraAxNt %s :%s v%s", time(NULL), gshost,
63 servername, time(NULL), gshost, PACKAGE, VERSION);
85ce9d3e 64 raw(":%S JOIN %s", c_Forest);
c7340cbd 65 raw(":%S MODE %s +mtn", c_Forest);
66#elif defined(BAHAMUT)
67 raw("PASS %s :TS", remotepass);
68 raw("SERVER %s 1 :%s", servername, servername);
69 raw("NICK %S 1 %d +o %s %s %s 0 :GameServ", time(NULL), gsident, gshost,
70 servername);
71 raw(":%s SJOIN %d %d %s +mnt :@%S", servername, time(NULL), time(NULL), c_Forest);
e1c41a84 72#elif defined(P10)
73 // Server numeric is: [] <-- must be unique
74 raw("PASS :%s", remotepass);
75 raw("SERVER %s 1 %d %d P10 []AAF :%s", servername, time(NULL), time(NULL), servername);
76 raw("[] N %S 1 %d %s %s DAqAoB %s :%S", time(NULL), gsident, gshost, gsnum);
77 raw("[] B %s %d +tnm %s:o", c_Forest, time(NULL) - 864000, gsnum);
c7340cbd 78#endif
e1c41a84 79
80#if defined(P10)
81 raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic);
fc9d2643 82 raw("[] EB"); // End burst
e1c41a84 83#else
85ce9d3e 84 raw(":%S MODE %s +o %S", c_Forest);
c7340cbd 85 raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic);
e1c41a84 86#endif
85ce9d3e 87
88 sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to
89 David Duchene <dave@ltd.com> for pointing out the possible
90 buffer overflow resulting from the linefeed added below. */
91
92
9f8c2acc 93 #ifdef DEBUGMODE
94 log("Server: %s",buffer);
95 #endif
96
ab4f4ec0 97 init_masters();
ad7dfaa0 98 load_gs_dbase();
44ea29f7 99 load_timestamp();
922daad7 100 long int loadtime = time(NULL);
101 long int currentTime;
102 long int oldTime = loadtime;
5963944b 103 bool loaded = false;
44ea29f7 104
4dde2ed9 105 if (load_monsters() == false)
106 goto end;
107
85ce9d3e 108 while (connected) {
109 if (sock_gets(sock,buffer,sizeof(buffer)) == -1) {
110 connected = 0;
111 }
112 strcpy(buf, buffer);
113
e1c41a84 114 #if !defined(P10)
85ce9d3e 115 if (buffer[0] == ':')
116 {
117 source = strtok(buf, " ");
118 cmd = strtok(NULL, " ");
119 }
120 else
121 cmd = strtok(buf, " ");
e1c41a84 122 #else
123 source = strtok(buf, " ");
124 cmd = strtok(NULL, " ");
125 #endif
85ce9d3e 126
9f8c2acc 127 #ifdef DEBUGMODE
128 log("Server: %s", buffer);
129 #endif
5963944b 130
bf2cabcd 131 // Wait N seconds then we're loaded.
5963944b 132 if (!loaded)
133 {
922daad7 134 if (time(NULL) >= welcomedelay + loadtime)
5963944b 135 loaded = true;
136 }
137
922daad7 138 // Save the player data every updateperiod seconds
139 currentTime = time(NULL);
140 if (currentTime - oldTime >= updateperiod)
141 {
142 oldTime = currentTime;
143 save_gs_dbase();
144 }
145
e1c41a84 146
147 #if !defined(P10)
85ce9d3e 148 if (stricmp(cmd, "PING") == 0) {
0a1518fa 149 char *timestamp;
150 timestamp = strtok(NULL, "");
151 raw("PONG %s", timestamp);
e1c41a84 152 #else
153 if (stricmp(cmd, "G") == 0) {
154 char *timestamp;
155 timestamp = strtok(NULL, " ");
156 raw("[] Z [] %s 0 %s", timestamp + 1, timestamp);
157 #endif
fc9d2643 158 #ifdef P10
159 } else if (stricmp(cmd, "EB") == 0) {
160 raw("[] EA");
161 #endif
0501fe18 162 } else if (stricmp(cmd, "VERSION") == 0) {
163 char *server;
164 server = strtok(NULL, " ");
165 server++;
0501fe18 166 raw(":%s 351 %s %s %s. %s", servername, source+1, PACKAGE, VERSION, servername);
ba2a880f 167 #if !defined(P10)
85ce9d3e 168 } else if (strncmp(cmd, "NICK", 4) == 0) {
169 if (buffer[0] == ':')
170 {
171 aClient *tempPtr;
28f552b8 172 if ((tempPtr = find((source + 1))))
85ce9d3e 173 {
174 char *nick;
175 nick = strtok(NULL, " ");
176 tempPtr->setNick(nick);
177 }
178 }
179 else
180 {
181 char *nick;
ba2a880f 182 #else
183 } else if (stricmp(cmd, "N") == 0 && strlen(source) == 2) {
184 {
185 char *nick;
186
187 for (int x = 0; x < 6; x++)
188 nick = strtok(NULL, " ");
fc9d2643 189
ba2a880f 190 if (nick[0] == '+')
fc9d2643 191 {
192 #ifdef DEBUGMODE
193 log ("aClient has modes");
194 #endif
195
196 // Searching for the +r mode (extra parameter)
197 for (unsigned int count = 1; count < strlen(nick); count++)
198 {
199 if (nick[count] == 'r')
200 {
201 nick = strtok(NULL, " ");
202 break;
203 }
204 }
205 nick = strtok(NULL, " ");
206 }
ba2a880f 207 #endif
85ce9d3e 208 aClient *newuser;
ba2a880f 209
85ce9d3e 210 nick = strtok(NULL, " ");
ba2a880f 211
85ce9d3e 212 newuser = new aClient(nick);
5963944b 213 if (loaded)
bf2cabcd 214 notice(s_GameServ, nick, welcomemsg, nick);
b0a5c536 215
85ce9d3e 216 clients.insertAtBack(newuser);
217 delete newuser;
218 }
ba2a880f 219 #if defined(P10)
220 } else if (stricmp(cmd, "Q") == 0) {
221 #else
85ce9d3e 222 } else if (stricmp(cmd, "QUIT") == 0) {
ba2a880f 223 #endif
85ce9d3e 224 aClient *quitter;
fc9d2643 225 char z = source[0];
226
227 if (z == ':')
228 source++;
229
230 if ((quitter = find(source)))
85ce9d3e 231 clients.remove(quitter);
fc9d2643 232 if ((quitter = findIRCplayer(source)))
ee38284f 233 {
234 quitter->setNick("!NULL!");
235 quitter->stats->user = NULL; // Unidentify them
236 }
fc9d2643 237
238 if (z == ':')
239 source--;
240
ba2a880f 241 #if defined(P10)
242 } else if (stricmp(cmd, "P") == 0) {
243 char *rest, *dest;
244 char *longname;
245 longname = new char[strlen(s_GameServ) + strlen(servername) + 2];
246
247 sprintf(longname, "%S@%s", servername);
85ce9d3e 248
ba2a880f 249 dest = strtok(NULL, " ");
250 rest = strtok(NULL, "");
251 if (stricmp(dest, gsnum) == 0 || stricmp(dest, longname) == 0)
252 {
253 delete [] longname;
254 gameserv(source, rest);
255 }
256 else if (stricmp(dest, c_Forest) == 0)
257 {
258 delete [] longname;
259 forest(source, rest);
260 }
261 #else
85ce9d3e 262 } else if (stricmp(cmd, "PRIVMSG") == 0) {
263 char *rest, *dest;
264 dest = strtok(NULL, " ");
265 rest = strtok(NULL, "");
ad7dfaa0 266 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
85ce9d3e 267 gameserv(source, rest);
268 else if (stricmp(dest, c_Forest) == 0)
269 forest(source, rest);
ba2a880f 270 #endif
85ce9d3e 271 } else if (stricmp(cmd, "JOIN") == 0) {
272 char *channel;
273 channel = strtok(NULL, " ");
274 if (stricmp(channel, c_Forest) == 0 && is_playing(source + 1))
275 raw(":%S MODE %s +v %s", c_Forest, (source + 1));
c7340cbd 276
277 #if defined(BAHAMUT)
278 } else if (stricmp(cmd, "SJOIN") == 0) {
279 char *channel, *nick;
280 strtok(NULL, " "); // Ignore the TS
281 strtok(NULL, " "); // Ignore the TS
282 channel = strtok(NULL, " ");
283 strtok(NULL, " ");
284 nick = strtok(NULL, " ");
285 nick++; // Get rid of the :
286 if (stricmp(channel, c_Forest) == 0 && is_playing(nick))
287 raw(":%S MODE %s +v %s", channel, nick);
288 #endif
289
85ce9d3e 290 } else {
9f8c2acc 291 #ifdef DEBUGMODE
292 log("Unrecognized Message: cmd = %s source = %s", cmd, source);
293 #endif
85ce9d3e 294 }
295 }
4dde2ed9 296
297 end:
298
c8ada07e 299 save_gs_dbase();
44ea29f7 300 save_timestamp();
4dde2ed9 301
c8ada07e 302 delete_monsters();
303 delete_masters();
304
9f8c2acc 305 #ifdef DEBUGMODE
306 log("<CLOSED>");
307 #endif
308
85ce9d3e 309 close(sock);
310 unload_config_file();
311 return 0;
312}
313
314aClient *find(char *nick)
315{
316 return findbynick(nick);
317}
318
319aClient *find(const char *nick)
320{
321 return findbynick(nick);
322}
323
324
325aClient *findbynick(char *nick)
326{
327 ListNode <aClient> *newPtr;
328 newPtr = clients.First();
329
330 aClient *client = NULL;
331
332 while (newPtr)
333 {
334 client = newPtr->getData();
335 if (stricmp(client->getNick(), nick) == 0)
336 return client;
337 client = NULL;
338 newPtr = newPtr->Next();
339 }
340 return client;
341}
342
ee38284f 343aClient *findIRCplayer(const char *nick)
344{
345 ListNode <aClient> *newPtr;
346 aClient *p = NULL;
347
348 for (newPtr = players.First(); newPtr; newPtr = newPtr->Next())
349 {
350 p = newPtr->getData();
351 if (stricmp(p->getNick(), nick) == 0)
352 return p;
353 p = NULL;
354 }
355 return NULL;
356}
0a1518fa 357aClient *findplayer(const char *name)
358{
359 ListNode <aClient> *newPtr;
360 Player *p = NULL;
361
362 for (newPtr = players.First(); newPtr; newPtr = newPtr->Next())
363 {
364 p = newPtr->getData()->stats;
365 if (stricmp(p->name, name) == 0)
366 return newPtr->getData();
367 p = NULL;
368 }
369 return NULL;
370}
371
85ce9d3e 372aClient *findbynick(const char *nick)
373{
374 ListNode <aClient> *newPtr;
375 newPtr = clients.First();
376
377 aClient *client = NULL;
378
379 while (newPtr)
380 {
381 client = newPtr->getData();
382 if (stricmp(client->getNick(), nick) == 0)
383 return client;
384 client = NULL;
385 newPtr = newPtr->Next();
386 }
387 return client;
388}
389
44ea29f7 390void load_timestamp()
391{
392 ifstream infile;
393
394 infile.open(".gstimestamp");
395
396 if (infile.fail())
397 {
9f8c2acc 398 #ifdef DEBUGMODE
399 log("Error opening .gstimestamp");
400 #endif
401
44ea29f7 402 generate:
9f8c2acc 403 #ifdef DEBUGMODE
404 log("Generating new timestamp");
405 #endif
44ea29f7 406 timestamp = midnight();
407 save_timestamp();
408 return;
409 }
410
411 infile >> timestamp;
412 infile.close();
413 if (timestamp < 1000000)
414 goto generate;
415}
416
417void save_timestamp()
418{
419 ofstream outfile;
420
421 outfile.open(".gstimestamp");
422
423 if (outfile.fail())
424 {
fb37ecc7 425 log("Error creating new file .gstimestamp");
44ea29f7 426 return;
427 }
428
429 outfile << timestamp << endl;
430
431 outfile.close();
432}
433
434long int midnight(long int offset)
435{
436 return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600);
437}