From 1c9c856857943c1222bb7351c51a8c4deb306a86 Mon Sep 17 00:00:00 2001 From: BSzili Date: Sat, 18 Oct 2025 09:10:16 +0200 Subject: [PATCH 1/4] Multiplayer big endian fix --- src/DETHRACE/common/network.c | 383 ++++++++++++++++++++++++++++++++++ src/DETHRACE/pc-all/allnet.c | 10 + 2 files changed, 393 insertions(+) diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index 149b77c6..c7c83062 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -811,6 +811,366 @@ tPlayer_ID NetExtractPlayerID(tNet_game_details* pDetails) { return PDNetExtractPlayerID(pDetails); } +#if BR_ENDIAN_BIG +static void NetSwapVector3(br_vector3* pVector) { + for (int i = 0; i < 3; i++) { + pVector->v[i] = BrSwapFloat(pVector->v[i]); + } +} + +static void NetSwapMatrix34(br_matrix34* pMatrix) { + for (int row = 0; row < 4; row++) { + for (int col = 0; col < 3; col++) { + pMatrix->m[row][col] = BrSwapFloat(pMatrix->m[row][col]); + } + } +} + +static void NetSwapMessage(tNet_message* pMessage) { + pMessage->magic_number = BrSwap32(pMessage->magic_number); + pMessage->guarantee_number = BrSwap32(pMessage->guarantee_number); + pMessage->sender = BrSwap32(pMessage->sender); + pMessage->version = BrSwap32(pMessage->version); + pMessage->senders_time_stamp = BrSwap32(pMessage->senders_time_stamp); + pMessage->num_contents = BrSwap16(pMessage->num_contents); + // pMessage->overall_size = BrSwap16(pMessage->overall_size); +} + +static void NetSwapPlayerInfo(tNet_game_player_info* pPlayer) { + pPlayer->this_players_time_stamp = BrSwap32(pPlayer->this_players_time_stamp); + pPlayer->last_heard_from_him = BrSwap32(pPlayer->last_heard_from_him); + pPlayer->reposition_time = BrSwap32(pPlayer->reposition_time); + pPlayer->last_waste_message = BrSwap32(pPlayer->last_waste_message); + pPlayer->host = BrSwap32(pPlayer->host); + pPlayer->ID = BrSwap32(pPlayer->ID); + pPlayer->car_index = BrSwap32(pPlayer->car_index); + pPlayer->grid_index = BrSwap32(pPlayer->grid_index); + pPlayer->grid_position_set = BrSwap32(pPlayer->grid_position_set); + pPlayer->opponent_list_index = BrSwap32(pPlayer->opponent_list_index); + pPlayer->score = BrSwap32(pPlayer->score); + pPlayer->credits = BrSwap32(pPlayer->credits); + pPlayer->wasted = BrSwap32(pPlayer->wasted); + pPlayer->wasteage_attributed = BrSwap32(pPlayer->wasteage_attributed); + pPlayer->name_not_clipped = BrSwap32(pPlayer->name_not_clipped); + pPlayer->race_stuff_initialised = BrSwap32(pPlayer->race_stuff_initialised); + pPlayer->played = BrSwap32(pPlayer->played); + pPlayer->won = BrSwap32(pPlayer->won); + pPlayer->next_car_index = BrSwap32(pPlayer->next_car_index); + pPlayer->last_score_index = BrSwap32(pPlayer->last_score_index); + NetSwapMatrix34(&pPlayer->initial_position); +} + +static void NetSwapOptions(tNet_game_options* pOptions) { + pOptions->show_players_on_map = BrSwap32(pOptions->show_players_on_map); + pOptions->show_peds_on_map = BrSwap32(pOptions->show_peds_on_map); + pOptions->enable_text_messages = BrSwap32(pOptions->enable_text_messages); + pOptions->show_powerups_on_map = BrSwap32(pOptions->show_powerups_on_map); + pOptions->powerup_respawn = BrSwap32(pOptions->powerup_respawn); + pOptions->open_game = BrSwap32(pOptions->open_game); + pOptions->starting_money_index = BrSwap32(pOptions->starting_money_index); + pOptions->grid_start = BrSwap32(pOptions->grid_start); + pOptions->race_end_target = BrSwap32(pOptions->race_end_target); + pOptions->random_car_choice = BrSwap32(pOptions->random_car_choice); + pOptions->race_sequence_type = BrSwap32(pOptions->race_sequence_type); + pOptions->car_choice = BrSwap32(pOptions->car_choice); +} + +static void NetSwapGameDetails(tNet_game_details* pDetails) { + pDetails->host_ID = BrSwap32(pDetails->host_ID); + pDetails->num_players = BrSwap32(pDetails->num_players); + pDetails->start_race = BrSwap32(pDetails->start_race); + pDetails->no_races_yet = BrSwap32(pDetails->no_races_yet); + pDetails->status.stage = BrSwap32(pDetails->status.stage); + NetSwapOptions(&pDetails->options); + pDetails->type = BrSwap32(pDetails->type); +} + +static void NetSwapJoin(tNet_message_join* pJoin) { + NetSwapPlayerInfo(&pJoin->player_info); +} + +static void NetSwapPlayerList(tNet_message_new_player_list* pPlayerList) { + pPlayerList->number_of_players = BrSwap32(pPlayerList->number_of_players); + pPlayerList->this_index = BrSwap32(pPlayerList->this_index); + pPlayerList->batch_number = BrSwap32(pPlayerList->batch_number); + NetSwapPlayerInfo(&pPlayerList->player); +} + +static void NetSwapGuaranteeReply(tNet_message_guarantee_reply* pReply) { + pReply->guarantee_number = BrSwap32(pReply->guarantee_number); +} + +static void NetSwapCarDetails(tNet_message_car_details* pCarDetails) { + pCarDetails->count = BrSwap32(pCarDetails->count); + for (int j = 0; j < 6; j++) { + pCarDetails->details[j].car_index = BrSwap32(pCarDetails->details[j].car_index); + } +} + +static void NetSwapRaceOver(tNet_message_race_over* pRaceOver) { + pRaceOver->reason = BrSwap32(pRaceOver->reason); +} + +static void NetSwapStatusReport(tNet_message_status_report* pStatusReport) { + pStatusReport->status = BrSwap32(pStatusReport->status); +} + +static void NetSwapStartRace(tNet_message_start_race* pStartRace) { + pStartRace->car_count = BrSwap32(pStartRace->car_count); + pStartRace->racing = BrSwap32(pStartRace->racing); + pStartRace->next_race = BrSwap32(pStartRace->next_race); + for (int i = 0; i < 6; i++) { + pStartRace->car_list[i].index = BrSwap32(pStartRace->car_list[i].index); + pStartRace->car_list[i].next_car_index = BrSwap32(pStartRace->car_list[i].next_car_index); + NetSwapMatrix34(&pStartRace->car_list[i].mat); + } +} + +static void NetSwapHostReply(tNet_message_host_reply* pHostReply) { + pHostReply->race_has_started = BrSwap32(pHostReply->race_has_started); + pHostReply->race_index = BrSwap32(pHostReply->race_index); + pHostReply->pending_race = BrSwap32(pHostReply->pending_race); +} + +static void NetSwapMechanics(tNet_message_mechanics_info* pMechanics) { + pMechanics->ID = BrSwap32(pMechanics->ID); + pMechanics->time = BrSwap32(pMechanics->time); + *(br_uint_32*)&pMechanics->keys = BrSwap32(*(br_uint_32*)&pMechanics->keys); + pMechanics->cc_coll_time = BrSwap32(pMechanics->cc_coll_time); + pMechanics->curvature = BrSwap16(pMechanics->curvature); + pMechanics->revs = BrSwap16(pMechanics->revs); + pMechanics->front = BrSwapFloat(pMechanics->front); + pMechanics->back = BrSwapFloat(pMechanics->back); + pMechanics->repair_time = BrSwap32(pMechanics->repair_time); + pMechanics->powerups = BrSwap16(pMechanics->powerups); + NetSwapVector3(&pMechanics->mat.row1); + NetSwapVector3(&pMechanics->mat.row2); + NetSwapVector3(&pMechanics->mat.translation); + NetSwapVector3(&pMechanics->v); + NetSwapVector3(&pMechanics->omega); + if (pMechanics->contents_size != sizeof(tNet_message_mechanics_info)) { + return; + } + for (int i = 0; i < 4; i++) { + pMechanics->wheel_dam_offset[i] = BrSwapFloat(pMechanics->wheel_dam_offset[i]); + } +} + +static void NetSwapNonCar(tNet_message_non_car_info* pNonCarInfo) { + pNonCarInfo->ID = BrSwap32(pNonCarInfo->ID); + pNonCarInfo->time = BrSwap32(pNonCarInfo->time); + pNonCarInfo->cc_coll_time = BrSwap32(pNonCarInfo->cc_coll_time); + pNonCarInfo->flags = BrSwap16(pNonCarInfo->flags); + NetSwapVector3(&pNonCarInfo->mat.row1); + NetSwapVector3(&pNonCarInfo->mat.row2); + NetSwapVector3(&pNonCarInfo->mat.translation); + NetSwapVector3(&pNonCarInfo->v); + NetSwapVector3(&pNonCarInfo->omega); +} + +static void NetSwapTimeSync(tNet_message_time_sync* pTimeSync) { + pTimeSync->race_start_time = BrSwap32(pTimeSync->race_start_time); +} + +static void NetSwapConfirm(tNet_message_players_confirm* pConfirm) { + pConfirm->player = BrSwap32(pConfirm->player); +} + +static void NetSwapPowerup(tNet_message_powerup* pPowerup) { + pPowerup->player = BrSwap32(pPowerup->player); + pPowerup->powerup_index = BrSwap32(pPowerup->powerup_index); + pPowerup->time_left = BrSwap32(pPowerup->time_left); + pPowerup->event = BrSwap32(pPowerup->event); +} + +static void NetSwapRecover(tNet_message_recover* pRecover) { + pRecover->ID = BrSwap32(pRecover->ID); + pRecover->time_to_recover = BrSwap32(pRecover->time_to_recover); +} + +static void NetSwapScores(tNet_message_scores* pScores) { + pScores->general_score = BrSwap32(pScores->general_score); + for (int i = 0; i < 6; i++) { + pScores->scores[i] = BrSwap32(pScores->scores[i]); + } +} + +static void NetSwapWasted(tNet_message_wasted* pWasted) { + pWasted->victim = BrSwap32(pWasted->victim); + pWasted->culprit = BrSwap32(pWasted->culprit); +} + +static void NetSwapPedestrian(tNet_message_pedestrian* pPedestrian) { + pPedestrian->index = BrSwap16(pPedestrian->index); + NetSwapVector3(&pPedestrian->pos); + pPedestrian->speed = BrSwapFloat(pPedestrian->speed); + if (!(pPedestrian->flags & 0x20)) { + return; + } + NetSwapVector3(&pPedestrian->to_pos); + if (!(pPedestrian->flags & 0x40)) { + return; + } + NetSwapVector3(&pPedestrian->offset); + pPedestrian->murderer = BrSwap32(pPedestrian->murderer); + pPedestrian->respawn_time_or_spin_period = BrSwap32(pPedestrian->respawn_time_or_spin_period); +} + +static void NetSwapGameplay(tNet_message_gameplay* pGameplay) { + pGameplay->mess = BrSwap16(pGameplay->mess); + pGameplay->param_1 = BrSwap16(pGameplay->param_1); + pGameplay->param_2 = BrSwap16(pGameplay->param_2); + pGameplay->param_3 = BrSwap16(pGameplay->param_3); + pGameplay->param_4 = BrSwap16(pGameplay->param_4); +} + +static void NetSwapNonCarPosition(tNet_message_non_car_position* pNonCarPosition) { + pNonCarPosition->ID = BrSwap32(pNonCarPosition->ID); + pNonCarPosition->flags = BrSwap16(pNonCarPosition->flags); + NetSwapMatrix34(&pNonCarPosition->mat); +} + +static void NetSwapCopInfo(tNet_message_cop_info* pCopInfo) { + pCopInfo->ID = BrSwap32(pCopInfo->ID); + pCopInfo->time = BrSwap32(pCopInfo->time); + pCopInfo->curvature = BrSwapFloat(pCopInfo->curvature); + NetSwapVector3(&pCopInfo->mat.row1); + NetSwapVector3(&pCopInfo->mat.row2); + NetSwapVector3(&pCopInfo->mat.translation); + NetSwapVector3(&pCopInfo->v); + NetSwapVector3(&pCopInfo->omega); + for (int i = 0; i < 4; i++) { + pCopInfo->d[i] = BrSwapFloat(pCopInfo->d[i]); + } +} + +static void NetSwapGameScores(tNet_message_game_scores* pGameScores) { + for (int i = 0; i < 6; i++) { + pGameScores->scores[i].played = BrSwap32(pGameScores->scores[i].played); + pGameScores->scores[i].won = BrSwap32(pGameScores->scores[i].won); + pGameScores->scores[i].score = BrSwap32(pGameScores->scores[i].score); + } +} + +static void NetSwapOilSpill(tNet_message_oil_spill* pOilSpill) { + pOilSpill->player = BrSwap32(pOilSpill->player); + pOilSpill->full_size = BrSwapFloat(pOilSpill->full_size); + pOilSpill->grow_rate = BrSwapFloat(pOilSpill->grow_rate); + pOilSpill->current_size = BrSwapFloat(pOilSpill->current_size); +} + +static void NetSwapCrushPoint(tNet_message_crush_point* pCrushPoint) { + pCrushPoint->id = BrSwap32(pCrushPoint->id); + pCrushPoint->vertex = BrSwap16(pCrushPoint->vertex); + NetSwapVector3(&pCrushPoint->energy_vector); +} + +void NetSwapContents(tNet_contents* pContents) { + switch (pContents->header.type) { + case NETMSGID_SENDMEDETAILS: // 0x00, + break; + case NETMSGID_DETAILS: // 0x01, + NetSwapGameDetails(&pContents->data.details.details); + break; + case NETMSGID_JOIN: // 0x02, + NetSwapJoin(&pContents->data.join); + break; + case NETMSGID_NEWPLAYERLIST: // 0x03, + NetSwapPlayerList(&pContents->data.player_list); + break; + case NETMSGID_GUARANTEEREPLY: // 0x04, + NetSwapGuaranteeReply(&pContents->data.reply); + break; + case NETMSGID_CARDETAILSREQ: // 0x05, + break; + case NETMSGID_CARDETAILS: // 0x06, + NetSwapCarDetails(&pContents->data.car_details); + break; + case NETMSGID_LEAVE: // 0x07, + break; + case NETMSGID_HOSTICIDE: // 0x08, + break; + case NETMSGID_RACEOVER: // 0x09, + NetSwapRaceOver(&pContents->data.race_over); + break; + case NETMSGID_STATUSREPORT: // 0x0a, + NetSwapStatusReport(&pContents->data.report); + break; + case NETMSGID_STARTRACE: // 0x0b, + NetSwapStartRace(&pContents->data.start_race); + break; + case NETMSGID_HEADUP: // 0x0c, + break; + case NETMSGID_HOSTQUERY: // 0x0d, + break; + case NETMSGID_HOSTREPLY: // 0x0e, + NetSwapHostReply(&pContents->data.heres_where_we_at); + break; + case NETMSGID_MECHANICS: // 0x0f, + NetSwapMechanics(&pContents->data.mech); + break; + case NETMSGID_NONCAR_INFO: // 0x10, + NetSwapNonCar(&pContents->data.non_car); + break; + case NETMSGID_TIMESYNC: // 0x11, + NetSwapTimeSync(&pContents->data.time_sync); + break; + case NETMSGID_CONFIRM: // 0x12, + NetSwapConfirm(&pContents->data.confirm); + break; + case NETMSGID_DISABLECAR: // 0x13, + break; + case NETMSGID_ENABLECAR: // 0x14, + break; + case NETMSGID_POWERUP: // 0x15, + NetSwapPowerup(&pContents->data.powerup); + break; + case NETMSGID_RECOVER: // 0x16, + NetSwapRecover(&pContents->data.recover); + break; + case NETMSGID_SCORES: // 0x17, + NetSwapScores(&pContents->data.scores); + break; + case NETMSGID_WASTED: // 0x18, + NetSwapWasted(&pContents->data.wasted); + break; + case NETMSGID_PEDESTRIAN: // 0x19, + NetSwapPedestrian(&pContents->data.pedestrian); + break; + case NETMSGID_GAMEPLAY: // 0x1a, + NetSwapGameplay(&pContents->data.gameplay); + break; + case NETMSGID_NONCARPOSITION: // 0x1b, + NetSwapNonCarPosition(&pContents->data.non_car_position); + break; + case NETMSGID_COPINFO: // 0x1c, + NetSwapCopInfo(&pContents->data.cop_info); + break; + case NETMSGID_GAMESCORES: // 0x1d, + NetSwapGameScores(&pContents->data.game_scores); + break; + case NETMSGID_OILSPILL: // 0x1e, + NetSwapOilSpill(&pContents->data.oil_spill); + break; + case NETMSGID_CRUSHPOINT: // 0x1f, + NetSwapCrushPoint(&pContents->data.crush); + break; + } +} + +void NetSwapMessageAndContents(tNet_message* pMessage) { + tNet_contents* contents; + int i; + + contents = &pMessage->contents; + for (i = 0; i < pMessage->num_contents; i++) { + NetSwapContents(contents); + contents = (tNet_contents*)((tU8*)contents + contents->header.contents_size); + } + NetSwapMessage(pMessage); +} +#endif + // IDA: int __usercall NetSendMessageToAddress@(tNet_game_details *pDetails@, tNet_message *pMessage@, void *pAddress@) // FUNCTION: CARM95 0x004478fd int NetSendMessageToAddress(tNet_game_details* pDetails, tNet_message* pMessage, void* pAddress) { @@ -820,6 +1180,9 @@ int NetSendMessageToAddress(tNet_game_details* pDetails, tNet_message* pMessage, } pMessage->sender = gLocal_net_ID; pMessage->senders_time_stamp = PDGetTotalTime(); +#if BR_ENDIAN_BIG + NetSwapMessageAndContents(pMessage); +#endif GetCheckSum(pMessage); return PDNetSendMessageToAddress(pDetails, pMessage, pAddress); } @@ -833,6 +1196,9 @@ int NetSendMessageToPlayer(tNet_game_details* pDetails, tNet_message* pMessage, } pMessage->sender = gLocal_net_ID; pMessage->senders_time_stamp = PDGetTotalTime(); +#if BR_ENDIAN_BIG + NetSwapMessageAndContents(pMessage); +#endif for (i = 0; i < gNumber_of_net_players; i++) { if (gNet_players[i].ID == pPlayer) { GetCheckSum(pMessage); @@ -851,6 +1217,9 @@ int NetSendMessageToHost(tNet_game_details* pDetails, tNet_message* pMessage) { } pMessage->sender = gLocal_net_ID; pMessage->senders_time_stamp = PDGetTotalTime(); +#if BR_ENDIAN_BIG + NetSwapMessageAndContents(pMessage); +#endif DoCheckSum(pMessage); return PDNetSendMessageToAddress(pDetails, pMessage, &pDetails->pd_net_info); } @@ -867,6 +1236,9 @@ int NetSendMessageToAllPlayers(tNet_game_details* pDetails, tNet_message* pMessa pMessage->sender = gLocal_net_ID; pMessage->senders_time_stamp = PDGetTotalTime(); +#if BR_ENDIAN_BIG + NetSwapMessageAndContents(pMessage); +#endif GetCheckSum(pMessage); return PDNetSendMessageToAllPlayers(pDetails, pMessage); } @@ -1802,6 +2174,11 @@ void ReceivedMessage(tNet_message* pMessage, void* pSender_address, tU32 pReceiv for (i = 0; i < pMessage->num_contents; i++) { if (contents->header.type <= NETMSGID_CARDETAILS || PlayerIsInList(pMessage->sender)) { +#if BR_ENDIAN_BIG + if (pMessage->sender != gLocal_net_ID) { + NetSwapContents(contents); + } +#endif switch (contents->header.type) { case NETMSGID_SENDMEDETAILS: // 0x00, ReceivedSendMeDetails(contents, pSender_address); @@ -1918,6 +2295,9 @@ void NetReceiveAndProcessMessages(void) { gIn_net_service = 1; while ((message = NetGetNextMessage(gCurrent_net_game, &sender_address)) != NULL) { receive_time = GetRaceTime(); +#if BR_ENDIAN_BIG + NetSwapMessage(message); +#endif if (message->magic_number == 0x763a5058) { CheckCheckSum(message); ReceivedMessage(message, sender_address, receive_time); @@ -2145,6 +2525,9 @@ int NetGuaranteedSendMessageToAddress(tNet_game_details* pDetails, tNet_message* gGuarantee_list[gNext_guarantee].NotifyFail = pNotifyFail; gGuarantee_list[gNext_guarantee].recieved = 0; gNext_guarantee++; +#if BR_ENDIAN_BIG + NetSwapMessageAndContents(pMessage); +#endif DoCheckSum(pMessage); return PDNetSendMessageToAddress(pDetails, pMessage, pAddress); } diff --git a/src/DETHRACE/pc-all/allnet.c b/src/DETHRACE/pc-all/allnet.c index fd42b442..39fa1fee 100644 --- a/src/DETHRACE/pc-all/allnet.c +++ b/src/DETHRACE/pc-all/allnet.c @@ -620,12 +620,22 @@ int PDNetGetHeaderSize(void) { } void PDNetCopyFromNative(tCopyable_sockaddr_in* pAddress, struct sockaddr_in* sock) { +#if BR_ENDIAN_BIG + pAddress->port = sock->sin_port << 16; + pAddress->address = (uint64_t)sock->sin_addr.s_addr << 32; +#else pAddress->port = sock->sin_port; pAddress->address = sock->sin_addr.s_addr; +#endif } void PDNetCopyToNative(struct sockaddr_in* sock, tCopyable_sockaddr_in* pAddress) { +#if BR_ENDIAN_BIG + sock->sin_addr.s_addr = pAddress->address >> 32; + sock->sin_port = pAddress->port >> 16; +#else sock->sin_addr.s_addr = pAddress->address; sock->sin_port = pAddress->port; +#endif sock->sin_family = AF_INET; } From 75a5db6230fb46bef0b914c51e8c654cec403ed3 Mon Sep 17 00:00:00 2001 From: BSzili Date: Tue, 6 Jan 2026 07:46:31 +0100 Subject: [PATCH 2/4] Separate the network byteswap functions into network_endian.h --- src/DETHRACE/common/network.c | 361 +------------------------- src/DETHRACE/common/network_endian.h | 374 +++++++++++++++++++++++++++ 2 files changed, 375 insertions(+), 360 deletions(-) create mode 100644 src/DETHRACE/common/network_endian.h diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index c7c83062..6c237f80 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -26,6 +26,7 @@ #include "structur.h" #include "utility.h" #include "world.h" +#include "network_endian.h" #include tU32 gMess_max_flags; @@ -811,366 +812,6 @@ tPlayer_ID NetExtractPlayerID(tNet_game_details* pDetails) { return PDNetExtractPlayerID(pDetails); } -#if BR_ENDIAN_BIG -static void NetSwapVector3(br_vector3* pVector) { - for (int i = 0; i < 3; i++) { - pVector->v[i] = BrSwapFloat(pVector->v[i]); - } -} - -static void NetSwapMatrix34(br_matrix34* pMatrix) { - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 3; col++) { - pMatrix->m[row][col] = BrSwapFloat(pMatrix->m[row][col]); - } - } -} - -static void NetSwapMessage(tNet_message* pMessage) { - pMessage->magic_number = BrSwap32(pMessage->magic_number); - pMessage->guarantee_number = BrSwap32(pMessage->guarantee_number); - pMessage->sender = BrSwap32(pMessage->sender); - pMessage->version = BrSwap32(pMessage->version); - pMessage->senders_time_stamp = BrSwap32(pMessage->senders_time_stamp); - pMessage->num_contents = BrSwap16(pMessage->num_contents); - // pMessage->overall_size = BrSwap16(pMessage->overall_size); -} - -static void NetSwapPlayerInfo(tNet_game_player_info* pPlayer) { - pPlayer->this_players_time_stamp = BrSwap32(pPlayer->this_players_time_stamp); - pPlayer->last_heard_from_him = BrSwap32(pPlayer->last_heard_from_him); - pPlayer->reposition_time = BrSwap32(pPlayer->reposition_time); - pPlayer->last_waste_message = BrSwap32(pPlayer->last_waste_message); - pPlayer->host = BrSwap32(pPlayer->host); - pPlayer->ID = BrSwap32(pPlayer->ID); - pPlayer->car_index = BrSwap32(pPlayer->car_index); - pPlayer->grid_index = BrSwap32(pPlayer->grid_index); - pPlayer->grid_position_set = BrSwap32(pPlayer->grid_position_set); - pPlayer->opponent_list_index = BrSwap32(pPlayer->opponent_list_index); - pPlayer->score = BrSwap32(pPlayer->score); - pPlayer->credits = BrSwap32(pPlayer->credits); - pPlayer->wasted = BrSwap32(pPlayer->wasted); - pPlayer->wasteage_attributed = BrSwap32(pPlayer->wasteage_attributed); - pPlayer->name_not_clipped = BrSwap32(pPlayer->name_not_clipped); - pPlayer->race_stuff_initialised = BrSwap32(pPlayer->race_stuff_initialised); - pPlayer->played = BrSwap32(pPlayer->played); - pPlayer->won = BrSwap32(pPlayer->won); - pPlayer->next_car_index = BrSwap32(pPlayer->next_car_index); - pPlayer->last_score_index = BrSwap32(pPlayer->last_score_index); - NetSwapMatrix34(&pPlayer->initial_position); -} - -static void NetSwapOptions(tNet_game_options* pOptions) { - pOptions->show_players_on_map = BrSwap32(pOptions->show_players_on_map); - pOptions->show_peds_on_map = BrSwap32(pOptions->show_peds_on_map); - pOptions->enable_text_messages = BrSwap32(pOptions->enable_text_messages); - pOptions->show_powerups_on_map = BrSwap32(pOptions->show_powerups_on_map); - pOptions->powerup_respawn = BrSwap32(pOptions->powerup_respawn); - pOptions->open_game = BrSwap32(pOptions->open_game); - pOptions->starting_money_index = BrSwap32(pOptions->starting_money_index); - pOptions->grid_start = BrSwap32(pOptions->grid_start); - pOptions->race_end_target = BrSwap32(pOptions->race_end_target); - pOptions->random_car_choice = BrSwap32(pOptions->random_car_choice); - pOptions->race_sequence_type = BrSwap32(pOptions->race_sequence_type); - pOptions->car_choice = BrSwap32(pOptions->car_choice); -} - -static void NetSwapGameDetails(tNet_game_details* pDetails) { - pDetails->host_ID = BrSwap32(pDetails->host_ID); - pDetails->num_players = BrSwap32(pDetails->num_players); - pDetails->start_race = BrSwap32(pDetails->start_race); - pDetails->no_races_yet = BrSwap32(pDetails->no_races_yet); - pDetails->status.stage = BrSwap32(pDetails->status.stage); - NetSwapOptions(&pDetails->options); - pDetails->type = BrSwap32(pDetails->type); -} - -static void NetSwapJoin(tNet_message_join* pJoin) { - NetSwapPlayerInfo(&pJoin->player_info); -} - -static void NetSwapPlayerList(tNet_message_new_player_list* pPlayerList) { - pPlayerList->number_of_players = BrSwap32(pPlayerList->number_of_players); - pPlayerList->this_index = BrSwap32(pPlayerList->this_index); - pPlayerList->batch_number = BrSwap32(pPlayerList->batch_number); - NetSwapPlayerInfo(&pPlayerList->player); -} - -static void NetSwapGuaranteeReply(tNet_message_guarantee_reply* pReply) { - pReply->guarantee_number = BrSwap32(pReply->guarantee_number); -} - -static void NetSwapCarDetails(tNet_message_car_details* pCarDetails) { - pCarDetails->count = BrSwap32(pCarDetails->count); - for (int j = 0; j < 6; j++) { - pCarDetails->details[j].car_index = BrSwap32(pCarDetails->details[j].car_index); - } -} - -static void NetSwapRaceOver(tNet_message_race_over* pRaceOver) { - pRaceOver->reason = BrSwap32(pRaceOver->reason); -} - -static void NetSwapStatusReport(tNet_message_status_report* pStatusReport) { - pStatusReport->status = BrSwap32(pStatusReport->status); -} - -static void NetSwapStartRace(tNet_message_start_race* pStartRace) { - pStartRace->car_count = BrSwap32(pStartRace->car_count); - pStartRace->racing = BrSwap32(pStartRace->racing); - pStartRace->next_race = BrSwap32(pStartRace->next_race); - for (int i = 0; i < 6; i++) { - pStartRace->car_list[i].index = BrSwap32(pStartRace->car_list[i].index); - pStartRace->car_list[i].next_car_index = BrSwap32(pStartRace->car_list[i].next_car_index); - NetSwapMatrix34(&pStartRace->car_list[i].mat); - } -} - -static void NetSwapHostReply(tNet_message_host_reply* pHostReply) { - pHostReply->race_has_started = BrSwap32(pHostReply->race_has_started); - pHostReply->race_index = BrSwap32(pHostReply->race_index); - pHostReply->pending_race = BrSwap32(pHostReply->pending_race); -} - -static void NetSwapMechanics(tNet_message_mechanics_info* pMechanics) { - pMechanics->ID = BrSwap32(pMechanics->ID); - pMechanics->time = BrSwap32(pMechanics->time); - *(br_uint_32*)&pMechanics->keys = BrSwap32(*(br_uint_32*)&pMechanics->keys); - pMechanics->cc_coll_time = BrSwap32(pMechanics->cc_coll_time); - pMechanics->curvature = BrSwap16(pMechanics->curvature); - pMechanics->revs = BrSwap16(pMechanics->revs); - pMechanics->front = BrSwapFloat(pMechanics->front); - pMechanics->back = BrSwapFloat(pMechanics->back); - pMechanics->repair_time = BrSwap32(pMechanics->repair_time); - pMechanics->powerups = BrSwap16(pMechanics->powerups); - NetSwapVector3(&pMechanics->mat.row1); - NetSwapVector3(&pMechanics->mat.row2); - NetSwapVector3(&pMechanics->mat.translation); - NetSwapVector3(&pMechanics->v); - NetSwapVector3(&pMechanics->omega); - if (pMechanics->contents_size != sizeof(tNet_message_mechanics_info)) { - return; - } - for (int i = 0; i < 4; i++) { - pMechanics->wheel_dam_offset[i] = BrSwapFloat(pMechanics->wheel_dam_offset[i]); - } -} - -static void NetSwapNonCar(tNet_message_non_car_info* pNonCarInfo) { - pNonCarInfo->ID = BrSwap32(pNonCarInfo->ID); - pNonCarInfo->time = BrSwap32(pNonCarInfo->time); - pNonCarInfo->cc_coll_time = BrSwap32(pNonCarInfo->cc_coll_time); - pNonCarInfo->flags = BrSwap16(pNonCarInfo->flags); - NetSwapVector3(&pNonCarInfo->mat.row1); - NetSwapVector3(&pNonCarInfo->mat.row2); - NetSwapVector3(&pNonCarInfo->mat.translation); - NetSwapVector3(&pNonCarInfo->v); - NetSwapVector3(&pNonCarInfo->omega); -} - -static void NetSwapTimeSync(tNet_message_time_sync* pTimeSync) { - pTimeSync->race_start_time = BrSwap32(pTimeSync->race_start_time); -} - -static void NetSwapConfirm(tNet_message_players_confirm* pConfirm) { - pConfirm->player = BrSwap32(pConfirm->player); -} - -static void NetSwapPowerup(tNet_message_powerup* pPowerup) { - pPowerup->player = BrSwap32(pPowerup->player); - pPowerup->powerup_index = BrSwap32(pPowerup->powerup_index); - pPowerup->time_left = BrSwap32(pPowerup->time_left); - pPowerup->event = BrSwap32(pPowerup->event); -} - -static void NetSwapRecover(tNet_message_recover* pRecover) { - pRecover->ID = BrSwap32(pRecover->ID); - pRecover->time_to_recover = BrSwap32(pRecover->time_to_recover); -} - -static void NetSwapScores(tNet_message_scores* pScores) { - pScores->general_score = BrSwap32(pScores->general_score); - for (int i = 0; i < 6; i++) { - pScores->scores[i] = BrSwap32(pScores->scores[i]); - } -} - -static void NetSwapWasted(tNet_message_wasted* pWasted) { - pWasted->victim = BrSwap32(pWasted->victim); - pWasted->culprit = BrSwap32(pWasted->culprit); -} - -static void NetSwapPedestrian(tNet_message_pedestrian* pPedestrian) { - pPedestrian->index = BrSwap16(pPedestrian->index); - NetSwapVector3(&pPedestrian->pos); - pPedestrian->speed = BrSwapFloat(pPedestrian->speed); - if (!(pPedestrian->flags & 0x20)) { - return; - } - NetSwapVector3(&pPedestrian->to_pos); - if (!(pPedestrian->flags & 0x40)) { - return; - } - NetSwapVector3(&pPedestrian->offset); - pPedestrian->murderer = BrSwap32(pPedestrian->murderer); - pPedestrian->respawn_time_or_spin_period = BrSwap32(pPedestrian->respawn_time_or_spin_period); -} - -static void NetSwapGameplay(tNet_message_gameplay* pGameplay) { - pGameplay->mess = BrSwap16(pGameplay->mess); - pGameplay->param_1 = BrSwap16(pGameplay->param_1); - pGameplay->param_2 = BrSwap16(pGameplay->param_2); - pGameplay->param_3 = BrSwap16(pGameplay->param_3); - pGameplay->param_4 = BrSwap16(pGameplay->param_4); -} - -static void NetSwapNonCarPosition(tNet_message_non_car_position* pNonCarPosition) { - pNonCarPosition->ID = BrSwap32(pNonCarPosition->ID); - pNonCarPosition->flags = BrSwap16(pNonCarPosition->flags); - NetSwapMatrix34(&pNonCarPosition->mat); -} - -static void NetSwapCopInfo(tNet_message_cop_info* pCopInfo) { - pCopInfo->ID = BrSwap32(pCopInfo->ID); - pCopInfo->time = BrSwap32(pCopInfo->time); - pCopInfo->curvature = BrSwapFloat(pCopInfo->curvature); - NetSwapVector3(&pCopInfo->mat.row1); - NetSwapVector3(&pCopInfo->mat.row2); - NetSwapVector3(&pCopInfo->mat.translation); - NetSwapVector3(&pCopInfo->v); - NetSwapVector3(&pCopInfo->omega); - for (int i = 0; i < 4; i++) { - pCopInfo->d[i] = BrSwapFloat(pCopInfo->d[i]); - } -} - -static void NetSwapGameScores(tNet_message_game_scores* pGameScores) { - for (int i = 0; i < 6; i++) { - pGameScores->scores[i].played = BrSwap32(pGameScores->scores[i].played); - pGameScores->scores[i].won = BrSwap32(pGameScores->scores[i].won); - pGameScores->scores[i].score = BrSwap32(pGameScores->scores[i].score); - } -} - -static void NetSwapOilSpill(tNet_message_oil_spill* pOilSpill) { - pOilSpill->player = BrSwap32(pOilSpill->player); - pOilSpill->full_size = BrSwapFloat(pOilSpill->full_size); - pOilSpill->grow_rate = BrSwapFloat(pOilSpill->grow_rate); - pOilSpill->current_size = BrSwapFloat(pOilSpill->current_size); -} - -static void NetSwapCrushPoint(tNet_message_crush_point* pCrushPoint) { - pCrushPoint->id = BrSwap32(pCrushPoint->id); - pCrushPoint->vertex = BrSwap16(pCrushPoint->vertex); - NetSwapVector3(&pCrushPoint->energy_vector); -} - -void NetSwapContents(tNet_contents* pContents) { - switch (pContents->header.type) { - case NETMSGID_SENDMEDETAILS: // 0x00, - break; - case NETMSGID_DETAILS: // 0x01, - NetSwapGameDetails(&pContents->data.details.details); - break; - case NETMSGID_JOIN: // 0x02, - NetSwapJoin(&pContents->data.join); - break; - case NETMSGID_NEWPLAYERLIST: // 0x03, - NetSwapPlayerList(&pContents->data.player_list); - break; - case NETMSGID_GUARANTEEREPLY: // 0x04, - NetSwapGuaranteeReply(&pContents->data.reply); - break; - case NETMSGID_CARDETAILSREQ: // 0x05, - break; - case NETMSGID_CARDETAILS: // 0x06, - NetSwapCarDetails(&pContents->data.car_details); - break; - case NETMSGID_LEAVE: // 0x07, - break; - case NETMSGID_HOSTICIDE: // 0x08, - break; - case NETMSGID_RACEOVER: // 0x09, - NetSwapRaceOver(&pContents->data.race_over); - break; - case NETMSGID_STATUSREPORT: // 0x0a, - NetSwapStatusReport(&pContents->data.report); - break; - case NETMSGID_STARTRACE: // 0x0b, - NetSwapStartRace(&pContents->data.start_race); - break; - case NETMSGID_HEADUP: // 0x0c, - break; - case NETMSGID_HOSTQUERY: // 0x0d, - break; - case NETMSGID_HOSTREPLY: // 0x0e, - NetSwapHostReply(&pContents->data.heres_where_we_at); - break; - case NETMSGID_MECHANICS: // 0x0f, - NetSwapMechanics(&pContents->data.mech); - break; - case NETMSGID_NONCAR_INFO: // 0x10, - NetSwapNonCar(&pContents->data.non_car); - break; - case NETMSGID_TIMESYNC: // 0x11, - NetSwapTimeSync(&pContents->data.time_sync); - break; - case NETMSGID_CONFIRM: // 0x12, - NetSwapConfirm(&pContents->data.confirm); - break; - case NETMSGID_DISABLECAR: // 0x13, - break; - case NETMSGID_ENABLECAR: // 0x14, - break; - case NETMSGID_POWERUP: // 0x15, - NetSwapPowerup(&pContents->data.powerup); - break; - case NETMSGID_RECOVER: // 0x16, - NetSwapRecover(&pContents->data.recover); - break; - case NETMSGID_SCORES: // 0x17, - NetSwapScores(&pContents->data.scores); - break; - case NETMSGID_WASTED: // 0x18, - NetSwapWasted(&pContents->data.wasted); - break; - case NETMSGID_PEDESTRIAN: // 0x19, - NetSwapPedestrian(&pContents->data.pedestrian); - break; - case NETMSGID_GAMEPLAY: // 0x1a, - NetSwapGameplay(&pContents->data.gameplay); - break; - case NETMSGID_NONCARPOSITION: // 0x1b, - NetSwapNonCarPosition(&pContents->data.non_car_position); - break; - case NETMSGID_COPINFO: // 0x1c, - NetSwapCopInfo(&pContents->data.cop_info); - break; - case NETMSGID_GAMESCORES: // 0x1d, - NetSwapGameScores(&pContents->data.game_scores); - break; - case NETMSGID_OILSPILL: // 0x1e, - NetSwapOilSpill(&pContents->data.oil_spill); - break; - case NETMSGID_CRUSHPOINT: // 0x1f, - NetSwapCrushPoint(&pContents->data.crush); - break; - } -} - -void NetSwapMessageAndContents(tNet_message* pMessage) { - tNet_contents* contents; - int i; - - contents = &pMessage->contents; - for (i = 0; i < pMessage->num_contents; i++) { - NetSwapContents(contents); - contents = (tNet_contents*)((tU8*)contents + contents->header.contents_size); - } - NetSwapMessage(pMessage); -} -#endif - // IDA: int __usercall NetSendMessageToAddress@(tNet_game_details *pDetails@, tNet_message *pMessage@, void *pAddress@) // FUNCTION: CARM95 0x004478fd int NetSendMessageToAddress(tNet_game_details* pDetails, tNet_message* pMessage, void* pAddress) { diff --git a/src/DETHRACE/common/network_endian.h b/src/DETHRACE/common/network_endian.h new file mode 100644 index 00000000..4365d5e7 --- /dev/null +++ b/src/DETHRACE/common/network_endian.h @@ -0,0 +1,374 @@ +#ifndef NETWORK_ENDIAN_H +#define NETWORK_ENDIAN_H + +#ifdef BR_ENDIAN_BIG + +#include "dr_types.h" + +static void NetSwapVector3(br_vector3* pVector) { + for (int i = 0; i < 3; i++) { + pVector->v[i] = BrSwapFloat(pVector->v[i]); + } +} + +static void NetSwapMatrix34(br_matrix34* pMatrix) { + for (int row = 0; row < 4; row++) { + for (int col = 0; col < 3; col++) { + pMatrix->m[row][col] = BrSwapFloat(pMatrix->m[row][col]); + } + } +} + +static void NetSwapMessage(tNet_message* pMessage) { + pMessage->magic_number = BrSwap32(pMessage->magic_number); + pMessage->guarantee_number = BrSwap32(pMessage->guarantee_number); + pMessage->sender = BrSwap32(pMessage->sender); + pMessage->version = BrSwap32(pMessage->version); + pMessage->senders_time_stamp = BrSwap32(pMessage->senders_time_stamp); + pMessage->num_contents = BrSwap16(pMessage->num_contents); + // pMessage->overall_size = BrSwap16(pMessage->overall_size); +} + +static void NetSwapPlayerInfo(tNet_game_player_info* pPlayer) { + pPlayer->this_players_time_stamp = BrSwap32(pPlayer->this_players_time_stamp); + pPlayer->last_heard_from_him = BrSwap32(pPlayer->last_heard_from_him); + pPlayer->reposition_time = BrSwap32(pPlayer->reposition_time); + pPlayer->last_waste_message = BrSwap32(pPlayer->last_waste_message); + pPlayer->host = BrSwap32(pPlayer->host); + pPlayer->ID = BrSwap32(pPlayer->ID); + pPlayer->car_index = BrSwap32(pPlayer->car_index); + pPlayer->grid_index = BrSwap32(pPlayer->grid_index); + pPlayer->grid_position_set = BrSwap32(pPlayer->grid_position_set); + pPlayer->opponent_list_index = BrSwap32(pPlayer->opponent_list_index); + pPlayer->score = BrSwap32(pPlayer->score); + pPlayer->credits = BrSwap32(pPlayer->credits); + pPlayer->wasted = BrSwap32(pPlayer->wasted); + pPlayer->wasteage_attributed = BrSwap32(pPlayer->wasteage_attributed); + pPlayer->name_not_clipped = BrSwap32(pPlayer->name_not_clipped); + pPlayer->race_stuff_initialised = BrSwap32(pPlayer->race_stuff_initialised); + pPlayer->played = BrSwap32(pPlayer->played); + pPlayer->won = BrSwap32(pPlayer->won); + pPlayer->next_car_index = BrSwap32(pPlayer->next_car_index); + pPlayer->last_score_index = BrSwap32(pPlayer->last_score_index); + NetSwapMatrix34(&pPlayer->initial_position); +} + +static void NetSwapOptions(tNet_game_options* pOptions) { + pOptions->show_players_on_map = BrSwap32(pOptions->show_players_on_map); + pOptions->show_peds_on_map = BrSwap32(pOptions->show_peds_on_map); + pOptions->enable_text_messages = BrSwap32(pOptions->enable_text_messages); + pOptions->show_powerups_on_map = BrSwap32(pOptions->show_powerups_on_map); + pOptions->powerup_respawn = BrSwap32(pOptions->powerup_respawn); + pOptions->open_game = BrSwap32(pOptions->open_game); + pOptions->starting_money_index = BrSwap32(pOptions->starting_money_index); + pOptions->grid_start = BrSwap32(pOptions->grid_start); + pOptions->race_end_target = BrSwap32(pOptions->race_end_target); + pOptions->random_car_choice = BrSwap32(pOptions->random_car_choice); + pOptions->race_sequence_type = BrSwap32(pOptions->race_sequence_type); + pOptions->car_choice = BrSwap32(pOptions->car_choice); +} + +static void NetSwapGameDetails(tNet_game_details* pDetails) { + pDetails->host_ID = BrSwap32(pDetails->host_ID); + pDetails->num_players = BrSwap32(pDetails->num_players); + pDetails->start_race = BrSwap32(pDetails->start_race); + pDetails->no_races_yet = BrSwap32(pDetails->no_races_yet); + pDetails->status.stage = BrSwap32(pDetails->status.stage); + NetSwapOptions(&pDetails->options); + pDetails->type = BrSwap32(pDetails->type); +} + +static void NetSwapJoin(tNet_message_join* pJoin) { + NetSwapPlayerInfo(&pJoin->player_info); +} + +static void NetSwapPlayerList(tNet_message_new_player_list* pPlayerList) { + pPlayerList->number_of_players = BrSwap32(pPlayerList->number_of_players); + pPlayerList->this_index = BrSwap32(pPlayerList->this_index); + pPlayerList->batch_number = BrSwap32(pPlayerList->batch_number); + NetSwapPlayerInfo(&pPlayerList->player); +} + +static void NetSwapGuaranteeReply(tNet_message_guarantee_reply* pReply) { + pReply->guarantee_number = BrSwap32(pReply->guarantee_number); +} + +static void NetSwapCarDetails(tNet_message_car_details* pCarDetails) { + pCarDetails->count = BrSwap32(pCarDetails->count); + for (int j = 0; j < 6; j++) { + pCarDetails->details[j].car_index = BrSwap32(pCarDetails->details[j].car_index); + } +} + +static void NetSwapRaceOver(tNet_message_race_over* pRaceOver) { + pRaceOver->reason = BrSwap32(pRaceOver->reason); +} + +static void NetSwapStatusReport(tNet_message_status_report* pStatusReport) { + pStatusReport->status = BrSwap32(pStatusReport->status); +} + +static void NetSwapStartRace(tNet_message_start_race* pStartRace) { + pStartRace->car_count = BrSwap32(pStartRace->car_count); + pStartRace->racing = BrSwap32(pStartRace->racing); + pStartRace->next_race = BrSwap32(pStartRace->next_race); + for (int i = 0; i < 6; i++) { + pStartRace->car_list[i].index = BrSwap32(pStartRace->car_list[i].index); + pStartRace->car_list[i].next_car_index = BrSwap32(pStartRace->car_list[i].next_car_index); + NetSwapMatrix34(&pStartRace->car_list[i].mat); + } +} + +static void NetSwapHostReply(tNet_message_host_reply* pHostReply) { + pHostReply->race_has_started = BrSwap32(pHostReply->race_has_started); + pHostReply->race_index = BrSwap32(pHostReply->race_index); + pHostReply->pending_race = BrSwap32(pHostReply->pending_race); +} + +static void NetSwapMechanics(tNet_message_mechanics_info* pMechanics) { + pMechanics->ID = BrSwap32(pMechanics->ID); + pMechanics->time = BrSwap32(pMechanics->time); + *(br_uint_32*)&pMechanics->keys = BrSwap32(*(br_uint_32*)&pMechanics->keys); + pMechanics->cc_coll_time = BrSwap32(pMechanics->cc_coll_time); + pMechanics->curvature = BrSwap16(pMechanics->curvature); + pMechanics->revs = BrSwap16(pMechanics->revs); + pMechanics->front = BrSwapFloat(pMechanics->front); + pMechanics->back = BrSwapFloat(pMechanics->back); + pMechanics->repair_time = BrSwap32(pMechanics->repair_time); + pMechanics->powerups = BrSwap16(pMechanics->powerups); + NetSwapVector3(&pMechanics->mat.row1); + NetSwapVector3(&pMechanics->mat.row2); + NetSwapVector3(&pMechanics->mat.translation); + NetSwapVector3(&pMechanics->v); + NetSwapVector3(&pMechanics->omega); + if (pMechanics->contents_size != sizeof(tNet_message_mechanics_info)) { + return; + } + for (int i = 0; i < 4; i++) { + pMechanics->wheel_dam_offset[i] = BrSwapFloat(pMechanics->wheel_dam_offset[i]); + } +} + +static void NetSwapNonCar(tNet_message_non_car_info* pNonCarInfo) { + pNonCarInfo->ID = BrSwap32(pNonCarInfo->ID); + pNonCarInfo->time = BrSwap32(pNonCarInfo->time); + pNonCarInfo->cc_coll_time = BrSwap32(pNonCarInfo->cc_coll_time); + pNonCarInfo->flags = BrSwap16(pNonCarInfo->flags); + NetSwapVector3(&pNonCarInfo->mat.row1); + NetSwapVector3(&pNonCarInfo->mat.row2); + NetSwapVector3(&pNonCarInfo->mat.translation); + NetSwapVector3(&pNonCarInfo->v); + NetSwapVector3(&pNonCarInfo->omega); +} + +static void NetSwapTimeSync(tNet_message_time_sync* pTimeSync) { + pTimeSync->race_start_time = BrSwap32(pTimeSync->race_start_time); +} + +static void NetSwapConfirm(tNet_message_players_confirm* pConfirm) { + pConfirm->player = BrSwap32(pConfirm->player); +} + +static void NetSwapPowerup(tNet_message_powerup* pPowerup) { + pPowerup->player = BrSwap32(pPowerup->player); + pPowerup->powerup_index = BrSwap32(pPowerup->powerup_index); + pPowerup->time_left = BrSwap32(pPowerup->time_left); + pPowerup->event = BrSwap32(pPowerup->event); +} + +static void NetSwapRecover(tNet_message_recover* pRecover) { + pRecover->ID = BrSwap32(pRecover->ID); + pRecover->time_to_recover = BrSwap32(pRecover->time_to_recover); +} + +static void NetSwapScores(tNet_message_scores* pScores) { + pScores->general_score = BrSwap32(pScores->general_score); + for (int i = 0; i < 6; i++) { + pScores->scores[i] = BrSwap32(pScores->scores[i]); + } +} + +static void NetSwapWasted(tNet_message_wasted* pWasted) { + pWasted->victim = BrSwap32(pWasted->victim); + pWasted->culprit = BrSwap32(pWasted->culprit); +} + +static void NetSwapPedestrian(tNet_message_pedestrian* pPedestrian) { + pPedestrian->index = BrSwap16(pPedestrian->index); + NetSwapVector3(&pPedestrian->pos); + pPedestrian->speed = BrSwapFloat(pPedestrian->speed); + if (!(pPedestrian->flags & 0x20)) { + return; + } + NetSwapVector3(&pPedestrian->to_pos); + if (!(pPedestrian->flags & 0x40)) { + return; + } + NetSwapVector3(&pPedestrian->offset); + pPedestrian->murderer = BrSwap32(pPedestrian->murderer); + pPedestrian->respawn_time_or_spin_period = BrSwap32(pPedestrian->respawn_time_or_spin_period); +} + +static void NetSwapGameplay(tNet_message_gameplay* pGameplay) { + pGameplay->mess = BrSwap16(pGameplay->mess); + pGameplay->param_1 = BrSwap16(pGameplay->param_1); + pGameplay->param_2 = BrSwap16(pGameplay->param_2); + pGameplay->param_3 = BrSwap16(pGameplay->param_3); + pGameplay->param_4 = BrSwap16(pGameplay->param_4); +} + +static void NetSwapNonCarPosition(tNet_message_non_car_position* pNonCarPosition) { + pNonCarPosition->ID = BrSwap32(pNonCarPosition->ID); + pNonCarPosition->flags = BrSwap16(pNonCarPosition->flags); + NetSwapMatrix34(&pNonCarPosition->mat); +} + +static void NetSwapCopInfo(tNet_message_cop_info* pCopInfo) { + pCopInfo->ID = BrSwap32(pCopInfo->ID); + pCopInfo->time = BrSwap32(pCopInfo->time); + pCopInfo->curvature = BrSwapFloat(pCopInfo->curvature); + NetSwapVector3(&pCopInfo->mat.row1); + NetSwapVector3(&pCopInfo->mat.row2); + NetSwapVector3(&pCopInfo->mat.translation); + NetSwapVector3(&pCopInfo->v); + NetSwapVector3(&pCopInfo->omega); + for (int i = 0; i < 4; i++) { + pCopInfo->d[i] = BrSwapFloat(pCopInfo->d[i]); + } +} + +static void NetSwapGameScores(tNet_message_game_scores* pGameScores) { + for (int i = 0; i < 6; i++) { + pGameScores->scores[i].played = BrSwap32(pGameScores->scores[i].played); + pGameScores->scores[i].won = BrSwap32(pGameScores->scores[i].won); + pGameScores->scores[i].score = BrSwap32(pGameScores->scores[i].score); + } +} + +static void NetSwapOilSpill(tNet_message_oil_spill* pOilSpill) { + pOilSpill->player = BrSwap32(pOilSpill->player); + pOilSpill->full_size = BrSwapFloat(pOilSpill->full_size); + pOilSpill->grow_rate = BrSwapFloat(pOilSpill->grow_rate); + pOilSpill->current_size = BrSwapFloat(pOilSpill->current_size); +} + +static void NetSwapCrushPoint(tNet_message_crush_point* pCrushPoint) { + pCrushPoint->id = BrSwap32(pCrushPoint->id); + pCrushPoint->vertex = BrSwap16(pCrushPoint->vertex); + NetSwapVector3(&pCrushPoint->energy_vector); +} + +static void NetSwapContents(tNet_contents* pContents) { + switch (pContents->header.type) { + case NETMSGID_SENDMEDETAILS: // 0x00, + break; + case NETMSGID_DETAILS: // 0x01, + NetSwapGameDetails(&pContents->data.details.details); + break; + case NETMSGID_JOIN: // 0x02, + NetSwapJoin(&pContents->data.join); + break; + case NETMSGID_NEWPLAYERLIST: // 0x03, + NetSwapPlayerList(&pContents->data.player_list); + break; + case NETMSGID_GUARANTEEREPLY: // 0x04, + NetSwapGuaranteeReply(&pContents->data.reply); + break; + case NETMSGID_CARDETAILSREQ: // 0x05, + break; + case NETMSGID_CARDETAILS: // 0x06, + NetSwapCarDetails(&pContents->data.car_details); + break; + case NETMSGID_LEAVE: // 0x07, + break; + case NETMSGID_HOSTICIDE: // 0x08, + break; + case NETMSGID_RACEOVER: // 0x09, + NetSwapRaceOver(&pContents->data.race_over); + break; + case NETMSGID_STATUSREPORT: // 0x0a, + NetSwapStatusReport(&pContents->data.report); + break; + case NETMSGID_STARTRACE: // 0x0b, + NetSwapStartRace(&pContents->data.start_race); + break; + case NETMSGID_HEADUP: // 0x0c, + break; + case NETMSGID_HOSTQUERY: // 0x0d, + break; + case NETMSGID_HOSTREPLY: // 0x0e, + NetSwapHostReply(&pContents->data.heres_where_we_at); + break; + case NETMSGID_MECHANICS: // 0x0f, + NetSwapMechanics(&pContents->data.mech); + break; + case NETMSGID_NONCAR_INFO: // 0x10, + NetSwapNonCar(&pContents->data.non_car); + break; + case NETMSGID_TIMESYNC: // 0x11, + NetSwapTimeSync(&pContents->data.time_sync); + break; + case NETMSGID_CONFIRM: // 0x12, + NetSwapConfirm(&pContents->data.confirm); + break; + case NETMSGID_DISABLECAR: // 0x13, + break; + case NETMSGID_ENABLECAR: // 0x14, + break; + case NETMSGID_POWERUP: // 0x15, + NetSwapPowerup(&pContents->data.powerup); + break; + case NETMSGID_RECOVER: // 0x16, + NetSwapRecover(&pContents->data.recover); + break; + case NETMSGID_SCORES: // 0x17, + NetSwapScores(&pContents->data.scores); + break; + case NETMSGID_WASTED: // 0x18, + NetSwapWasted(&pContents->data.wasted); + break; + case NETMSGID_PEDESTRIAN: // 0x19, + NetSwapPedestrian(&pContents->data.pedestrian); + break; + case NETMSGID_GAMEPLAY: // 0x1a, + NetSwapGameplay(&pContents->data.gameplay); + break; + case NETMSGID_NONCARPOSITION: // 0x1b, + NetSwapNonCarPosition(&pContents->data.non_car_position); + break; + case NETMSGID_COPINFO: // 0x1c, + NetSwapCopInfo(&pContents->data.cop_info); + break; + case NETMSGID_GAMESCORES: // 0x1d, + NetSwapGameScores(&pContents->data.game_scores); + break; + case NETMSGID_OILSPILL: // 0x1e, + NetSwapOilSpill(&pContents->data.oil_spill); + break; + case NETMSGID_CRUSHPOINT: // 0x1f, + NetSwapCrushPoint(&pContents->data.crush); + break; + } +} + +static void NetSwapMessageAndContents(tNet_message* pMessage) { + tNet_contents* contents; + int i; + + contents = &pMessage->contents; + for (i = 0; i < pMessage->num_contents; i++) { + NetSwapContents(contents); + contents = (tNet_contents*)((tU8*)contents + contents->header.contents_size); + } + NetSwapMessage(pMessage); +} + +#else + +#define NetSwapMessage(a) +#define NetSwapContents(a) +#define NetSwapMessageAndContents(a) + +#endif // BR_ENDIAN_BIG + +#endif // NETWORK_ENDIAN_H From 9e9b6cb8bde85ce7d9a7fce415b2c87a24e3eedb Mon Sep 17 00:00:00 2001 From: BSzili Date: Tue, 6 Jan 2026 07:51:18 +0100 Subject: [PATCH 3/4] Don't include network_endian.h if BR_ENDIAN_BIG is not 1 --- src/DETHRACE/common/network.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index 6c237f80..2838dfd7 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -26,7 +26,9 @@ #include "structur.h" #include "utility.h" #include "world.h" +#if BR_ENDIAN_BIG #include "network_endian.h" +#endif #include tU32 gMess_max_flags; From 4af9cba997c114dd0aefd7f462219b23ff0495f7 Mon Sep 17 00:00:00 2001 From: BSzili Date: Tue, 6 Jan 2026 18:18:00 +0100 Subject: [PATCH 4/4] Fix the BR_ENDIAN_BIG macro guard in network_endian.h --- src/DETHRACE/common/network.c | 2 -- src/DETHRACE/common/network_endian.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index 2838dfd7..6c237f80 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -26,9 +26,7 @@ #include "structur.h" #include "utility.h" #include "world.h" -#if BR_ENDIAN_BIG #include "network_endian.h" -#endif #include tU32 gMess_max_flags; diff --git a/src/DETHRACE/common/network_endian.h b/src/DETHRACE/common/network_endian.h index 4365d5e7..7452cb80 100644 --- a/src/DETHRACE/common/network_endian.h +++ b/src/DETHRACE/common/network_endian.h @@ -1,7 +1,7 @@ #ifndef NETWORK_ENDIAN_H #define NETWORK_ENDIAN_H -#ifdef BR_ENDIAN_BIG +#if BR_ENDIAN_BIG #include "dr_types.h"