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