1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16 #define CLAN_INTERNAL_ACCESS
17 #include "common/setup_before.h"
18 #include <stdio.h>
19 #ifdef HAVE_STDDEF_H
20 # include <stddef.h>
21 #else
22 # ifndef NULL
23 # define NULL ((void *)0)
24 # endif
25 #endif
26 #ifdef STDC_HEADERS
27 # include <stdlib.h>
28 #else
29 # ifdef HAVE_MALLOC_H
30 # include <malloc.h>
31 # endif
32 #endif
33 #ifdef HAVE_STRING_H
34 # include <string.h>
35 #else
36 # ifdef HAVE_STRINGS_H
37 # include <strings.h>
38 # endif
39 #endif
40 #include "compat/strrchr.h"
41 #include "compat/strdup.h"
42 #include "compat/strcasecmp.h"
43 #include "compat/strncasecmp.h"
44 #include "compat/pdir.h"
45 #include <errno.h>
46 #include "compat/strerror.h"
47 #ifdef TIME_WITH_SYS_TIME
48 # include <sys/time.h>
49 # include <time.h>
50 #else
51 # ifdef HAVE_SYS_TIME_H
52 # include <sys/time.h>
53 # else
54 # include <time.h>
55 # endif
56 #endif
57 #ifdef HAVE_SYS_TYPES_H
58 # include <sys/types.h>
59 #endif
60 #include "common/eventlog.h"
61 #include "common/packet.h"
62 #include "common/bnet_protocol.h"
63 #include "common/tag.h"
64 #include "common/util.h"
65 #include "common/bnettime.h"
66 #include "common/eventlog.h"
67 #include "common/list.h"
68 #include "common/proginfo.h"
69 #include "common/bn_type.h"
70 #include "common/xalloc.h"
71 #include "connection.h"
72 #include "anongame.h"
73 #include "prefs.h"
74 #include "friends.h"
75 #include "game.h"
76 #include "clan.h"
77 #include "account.h"
78 #include "channel.h"
79 #include "anongame.h"
80 #include "storage.h"
81 #include "server.h"
82 #include "compat/uint.h"
83 #include "common/setup_after.h"
84
85 static t_list *clanlist_head = NULL;
86 int max_clanid = 0;
87
88 /* callback function for storage use */
89
_cb_load_clans(void * clan)90 static int _cb_load_clans(void *clan)
91 {
92 if (clanlist_add_clan(clan) < 0)
93 {
94 eventlog(eventlog_level_error, __FUNCTION__, "failed to add clan to clanlist");
95 return -1;
96 }
97
98 if (((t_clan *) clan)->clanid > max_clanid)
99 max_clanid = ((t_clan *) clan)->clanid;
100 return 0;
101 }
102
103 /*
104 ** Packet Management
105 */
106
clan_send_packet_to_online_members(t_clan * clan,t_packet * packet)107 extern int clan_send_packet_to_online_members(t_clan * clan, t_packet * packet)
108 {
109 t_elem *curr;
110
111 if (!clan)
112 {
113 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
114 return -1;
115 }
116
117 if (!packet)
118 {
119 eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet");
120 return -1;
121 }
122
123 LIST_TRAVERSE(clan->members, curr)
124 {
125 t_clanmember * member;
126 t_clienttag clienttag;
127 t_connection * conn;
128
129 if (!(member = elem_get_data(curr)))
130 {
131 eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
132 continue;
133 }
134 if (!(conn = clanmember_get_conn(member)))
135 continue; // not online
136
137 if (!(clienttag = conn_get_clienttag(conn)))
138 {
139 eventlog(eventlog_level_error,__FUNCTION__,"conn has NULL clienttag");
140 continue;
141 }
142
143 if ((clienttag != CLIENTTAG_WARCRAFT3_UINT ) && (clienttag != CLIENTTAG_WAR3XP_UINT))
144 continue; // online but wrong client
145
146 conn_push_outqueue(conn, packet);
147 }
148
149 return 0;
150 }
151
clan_send_status_window_on_create(t_clan * clan)152 extern int clan_send_status_window_on_create(t_clan * clan)
153 {
154 t_packet * rpacket;
155 t_elem *curr;
156
157 if (!(clan))
158 {
159 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
160 return -1;
161 }
162
163 if ((rpacket = packet_create(packet_class_bnet)))
164 {
165 char channelname[10];
166 if (clan->clantag)
167 sprintf(channelname, "Clan %c%c%c%c", (clan->clantag >> 24), (clan->clantag >> 16) & 0xff, (clan->clantag >> 8) & 0xff, clan->clantag & 0xff);
168 else
169 {
170 sprintf(channelname, "Clans");
171 eventlog(eventlog_level_error,__FUNCTION__,"clan has NULL clantag");
172 }
173
174 packet_set_size(rpacket, sizeof(t_server_w3xp_clan_clanack));
175 packet_set_type(rpacket, SERVER_W3XP_CLAN_CLANACK);
176 bn_byte_set(&rpacket->u.server_w3xp_clan_clanack.unknow1, 0);
177 bn_int_set(&rpacket->u.server_w3xp_clan_clanack.clantag, clan->clantag);
178
179 LIST_TRAVERSE(clan->members, curr)
180 {
181 t_clanmember * member;
182 t_clienttag clienttag;
183 t_connection * conn;
184
185 if (!(member = elem_get_data(curr)))
186 {
187 eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
188 continue;
189 }
190 if (!(conn = clanmember_get_conn(member)))
191 continue; // not online;
192
193 if (!(clienttag = conn_get_clienttag(conn)))
194 {
195 eventlog(eventlog_level_error,__FUNCTION__,"conn has NULL clienttag");
196 continue;
197 }
198 if ((clienttag != CLIENTTAG_WARCRAFT3_UINT) && (clienttag != CLIENTTAG_WAR3XP_UINT))
199 continue; // online but wrong client
200
201 if (conn_get_channel(conn))
202 {
203 conn_update_w3_playerinfo(conn);
204 channel_set_userflags(conn);
205 if (conn_set_channel(conn, channelname) < 0)
206 conn_set_channel(conn, CHANNEL_NAME_BANNED); /* should not fail */
207 }
208 bn_byte_set(&rpacket->u.server_w3xp_clan_clanack.status, member->status);
209 conn_push_outqueue(conn, rpacket);
210 }
211 packet_del_ref(rpacket);
212 }
213 return 0;
214 }
215
clan_close_status_window_on_disband(t_clan * clan)216 extern int clan_close_status_window_on_disband(t_clan * clan)
217 {
218 t_packet * rpacket;
219 t_elem *curr;
220
221 if (!(clan))
222 {
223 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
224 return -1;
225 }
226
227 if ((rpacket = packet_create(packet_class_bnet)))
228 {
229 packet_set_size(rpacket, sizeof(t_server_w3xp_clanquitnotify));
230 packet_set_type(rpacket, SERVER_W3XP_CLANQUITNOTIFY);
231 bn_byte_set(&rpacket->u.server_w3xp_clan_clanack.status, SERVER_W3XP_CLANQUITNOTIFY_STATUS_REMOVED_FROM_CLAN);
232 LIST_TRAVERSE(clan->members, curr)
233 {
234 t_clanmember * member;
235 t_clienttag clienttag;
236 t_connection * conn;
237
238 if (!(member = elem_get_data(curr)))
239 {
240 eventlog(eventlog_level_error,__FUNCTION__,"got NULL elem in list");
241 continue;
242 }
243 if (!(conn = clanmember_get_conn(member)))
244 continue; // not online;
245
246 if (!(clienttag = conn_get_clienttag(conn)))
247 {
248 eventlog(eventlog_level_error,__FUNCTION__,"conn has NULL clienttag");
249 continue;
250 }
251
252 if ((clienttag != CLIENTTAG_WARCRAFT3_UINT) && (clienttag != CLIENTTAG_WAR3XP_UINT))
253 continue; // online but wrong client
254
255 conn_push_outqueue(conn, rpacket);
256 conn_update_w3_playerinfo(conn);
257 }
258 packet_del_ref(rpacket);
259 }
260
261
262 return 0;
263 }
264
clan_send_status_window(t_connection * c)265 extern int clan_send_status_window(t_connection * c)
266 {
267 t_packet * rpacket;
268 t_account *acc;
269 t_clanmember *member;
270 t_clienttag clienttag;
271 t_clan * clan;
272
273 if (!(acc = conn_get_account(c)))
274 return 0;
275
276 if (!(member = account_get_clanmember(acc)))
277 return 0;
278
279 if (!(clan = member->clan))
280 {
281 eventlog(eventlog_level_error,__FUNCTION__,"member has NULL clan");
282 return -1;
283 }
284
285 if (!(clan->clantag))
286 {
287 eventlog(eventlog_level_error,__FUNCTION__,"clan has NULL clantag");
288 return -1;
289 }
290
291 if (!(clienttag = conn_get_clienttag(c)))
292 {
293 eventlog(eventlog_level_error,__FUNCTION__,"conn has NULL clienttag");
294 return -1;
295 }
296
297 if ((clienttag != CLIENTTAG_WARCRAFT3_UINT) && (clienttag != CLIENTTAG_WAR3XP_UINT))
298 return 0;
299
300 if ((rpacket = packet_create(packet_class_bnet)))
301 {
302 packet_set_size(rpacket, sizeof(t_server_w3xp_clan_clanack));
303 packet_set_type(rpacket, SERVER_W3XP_CLAN_CLANACK);
304 bn_byte_set(&rpacket->u.server_w3xp_clan_clanack.unknow1, 0);
305 bn_int_set(&rpacket->u.server_w3xp_clan_clanack.clantag, member->clan->clantag);
306 bn_byte_set(&rpacket->u.server_w3xp_clan_clanack.status, member->status);
307 conn_push_outqueue(c, rpacket);
308 packet_del_ref(rpacket);
309 }
310 return 0;
311 }
312
clan_close_status_window(t_connection * c)313 extern int clan_close_status_window(t_connection * c)
314 {
315 t_packet * rpacket;
316 t_clienttag clienttag;
317
318 if (!(clienttag = conn_get_clienttag(c)))
319 {
320 eventlog(eventlog_level_error,__FUNCTION__,"conn has NULL clienttag");
321 return -1;
322 }
323
324 if ((clienttag != CLIENTTAG_WARCRAFT3_UINT) && (clienttag != CLIENTTAG_WAR3XP_UINT))
325 return 0;
326
327 if ((rpacket = packet_create(packet_class_bnet)))
328 {
329 packet_set_size(rpacket, sizeof(t_server_w3xp_clanquitnotify));
330 packet_set_type(rpacket, SERVER_W3XP_CLANQUITNOTIFY);
331 bn_byte_set(&rpacket->u.server_w3xp_clanquitnotify.status, SERVER_W3XP_CLANQUITNOTIFY_STATUS_REMOVED_FROM_CLAN);
332 conn_push_outqueue(c, rpacket);
333 packet_del_ref(rpacket);
334 }
335 return 0;
336 }
337
clan_send_memberlist(t_connection * c,t_packet const * const packet)338 extern int clan_send_memberlist(t_connection * c, t_packet const *const packet)
339 {
340 t_packet * rpacket;
341 t_elem *curr;
342 char const *username;
343 t_clanmember *member;
344 t_clan *clan;
345 t_account *account;
346 int count = 0;
347 char tmpstr[2];
348 const char *append_str;
349
350 if (!(account = conn_get_account(c)))
351 return -1;
352
353 if (!(clan = account_get_clan(account)))
354 return -1;
355
356 if ((rpacket = packet_create(packet_class_bnet)))
357 {
358 t_account * memberacc;
359
360 packet_set_size(rpacket, sizeof(t_server_w3xp_clanmemberlist_reply));
361 packet_set_type(rpacket, SERVER_W3XP_CLANMEMBERLIST_REPLY);
362 bn_int_set(&rpacket->u.server_w3xp_clanmemberlist_reply.count,
363 bn_int_get(packet->u.client_w3xp_clanmemberlist_req.count));
364 LIST_TRAVERSE(clan->members, curr)
365 {
366 if (!(member = elem_get_data(curr)))
367 {
368 eventlog(eventlog_level_error, __FUNCTION__, "got NULL element in list");
369 continue;
370 }
371
372 if (!(memberacc = member->memberacc))
373 {
374 eventlog(eventlog_level_error,__FUNCTION__,"member has NULL account");
375 continue;
376 }
377
378 username = account_get_name(memberacc);
379 packet_append_string(rpacket, username);
380 tmpstr[0] = member->status;
381 append_str = clanmember_get_online_status(member, &tmpstr[1]);
382 packet_append_data(rpacket, tmpstr, 2);
383 if (append_str)
384 packet_append_string(rpacket, append_str);
385 else
386 packet_append_string(rpacket, "");
387 count++;
388 }
389 bn_byte_set(&rpacket->u.server_w3xp_clanmemberlist_reply.member_count, count);
390 conn_push_outqueue(c, rpacket);
391 packet_del_ref(rpacket);
392 return 0;
393 }
394
395 return -1;
396 }
397
clan_save_motd_chg(t_connection * c,t_packet const * const packet)398 extern int clan_save_motd_chg(t_connection * c, t_packet const *const packet)
399 {
400 t_account *account;
401 char const *motd;
402 int offset;
403 t_clan *clan;
404
405 if ((account = conn_get_account(c)) == NULL)
406 return -1;
407 if ((clan = account_get_clan(account)) == NULL)
408 return -1;
409 offset = sizeof(packet->u.client_w3xp_clan_motdchg);
410 motd = packet_get_str_const(packet, offset, CLAN_MOTD_MAX);
411 eventlog(eventlog_level_trace, __FUNCTION__, "[%d] got W3XP_CLAN_MOTDCHG packet : %s", conn_get_socket(c), motd);
412 if (clan_set_motd(clan, motd) != 0)
413 {
414 eventlog(eventlog_level_error, __FUNCTION__, "Failed to set clan motd.");
415 return -1;
416 }
417 clan->modified = 1;
418 return 0;
419 }
420
421
clan_send_motd_reply(t_connection * c,t_packet const * const packet)422 extern int clan_send_motd_reply(t_connection * c, t_packet const *const packet)
423 {
424 t_packet * rpacket;
425 t_account *account;
426 t_clan *clan;
427
428 if ((account = conn_get_account(c)) == NULL)
429 return -1;
430 if ((clan = account_get_clan(account)) == NULL)
431 return -1;
432 if (clan->clan_motd == NULL)
433 {
434 eventlog(eventlog_level_error, __FUNCTION__, "Failed to get clan motd.");
435 return -1;
436 }
437 if ((rpacket = packet_create(packet_class_bnet)))
438 {
439 packet_set_size(rpacket, sizeof(t_server_w3xp_clan_motdreply));
440 packet_set_type(rpacket, SERVER_W3XP_CLAN_MOTDREPLY);
441 bn_int_set(&rpacket->u.server_w3xp_clan_motdreply.count, bn_int_get(packet->u.client_w3xp_clan_motdreq.count));
442 bn_int_set(&rpacket->u.server_w3xp_clan_motdreply.unknow1, SERVER_W3XP_CLAN_MOTDREPLY_UNKNOW1);
443 packet_append_string(rpacket, clan->clan_motd);
444 conn_push_outqueue(c, rpacket);
445 packet_del_ref(rpacket);
446 }
447
448 return 0;
449 }
450
451 /*
452 ** String / Function Management
453 */
454
clan_get_possible_member(t_connection * c,t_packet const * const packet)455 extern int clan_get_possible_member(t_connection * c, t_packet const *const packet)
456 {
457 t_packet * rpacket;
458 t_channel *channel;
459 t_connection *conn;
460 char const *username;
461 t_account * account;
462
463 int friend_count = 0;
464 int clantag;
465 clantag = bn_int_get(packet->u.client_w3xp_clan_createreq.clantag);
466 if ((rpacket = packet_create(packet_class_bnet)) == NULL)
467 {
468 return -1;
469 }
470 packet_set_size(rpacket, sizeof(t_server_w3xp_clan_createreply));
471 packet_set_type(rpacket, SERVER_W3XP_CLAN_CREATEREPLY);
472 bn_int_set(&rpacket->u.server_w3xp_clan_createreply.count, bn_int_get(packet->u.client_w3xp_clan_createreq.count));
473 if (clanlist_find_clan_by_clantag(clantag) != NULL)
474 {
475 bn_byte_set(&rpacket->u.server_w3xp_clan_createreply.check_result, SERVER_W3XP_CLAN_CREATEREPLY_CHECK_ALLREADY_IN_USE);
476 bn_byte_set(&rpacket->u.server_w3xp_clan_createreply.friend_count, 0);
477 conn_push_outqueue(c, rpacket);
478 packet_del_ref(rpacket);
479 return 0;
480 }
481 if ((account = conn_get_account(c)) && (account_get_clan(account) != NULL || account_get_creating_clan(account) != NULL))
482 {
483 bn_byte_set(&rpacket->u.server_w3xp_clan_createreply.check_result, SERVER_W3XP_CLAN_CREATEREPLY_CHECK_EXCEPTION);
484 bn_byte_set(&rpacket->u.server_w3xp_clan_createreply.friend_count, 0);
485 conn_push_outqueue(c, rpacket);
486 packet_del_ref(rpacket);
487 return 0;
488 }
489 bn_byte_set(&rpacket->u.server_w3xp_clan_createreply.check_result, SERVER_W3XP_CLAN_CREATEREPLY_CHECK_OK);
490 channel = conn_get_channel(c);
491 if (channel_get_permanent(channel))
492 {
493 /* If not in a private channel, retreive number of mutual friend connected */
494 t_list *flist = account_get_friends(conn_get_account(c));
495 t_elem const *curr;
496 t_friend *fr;
497
498 LIST_TRAVERSE_CONST(flist, curr)
499 {
500 if ((fr = elem_get_data(curr)) != NULL)
501 {
502 t_account *fr_acc = friend_get_account(fr);
503 t_clienttag clienttag;
504 if (fr->mutual
505 && ((conn = connlist_find_connection_by_account(fr_acc)) != NULL)
506 && (conn_get_channel(conn) == channel)
507 && (!account_get_clan(fr_acc))
508 && (!account_get_creating_clan(fr_acc))
509 && (clienttag = conn_get_clienttag(conn))
510 && ((clienttag == CLIENTTAG_WAR3XP_UINT) || (clienttag == CLIENTTAG_WARCRAFT3_UINT))
511 && (username = account_get_name(fr_acc)))
512 {
513 friend_count++;
514 packet_append_string(rpacket, username);
515 }
516 }
517 }
518 } else
519 {
520 /* If in a private channel, retreive all users in the channel */
521 for (conn = channel_get_first(channel); conn; conn = channel_get_next())
522 {
523 t_account * acc;
524 t_clienttag clienttag;
525 if ((conn != c)
526 && (acc = conn_get_account(conn))
527 && (!account_get_clan(acc))
528 && (!account_get_creating_clan(acc))
529 && (clienttag = conn_get_clienttag(conn))
530 && ((clienttag == CLIENTTAG_WAR3XP_UINT) || (clienttag == CLIENTTAG_WARCRAFT3_UINT))
531 && (username = conn_get_username(conn)))
532 {
533 friend_count++;
534 packet_append_string(rpacket, username);
535 }
536 }
537 }
538 bn_byte_set(&rpacket->u.server_w3xp_clan_createreply.friend_count, friend_count);
539 conn_push_outqueue(c, rpacket);
540 packet_del_ref(rpacket);
541
542 return 0;
543 }
544
clanmember_on_change_status(t_clanmember * member)545 extern int clanmember_on_change_status(t_clanmember * member)
546 {
547 t_packet * rpacket;
548 if (member == NULL)
549 {
550 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
551 return -1;
552 }
553 if (member->clan == NULL)
554 {
555 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
556 return -1;
557 }
558 if ((rpacket = packet_create(packet_class_bnet)) != NULL)
559 {
560 char tmpstr[2];
561 const char *append_str;
562 packet_set_size(rpacket, sizeof(t_server_w3xp_clanmemberupdate));
563 packet_set_type(rpacket, SERVER_W3XP_CLANMEMBERUPDATE);
564 packet_append_string(rpacket, account_get_name(member->memberacc));
565 tmpstr[0] = member->status;
566 append_str = clanmember_get_online_status(member, &tmpstr[1]);
567 packet_append_data(rpacket, tmpstr, 2);
568 if (append_str)
569 packet_append_string(rpacket, append_str);
570 else
571 packet_append_string(rpacket, "");
572 clan_send_packet_to_online_members(member->clan, rpacket);
573 packet_del_ref(rpacket);
574 }
575 return 0;
576 }
577
clanmember_on_change_status_by_connection(t_connection * conn)578 extern int clanmember_on_change_status_by_connection(t_connection * conn)
579 {
580 t_packet * rpacket;
581 t_account *acc;
582 t_clanmember *member;
583 if (!(conn))
584 {
585 eventlog(eventlog_level_error, __FUNCTION__, "got NULL conn");
586 return -1;
587 }
588 if ((acc = conn_get_account(conn)) == NULL)
589 return -1;
590 if ((member = account_get_clanmember(acc)) == NULL)
591 return -1;
592 if (member->clan == NULL)
593 return -1;
594 if ((rpacket = packet_create(packet_class_bnet)) != NULL)
595 {
596 char tmpstr[2];
597 const char *append_str;
598 packet_set_size(rpacket, sizeof(t_server_w3xp_clanmemberupdate));
599 packet_set_type(rpacket, SERVER_W3XP_CLANMEMBERUPDATE);
600 packet_append_string(rpacket, account_get_name(acc));
601 tmpstr[0] = member->status;
602 append_str = clanmember_get_online_status_by_connection(conn, &tmpstr[1]);
603 packet_append_data(rpacket, tmpstr, 2);
604 if (append_str)
605 packet_append_string(rpacket, append_str);
606 else
607 packet_append_string(rpacket, "");
608 clan_send_packet_to_online_members(member->clan, rpacket);
609 packet_del_ref(rpacket);
610 }
611 return 0;
612 }
613
clan_unload_members(t_clan * clan)614 extern int clan_unload_members(t_clan * clan)
615 {
616 t_elem *curr;
617 t_clanmember *member;
618
619 if (clan->members)
620 {
621 LIST_TRAVERSE(clan->members, curr)
622 {
623 if (!(member = elem_get_data(curr)))
624 {
625 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
626 continue;
627 }
628 list_remove_elem(clan->members, &curr);
629 xfree((void *) member);
630 }
631
632 if (list_destroy(clan->members) < 0)
633 return -1;
634
635 clan->members = NULL;
636 }
637
638 return 0;
639 }
640
clan_remove_all_members(t_clan * clan)641 extern int clan_remove_all_members(t_clan * clan)
642 {
643 t_elem *curr;
644 t_clanmember *member;
645
646 if (clan->members)
647 {
648 LIST_TRAVERSE(clan->members, curr)
649 {
650 if (!(member = elem_get_data(curr)))
651 {
652 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
653 continue;
654 }
655 if (member->memberacc != NULL)
656 account_set_clanmember(member->memberacc, NULL);
657 list_remove_elem(clan->members, &curr);
658 xfree((void *) member);
659 }
660
661 if (list_destroy(clan->members) < 0)
662 return -1;
663
664 clan->members = NULL;
665 }
666
667 return 0;
668 }
669
clanlist_remove_clan(t_clan * clan)670 extern int clanlist_remove_clan(t_clan * clan)
671 {
672 t_elem * elem;
673 if (clan == NULL)
674 {
675 eventlog(eventlog_level_error, __FUNCTION__, "get NULL clan");
676 return -1;
677 }
678 if (list_remove_data(clanlist_head, clan, &elem) < 0)
679 {
680 eventlog(eventlog_level_error, __FUNCTION__, "could not delete clan entry");
681 return -1;
682 }
683 return 0;
684 }
685
clan_remove(int clantag)686 extern int clan_remove(int clantag)
687 {
688 return storage->remove_clan(clantag);
689 }
690
clan_save(t_clan * clan)691 extern int clan_save(t_clan * clan)
692 {
693 if (clan->created <= 0)
694 {
695 if (now - clan->creation_time > 120)
696 {
697 clanlist_remove_clan(clan);
698 clan_destroy(clan);
699 }
700 return 0;
701 }
702
703 storage->write_clan(clan);
704
705 clan->modified = 0;
706
707 return 0;
708 }
709
clanlist(void)710 extern t_list *clanlist(void)
711 {
712 return clanlist_head;
713 }
714
clanlist_add_clan(t_clan * clan)715 extern int clanlist_add_clan(t_clan * clan)
716 {
717 if (!(clan))
718 {
719 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
720 return -1;
721 }
722
723 if (!(clan->clanid))
724 clan->clanid = ++max_clanid;
725
726 list_append_data(clanlist_head, clan);
727
728 return clan->clanid;
729 }
730
clanlist_load(void)731 int clanlist_load(void)
732 {
733 // make sure to unload previous clanlist before loading again
734 if (clanlist_head)
735 clanlist_unload();
736
737 clanlist_head = list_create();
738
739 storage->load_clans(_cb_load_clans);
740
741 return 0;
742 }
743
clanlist_save(void)744 extern int clanlist_save(void)
745 {
746 t_elem *curr;
747 t_clan *clan;
748
749 if (clanlist_head)
750 {
751 LIST_TRAVERSE(clanlist_head, curr)
752 {
753 if (!(clan = elem_get_data(curr)))
754 {
755 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
756 continue;
757 }
758 if (clan->modified)
759 clan_save(clan);
760 }
761
762 }
763
764 return 0;
765 }
766
clanlist_unload(void)767 extern int clanlist_unload(void)
768 {
769 t_elem *curr;
770 t_clan *clan;
771
772 if (clanlist_head)
773 {
774 LIST_TRAVERSE(clanlist_head, curr)
775 {
776 if (!(clan = elem_get_data(curr)))
777 {
778 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
779 continue;
780 }
781 if (clan->clanname)
782 xfree((void *) clan->clanname);
783 if (clan->clan_motd)
784 xfree((void *) clan->clan_motd);
785 clan_unload_members(clan);
786 xfree((void *) clan);
787 list_remove_elem(clanlist_head, &curr);
788 }
789
790 if (list_destroy(clanlist_head) < 0)
791 return -1;
792
793 clanlist_head = NULL;
794 }
795
796 return 0;
797 }
798
clanlist_find_clan_by_clanid(int cid)799 extern t_clan *clanlist_find_clan_by_clanid(int cid)
800 {
801 t_elem *curr;
802 t_clan *clan;
803
804 if (clanlist_head)
805 {
806 LIST_TRAVERSE(clanlist_head, curr)
807 {
808 if (!(clan = elem_get_data(curr)))
809 {
810 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
811 continue;
812 }
813 eventlog(eventlog_level_error, __FUNCTION__, "trace %d", clan->clanid);
814 if (clan->created && (clan->clanid == cid))
815 return clan;
816 }
817
818 }
819
820 return NULL;
821 }
822
clanlist_find_clan_by_clantag(int clantag)823 extern t_clan *clanlist_find_clan_by_clantag(int clantag)
824 {
825 t_elem *curr;
826 t_clan *clan;
827
828 if (clantag == 0)
829 return NULL;
830 if (clanlist_head)
831 {
832 LIST_TRAVERSE(clanlist_head, curr)
833 {
834 if (!(clan = elem_get_data(curr)))
835 {
836 eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
837 continue;
838 }
839 if (clan->created && (clan->clantag == clantag))
840 return clan;
841 }
842
843 }
844
845 return NULL;
846 }
847
clan_find_member(t_clan * clan,t_account * memberacc)848 extern t_clanmember *clan_find_member(t_clan * clan, t_account * memberacc)
849 {
850 t_clanmember *member;
851 t_elem *curr;
852 if (!(clan))
853 {
854 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
855 return NULL;
856 }
857 if (!(clan->members))
858 {
859 eventlog(eventlog_level_error, __FUNCTION__, "found NULL clan->members");
860 return NULL;
861 }
862 LIST_TRAVERSE(clan->members, curr)
863 {
864 if (!(member = elem_get_data(curr)))
865 {
866 eventlog(eventlog_level_error, __FUNCTION__, "got NULL element in list");
867 return NULL;
868 }
869 if (member->memberacc == memberacc)
870 return member;
871 }
872
873 return NULL;
874 }
875
clan_find_member_by_name(t_clan * clan,char const * membername)876 extern t_clanmember *clan_find_member_by_name(t_clan * clan, char const *membername)
877 {
878 t_clanmember *member;
879 t_elem *curr;
880 if (!(clan))
881 {
882 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
883 return NULL;
884 }
885 if (!(clan->members))
886 {
887 eventlog(eventlog_level_error, __FUNCTION__, "found NULL clan->members");
888 return NULL;
889 }
890 LIST_TRAVERSE(clan->members, curr)
891 {
892 if (!(member = elem_get_data(curr)))
893 {
894 eventlog(eventlog_level_error, __FUNCTION__, "got NULL element in list");
895 return NULL;
896 }
897 if (strcasecmp(account_get_name(member->memberacc), membername) == 0)
898 return member;
899 }
900
901 return NULL;
902 }
903
clan_find_member_by_uid(t_clan * clan,unsigned int memberuid)904 extern t_clanmember *clan_find_member_by_uid(t_clan * clan, unsigned int memberuid)
905 {
906 t_clanmember *member;
907 t_elem *curr;
908 if (!(clan))
909 {
910 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
911 return NULL;
912 }
913 if (!(clan->members))
914 {
915 eventlog(eventlog_level_error, __FUNCTION__, "found NULL clan->members");
916 return NULL;
917 }
918 LIST_TRAVERSE(clan->members, curr)
919 {
920 if (!(member = elem_get_data(curr)))
921 {
922 eventlog(eventlog_level_error, __FUNCTION__, "got NULL element in list");
923 return NULL;
924 }
925 if (account_get_uid(member->memberacc) == memberuid)
926 return member;
927 }
928
929 return NULL;
930 }
931
clanmember_get_account(t_clanmember * member)932 extern t_account *clanmember_get_account(t_clanmember * member)
933 {
934 if (!(member))
935 {
936 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
937 return NULL;
938 }
939
940 return (t_account *) member->memberacc;
941 }
942
clanmember_set_account(t_clanmember * member,t_account * memberacc)943 extern int clanmember_set_account(t_clanmember * member, t_account * memberacc)
944 {
945 if (!(member))
946 {
947 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
948 return -1;
949 }
950
951 member->memberacc = memberacc;
952 return 0;
953 }
954
clanmember_get_conn(t_clanmember * member)955 extern t_connection *clanmember_get_conn(t_clanmember * member)
956 {
957 t_account * account;
958
959 if (!(member))
960 {
961 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
962 return NULL;
963 }
964
965 if (!(account = member->memberacc))
966 {
967 eventlog(eventlog_level_error,__FUNCTION__,"member as NULL account");
968 return NULL;
969 }
970
971 return account_get_conn(account);
972 }
973
clanmember_get_status(t_clanmember * member)974 extern char clanmember_get_status(t_clanmember * member)
975 {
976 if (!(member))
977 {
978 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
979 return 0;
980 }
981
982 if ((member->status == CLAN_NEW) && (now - member->join_time > prefs_get_clan_newer_time() * 3600))
983 {
984 member->status = CLAN_PEON;
985 member->clan->modified = 1;
986 #ifdef WITH_SQL
987 member->modified = 1;
988 #endif
989 }
990
991 return member->status;
992 }
993
clanmember_set_status(t_clanmember * member,char status)994 extern int clanmember_set_status(t_clanmember * member, char status)
995 {
996 if (!(member))
997 {
998 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
999 return -1;
1000 }
1001
1002 if (member->status != status)
1003 {
1004 member->status = status;
1005 member->clan->modified = 1;
1006 #ifdef WITH_SQL
1007 member->modified = 1;
1008 #endif
1009 }
1010 return 0;
1011 }
1012
clanmember_get_join_time(t_clanmember * member)1013 extern time_t clanmember_get_join_time(t_clanmember * member)
1014 {
1015 if (!(member))
1016 {
1017 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
1018 return 0;
1019 }
1020
1021 return member->join_time;
1022 }
1023
clanmember_get_clan(t_clanmember * member)1024 extern t_clan *clanmember_get_clan(t_clanmember * member)
1025 {
1026 if (!(member))
1027 {
1028 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanmember");
1029 return 0;
1030 }
1031
1032 return member->clan;
1033 }
1034
clanmember_get_online_status(t_clanmember * member,char * status)1035 extern const char *clanmember_get_online_status(t_clanmember * member, char *status)
1036 {
1037 return clanmember_get_online_status_by_connection(clanmember_get_conn(member), status);
1038 }
1039
clanmember_get_online_status_by_connection(t_connection * conn,char * status)1040 extern const char *clanmember_get_online_status_by_connection(t_connection * conn, char *status)
1041 {
1042 if (conn && (conn_get_state(conn)!=conn_state_empty))
1043 {
1044 t_game *game;
1045 t_channel *channel;
1046 if ((game = conn_get_game(conn)) != NULL)
1047 {
1048 if (game_get_flag(game) == game_flag_private)
1049 (*status) = SERVER_W3XP_CLAN_MEMBER_PRIVATE_GAME;
1050 else
1051 (*status) = SERVER_W3XP_CLAN_MEMBER_GAME;
1052 return game_get_name(game);
1053 }
1054 if ((channel = conn_get_channel(conn)) != NULL)
1055 {
1056 (*status) = SERVER_W3XP_CLAN_MEMBER_CHANNEL;
1057 return channel_get_name(channel);
1058 }
1059
1060 (*status) = SERVER_W3XP_CLAN_MEMBER_ONLINE;
1061 } else
1062 (*status) = SERVER_W3XP_CLAN_MEMBER_OFFLINE;
1063 return NULL;
1064 }
1065
clanmember_set_online(t_connection * c)1066 extern int clanmember_set_online(t_connection * c)
1067 {
1068 t_clanmember *member;
1069 t_account *acc;
1070
1071 if (!c)
1072 {
1073 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
1074 return -1;
1075 }
1076
1077 if ((acc = conn_get_account(c)) && (member = account_get_clanmember(acc)))
1078 {
1079 clanmember_on_change_status(member);
1080 }
1081
1082 return 0;
1083 }
1084
clanmember_set_offline(t_connection * c)1085 extern int clanmember_set_offline(t_connection * c)
1086 {
1087 t_clanmember *member;
1088 t_account *acc;
1089
1090 if (!c)
1091 {
1092 eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
1093 return -1;
1094 }
1095
1096 if ((acc = conn_get_account(c)) && (member = account_get_clanmember_forced(acc)))
1097 {
1098 clanmember_on_change_status(member);
1099 }
1100
1101 return 0;
1102 }
1103
clan_get_created(t_clan * clan)1104 extern int clan_get_created(t_clan * clan)
1105 {
1106 if (!(clan))
1107 {
1108 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1109 return -1;
1110 }
1111
1112 return clan->created;
1113 }
1114
clan_set_created(t_clan * clan,int created)1115 extern int clan_set_created(t_clan * clan, int created)
1116 {
1117 if (!(clan))
1118 {
1119 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1120 return -1;
1121 }
1122
1123 clan->created = created;
1124
1125 return 0;
1126 }
1127
clan_get_modified(t_clan * clan)1128 extern char clan_get_modified(t_clan * clan)
1129 {
1130 if (!(clan))
1131 {
1132 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1133 return -1;
1134 }
1135
1136 return clan->modified;
1137 }
1138
clan_set_modified(t_clan * clan,char modified)1139 extern int clan_set_modified(t_clan * clan, char modified)
1140 {
1141 if (!(clan))
1142 {
1143 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1144 return -1;
1145 }
1146
1147 clan->modified = modified;
1148
1149 return 0;
1150 }
1151
clan_get_channel_type(t_clan * clan)1152 extern char clan_get_channel_type(t_clan * clan)
1153 {
1154 if (!(clan))
1155 {
1156 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1157 return -1;
1158 }
1159
1160 return clan->channel_type;
1161 }
1162
clan_set_channel_type(t_clan * clan,char channel_type)1163 extern int clan_set_channel_type(t_clan * clan, char channel_type)
1164 {
1165 if (!(clan))
1166 {
1167 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1168 return -1;
1169 }
1170
1171 clan->channel_type = channel_type;
1172
1173 return 0;
1174 }
1175
clan_get_members(t_clan * clan)1176 extern t_list *clan_get_members(t_clan * clan)
1177 {
1178 if (!(clan))
1179 {
1180 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1181 return NULL;
1182 }
1183
1184 return clan->members;
1185 }
1186
clan_get_name(t_clan * clan)1187 extern char const *clan_get_name(t_clan * clan)
1188 {
1189 if (!(clan))
1190 {
1191 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1192 return NULL;
1193 }
1194
1195 return clan->clanname;
1196 }
1197
clan_get_clantag(t_clan * clan)1198 extern int clan_get_clantag(t_clan * clan)
1199 {
1200 if (!(clan))
1201 {
1202 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1203 return 0;
1204 }
1205
1206 return clan->clantag;
1207 }
1208
clan_get_motd(t_clan * clan)1209 extern char const *clan_get_motd(t_clan * clan)
1210 {
1211 if (!(clan))
1212 {
1213 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1214 return NULL;
1215 }
1216
1217 return clan->clan_motd;
1218 }
1219
clan_set_motd(t_clan * clan,const char * motd)1220 extern int clan_set_motd(t_clan * clan, const char *motd)
1221 {
1222 if (!(clan))
1223 {
1224 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1225 return -1;
1226 }
1227 if (!(motd))
1228 {
1229 eventlog(eventlog_level_error, __FUNCTION__, "got NULL motd");
1230 return -1;
1231 } else
1232 {
1233 if (clan->clan_motd)
1234 xfree((void *) clan->clan_motd);
1235 clan->clan_motd = xstrdup(motd);
1236 }
1237 return 0;
1238 }
1239
clan_get_clanid(t_clan * clan)1240 extern unsigned int clan_get_clanid(t_clan * clan)
1241 {
1242 if (!(clan))
1243 {
1244 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1245 return 0;
1246 }
1247
1248 return clan->clanid;
1249 }
1250
clan_set_creation_time(t_clan * clan,time_t c_time)1251 extern int clan_set_creation_time(t_clan * clan, time_t c_time)
1252 {
1253 if (!(clan))
1254 {
1255 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1256 return -1;
1257 }
1258
1259 clan->creation_time = c_time;
1260
1261 return 0;
1262 }
1263
clan_get_creation_time(t_clan * clan)1264 extern time_t clan_get_creation_time(t_clan * clan)
1265 {
1266 if (!(clan))
1267 {
1268 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1269 return 0;
1270 }
1271
1272 return clan->creation_time;
1273 }
1274
clan_add_member(t_clan * clan,t_account * memberacc,char status)1275 extern t_clanmember *clan_add_member(t_clan * clan, t_account * memberacc, char status)
1276 {
1277 t_clanmember *member;
1278
1279 if (!(clan))
1280 {
1281 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clan");
1282 return NULL;
1283 }
1284
1285 if (!(clan->members))
1286 {
1287 eventlog(eventlog_level_error, __FUNCTION__, "found NULL clan->members");
1288 return NULL;
1289 }
1290
1291 member = xmalloc(sizeof(t_clanmember));
1292 member->memberacc = memberacc;
1293 member->status = status;
1294 member->join_time = now;
1295 member->clan = clan;
1296 #ifdef WITH_SQL
1297 member->modified = 1;
1298 #endif
1299
1300 list_append_data(clan->members, member);
1301
1302 account_set_clanmember(memberacc, member);
1303
1304 clan->modified = 1;
1305
1306 return member;
1307 }
1308
clan_remove_member(t_clan * clan,t_clanmember * member)1309 extern int clan_remove_member(t_clan * clan, t_clanmember * member)
1310 {
1311 t_elem * elem;
1312
1313 if (!member)
1314 return -1;
1315 if (list_remove_data(clan->members, member, &elem) < 0)
1316 {
1317 eventlog(eventlog_level_error, __FUNCTION__, "could not remove member");
1318 return -1;
1319 }
1320 if (member->memberacc != NULL)
1321 {
1322 account_set_clanmember(member->memberacc, NULL);
1323 storage->remove_clanmember(account_get_uid(member->memberacc));
1324 }
1325 xfree((void *) member);
1326 clan->modified = 1;
1327 return 0;
1328 }
1329
clan_create(t_account * chieftain_acc,int clantag,const char * clanname,const char * motd)1330 extern t_clan *clan_create(t_account * chieftain_acc, int clantag, const char *clanname, const char *motd)
1331 {
1332 t_clan *clan;
1333 t_clanmember *member;
1334
1335 clan = xmalloc(sizeof(t_clan));
1336 member = xmalloc(sizeof(t_clanmember));
1337
1338 if (!(clanname))
1339 {
1340 eventlog(eventlog_level_error, __FUNCTION__, "got NULL clanname");
1341 xfree((void *) clan);
1342 xfree((void *) member);
1343 return NULL;
1344 }
1345
1346 clan->clanname = xstrdup(clanname);
1347
1348 if (!(motd))
1349 clan->clan_motd = xstrdup("This is a newly created clan");
1350 else
1351 clan->clan_motd = xstrdup(motd);
1352
1353 clan->creation_time = now;
1354 clan->clantag = clantag;
1355 clan->clanid = ++max_clanid;
1356 clan->created = 0;
1357 clan->modified = 1;
1358 clan->channel_type = prefs_get_clan_channel_default_private();
1359
1360 clan->members = list_create();
1361
1362 member->memberacc = chieftain_acc;
1363 member->status = CLAN_CHIEFTAIN;
1364 member->join_time = clan->creation_time;
1365 member->clan = clan;
1366 #ifdef WITH_SQL
1367 member->modified = 1;
1368 #endif
1369
1370 list_append_data(clan->members, member);
1371
1372 account_set_clanmember(chieftain_acc, member);
1373
1374 return clan;
1375 }
1376
clan_destroy(t_clan * clan)1377 extern int clan_destroy(t_clan * clan)
1378 {
1379 if (!clan)
1380 return 0;
1381 if (clan->clanname)
1382 xfree((void *) clan->clanname);
1383 if (clan->clan_motd)
1384 xfree((void *) clan->clan_motd);
1385 clan_remove_all_members(clan);
1386 xfree((void *) clan);
1387 return 0;
1388 }
1389
clan_get_member_count(t_clan * clan)1390 extern int clan_get_member_count(t_clan * clan)
1391 {
1392 t_elem *curr;
1393 int count = 0;
1394 LIST_TRAVERSE(clan->members, curr)
1395 {
1396 if ((elem_get_data(curr)) != NULL)
1397 count++;
1398 }
1399 return count;
1400 }
1401
str_to_clantag(const char * str)1402 extern int str_to_clantag(const char *str)
1403 {
1404 int clantag = 0;
1405
1406 if (!str)
1407 return 0;
1408
1409 if (str[0])
1410 {
1411 clantag = str[0] << 24;
1412 if (str[1])
1413 {
1414 clantag += str[1] << 16;
1415 if (str[2])
1416 {
1417 clantag += str[2] << 8;
1418 if (str[3])
1419 clantag += str[3];
1420 }
1421 }
1422 }
1423 return clantag;
1424
1425 }
1426