From 44ba0fec45dd53f2ed48336254328b14ec65a748 Mon Sep 17 00:00:00 2001 From: ZivDero Date: Wed, 2 Oct 2024 03:39:11 +0300 Subject: [PATCH] Migrate to CnCNet5UDPInterfaceClass --- src/cncnet/cncnet4/cncnet4.cpp | 413 ------------------ src/cncnet/cncnet4/cncnet4.h | 48 -- src/cncnet/cncnet4/cncnet4_globals.cpp | 55 --- src/cncnet/cncnet4/cncnet4_globals.h | 56 --- src/cncnet/cncnet4/cncnet4_hooks.cpp | 185 -------- src/cncnet/cncnet4/cncnet4_hooks.h | 31 -- src/cncnet/cncnet4/cncnet4_net.cpp | 310 ------------- src/cncnet/cncnet4/cncnet4_net.h | 84 ---- src/cncnet/cncnet5/cncnet5_globals.cpp | 44 -- src/cncnet/cncnet5/cncnet5_globals.h | 63 --- src/cncnet/cncnet5/cncnet5_hooks.cpp | 99 ----- src/cncnet/cncnet5/cncnet5_hooks.h | 31 -- src/hooker/setup_hooks.cpp | 5 - .../net}/cncnet5_wspudp.cpp | 43 +- .../cncnet5 => spawner/net}/cncnet5_wspudp.h | 15 +- src/spawner/spawner.cpp | 49 ++- src/spawner/spawner_hooks.cpp | 4 +- src/vinifera/vinifera_functions.cpp | 27 -- src/vinifera/vinifera_util.cpp | 29 +- 19 files changed, 57 insertions(+), 1534 deletions(-) delete mode 100644 src/cncnet/cncnet4/cncnet4.cpp delete mode 100644 src/cncnet/cncnet4/cncnet4.h delete mode 100644 src/cncnet/cncnet4/cncnet4_globals.cpp delete mode 100644 src/cncnet/cncnet4/cncnet4_globals.h delete mode 100644 src/cncnet/cncnet4/cncnet4_hooks.cpp delete mode 100644 src/cncnet/cncnet4/cncnet4_hooks.h delete mode 100644 src/cncnet/cncnet4/cncnet4_net.cpp delete mode 100644 src/cncnet/cncnet4/cncnet4_net.h delete mode 100644 src/cncnet/cncnet5/cncnet5_globals.cpp delete mode 100644 src/cncnet/cncnet5/cncnet5_globals.h delete mode 100644 src/cncnet/cncnet5/cncnet5_hooks.cpp delete mode 100644 src/cncnet/cncnet5/cncnet5_hooks.h rename src/{cncnet/cncnet5 => spawner/net}/cncnet5_wspudp.cpp (85%) rename src/{cncnet/cncnet5 => spawner/net}/cncnet5_wspudp.h (87%) diff --git a/src/cncnet/cncnet4/cncnet4.cpp b/src/cncnet/cncnet4/cncnet4.cpp deleted file mode 100644 index 9c6e57842..000000000 --- a/src/cncnet/cncnet4/cncnet4.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4.CPP - * - * @author CCHyper (Based on work by Toni Spets) - * - * @brief CnCNet4 replacements for low level networking API. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#include "cncnet4.h" -#include "cncnet4_net.h" -#include "cncnet4_globals.h" -#include "rawfile.h" -#include "ini.h" -#include "debughandler.h" -#include "asserthandler.h" - -#include -#include -#include -#include -#include - - -/** - * Initialises the CnCNet4 system. - */ -bool __stdcall CnCNet4::Init() -{ - RawFileClass file("SUN.INI"); - INIClass ini; - - /** - * Load the CnCNet4 settings. - */ - ini.Load(file); - if (ini.Is_Present("CnCNet4")) { - CnCNet4::IsEnabled = ini.Get_Bool("CnCNet4", "Enabled", CnCNet4::IsEnabled); - ini.Get_String("CnCNet4", "Host", CnCNet4::Host, sizeof(CnCNet4::Host)); - CnCNet4::Peer2Peer = ini.Get_Bool("CnCNet4", "P2P", CnCNet4::Peer2Peer); - CnCNet4::UseUDP = ini.Get_Bool("CnCNet4", "UDP", CnCNet4::UseUDP); - CnCNet4::Port = ini.Get_Int("CnCNet4", "Port", CnCNet4::Port); - } - - if (!CnCNet4::IsEnabled) { - - /** - * Nothing went wrong, but the CnCNet4 interface is not enabled. - */ - return true; - } - - /** - * Check to make sure the CnCNet4 DLL is not present in the directory. - */ - if (RawFileClass("wsock32.dll").Is_Available()) { - MessageBox(nullptr, "File conflict detected!\nPlease remove WSOCK32.DLL from the game directory!", "Vinifera", MB_OK|MB_ICONEXCLAMATION); - return false; - } - if (RawFileClass("cncnet.dll").Is_Available()) { - MessageBox(nullptr, "File conflict detected!\nPlease remove CNCNET.DLL from the game directory!", "Vinifera", MB_OK|MB_ICONEXCLAMATION); - return false; - } - - int s = net_init(); - net_opt_reuse(); - - DEBUG_INFO("CnCNet4: Initialising...\n"); - - if (CnCNet4::Port < 1024 || CnCNet4::Port > 65534) { - CnCNet4::Port = 9001; - } - - DEBUG_INFO("CnCNet4: Broadcasting to \"%s:%d\".\n", CnCNet4::Host, CnCNet4::Port); - - CnCNet4::IsDedicated = true; - - if (!net_address(&CnCNet4::Server, CnCNet4::Host, CnCNet4::Port)) { - return false; - } - - if (CnCNet4::Peer2Peer) { - - /** - * Test P2P. - */ - bool pass = false; - - fd_set rfds; - struct timeval tv; - struct sockaddr_in to; - struct sockaddr_in from; - int start = time(nullptr); - - net_write_int8(CMD_TESTP2P); - net_write_int32(start); - - while (time(nullptr) < start + 5) { - - net_send_noflush(&to); - - FD_ZERO(&rfds); - FD_SET(s, &rfds); - tv.tv_sec = 1; - tv.tv_usec = 0; - - if (select(s + 1, &rfds, NULL, NULL, &tv) > -1) { - if (FD_ISSET(s, &rfds)) { - net_recv(&from); - - if (net_read_int8() == CMD_TESTP2P && net_read_int32() == start) { - pass = true; - break; - } - } - } - } - - /** - * Enable P2P if passed. - */ - if (pass) { - DEBUG_INFO("CnCNet4: Peer-to-peer test passed.\n"); - DEBUG_INFO("CnCNet4: Peer-to-peer is enabled.\n"); - net_bind("0.0.0.0", 8054); - - } else { - DEBUG_WARNING("CnCNet4: Peer-to-peer test failed!\n"); - //return false; - } - - } - - return true; -} - - - -/** - * Shutdown the CnCNet4 system. - */ -void __stdcall CnCNet4::Shutdown() -{ - net_free(); -} - - -SOCKET __stdcall CnCNet4::socket(int af, int type, int protocol) -{ -#ifndef NDEBUG - DEV_DEBUG_INFO("CnCNet4: socket(af=%08X, type=%08X, protocol=%08X)\n", af, type, protocol); -#endif - - if (af == AF_IPX) { - return net_socket; - } - - return ::socket(af, type, protocol); -} - - -int __stdcall CnCNet4::bind(SOCKET s, const struct sockaddr *name, int namelen) -{ -#ifndef NDEBUG - DEV_DEBUG_INFO("CnCNet4: bind(s=%d, name=%p, namelen=%d)\n", s, name, namelen); -#endif - - if (s == net_socket) { - return 0; - } - - return ::bind(s, name, namelen); -} - - -int __stdcall CnCNet4::recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen) -{ -#ifndef NDEBUG - //DEV_DEBUG_INFO("CnCNet4: recvfrom(s=%d, buf=%p, len=%d, flags=%08X, from=%p, fromlen=%p (%d))\n", s, buf, len, flags, from, fromlen, *fromlen); -#endif - - if (s == net_socket) { - int ret; - struct sockaddr_in from_in; - - ret = net_recv(&from_in); - - if (ret > 0) { - - if (CnCNet4::IsDedicated) { - - if (from_in.sin_addr.s_addr == CnCNet4::Server.sin_addr.s_addr && from_in.sin_port == CnCNet4::Server.sin_port) { - uint8_t cmd = net_read_int8(); - - /** - * Handle keepalive packets from server, very special case. - */ - if (cmd == CMD_PING) { - net_write_int8(CMD_PING); - net_write_int32(net_read_int32()); - net_send(&from_in); - - /** - * #FIXME: returning 0 means disconnected - */ - return 0; - } - - /** - * P2p flag. - */ - from_in.sin_zero[0] = cmd; - - from_in.sin_addr.s_addr = net_read_int32(); - from_in.sin_port = net_read_int16(); - - } else if (CnCNet4::Peer2Peer) { - /** - * P2p flag for direct packets. - */ - from_in.sin_zero[0] = 1; - - } else { - /** - * Discard p2p packets if not in p2p mode. - * #FIXME: returning 0 means disconnected - */ - return 0; - } - - /** - * Force p2p port. - */ - if (from_in.sin_zero[0]) { - from_in.sin_port = htons(8054); - } - - in2ipx(&from_in, (struct sockaddr_ipx *)from); - - } else { - in2ipx(&from_in, (struct sockaddr_ipx *)from); - } - - ret = net_read_data((void *)buf, len); - } - - return ret; - } - - return ::recvfrom(s, buf, len, flags, from, fromlen); -} - - -int __stdcall CnCNet4::sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen) -{ -#ifndef NDEBUG - //DEV_DEBUG_INFO("CnCNet4: sendto(s=%d, buf=%p, len=%d, flags=%08X, to=%p, tolen=%d)\n", s, buf, len, flags, to, tolen); -#endif - - if (to->sa_family == AF_IPX) { - struct sockaddr_in to_in; - - if (CnCNet4::IsDedicated) { - - if (is_ipx_broadcast((struct sockaddr_ipx *)to)) { - net_write_int8(CnCNet4::Peer2Peer ? 1 : 0); - net_write_int32(0xFFFFFFFF); - net_write_int16(0xFFFF); - net_write_data((void *)buf, len); - net_send(&CnCNet4::Server); - - } else { - - ipx2in((struct sockaddr_ipx *)to, &to_in); - - /** - * Use p2p only if both clients are in p2p mode. - */ - if (to_in.sin_zero[0] && CnCNet4::Peer2Peer) { - net_write_data((void *)buf, len); - net_send(&to_in); - - } else { - net_write_int8(CnCNet4::Peer2Peer ? 1 : 0); - net_write_int32(to_in.sin_addr.s_addr); - net_write_int16(to_in.sin_port); - net_write_data((void *)buf, len); - net_send(&CnCNet4::Server); - } - } - - return len; - } - - ipx2in((struct sockaddr_ipx *)to, &to_in); - net_write_data((void *)buf, len); - - /** - * Check if it's a broadcast. - */ - if (is_ipx_broadcast((struct sockaddr_ipx *)to)) { - net_send(&CnCNet4::Server); - return len; - - } else { - return net_send(&to_in); - } - } - - return ::sendto(s, buf, len, flags, to, tolen); -} - - -int __stdcall CnCNet4::getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen) -{ -#ifndef NDEBUG - DEV_DEBUG_INFO("CnCNet4: getsockopt(s=%d, level=%08X, optname=%08X, optval=%p, optlen=%p (%d))\n", s, level, optname, optval, optlen, *optlen); -#endif - - if (level == 0x3E8) { - *optval = 1; - *optlen = 1; - return 0; - } - - if (level == 0xFFFF) { - *optval = 1; - *optlen = 1; - return 0; - } - - return ::getsockopt(s, level, optname, optval, optlen); -} - - -int __stdcall CnCNet4::setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen) -{ -#ifndef NDEBUG - DEV_DEBUG_INFO("CnCNet4: setsockopt(s=%d, level=%08X, optname=%08X, optval=%p, optlen=%d)\n", s, level, optname, optval, optlen); -#endif - - if (level == 0x3E8) { - return 0; - } - if (level == 0xFFFF) { - return 0; - } - - return ::setsockopt(s, level, optname, optval, optlen); -} - - -int __stdcall CnCNet4::closesocket(SOCKET s) -{ -#ifndef NDEBUG - DEV_DEBUG_INFO("CnCNet4: closesocket(s=%d)\n", s); -#endif - - if (s == net_socket) { - if (CnCNet4::IsDedicated) { - net_write_int8(CMD_DISCONNECT); - net_send(&CnCNet4::Server); - } - return 0; - } - - return ::closesocket(s); -} - - -int __stdcall CnCNet4::getsockname(SOCKET s, struct sockaddr *name, int *namelen) -{ -#ifndef NDEBUG - DEV_DEBUG_INFO("CnCNet4: getsockname(s=%d, name=%p, namelen=%p (%d)\n", s, name, namelen, *namelen); -#endif - - if (s == net_socket) { - struct sockaddr_in name_in; - char hostname[256]; - struct hostent *he; - - gethostname(hostname, 256); - he = ::gethostbyname(hostname); - - DEBUG_INFO("getsockname: local hostname: %s\n", hostname); - - if (he) { - DEBUG_INFO("getsockname: local ip: %s\n", inet_ntoa(*(struct in_addr *)(he->h_addr_list[0]))); - name_in.sin_addr = *(struct in_addr *)(he->h_addr_list[0]); - in2ipx(&name_in, (struct sockaddr_ipx *)name); - } - } - - return ::getsockname(s, name, namelen);; -} diff --git a/src/cncnet/cncnet4/cncnet4.h b/src/cncnet/cncnet4/cncnet4.h deleted file mode 100644 index a88d95fea..000000000 --- a/src/cncnet/cncnet4/cncnet4.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4.H - * - * @author CCHyper - * - * @brief CnCNet4 replacements for low level networking API. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#pragma once - -#include -#include - - -namespace CnCNet4 { - -bool __stdcall Init(); -void __stdcall Shutdown(); - -int __stdcall bind(SOCKET s, const struct sockaddr *name, int namelen); -SOCKET __stdcall socket(int af, int type, int protocol); -int __stdcall recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen); -int __stdcall sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen); -int __stdcall getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen); -int __stdcall setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen); -int __stdcall closesocket(SOCKET s); -int __stdcall getsockname(SOCKET s, struct sockaddr *name, int *namelen); - -}; // namespace CnCNet4 diff --git a/src/cncnet/cncnet4/cncnet4_globals.cpp b/src/cncnet/cncnet4/cncnet4_globals.cpp deleted file mode 100644 index 3dca2d98d..000000000 --- a/src/cncnet/cncnet4/cncnet4_globals.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4_GLOBALS.CPP - * - * @author CCHyper - * - * @brief CnCNet4 global values. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#include "cncnet4_globals.h" -#include "cncnet4.h" - - -/** - * Is the CnCNet4 interface active? - */ -bool CnCNet4::IsEnabled = false; - -/** - * The host name (Must be running a instance of the dedicated server). - */ -char CnCNet4::Host[256] = { "server.cncnet.org" }; -unsigned CnCNet4::Port = 9001; - -/** - * Clients connect to each other rather than the server? - */ -bool CnCNet4::Peer2Peer = false; - -bool CnCNet4::IsDedicated = false; - -/** - * Use the UDP interface instead of IPX? - */ -bool CnCNet4::UseUDP = true; - -struct sockaddr_in CnCNet4::Server; diff --git a/src/cncnet/cncnet4/cncnet4_globals.h b/src/cncnet/cncnet4/cncnet4_globals.h deleted file mode 100644 index 098937913..000000000 --- a/src/cncnet/cncnet4/cncnet4_globals.h +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4_GLOBALS.H - * - * @author CCHyper - * - * @brief CnCNet4 global values. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#pragma once - -#include -#include - - -namespace CnCNet4 { - -extern bool IsEnabled; - -extern char Host[256]; -extern unsigned Port; -extern bool Peer2Peer; -extern bool IsDedicated; -extern bool UseUDP; - -extern struct sockaddr_in Server; - -}; // namespace CnCNet4 - - -int __stdcall bind_intercept(SOCKET s, const struct sockaddr *name, int namelen); -int __stdcall closesocket_intercept(SOCKET s); -int __stdcall getsockname_intercept(SOCKET s, struct sockaddr *name, int *namelen); -int __stdcall getsockopt_intercept(SOCKET s, int level, int optname, char *optval, int *optlen); -int __stdcall recvfrom_intercept(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen); -int __stdcall sendto_intercept(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen); -int __stdcall setsockopt_intercept(SOCKET s, int level, int optname, const char *optval, int optlen); -SOCKET __stdcall socket_intercept(int af, int type, int protocol); diff --git a/src/cncnet/cncnet4/cncnet4_hooks.cpp b/src/cncnet/cncnet4/cncnet4_hooks.cpp deleted file mode 100644 index b0a8e488b..000000000 --- a/src/cncnet/cncnet4/cncnet4_hooks.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4_HOOKS.CPP - * - * @author CCHyper - * - * @brief Contains the hooks for the CnCNet4 system. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#include "cncnet4_hooks.h" -#include "cncnet4_globals.h" -#include "cncnet4.h" -#include "tibsun_globals.h" -#include "session.h" -#include "wspudp.h" -#include "wspipx.h" -#include "debughandler.h" - -#include "hooker.h" -#include "hooker_macros.h" - - -static int __stdcall bind_intercept(SOCKET s, const struct sockaddr *name, int namelen) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::bind(s, name, namelen); - } else { - return ::bind(s, name, namelen); - } -} - -static int __stdcall closesocket_intercept(SOCKET s) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::closesocket(s); - } else { - return ::closesocket(s); - } -} - -static int __stdcall getsockname_intercept(SOCKET s, struct sockaddr *name, int *namelen) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::getsockname(s, name, namelen); - } else { - return ::getsockname(s, name, namelen); - } -} - -static int __stdcall getsockopt_intercept(SOCKET s, int level, int optname, char *optval, int *optlen) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::getsockopt(s, level, optname, optval, optlen); - } else { - return ::getsockopt(s, level, optname, optval, optlen); - } -} - -static int __stdcall recvfrom_intercept(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::recvfrom(s, buf, len, flags, from, fromlen); - } else { - return ::recvfrom(s, buf, len, flags, from, fromlen); - } -} - -static int __stdcall sendto_intercept(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::sendto(s, buf, len, flags, to, tolen); - } else { - return ::sendto(s, buf, len, flags, to, tolen); - } -} - -static int __stdcall setsockopt_intercept(SOCKET s, int level, int optname, const char *optval, int optlen) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::setsockopt(s, level, optname, optval, optlen); - } else { - return ::setsockopt(s, level, optname, optval, optlen); - } -} - -static SOCKET __stdcall socket_intercept(int af, int type, int protocol) -{ - if (CnCNet4::IsEnabled) { - return CnCNet4::socket(af, type, protocol); - } else { - return ::socket(af, type, protocol); - } -} - - -/** - * #issue-504 - * - * Create the CnCNet4 UDP interface or standard UDP interface depending - * on if the CnCNet4 system has been enabled. - * - * @author: CCHyper - */ -static void CnCNet_Create_PacketTransport() -{ - bool created = false; - - if (CnCNet4::IsEnabled && CnCNet4::UseUDP) { - PacketTransport = new UDPInterfaceClass(); - if (PacketTransport) { - DEBUG_INFO("UDP PacketTransport for CnCNet4.\n"); - } - - created = (PacketTransport != nullptr); - } - - if (!created) { - PacketTransport = new IPXInterfaceClass(); - if (PacketTransport) { - DEBUG_INFO("IPX PacketTransport created.\n"); - } - } - - if (!PacketTransport) { - DEBUG_ERROR("Failed to create PacketTransport!\n"); - } -} - - -/** - * #issue-504 - * - * This patch replaces the call to the IPXInterfaceClass constructor when - * setting up the PacketTransport for network multiplayer games with - * conditional code that creates the UDPInterfaceClass when enabled. - * - * @author: CCHyper - */ -DECLARE_PATCH(_Select_Game_Network_Create_PacketTransport_Patch) -{ - Session.Type = GAME_IPX; - Session.CommProtocol = COMM_PROTOCOL_MULTI_E_COMP; - - if (!PacketTransport) { - CnCNet_Create_PacketTransport(); - } - - JMP(0x004E2698); -} - - -/** - * Main function for patching the hooks. - */ -void CnCNet4_Hooks() -{ - Patch_Jump(0x006B4D54, &bind_intercept); - Patch_Jump(0x006B4D4E, &closesocket_intercept); - //Patch_Jump(0x, &getsockname_intercept); - Patch_Jump(0x006B4D48, &getsockopt_intercept); - Patch_Jump(0x006B4D66, &recvfrom_intercept); - Patch_Jump(0x006B4D6C, &sendto_intercept); - Patch_Jump(0x006B4D60, &setsockopt_intercept); - Patch_Jump(0x006B4D5A, &socket_intercept); - - Patch_Jump(0x004E2656, &_Select_Game_Network_Create_PacketTransport_Patch); -} diff --git a/src/cncnet/cncnet4/cncnet4_hooks.h b/src/cncnet/cncnet4/cncnet4_hooks.h deleted file mode 100644 index 5dcc88fec..000000000 --- a/src/cncnet/cncnet4/cncnet4_hooks.h +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4_HOOKS.H - * - * @author CCHyper - * - * @brief Contains the hooks for the CnCNet4 system. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#pragma once - - -void CnCNet4_Hooks(); diff --git a/src/cncnet/cncnet4/cncnet4_net.cpp b/src/cncnet/cncnet4/cncnet4_net.cpp deleted file mode 100644 index c7b2f664e..000000000 --- a/src/cncnet/cncnet4/cncnet4_net.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4_NET.CPP - * - * @author CCHyper (Based on work by Toni Spets) - * - * @brief Network utility functions. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#include -#include -#include - -#include "cncnet4_net.h" - -#include "debughandler.h" -#include "asserthandler.h" - - -static struct sockaddr_in net_local; -static uint8_t net_ibuf[NET_BUF_SIZE]; -static uint8_t net_obuf[NET_BUF_SIZE]; -static uint32_t net_ipos; -static uint32_t net_ilen; -static uint32_t net_opos; -int net_socket = 0; - - -void ipx2in(struct sockaddr_ipx *from, struct sockaddr_in *to) -{ - to->sin_family = AF_INET; - std::memcpy(&to->sin_addr.s_addr, from->sa_nodenum, 4); - std::memcpy(&to->sin_port, from->sa_nodenum + 4, 2); - to->sin_zero[0] = from->sa_netnum[1]; -} - - -void in2ipx(struct sockaddr_in *from, struct sockaddr_ipx *to) -{ - to->sa_family = AF_IPX; - *(DWORD *)&to->sa_netnum = 1; - to->sa_netnum[1] = from->sin_zero[0]; - std::memcpy(to->sa_nodenum, &from->sin_addr.s_addr, 4); - std::memcpy(to->sa_nodenum + 4, &from->sin_port, 2); -} - - -bool is_ipx_broadcast(struct sockaddr_ipx *addr) -{ - unsigned char ff[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - if (std::memcmp(addr->sa_netnum, ff, 4) == 0 || std::memcmp(addr->sa_nodenum, ff, 6) == 0) { - return true; - } else { - return false; - } -} - - -int net_opt_reuse() -{ - int yes = 1; - ::setsockopt(net_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)); - return yes; -} - - -int net_opt_broadcast() -{ - int yes = 1; - ::setsockopt(net_socket, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes)); - return yes; -} - - -int net_address(struct sockaddr_in *addr, const char *host, uint16_t port) -{ - struct hostent *hent; - hent = ::gethostbyname(host); - if (!hent) { - DEBUG_ERROR("CnCNet4: gethostbyname failed!\n"); - return 0; - } - - net_address_ex(addr, *(int *)hent->h_addr_list[0], port); - return 1; -} - - -void net_address_ex(struct sockaddr_in *addr, uint32_t ip, uint16_t port) -{ - int size = sizeof(struct sockaddr_in); - std::memset(addr, 0, size); - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = ip; - addr->sin_port = htons(port); -} - - -int net_init() -{ - WSADATA wsaData; - - if (net_socket) { - net_free(); - } - - WSAStartup(0x0101, &wsaData); - - net_socket = ::socket(AF_INET, SOCK_DGRAM, 0); - net_ipos = 0; - net_opos = 0; - return net_socket; -} - - -void net_free() -{ - ::closesocket(net_socket); - WSACleanup(); - net_socket = 0; -} - - -int net_bind(const char *ip, int port) -{ - if (!net_socket) { - return 0; - } - - net_address(&net_local, ip, port); - - return ::bind(net_socket, (struct sockaddr *)&net_local, sizeof(net_local)); -} - - -uint32_t net_read_size() -{ - return net_ilen - net_ipos; -} - - -int8_t net_read_int8() -{ - int8_t tmp; - if (net_ipos + 1 > net_ilen) { - return 0; - } - std::memcpy(&tmp, net_ibuf + net_ipos, 1); - net_ipos += 1; - return tmp; -} - - -int16_t net_read_int16() -{ - int16_t tmp; - if (net_ipos + 2 > net_ilen) { - return 0; - } - std::memcpy(&tmp, net_ibuf + net_ipos, 2); - net_ipos += 2; - return tmp; -} - - -int32_t net_read_int32() -{ - int32_t tmp; - if (net_ipos + 4 > net_ilen) { - return 0; - } - std::memcpy(&tmp, net_ibuf + net_ipos, 4); - net_ipos += 4; - return tmp; -} - - -int net_read_data(void *ptr, size_t len) -{ - if (net_ipos + len > net_ilen) { - len = net_ilen - net_ipos; - } - - std::memcpy(ptr, net_ibuf + net_ipos, len); - net_ipos += len; - return len; -} - - -int net_read_string(char *str, size_t len) -{ - int i; - for (i = net_ipos; i < NET_BUF_SIZE; i++) { - if (net_ibuf[i] == '\0') { - break; - } - } - - if (len > i - net_ipos) { - len = i - net_ipos; - } - - std::memcpy(str, net_ibuf + net_ipos, len); - str[len] = '\0'; - net_ipos += len + 1; - return 0; -} - - -int net_write_int8(int8_t d) -{ - ASSERT(net_opos + 1 <= NET_BUF_SIZE); - std::memcpy(net_obuf + net_opos, &d, 1); - net_opos += 1; - return 1; -} - - -int net_write_int16(int16_t d) -{ - ASSERT(net_opos + 2 <= NET_BUF_SIZE); - int16_t tmp = d; - std::memcpy(net_obuf + net_opos, &tmp, 2); - net_opos += 2; - return 1; -} - - -int net_write_int32(int32_t d) -{ - ASSERT(net_opos + 4 <= NET_BUF_SIZE); - int32_t tmp = d; - std::memcpy(net_obuf + net_opos, &tmp, 4); - net_opos += 4; - return 1; -} - - -int net_write_data(void *ptr, size_t len) -{ - ASSERT(net_opos + len <= NET_BUF_SIZE); - std::memcpy(net_obuf + net_opos, ptr, len); - net_opos += len; - return 1; -} - - -int net_write_string(char *str) -{ - ASSERT(net_opos + strlen(str) + 1 <= NET_BUF_SIZE); - std::memcpy(net_obuf + net_opos, str, strlen(str) + 1); - net_opos += strlen(str) + 1; - return 1; -} - - -int net_write_string_int32(int32_t d) -{ - char str[32]; - std::snprintf(str, sizeof(str), "%d", d); - return net_write_string(str); -} - - -int net_recv(struct sockaddr_in *src) -{ - socklen_t l = sizeof(struct sockaddr_in); - net_ipos = 0; - net_ilen = ::recvfrom(net_socket, (char *)net_ibuf, NET_BUF_SIZE, 0, (struct sockaddr *)src, &l); - return net_ilen; -} - - -int net_send(struct sockaddr_in *dst) -{ - int ret = net_send_noflush(dst); - net_send_discard(); - return ret; -} - - -int net_send_noflush(struct sockaddr_in *dst) -{ - int ret = ::sendto(net_socket, (char *)net_obuf, net_opos, 0, (struct sockaddr *)dst, sizeof(struct sockaddr_in)); - return ret; -} - - -void net_send_discard() -{ - net_opos = 0; -} diff --git a/src/cncnet/cncnet4/cncnet4_net.h b/src/cncnet/cncnet4/cncnet4_net.h deleted file mode 100644 index 862de3391..000000000 --- a/src/cncnet/cncnet4/cncnet4_net.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET4_NET.H - * - * @author CCHyper (Based on work by Toni Spets) - * - * @brief Network utility functions. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#pragma once - -#include -#include -#include -#include - - -#define NET_BUF_SIZE 2048 - -typedef int socklen_t; - -enum { - CMD_TUNNEL, - CMD_P2P, - CMD_DISCONNECT, - CMD_PING, - CMD_QUERY, - CMD_TESTP2P -}; - - -extern int net_socket; - -void ipx2in(struct sockaddr_ipx *from, struct sockaddr_in *to); -void in2ipx(struct sockaddr_in *from, struct sockaddr_ipx *to); -bool is_ipx_broadcast(struct sockaddr_ipx *addr); - -int net_opt_reuse(); -int net_opt_broadcast(); - -int net_address(struct sockaddr_in *addr, const char *host, uint16_t port); -void net_address_ex(struct sockaddr_in *addr, uint32_t ip, uint16_t port); - -int net_init(); -void net_free(); - -int net_bind(const char *ip, int port); - -uint32_t net_read_size(); -int8_t net_read_int8(); -int16_t net_read_int16(); -int32_t net_read_int32(); -int net_read_data(void *, size_t); -int net_read_string(char *str, size_t len); - -int net_write_int8(int8_t); -int net_write_int16(int16_t); -int net_write_int32(int32_t); -int net_write_data(void *, size_t); -int net_write_string(char *str); -int net_write_string_int32(int32_t); - -int net_recv(struct sockaddr_in *); -int net_send(struct sockaddr_in *); -int net_send_noflush(struct sockaddr_in *dst); -void net_send_discard(); diff --git a/src/cncnet/cncnet5/cncnet5_globals.cpp b/src/cncnet/cncnet5/cncnet5_globals.cpp deleted file mode 100644 index b30f9fe8a..000000000 --- a/src/cncnet/cncnet5/cncnet5_globals.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET_GLOBALS.CPP - * - * @author CCHyper - * - * @brief Global values and types used for the CnCNet5 system. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#include "cncnet5_globals.h" - - -/** - * Has the CnCNet5 system been activated? - */ -bool CnCNet5::IsActive = false; - -/** - * Is the tunnel system active (set when tunnel information has been provided)? - */ -bool CnCNet5::IsTunnelActive = false; - -/** - * CnCNet5 UDP Tunnel info. - */ -CnCNet5::TunnelInfoStruct CnCNet5::TunnelInfo { -1, -1, -1, false }; diff --git a/src/cncnet/cncnet5/cncnet5_globals.h b/src/cncnet/cncnet5/cncnet5_globals.h deleted file mode 100644 index 7ad79c15e..000000000 --- a/src/cncnet/cncnet5/cncnet5_globals.h +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET_GLOBALS.H - * - * @author CCHyper - * - * @brief Global values and types used for the CnCNet5 system. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#pragma once - -#include - - -namespace CnCNet5 -{ - -typedef struct TunnelInfoStruct -{ - unsigned long ID; - unsigned long IP; - unsigned short Port; - bool PortHack; - - bool Is_Valid() const { return !(ID == -1 || IP == -1 || Port == -1); } - -} TunnelInfoStruct; - - -/** - * Has the CnCNet5 system been activated? - */ -extern bool IsActive; - -/** - * Is the tunnel system active (set when tunnel information has been provided)? - */ -extern bool IsTunnelActive; - -/** - * CnCNet5 UDP Tunnel info. - */ -extern TunnelInfoStruct TunnelInfo; - -}; diff --git a/src/cncnet/cncnet5/cncnet5_hooks.cpp b/src/cncnet/cncnet5/cncnet5_hooks.cpp deleted file mode 100644 index e4556a5d1..000000000 --- a/src/cncnet/cncnet5/cncnet5_hooks.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET5_HOOKS.CPP - * - * @author CCHyper - * - * @brief Contains the hooks for implementing the CnCNet5 system. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#include "cncnet5_hooks.h" -#include "cncnet5_globals.h" -#include "cncnet5_wspudp.h" -#include "wsproto.h" -#include "wspipx.h" -#include "wspudp.h" -#include "tibsun_globals.h" -#include "session.h" -#include "debughandler.h" -#include "asserthandler.h" -#include "hooker.h" -#include "hooker_macros.h" - - -/** - * #issue-69 - * - * Create the CnCNet5 UDP interface or standard UDP interface depending - * on if the CnCNet5 system has been enabled. - * - * @author: CCHyper - */ -static void Create_PacketTransport() -{ - if (CnCNet5::IsActive && CnCNet5::TunnelInfo.Is_Valid()) { - PacketTransport = new CnCNet5UDPInterfaceClass( - CnCNet5::TunnelInfo.ID, - CnCNet5::TunnelInfo.IP, - CnCNet5::TunnelInfo.Port, - CnCNet5::TunnelInfo.PortHack); - if (!PacketTransport) { - DEBUG_ERROR("Failed to create PacketTransport for CnCNet5!\n"); - } - - } else { - PacketTransport = new UDPInterfaceClass(); - if (!PacketTransport) { - DEBUG_ERROR("Failed to create PacketTransport!\n"); - } - } -} - - -/** - * #issue-69 - * - * This patch replaces the call to the UDPInterfaceClass constructor when - * setting up the PacketTransport for network multiplayer games with - * conditional code that creates the CnCNet5 interface is enabled. - * - * @author: CCHyper - */ -DECLARE_PATCH(_Select_Game_Create_PacketTransport_Patch) -{ - Create_PacketTransport(); - - Session.CommProtocol = COMM_PROTOCOL_SINGLE_NO_COMP; - - _asm { mov eax, [0x0074C8D8] } // PacketProtocol - _asm { mov eax, [eax] } - - JMP_REG(edx, 0x004E2436); -} - - -/** - * Main function for patching the hooks. - */ -void CnCNet5_Hooks() -{ - Patch_Jump(0x004E2406, &_Select_Game_Create_PacketTransport_Patch); -} diff --git a/src/cncnet/cncnet5/cncnet5_hooks.h b/src/cncnet/cncnet5/cncnet5_hooks.h deleted file mode 100644 index 853ea9b0c..000000000 --- a/src/cncnet/cncnet5/cncnet5_hooks.h +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* -/* O P E N S O U R C E -- V I N I F E R A ** -/******************************************************************************* - * - * @project Vinifera - * - * @file CNCNET5_HOOKS.H - * - * @author CCHyper - * - * @brief Contains the hooks for implementing the CnCNet5 system. - * - * @license Vinifera is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version - * 3 of the License, or (at your option) any later version. - * - * Vinifera is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. - * If not, see . - * - ******************************************************************************/ -#pragma once - - -void CnCNet5_Hooks(); diff --git a/src/hooker/setup_hooks.cpp b/src/hooker/setup_hooks.cpp index 2851cd6ec..81a650626 100644 --- a/src/hooker/setup_hooks.cpp +++ b/src/hooker/setup_hooks.cpp @@ -36,8 +36,6 @@ #include "vinifera_hooks.h" #include "newswizzle_hooks.h" #include "extension_hooks.h" -#include "cncnet4_hooks.h" -#include "cncnet5_hooks.h" #include "sidebarext_hooks.h" @@ -50,9 +48,6 @@ void Setup_Hooks() Vinifera_Hooks(); NewSwizzle_Hooks(); Extension_Hooks(); - - CnCNet4_Hooks(); - CnCNet5_Hooks(); } /** diff --git a/src/cncnet/cncnet5/cncnet5_wspudp.cpp b/src/spawner/net/cncnet5_wspudp.cpp similarity index 85% rename from src/cncnet/cncnet5/cncnet5_wspudp.cpp rename to src/spawner/net/cncnet5_wspudp.cpp index cc9706bff..e3cd7b992 100644 --- a/src/cncnet/cncnet5/cncnet5_wspudp.cpp +++ b/src/spawner/net/cncnet5_wspudp.cpp @@ -36,7 +36,6 @@ */ CnCNet5UDPInterfaceClass::CnCNet5UDPInterfaceClass(unsigned short id, unsigned long ip, unsigned short port, bool port_hack) : UDPInterfaceClass(), - IsEnabled(false), AddressList(), TunnelID(id), TunnelIP(ip), @@ -55,14 +54,7 @@ CnCNet5UDPInterfaceClass::CnCNet5UDPInterfaceClass(unsigned short id, unsigned l */ LRESULT CnCNet5UDPInterfaceClass::Message_Handler(HWND hWnd, UINT uMsg, UINT wParam, LONG lParam) { - /** - * If the CnCNet interface has not been enabled, just use the standard UDP interface. - */ - if (!IsEnabled) { - return UDPInterfaceClass::Message_Handler(hWnd, uMsg, wParam, lParam); - } - - struct sockaddr_in addr; + sockaddr_in addr; int rc; int addr_len; WinsockBufferType *packet; @@ -94,9 +86,9 @@ LRESULT CnCNet5UDPInterfaceClass::Message_Handler(HWND hWnd, UINT uMsg, UINT wPa * Call the CnCNet tunnel Receive_From function to get the outstanding packet. */ addr_len = sizeof(addr); - rc = CnCNet5UDPInterfaceClass::Receive_From(Socket, (char*)ReceiveBuffer, sizeof(ReceiveBuffer), 0, (PSOCKADDR_IN)&addr, &addr_len); + rc = Receive_From(Socket, reinterpret_cast(ReceiveBuffer), sizeof(ReceiveBuffer), 0, &addr, &addr_len); if (rc == SOCKET_ERROR) { - DEBUG_WARNING("CnCNet5: Send_To returned %d!\n", WSAGetLastError()); + DEBUG_WARNING("CnCNet5: Receive_From returned %d!\n", WSAGetLastError()); Clear_Socket_Error(Socket); return 0; } @@ -104,7 +96,7 @@ LRESULT CnCNet5UDPInterfaceClass::Message_Handler(HWND hWnd, UINT uMsg, UINT wPa /** * (CnCNet) Now, we need to map addr ip/port to index by reversing the search! */ - for (int i = 0; i < ARRAY_SIZE(AddressList); i++) { + for (int i = 0; i < std::size(AddressList); i++) { /** * Compare ip. @@ -143,15 +135,16 @@ LRESULT CnCNet5UDPInterfaceClass::Message_Handler(HWND hWnd, UINT uMsg, UINT wPa * Create a new buffer and store this packet in it. */ packet = Get_New_In_Buffer(); - packet->BufferLen = rc; - std::memcpy(packet->PacketData.Buffer, ReceiveBuffer, rc); + packet->BufferLen = rc - 4; + packet->PacketData.CRC = *reinterpret_cast(ReceiveBuffer); + std::memcpy(packet->PacketData.Buffer, ReceiveBuffer + 4, rc - 4); if (!Passes_CRC_Check(packet)) { DEBUG_INFO("CnCNet5: Throwing away malformed packet!\n"); Delete_In_Buffer(packet); return 0; } std::memset(packet->Address, 0, sizeof (packet->Address)); - std::memcpy(packet->Address+4, &addr.sin_addr.s_addr, 4); + std::memcpy(packet->Address + 4, &addr.sin_addr.s_addr, 4); InBuffers.Add(packet); } return 0; @@ -185,12 +178,12 @@ LRESULT CnCNet5UDPInterfaceClass::Message_Handler(HWND hWnd, UINT uMsg, UINT wPa /** * (CnCNet) pull index. */ - int i = addr.sin_addr.s_addr - 1; + const int i = *reinterpret_cast(packet->Address + 4) - 1; /** * (CnCNet) validate index. */ - if (i >= ARRAY_SIZE(AddressList) || i < 0) { + if (i >= std::size(AddressList) || i < 0) { return -1; } @@ -207,8 +200,8 @@ LRESULT CnCNet5UDPInterfaceClass::Message_Handler(HWND hWnd, UINT uMsg, UINT wPa * at this time. In this case, we clear the socket error and just exit. Winsock will * send us another WRITE message when it is ready to receive more data. */ - rc = CnCNet5UDPInterfaceClass::Send_To(Socket, (const char *)&packet->PacketData, packet->BufferLen, 0, (PSOCKADDR_IN)&addr, sizeof (addr)); - if (rc == SOCKET_ERROR){ + rc = Send_To(Socket, (const char *)&packet->PacketData, packet->BufferLen + 4, 0, (PSOCKADDR_IN)&addr, sizeof(addr)); + if (rc == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { Clear_Socket_Error(Socket); return 0; @@ -241,13 +234,13 @@ int CnCNet5UDPInterfaceClass::Send_To(SOCKET s, const char *buf, int len, int fl /** * No processing if no tunnel. */ - if (TunnelPort == -1) { + if (TunnelPort == 0) { DEBUG_WARNING("CnCNet5: TunnelPort is invalid in Send_To!\n"); return sendto(s, buf, len, flags, (const sockaddr *)dest_addr, addrlen); } #ifndef NDEBUG - //DEV_DEBUG_INFO("CnCNet5: sendto(s=%d, buf=%p, len=%d, flags=%08X, to=%p, addrlen=%d)\n", s, buf, len, flags, dest_addr, addrlen); + DEV_DEBUG_INFO("CnCNet5: sendto(s=%d, buf=%p, len=%d, flags=%08X, to=%p, addrlen=%d)\n", s, buf, len, flags, dest_addr, addrlen); #endif /** @@ -282,19 +275,19 @@ int CnCNet5UDPInterfaceClass::Receive_From(SOCKET s, char *buf, int len, int fla /** * No processing if no tunnel. */ - if (TunnelPort == -1) { + if (TunnelPort == 0) { DEBUG_WARNING("CnCNet5: TunnelPort is invalid in Recieve_From!\n"); - return recvfrom(s, buf, len, flags, (sockaddr *)src_addr, addrlen); + return recvfrom(s, buf, len, flags, reinterpret_cast(src_addr), addrlen); } #ifndef NDEBUG - //DEV_DEBUG_INFO("CnCNet5: recvfrom(s=%d, buf=%p, len=%d, flags=%08X, from=%p, addrlen=%p (%d))\n", s, buf, len, flags, src_addr, addrlen, *addrlen); + DEV_DEBUG_INFO("CnCNet5: recvfrom(s=%d, buf=%p, len=%d, flags=%08X, from=%p, addrlen=%p (%d))\n", s, buf, len, flags, src_addr, addrlen, *addrlen); #endif /** * Call recvfrom first to get the packet. */ - int ret = recvfrom(s, tempbuf, sizeof tempbuf, flags, (sockaddr *)src_addr, addrlen); + int ret = recvfrom(s, tempbuf, sizeof(tempbuf), flags, reinterpret_cast(src_addr), addrlen); /** * No processing if returning error or less than 5 bytes of data. diff --git a/src/cncnet/cncnet5/cncnet5_wspudp.h b/src/spawner/net/cncnet5_wspudp.h similarity index 87% rename from src/cncnet/cncnet5/cncnet5_wspudp.h rename to src/spawner/net/cncnet5_wspudp.h index d1e5349a8..38913038b 100644 --- a/src/cncnet/cncnet5/cncnet5_wspudp.h +++ b/src/spawner/net/cncnet5_wspudp.h @@ -31,11 +31,11 @@ #include "tibsun_defines.h" -typedef struct TunnelAddress +struct TunnelAddress { unsigned long IP; - unsigned long Port; -} TunnelAddress; + unsigned short Port; +}; /** @@ -49,7 +49,7 @@ class CnCNet5UDPInterfaceClass : public UDPInterfaceClass { public: CnCNet5UDPInterfaceClass(unsigned short id, unsigned long ip, unsigned short port, bool port_hack = false); - virtual ~CnCNet5UDPInterfaceClass() {} + virtual ~CnCNet5UDPInterfaceClass() override = default; virtual LRESULT Message_Handler(HWND hWnd, UINT uMsg, UINT wParam, LONG lParam) override; @@ -58,13 +58,6 @@ class CnCNet5UDPInterfaceClass : public UDPInterfaceClass int Receive_From(SOCKET s, char *buf, int len, int flags, sockaddr_in *src_addr, int *addrlen); public: - /** - * Should be CnCNet5 tunnel system interface be used over WinSock? - * - * @note: This should manually be set after instantiating the class. - */ - bool IsEnabled; - TunnelAddress AddressList[MAX_PLAYERS]; unsigned short TunnelID; diff --git a/src/spawner/spawner.cpp b/src/spawner/spawner.cpp index 63a7d3fb3..b84bf0d82 100644 --- a/src/spawner/spawner.cpp +++ b/src/spawner/spawner.cpp @@ -42,6 +42,7 @@ #include "wspudp.h" #include "wwmouse.h" #include "ccini.h" +#include "cncnet5_wspudp.h" #include "debughandler.h" #include "extension_globals.h" #include "gscreen.h" @@ -159,9 +160,8 @@ bool Spawner::Start_New_Scenario(const char* scenario_name) DEBUG_INFO("[Spawner] Session.IsGDI = %d\n", Session.IsGDI); // Configure Human Players - NetHack::PortHack = true; - const char max_players = Config->IsCampaign ? 1 : (char)std::size(Config->Players); - for (char player_index = 0; player_index < max_players; player_index++) + const int max_players = Config->IsCampaign ? 1 : std::size(Config->Players); + for (int player_index = 0; player_index < max_players; player_index++) { const auto player = &Config->Players[player_index]; if (!player->IsHuman) @@ -175,18 +175,6 @@ bool Spawner::Start_New_Scenario(const char* scenario_name) nodename->Player.Color = (PlayerColorType)player->Color; nodename->Player.ProcessTime = -1; nodename->Game.LastTime = 1; - - if (player_index > 0) - { - nodename->Address.NodeAddress[0] = player_index; - - const auto ip = inet_addr(player->Ip); - const auto port = htons(player->Port); - ListAddress::Array[player_index - 1].Ip = ip; - ListAddress::Array[player_index - 1].Port = port; - if (port != Config->ListenPort) - NetHack::PortHack = false; - } } Session.NumPlayers = Session.Players.Count(); @@ -256,13 +244,34 @@ bool Spawner::Load_Saved_Game(const char* save_game_name) void Spawner::Spawner_Init_Network() { - Tunnel::Id = htons(Config->TunnelId); - Tunnel::Ip = inet_addr(Config->TunnelIp); - Tunnel::Port = htons(Config->TunnelPort); + unsigned short id = htons(Config->TunnelId); + unsigned long ip = inet_addr(Config->TunnelIp); + unsigned short port = htons(Config->TunnelPort); + + const auto udp_interface = new CnCNet5UDPInterfaceClass(id, ip, port, true); + PacketTransport = udp_interface; + + PlanetWestwoodPortNumber = port ? 0 : Config->ListenPort; - PlanetWestwoodPortNumber = Tunnel::Port ? 0 : Config->ListenPort; + const char max_players = std::size(Config->Players); + + for (char player_index = 1; player_index < max_players; player_index++) + { + const auto player = &Config->Players[player_index]; + if (!player->IsHuman) + continue; + + auto& nodename = *Session.Players[player_index]; + + reinterpret_cast(&nodename.Address)->sin_addr.s_addr = player_index; + const auto ip = inet_addr(player->Ip); + const auto port = htons(player->Port); + udp_interface->AddressList[player_index - 1].IP = ip; + udp_interface->AddressList[player_index - 1].Port = port; + if (port != Config->ListenPort) + udp_interface->PortHack = false; + } - PacketTransport = new UDPInterfaceClass(); PacketTransport->Init(); PacketTransport->Open_Socket(0); PacketTransport->Start_Listening(); diff --git a/src/spawner/spawner_hooks.cpp b/src/spawner/spawner_hooks.cpp index dd96d4c91..2a8a427c4 100644 --- a/src/spawner/spawner_hooks.cpp +++ b/src/spawner/spawner_hooks.cpp @@ -110,8 +110,8 @@ void Spawner_Hooks() { Patch_Call(0x004629D1, &Spawner::Start_Game); // Main_Game Patch_Call(0x00462B8B, &Spawner::Start_Game); // Main_Game - Patch_Call(0x006A2525, &NetHack::SendTo); // NetHack - Patch_Call(0x006A25F9, &NetHack::RecvFrom); // NetHack + //Patch_Call(0x006A2525, &NetHack::SendTo); // NetHack + //Patch_Call(0x006A25F9, &NetHack::RecvFrom); // NetHack /** * The spawner allows player to jump right into a game, so no need to diff --git a/src/vinifera/vinifera_functions.cpp b/src/vinifera/vinifera_functions.cpp index c565f8cbc..8a93e2635 100644 --- a/src/vinifera/vinifera_functions.cpp +++ b/src/vinifera/vinifera_functions.cpp @@ -29,9 +29,6 @@ #include "vinifera_globals.h" #include "vinifera_newdel.h" #include "tibsun_globals.h" -#include "cncnet4.h" -#include "cncnet4_globals.h" -#include "cncnet5_globals.h" #include "rulesext.h" #include "ccfile.h" #include "ccini.h" @@ -589,30 +586,6 @@ bool Vinifera_Startup() return false; } -#if !defined(TS_CLIENT) - /** - * Initialise the CnCNet4 system. - */ - if (!CnCNet4::Init()) { - CnCNet4::IsEnabled = false; - DEBUG_WARNING("Failed to initialise CnCNet4, continuing without CnCNet4 support!\n"); - } - - /** - * Disable CnCNet4 if CnCNet5 is active, they can not co-exist. - */ - if (CnCNet4::IsEnabled && CnCNet5::IsActive) { - CnCNet4::Shutdown(); - CnCNet4::IsEnabled = false; - } -#else - /** - * Client builds can only use CnCNet5. - */ - CnCNet4::IsEnabled = false; - //CnCNet5::IsActive = true; // Enable when new Client system is implemented. -#endif - return true; } diff --git a/src/vinifera/vinifera_util.cpp b/src/vinifera/vinifera_util.cpp index 137c8fffc..d8c6c507d 100644 --- a/src/vinifera/vinifera_util.cpp +++ b/src/vinifera/vinifera_util.cpp @@ -38,7 +38,6 @@ #include "spritecollection.h" #include "filepng.h" #include "filepcx.h" -#include "cncnet4_globals.h" #include "wwfont.h" #include "msgbox.h" #include "minidump.h" @@ -61,26 +60,16 @@ const char *Vinifera_Name_String() if (_buffer[0] == '\0') { - /** - * Append the CnCNet version if enabled. - */ - char *cncnet_mode = nullptr; - if (CnCNet4::IsEnabled) { - cncnet_mode = " (CnCNet4)"; - } - char *dev_mode = nullptr; if (Vinifera_DeveloperMode) { dev_mode = " (Dev)"; } - if (!dev_mode && !cncnet_mode) { + if (!dev_mode) { std::snprintf(_buffer, sizeof(_buffer), "Vinifera"); } else { - std::snprintf(_buffer, sizeof(_buffer), "Vinifera:%s%s", - cncnet_mode != nullptr ? cncnet_mode : "", - dev_mode != nullptr ? dev_mode : ""); + std::snprintf(_buffer, sizeof(_buffer), "Vinifera:%s", dev_mode != nullptr ? dev_mode : ""); } #if defined(TS_CLIENT) @@ -164,24 +153,14 @@ const char *Vinifera_Version_String() static char _buffer[512] { '\0' }; if (_buffer[0] == '\0') { - - /** - * Append the CnCNet version if enabled. - */ - char *cncnet_mode = nullptr; - if (CnCNet4::IsEnabled) { - cncnet_mode = " (CnCNet4)"; - } #ifndef RELEASE - std::snprintf(_buffer, sizeof(_buffer), "Vinifera:%s%s - %s %s %s%s %s", - cncnet_mode != nullptr ? cncnet_mode : "", + std::snprintf(_buffer, sizeof(_buffer), "Vinifera:%s - %s %s %s%s %s", Vinifera_DeveloperMode ? " (Dev)" : "", Vinifera_Git_Branch(), Vinifera_Git_Author(), Vinifera_Git_Uncommitted_Changes() ? "~" : "", Vinifera_Git_Hash_Short(), Vinifera_Git_DateTime()); #else - std::snprintf(_buffer, sizeof(_buffer), "Vinifera:%s%s - %s%s %s", - cncnet_mode != nullptr ? cncnet_mode : "", + std::snprintf(_buffer, sizeof(_buffer), "Vinifera:%s - %s%s %s", Vinifera_DeveloperMode ? " (Dev)" : "", Vinifera_Git_Uncommitted_Changes() ? "~" : "", Vinifera_Git_Hash_Short(), Vinifera_Git_DateTime()); #endif