1 // Emacs style mode select   -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // Copyright (C) 2000 by DooM Legacy Team.
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 //-----------------------------------------------------------------------------
17 
18 #ifdef __GNUC__
19 #include <unistd.h>
20 #endif
21 #include <typeinfo>
22 #include "common.h"
23 #include "srvlist.h"
24 
25 //=============================================================================
26 
27 /*
28 **
29 */
CList()30 CList::CList()
31 {
32 	list = NULL;
33 	current = NULL;
34 }
35 
36 /*
37 **
38 */
~CList()39 CList::~CList()
40 {
41 	CItem *p;
42 
43 	while (list)
44 	{
45 		p = list;
46 		list = list->next;
47 		delete(p);
48 	}
49 }
50 
51 /*
52 **
53 */
insert(CItem * item)54 int CList::insert(CItem *item)
55 {
56 	item->next = list;
57 	list = item;
58 	return 0;
59 }
60 
61 /*
62 **
63 */
remove(CItem * item)64 int CList::remove(CItem *item)
65 {
66 	CItem *position, *q;
67 
68 	q = NULL;
69 	position = list;
70 
71 	while (position && (position != item))
72 	{
73 		q = position;
74 		position = position->next;
75 	}
76 	if (position)
77 	{
78 		if (q)
79 			q->next = position->next;
80 		else
81 			list = position->next;
82 		delete position;
83 
84 		return 1;
85 	}
86 
87 	return 0;
88 }
89 
90 /*
91 **
92 */
getFirst()93 CItem *CList::getFirst()
94 {
95 	current = list;
96 	return current;
97 }
98 
99 /*
100 **
101 */
getNext()102 CItem *CList::getNext()
103 {
104 	if (current)
105 		current = current->next;
106 	return current;
107 }
108 
109 /*
110 **
111 */
show()112 void CList::show()
113 {
114 	CItem *p;
115 
116 	p = list;
117 	while (p)
118 	{
119 		p->print();
120 		p = p->next;
121 	}
122 }
123 
124 //=============================================================================
125 
126 /*
127 **
128 */
CItem()129 CItem::CItem()
130 {
131 	next = NULL;
132 }
133 
134 //=============================================================================
135 
136 /*
137 **
138 */
CInetAddr(const char * ip,const char * port)139 CInetAddr::CInetAddr(const char *ip, const char *port)
140 {
141 	strcpy(this->ip, ip);
142 	strcpy(this->port, port);
143 	PortNotChanged = true;
144 }
145 
146 /*
147 **
148 */
getIP()149 const char *CInetAddr::getIP()
150 {
151 	return ip;
152 }
153 
154 /*
155 **
156 */
getPort()157 const char *CInetAddr::getPort()
158 {
159 	return port;
160 }
161 
162 /*
163 **
164 */
setPort(const char * port)165 bool CInetAddr::setPort(const char *port)
166 {
167 	if (PortNotChanged)
168 	{
169 		strcpy(this->port, port);
170 		PortNotChanged = false;
171 	}
172 	return !PortNotChanged;
173 }
174 
175 //=============================================================================
176 
177 /*
178 **
179 */
CPlayerItem(const char * ip,const char * port,const char * nickname)180 CPlayerItem::CPlayerItem(const char *ip, const char *port,
181 	const char *nickname) : CInetAddr(ip, port)
182 {
183 	strcpy(this->nickname, nickname);
184 }
185 
186 /*
187 **
188 */
print()189 void CPlayerItem::print()
190 {
191 	dbgPrintf(GREEN, "\tIP\t\t: %s\n\tPort\t\t: %s\n\tNickname\t: %s\n",
192 		ip, port, nickname);
193 }
194 
195 /*
196 **
197 */
getString()198 char *CPlayerItem::getString()
199 {
200 	static char tmpbuf[1024];
201 
202 	snprintf(tmpbuf, sizeof tmpbuf,
203 		"\tIP\t\t: %s\n\tPort\t\t: %s\n\tNickname\t: %s\n",
204 		ip, port, nickname);
205 	return tmpbuf;
206 }
207 
208 //=============================================================================
209 
210 /*
211 **
212 */
CServerItem(const char * ip,const char * port,const char * hostname,const char * version,ServerType type)213 CServerItem::CServerItem(const char *ip, const char *port, const char *hostname, const char *version, ServerType type) : CInetAddr(ip, port)
214 {
215 	time_t timenow = time(NULL);
216 	const tm *timeGMT = gmtime(&timenow);
217 	// check name of server here
218 	strcpy(this->hostname, hostname);
219 	strcpy(this->version, version);
220 	this->type = type;
221 	strftime(reg_time, REG_TIME_SIZE+1, "%Y-%m-%dT%H:%MZ",timeGMT);
222 	{
223 		int i;
224 		memset(guid,'\0',GUID_SIZE);
225 		strcpy(&guid[0], ip);
226 		strcpy(&guid[15], port); // GenUID
227 		for (i = 0; i <= GUID_SIZE-1; i++)
228 		{
229 			if (guid[i] == '\0' || guid[i] == '.')
230 				guid[i] = '0' + (rand()/(RAND_MAX/15));
231 			if (guid[i] > '9')
232 				guid[i] += 'A'-'9';
233 		}
234 		guid[GUID_SIZE] = '\0';
235 	}
236 
237 	HeartBeat = time(NULL);
238 }
239 
240 /*
241 **
242 */
print()243 void CServerItem::print()
244 {
245 	dbgPrintf(GREEN, "IP\t\t: %s\nPort\t\t: %s\nHostname\t: %s\nVersion\t: %s\nPermanent\t: %s\n",
246 		ip, port, hostname, version, (type == ST_PERMANENT) ? "Yes" : "No");
247 }
248 
249 /*
250 **
251 */
getString()252 const char *CServerItem::getString()
253 {
254 	static char tmpbuf[1024];
255 
256 	snprintf(tmpbuf, sizeof tmpbuf,
257 		"IP\t\t: %s\nPort\t\t: %s\nHostname\t: %s\nVersion\t\t: %s\nPermanent\t: %s\n",
258 		ip, port, hostname, version, (type==ST_PERMANENT) ? "Yes" : "No");
259 	return tmpbuf;
260 }
261 
262 /*
263 **
264 */
getName()265 const char *CServerItem::getName()
266 {
267 	return hostname;
268 }
269 
270 /*
271 **
272 */
getVersion()273 const char *CServerItem::getVersion()
274 {
275 	return version;
276 }
277 
278 /*
279 **
280 */
getGuid()281 const char *CServerItem::getGuid()
282 {
283 	return guid;
284 }
285 
286 /*
287 **
288 */
getRegtime()289 const char *CServerItem::getRegtime()
290 {
291 	return reg_time;
292 }
293 
294 /*
295 **
296 */
297 //=============================================================================
298 
299 /*
300 **
301 */
insertPlayer(CServerItem * server,CPlayerItem * player)302 void CServerList::insertPlayer(CServerItem *server, CPlayerItem *player)
303 {
304 	server->players_list.insert(player);
305 }
306 
307 /*
308 **
309 */
removePlayer(CServerItem * server,CPlayerItem * player)310 void CServerList::removePlayer(CServerItem *server, CPlayerItem *player)
311 {
312 	server->players_list.remove(player);
313 }
314 
315 /*
316 **
317 */
insert(CServerItem * server)318 int CServerList::insert(CServerItem *server)
319 {
320 	CList::insert((CItem *)server);
321 	return 0;
322 }
323 
324 /*
325 **
326 */
insert(const char * ip,const char * port,const char * hostname,const char * version,ServerType type)327 int CServerList::insert(const char *ip, const char *port,
328 	const char *hostname, const char *version, ServerType type)
329 {
330 	CServerItem *server;
331 
332 	server = new CServerItem(ip, port, hostname, version, type);
333 	CList::insert(server);
334 	return 0;
335 }
336 
337 /*
338 **
339 */
remove(CServerItem * server)340 int CServerList::remove(CServerItem *server)
341 {
342 	return CList::remove((CItem *)server);
343 }
344 
345 /*
346 **
347 */
remove(const char * ip,const char * port,const char * hostname,const char * version,ServerType type)348 int CServerList::remove(const char *ip, const char *port,
349 	const char *hostname, const char *version, ServerType type)
350 {
351 	// TODO
352 	CServerItem *position, *q;
353 	bool match;
354 
355 	(void)hostname;
356 	(void)port;
357 
358 	match = false;
359 	position = (CServerItem *)list;
360 	q = NULL;
361 
362 	while (position && !match)
363 	{
364 		if (strcmp(position->ip, ip) == 0
365 			&& strcmp(position->version, version) == 0
366 			&& strcmp(position->port, port) == 0
367 			&& position->type == type)
368 		{
369 			match = true;
370 		}
371 		else
372 		{
373 			q = position;
374 			position = (CServerItem *)position->next;
375 		}
376 	}
377 	if (position && match)
378 	{
379 		if (q)
380 			q->next = position->next;
381 		else
382 			list = position->next;
383 		delete position;
384 
385 		return 1;
386 	}
387 
388 	return 0;
389 }
390 
391 /*
392 **
393 */
show()394 void CServerList::show()
395 {
396 	CServerItem *p;
397 
398 	p = (CServerItem *)list;
399 	while (p)
400 	{
401 		p->print();
402 		p->players_list.show();
403 		p = (CServerItem *)p->next;
404 	}
405 }
406