📄 anongame.c
字号:
* byteorder, not depended on LE/BE * fixed broken htonl() conversion for BE platforms - change it to * bn_int_nset(). i hope it's worked on intel too %) */ t_packet *rpacket; t_connection *gamec; char const *username; t_anongame *a = NULL; t_uint8 gametype, plnum; int tp, i; if (!c) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL connection", conn_get_socket(c)); return -1; } if (!packet) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL packet", conn_get_socket(c)); return -1; } if (packet_get_class(packet) != packet_class_w3route) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad packet (class %d)", conn_get_socket(c), packet_get_class(packet)); return -1; } if (conn_get_state(c) != conn_state_connected) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] not connected", conn_get_socket(c)); return -1; } /* init route connection */ if (packet_get_type(packet) == CLIENT_W3ROUTE_REQ) { t_connection *oldc; eventlog(eventlog_level_trace, __FUNCTION__, "[%d] sizeof t_client_w3route_req %d", conn_get_socket(c), sizeof(t_client_w3route_req)); username = packet_get_str_const(packet, sizeof(t_client_w3route_req), USER_NAME_MAX); eventlog(eventlog_level_info, __FUNCTION__, "[%d] got username '%s'", conn_get_socket(c), username); gamec = connlist_find_connection_by_accountname(username); if (!gamec) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] no game connection found for this w3route connection; closing", conn_get_socket(c)); conn_set_state(c, conn_state_destroy); return 0; } if (!(a = conn_get_anongame(gamec))) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] no anongame struct for game connection", conn_get_socket(c)); conn_set_state(c, conn_state_destroy); return 0; } if (bn_int_get((unsigned char const *) packet->u.data + sizeof(t_client_w3route_req) + strlen(username) + 2) != anongame_get_id(a)) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] client sent wrong id for user '%s', closing connection", conn_get_socket(c), username); conn_set_state(c, conn_state_destroy); return 0; } oldc = conn_get_routeconn(gamec); if (oldc) { conn_set_routeconn(oldc, NULL); conn_set_state(oldc, conn_state_destroy); } if (conn_set_routeconn(c, gamec) < 0 || conn_set_routeconn(gamec, c) < 0) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] conn_set_routeconn failed", conn_get_socket(c)); return -1; } /* set clienttag for w3route connections; we can do conn_get_clienttag() on them */ conn_set_clienttag(c, conn_get_clienttag(gamec)); anongame_set_addr(a, bn_int_get((unsigned char const *) packet->u.data + sizeof(t_client_w3route_req) + strlen(username) + 2 + 12)); anongame_set_joined(a, 0); anongame_set_loaded(a, 0); anongame_set_result(a, -1); anongame_set_gameresults(a, NULL); anongame_set_handle(a, bn_int_get(packet->u.client_w3route_req.handle)); if (!(rpacket = packet_create(packet_class_w3route))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] packet_create failed", conn_get_socket(c)); return -1; } packet_set_size(rpacket, sizeof(t_server_w3route_ack)); packet_set_type(rpacket, SERVER_W3ROUTE_ACK); bn_byte_set(&rpacket->u.server_w3route_ack.unknown1, 7); bn_short_set(&rpacket->u.server_w3route_ack.unknown2, 0); bn_int_set(&rpacket->u.server_w3route_ack.unknown3, SERVER_W3ROUTE_ACK_UNKNOWN3); bn_short_set(&rpacket->u.server_w3route_ack.unknown4, 0xcccc); bn_byte_set(&rpacket->u.server_w3route_ack.playernum, anongame_get_playernum(a)); bn_short_set(&rpacket->u.server_w3route_ack.unknown5, 0x0002); bn_short_set(&rpacket->u.server_w3route_ack.port, conn_get_port(c)); bn_int_nset(&rpacket->u.server_w3route_ack.ip, conn_get_addr(c)); bn_int_set(&rpacket->u.server_w3route_ack.unknown7, 0); bn_int_set(&rpacket->u.server_w3route_ack.unknown8, 0); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); return 0; } else { gamec = conn_get_routeconn(c); if (gamec) a = conn_get_anongame(gamec); } if (!gamec) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] no game connection found for this w3route connection", conn_get_socket(c)); return 0; } if (!a) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] no anongame struct found for this w3route connection", conn_get_socket(c)); return 0; } gametype = anongame_get_queue(a); plnum = anongame_get_playernum(a); tp = anongame_get_totalplayers(a); /* handle these packets _before_ checking for routeconn of other players */ switch (packet_get_type(packet)) { case CLIENT_W3ROUTE_ECHOREPLY: return 0; case CLIENT_W3ROUTE_CONNECTED: return 0; case CLIENT_W3ROUTE_GAMERESULT: case CLIENT_W3ROUTE_GAMERESULT_W3XP: { /* insert reading of whole packet into t_gameresult */ t_anongame_gameresult *gameresult; int result; t_timer_data data; t_anongameinfo *inf = anongame_get_info(a); t_connection *ac; data.p = NULL; if (!(gameresult = anongame_gameresult_parse(packet))) result = -1; else /* own result is always stored as first result */ result = gameresult_get_player_result(gameresult, 0); eventlog(eventlog_level_trace, __FUNCTION__, "[%d] got W3ROUTE_GAMERESULT: %08x", conn_get_socket(c), result); if (!inf) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] NULL anongameinfo", conn_get_socket(c)); return -1; } anongame_set_gameresults(a, gameresult); anongame_set_result(a, result); conn_set_state(c, conn_state_destroy); /* activate timers on open w3route connectons */ if (result == W3_GAMERESULT_WIN) { for (i = 0; i < tp; i++) { if (anongame_get_player(a, i)) { ac = conn_get_routeconn(anongame_get_player(a, i)); if (ac) { /* 300 seconds or 5 minute timer */ timerlist_add_timer(ac, now + (time_t) 300, conn_shutdown, data); eventlog(eventlog_level_trace, __FUNCTION__, "[%d] started timer to close w3route", conn_get_socket(ac)); } } } } return 0; } } for (i = 0; i < tp; i++) if (i + 1 != plnum && anongame_get_player(a, i)) if (!conn_get_routeconn(anongame_get_player(a, i)) || !conn_get_anongame(anongame_get_player(a, i))) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] not all players have w3route connections up yet", conn_get_socket(c)); return 0; } /* handle these packets _after_ checking for routeconns of other players */ switch (packet_get_type(packet)) { case CLIENT_W3ROUTE_LOADINGDONE: eventlog(eventlog_level_trace, __FUNCTION__, "[%d] got LOADINGDONE, playernum: %d", conn_get_socket(c), plnum); anongame_set_loaded(a, 1); for (i = 0; i < tp; i++) { if (!anongame_get_player(a, i)) /* ignore disconnected players */ continue; if (!(rpacket = packet_create(packet_class_w3route))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] packet_create failed", conn_get_socket(c)); return -1; } packet_set_size(rpacket, sizeof(t_server_w3route_loadingack)); packet_set_type(rpacket, SERVER_W3ROUTE_LOADINGACK); bn_byte_set(&rpacket->u.server_w3route_loadingack.playernum, plnum); conn_push_outqueue(conn_get_routeconn(anongame_get_player(a, i)), rpacket); packet_del_ref(rpacket); } /* have all players loaded? */ for (i = 0; i < tp; i++) if (i + 1 != plnum && anongame_get_player(a, i) && !anongame_get_loaded(conn_get_anongame(anongame_get_player(a, i)))) return 0; for (i = 0; i < tp; i++) { if (!anongame_get_player(a, i)) continue; if (!(rpacket = packet_create(packet_class_w3route))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] packet_create failed", conn_get_socket(c)); return -1; } packet_set_size(rpacket, sizeof(t_server_w3route_ready)); packet_set_type(rpacket, SERVER_W3ROUTE_READY); bn_byte_set(&rpacket->u.server_w3route_host.unknown1, 0); conn_push_outqueue(conn_get_routeconn(anongame_get_player(a, i)), rpacket); packet_del_ref(rpacket); } break; case CLIENT_W3ROUTE_ABORT: eventlog(eventlog_level_debug, __FUNCTION__, "[%d] got W3ROUTE_ABORT", conn_get_socket(c)); break; default: eventlog(eventlog_level_trace, __FUNCTION__, "[%d] default: got packet type: %04x", conn_get_socket(c), packet_get_type(packet)); } return 0;}extern int handle_anongame_join(t_connection * c){ t_anongame *a, *ja, *oa; t_connection *jc, *o; t_packet *rpacket; int tp, level; char gametype; t_account *acct; t_clienttag ct = conn_get_clienttag(c); static t_server_w3route_playerinfo2 pl2; static t_server_w3route_levelinfo2 li2; static t_server_w3route_playerinfo_addr pl_addr; int i, j; if (!c) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got NULL connection", conn_get_socket(c)); return -1; } if (!(conn_get_routeconn(c))) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] no route connection", conn_get_socket(c)); return -1; } if (!(a = conn_get_anongame(c))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] no anongame struct", conn_get_socket(c)); return -1; } anongame_set_joined(a, 1); gametype = anongame_get_queue(a); tp = anongame_get_totalplayers(a); /* wait till all players have w3route conns */ for (i = 0; i < tp; i++) if (anongame_get_player(a, i) && (!conn_get_routeconn(anongame_get_player(a, i)) || !conn_get_anongame(anongame_get_player(a, i)) || !anongame_get_joined(conn_get_anongame(anongame_get_player(a, i))))) { eventlog(eventlog_level_info, __FUNCTION__, "[%d] not all players have joined game BNet yet", conn_get_socket(c)); return 0; } /* then send each player info about all others */ for (j = 0; j < tp; j++) { jc = anongame_get_player(a, j); if (!jc) /* ignore disconnected players */ continue; ja = conn_get_anongame(jc); /* send a playerinfo packet for this player to each other player */ for (i = 0; i < tp; i++) { if (i + 1 != anongame_get_playernum(ja)) { eventlog(eventlog_level_trace, __FUNCTION__, "i = %d", i); if (!(o = anongame_get_player(ja, i))) { eventlog(eventlog_level_warn, __FUNCTION__, "[%d] player %d disconnected, ignoring", conn_get_socket(c), i); continue; } if (!(rpacket = packet_create(packet_class_w3route))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] packet_create failed", conn_get_socket(c)); return -1; } packet_set_size(rpacket, sizeof(t_server_w3route_playerinfo)); packet_set_type(rpacket, SERVER_W3ROUTE_PLAYERINFO); if (!(oa = conn_get_anongame(o))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] no anongame struct of player %d", conn_get_socket(c), i); return -1; } bn_int_set(&rpacket->u.server_w3route_playerinfo.handle, anongame_get_handle(oa)); bn_byte_set(&rpacket->u.server_w3route_playerinfo.playernum, anongame_get_playernum(oa)); packet_append_string(rpacket, conn_get_username(o)); /* playerinfo2 */ bn_byte_set(&pl2.unknown1, 8); bn_int_set(&pl2.id, anongame_get_id(oa)); bn_int_set(&pl2.race, anongame_get_race(oa)); packet_append_data(rpacket, &pl2, sizeof(pl2)); /* external addr */ bn_short_set(&pl_addr.unknown1, 2); { /* trans support */ unsigned short port = conn_get_game_port(o); unsigned int addr = conn_get_game_addr(o); trans_net(conn_get_game_addr(jc), &addr, &port); bn_short_nset(&pl_addr.port, port); bn_int_nset(&pl_addr.ip, addr); } bn_int_set(&pl_addr.unknown2, 0); bn_int_set(&pl_addr.unknown3, 0); packet_append_data(rpacket, &pl_addr, sizeof(pl_addr)); /* local addr */ bn_short_set(&pl_addr.unknown1, 2); bn_short_nset(&pl_addr.port, conn_get_game_port(o)); bn_int_set(&pl_addr.ip, anongame_get_addr(oa)); bn_int_set(&pl_addr.unknown2, 0); bn_int_set(&pl_addr.unknown3, 0); packet_append_data(rpacket, &pl_addr, sizeof(pl_addr)); conn_push_outqueue(conn_get_routeconn(jc), rpacket); packet_del_ref(rpacket); } } /* levelinfo */ if (!(rpacket = packet_create(packet_class_w3route))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] packet_create failed", conn_get_socket(c)); return -1; } packet_set_size(rpacket, sizeof(t_server_w3route_levelinfo)); packet_set_type(rpacket, SERVER_W3ROUTE_LEVELINFO); bn_byte_set(&rpacket->u.server_w3route_levelinfo.numplayers, anongame_get_currentplayers(a)); for (i = 0; i < tp; i++) { if (!anongame_get_player(ja, i)) continue; bn_byte_set(&li2.plnum, i + 1); bn_byte_set(&li2.unknown1, 3); switch (gametype) { case ANONGAME_TYPE_1V1: level = account_get_ladder_level(conn_get_account(anongame_get_player(ja, i)), ct, ladder_id_solo); break; case ANONGAME_TYPE_SMALL_FFA: case ANONGAME_TYPE_TEAM_FFA: level = account_get_ladder_level(conn_get_account(anongame_get_player(ja, i)), ct, ladder_id_ffa); break; case ANONGAME_TYPE_AT_2V2: case ANONGAME_TYPE_AT_3V3: case ANONGAME_TYPE_AT_4V4: case ANONGAME_TYPE_AT_2V2V2: acct = conn_get_account(anongame_get_player(ja, i)); level = team_get_level(account_find_team_by_teamid(acct, account_get_currentatteam(acct))); break; case ANONGAME_TYPE_TY: level = 0; /* FIXME-TY: WHAT TO DO HERE */ break; default: level = account_get_ladder_level(conn_get_account(anongame_get_player(ja, i)), ct, ladder_id_team); break; } /* first anongame shows level 0 as level 1 */ bn_byte_set(&li2.level, level ? level : 1); bn_short_set(&li2.unknown2, 0); packet_append_data(rpacket, &li2, sizeof(li2)); } conn_push_outqueue(conn_get_routeconn(jc), rpacket); packet_del_ref(rpacket); /* startgame1 */ if (!(rpacket = packet_create(packet_class_w3rout
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -