📄 connection.c
字号:
return 0;}extern t_connection * d2cs_conn_create(int sock, unsigned int local_addr, unsigned short local_port, unsigned int addr, unsigned short port){ static unsigned int sessionnum=1; t_connection * c; if (sock<0) { eventlog(eventlog_level_error,__FUNCTION__,"got bad socket"); return NULL; } c=xmalloc(sizeof(t_connection)); c->charname=NULL; c->account=NULL; c->sock=sock; c->fdw_idx = -1; c->socket_flag=0; c->local_addr=local_addr; c->local_port=local_port; c->addr=addr; c->port=port; c->class=conn_class_init; c->state=conn_state_init; c->sessionnum=sessionnum++; c->outqueue=NULL; c->inqueue=NULL; c->outsize=0; c->outsizep=0; c->insize=0; c->charinfo=NULL; c->d2gs_id=0; c->gamequeue=NULL; c->last_active=time(NULL); c->sessionnum_hash=conn_sessionnum_hash(c->sessionnum); c->bnetd_sessionnum=0; c->charname_hash=0; if (hashtable_insert_data(connlist_head, c, c->sessionnum_hash)<0) { xfree(c); eventlog(eventlog_level_error,__FUNCTION__,"error add connection to list"); return NULL; } total_connection++; eventlog(eventlog_level_info,__FUNCTION__,"created session=%d socket=%d (%d current connections)", c->sessionnum, sock, total_connection); return c;}extern int d2cs_conn_destroy(t_connection * c, t_elem ** curr){ t_elem * elem; ASSERT(c,-1); if (c->state==conn_state_destroying) return 0; if (hashtable_remove_data(connlist_head,c,c->sessionnum_hash)<0) { eventlog(eventlog_level_error,__FUNCTION__,"error remove connection from list"); return -1; } c->state=conn_state_destroying; if (c->d2gs_id && c->class==conn_class_d2gs) { d2gs_deactive(d2gslist_find_gs(c->d2gs_id),c); } if (c->class==conn_class_bnetd) { s2s_destroy(c); } if (c->gamequeue) { gq_destroy(c->gamequeue,&elem); } if (c->account) xfree((void *)c->account); if (c->charinfo) xfree((void *)c->charinfo); if (c->charname) d2cs_conn_set_charname(c,NULL); if (c->inqueue) packet_del_ref(c->inqueue); queue_clear(&c->outqueue); if (connlist_dead) list_remove_data(connlist_dead, c, curr); fdwatch_del_fd(c->fdw_idx); psock_shutdown(c->sock,PSOCK_SHUT_RDWR); psock_close(c->sock); total_connection--; eventlog(eventlog_level_info,__FUNCTION__,"[%d] closed connection %d (%d left)",c->sock,c->sessionnum,total_connection); xfree(c); return 0;}extern int d2cs_conn_get_socket(t_connection const * c){ ASSERT(c,-1); return c->sock;}extern t_conn_state d2cs_conn_get_state(t_connection const * c){ ASSERT(c,conn_state_none); return c->state;}extern int d2cs_conn_set_state(t_connection * c, t_conn_state state){ t_elem * curr; ASSERT(c,-1); /* special case for destroying connections, add them to connlist_dead list */ if (state == conn_state_destroy && c->state != conn_state_destroy) { if (!connlist_dead) connlist_dead = list_create(); list_append_data(connlist_dead, c); } else if (state != conn_state_destroy && c->state == conn_state_destroy) { if (list_remove_data(connlist_dead, c, &curr)) { eventlog(eventlog_level_error, __FUNCTION__, "could not remove dead connection"); return -1; } } c->state=state; return 0;} extern t_conn_class d2cs_conn_get_class(t_connection const * c){ ASSERT(c,conn_class_none); return c->class;}extern int d2cs_conn_set_class(t_connection * c, t_conn_class class){ ASSERT(c,-1); c->class=class; return 0;}extern t_packet * d2cs_conn_get_in_queue(t_connection const * c){ ASSERT(c,NULL); return c->inqueue;}extern void d2cs_conn_set_in_queue(t_connection * c, t_packet *packet){ assert(c); c->inqueue = packet;}extern unsigned int d2cs_conn_get_out_size(t_connection const * c){ ASSERT(c,0); return c->outsize;}extern t_queue * * d2cs_conn_get_out_queue(t_connection const * c){ ASSERT(c,NULL); return (t_queue * *)&c->outqueue;}extern unsigned int d2cs_conn_get_in_size(t_connection const * c){ ASSERT(c,0); return c->insize;}extern int conn_push_outqueue(t_connection * c, t_packet * packet){ if (!c) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection"); return -1; } if (!packet) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL packet"); return -1; } queue_push_packet((t_queue * *)&c->outqueue, packet); if (!c->outsizep++) fdwatch_update_fd(c->fdw_idx, fdwatch_type_read | fdwatch_type_write); return 0;}extern t_packet * conn_peek_outqueue(t_connection * c){ if (!c) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection"); return NULL; } return queue_peek_packet((t_queue const * const *)&c->outqueue);}extern t_packet * conn_pull_outqueue(t_connection * c){ if (!c) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL connection"); return NULL; } if (c->outsizep) { if (!(--c->outsizep)) fdwatch_update_fd(c->fdw_idx, fdwatch_type_read); return queue_pull_packet((t_queue * *)&c->outqueue); } return NULL;}extern int conn_add_socket_flag(t_connection * c, unsigned int flag){ ASSERT(c,-1); c->socket_flag |= flag; return 0;}extern int conn_process_packet(t_connection * c, t_packet * packet, t_packet_handle_table * table, unsigned int table_size){ unsigned int type; unsigned int size; ASSERT(c,-1); ASSERT(packet,-1); ASSERT(table,-1); type=packet_get_type(packet); size=packet_get_size(packet); if (type >= table_size || !table[type].size) { eventlog(eventlog_level_error,__FUNCTION__,"got bad packet type %d (class %d)",type,packet_get_class(packet)); return -1; } if (size < table[type].size) { eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size %d (type %d class %d)",size,type,packet_get_class(packet)); return -1; } if (!(c->state & table[type].state)) { eventlog(eventlog_level_error,__FUNCTION__,"connection %d state mismatch for packet type %d (class %d)",c->sessionnum, type,packet_get_class(packet)); return -1; } if (!table[type].handler) { eventlog(eventlog_level_error,__FUNCTION__,"missing handler for packet type %d (class %d)",type,packet_get_class(packet)); return -1; } return table[type].handler(c,packet);}extern int d2cs_conn_set_account(t_connection * c, char const * account){ ASSERT(c,-1); if (!account) { if (c->account) xfree((void *)c->account); c->account=NULL; } if (c->account) xfree((void *)c->account); c->account=xstrdup(account); return 0;}extern char const * d2cs_conn_get_account(t_connection const * c){ ASSERT(c,NULL); return c->account;}extern int d2cs_conn_set_charname(t_connection * c, char const * charname){ char const * temp; ASSERT(c,-1); temp=NULL; if (charname) temp=xstrdup(charname); if (c->charname) { if (hashtable_remove_data(conn_charname_list_head,c,c->charname_hash) <0) { eventlog(eventlog_level_error,__FUNCTION__,"error remove charname %s from list",charname); if (temp) xfree((void *)temp); return -1; } hashtable_purge(conn_charname_list_head); xfree((void *)c->charname); } if (charname) { c->charname=temp; c->charname_hash=conn_charname_hash(charname); if (hashtable_insert_data(conn_charname_list_head,c,c->charname_hash) <0) { eventlog(eventlog_level_error,__FUNCTION__,"error insert charname %s to list",charname); xfree((void *)c->charname); c->charname=NULL; return -1; } } else { c->charname=NULL; c->charname_hash=0; } return 0;}extern char const * d2cs_conn_get_charname(t_connection const * c){ ASSERT(c,NULL); return c->charname;}extern unsigned int d2cs_conn_get_sessionnum(t_connection const * c){ ASSERT(c,0); return c->sessionnum;}extern unsigned int conn_get_charinfo_ladder(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_ladder(c->charinfo);}extern unsigned int conn_get_charinfo_expansion(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_expansion(c->charinfo);}extern unsigned int conn_get_charinfo_hardcore(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_hardcore(c->charinfo);}extern unsigned int conn_get_charinfo_dead(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_dead(c->charinfo);}extern unsigned int conn_get_charinfo_difficulty(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_difficulty(c->charinfo);}extern unsigned int conn_get_charinfo_level(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_level(c->charinfo);}extern unsigned int conn_get_charinfo_class(t_connection const * c){ ASSERT(c,0); return d2charinfo_get_class(c->charinfo);}extern int conn_set_charinfo(t_connection * c, t_d2charinfo_summary const * charinfo){ ASSERT(c,-1); if (!charinfo) { if (c->charinfo) xfree((void *)c->charinfo); c->charinfo=NULL; return 0; } if (c->charinfo) xfree((void *)c->charinfo); c->charinfo=xmalloc(sizeof(t_d2charinfo_summary)); memcpy((void*)c->charinfo,charinfo,sizeof(t_d2charinfo_summary)); return 0;}extern int conn_set_d2gs_id(t_connection * c, unsigned int d2gs_id){ ASSERT(c,-1) c->d2gs_id=d2gs_id; return 0;}extern unsigned int conn_get_d2gs_id(t_connection const * c){ ASSERT(c,0) return c->d2gs_id;}extern unsigned int d2cs_conn_get_addr(t_connection const * c){ ASSERT(c,0); return c->addr;}extern unsigned short d2cs_conn_get_port(t_connection const * c){ ASSERT(c,0); return c->port;}extern t_gq * conn_get_gamequeue(t_connection const * c){ ASSERT(c,NULL); return c->gamequeue;}extern int conn_set_gamequeue(t_connection * c, t_gq * gq){ ASSERT(c,-1); c->gamequeue=gq; return 0;}extern int conn_set_bnetd_sessionnum(t_connection * c, unsigned int sessionnum){ ASSERT(c,-1); c->bnetd_sessionnum=sessionnum; return 0;}extern unsigned int conn_get_bnetd_sessionnum(t_connection const * c){ ASSERT(c,0); return c->bnetd_sessionnum;}extern int conn_add_fd(t_connection * c, t_fdwatch_type rw, fdwatch_handler handler){ assert(c); c->fdw_idx = fdwatch_add_fd(c->sock,rw,handler,c); return c->fdw_idx;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -