]> jfr.im git - irc/gameservirc.git/blob - gameserv/tcpclient.cpp
Updated the Change log and added flags.h.
[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 <iostream.h>
24 #include <fstream.h>
25 #include <iomanip.h>
26 #include <stdlib.h>
27
28 int sock;
29 long timestamp;
30
31 List<aClient> clients;
32
33 void save_timestamp();
34 void load_timestamp();
35
36 int main(int argc, char *argv[])
37 {
38 char buffer[1024], buf[1024];
39 int connected = 1;
40 char *cmd, *source = NULL;
41 srand(time(NULL));
42
43 load_config_file();
44
45 if (argc == 1) {
46 argc = 3;
47 argv[1] = remoteserver;
48 argv[2] = remoteport;
49 }
50 if (argc != 3) {
51 fprintf(stderr,"Usage: tcpclient host port\n");
52 fprintf(stderr,"where host is the machine which is running the\n");
53 fprintf(stderr,"tcpserver program, and port is the port it is\n");
54 fprintf(stderr,"listening on.\n");
55 exit(EXIT_FAILURE);
56 }
57 ignore_pipe();
58 sock = make_connection(argv[2], SOCK_STREAM, argv[1]);
59 if (sock == -1) {
60 fprintf(stderr,"make_connection failed.\n");
61 unload_config_file();
62 return -1;
63 }
64
65 #ifdef UNREAL
66 raw("PROTOCTL NICKv2 VHP");
67 raw("PASS :%s", remotepass);
68 raw("SERVER %s 1 :%s", servername, servername);
69 raw("NICK %S 1 %d %S %s %s %d +owghraAxNt %s :GameServ", time(NULL), gshost,
70 servername, time(NULL), gshost);
71 raw(":%S JOIN %s", c_Forest);
72 raw(":%S MODE %s +mtn", c_Forest);
73 #elif defined(BAHAMUT)
74 raw("PASS %s :TS", remotepass);
75 raw("SERVER %s 1 :%s", servername, servername);
76 raw("NICK %S 1 %d +o %s %s %s 0 :GameServ", time(NULL), gsident, gshost,
77 servername);
78 raw(":%s SJOIN %d %d %s +mnt :@%S", servername, time(NULL), time(NULL), c_Forest);
79 #endif
80 raw(":%S MODE %s +o %S", c_Forest);
81 raw(":%S TOPIC %s :%s", c_Forest, c_ForestTopic);
82
83 sock_gets(sock,buffer,sizeof(buffer)-1); /* -1 added thanks to
84 David Duchene <dave@ltd.com> for pointing out the possible
85 buffer overflow resulting from the linefeed added below. */
86
87
88 printf("Server: %s\n",buffer);
89 init_monsters();
90 init_masters();
91 load_gs_dbase();
92 load_timestamp();
93 int loadtime = time(NULL);
94 bool loaded = false;
95
96 while (connected) {
97 if (sock_gets(sock,buffer,sizeof(buffer)) == -1) {
98 connected = 0;
99 }
100 strcpy(buf, buffer);
101
102 if (buffer[0] == ':')
103 {
104 source = strtok(buf, " ");
105 cmd = strtok(NULL, " ");
106 }
107 else
108 cmd = strtok(buf, " ");
109
110 cout << "Server: " << buffer << endl << flush;
111
112 // Wait five seconds then we're loaded.
113 if (!loaded)
114 {
115 if (time(NULL) >= 5 + loadtime)
116 loaded = true;
117 }
118
119 if (stricmp(cmd, "PING") == 0) {
120 char *timestamp;
121 timestamp = strtok(NULL, "");
122 raw("PONG %s", timestamp);
123 } else if (strncmp(cmd, "NICK", 4) == 0) {
124 if (buffer[0] == ':')
125 {
126 aClient *tempPtr;
127 if ((tempPtr = find((source + 1))))
128 {
129 char *nick;
130 nick = strtok(NULL, " ");
131 tempPtr->setNick(nick);
132 }
133 }
134 else
135 {
136 char *nick;
137 aClient *newuser;
138 nick = strtok(NULL, " ");
139 newuser = new aClient(nick);
140 if (loaded)
141 {
142 notice(s_GameServ, nick, "Hello, %s! This network utilizes a services package called GameServ.", nick);
143 notice(s_GameServ, nick, "For info on how to play the game, type /msg %S help.");
144 }
145 clients.insertAtBack(newuser);
146 delete newuser;
147 }
148 } else if (stricmp(cmd, "QUIT") == 0) {
149 aClient *quitter;
150 if ((quitter = find(source + 1)))
151 clients.remove(quitter);
152 if ((quitter = findplayer(source + 1)))
153 quitter->setNick("NULL");
154
155 } else if (stricmp(cmd, "PRIVMSG") == 0) {
156 char *rest, *dest;
157 dest = strtok(NULL, " ");
158 rest = strtok(NULL, "");
159 if (strnicmp(dest, s_GameServ, strlen(s_GameServ)) == 0)
160 gameserv(source, rest);
161 else if (stricmp(dest, c_Forest) == 0)
162 forest(source, rest);
163 } else if (stricmp(cmd, "JOIN") == 0) {
164 char *channel;
165 channel = strtok(NULL, " ");
166 if (stricmp(channel, c_Forest) == 0 && is_playing(source + 1))
167 raw(":%S MODE %s +v %s", c_Forest, (source + 1));
168
169 #if defined(BAHAMUT)
170 } else if (stricmp(cmd, "SJOIN") == 0) {
171 char *channel, *nick;
172 strtok(NULL, " "); // Ignore the TS
173 strtok(NULL, " "); // Ignore the TS
174 channel = strtok(NULL, " ");
175 strtok(NULL, " ");
176 nick = strtok(NULL, " ");
177 nick++; // Get rid of the :
178 if (stricmp(channel, c_Forest) == 0 && is_playing(nick))
179 raw(":%S MODE %s +v %s", channel, nick);
180 #endif
181
182 } else {
183 // cout << "Unrecognized Message: cmd = " << cmd << setw(30) << "source = " <<
184 // source << endl;
185 }
186 }
187 save_gs_dbase();
188 save_timestamp();
189 delete_monsters();
190 delete_masters();
191
192 printf("<CLOSED>\n");
193 close(sock);
194 unload_config_file();
195 return 0;
196 }
197
198 aClient *find(char *nick)
199 {
200 return findbynick(nick);
201 }
202
203 aClient *find(const char *nick)
204 {
205 return findbynick(nick);
206 }
207
208
209 aClient *findbynick(char *nick)
210 {
211 ListNode <aClient> *newPtr;
212 newPtr = clients.First();
213
214 aClient *client = NULL;
215
216 while (newPtr)
217 {
218 client = newPtr->getData();
219 if (stricmp(client->getNick(), nick) == 0)
220 return client;
221 client = NULL;
222 newPtr = newPtr->Next();
223 }
224 return client;
225 }
226
227 aClient *findplayer(const char *name)
228 {
229 ListNode <aClient> *newPtr;
230 Player *p = NULL;
231
232 for (newPtr = players.First(); newPtr; newPtr = newPtr->Next())
233 {
234 p = newPtr->getData()->stats;
235 if (stricmp(p->name, name) == 0)
236 return newPtr->getData();
237 p = NULL;
238 }
239 return NULL;
240 }
241
242 aClient *findbynick(const char *nick)
243 {
244 ListNode <aClient> *newPtr;
245 newPtr = clients.First();
246
247 aClient *client = NULL;
248
249 while (newPtr)
250 {
251 client = newPtr->getData();
252 if (stricmp(client->getNick(), nick) == 0)
253 return client;
254 client = NULL;
255 newPtr = newPtr->Next();
256 }
257 return client;
258 }
259
260 void load_timestamp()
261 {
262 ifstream infile;
263
264 infile.open(".gstimestamp");
265
266 if (infile.fail())
267 {
268 cout << "Error opening .gstimestamp" << endl;
269 cout << "Generating new timestamp" << endl;
270 generate:
271 timestamp = midnight();
272 save_timestamp();
273 return;
274 }
275
276 infile >> timestamp;
277 infile.close();
278 if (timestamp < 1000000)
279 goto generate;
280 }
281
282 void save_timestamp()
283 {
284 ofstream outfile;
285
286 outfile.open(".gstimestamp");
287
288 if (outfile.fail())
289 {
290 cout << "Error creating new file." << endl;
291 return;
292 }
293
294 outfile << timestamp << endl;
295
296 outfile.close();
297 }
298
299 long int midnight(long int offset)
300 {
301 return (time(NULL) - (time(NULL) % 86400)) + (offset * 3600);
302 }