]> jfr.im git - irc/gameservirc.git/blame - gameserv/tcpclient.cpp
Added the new contributed hybrid patch for 1.1.7. Thanks wcampbel!
[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";
54d31976 30char *VERSION = "1.1.7";
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();
23ec3ff4 335 #ifdef P10
23ec3ff4 336 if (strcmp(client->getNick(), nick) == 0)
337 #else
338 if (stricmp(client->getNick(), nick) == 0)
339 #endif
85ce9d3e 340 return client;
341 client = NULL;
342 newPtr = newPtr->Next();
343 }
344 return client;
345}
346
ee38284f 347aClient *findIRCplayer(const char *nick)
348{
349 ListNode <aClient> *newPtr;
350 aClient *p = NULL;
351
352 for (newPtr = players.First(); newPtr; newPtr = newPtr->Next())
353 {
354 p = newPtr->getData();
23ec3ff4 355 #ifdef P10
356 if (strcmp(p->getNick(), nick) == 0)
357 #else
358 if (stricmp(p->getNick(), nick) == 0)
359 #endif
ee38284f 360 return p;
361 p = NULL;
362 }
363 return NULL;
364}
0a1518fa 365aClient *findplayer(const char *name)
366{
367 ListNode <aClient> *newPtr;
368 Player *p = NULL;
369
370 for (newPtr = players.First(); newPtr; newPtr = newPtr->Next())
371 {
372 p = newPtr->getData()->stats;
373 if (stricmp(p->name, name) == 0)
374 return newPtr->getData();
375 p = NULL;
376 }
377 return NULL;
378}
379
85ce9d3e 380aClient *findbynick(const char *nick)
381{
382 ListNode <aClient> *newPtr;
383 newPtr = clients.First();
384
385 aClient *client = NULL;
386
387 while (newPtr)
388 {
389 client = newPtr->getData();
23ec3ff4 390 #ifdef P10
391 if (strcmp(client->getNick(), nick) == 0)
392 #else
393 if (stricmp(client->getNick(), nick) == 0)
394 #endif
85ce9d3e 395 return client;
396 client = NULL;
397 newPtr = newPtr->Next();
398 }
399 return client;
400}
401
44ea29f7 402void load_timestamp()
403{
404 ifstream infile;
405
406 infile.open(".gstimestamp");
407
408 if (infile.fail())
409 {
9f8c2acc 410 #ifdef DEBUGMODE
411 log("Error opening .gstimestamp");
412 #endif
413
44ea29f7 414 generate:
9f8c2acc 415 #ifdef DEBUGMODE
416 log("Generating new timestamp");
417 #endif
44ea29f7 418 timestamp = midnight();
419 save_timestamp();
420 return;
421 }
422
423 infile >> timestamp;
424 infile.close();
425 if (timestamp < 1000000)
426 goto generate;
427}
428
429void save_timestamp()
430{
431 ofstream outfile;
432
433 outfile.open(".gstimestamp");
434
435 if (outfile.fail())
436 {
fb37ecc7 437 log("Error creating new file .gstimestamp");
44ea29f7 438 return;
439 }
440
441 outfile << timestamp << endl;
442
443 outfile.close();
444}
445
446long int midnight(long int offset)
447{
448 return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600);
449}