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