📄 handle_d2cs.c
字号:
}static int on_client_joingamereq(t_connection * c, t_packet * packet){ char const * gamename; char const * gamepass; char const * charname; char const * account; t_game * game; t_d2gs * gs; int reply; unsigned int pos; unsigned int seqno; gs = NULL; pos=sizeof(t_client_d2cs_joingamereq); if (!(gamename=packet_get_str_const(packet,pos,MAX_GAMENAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad game name"); return -1; } pos+=strlen(gamename)+1; if (!(gamepass=packet_get_str_const(packet,pos,MAX_GAMEPASS_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad game pass"); return -1; } if (!(charname=d2cs_conn_get_charname(c))) { eventlog(eventlog_level_error,__FUNCTION__,"missing character name for connection"); return -1; } if (!(account=d2cs_conn_get_account(c))) { eventlog(eventlog_level_error,__FUNCTION__,"missing account for connection"); return -1; } if (conn_check_multilogin(c,charname)<0) { eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname); return -1; } if (!(game=d2cs_gamelist_find_game(gamename))) { eventlog(eventlog_level_info,__FUNCTION__,"game %s not found",gamename); reply=D2CS_CLIENT_JOINGAMEREPLY_NOT_EXIST; } else if (!(gs=game_get_d2gs(game))) { eventlog(eventlog_level_error,__FUNCTION__,"missing game server for game %s",gamename); reply=D2CS_CLIENT_JOINGAMEREPLY_NOT_EXIST; } else { reply=d2cs_try_joingame(c,game,gamepass); } seqno=bn_short_get(packet->u.client_d2cs_joingamereq.seqno); if (reply!=D2CS_CLIENT_JOINGAMEREPLY_SUCCEED) { t_packet * rpacket; if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_joingamereply)); packet_set_type(rpacket,D2CS_CLIENT_JOINGAMEREPLY); bn_short_set(&rpacket->u.d2cs_client_joingamereply.seqno,seqno); bn_short_set(&rpacket->u.d2cs_client_joingamereply.u1,0); bn_short_set(&rpacket->u.d2cs_client_joingamereply.gameid,0); bn_int_set(&rpacket->u.d2cs_client_joingamereply.addr,0); bn_int_set(&rpacket->u.d2cs_client_joingamereply.token,0); bn_int_set(&rpacket->u.d2cs_client_joingamereply.reply,reply); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } } else { t_packet * gspacket; t_sq * sq; struct in_addr addr; if ((gspacket=packet_create(packet_class_d2gs))) { if ((sq=sq_create(d2cs_conn_get_sessionnum(c),packet,d2cs_game_get_id(game)))) { packet_set_size(gspacket,sizeof(t_d2cs_d2gs_joingamereq)); packet_set_type(gspacket,D2CS_D2GS_JOINGAMEREQ); bn_int_set(&gspacket->u.d2cs_d2gs_joingamereq.h.seqno,sq_get_seqno(sq)); bn_int_set(&gspacket->u.d2cs_d2gs_joingamereq.gameid, game_get_d2gs_gameid(game)); sq_set_gametoken(sq,d2gs_make_token(gs)); bn_int_set(&gspacket->u.d2cs_d2gs_joingamereq.token,sq_get_gametoken(sq)); packet_append_string(gspacket,charname); packet_append_string(gspacket,account); addr.s_addr = htonl(d2cs_conn_get_addr(c)); packet_append_string(gspacket,inet_ntoa(addr)); conn_push_outqueue(d2gs_get_connection(gs),gspacket); } packet_del_ref(gspacket); eventlog(eventlog_level_info,__FUNCTION__,"request join game %s for character %s on gs %d",gamename, charname,d2gs_get_id(gs)); } } return 0;}static int on_client_gamelistreq(t_connection * c, t_packet * packet){ t_packet * rpacket; t_game * game; unsigned int count; unsigned int seqno; time_t now; unsigned int maxlifetime; t_elem const * start_elem; t_elem const * elem; seqno=bn_short_get(packet->u.client_d2cs_gamelistreq.seqno); /* if (seqno%2) return 0; */ count=0; now=time(NULL); maxlifetime=prefs_get_game_maxlifetime(); elem=start_elem=gamelist_get_curr_elem(); if (!elem) elem=list_get_first_const(d2cs_gamelist()); else elem=elem_get_next_const(d2cs_gamelist(),elem); for (; elem != start_elem; elem=elem_get_next_const(d2cs_gamelist(),elem)) { if (!elem) { elem=list_get_first_const(d2cs_gamelist()); if (elem == start_elem) break; } if (!(game=elem_get_data(elem))) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL game"); break; } if (maxlifetime && (now-game->create_time>maxlifetime)) continue; if (!game_get_currchar(game)) continue; if (!prefs_allow_gamelist_showall()) { if (conn_get_charinfo_difficulty(c)!=game_get_gameflag_difficulty(game)) continue; } if (d2cs_try_joingame(c,game,"")!=D2CS_CLIENT_JOINGAMEREPLY_SUCCEED) continue; if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_gamelistreply)); packet_set_type(rpacket,D2CS_CLIENT_GAMELISTREPLY); bn_short_set(&rpacket->u.d2cs_client_gamelistreply.seqno,seqno); bn_int_set(&rpacket->u.d2cs_client_gamelistreply.token,d2cs_game_get_id(game)); bn_byte_set(&rpacket->u.d2cs_client_gamelistreply.currchar,game_get_currchar(game)); bn_int_set(&rpacket->u.d2cs_client_gamelistreply.gameflag,game_get_gameflag(game)); packet_append_string(rpacket,d2cs_game_get_name(game)); packet_append_string(rpacket,game_get_desc(game)); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); count++; if (prefs_get_maxgamelist() && count>=prefs_get_maxgamelist()) break; } } gamelist_set_curr_elem(elem); if (count) { if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_gamelistreply)); packet_set_type(rpacket,D2CS_CLIENT_GAMELISTREPLY); bn_short_set(&rpacket->u.d2cs_client_gamelistreply.seqno,seqno); bn_int_set(&rpacket->u.d2cs_client_gamelistreply.token,0); bn_byte_set(&rpacket->u.d2cs_client_gamelistreply.currchar,0); bn_int_set(&rpacket->u.d2cs_client_gamelistreply.gameflag,0); packet_append_string(rpacket,""); packet_append_string(rpacket,""); packet_append_string(rpacket,""); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } } return 0;}static int on_client_gameinforeq(t_connection * c, t_packet * packet){ t_game_charinfo * info; t_packet * rpacket; char const * gamename; t_game * game; unsigned int seqno, n; if (!(gamename=packet_get_str_const(packet,sizeof(t_client_d2cs_gameinforeq),MAX_GAMENAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad game name"); return -1; } if (!(game=d2cs_gamelist_find_game(gamename))) { eventlog(eventlog_level_error,__FUNCTION__,"game %s not found",gamename); return 0; } seqno=bn_short_get(packet->u.client_d2cs_gameinforeq.seqno); if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_gameinforeply)); packet_set_type(rpacket,D2CS_CLIENT_GAMEINFOREPLY); bn_short_set(&rpacket->u.d2cs_client_gameinforeply.seqno,seqno); bn_int_set(&rpacket->u.d2cs_client_gameinforeply.gameflag,game_get_gameflag(game)); bn_int_set(&rpacket->u.d2cs_client_gameinforeply.etime,time(NULL)-d2cs_game_get_create_time(game)); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.charlevel,game_get_charlevel(game)); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.leveldiff,game_get_leveldiff(game)); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.maxchar,game_get_maxchar(game)); packet_append_string(rpacket, game_get_desc(game) ? game_get_desc(game) : NULL); n=0; BEGIN_LIST_TRAVERSE_DATA_CONST(game_get_charlist(game),info) { if (!info->charname) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL charname in game %s char list",gamename); continue; } packet_append_string(rpacket,info->charname); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.class[n],info->class); bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.level[n],info->level); n++; } END_LIST_TRAVERSE_DATA_CONST() bn_byte_set(&rpacket->u.d2cs_client_gameinforeply.currchar,n); if (n!=game_get_currchar(game)) { eventlog(eventlog_level_error,__FUNCTION__,"game %s character list corrupted",gamename); } conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } return 0;}static int on_client_charloginreq(t_connection * c, t_packet * packet){ t_packet * bnpacket; char const * charname; char const * account; t_sq * sq; t_d2charinfo_file data; unsigned int expire_time; if (!(charname=packet_get_str_const(packet,sizeof(t_client_d2cs_charloginreq),MAX_CHARNAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad character name"); return -1; } if (!(account=d2cs_conn_get_account(c))) { eventlog(eventlog_level_error,__FUNCTION__,"missing account for connection"); return -1; } if (d2charinfo_load(account,charname,&data)<0) { eventlog(eventlog_level_error,__FUNCTION__,"error loading charinfo for character %s(*%s)",charname,account); return -1; } else if (!bnetd_conn()) { eventlog(eventlog_level_error,__FUNCTION__,"no bnetd connection available,character login rejected"); return -1; } expire_time = prefs_get_char_expire_time(); if (expire_time && (time(NULL) > bn_int_get(data.header.last_time) + expire_time)) { t_packet * rpacket; if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_charloginreply)); packet_set_type(rpacket,D2CS_CLIENT_CHARLOGINREPLY); bn_int_set(&rpacket->u.d2cs_client_charloginreply.reply, D2CS_CLIENT_CHARLOGINREPLY_EXPIRED); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } eventlog(eventlog_level_info,__FUNCTION__,"character %s(*%s) login rejected due to char expired",charname,account); return 0; } conn_set_charinfo(c,&data.summary); eventlog(eventlog_level_info,__FUNCTION__,"got character %s(*%s) login request",charname,account); if ((bnpacket=packet_create(packet_class_d2cs_bnetd))) { if ((sq=sq_create(d2cs_conn_get_sessionnum(c),packet,0))) { packet_set_size(bnpacket,sizeof(t_d2cs_bnetd_charloginreq)); packet_set_type(bnpacket,D2CS_BNETD_CHARLOGINREQ); bn_int_set(&bnpacket->u.d2cs_bnetd_charloginreq.h.seqno,sq_get_seqno(sq)); bn_int_set(&bnpacket->u.d2cs_bnetd_charloginreq.sessionnum, conn_get_bnetd_sessionnum(c)); packet_append_string(bnpacket,charname); packet_append_string(bnpacket,(char const *)&data.portrait); conn_push_outqueue(bnetd_conn(),bnpacket); } packet_del_ref(bnpacket); } return 0;}static int on_client_deletecharreq(t_connection * c, t_packet * packet){ t_packet * rpacket; char const * charname; char const * account; unsigned int reply; if (!(charname=packet_get_str_const(packet,sizeof(t_client_d2cs_deletecharreq),MAX_CHARNAME_LEN))) { eventlog(eventlog_level_error,__FUNCTION__,"got bad character name"); return -1; } if (conn_check_multilogin(c,charname)<0) { eventlog(eventlog_level_error,__FUNCTION__,"character %s is already logged in",charname); return -1; } d2cs_conn_set_charname(c,NULL); account=d2cs_conn_get_account(c); if (d2char_delete(account,charname)<0) { eventlog(eventlog_level_error,__FUNCTION__,"failed to delete character %s(*%s)",charname,account); reply = D2CS_CLIENT_DELETECHARREPLY_FAILED; } else { reply = D2CS_CLIENT_DELETECHARREPLY_SUCCEED; } if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_deletecharreply)); packet_set_type(rpacket,D2CS_CLIENT_DELETECHARREPLY); bn_short_set(&rpacket->u.d2cs_client_deletecharreply.u1,0); bn_int_set(&rpacket->u.d2cs_client_deletecharreply.reply,reply); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } return 0;}static int on_client_ladderreq(t_connection * c, t_packet * packet){ unsigned char type; unsigned short start_pos; type=bn_byte_get(packet->u.client_d2cs_ladderreq.type); start_pos=bn_short_get(packet->u.client_d2cs_ladderreq.start_pos); d2cs_send_client_ladder(c,type,start_pos); return 0;}static int d2cs_send_client_ladder(t_connection * c, unsigned char type, unsigned short from){ t_packet * rpacket; t_d2cs_client_ladderinfo const * ladderinfo; unsigned int curr_len, cont_len, total_len; t_d2cs_client_ladderheader ladderheader; t_d2cs_client_ladderinfoheader infoheader; unsigned int start_pos, count, count_per_packet, npacket; unsigned int i, n, curr_pos; start_pos=from; count=prefs_get_ladderlist_count(); if (d2ladder_get_ladder(&start_pos,&count,type,&ladderinfo)<0) { eventlog(eventlog_level_error,__FUNCTION__,"error get ladder for type %d start_pos %d",type,from); return 0; } count_per_packet=14; npacket=count/count_per_packet; if (count % count_per_packet) npacket++; curr_len=0; cont_len=0; total_len = count * sizeof(*ladderinfo) + sizeof(ladderheader) + sizeof(infoheader) * npacket; total_len -= 4; bn_short_set(&ladderheader.start_pos,start_pos); bn_short_set(&ladderheader.u1,0); bn_int_set(&ladderheader.count1,count); for (i=0; i< npacket; i++) { curr_len=0; if ((rpacket=packet_create(packet_class_d2cs))) { packet_set_size(rpacket,sizeof(t_d2cs_client_ladderreply)); packet_set_type(rpacket,D2CS_CLIENT_LADDERREPLY); bn_byte_set(&rpacket->u.d2cs_client_ladderreply.type, type); bn_short_set(&rpacket->u.d2cs_client_ladderreply.total_len, total_len); bn_short_set(&rpacket->u.d2cs_client_ladderreply.cont_len,cont_len); if (i==0) { bn_int_set(&infoheader.count2,count); packet_append_data(rpacket,&ladderheader,sizeof(ladderheader)); curr_len += sizeof(ladderheader); } else { bn_int_set(&infoheader.count2,0); } packet_append_data(rpacket,&infoheader,sizeof(infoheader)); curr_len += sizeof(infoheader); for (n=0; n< count_per_packet; n++) { curr_pos = n + i * count_per_packet; if (curr_pos >= count) break; packet_append_data(rpacket, ladderinfo+curr_pos, sizeof(*ladderinfo)); curr_len += sizeof(*ladderinfo); } if (i==0) { packet_set_size(rpacket, packet_get_size(rpacket)-4); curr_len -= 4; } bn_short_set(&rpacket->u.d2cs_client_ladderreply.curr_len,curr_len); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } cont_len += curr_len; } return 0;}#define MAX_MOTD_LENGTH 511static int on_client_motdreq(t_connection * c, t_packet * packet){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -