]>
jfr.im git - irc/gameservirc.git/blob - gameserv/tcpclient.cpp
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.
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.
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/.
27 //#include <sys/types.h>
28 //#include <sys/wait.h>
38 char *PACKAGE
= "GameServ";
39 char *VERSION
= "1.1.8";
44 List
<aClient
> clients
;
46 void save_timestamp();
47 void load_timestamp();
50 int daemon(int nochdir
, int noclose
);
52 // Close all file descriptors from >= fd
53 void closeall(int fd
);
57 char buffer
[1024], buf
[1024];
59 char *cmd
, *source
= NULL
;
63 load_config_file(); // default = gameserv.conf
68 perror("Could not turn into a daemon");
73 sock
= make_connection(remoteport
, SOCK_STREAM
, remoteserver
);
75 fprintf(stderr
,"make_connection failed.\n");
81 raw("PROTOCTL NICKv2 VHP");
82 raw("PASS :%s", remotepass
);
83 raw("SERVER %s 1 :%s", servername
, servername
);
84 raw("NICK %S 1 %d %S %s %s %d +owghraAxNt %s :%s v%s", time(NULL
), gshost
,
85 servername
, time(NULL
), gshost
, PACKAGE
, VERSION
);
86 raw(":%S JOIN %s", c_Forest
);
87 raw(":%S MODE %s +mtn", c_Forest
);
88 #elif defined(BAHAMUT)
89 raw("PASS %s :TS", remotepass
);
90 raw("SERVER %s 1 :%s", servername
, servername
);
91 raw("NICK %S 1 %d +o %s %s %s 0 :GameServ", time(NULL
), gsident
, gshost
,
93 raw(":%s SJOIN %d %d %s +mnt :@%S", servername
, time(NULL
), time(NULL
), c_Forest
);
95 raw("PASS %s :TS", remotepass
);
96 raw("SERVER %s 1 :%s", servername
, servername
);
97 raw("NICK %S 1 %d +o %s %s %s :GameServ", time(NULL
), gsident
, gshost
,
99 // Sending a timestamp of 1 to force ops.
100 raw(":%s SJOIN 1 %s +ntm :@%S", servername
, c_Forest
);
102 // Server numeric is: [] <-- must be unique
103 raw("PASS :%s", remotepass
);
104 raw("SERVER %s 1 %d %d P10 []AAF :%s", servername
, time(NULL
), time(NULL
), servername
);
105 raw("[] N %S 1 %d %s %s DAqAoB %s :%S", time(NULL
), gsident
, gshost
, gsnum
);
106 raw("[] B %s %d +tnm %s:o", c_Forest
, time(NULL
) - 864000, gsnum
);
110 raw("%s T %s :%s", gsnum
, c_Forest
, c_ForestTopic
);
111 raw("[] EB"); // End burst
114 raw(":%S MODE %s +o %S", c_Forest
);
116 raw(":%S TOPIC %s :%s", c_Forest
, c_ForestTopic
);
119 sock_gets(sock
,buffer
,sizeof(buffer
)-1); /* -1 added thanks to
120 David Duchene <dave@ltd.com> for pointing out the possible
121 buffer overflow resulting from the linefeed added below. */
125 log("Server: %s",buffer
);
131 long int loadtime
= time(NULL
);
132 long int currentTime
;
133 long int oldTime
= loadtime
;
136 if (load_monsters() == false)
140 if (sock_gets(sock
,buffer
,sizeof(buffer
)) == -1) {
146 if (buffer
[0] == ':')
148 source
= strtok(buf
, " ");
149 cmd
= strtok(NULL
, " ");
152 cmd
= strtok(buf
, " ");
154 source
= strtok(buf
, " ");
155 cmd
= strtok(NULL
, " ");
159 log("Server: %s", buffer
);
162 // Wait N seconds then we're loaded.
165 if (time(NULL
) >= welcomedelay
+ loadtime
)
169 // Save the player data every updateperiod seconds
170 currentTime
= time(NULL
);
171 if (currentTime
- oldTime
>= updateperiod
)
173 oldTime
= currentTime
;
179 if (stricmp(cmd
, "PING") == 0) {
181 timestamp
= strtok(NULL
, "");
182 raw("PONG %s", timestamp
);
184 if (stricmp(cmd
, "G") == 0) {
186 timestamp
= strtok(NULL
, " ");
187 raw("[] Z [] %s 0 %s", timestamp
+ 1, timestamp
);
190 } else if (stricmp(cmd
, "EB") == 0) {
193 } else if (stricmp(cmd
, "VERSION") == 0) {
195 server
= strtok(NULL
, " ");
197 raw(":%s 351 %s %s_%s. %s", servername
, source
+1, PACKAGE
, VERSION
, servername
);
199 } else if (strncmp(cmd
, "NICK", 4) == 0) {
200 if (buffer
[0] == ':')
203 if ((tempPtr
= find((source
+ 1))))
206 nick
= strtok(NULL
, " ");
207 tempPtr
->setNick(nick
);
214 } else if (stricmp(cmd
, "N") == 0 && strlen(source
) == 2) {
216 char *nick
, *realnick
;
217 realnick
= strtok(NULL
, " ");
219 for (int x
= 0; x
< 5; x
++)
220 nick
= strtok(NULL
, " ");
225 log ("aClient has modes");
228 // Searching for the +r mode (extra parameter)
229 for (unsigned int count
= 1; count
< strlen(nick
); count
++)
231 if (nick
[count
] == 'r')
233 nick
= strtok(NULL
, " ");
237 nick
= strtok(NULL
, " ");
242 nick
= strtok(NULL
, " ");
245 newuser
= new aClient(nick
, realnick
);
247 newuser
= new aClient(nick
);
253 notice(s_GameServ
, nick
, welcomemsg
, realnick
);
255 notice(s_GameServ
, nick
, welcomemsg
, nick
);
258 clients
.insertAtBack(newuser
);
262 } else if (stricmp(cmd
, "Q") == 0) {
264 } else if (stricmp(cmd
, "QUIT") == 0) {
272 if ((quitter
= find(source
)))
273 clients
.remove(quitter
);
274 if ((quitter
= findIRCplayer(source
)))
276 quitter
->setNick("!NULL!");
277 quitter
->stats
->user
= NULL
; // Unidentify them
284 } else if (stricmp(cmd
, "P") == 0) {
287 longname
= new char[strlen(s_GameServ
) + strlen(servername
) + 2];
289 sprintf(longname
, "%S@%s", servername
);
291 dest
= strtok(NULL
, " ");
292 rest
= strtok(NULL
, "");
293 if (stricmp(dest
, gsnum
) == 0 || stricmp(dest
, longname
) == 0)
296 gameserv(source
, rest
);
298 else if (stricmp(dest
, c_Forest
) == 0)
301 forest(source
, rest
);
304 } else if (stricmp(cmd
, "PRIVMSG") == 0) {
306 dest
= strtok(NULL
, " ");
307 rest
= strtok(NULL
, "");
308 if (strnicmp(dest
, s_GameServ
, strlen(s_GameServ
)) == 0)
309 gameserv(source
, rest
);
310 else if (stricmp(dest
, c_Forest
) == 0)
311 forest(source
, rest
);
313 } else if (stricmp(cmd
, "JOIN") == 0) {
315 channel
= strtok(NULL
, " ");
316 if (stricmp(channel
, c_Forest
) == 0 && is_playing(source
+ 1))
317 raw(":%S MODE %s +v %s", c_Forest
, (source
+ 1));
320 } else if (stricmp(cmd
, "SJOIN") == 0) {
321 char *channel
, *nick
, *tmp
, *rest
;
322 strtok(NULL
, " "); // Ignore the TS
324 strtok(NULL
, " "); // Ignore the TS
326 channel
= strtok(NULL
, " ");
327 rest
= strtok(NULL
, "");
328 tmp
= strchr(rest
, ':');
330 nick
= strtok(tmp
, " ");
336 nick
++; // Assume for users set op and voice, they
337 // are never passed as +@nick
338 if (stricmp(channel
, c_Forest
) == 0 && is_playing(nick
))
339 raw(":%S MODE %s +v %s", channel
, nick
);
341 nick
= strtok(NULL
, " ");
346 log("Unrecognized Message: cmd = %s source = %s", cmd
, source
);
364 unload_config_file();
368 aClient
*find(char *nick
)
370 return findbynick(nick
);
373 aClient
*find(const char *nick
)
375 return findbynick(nick
);
380 aClient
*findbyrealnick(char *realnick
)
382 ListNode
<aClient
> *newPtr
;
383 newPtr
= clients
.First();
385 aClient
*client
= NULL
;
389 client
= newPtr
->getData();
390 if (stricmp(client
->getRealNick(), realnick
) == 0)
393 newPtr
= newPtr
->Next();
400 aClient
*findbyrealnick(char *realnick
)
402 return findbynick(realnick
);
407 aClient
*findbynick(char *nick
)
409 ListNode
<aClient
> *newPtr
;
410 newPtr
= clients
.First();
412 aClient
*client
= NULL
;
416 client
= newPtr
->getData();
418 if (strcmp(client
->getNick(), nick
) == 0)
420 if (stricmp(client
->getNick(), nick
) == 0)
424 newPtr
= newPtr
->Next();
429 aClient
*findIRCplayer(const char *nick
)
431 ListNode
<aClient
> *newPtr
;
434 for (newPtr
= players
.First(); newPtr
; newPtr
= newPtr
->Next())
436 p
= newPtr
->getData();
438 if (strcmp(p
->getNick(), nick
) == 0)
440 if (stricmp(p
->getNick(), nick
) == 0)
447 aClient
*findplayer(const char *name
)
449 ListNode
<aClient
> *newPtr
;
452 for (newPtr
= players
.First(); newPtr
; newPtr
= newPtr
->Next())
454 p
= newPtr
->getData()->stats
;
455 if (stricmp(p
->name
, name
) == 0)
456 return newPtr
->getData();
462 aClient
*findbynick(const char *nick
)
464 ListNode
<aClient
> *newPtr
;
465 newPtr
= clients
.First();
467 aClient
*client
= NULL
;
471 client
= newPtr
->getData();
473 if (strcmp(client
->getNick(), nick
) == 0)
475 if (stricmp(client
->getNick(), nick
) == 0)
479 newPtr
= newPtr
->Next();
484 void load_timestamp()
488 infile
.open(".gstimestamp");
493 log("Error opening .gstimestamp");
498 log("Generating new timestamp");
500 timestamp
= midnight();
507 if (timestamp
< 1000000)
511 void save_timestamp()
515 outfile
.open(".gstimestamp");
519 log("Error creating new file .gstimestamp");
523 outfile
<< timestamp
<< endl
;
528 long int midnight(long int offset
)
530 return (time(NULL
) - (time(NULL
) % 86400)) + (offset
* 3600);
533 /* daemon() - detach process from user and disappear into the background
534 * returns -1 on failure, but you can't do much except exit in that case
535 * since we may already have forked. This is based on the BSD version,
536 * so the caller is responsible for things like the umask, etc.
539 /* believed to work on all Posix systems */
541 int daemon(int nochdir
, int noclose
)
544 switch (pid
= fork())
548 default: _exit(0); /* exit the original process */
551 if (setsid() < 0) /* shoudn't fail */
554 /* dyke out this switch if you want to acquire a control tty in */
555 /* the future -- not normally advisable for daemons */
557 switch (pid
= fork())
563 outfile
.open("gameserv.pid");
565 cerr
<< "Unable to open gameserv.pid" << endl
;
566 outfile
<< pid
<< endl
;
578 open("/dev/null",O_RDWR
);
586 /* closeall() -- close all FDs >= a specified value */
588 void closeall(int fd
)
590 int fdlimit
= sysconf(_SC_OPEN_MAX
);