/[LeafOK_CVS]/pvpgn-1.7.4/src/d2cs/connection.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/d2cs/connection.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sat Jun 10 16:20:48 2006 UTC (19 years, 9 months ago) by sysadm
Branch: MAIN
Changes since 1.1: +15 -0 lines
Content type: text/x-csrc
Antibot

1 sysadm 1.1 /*
2     * Copyright (C) 2000,2001 Onlyer (onlyer@263.net)
3     *
4     * This program is free software; you can redistribute it and/or
5     * modify it under the terms of the GNU General Public License
6     * as published by the Free Software Foundation; either version 2
7     * of the License, or (at your option) any later version.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the Free Software
16     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17     */
18     #include "common/setup_before.h"
19     #include "setup.h"
20    
21     #include <ctype.h>
22     #ifdef HAVE_STRING_H
23     # include <string.h>
24     #else
25     # ifdef HAVE_STRINGS_H
26     # include <strings.h>
27     # endif
28     # ifdef HAVE_MEMORY_H
29     # include <memory.h>
30     # endif
31     #endif
32     #ifdef STDC_HEADERS
33     # include <stdlib.h>
34     #else
35     # ifdef HAVE_MALLOC_H
36     # include <malloc.h>
37     # endif
38     #endif
39     #include "compat/memcpy.h"
40     #include "compat/strdup.h"
41     #ifdef HAVE_UNISTD_H
42     # include <unistd.h>
43     #endif
44     #ifdef HAVE_SYS_TYPES_H
45     # include <sys/types.h>
46     #endif
47     #ifdef HAVE_SYS_SOCKET_H
48     # include <sys/socket.h>
49     #endif
50     #include "compat/psock.h"
51     #ifdef HAVE_NETINET_IN_H
52     # include <netinet/in.h>
53     #endif
54     #include "compat/netinet_in.h"
55     #ifdef HAVE_LIMITS_H
56     # include <limits.h>
57     #endif
58     #include "compat/char_bit.h"
59     #ifdef TIME_WITH_SYS_TIME
60     # include <time.h>
61     # include <sys/time.h>
62     #else
63     # ifdef HAVE_SYS_TIME_H
64     # include <sys/time.h>
65     # else
66     # include <time.h>
67     # endif
68     #endif
69     #ifdef HAVE_ASSERT_H
70     # include <assert.h>
71     #endif
72    
73     #include "compat/psock.h"
74     #include "compat/strcasecmp.h"
75     #include "connection.h"
76     #include "game.h"
77     #include "gamequeue.h"
78     #include "prefs.h"
79     #include "d2gs.h"
80     #include "net.h"
81     #include "s2s.h"
82     #include "handle_d2gs.h"
83     #include "handle_d2cs.h"
84     #include "handle_init.h"
85     #include "handle_bnetd.h"
86     #include "d2charfile.h"
87     #include "common/fdwatch.h"
88     #include "common/addr.h"
89     #include "common/introtate.h"
90     #include "common/network.h"
91     #include "common/packet.h"
92     #include "common/hashtable.h"
93     #include "common/queue.h"
94     #include "common/eventlog.h"
95     #include "common/xalloc.h"
96     #include "common/setup_after.h"
97    
98     static t_hashtable * connlist_head=NULL;
99     static t_hashtable * conn_charname_list_head=NULL;
100     static t_list * connlist_dead=NULL;
101     static unsigned int total_connection=0;
102    
103     static int conn_handle_connecting(t_connection * c);
104     static t_packet * conn_create_packet(t_connection * c);
105     static int conn_handle_packet(t_connection * c, t_packet * packet);
106     static int conn_handle_read(t_connection * c);
107     static int conn_handle_write(t_connection * c);
108     static unsigned int conn_charname_hash(char const * charname);
109     static unsigned int conn_sessionnum_hash(unsigned int sessionnum);
110    
111     static unsigned int conn_sessionnum_hash(unsigned int sessionnum)
112     {
113     return sessionnum;
114     }
115    
116     static unsigned int conn_charname_hash(char const * charname)
117     {
118     unsigned int hash;
119     unsigned int i, len, pos;
120     unsigned int ch;
121    
122     ASSERT(charname,0);
123     len=strlen(charname);
124     for (hash=0, i=0, pos=0; i<len; i++) {
125     if (isascii((int)charname[i])) {
126     ch=(unsigned int)(unsigned char)tolower((int)charname[i]);
127     } else {
128     ch=(unsigned int)(unsigned char)charname[i];
129     }
130     hash ^= ROTL(ch,pos,sizeof(unsigned int) * CHAR_BIT);
131     pos += CHAR_BIT-1;
132     }
133     return hash;
134     }
135    
136     extern t_hashtable * d2cs_connlist(void)
137     {
138     return connlist_head;
139     }
140    
141     extern int d2cs_connlist_create(void)
142     {
143     if (!(connlist_head=hashtable_create(200))) return -1;
144     if (!(conn_charname_list_head=hashtable_create(200))) return -1;
145     return 0;
146     }
147    
148     extern int d2cs_connlist_destroy(void)
149     {
150     t_connection * c;
151     t_elem * curr;
152    
153    
154     if (connlist_dead) {
155     d2cs_connlist_reap();
156     if (list_destroy(connlist_dead))
157     eventlog(eventlog_level_error,__FUNCTION__,"error destroy conndead list");
158     connlist_dead = NULL;
159     }
160    
161     BEGIN_HASHTABLE_TRAVERSE_DATA(connlist_head, c)
162     {
163     d2cs_conn_destroy(c,&curr);
164     }
165     END_HASHTABLE_TRAVERSE_DATA()
166    
167     if (hashtable_destroy(connlist_head)<0) {
168     eventlog(eventlog_level_error,__FUNCTION__,"error destroy connection list");
169     return -1;
170     }
171     connlist_head=NULL;
172    
173     if (hashtable_destroy(conn_charname_list_head)<0) {
174     eventlog(eventlog_level_error,__FUNCTION__,"error destroy connection charname list");
175     return -1;
176     }
177     conn_charname_list_head=NULL;
178     return 0;
179     }
180    
181     extern int d2cs_connlist_reap(void)
182     {
183     t_connection * c;
184    
185     if (!connlist_dead) return 0;
186     BEGIN_LIST_TRAVERSE_DATA(connlist_dead, c)
187     {
188     d2cs_conn_destroy(c,&curr_elem_);
189     }
190     END_LIST_TRAVERSE_DATA()
191    
192     return 0;
193     }
194    
195     extern int conn_check_multilogin(t_connection const * c,char const * charname)
196     {
197     t_connection * conn;
198    
199     ASSERT(charname,-1);
200     if (!prefs_check_multilogin()) return 0;
201     if (gamelist_find_character(charname)) {
202     return -1;
203     }
204     conn=d2cs_connlist_find_connection_by_charname(charname);
205     if (conn && conn!=c) {
206     return -1;
207     }
208     return 0;
209     }
210    
211     extern t_connection * d2cs_connlist_find_connection_by_sessionnum(unsigned int sessionnum)
212     {
213     t_connection * c;
214     t_entry * curr;
215     unsigned int hash;
216    
217     hash=conn_sessionnum_hash(sessionnum);
218     HASHTABLE_TRAVERSE_MATCHING(connlist_head,curr,hash)
219     {
220     if (!(c=entry_get_data(curr))) {
221     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection in list");
222     } else if (c->sessionnum==sessionnum) {
223     hashtable_entry_release(curr);
224     return c;
225     }
226     }
227     return NULL;
228     }
229    
230     extern t_connection * d2cs_connlist_find_connection_by_charname(char const * charname)
231     {
232     t_entry * curr;
233     t_connection * c;
234     unsigned int hash;
235    
236     hash=conn_charname_hash(charname);
237     HASHTABLE_TRAVERSE_MATCHING(connlist_head,curr,hash)
238     {
239     if (!(c=entry_get_data(curr))) {
240     eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection in list");
241     } else {
242     if (!c->charname) continue;
243     if (!strcmp_charname(c->charname,charname)) {
244     hashtable_entry_release(curr);
245     return c;
246     }
247     }
248     }
249     return NULL;
250     }
251    
252     static t_packet * conn_create_packet(t_connection * c)
253     {
254     t_packet * packet;
255    
256     switch (c->class) {
257     CASE(conn_class_init, packet=packet_create(packet_class_init));
258     CASE(conn_class_d2cs, packet=packet_create(packet_class_d2cs));
259     CASE(conn_class_d2gs, packet=packet_create(packet_class_d2gs));
260     CASE(conn_class_bnetd, packet=packet_create(packet_class_d2cs_bnetd));
261     default:
262     eventlog(eventlog_level_error,__FUNCTION__,"got bad connection class %d",c->class);
263     return NULL;
264     }
265     if (!packet) {
266     eventlog(eventlog_level_error,__FUNCTION__,"error create packet");
267     return NULL;
268     }
269     d2cs_conn_set_in_queue(c,packet);
270     return packet;
271     }
272    
273     static int conn_handle_connecting(t_connection * c)
274     {
275     int retval;
276    
277     if (net_check_connected(c->sock)<0) {
278     eventlog(eventlog_level_warn,__FUNCTION__,"can not connect to %s",addr_num_to_addr_str(c->addr, c->port));
279     return -1;
280     }
281     eventlog(eventlog_level_info,__FUNCTION__,"connected to %s",addr_num_to_addr_str(c->addr, c->port));
282     c->state=conn_state_init;
283     /* this is a kind of hack to not update fd but updating breaks kqueue
284     * and the clean fix would require a cache a userland copy of the kernel
285     * kqueue fds, considering that it also doesnt brake anything else should do
286     * for the moment
287     fdwatch_update_fd(c->sock, fdwatch_type_read); */
288     switch (c->class) {
289     case conn_class_bnetd:
290     retval=handle_bnetd_init(c);
291     break;
292     default:
293     eventlog(eventlog_level_error,__FUNCTION__,"got bad connection class %d",c->class);
294     return -1;
295     }
296     return retval;
297     }
298    
299     static int conn_handle_packet(t_connection * c, t_packet * packet)
300     {
301     int retval;
302    
303     switch (c->class) {
304     CASE (conn_class_init, retval=d2cs_handle_init_packet(c,packet));
305     CASE (conn_class_d2cs, retval=d2cs_handle_d2cs_packet(c,packet));
306     CASE (conn_class_d2gs, retval=handle_d2gs_packet(c,packet));
307     CASE (conn_class_bnetd, retval=handle_bnetd_packet(c,packet));
308     default:
309     eventlog(eventlog_level_error,__FUNCTION__,"got bad connection class %d (close connection)",c->class);
310     retval=-1;
311     break;
312     }
313     return retval;
314     }
315    
316     static int conn_handle_read(t_connection * c)
317     {
318     t_packet * packet;
319     int retval;
320    
321     packet = d2cs_conn_get_in_queue(c);
322     if (!packet) {
323     packet = conn_create_packet(c);
324     if (!packet) return -1;
325     c->insize=0;
326     }
327    
328     switch (net_recv_packet(c->sock,packet,&c->insize)) {
329     case -1:
330     retval=-1;
331     break;
332     case 0:
333     retval=0;
334     break;
335     case 1:
336     c->insize=0;
337     d2cs_conn_set_in_queue(c,NULL);
338     retval=conn_handle_packet(c,packet);
339     packet_del_ref(packet);
340     break;
341     default:
342     retval=0;
343     break;
344     }
345     return retval;
346     }
347    
348     static int conn_handle_write(t_connection * c)
349     {
350     t_packet * packet;
351     int retval;
352    
353     if (c->state==conn_state_connecting) {
354     return conn_handle_connecting(c);
355     }
356    
357     if (!(packet=conn_peek_outqueue(c))) return 0;
358    
359     switch (net_send_packet(c->sock, packet, &c->outsize)) {
360     case -1:
361     retval=-1;
362     break;
363     case 0:
364     retval=0;
365     break;
366     case 1:
367     c->outsize=0;
368     packet=conn_pull_outqueue(c);
369     packet_del_ref(packet);
370     retval=0;
371     break;
372     default:
373     retval = -1;
374     }
375     return retval;
376     }
377    
378     extern int conn_handle_socket(t_connection * c)
379     {
380     time_t now;
381    
382     ASSERT(c,-1);
383     now=time(NULL);
384     if (c->socket_flag & SOCKET_FLAG_READ) {
385     if (conn_handle_read(c)<0) return -1;
386     c->last_active=now;
387     }
388     if (c->socket_flag & SOCKET_FLAG_WRITE) {
389     if (conn_handle_write(c)<0) return -1;
390     c->last_active=now;
391     }
392     c->socket_flag=0;
393     return 0;
394     }
395    
396     extern int connlist_check_timeout(void)
397     {
398     t_connection * c;
399     time_t now;
400    
401     now=time(NULL);
402     BEGIN_HASHTABLE_TRAVERSE_DATA(connlist_head, c)
403     {
404     switch (c->class) {
405     case conn_class_d2cs:
406     if (prefs_get_idletime() && (now - c->last_active > prefs_get_idletime())) {
407     eventlog(eventlog_level_info,__FUNCTION__,"client %d idled too long time, destroy it",c->sessionnum);
408     d2cs_conn_set_state(c,conn_state_destroy);
409     }
410     break;
411     case conn_class_d2gs:
412     if (prefs_get_s2s_idletime() && now - c->last_active > prefs_get_s2s_idletime()) {
413     eventlog(eventlog_level_info,__FUNCTION__,"server %d timed out",c->sessionnum);
414     d2cs_conn_set_state(c,conn_state_destroy);
415     }
416     break;
417     case conn_class_bnetd:
418     break;
419     default:
420     break;
421     }
422     }
423     END_HASHTABLE_TRAVERSE_DATA()
424     return 0;
425     }
426    
427     extern t_connection * d2cs_conn_create(int sock, unsigned int local_addr, unsigned short local_port,
428     unsigned int addr, unsigned short port)
429     {
430     static unsigned int sessionnum=1;
431     t_connection * c;
432    
433     if (sock<0) {
434     eventlog(eventlog_level_error,__FUNCTION__,"got bad socket");
435     return NULL;
436     }
437     c=xmalloc(sizeof(t_connection));
438     c->charname=NULL;
439     c->account=NULL;
440     c->sock=sock;
441     c->fdw_idx = -1;
442     c->socket_flag=0;
443     c->local_addr=local_addr;
444     c->local_port=local_port;
445     c->addr=addr;
446     c->port=port;
447     c->class=conn_class_init;
448     c->state=conn_state_init;
449     c->sessionnum=sessionnum++;
450     c->outqueue=NULL;
451     c->inqueue=NULL;
452     c->outsize=0;
453     c->outsizep=0;
454     c->insize=0;
455     c->charinfo=NULL;
456     c->d2gs_id=0;
457     c->gamequeue=NULL;
458     c->last_active=time(NULL);
459     c->sessionnum_hash=conn_sessionnum_hash(c->sessionnum);
460     c->bnetd_sessionnum=0;
461     c->charname_hash=0;
462     if (hashtable_insert_data(connlist_head, c, c->sessionnum_hash)<0) {
463     xfree(c);
464     eventlog(eventlog_level_error,__FUNCTION__,"error add connection to list");
465     return NULL;
466     }
467     total_connection++;
468     eventlog(eventlog_level_info,__FUNCTION__,"created session=%d socket=%d (%d current connections)", c->sessionnum, sock, total_connection);
469     return c;
470     }
471    
472     extern int d2cs_conn_destroy(t_connection * c, t_elem ** curr)
473     {
474     t_elem * elem;
475    
476     ASSERT(c,-1);
477     if (c->state==conn_state_destroying) return 0;
478     if (hashtable_remove_data(connlist_head,c,c->sessionnum_hash)<0) {
479     eventlog(eventlog_level_error,__FUNCTION__,"error remove connection from list");
480     return -1;
481     }
482     c->state=conn_state_destroying;
483     if (c->d2gs_id && c->class==conn_class_d2gs) {
484     d2gs_deactive(d2gslist_find_gs(c->d2gs_id),c);
485     }
486     if (c->class==conn_class_bnetd) {
487     s2s_destroy(c);
488     }
489     if (c->gamequeue) {
490     gq_destroy(c->gamequeue,&elem);
491     }
492     if (c->account) xfree((void *)c->account);
493     if (c->charinfo) xfree((void *)c->charinfo);
494     if (c->charname) d2cs_conn_set_charname(c,NULL);
495     if (c->inqueue) packet_del_ref(c->inqueue);
496     queue_clear(&c->outqueue);
497    
498     if (connlist_dead) list_remove_data(connlist_dead, c, curr);
499     fdwatch_del_fd(c->fdw_idx);
500     psock_shutdown(c->sock,PSOCK_SHUT_RDWR);
501     psock_close(c->sock);
502    
503     total_connection--;
504     eventlog(eventlog_level_info,__FUNCTION__,"[%d] closed connection %d (%d left)",c->sock,c->sessionnum,total_connection);
505     xfree(c);
506     return 0;
507     }
508    
509     extern int d2cs_conn_get_socket(t_connection const * c)
510     {
511     ASSERT(c,-1);
512     return c->sock;
513     }
514    
515     extern t_conn_state d2cs_conn_get_state(t_connection const * c)
516     {
517     ASSERT(c,conn_state_none);
518     return c->state;
519     }
520    
521     extern int d2cs_conn_set_state(t_connection * c, t_conn_state state)
522     {
523     t_elem * curr;
524    
525     ASSERT(c,-1);
526     /* special case for destroying connections, add them to connlist_dead list */
527     if (state == conn_state_destroy && c->state != conn_state_destroy) {
528     if (!connlist_dead)
529     connlist_dead = list_create();
530     list_append_data(connlist_dead, c);
531     } else if (state != conn_state_destroy && c->state == conn_state_destroy) {
532     if (list_remove_data(connlist_dead, c, &curr)) {
533     eventlog(eventlog_level_error, __FUNCTION__, "could not remove dead connection");
534     return -1;
535     }
536     }
537     c->state=state;
538     return 0;
539     }
540    
541     extern t_conn_class d2cs_conn_get_class(t_connection const * c)
542     {
543     ASSERT(c,conn_class_none);
544     return c->class;
545     }
546    
547     extern int d2cs_conn_set_class(t_connection * c, t_conn_class class)
548     {
549     ASSERT(c,-1);
550     c->class=class;
551     return 0;
552     }
553    
554     extern t_packet * d2cs_conn_get_in_queue(t_connection const * c)
555     {
556     ASSERT(c,NULL);
557     return c->inqueue;
558     }
559    
560     extern void d2cs_conn_set_in_queue(t_connection * c, t_packet *packet)
561     {
562     assert(c);
563     c->inqueue = packet;
564     }
565    
566     extern unsigned int d2cs_conn_get_out_size(t_connection const * c)
567     {
568     ASSERT(c,0);
569     return c->outsize;
570     }
571    
572     extern t_queue * * d2cs_conn_get_out_queue(t_connection const * c)
573     {
574     ASSERT(c,NULL);
575     return (t_queue * *)&c->outqueue;
576     }
577    
578     extern unsigned int d2cs_conn_get_in_size(t_connection const * c)
579     {
580     ASSERT(c,0);
581     return c->insize;
582     }
583    
584     extern int conn_push_outqueue(t_connection * c, t_packet * packet)
585     {
586     if (!c)
587     {
588     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
589     return -1;
590     }
591    
592     if (!packet)
593     {
594     eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet");
595     return -1;
596     }
597    
598     queue_push_packet((t_queue * *)&c->outqueue, packet);
599     if (!c->outsizep++) fdwatch_update_fd(c->fdw_idx, fdwatch_type_read | fdwatch_type_write);
600    
601     return 0;
602     }
603    
604     extern t_packet * conn_peek_outqueue(t_connection * c)
605     {
606     if (!c)
607     {
608     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
609     return NULL;
610     }
611    
612     return queue_peek_packet((t_queue const * const *)&c->outqueue);
613     }
614    
615     extern t_packet * conn_pull_outqueue(t_connection * c)
616     {
617     if (!c)
618     {
619     eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection");
620     return NULL;
621     }
622    
623     if (c->outsizep) {
624     if (!(--c->outsizep)) fdwatch_update_fd(c->fdw_idx, fdwatch_type_read);
625     return queue_pull_packet((t_queue * *)&c->outqueue);
626     }
627    
628     return NULL;
629     }
630    
631     extern int conn_add_socket_flag(t_connection * c, unsigned int flag)
632     {
633     ASSERT(c,-1);
634     c->socket_flag |= flag;
635     return 0;
636     }
637    
638     extern int conn_process_packet(t_connection * c, t_packet * packet, t_packet_handle_table * table,
639     unsigned int table_size)
640     {
641     unsigned int type;
642     unsigned int size;
643    
644     ASSERT(c,-1);
645     ASSERT(packet,-1);
646     ASSERT(table,-1);
647     type=packet_get_type(packet);
648     size=packet_get_size(packet);
649    
650     if (type >= table_size || !table[type].size) {
651     eventlog(eventlog_level_error,__FUNCTION__,"got bad packet type %d (class %d)",type,packet_get_class(packet));
652     return -1;
653     }
654     if (size < table[type].size) {
655     eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size %d (type %d class %d)",size,type,packet_get_class(packet));
656     return -1;
657     }
658     if (!(c->state & table[type].state)) {
659     eventlog(eventlog_level_error,__FUNCTION__,"connection %d state mismatch for packet type %d (class %d)",c->sessionnum,
660     type,packet_get_class(packet));
661     return -1;
662     }
663     if (!table[type].handler) {
664     eventlog(eventlog_level_error,__FUNCTION__,"missing handler for packet type %d (class %d)",type,packet_get_class(packet));
665     return -1;
666     }
667     return table[type].handler(c,packet);
668     }
669    
670     extern int d2cs_conn_set_account(t_connection * c, char const * account)
671     {
672     ASSERT(c,-1);
673     if (!account) {
674     if (c->account) xfree((void *)c->account);
675     c->account=NULL;
676     }
677     if (c->account) xfree((void *)c->account);
678     c->account=xstrdup(account);
679    
680     return 0;
681     }
682    
683     extern char const * d2cs_conn_get_account(t_connection const * c)
684     {
685     ASSERT(c,NULL);
686     return c->account;
687     }
688    
689     extern int d2cs_conn_set_charname(t_connection * c, char const * charname)
690     {
691     char const * temp;
692    
693     ASSERT(c,-1);
694     temp=NULL;
695     if (charname) temp=xstrdup(charname);
696     if (c->charname) {
697     if (hashtable_remove_data(conn_charname_list_head,c,c->charname_hash) <0) {
698     eventlog(eventlog_level_error,__FUNCTION__,"error remove charname %s from list",charname);
699     if (temp) xfree((void *)temp);
700     return -1;
701     }
702     hashtable_purge(conn_charname_list_head);
703     xfree((void *)c->charname);
704     }
705     if (charname) {
706     c->charname=temp;
707     c->charname_hash=conn_charname_hash(charname);
708     if (hashtable_insert_data(conn_charname_list_head,c,c->charname_hash) <0) {
709     eventlog(eventlog_level_error,__FUNCTION__,"error insert charname %s to list",charname);
710     xfree((void *)c->charname);
711     c->charname=NULL;
712     return -1;
713     }
714     } else {
715     c->charname=NULL;
716     c->charname_hash=0;
717     }
718     return 0;
719     }
720    
721     extern char const * d2cs_conn_get_charname(t_connection const * c)
722     {
723     ASSERT(c,NULL);
724     return c->charname;
725     }
726    
727     extern unsigned int d2cs_conn_get_sessionnum(t_connection const * c)
728     {
729     ASSERT(c,0);
730     return c->sessionnum;
731     }
732    
733     extern unsigned int conn_get_charinfo_ladder(t_connection const * c)
734     {
735     ASSERT(c,0);
736     return d2charinfo_get_ladder(c->charinfo);
737     }
738    
739     extern unsigned int conn_get_charinfo_expansion(t_connection const * c)
740     {
741     ASSERT(c,0);
742     return d2charinfo_get_expansion(c->charinfo);
743     }
744    
745     extern unsigned int conn_get_charinfo_hardcore(t_connection const * c)
746     {
747     ASSERT(c,0);
748     return d2charinfo_get_hardcore(c->charinfo);
749     }
750    
751     extern unsigned int conn_get_charinfo_dead(t_connection const * c)
752     {
753     ASSERT(c,0);
754     return d2charinfo_get_dead(c->charinfo);
755     }
756    
757     extern unsigned int conn_get_charinfo_difficulty(t_connection const * c)
758     {
759     ASSERT(c,0);
760     return d2charinfo_get_difficulty(c->charinfo);
761     }
762    
763     extern unsigned int conn_get_charinfo_level(t_connection const * c)
764     {
765     ASSERT(c,0);
766     return d2charinfo_get_level(c->charinfo);
767     }
768    
769     extern unsigned int conn_get_charinfo_class(t_connection const * c)
770     {
771     ASSERT(c,0);
772     return d2charinfo_get_class(c->charinfo);
773     }
774    
775     extern int conn_set_charinfo(t_connection * c, t_d2charinfo_summary const * charinfo)
776     {
777     ASSERT(c,-1);
778     if (!charinfo) {
779     if (c->charinfo) xfree((void *)c->charinfo);
780     c->charinfo=NULL;
781     return 0;
782     }
783     if (c->charinfo) xfree((void *)c->charinfo);
784     c->charinfo=xmalloc(sizeof(t_d2charinfo_summary));
785     memcpy((void*)c->charinfo,charinfo,sizeof(t_d2charinfo_summary));
786     return 0;
787     }
788    
789     extern int conn_set_d2gs_id(t_connection * c, unsigned int d2gs_id)
790     {
791     ASSERT(c,-1)
792     c->d2gs_id=d2gs_id;
793     return 0;
794     }
795    
796     extern unsigned int conn_get_d2gs_id(t_connection const * c)
797     {
798     ASSERT(c,0)
799     return c->d2gs_id;
800     }
801    
802     extern unsigned int d2cs_conn_get_addr(t_connection const * c)
803     {
804     ASSERT(c,0);
805     return c->addr;
806     }
807    
808     extern unsigned short d2cs_conn_get_port(t_connection const * c)
809     {
810     ASSERT(c,0);
811     return c->port;
812     }
813    
814     extern t_gq * conn_get_gamequeue(t_connection const * c)
815     {
816     ASSERT(c,NULL);
817     return c->gamequeue;
818     }
819    
820     extern int conn_set_gamequeue(t_connection * c, t_gq * gq)
821     {
822     ASSERT(c,-1);
823     c->gamequeue=gq;
824     return 0;
825     }
826    
827     extern int conn_set_bnetd_sessionnum(t_connection * c, unsigned int sessionnum)
828     {
829     ASSERT(c,-1);
830     c->bnetd_sessionnum=sessionnum;
831     return 0;
832     }
833    
834     extern unsigned int conn_get_bnetd_sessionnum(t_connection const * c)
835     {
836     ASSERT(c,-1);
837     return c->bnetd_sessionnum;
838     }
839    
840     extern int conn_add_fd(t_connection * c, t_fdwatch_type rw, fdwatch_handler handler)
841     {
842     assert(c);
843     c->fdw_idx = fdwatch_add_fd(c->sock,rw,handler,c);
844     return c->fdw_idx;
845     }
846 sysadm 1.2
847     /* sowater */
848     extern int d2cs_conn_set_checknum(t_connection *c, char checknum)
849     {
850     ASSERT(c,-1);
851     c->checknum=checknum;
852     return 0;
853     }
854    
855     extern char d2cs_conn_get_checknum(t_connection *c)
856     {
857     ASSERT(c,-1);
858     return c->checknum;
859     }
860    

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1