This commit is contained in:
Dethrace Labs 2025-05-05 09:56:35 +12:00
parent c8a050bd66
commit dcf3cfdd89
3 changed files with 44 additions and 129 deletions

View File

@ -1,7 +1,11 @@
#ifndef PC_ALL_NET_TYPES_H
#define PC_ALL_NET_TYPES_H
// dethrace: have switched out IPX implementation for IP
#include <stdint.h>
// This file added dethrace
// - have switched out IPX implementation for IP
// - cross-platform instead of per-platform implementation
// cannot be a regular sockaddr_in because it is transmitted between OS's
typedef struct tCopyable_sockaddr_in {
@ -10,25 +14,17 @@ typedef struct tCopyable_sockaddr_in {
} tCopyable_sockaddr_in;
typedef struct tPD_net_player_info {
// struct sockaddr_ipx addr_ipx;
// cannot be a regular sockaddr_in because it is transmitted between machines
// cannot be a regular sockaddr_in because it is transmitted between OS's
tCopyable_sockaddr_in addr_in;
// added by dethrace
// tU32 pad0;
} tPD_net_player_info;
// has to match `tPD_net_player_info`
// has to match `tPD_net_player_info` - see `PDNetGetNextJoinGame`
typedef struct tPD_net_game_info {
// struct sockaddr_ipx addr_ipx;
// cannot be a regular sockaddr_in because it is transmitted between machines
// cannot be a regular sockaddr_in because it is transmitted between OS's
tCopyable_sockaddr_in addr_in;
uint32_t last_response;
} tPD_net_game_info;
// typedef struct tIPX_netnum {
// unsigned char bNetwork[4];
// } tIPX_netnum;
#endif

View File

@ -8,7 +8,6 @@
#include "globvrpb.h"
#include "harness/config.h"
#include "harness/hooks.h"
#include "harness/os.h"
#include "harness/trace.h"
#include "harness/winsock.h"
#include "network.h"
@ -24,17 +23,17 @@ tU32 gNetwork_init_flags;
tPD_net_game_info* gJoinable_games;
int gMatts_PC;
tU16 gSocket_number_pd_format;
// _IPX_ELEMENT gListen_elements[16];
//_IPX_ELEMENT gListen_elements[16];
char gLocal_ipx_addr_string[32];
//_IPX_ELEMENT gSend_elements[16];
// struct sockaddr_in* gLocal_addr_ipx;
struct sockaddr_in* gLocal_addr_ipx;
char gReceive_buffer[512];
tPD_net_player_info gRemote_net_player_info;
// struct sockaddr_in* gBroadcast_addr_ipx;
struct sockaddr_in* gBroadcast_addr_ipx;
tPD_net_player_info gLocal_net_player_info;
char gSend_buffer[512];
tIPX_netnum gNetworks[16];
// struct sockaddr_in* gRemote_addr_ipx;
struct sockaddr_in* gRemote_addr_ipx;
tU8* gSend_packet;
// W32 gListen_segment;
tU8* gSend_packet_ptr;
@ -50,22 +49,14 @@ tU16 gSocket_number_network_order;
tU16 gListen_selector;
tU16 gSend_selector;
// Added by dethrace
struct sockaddr_in gAny_addr;
struct sockaddr_in gLocal_addr;
struct sockaddr_in gRemote_addr;
struct sockaddr_in gBroadcast_addr;
struct sockaddr_in gLast_received_addr;
tCopyable_sockaddr_in gLocal_addr_copyable;
tCopyable_sockaddr_in gLast_received_addr_copyable;
int gSocket;
int gPlayer_id;
#define MESSAGE_HEADER_STR "CW95MSG"
#define JOINABLE_GAMES_CAPACITY 16
#define PORT 12286
DR_STATIC_ASSERT(offsetof(tNet_message, pd_stuff_so_DO_NOT_USE) == 0);
DR_STATIC_ASSERT(offsetof(tNet_message, magic_number) == 4);
@ -124,17 +115,6 @@ void NetNowIPXLocalTarget2String(char* pString, struct sockaddr_in* pSock_addr_i
strcat(pString, portbuf);
}
// added by dethrace
void NetNowIPXLocalTarget2String2(char* pString, tCopyable_sockaddr_in* pSock_addr_ipx) {
LOG_TRACE("(\"%s\", %p)", pString, pSock_addr_ipx);
char portbuf[10];
inet_ntop(AF_INET, &pSock_addr_ipx->address, pString, 32);
sprintf(portbuf, ":%d", ntohs(pSock_addr_ipx->port));
strcat(pString, portbuf);
}
// IDA: int __usercall GetMessageTypeFromMessage@<EAX>(char *pMessage_str@<EAX>)
int GetMessageTypeFromMessage(char* pMessage_str) {
char* real_msg;
@ -162,13 +142,6 @@ int SameEthernetAddress(struct sockaddr_in* pAddr_ipx1, struct sockaddr_in* pAdd
return memcmp(pAddr_ipx1, pAddr_ipx2, sizeof(struct sockaddr_in)) == 0;
}
// added by dethrace
int SameEthernetAddress2(tCopyable_sockaddr_in* pAddr_ipx1, struct sockaddr_in* pAddr_ipx2) {
LOG_TRACE("(%p, %p)", pAddr_ipx1, pAddr_ipx2);
return pAddr_ipx1->port == pAddr_ipx2->sin_port && pAddr_ipx1->address == pAddr_ipx2->sin_addr.s_addr;
}
/*SOCKADDR_IPX_* */ void* GetIPXAddrFromPlayerID(tPlayer_ID pPlayer_id) {
int i;
tU8* nodenum;
@ -202,10 +175,10 @@ int ReceiveHostResponses(void) {
if (recvfrom(gSocket, gReceive_buffer, sizeof(gReceive_buffer), 0, (struct sockaddr*)&gRemote_addr, &sa_len) == -1) {
break;
}
NetNowIPXLocalTarget2String(addr_string, &gRemote_addr);
NetNowIPXLocalTarget2String(addr_string, gRemote_addr_ipx);
dr_dprintf("ReceiveHostResponses(): Received string '%s' from %s", gReceive_buffer, addr_string);
if (SameEthernetAddress(&gLocal_addr, &gRemote_addr)) {
if (SameEthernetAddress(gLocal_addr_ipx, gRemote_addr_ipx)) {
dr_dprintf("*** Discounting the above 'cos we sent it ***");
continue;
}
@ -217,7 +190,7 @@ int ReceiveHostResponses(void) {
dr_dprintf("*** It's a host reply! ***");
already_registered = 0;
for (i = 0; i < gNumber_of_hosts; i++) {
if (SameEthernetAddress2(&gJoinable_games[i].addr_in, &gRemote_addr)) {
if (SameEthernetAddress(&gJoinable_games[i].addr_in, gRemote_addr_ipx)) {
already_registered = 1;
break;
}
@ -227,7 +200,7 @@ int ReceiveHostResponses(void) {
gJoinable_games[i].last_response = PDGetTotalTime();
} else {
dr_dprintf("Adding joinable game to slot #%d", gNumber_of_hosts);
PDNetCopyFromNative(&gJoinable_games[gNumber_of_hosts].addr_in, &gRemote_addr);
gJoinable_games[gNumber_of_hosts].addr_in = *gRemote_addr_ipx;
gJoinable_games[gNumber_of_hosts].last_response = PDGetTotalTime();
gNumber_of_hosts++;
dr_dprintf("Number of games found so far: %d", gNumber_of_hosts);
@ -235,7 +208,7 @@ int ReceiveHostResponses(void) {
if (gNumber_of_hosts) {
dr_dprintf("Currently registered net games:");
for (i = 0; i < gNumber_of_hosts; i++) {
NetNowIPXLocalTarget2String2(str, &gJoinable_games[i].addr_in);
NetNowIPXLocalTarget2String(str, &gJoinable_games[i].addr_in);
dr_dprintf("%d: Host addr %s", i, str);
}
}
@ -259,7 +232,7 @@ int BroadcastMessage(void) {
errors = 0;
for (i = 0; i < gNumber_of_networks; i++) {
//*(_DWORD*)gBroadcast_addr_ipx->sa_netnum = gNetworks[i];
NetNowIPXLocalTarget2String(broadcast_addr_string, &gBroadcast_addr);
NetNowIPXLocalTarget2String(broadcast_addr_string, gBroadcast_addr_ipx);
dr_dprintf("Broadcasting on address '%s'", broadcast_addr_string);
if (sendto(gSocket, gSend_buffer, strlen(gSend_buffer) + 1, 0, (struct sockaddr*)&gBroadcast_addr, sizeof(gBroadcast_addr)) == -1) {
dr_dprintf("BroadcastMessage(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
@ -285,10 +258,9 @@ int PDNetInitialise(void) {
WSADATA wsadata;
LOG_TRACE("()");
gPlayer_id = PDGetTotalTime();
sa_len = sizeof(struct sockaddr_in);
dr_dprintf("PDNetInitialise()");
int ipx_socket_num = PORT;
int ipx_socket_num = 12286;
// Dont bother to handle network.ini
// if (gWin32_should_load_network_ini) {
// if (GetPrivateProfileStringA(
@ -307,10 +279,12 @@ int PDNetInitialise(void) {
// }
// }
// }
memset(&gAny_addr, 0, sizeof(gAny_addr));
memset(&gLocal_addr, 0, sizeof(gLocal_addr));
memset(&gRemote_addr, 0, sizeof(gRemote_addr));
memset(&gBroadcast_addr, 0, sizeof(gBroadcast_addr));
gLocal_addr_ipx = &gLocal_addr;
gRemote_addr_ipx = &gRemote_addr;
gBroadcast_addr_ipx = &gBroadcast_addr;
memset(&gLocal_addr, 0, sizeof(struct sockaddr_in));
memset(&gRemote_addr, 0, sizeof(struct sockaddr_in));
memset(&gBroadcast_addr, 0, sizeof(struct sockaddr_in));
// gLocal_addr_ipx->sa_family = AF_IPX;
// gRemote_addr_ipx->sa_family = AF_IPX;
@ -327,34 +301,13 @@ int PDNetInitialise(void) {
// gBroadcast_addr_ipx->sa_nodenum[4] = -1;
// gBroadcast_addr_ipx->sa_nodenum[5] = -1;
gAny_addr.sin_family = AF_INET;
gAny_addr.sin_addr.s_addr = INADDR_ANY;
gAny_addr.sin_port = htons(PORT);
int found = OS_GetAdapterAddress(harness_game_config.network_adapter_name, &gLocal_addr);
if (!found) {
gLocal_addr.sin_addr.s_addr = INADDR_LOOPBACK;
}
gLocal_addr.sin_port = htons(PORT);
// advertise that we are connectable on this address
PDNetCopyFromNative(&gLocal_addr_copyable, &gLocal_addr);
NetNowIPXLocalTarget2String(str, &gLocal_addr);
LOG_INFO("Advertising on %s", str);
// actually listen on any address
gLocal_addr.sin_family = AF_INET;
gLocal_addr.sin_port = htons(12286);
gLocal_addr.sin_addr.s_addr = INADDR_ANY;
NetNowIPXLocalTarget2String(str, &gLocal_addr);
LOG_INFO("Listening on %s", str);
gRemote_addr.sin_family = AF_INET;
gRemote_addr.sin_port = htons(PORT);
gRemote_addr.sin_port = htons(12286);
gBroadcast_addr.sin_family = AF_INET;
gBroadcast_addr.sin_port = htons(PORT);
gBroadcast_addr.sin_addr.s_addr = INADDR_BROADCAST;
gBroadcast_addr.sin_port = htons(12286);
// original code was using MAKEWORD(1, 1)
if (WSAStartup(MAKEWORD(2, 2), &wsadata) == -1) {
@ -362,6 +315,7 @@ int PDNetInitialise(void) {
return -1;
}
// gSocket = socket(6, 2, 1000);
gSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (gSocket == -1) {
dr_dprintf("PDNetInitialise(): Failed to create socket - WSAGetLastError=%d", WSAGetLastError());
@ -383,7 +337,7 @@ int PDNetInitialise(void) {
}
if (harness_game_config.no_bind == 0) {
if (bind(gSocket, (struct sockaddr*)&gAny_addr, sizeof(gAny_addr)) == -1) {
if (bind(gSocket, (struct sockaddr*)&gLocal_addr, sizeof(gLocal_addr)) == -1) {
dr_dprintf("Error on bind() - WSAGetLastError=%d", WSAGetLastError());
closesocket(gSocket);
WSACleanup();
@ -391,9 +345,8 @@ int PDNetInitialise(void) {
}
}
// int res = getsockname(gSocket, (struct sockaddr*)&gLocal_addr, &sa_len);
NetNowIPXLocalTarget2String(gLocal_ipx_addr_string, &gLocal_addr);
int res = getsockname(gSocket, (struct sockaddr*)&gLocal_addr, &sa_len);
NetNowIPXLocalTarget2String(gLocal_ipx_addr_string, gLocal_addr_ipx);
// gNetworks[0] = *(tIPX_netnum*)gLocal_addr_ipx->sa_netnum;
gNumber_of_networks = 1;
@ -510,8 +463,7 @@ int PDNetGetNextJoinGame(tNet_game_details* pGame, int pIndex) {
return 0;
}
dr_dprintf("PDNetGetNextJoinGame(): Adding game.");
// danger: copying a tPD_net_game_info into a tPD_net_player_info
pGame->pd_net_info = *(tPD_net_player_info*)&gJoinable_games[pIndex];
memcpy(&pGame->pd_net_info.addr_in, &gJoinable_games[pIndex].addr_in, sizeof(pGame->pd_net_info.addr_in));
return 1;
}
@ -526,8 +478,7 @@ int PDNetHostGame(tNet_game_details* pDetails, char* pHost_name, void** pHost_ad
LOG_TRACE("(%p, \"%s\", %p)", pDetails, pHost_name, pHost_address);
dr_dprintf("PDNetHostGame()");
//*pHost_address = &gLocal_addr;
*pHost_address = &gLocal_addr_copyable;
*pHost_address = &gLocal_addr;
return 1;
}
@ -558,9 +509,7 @@ tU32 PDNetExtractGameID(tNet_game_details* pDetails) {
LOG_TRACE("(%p)", pDetails);
dr_dprintf("PDNetExtractGameID()");
// dethrace changed
// return ntohs(gLocal_addr.sin_addr.s_addr);
return gPlayer_id;
return ntohs(pDetails->pd_net_info.addr_in.sin_port); // PDGetTotalTime();
}
// IDA: tPlayer_ID __usercall PDNetExtractPlayerID@<EAX>(tNet_game_details *pDetails@<EAX>)
@ -568,9 +517,7 @@ tPlayer_ID PDNetExtractPlayerID(tNet_game_details* pDetails) {
LOG_TRACE("(%p)", pDetails);
dr_dprintf("PDNetExtractPlayerID()");
// dethrace changed
// return ntohs(gLocal_addr.sin_addr.s_addr);
return gPlayer_id;
return ntohs(gLocal_addr_ipx->sin_port);
}
// IDA: void __usercall PDNetObtainSystemUserName(char *pName@<EAX>, int pMax_length@<EDX>)
@ -606,17 +553,11 @@ int PDNetSendMessageToAllPlayers(tNet_game_details* pDetails, tNet_message* pMes
int i;
LOG_TRACE("(%p, %p)", pDetails, pMessage);
struct sockaddr_in someaddr;
for (i = 0; i < gNumber_of_net_players; ++i) {
if (i == gThis_net_player_index) {
continue;
}
PDNetCopyToNative(&someaddr, &gNet_players[i].pd_net_info.addr_in);
NetNowIPXLocalTarget2String(str, &someaddr);
LOG_DEBUG(str);
if (sendto(gSocket, (const char*)pMessage, pMessage->overall_size, 0, (struct sockaddr*)&someaddr, sizeof(someaddr)) == -1) {
if (sendto(gSocket, (const char*)pMessage, pMessage->overall_size, 0, (struct sockaddr*)&gNet_players[i].pd_net_info.addr_in, sizeof(gNet_players[i].pd_net_info.addr_in)) == -1) {
dr_dprintf("PDNetSendMessageToAllPlayers(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
NetDisposeMessage(pDetails, pMessage);
return 1;
@ -650,8 +591,8 @@ tNet_message* PDNetGetNextMessage(tNet_game_details* pDetails, void** pSender_ad
PDFatalError(str);
}
} else {
NetNowIPXLocalTarget2String(addr_str, &gRemote_addr);
if (!SameEthernetAddress(&gLocal_addr, &gRemote_addr)) {
NetNowIPXLocalTarget2String(addr_str, gRemote_addr_ipx);
if (!SameEthernetAddress(gLocal_addr_ipx, gRemote_addr_ipx)) {
msg_type = GetMessageTypeFromMessage(receive_buffer);
switch (msg_type) {
case 1:
@ -668,12 +609,8 @@ tNet_message* PDNetGetNextMessage(tNet_game_details* pDetails, void** pSender_ad
break;
default:
dr_dprintf("PDNetGetNextMessage(): res is %d, received message type %d from '%s', passing up", res, msg->contents.header.type, addr_str);
memcpy(&gLast_received_addr, &gRemote_addr, sizeof(gLast_received_addr));
// Changed by dethrace
// *pSender_address = &gLast_received_addr;
PDNetCopyFromNative(&gLast_received_addr_copyable, &gLast_received_addr);
*pSender_address = &gLast_received_addr_copyable;
memcpy(&gLast_received_addr, gRemote_addr_ipx, sizeof(gLast_received_addr));
*pSender_address = &gLast_received_addr;
return msg;
}
}
@ -713,13 +650,10 @@ void PDNetDisposePlayer(tNet_game_player_info* pPlayer) {
int PDNetSendMessageToAddress(tNet_game_details* pDetails, tNet_message* pMessage, void* pAddress) {
char str[256];
LOG_TRACE("(%p, %p, %p)", pDetails, pMessage, pAddress);
struct sockaddr_in someaddr;
PDNetCopyToNative(&someaddr, pAddress);
NetNowIPXLocalTarget2String(str, (struct sockaddr_in*)pAddress);
NetNowIPXLocalTarget2String(str, &someaddr);
if (sendto(gSocket, (const char*)pMessage, pMessage->overall_size, 0, (struct sockaddr*)&someaddr, sizeof(someaddr)) == -1) {
if (sendto(gSocket, (const char*)pMessage, pMessage->overall_size, 0, (const struct sockaddr*)pAddress, sizeof(struct sockaddr)) == -1) {
dr_dprintf("PDNetSendMessageToAddress(): Error on sendto() - WSAGetLastError=%d", WSAGetLastError());
NetDisposeMessage(pDetails, pMessage);
return 1;
@ -742,15 +676,4 @@ int PDNetGetHeaderSize(void) {
return 0;
}
void PDNetCopyFromNative(tCopyable_sockaddr_in* pAddress, struct sockaddr_in* sock) {
pAddress->port = sock->sin_port;
pAddress->address = sock->sin_addr.s_addr;
}
void PDNetCopyToNative(struct sockaddr_in* sock, tCopyable_sockaddr_in* pAddress) {
sock->sin_addr.s_addr = pAddress->address;
sock->sin_port = pAddress->port;
sock->sin_family = AF_INET;
}
#endif

View File

@ -40,8 +40,6 @@ target_sources(harness PRIVATE
include/harness/trace.h
include/harness/config.h
include/harness/os.h
include/harness/win95_polyfill.h
include/harness/win95_polyfill_defs.h
include/harness/audio.h
# cameras/debug_camera.c
# cameras/debug_camera.h
@ -50,8 +48,6 @@ target_sources(harness PRIVATE
harness.c
harness.h
audio/miniaudio.c
#win95/polyfill.c
#win95/winsock.c
platforms/null.c
platforms/null.h