diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f9bd416f4..58a0ec69f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -7,6 +7,7 @@ arch/ogl/ogl.c, include/ogl_init.h, main/ai.c, main/ai.h, main/aipath.c, main/ai main/game.c: Use game_init_render_buffers for editor (for now), fixing crash main/gamecntl.c, main/net_udp.c: Fix warning for deliberate GameTime64 wrap; uncomment multi_object_to_object_rw and multi_object_rw_to_object prototypes main/collide.c, main/object.c, main/object.h, main/state.c: added hitobj_list to struct laser_info to get a bit cleaner code +main/multi.h, main/net_udp.c, main/net_udp.h: in IPv6 builds also send regular broadcast packets to get games found via LAN between IPv4 clients/systems and IPv6 clients/systems; rather than identifying (lite_info) games via IP use randomly generated GameID and game name to prevent duplicated coming from IPv6 builds 20101211 -------- diff --git a/main/multi.h b/main/multi.h index 75f63efe5..8474adabe 100644 --- a/main/multi.h +++ b/main/multi.h @@ -386,6 +386,7 @@ typedef struct netgame_info struct _sockaddr addr; // IP address of this netgame's host short program_iver[3]; // IVER of program for version checking sbyte valid; // Status of Netgame info: -1 = Failed, Wrong version; 0 = No info, yet; 1 = Success + fix GameID; } udp; #endif } protocol; diff --git a/main/net_udp.c b/main/net_udp.c index a7a3cbb55..7c8e36049 100644 --- a/main/net_udp.c +++ b/main/net_udp.c @@ -98,6 +98,9 @@ int num_active_udp_changed = 0; static int UDP_Socket[2] = { -1, -1 }; static char UDP_MyPort[6] = ""; struct _sockaddr GBcast; // global Broadcast address clients and hosts will use for lite_info exchange over LAN +#ifdef IPv6 +struct _sockaddr GMcast_v6; // same for IPv6-only +#endif extern obj_position Player_init[MAX_PLAYERS]; /* General UDP functions - START */ @@ -513,6 +516,9 @@ int net_udp_list_join_poll( newmenu *menu, d_event *event, direct_join *dj ) num_active_udp_changed = 1; num_active_udp_games = 0; net_udp_request_game_info(GBcast, 1); +#ifdef IPv6 + net_udp_request_game_info(GMcast_v6, 1); +#endif break; } case EVENT_IDLE: @@ -547,6 +553,9 @@ int net_udp_list_join_poll( newmenu *menu, d_event *event, direct_join *dj ) num_active_udp_changed = 1; num_active_udp_games = 0; net_udp_request_game_info(GBcast, 1); +#ifdef IPv6 + net_udp_request_game_info(GMcast_v6, 1); +#endif break; } if (key == KEY_ESC) @@ -711,6 +720,10 @@ void net_udp_list_join_game() // prepare broadcast address to discover games memset(&GBcast, '\0', sizeof(struct _sockaddr)); udp_dns_filladdr(UDP_BCAST_ADDR, UDP_PORT_DEFAULT, &GBcast); +#ifdef IPv6 + memset(&GMcast_v6, '\0', sizeof(struct _sockaddr)); + udp_dns_filladdr(UDP_MCASTv6_ADDR, UDP_PORT_DEFAULT, &GMcast_v6); +#endif change_playernum_to(1); N_players = 0; @@ -1739,6 +1752,7 @@ void net_udp_send_game_info(struct _sockaddr sender_addr, ubyte info_upid) PUT_INTEL_SHORT(buf + len, D1XMAJORi); len += 2; PUT_INTEL_SHORT(buf + len, D1XMINORi); len += 2; PUT_INTEL_SHORT(buf + len, D1XMICROi); len += 2; + PUT_INTEL_INT(buf + len, Netgame.protocol.udp.GameID); len += 4; memcpy(&(buf[len]), Netgame.game_name, NETGAME_NAME_LEN+1); len += (NETGAME_NAME_LEN+1); memcpy(&(buf[len]), Netgame.mission_title, MISSION_NAME_LEN+1); len += (MISSION_NAME_LEN+1); memcpy(&(buf[len]), Netgame.mission_name, 9); len += 9; @@ -1872,6 +1886,9 @@ void net_udp_send_netgame_update() net_udp_send_game_info(Netgame.players[i].protocol.udp.addr, UPID_GAME_INFO); } net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE); +#ifdef IPv6 + net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE); +#endif } int net_udp_send_request(void) @@ -1917,6 +1934,7 @@ void net_udp_process_game_info(ubyte *data, int data_len, struct _sockaddr game_ if ((recv_game.program_iver[0] != D1XMAJORi) || (recv_game.program_iver[1] != D1XMINORi) || (recv_game.program_iver[2] != D1XMICROi)) return; + recv_game.GameID = GET_INTEL_INT(&(data[len])); len += 4; memcpy(&recv_game.game_name, &(data[len]), NETGAME_NAME_LEN+1); len += (NETGAME_NAME_LEN+1); memcpy(&recv_game.mission_title, &(data[len]), MISSION_NAME_LEN+1); len += (MISSION_NAME_LEN+1); memcpy(&recv_game.mission_name, &(data[len]), 9); len += 9; @@ -1933,7 +1951,7 @@ void net_udp_process_game_info(ubyte *data, int data_len, struct _sockaddr game_ num_active_udp_changed = 1; for (i = 0; i < num_active_udp_games; i++) - if (!strcasecmp(Active_udp_games[i].game_name, recv_game.game_name) && !memcmp((struct _sockaddr *)&Active_udp_games[i].game_addr, (struct _sockaddr *)&recv_game.game_addr, sizeof(struct _sockaddr))) + if (!strcasecmp(Active_udp_games[i].game_name, recv_game.game_name) && Active_udp_games[i].GameID == recv_game.GameID) break; if (i == UDP_MAX_NETGAMES) @@ -3018,6 +3036,9 @@ int net_udp_send_sync(void) net_udp_send_game_info(Netgame.players[i].protocol.udp.addr, UPID_GAME_INFO); } net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE); +#ifdef IPv6 + net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE); +#endif return -1; } @@ -3196,6 +3217,9 @@ abort: net_udp_send_game_info(Netgame.players[i].protocol.udp.addr, UPID_GAME_INFO); } net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE); +#ifdef IPv6 + net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE); +#endif Netgame.numplayers = save_nplayers; Network_status = NETSTAT_MENU; @@ -3282,6 +3306,13 @@ int net_udp_start_game(void) // prepare broadcast address to announce our game memset(&GBcast, '\0', sizeof(struct _sockaddr)); udp_dns_filladdr(UDP_BCAST_ADDR, UDP_PORT_DEFAULT, &GBcast); +#ifdef IPv6 + memset(&GMcast_v6, '\0', sizeof(struct _sockaddr)); + udp_dns_filladdr(UDP_MCASTv6_ADDR, UDP_PORT_DEFAULT, &GMcast_v6); +#endif + d_srand( (fix)timer_query() ); + Netgame.protocol.udp.GameID=d_rand(); + N_players = 0; @@ -3303,6 +3334,9 @@ int net_udp_start_game(void) return 0; // see if we want to tweak the game we setup } net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE); // game started. broadcast our current status to everyone who wants to know +#ifdef IPv6 + net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE); // game started. broadcast our current status to everyone who wants to know +#endif return 1; // don't keep params menu or mission listbox (may want to join a game next time) } @@ -3507,6 +3541,9 @@ void net_udp_leave_game() net_udp_send_game_info(Netgame.players[i].protocol.udp.addr, UPID_GAME_INFO); } net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE); +#ifdef IPv6 + net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE); +#endif N_players=nsave; } @@ -3684,6 +3721,9 @@ void net_udp_do_frame(int force, int listen) { last_bcast_time = time; net_udp_send_game_info(GBcast, UPID_GAME_INFO_LITE); +#ifdef IPv6 + net_udp_send_game_info(GMcast_v6, UPID_GAME_INFO_LITE); +#endif } if (listen) diff --git a/main/net_udp.h b/main/net_udp.h index f4207a2d3..5f967c8ec 100644 --- a/main/net_udp.h +++ b/main/net_udp.h @@ -24,10 +24,9 @@ int net_udp_level_sync(); // Some defines #ifdef IPv6 -#define UDP_BCAST_ADDR "ff02::1" -#else -#define UDP_BCAST_ADDR "255.255.255.255" +#define UDP_MCASTv6_ADDR "ff02::1" #endif +#define UDP_BCAST_ADDR "255.255.255.255" #define UDP_PORT_DEFAULT 42424 // Our default port - easy to remember: D = 4, X = 24, X = 24 #define UDP_REQ_ID "D1XR" // ID string for a request packet #define UDP_MAX_NETGAMES 600 @@ -38,7 +37,7 @@ int net_udp_level_sync(); #define UDP_OBJ_PACKETS_PER_FRAME 1 // Following are static defines for the buffer size of various packets. IF you change the packets, you must change the size, too. -#define UPKT_MAX_SIZE 576 // Max size for a packet - just for the buffers +#define UPKT_MAX_SIZE 1024 // Max size for a packet - just for the buffers #define UPKT_GAME_INFO_REQ_SIZE 11 #define UPKT_SEQUENCE_SIZE 14 #define UPKT_PING_SIZE 37 @@ -70,14 +69,15 @@ int net_udp_level_sync(); // Structure keeping lite game infos (for netlist, etc.) typedef struct UDP_netgame_info_lite { - struct _sockaddr game_addr; - short program_iver[3]; + struct _sockaddr game_addr; + fix GameID; + short program_iver[3]; char game_name[NETGAME_NAME_LEN+1]; char mission_title[MISSION_NAME_LEN+1]; char mission_name[9]; int32_t levelnum; ubyte gamemode; - ubyte RefusePlayers; + ubyte RefusePlayers; ubyte difficulty; ubyte game_status; ubyte numconnected;