]> jfr.im git - irc/gameservirc.git/blob - gameserv/tcpclient.cpp
Updated the version in tcpclient.cpp for next release!
[irc/gameservirc.git] / gameserv / tcpclient.cpp
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"
16 #include "options.h"
17 #include "list.h"
18 #include "aClient.h"
19 #include "extern.h"
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <fstream>
24 #include <stdlib.h>
25
26 using std::ofstream;
27 using std::ifstream;
28
29 char *PACKAGE = "GameServ";
30 char *VERSION = "1.1.7";
31
32 int sock;
33 long timestamp;
34
35 List<aClient> clients;
36
37 void save_timestamp();
38 void load_timestamp();
39
40 int main()
41 {
42 char buffer[1024], buf[1024];
43 int connected = 1;
44 char *cmd, *source = NULL;
45 srand(time(NULL));
46
47
48 load_config_file(); // default = gameserv.conf
49
50 ignore_pipe();
51 sock = make_connection(remoteport, SOCK_STREAM, remoteserver);
52 if (sock == -1) {
53 fprintf(stderr,"make_connection failed.\n");
54 unload_config_file();
55 return -1;
56 }
57
58 #ifdef UNREAL
59 raw("PROTOCTL NICKv2 VHP");
60 raw("PASS :%s", remotepass);
61 raw("SERVER %s 1 :%s", servername, servername);
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);
64 raw(":%S JOIN %s", c_Forest);
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);
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);
78 #endif
79
80 #if defined(P10)
81 raw("%s T %s :%s", gsnum, c_Forest, c_ForestTopic);
82 raw("[] EB"); // End burst
83 #else
84 raw(":%S MODE %s +o %S", c_Forest);
85 raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic);
86 #endif
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
93 #ifdef DEBUGMODE
94 log("Server: %s",buffer);
95 #endif
96
97 init_masters();
98 load_gs_dbase();
99 load_timestamp();
100 long int loadtime = time(NULL);
101 long int currentTime;
102 long int oldTime = loadtime;
103 bool loaded = false;
104
105 if (load_monsters() == false)
106 goto end;
107
108 while (connected) {
109 if (sock_gets(sock,buffer,sizeof(buffer)) == -1) {
110 connected = 0;
111 }
112 strcpy(buf, buffer);
113
114 #if !defined(P10)
115 if (buffer[0] == ':')
116 {
117 source = strtok(buf, " ");
118 cmd = strtok(NULL, " ");
119 }
120 else
121 cmd = strtok(buf, " ");
122 #else
123 source = strtok(buf, " ");
124 cmd = strtok(NULL, " ");
125 #endif
126
127 #ifdef DEBUGMODE
128 log("Server: %s", buffer);
129 #endif
130
131 // Wait N seconds then we're loaded.
132 if (!loaded)
133 {
134 if (time(NULL) >= welcomedelay + loadtime)
135 loaded = true;
136 }
137
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
146
147 #if !defined(P10)
148 if (stricmp(cmd, "PING") == 0) {
149 char *timestamp;
150 timestamp = strtok(NULL, "");
151 raw("PONG %s", timestamp);
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
158 #ifdef P10
159 } else if (stricmp(cmd, "EB") == 0) {
160 raw("[] EA");
161 #endif
162 } else if (stricmp(cmd, "VERSION") == 0) {
163 char *server;
164 server = strtok(NULL, " ");
165 server++;
166 raw(":%s 351 %s %s %s. %s", servername, source+1, PACKAGE, VERSION, servername);
167 #if !defined(P10)
168 } else if (strncmp(cmd, "NICK", 4) == 0) {
169 if (buffer[0] == ':')
170 {
171 aClient *tempPtr;
172 if ((tempPtr = find((source + 1))))
173 {
174 char *nick;
175 nick = strtok(NULL, " ");
176 tempPtr->setNick(nick);
177 }
178 }
179 else
180 {
181 char *nick;
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, " ");
189
190 if (nick[0] == '+')
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 }
207 #endif
208 aClient *newuser;
209
210 nick = strtok(NULL, " ");
211
212 newuser = new aClient(nick);
213 if (loaded)
214 notice(s_GameServ, nick, welcomemsg, nick);
215
216 clients.insertAtBack(newuser);
217 delete newuser;
218 }
219 #if defined(P10)
220 } else if (stricmp(cmd, "Q") == 0) {
221 #else
222 } else if (stricmp(cmd, "QUIT") == 0) {
223 #endif
224 aClient *quitter;
225 char z = source[0];
226
227 if (z == ':')
228 source++;
229
230 if ((quitter = find(source)))
231 clients.remove(quitter);
232 if ((quitter = findIRCplayer(source)))
233 {
234 quitter->setNick("!NULL!");
235 quitter->stats->user = NULL; // Unidentify them
236 }
237
238 if (z == ':')
239 source--;
240
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);
248
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
262 } else if (stricmp(cmd, "PRIVMSG") == 0) {
263 char *rest, *dest;
264 dest = strtok(NULL, " ");
265 rest = strtok(NULL, "");
266 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
267 gameserv(source, rest);
268 else if (stricmp(dest, c_Forest) == 0)
269 forest(source, rest);
270 #endif
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));
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
290 } else {
291 #ifdef DEBUGMODE
292 log("Unrecognized Message: cmd = %s source = %s", cmd, source);
293 #endif
294 }
295 }
296
297 end:
298
299 save_gs_dbase();
300 save_timestamp();
301
302 delete_monsters();
303 delete_masters();
304
305 #ifdef DEBUGMODE
306 log("<CLOSED>");
307 #endif
308
309 close(sock);
310 unload_config_file();
311 return 0;
312 }
313
314 aClient *find(char *nick)
315 {
316 return findbynick(nick);
317 }
318
319 aClient *find(const char *nick)
320 {
321 return findbynick(nick);
322 }
323
324
325 aClient *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
343 aClient *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 }
357 aClient *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
372 aClient *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
390 void load_timestamp()
391 {
392 ifstream infile;
393
394 infile.open(".gstimestamp");
395
396 if (infile.fail())
397 {
398 #ifdef DEBUGMODE
399 log("Error opening .gstimestamp");
400 #endif
401
402 generate:
403 #ifdef DEBUGMODE
404 log("Generating new timestamp");
405 #endif
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
417 void save_timestamp()
418 {
419 ofstream outfile;
420
421 outfile.open(".gstimestamp");
422
423 if (outfile.fail())
424 {
425 log("Error creating new file .gstimestamp");
426 return;
427 }
428
429 outfile << timestamp << endl;
430
431 outfile.close();
432 }
433
434 long int midnight(long int offset)
435 {
436 return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600);
437 }