From 35ce538887dfae5f6ecc414b993ed73f8cd03f9c Mon Sep 17 00:00:00 2001 From: Yukita Mayako Date: Mon, 22 Feb 2016 02:00:00 -0500 Subject: [PATCH] Hopefully I didn't delete too much this time. --- src/CMakeLists.txt | 7 - src/d_net.c | 1199 -------------------------------- src/d_net.h | 60 -- src/d_netmobj.c | 32 - src/d_netmobj.h | 43 -- src/i_net.h | 154 ----- src/i_tcp.c | 1487 ---------------------------------------- src/i_tcp.h | 31 - src/sdl/CMakeLists.txt | 1 - src/sdl/i_net.c | 442 ------------ src/sdl12/i_net.c | 442 ------------ 11 files changed, 3898 deletions(-) delete mode 100644 src/d_net.c delete mode 100644 src/d_net.h delete mode 100644 src/d_netmobj.c delete mode 100644 src/d_netmobj.h delete mode 100644 src/i_net.h delete mode 100644 src/i_tcp.c delete mode 100644 src/i_tcp.h delete mode 100644 src/sdl/i_net.c delete mode 100644 src/sdl12/i_net.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1eee89b96..6da190183 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,10 +9,8 @@ set(SRB2_CORE_SOURCES console.c d_clisrv.c d_main.c - d_net.c d_netcmd.c d_netfil.c - d_netmobj.c dehacked.c f_finale.c f_wipe.c @@ -20,7 +18,6 @@ set(SRB2_CORE_SOURCES g_game.c g_input.c hu_stuff.c - i_tcp.c info.c lzf.c m_anigif.c @@ -56,10 +53,8 @@ set(SRB2_CORE_HEADERS d_clisrv.h d_event.h d_main.h - d_net.h d_netcmd.h d_netfil.h - d_netmobj.h d_player.h d_think.h d_ticcmd.h @@ -77,10 +72,8 @@ set(SRB2_CORE_HEADERS g_state.h hu_stuff.h i_joy.h - i_net.h i_sound.h i_system.h - i_tcp.h i_video.h info.h keys.h diff --git a/src/d_net.c b/src/d_net.c deleted file mode 100644 index 6f07fad52..000000000 --- a/src/d_net.c +++ /dev/null @@ -1,1199 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2014 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file d_net.c -/// \brief SRB2 network game communication and protocol, all OS independent parts. -// -/// Implement a Sliding window protocol without receiver window -/// (out of order reception) -/// This protocol uses a mix of "goback n" and "selective repeat" implementation -/// The NOTHING packet is sent when connection is idle to acknowledge packets - -#include "doomdef.h" -#include "g_game.h" -#include "i_net.h" -#include "i_system.h" -#include "m_argv.h" -#include "d_net.h" -#include "w_wad.h" -#include "d_netfil.h" -#include "d_clisrv.h" -#include "z_zone.h" -#include "i_tcp.h" - -// -// NETWORKING -// -// gametic is the tic about to be (or currently being) run - -#define FORCECLOSE 0x8000 -tic_t connectiontimeout = (15*TICRATE); - -/// \brief network packet -doomcom_t *doomcom = NULL; -/// \brief network packet data, points inside doomcom -doomdata_t *netbuffer = NULL; - -FILE *debugfile = NULL; // put some net info in a file during the game - -#define MAXREBOUND 8 -static doomdata_t reboundstore[MAXREBOUND]; -static INT16 reboundsize[MAXREBOUND]; -static INT32 rebound_head, rebound_tail; - -/// \brief bandwith of netgame -INT32 net_bandwidth; - -/// \brief max length per packet -INT16 hardware_MAXPACKETLENGTH; - -void (*I_NetGet)(void) = NULL; -void (*I_NetSend)(void) = NULL; -boolean (*I_NetCanSend)(void) = NULL; -boolean (*I_NetCanGet)(void) = NULL; -void (*I_NetCloseSocket)(void) = NULL; -void (*I_NetFreeNodenum)(INT32 nodenum) = NULL; -SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL; -boolean (*I_NetOpenSocket)(void) = NULL; -boolean (*I_Ban) (INT32 node) = NULL; -void (*I_ClearBans)(void) = NULL; -const char *(*I_GetNodeAddress) (INT32 node) = NULL; -const char *(*I_GetBanAddress) (size_t ban) = NULL; -const char *(*I_GetBanMask) (size_t ban) = NULL; -boolean (*I_SetBanAddress) (const char *address, const char *mask) = NULL; -boolean *bannednode = NULL; - - -// network stats -static tic_t statstarttic; -INT32 getbytes = 0; -INT64 sendbytes = 0; -static INT32 retransmit = 0, duppacket = 0; -static INT32 sendackpacket = 0, getackpacket = 0; -INT32 ticruned = 0, ticmiss = 0; - -// globals -INT32 getbps, sendbps; -float lostpercent, duppercent, gamelostpercent; -INT32 packetheaderlength; - -boolean Net_GetNetStat(void) -{ - const tic_t t = I_GetTime(); - static INT64 oldsendbyte = 0; - if (statstarttic+STATLENGTH <= t) - { - const tic_t df = t-statstarttic; - const INT64 newsendbyte = sendbytes - oldsendbyte; - sendbps = (INT32)(newsendbyte*TICRATE)/df; - getbps = (getbytes*TICRATE)/df; - if (sendackpacket) - lostpercent = 100.0f*(float)retransmit/(float)sendackpacket; - else - lostpercent = 0.0f; - if (getackpacket) - duppercent = 100.0f*(float)duppacket/(float)getackpacket; - else - duppercent = 0.0f; - if (ticruned) - gamelostpercent = 100.0f*(float)ticmiss/(float)ticruned; - else - gamelostpercent = 0.0f; - - ticmiss = ticruned = 0; - oldsendbyte = sendbytes; - getbytes = 0; - sendackpacket = getackpacket = duppacket = retransmit = 0; - statstarttic = t; - - return 1; - } - return 0; -} - -// ----------------------------------------------------------------- -// Some structs and functions for acknowledgement of packets -// ----------------------------------------------------------------- -#define MAXACKPACKETS 96 // minimum number of nodes -#define MAXACKTOSEND 96 -#define URGENTFREESLOTENUM 10 -#define ACKTOSENDTIMEOUT (TICRATE/11) - -#ifndef NONET -typedef struct -{ - UINT8 acknum; - UINT8 nextacknum; - UINT8 destinationnode; - tic_t senttime; - UINT16 length; - UINT16 resentnum; - union { - SINT8 raw[MAXPACKETLENGTH]; - doomdata_t data; - } pak; -} ackpak_t; -#endif - -typedef enum -{ - CLOSE = 1, // flag is set when connection is closing -} node_flags_t; - -#ifndef NONET -// table of packet that was not acknowleged can be resend (the sender window) -static ackpak_t ackpak[MAXACKPACKETS]; -#endif - -typedef struct -{ - // ack return to send (like sliding window protocol) - UINT8 firstacktosend; - - // when no consecutive packets are received we keep in mind what packets - // we already received in a queue - UINT8 acktosend_head; - UINT8 acktosend_tail; - UINT8 acktosend[MAXACKTOSEND]; - - // automatically send keep alive packet when not enough trafic - tic_t lasttimeacktosend_sent; - // detect connection lost - tic_t lasttimepacketreceived; - - // flow control: do not send too many packets with ack - UINT8 remotefirstack; - UINT8 nextacknum; - - UINT8 flags; -#ifndef NEWPING - // jacobson tcp timeout evaluation algorithm (Karn variation) - fixed_t ping; - fixed_t varping; - INT32 timeout; // computed with ping and varping -#endif -} node_t; - -static node_t nodes[MAXNETNODES]; -#ifndef NEWPING -#define PINGDEFAULT ((200*TICRATE*FRACUNIT)/1000) -#define VARPINGDEFAULT ((50*TICRATE*FRACUNIT)/1000) -#define TIMEOUT(p,v) (p+4*v+FRACUNIT/2)>>FRACBITS; -#else -#define NODETIMEOUT 14 //What the above boiled down to... -#endif - -#ifndef NONET -// return <0 if a < b (mod 256) -// 0 if a = n (mod 256) -// >0 if a > b (mod 256) -// mnemonic: to use it compare to 0: cmpack(a,b)<0 is "a < b" ... -FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b) -{ - register INT32 d = a - b; - - if (d >= 127 || d < -128) - return -d; - return d; -} - -// return a free acknum and copy netbuffer in the ackpak table -static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) -{ - node_t *node = &nodes[doomcom->remotenode]; - INT32 i, numfreeslote = 0; - - if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0) - { - DEBFILE(va("too fast %d %d\n",node->remotefirstack,node->nextacknum)); - return false; - } - - for (i = 0; i < MAXACKPACKETS; i++) - if (!ackpak[i].acknum) - { - // for low priority packet, make sure let freeslotes so urgents packets can be sent - numfreeslote++; - if (netbuffer->packettype >= PT_CANFAIL && numfreeslote < URGENTFREESLOTENUM) - continue; - - ackpak[i].acknum = node->nextacknum; - ackpak[i].nextacknum = node->nextacknum; - node->nextacknum++; - if (!node->nextacknum) - node->nextacknum++; - ackpak[i].destinationnode = (UINT8)(node - nodes); - ackpak[i].length = doomcom->datalength; - if (lowtimer) - { - // lowtime mean can't be sent now so try it soon as possible - ackpak[i].senttime = 0; - ackpak[i].resentnum = 1; - } - else - { - ackpak[i].senttime = I_GetTime(); - ackpak[i].resentnum = 0; - } - M_Memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length); - - *freeack = ackpak[i].acknum; - - sendackpacket++; // for stat - - return true; - } -#ifdef PARANOIA - CONS_Debug(DBG_NETPLAY, "No more free ackpacket\n"); -#endif - if (netbuffer->packettype < PT_CANFAIL) - I_Error("Connection lost\n"); - return false; -} - -// Get a ack to send in the queu of this node -static UINT8 GetAcktosend(INT32 node) -{ - nodes[node].lasttimeacktosend_sent = I_GetTime(); - return nodes[node].firstacktosend; -} - -static void Removeack(INT32 i) -{ - INT32 node = ackpak[i].destinationnode; -#ifndef NEWPING - fixed_t trueping = (I_GetTime() - ackpak[i].senttime)<>FRACBITS,(double)FIXED_TO_FLOAT(nodes[node].ping),(double)FIXED_TO_FLOAT(nodes[node].varping),nodes[node].timeout)); -#else - DEBFILE(va("Remove ack %d\n",ackpak[i].acknum)); -#endif - ackpak[i].acknum = 0; - if (nodes[node].flags & CLOSE) - Net_CloseConnection(node); -} - -// we have got a packet proceed the ack request and ack return -static boolean Processackpak(void) -{ - INT32 i; - boolean goodpacket = true; - node_t *node = &nodes[doomcom->remotenode]; - - // received an ack return, so remove the ack in the list - if (netbuffer->ackreturn && cmpack(node->remotefirstack, netbuffer->ackreturn) < 0) - { - node->remotefirstack = netbuffer->ackreturn; - // search the ackbuffer and free it - for (i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes - && cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0) - { - Removeack(i); - } - } - - // received a packet with ack, queue it to send the ack back - if (netbuffer->ack) - { - UINT8 ack = netbuffer->ack; - getackpacket++; - if (cmpack(ack, node->firstacktosend) <= 0) - { - DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); - duppacket++; - goodpacket = false; // discard packet (duplicate) - } - else - { - // check if it is not already in the queue - for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) - if (node->acktosend[i] == ack) - { - DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); - duppacket++; - goodpacket = false; // discard packet (duplicate) - break; - } - if (goodpacket) - { - // is a good packet so increment the acknowledge number, - // then search for a "hole" in the queue - UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); - if (!nextfirstack) - nextfirstack = 1; - - if (ack == nextfirstack) - { - UINT8 hm1; // head - 1 - boolean change = true; - - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND); - while (change) - { - change = false; - for (i = node->acktosend_tail; i != node->acktosend_head; - i = (i+1) % MAXACKTOSEND) - { - if (cmpack(node->acktosend[i], nextfirstack) <= 0) - { - if (node->acktosend[i] == nextfirstack) - { - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - change = true; - } - if (i == node->acktosend_tail) - { - node->acktosend[node->acktosend_tail] = 0; - node->acktosend_tail = (UINT8)((i+1) % MAXACKTOSEND); - } - else if (i == hm1) - { - node->acktosend[hm1] = 0; - node->acktosend_head = hm1; - hm1 = (UINT8)((hm1-1+MAXACKTOSEND) % MAXACKTOSEND); - } - } - } - } - } - else // out of order packet - { - // don't increment firsacktosend, put it in asktosend queue - // will be incremented when the nextfirstack comes (code above) - UINT8 newhead = (UINT8)((node->acktosend_head+1) % MAXACKTOSEND); - DEBFILE(va("out of order packet (%d expected)\n", nextfirstack)); - if (newhead != node->acktosend_tail) - { - node->acktosend[node->acktosend_head] = ack; - node->acktosend_head = newhead; - } - else // buffer full discard packet, sender will resend it - { // we can admit the packet but we will not detect the duplication after :( - DEBFILE("no more freeackret\n"); - goodpacket = false; - } - } - } - } - } - return goodpacket; -} -#endif - -// send special packet with only ack on it -void Net_SendAcks(INT32 node) -{ -#ifdef NONET - (void)node; -#else - netbuffer->packettype = PT_NOTHING; - M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND); - HSendPacket(node, false, 0, MAXACKTOSEND); -#endif -} - -#ifndef NONET -static void GotAcks(void) -{ - INT32 i, j; - - for (j = 0; j < MAXACKTOSEND; j++) - if (netbuffer->u.textcmd[j]) - for (i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode) - { - if (ackpak[i].acknum == netbuffer->u.textcmd[j]) - Removeack(i); - else - // nextacknum is first equal to acknum, then when receiving bigger ack - // there is big chance the packet is lost - // when resent, nextacknum = nodes[node].nextacknum - // will redo the same but with different value - if (cmpack(ackpak[i].nextacknum, netbuffer->u.textcmd[j]) <= 0 - && ackpak[i].senttime > 0) - { - ackpak[i].senttime--; // hurry up - } - } -} -#endif - -static inline void Net_ConnectionTimeout(INT32 node) -{ - // send a very special packet to self (hack the reboundstore queue) - // main code will handle it - reboundstore[rebound_head].packettype = PT_NODETIMEOUT; - reboundstore[rebound_head].ack = 0; - reboundstore[rebound_head].ackreturn = 0; - reboundstore[rebound_head].u.textcmd[0] = (UINT8)node; - reboundsize[rebound_head] = (INT16)(BASEPACKETSIZE + 1); - rebound_head = (rebound_head+1) % MAXREBOUND; - - // do not redo it quickly (if we do not close connection it is - // for a good reason!) - nodes[node].lasttimepacketreceived = I_GetTime(); -} - -// resend the data if needed -void Net_AckTicker(void) -{ -#ifndef NONET - INT32 i; - - for (i = 0; i < MAXACKPACKETS; i++) - { - const INT32 nodei = ackpak[i].destinationnode; - node_t *node = &nodes[nodei]; -#ifdef NEWPING - if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime()) -#else - if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime()) -#endif - { - if (ackpak[i].resentnum > 10 && (node->flags & CLOSE)) - { - DEBFILE(va("ack %d sent 10 times so connection is supposed lost: node %d\n", - i, nodei)); - Net_CloseConnection(nodei | FORCECLOSE); - - ackpak[i].acknum = 0; - continue; - } -#ifdef NEWPING - DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime, - NODETIMEOUT, I_GetTime())); -#else - DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime, - node->timeout, I_GetTime())); -#endif - M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length); - ackpak[i].senttime = I_GetTime(); - ackpak[i].resentnum++; - ackpak[i].nextacknum = node->nextacknum; - retransmit++; // for stat - HSendPacket((INT32)(node - nodes), false, ackpak[i].acknum, - (size_t)(ackpak[i].length - BASEPACKETSIZE)); - } - } - - for (i = 1; i < MAXNETNODES; i++) - { - // this is something like node open flag - if (nodes[i].firstacktosend) - { - // we haven't sent a packet for a long time - // acknowledge packet if needed - if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime()) - Net_SendAcks(i); - - if (!(nodes[i].flags & CLOSE) - && nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime()) - { - Net_ConnectionTimeout(i); - } - } - } -#endif -} - -// remove last packet received ack before resending the ackret -// (the higher layer doesn't have room, or something else ....) -void Net_UnAcknowledgPacket(INT32 node) -{ -#ifdef NONET - (void)node; -#else - INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND; - DEBFILE(va("UnAcknowledge node %d\n", node)); - if (!node) - return; - if (nodes[node].acktosend[hm1] == netbuffer->ack) - { - nodes[node].acktosend[hm1] = 0; - nodes[node].acktosend_head = (UINT8)hm1; - } - else if (nodes[node].firstacktosend == netbuffer->ack) - { - nodes[node].firstacktosend--; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = UINT8_MAX; - } - else - { - while (nodes[node].firstacktosend != netbuffer->ack) - { - nodes[node].acktosend_tail = (UINT8) - ((nodes[node].acktosend_tail-1+MAXACKTOSEND) % MAXACKTOSEND); - nodes[node].acktosend[nodes[node].acktosend_tail] = nodes[node].firstacktosend; - - nodes[node].firstacktosend--; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = UINT8_MAX; - } - nodes[node].firstacktosend++; - if (!nodes[node].firstacktosend) - nodes[node].firstacktosend = 1; - } -#endif -} - -boolean Net_AllAckReceived(void) -{ -#ifndef NONET - INT32 i; - - for (i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum) - return false; -#endif - - return true; -} - -// wait for all ackreturns with timeout in seconds -void Net_WaitAllAckReceived(UINT32 timeout) -{ -#ifdef NONET - (void)timeout; -#else - tic_t tictac = I_GetTime(); - timeout = tictac + timeout*NEWTICRATE; - - HGetPacket(); - while (timeout > I_GetTime() && !Net_AllAckReceived()) - { - while (tictac == I_GetTime()) - I_Sleep(); - tictac = I_GetTime(); - HGetPacket(); - Net_AckTicker(); - } -#endif -} - -static void InitNode(INT32 node) -{ - nodes[node].acktosend_head = nodes[node].acktosend_tail = 0; -#ifndef NEWPING - nodes[node].ping = PINGDEFAULT; - nodes[node].varping = VARPINGDEFAULT; - nodes[node].timeout = TIMEOUT(nodes[node].ping,nodes[node].varping); -#endif - nodes[node].firstacktosend = 0; - nodes[node].nextacknum = 1; - nodes[node].remotefirstack = 0; - nodes[node].flags = 0; -} - -static void InitAck(void) -{ - INT32 i; - -#ifndef NONET - for (i = 0; i < MAXACKPACKETS; i++) - ackpak[i].acknum = 0; -#endif - - for (i = 0; i < MAXNETNODES; i++) - InitNode(i); -} - -void Net_AbortPacketType(UINT8 packettype) -{ -#ifdef NONET - (void)packettype; -#else - INT32 i; - for (i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype - || packettype == UINT8_MAX)) - { - ackpak[i].acknum = 0; - } -#endif -} - -// ----------------------------------------------------------------- -// end of acknowledge function -// ----------------------------------------------------------------- - -// remove a node, clear all ack from this node and reset askret -void Net_CloseConnection(INT32 node) -{ -#ifdef NONET - (void)node; -#else - INT32 i; - boolean forceclose = (node & FORCECLOSE) != 0; - node &= ~FORCECLOSE; - - if (!node) - return; - - nodes[node].flags |= CLOSE; - - // try to Send ack back (two army problem) - if (GetAcktosend(node)) - { - Net_SendAcks(node); - Net_SendAcks(node); - } - - // check if we are waiting for an ack from this node - for (i = 0; i < MAXACKPACKETS; i++) - if (ackpak[i].acknum && ackpak[i].destinationnode == node) - { - if (!forceclose) - return; // connection will be closed when ack is returned - else - ackpak[i].acknum = 0; - } - - InitNode(node); - AbortSendFiles(node); - I_NetFreeNodenum(node); -#endif -} - -#ifndef NONET -// -// Checksum -// -static UINT32 NetbufferChecksum(void) -{ - UINT32 c = 0x1234567; - const INT32 l = doomcom->datalength - 4; - const UINT8 *buf = (UINT8 *)netbuffer + 4; - INT32 i; - - for (i = 0; i < l; i++, buf++) - c += (*buf) * (i+1); - - return LONG(c); -} -#endif - -#ifdef DEBUGFILE - -static void fprintfstring(char *s, size_t len) -{ - INT32 mode = 0; - size_t i; - - for (i = 0; i < len; i++) - if (s[i] < 32) - { - if (!mode) - { - fprintf(debugfile, "[%d", (UINT8)s[i]); - mode = 1; - } - else - fprintf(debugfile, ",%d", (UINT8)s[i]); - } - else - { - if (mode) - { - fprintf(debugfile, "]"); - mode = 0; - } - fprintf(debugfile, "%c", s[i]); - } - if (mode) - fprintf(debugfile, "]"); - fprintf(debugfile, "\n"); -} - -// Matches packet structure PT_ enum in d_clisrv.h -static const char *packettypename[] = -{ - "NOTHING", - "SERVERCFG", - "SERVERREFUSE", - "SERVERSHUTDOWN", - "CLIENTQUIT", - - "ASKINFO", - "SERVERINFO", - "REQUESTFILE", - "ASKINFOVIAMS" -}; - -static const char *failtypename[] = -{ - "FILEFRAGMENT", - "CLIENTJOIN", - "NODETIMEOUT", -#ifdef NEWPING - "PING" -#endif -}; - -static void DebugPrintpacket(const char *header) -{ - fprintf(debugfile, "%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n", - header, doomcom->remotenode, netbuffer->ack, netbuffer->ackreturn, doomcom->datalength, - netbuffer->packettype, netbuffer->packettype < PT_CANFAIL ? packettypename[netbuffer->packettype] : failtypename[netbuffer->packettype - PT_CANFAIL]); - - switch (netbuffer->packettype) - { - case PT_ASKINFO: - case PT_ASKINFOVIAMS: - fprintf(debugfile, " time %u\n", (tic_t)LONG(netbuffer->u.askinfo.time) ); - break; - case PT_CLIENTJOIN: - fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers, - netbuffer->u.clientcfg.mode); - break; - case PT_SERVERCFG: - fprintf(debugfile, " playerslots %d clientnode %d serverplayer %d " - "gametic %u gamestate %d gametype %d modifiedgame %d\n", - netbuffer->u.servercfg.totalslotnum, netbuffer->u.servercfg.clientnode, - netbuffer->u.servercfg.serverplayer, (UINT32)LONG(netbuffer->u.servercfg.gametic), - netbuffer->u.servercfg.gamestate, netbuffer->u.servercfg.gametype, - netbuffer->u.servercfg.modifiedgame); - break; - case PT_SERVERINFO: - fprintf(debugfile, " '%s' player %d/%d, map %s, filenum %d, time %u \n", - netbuffer->u.serverinfo.servername, netbuffer->u.serverinfo.numberofplayer, - netbuffer->u.serverinfo.maxplayer, netbuffer->u.serverinfo.mapname, - netbuffer->u.serverinfo.fileneedednum, - (UINT32)LONG(netbuffer->u.serverinfo.time)); - fprintfstring((char *)netbuffer->u.serverinfo.fileneeded, - (UINT8)((UINT8 *)netbuffer + doomcom->datalength - - (UINT8 *)netbuffer->u.serverinfo.fileneeded)); - break; - case PT_SERVERREFUSE: - fprintf(debugfile, " reason %s\n", netbuffer->u.serverrefuse.reason); - break; - case PT_FILEFRAGMENT: - fprintf(debugfile, " fileid %d datasize %d position %u\n", - netbuffer->u.filetxpak.fileid, (UINT16)SHORT(netbuffer->u.filetxpak.size), - (UINT32)LONG(netbuffer->u.filetxpak.position)); - break; - case PT_REQUESTFILE: - default: // write as a raw packet - fprintfstring((char *)netbuffer->u.textcmd, - (UINT8)((UINT8 *)netbuffer + doomcom->datalength - (UINT8 *)netbuffer->u.textcmd)); - break; - } -} -#endif - -// -// HSendPacket -// -boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength) -{ - doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE); - if (node == 0) // packet is to go back to us - { - if ((rebound_head+1) % MAXREBOUND == rebound_tail) - { -#ifdef PARANOIA - CONS_Debug(DBG_NETPLAY, "No more rebound buf\n"); -#endif - return false; - } - M_Memcpy(&reboundstore[rebound_head], netbuffer, - doomcom->datalength); - reboundsize[rebound_head] = doomcom->datalength; - rebound_head = (rebound_head+1) % MAXREBOUND; -#ifdef DEBUGFILE - if (debugfile) - { - doomcom->remotenode = (INT16)node; - DebugPrintpacket("SENDLOCAL"); - } -#endif - return true; - } - - if (!netgame) - I_Error("Tried to transmit to another node"); - -#ifdef NONET - (void)node; - (void)reliable; - (void)acknum; -#else - // do this before GetFreeAcknum because this function backup - // the current packet - doomcom->remotenode = (INT16)node; - if (doomcom->datalength <= 0) - { - DEBFILE("HSendPacket: nothing to send\n"); -#ifdef DEBUGFILE - if (debugfile) - DebugPrintpacket("TRISEND"); -#endif - return false; - } - - if (node < MAXNETNODES) // can be a broadcast - netbuffer->ackreturn = GetAcktosend(node); - else - netbuffer->ackreturn = 0; - if (reliable) - { - if (I_NetCanSend && !I_NetCanSend()) - { - if (netbuffer->packettype < PT_CANFAIL) - GetFreeAcknum(&netbuffer->ack, true); - - DEBFILE("HSendPacket: Out of bandwidth\n"); - return false; - } - else if (!GetFreeAcknum(&netbuffer->ack, false)) - return false; - } - else - netbuffer->ack = acknum; - - netbuffer->checksum = NetbufferChecksum(); - sendbytes += packetheaderlength + doomcom->datalength; // for stat - - // simulate internet :) - if (true || rand()<(INT32)RAND_MAX/5) - { -#ifdef DEBUGFILE - if (debugfile) - DebugPrintpacket("SEND"); -#endif - I_NetSend(); - } -#ifdef DEBUGFILE - else if (debugfile) - DebugPrintpacket("NOTSEND"); -#endif - -#endif // ndef NONET - - return true; -} - -// -// HGetPacket -// Returns false if no packet is waiting -// Check Datalength and checksum -// -boolean HGetPacket(void) -{ - // get a packet from self - if (rebound_tail != rebound_head) - { - M_Memcpy(netbuffer, &reboundstore[rebound_tail], reboundsize[rebound_tail]); - doomcom->datalength = reboundsize[rebound_tail]; - if (netbuffer->packettype == PT_NODETIMEOUT) - doomcom->remotenode = netbuffer->u.textcmd[0]; - else - doomcom->remotenode = 0; - - rebound_tail = (rebound_tail+1) % MAXREBOUND; -#ifdef DEBUGFILE - if (debugfile) - DebugPrintpacket("GETLOCAL"); -#endif - return true; - } - - if (!netgame) - return false; - -#ifndef NONET - - while(true) - { - I_NetGet(); - - if (doomcom->remotenode == -1) - return false; - - getbytes += packetheaderlength + doomcom->datalength; // for stat - - if (doomcom->remotenode >= MAXNETNODES) - { - DEBFILE(va("receive packet from node %d !\n", doomcom->remotenode)); - continue; - } - - nodes[doomcom->remotenode].lasttimepacketreceived = I_GetTime(); - - if (netbuffer->checksum != NetbufferChecksum()) - { - DEBFILE("Bad packet checksum\n"); - Net_CloseConnection(doomcom->remotenode); - continue; - } - -#ifdef DEBUGFILE - if (debugfile) - DebugPrintpacket("GET"); -#endif - - // proceed the ack and ackreturn field - if (!Processackpak()) - continue; // discarded (duplicated) - - // a packet with just ackreturn - if (netbuffer->packettype == PT_NOTHING) - { - GotAcks(); - continue; - } - break; - } -#endif // ndef NONET - - return true; -} - -static void Internal_Get(void) -{ - doomcom->remotenode = -1; -} - -FUNCNORETURN static ATTRNORETURN void Internal_Send(void) -{ - I_Error("Send without netgame\n"); -} - -static void Internal_FreeNodenum(INT32 nodenum) -{ - (void)nodenum; -} - -SINT8 I_NetMakeNode(const char *hostname) -{ - SINT8 newnode = -1; - if (I_NetMakeNodewPort) - { - char *localhostname = strdup(hostname); - char *t = localhostname; - const char *port; - if (!localhostname) - return newnode; - // retrieve portnum from address! - strtok(localhostname, ":"); - port = strtok(NULL, ":"); - - // remove the port in the hostname as we've it already - while ((*t != ':') && (*t != '\0')) - t++; - *t = '\0'; - - newnode = I_NetMakeNodewPort(localhostname, port); - free(localhostname); - } - return newnode; -} - -void D_SetDoomcom(void) -{ - if (doomcom) return; - doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL); - doomcom->id = DOOMCOM_ID; - doomcom->numslots = doomcom->numnodes = 1; - doomcom->gametype = 0; - doomcom->consoleplayer = 0; - doomcom->extratics = 0; -} - -// -// D_CheckNetGame -// Works out player numbers among the net participants -// -boolean D_CheckNetGame(void) -{ - boolean ret = false; - - InitAck(); - rebound_tail = rebound_head = 0; - - statstarttic = I_GetTime(); - - I_NetGet = Internal_Get; - I_NetSend = Internal_Send; - I_NetCanSend = NULL; - I_NetCloseSocket = NULL; - I_NetFreeNodenum = Internal_FreeNodenum; - I_NetMakeNodewPort = NULL; - - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - net_bandwidth = 30000; - // I_InitNetwork sets doomcom and netgame - // check and initialize the network driver - multiplayer = false; - - // only dos version with external driver will return true - netgame = I_InitNetwork(); - if (!netgame && !I_NetOpenSocket) - { - D_SetDoomcom(); - netgame = I_InitTcpNetwork(); - } - - if (netgame) - ret = true; - if (!server && netgame) - netgame = false; - server = true; // WTF? server always true??? - // no! The deault mode is server. Client is set elsewhere - // when the client executes connect command. - doomcom->ticdup = 1; - - if (M_CheckParm("-extratic")) - { - if (M_IsNextParm()) - doomcom->extratics = (INT16)atoi(M_GetNextParm()); - else - doomcom->extratics = 1; - CONS_Printf(M_GetText("Set extratics to %d\n"), doomcom->extratics); - } - - if (M_CheckParm("-bandwidth")) - { - if (M_IsNextParm()) - { - net_bandwidth = atoi(M_GetNextParm()); - if (net_bandwidth < 1000) - net_bandwidth = 1000; - if (net_bandwidth > 100000) - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - CONS_Printf(M_GetText("Network bandwidth set to %d\n"), net_bandwidth); - } - else - I_Error("usage: -bandwidth "); - } - - software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH; - if (M_CheckParm("-packetsize")) - { - if (M_IsNextParm()) - { - INT32 p = atoi(M_GetNextParm()); - if (p < 75) - p = 75; - if (p > hardware_MAXPACKETLENGTH) - p = hardware_MAXPACKETLENGTH; - software_MAXPACKETLENGTH = (UINT16)p; - } - else - I_Error("usage: -packetsize "); - } - - if (netgame) - multiplayer = true; - - if (doomcom->id != DOOMCOM_ID) - I_Error("Doomcom buffer invalid!"); - if (doomcom->numnodes > MAXNETNODES) - I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES); - - netbuffer = (doomdata_t *)(void *)&doomcom->data; - -#ifdef DEBUGFILE -#ifdef _arch_dreamcast - //debugfile = stderr; - if (debugfile) - CONS_Printf(M_GetText("debug output to: %s\n"), "STDERR"); -#else - if (M_CheckParm("-debugfile")) - { - char filename[20]; - INT32 k = doomcom->consoleplayer - 1; - if (M_IsNextParm()) - k = atoi(M_GetNextParm()) - 1; - while (!debugfile && k < MAXPLAYERS) - { - k++; - sprintf(filename, "debug%d.txt", k); - debugfile = fopen(filename, "w"); - } - if (debugfile) - CONS_Printf(M_GetText("debug output to: %s\n"), filename); - else - CONS_Alert(CONS_WARNING, M_GetText("cannot debug output to file %s!\n"), filename); - } -#endif -#endif - - D_ClientServerInit(); - - return ret; -} - -void Command_Ping_f(void) -{ -#ifndef NEWPING - if(server) - { -#endif - INT32 i; - for (i = 0; i < MAXPLAYERS;i++) - { -#ifndef NEWPING - const INT32 node = playernode[i]; - if (playeringame[i] && node != 0) - CONS_Printf(M_GetText("%.2d : %s\n %d tics, %d ms.\n"), i, player_names[i], - GetLag(node), G_TicsToMilliseconds(GetLag(node))); -#else - if (playeringame[i] && i != 0) - CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]); -#endif - } -#ifndef NEWPING - } - else - CONS_Printf(M_GetText("Only the server can use this.\n")); -#endif -} - -void D_CloseConnection(void) -{ - INT32 i; - - if (netgame) - { - // wait the ackreturn with timout of 5 Sec - Net_WaitAllAckReceived(5); - - // close all connection - for (i = 0; i < MAXNETNODES; i++) - Net_CloseConnection(i|FORCECLOSE); - - InitAck(); - - if (I_NetCloseSocket) - I_NetCloseSocket(); - - I_NetGet = Internal_Get; - I_NetSend = Internal_Send; - I_NetCanSend = NULL; - I_NetCloseSocket = NULL; - I_NetFreeNodenum = Internal_FreeNodenum; - I_NetMakeNodewPort = NULL; - netgame = false; - addedtogame = false; - } -} diff --git a/src/d_net.h b/src/d_net.h deleted file mode 100644 index 72de080d4..000000000 --- a/src/d_net.h +++ /dev/null @@ -1,60 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2014 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file d_net.h -/// \brief part of layer 4 (transport) (tp4) of the osi model -/// assure the reception of packet and proceed a checksums -/// -/// There is a data struct that stores network communication related -/// stuff, and one that defines the actual packets to be transmitted - -#ifndef __D_NET__ -#define __D_NET__ - -// Max computers in a game. -#define MAXNETNODES 32 -#define BROADCASTADDR MAXNETNODES -#define MAXSPLITSCREENPLAYERS 2 // max number of players on a single computer - -#define STATLENGTH (TICRATE*2) - -// stat of net -extern INT32 ticruned, ticmiss; -extern INT32 getbps, sendbps; -extern float lostpercent, duppercent, gamelostpercent; -extern INT32 packetheaderlength; -boolean Net_GetNetStat(void); -extern INT32 getbytes; -extern INT64 sendbytes; // realtime updated - -extern SINT8 nodetoplayer[MAXNETNODES]; -extern SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) -extern UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen -extern boolean nodeingame[MAXNETNODES]; // set false as nodes leave game - -void Net_AckTicker(void); -boolean Net_AllAckReceived(void); - -// if reliable return true if packet sent, 0 else -boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, - size_t packetlength); -boolean HGetPacket(void); -void D_SetDoomcom(void); -#ifndef NONET -void D_SaveBan(void); -#endif -boolean D_CheckNetGame(void); -void D_CloseConnection(void); -void Net_UnAcknowledgPacket(INT32 node); -void Net_CloseConnection(INT32 node); -void Net_AbortPacketType(UINT8 packettype); -void Net_SendAcks(INT32 node); -void Net_WaitAllAckReceived(UINT32 timeout); -#endif diff --git a/src/d_netmobj.c b/src/d_netmobj.c deleted file mode 100644 index 167e4044c..000000000 --- a/src/d_netmobj.c +++ /dev/null @@ -1,32 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 2015 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file d_netmobj.c -/// \brief Network handling for MObj. - -#include "d_netmobj.h" - -// Send a new mobj to clients. -void Net_AddMobj(mobj_t *mo) -{ -} - -// Send mobj updates to clients. -void Net_WriteMobj(mobj_t *mo) -{ -} - -// Spawn a new mobj from a server message. -mobj_t *Net_ReadMobj(void *p) -{ -} - -// Update mobj from server message. -void Net_UpdateMobj(mobj_t *mo, void *p) -{ -} diff --git a/src/d_netmobj.h b/src/d_netmobj.h deleted file mode 100644 index e5fde73d5..000000000 --- a/src/d_netmobj.h +++ /dev/null @@ -1,43 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 2015 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file d_netmobj.h -/// \brief Network handling for MObj. - -#ifndef __D_NETMOBJ__ -#define __D_NETMOBJ__ -/// \todo Fix NONET... - -#include "p_mobj.h" - -struct net_mobj_s -{ - UINT16 id; - - fixed_t x, y, z; - fixed_t momx, momy, momz; - fixed_t radius, height; - - angle_t angle; - spritenum_t sprite; - UINT8 sprite2; - UINT32 frame; - - INT32 tics; - state_t *state; -}; - -// Server. -void Net_AddMobj(mobj_t *mo); // Send a new mobj to clients. -void Net_WriteMobj(mobj_t *mo); // Send mobj updates to clients. - -// Client. -mobj_t *Net_ReadMobj(void *p); // Spawn a new mobj from a server message. -void Net_UpdateMobj(mobj_t *mo, void *p); // Update mobj from server message. - -#endif diff --git a/src/i_net.h b/src/i_net.h deleted file mode 100644 index 7a18ad186..000000000 --- a/src/i_net.h +++ /dev/null @@ -1,154 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2014 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file i_net.h -/// \brief System specific network interface stuff. - -#ifndef __I_NET__ -#define __I_NET__ - -#ifdef __GNUG__ -#pragma interface -#endif - -#include "doomdef.h" -#include "command.h" - -/// \brief program net id -#define DOOMCOM_ID (INT32)0x12345678l - -/// \def MAXPACKETLENGTH -/// For use in a LAN -#define MAXPACKETLENGTH 1450 -/// \def INETPACKETLENGTH -/// For use on the internet -#define INETPACKETLENGTH 1024 - -extern INT16 hardware_MAXPACKETLENGTH; -extern INT32 net_bandwidth; // in byte/s - -#if defined(_MSC_VER) -#pragma pack(1) -#endif - -typedef struct -{ - /// Supposed to be DOOMCOM_ID - INT32 id; - - /// SRB2 executes an INT32 to execute commands. - INT16 intnum; - /// Communication between SRB2 and the driver. - /// Is CMD_SEND or CMD_GET. - INT16 command; - /// Is dest for send, set by get (-1 = no packet). - INT16 remotenode; - - /// Number of bytes in doomdata to be sent - INT16 datalength; - - /// Info common to all nodes. - /// Console is always node 0. - INT16 numnodes; - /// Flag: 1 = no duplication, 2-5 = dup for slow nets. - INT16 ticdup; - /// Flag: 1 = send a backup tic in every packet. - INT16 extratics; - /// kind of game - INT16 gametype; - /// Flag: -1 = new game, 0-5 = load savegame - INT16 savegame; - /// currect map - INT16 map; - - /// Info specific to this node. - INT16 consoleplayer; - /// Number of "slots": the highest player number in use plus one. - INT16 numslots; - - /// The packet data to be sent. - char data[MAXPACKETLENGTH]; -} ATTRPACK doomcom_t; - -#if defined(_MSC_VER) -#pragma pack() -#endif - -extern doomcom_t *doomcom; - -/** \brief return packet in doomcom struct -*/ -extern void (*I_NetGet)(void); - -/** \brief ask to driver if there is data waiting -*/ -extern boolean (*I_NetCanGet)(void); - -/** \brief send packet within doomcom struct -*/ -extern void (*I_NetSend)(void); - -/** \brief ask to driver if all is ok to send data now -*/ -extern boolean (*I_NetCanSend)(void); - -/** \brief close a connection - - \param nodenum node to be closed - - \return void - - -*/ -extern void (*I_NetFreeNodenum)(INT32 nodenum); - -/** \brief open a connection with specified address - - \param address address to connect to - - \return number of node - - -*/ -extern SINT8 I_NetMakeNode(const char *address); - -/** \brief open a connection with specified address and port - - \param address address to connect to - - \param port port to connect to - - \return number of node - - -*/ -extern SINT8 (*I_NetMakeNodewPort)(const char *address, const char *port); - -/** \brief open connection -*/ -extern boolean (*I_NetOpenSocket)(void); - -/** \brief close all connections no more allow geting any packet -*/ -extern void (*I_NetCloseSocket)(void); - - -extern boolean (*I_Ban) (INT32 node); -extern void (*I_ClearBans)(void); -extern const char *(*I_GetNodeAddress) (INT32 node); -extern const char *(*I_GetBanAddress) (size_t ban); -extern const char *(*I_GetBanMask) (size_t ban); -extern boolean (*I_SetBanAddress) (const char *address,const char *mask); -extern boolean *bannednode; - -/// \brief Called by D_SRB2Main to be defined by extern network driver -boolean I_InitNetwork(void); - -#endif diff --git a/src/i_tcp.c b/src/i_tcp.c deleted file mode 100644 index ba2f814ec..000000000 --- a/src/i_tcp.c +++ /dev/null @@ -1,1487 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2014 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file i_tcp.c -/// \brief TCP driver, socket code. -/// This is not really OS-dependent because all OSes have the same socket API. -/// Just use ifdef for OS-dependent parts. - -#include -#include -#include -#ifdef __GNUC__ -#include -#endif -#ifdef __OS2__ -#include -#include -#endif // __OS2__ - -#ifdef _PS3 -#define NO_IPV6 // PSL1GHT v2 do not have IPv6 support -#endif - -#ifndef NO_IPV6 -#define HAVE_IPV6 -#endif - -#if defined (_WIN32) || defined (_WIN32_WCE) -#define USE_WINSOCK -#if defined (_WIN64) || defined (HAVE_IPV6) -#define USE_WINSOCK2 -#else //_WIN64/HAVE_IPV6 -#define USE_WINSOCK1 -#endif -#endif //WIN32 OS - -#ifdef _XBOX // XBox have on WinSock API? -#undef USE_WINSOCK -#undef USE_WINSOCK1 -#undef USE_WINSOCK2 -#endif - -#ifdef USE_WINSOCK2 -#include -#endif - -#include "doomdef.h" - -#if defined (NOMD5) && !defined (NONET) -//#define NONET -#endif - -#ifndef NONET -#ifdef USE_WINSOCK1 -#include -#elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__) -#ifdef HAVE_LWIP -#include -#elif !defined (USE_WINSOCK) -#include -#endif //normal BSD API - -#ifdef HAVE_LWIP -#include -#define ioctl lwip_ioctl -#elif !defined (USE_WINSOCK) //!HAVE_LWIP -#ifdef __APPLE_CC__ -#ifndef _BSD_SOCKLEN_T_ -#define _BSD_SOCKLEN_T_ -#endif //_BSD_SOCKLEN_T_ -#endif //__APPLE_CC__ -#include -#include -#endif //normal BSD API - -#if defined(_arch_dreamcast) && !defined(HAVE_LWIP) -#include -#elif defined(HAVE_LWIP) -#include -#elif defined (_PS3) -#include -#include -#elif !defined(USE_WINSOCK) //!HAVE_LWIP -#include -#include -#endif //normal BSD API - -#include -#include - -#ifdef _arch_dreamcast -#include "sdl/SRB2DC/dchelp.h" -#endif - -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) - #include -#endif // UNIXCOMMON -#endif // !NONET - -#ifdef USE_WINSOCK - // some undefined under win32 - #undef errno - //#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right? - #define errno h_errno // some very strange things happen when not using h_error?!? - #ifdef EWOULDBLOCK - #undef EWOULDBLOCK - #endif - #define EWOULDBLOCK WSAEWOULDBLOCK - #ifdef EMSGSIZE - #undef EMSGSIZE - #endif - #define EMSGSIZE WSAEMSGSIZE - #ifdef ECONNREFUSED - #undef ECONNREFUSED - #endif - #define ECONNREFUSED WSAECONNREFUSED - #ifdef ETIMEDOUT - #undef ETIMEDOUT - #endif - #define ETIMEDOUT WSAETIMEDOUT - #ifndef IOC_VENDOR - #define IOC_VENDOR 0x18000000 - #endif - #ifndef _WSAIOW - #define _WSAIOW(x,y) (IOC_IN|(x)|(y)) - #endif - #ifndef SIO_UDP_CONNRESET - #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) - #endif - #ifndef AI_ADDRCONFIG - #define AI_ADDRCONFIG 0x00000400 - #endif - #ifndef STATUS_INVALID_PARAMETER - #define STATUS_INVALID_PARAMETER 0xC000000D - #endif -#endif - -#ifdef __DJGPP__ -#ifdef WATTCP // Alam_GBC: Wattcp may need this -#include -#define strerror strerror_s -#else // wattcp -#include -#endif // libsocket -#endif // djgpp - -typedef union -{ - struct sockaddr any; - struct sockaddr_in ip4; -#ifdef HAVE_IPV6 - struct sockaddr_in6 ip6; -#endif -} mysockaddr_t; - -#ifdef HAVE_MINIUPNPC -#ifdef STATIC_MINIUPNPC -#define STATICLIB -#endif -#include "miniupnpc/miniwget.h" -#include "miniupnpc/miniupnpc.h" -#include "miniupnpc/upnpcommands.h" -#undef STATICLIB -static UINT8 UPNP_support = TRUE; -#endif - -#endif // !NONET - -#define MAXBANS 100 - -#include "i_system.h" -#include "i_net.h" -#include "d_net.h" -#include "i_tcp.h" -#include "m_argv.h" - -#include "doomstat.h" - -// win32 or djgpp -#if defined (USE_WINSOCK) || defined (__DJGPP__) - // winsock stuff (in winsock a socket is not a file) - #define ioctl ioctlsocket - #define close closesocket - - #ifdef _WIN32_WCE - #include "sdl/SRB2CE/cehelp.h" - #endif - -#endif - -#include "i_addrinfo.h" - -#ifdef __DJGPP__ - -#ifdef WATTCP -#define SELECTTEST -#endif - -#elif defined(HAVE_LWIP) -#define SELECTTEST -#elif !defined( _arch_dreamcast) -#define SELECTTEST -#endif - -#define DEFAULTPORT "5029" - -#if defined (USE_WINSOCK) && !defined (NONET) -typedef SOCKET SOCKET_TYPE; -#define BADSOCKET INVALID_SOCKET -#define ERRSOCKET (SOCKET_ERROR) -#else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) || defined(_PS3) -typedef int SOCKET_TYPE; -#else -typedef unsigned long SOCKET_TYPE; -#endif -#define BADSOCKET (SOCKET_TYPE)(~0) -#define ERRSOCKET (-1) -#endif - -#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) -typedef int socklen_t; -#endif - -#ifndef NONET -static SOCKET_TYPE mysockets[MAXNETNODES+1] = {BADSOCKET}; -static size_t mysocketses = 0; -static int myfamily[MAXNETNODES+1] = {0}; -static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {BADSOCKET}; -static mysockaddr_t clientaddress[MAXNETNODES+1]; -static mysockaddr_t broadcastaddress[MAXNETNODES+1]; -static size_t broadcastaddresses = 0; -static boolean nodeconnected[MAXNETNODES+1]; -static mysockaddr_t banned[MAXBANS]; -static UINT8 bannedmask[MAXBANS]; -#endif - -static size_t numbans = 0; -static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? -static boolean init_tcp_driver = false; - -static char port_name[8] = DEFAULTPORT; - -#ifndef NONET - -#ifdef WATTCP -static void wattcp_outch(char s) -{ - static char old = '\0'; - char pr[2] = {s,0}; - if (s == old && old == ' ') return; - else old = s; - if (s == '\r') CONS_Printf("\n"); - else if (s != '\n') CONS_Printf(pr); -} -#endif - -#ifdef USE_WINSOCK2 -#define inet_ntop inet_ntopA -#define HAVE_NTOP -static const char* inet_ntopA(short af, const void *cp, char *buf, socklen_t len) -{ - DWORD Dlen = len, AFlen = 0; - SOCKADDR_STORAGE any; - LPSOCKADDR anyp = (LPSOCKADDR)&any; - LPSOCKADDR_IN any4 = (LPSOCKADDR_IN)&any; - LPSOCKADDR_IN6 any6 = (LPSOCKADDR_IN6)&any; - - if (!buf) - { - WSASetLastError(STATUS_INVALID_PARAMETER); - return NULL; - } - - if (af != AF_INET && af != AF_INET6) - { - WSASetLastError(WSAEAFNOSUPPORT); - return NULL; - } - - ZeroMemory(&any, sizeof(SOCKADDR_STORAGE)); - any.ss_family = af; - - switch (af) - { - case AF_INET: - { - CopyMemory(&any4->sin_addr, cp, sizeof(IN_ADDR)); - AFlen = sizeof(SOCKADDR_IN); - break; - } - case AF_INET6: - { - CopyMemory(&any6->sin6_addr, cp, sizeof(IN6_ADDR)); - AFlen = sizeof(SOCKADDR_IN6); - break; - } - } - - if (WSAAddressToStringA(anyp, AFlen, NULL, buf, &Dlen) == SOCKET_ERROR) - return NULL; - return buf; -} -#elif !defined (USE_WINSOCK1) -#define HAVE_NTOP -#endif - -#ifdef HAVE_MINIUPNPC // based on old XChat patch -static struct UPNPUrls urls; -static struct IGDdatas data; -static char lanaddr[64]; - -static void I_ShutdownUPnP(void) -{ - FreeUPNPUrls(&urls); -} - -static inline void I_InitUPnP(void) -{ - struct UPNPDev * devlist = NULL; - int upnp_error = -2; - CONS_Printf(M_GetText("Looking for UPnP Internet Gateway Device\n")); - devlist = upnpDiscover(2000, NULL, NULL, 0, false, &upnp_error); - if (devlist) - { - struct UPNPDev *dev = devlist; - char * descXML; - int descXMLsize = 0; - while (dev) - { - if (strstr (dev->st, "InternetGatewayDevice")) - break; - dev = dev->pNext; - } - if (!dev) - dev = devlist; /* defaulting to first device */ - - CONS_Printf(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"), - dev->descURL, dev->st); - - UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); - CONS_Printf(M_GetText("Local LAN IP address: %s\n"), lanaddr); - descXML = miniwget(dev->descURL, &descXMLsize); - if (descXML) - { - parserootdesc(descXML, descXMLsize, &data); - free(descXML); - descXML = NULL; - memset(&urls, 0, sizeof(struct UPNPUrls)); - memset(&data, 0, sizeof(struct IGDdatas)); - GetUPNPUrls(&urls, &data, dev->descURL); - I_AddExitFunc(I_ShutdownUPnP); - } - freeUPNPDevlist(devlist); - } - else if (upnp_error == UPNPDISCOVER_SOCKET_ERROR) - { - CONS_Printf(M_GetText("No UPnP devices discovered\n")); - } -} - -static inline void I_UPnP_add(const char * addr, const char *port, const char * servicetype) -{ - if (addr == NULL) - addr = lanaddr; - if (!urls.controlURL || urls.controlURL[0] == '\0') - return; - UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, addr, "SRB2", servicetype, NULL, NULL); -} - -static inline void I_UPnP_rem(const char *port, const char * servicetype) -{ - if (!urls.controlURL || urls.controlURL[0] == '\0') - return; - UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, - port, servicetype, NULL); -} -#endif - -static const char *SOCK_AddrToStr(mysockaddr_t *sk) -{ - static char s[64]; // 255.255.255.255:65535 or IPv6:65535 -#ifdef HAVE_NTOP - void *addr; - - if(sk->any.sa_family == AF_INET) - addr = &sk->ip4.sin_addr; -#ifdef HAVE_IPV6 - else if(sk->any.sa_family == AF_INET6) - addr = &sk->ip6.sin6_addr; -#endif - else - addr = NULL; - - if(addr == NULL) - sprintf(s, "No address"); - else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL) - sprintf(s, "Unknown family type, error #%u", errno); -#ifdef HAVE_IPV6 - else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0) - strcat(s, va(":%d", ntohs(sk->ip6.sin6_port))); -#endif - else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0) - strcat(s, va(":%d", ntohs(sk->ip4.sin_port))); -#else - if (sk->any.sa_family == AF_INET) - { - strcpy(s, inet_ntoa(sk->ip4.sin_addr)); - if (sk->ip4.sin_port != 0) strcat(s, va(":%d", ntohs(sk->ip4.sin_port))); - } - else - sprintf(s, "Unknown type"); -#endif - return s; -} -#endif - -static const char *SOCK_GetNodeAddress(INT32 node) -{ - if (node == 0) - return "self"; -#ifdef NONET - return NULL; -#else - if (!nodeconnected[node]) - return NULL; - return SOCK_AddrToStr(&clientaddress[node]); -#endif -} - -static const char *SOCK_GetBanAddress(size_t ban) -{ - if (ban >= numbans) - return NULL; -#ifdef NONET - return NULL; -#else - return SOCK_AddrToStr(&banned[ban]); -#endif -} - -static const char *SOCK_GetBanMask(size_t ban) -{ -#ifdef NONET - (void)ban; -#else - static char s[16]; //255.255.255.255 netmask? no, just CDIR for only - if (ban >= numbans) - return NULL; - if (sprintf(s,"%d",bannedmask[ban]) > 0) - return s; -#endif - return NULL; -} - -#ifndef NONET -static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) -{ - UINT32 bitmask = INADDR_NONE; - - if (mask && mask < 32) - bitmask = htonl(-1 << (32 - mask)); - - if (b->any.sa_family == AF_INET) - return (a->ip4.sin_addr.s_addr & bitmask) == (b->ip4.sin_addr.s_addr & bitmask) - && (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port)); -#ifdef HAVE_IPV6 - else if (b->any.sa_family == AF_INET6) - return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) - && (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port)); -#endif - else - return false; -} - -static SINT8 getfreenode(void) -{ - SINT8 j; - - for (j = 0; j < MAXNETNODES; j++) - if (!nodeconnected[j]) - { - nodeconnected[j] = true; - return j; - } - return -1; -} - -// This is a hack. For some reason, nodes aren't being freed properly. -// This goes through and cleans up what nodes were supposed to be freed. -static void cleanupnodes(void) -{ - SINT8 j; - - if (!Playing()) - return; - - // Why can't I start at zero? - for (j = 1; j < MAXNETNODES; j++) - if (!nodeingame[j]) - nodeconnected[j] = false; -} -#endif - -#ifndef NONET -static void SOCK_Get(void) -{ - size_t i, n; - int j; - ssize_t c; - mysockaddr_t fromaddress; - socklen_t fromlen; - - for (n = 0; n < mysocketses; n++) - { - fromlen = (socklen_t)sizeof(fromaddress); - c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0, - (void *)&fromaddress, &fromlen); - if (c != ERRSOCKET) - { - // find remote node number - for (j = 0; j <= MAXNETNODES; j++) //include LAN - { - if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0)) - { - doomcom->remotenode = (INT16)j; // good packet from a game player - doomcom->datalength = (INT16)c; - nodesocket[j] = mysockets[n]; - return; - } - } - // not found - - // find a free slot - cleanupnodes(); - j = getfreenode(); - if (j > 0) - { - M_Memcpy(&clientaddress[j], &fromaddress, fromlen); - nodesocket[j] = mysockets[n]; - DEBFILE(va("New node detected: node:%d address:%s\n", j, - SOCK_GetNodeAddress(j))); - doomcom->remotenode = (INT16)j; // good packet from a game player - doomcom->datalength = (INT16)c; - - // check if it's a banned dude so we can send a refusal later - for (i = 0; i < numbans; i++) - { - if (SOCK_cmpaddr(&fromaddress, &banned[i], bannedmask[i])) - { - SOCK_bannednode[j] = true; - DEBFILE("This dude has been banned\n"); - break; - } - } - if (i == numbans) - SOCK_bannednode[j] = false; - return; - } - else - DEBFILE("New node detected: No more free slots\n"); - - } - } - doomcom->remotenode = -1; // no packet -} -#endif - -// check if we can send (do not go over the buffer) -#ifndef NONET - -static fd_set masterset; - -#ifdef SELECTTEST -static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len) -{ - size_t i; - boolean testset = false; - FD_ZERO(dst); - for (i = 0; i < len;i++) - { - if(fd[i] != BADSOCKET && fd[i] != (SOCKET_TYPE)ERRSOCKET && - FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups - { - FD_SET(fd[i], dst); - testset = true; - } - } - return testset; -} - -static boolean SOCK_CanSend(void) -{ - struct timeval timeval_for_select = {0, 0}; - fd_set tset; - int wselect; - - if(!FD_CPY(&masterset, &tset, mysockets, mysocketses)) - return false; - wselect = select(255, NULL, &tset, NULL, &timeval_for_select); - if (wselect >= 1) - return true; - return false; -} - -static boolean SOCK_CanGet(void) -{ - struct timeval timeval_for_select = {0, 0}; - fd_set tset; - int rselect; - - if(!FD_CPY(&masterset, &tset, mysockets, mysocketses)) - return false; - rselect = select(255, &tset, NULL, NULL, &timeval_for_select); - if (rselect >= 1) - return true; - return false; -} -#endif -#endif - -#ifndef NONET -static void SOCK_Send(void) -{ - ssize_t c = ERRSOCKET; - socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in); -#ifdef HAVE_IPV6 - socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6); -#endif - socklen_t d, da = (socklen_t)sizeof(mysockaddr_t); - size_t i, j; - - if (!nodeconnected[doomcom->remotenode]) - return; - - if (doomcom->remotenode == BROADCASTADDR) - { - for (i = 0; i < mysocketses; i++) - { - for (j = 0; j < broadcastaddresses; j++) - { - if (myfamily[i] == broadcastaddress[j].any.sa_family) - { - if (broadcastaddress[i].any.sa_family == AF_INET) - d = d4; -#ifdef HAVE_IPV6 - else if (broadcastaddress[i].any.sa_family == AF_INET6) - d = d6; -#endif - else - d = da; - - c = sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0, - &broadcastaddress[j].any, d); - } - } - } - return; - } - else if (nodesocket[doomcom->remotenode] == BADSOCKET) - { - for (i = 0; i < mysocketses; i++) - { - if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family) - { - if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET) - d = d4; -#ifdef HAVE_IPV6 - else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6) - d = d6; -#endif - else - d = da; - - sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0, - &clientaddress[doomcom->remotenode].any, d); - } - } - return; - } - else - { - if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET) - d = d4; -#ifdef HAVE_IPV6 - else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6) - d = d6; -#endif - else - d = da; - - c = sendto(nodesocket[doomcom->remotenode], (char *)&doomcom->data, doomcom->datalength, 0, - &clientaddress[doomcom->remotenode].any, d); - } - - if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK) - I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, - SOCK_GetNodeAddress(doomcom->remotenode), errno, strerror(errno)); -} -#endif - -#ifndef NONET -static void SOCK_FreeNodenum(INT32 numnode) -{ - // can't disconnect from self :) - if (!numnode || numnode > MAXNETNODES) - return; - - DEBFILE(va("Free node %d (%s)\n", numnode, SOCK_GetNodeAddress(numnode))); - - nodeconnected[numnode] = false; - nodesocket[numnode] = BADSOCKET; - - // put invalid address - memset(&clientaddress[numnode], 0, sizeof (clientaddress[numnode])); -} -#endif - -// -// UDPsocket -// -#ifndef NONET - -// allocate a socket -static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen) -{ - SOCKET_TYPE s = socket(family, SOCK_DGRAM, IPPROTO_UDP); - int opt; - socklen_t opts; -#ifdef FIONBIO -#ifdef WATTCP - char trueval = true; -#else - unsigned long trueval = true; -#endif -#endif - mysockaddr_t straddr; - - if (s == (SOCKET_TYPE)ERRSOCKET || s == BADSOCKET) - return (SOCKET_TYPE)ERRSOCKET; -#ifdef USE_WINSOCK - { // Alam_GBC: disable the new UDP connection reset behavior for Win2k and up -#ifdef USE_WINSOCK2 - DWORD dwBytesReturned = 0; - BOOL bfalse = FALSE; - WSAIoctl(s, SIO_UDP_CONNRESET, &bfalse, sizeof(bfalse), - NULL, 0, &dwBytesReturned, NULL, NULL); -#else - unsigned long falseval = false; - ioctl(s, SIO_UDP_CONNRESET, &falseval); -#endif - } -#endif - - straddr.any = *addr; - I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr)); - - if (family == AF_INET) - { - mysockaddr_t tmpaddr; - tmpaddr.any = *addr ; - if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY)) - { - opt = true; - opts = (socklen_t)sizeof(opt); - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts); - } - // make it broadcastable - opt = true; - opts = (socklen_t)sizeof(opt); - if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, opts)) - { - CONS_Alert(CONS_WARNING, M_GetText("Could not get broadcast rights\n")); // I do not care anymore - } - } -#ifdef HAVE_IPV6 - else if (family == AF_INET6) - { - if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL - { - opt = true; - opts = (socklen_t)sizeof(opt); - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, opts); - } -#ifdef IPV6_V6ONLY - // make it IPv6 ony - opt = true; - opts = (socklen_t)sizeof(opt); - if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts)) - { - CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore - } -#endif - } -#endif - - if (bind(s, addr, addrlen) == ERRSOCKET) - { - close(s); - I_OutputMsg("Binding failed\n"); - return (SOCKET_TYPE)ERRSOCKET; - } - -#ifdef FIONBIO - // make it non blocking - opt = true; - if (ioctl(s, FIONBIO, &trueval) != 0) - { - close(s); - I_OutputMsg("Seting FIOBIO on failed\n"); - return (SOCKET_TYPE)ERRSOCKET; - } -#endif - - opts = (socklen_t)sizeof(opt); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts); - CONS_Printf(M_GetText("Network system buffer: %dKb\n"), opt>>10); - - if (opt < 64<<10) // 64k - { - opt = 64<<10; - opts = (socklen_t)sizeof(opt); - setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, opts); - getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &opts); - if (opt < 64<<10) - CONS_Alert(CONS_WARNING, M_GetText("Can't set buffer length to 64k, file transfer will be bad\n")); - else - CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10); - } - - return s; -} - -static boolean UDP_Socket(void) -{ - const char *sock_port = NULL; - size_t s; - struct my_addrinfo *ai, *runp, hints; - int gaie; -#ifdef HAVE_IPV6 - const INT32 b_ipv6 = M_CheckParm("-ipv6"); -#endif - - - for (s = 0; s < mysocketses; s++) - mysockets[s] = BADSOCKET; - for (s = 0; s < MAXNETNODES+1; s++) - nodesocket[s] = BADSOCKET; - FD_ZERO(&masterset); - s = 0; - - memset(&hints, 0x00, sizeof (hints)); - hints.ai_flags = AI_NUMERICHOST; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - - if (M_CheckParm("-clientport")) - { - if (!M_IsNextParm()) - I_Error("syntax: -clientport "); - sock_port = M_GetNextParm(); - } - else - sock_port = port_name; - - if (M_CheckParm("-bindaddr")) - { - while (M_IsNextParm()) - { - gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL && s < MAXNETNODES+1) - { - mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); - if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) - { - FD_SET(mysockets[s], &masterset); - myfamily[s] = hints.ai_family; - s++; - } - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } - } - else - { - gaie = I_getaddrinfo("0.0.0.0", sock_port, &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL && s < MAXNETNODES+1) - { - mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); - if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) - { - FD_SET(mysockets[s], &masterset); - myfamily[s] = hints.ai_family; - s++; -#ifdef HAVE_MINIUPNPC - if (UPNP_support) - { - I_UPnP_rem(sock_port, "UDP"); - I_UPnP_add(NULL, sock_port, "UDP"); - } -#endif - } - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } -#ifdef HAVE_IPV6 - if (b_ipv6) - { - hints.ai_family = AF_INET6; - if (M_CheckParm("-bindaddr6")) - { - while (M_IsNextParm()) - { - gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL && s < MAXNETNODES+1) - { - mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); - if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) - { - FD_SET(mysockets[s], &masterset); - myfamily[s] = hints.ai_family; - s++; - } - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } - } - else - { - gaie = I_getaddrinfo("::", sock_port, &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL && s < MAXNETNODES+1) - { - mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen); - if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET) - { - FD_SET(mysockets[s], &masterset); - myfamily[s] = hints.ai_family; - s++; - } - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } - } -#endif - - mysocketses = s; - if (s == 0) // no sockets? - return false; - - s = 0; - - // ip + udp - packetheaderlength = 20 + 8; // for stats - - hints.ai_family = AF_INET; - gaie = I_getaddrinfo("127.0.0.1", "0", &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL) - { - memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen); - s++; - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - else - { - clientaddress[s].any.sa_family = AF_INET; - clientaddress[s].ip4.sin_port = htons(0); - clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip - s++; - } - // setup broadcast adress to BROADCASTADDR entry - gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL) - { - memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen); - s++; - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - else - { - broadcastaddress[s].any.sa_family = AF_INET; - broadcastaddress[s].ip4.sin_port = htons(0); - broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST); - s++; - } -#ifdef HAVE_IPV6 - if (b_ipv6) - { - hints.ai_family = AF_INET6; - gaie = I_getaddrinfo("ff02::1", "0", &hints, &ai); - if (gaie == 0) - { - runp = ai; - while (runp != NULL) - { - memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen); - s++; - runp = runp->ai_next; - } - I_freeaddrinfo(ai); - } - } -#endif - - broadcastaddresses = s; - - doomcom->extratics = 1; // internet is very high ping - - return true; -} -#endif - -boolean I_InitTcpDriver(void) -{ - boolean tcp_was_up = init_tcp_driver; -#ifndef NONET - if (!init_tcp_driver) - { -#ifdef USE_WINSOCK -#ifdef USE_WINSOCK2 - const WORD VerNeed = MAKEWORD(2,2); -#else - const WORD VerNeed = MAKEWORD(1,1); -#endif - WSADATA WSAData; - const int WSAresult = WSAStartup(VerNeed, &WSAData); - if (WSAresult != 0) - { - LPCSTR WSError = NULL; - switch (WSAresult) - { - case WSASYSNOTREADY: - WSError = "The underlying network subsystem is not ready for network communication"; - break; - case WSAEINPROGRESS: - WSError = "A blocking Windows Sockets 1.1 operation is in progress"; - break; - case WSAEPROCLIM: - WSError = "Limit on the number of tasks supported by the Windows Sockets implementation has been reached"; - break; - case WSAEFAULT: - WSError = "WSAData is not a valid pointer? What kind of setup do you have?"; - break; - default: - WSError = va("Error code %u",WSAresult); - break; - } - if (WSAresult != WSAVERNOTSUPPORTED) - CONS_Debug(DBG_NETPLAY, "WinSock(TCP/IP) error: %s\n",WSError); - } -#ifdef USE_WINSOCK2 - if(LOBYTE(WSAData.wVersion) != 2 || - HIBYTE(WSAData.wVersion) != 2) - { - WSACleanup(); - CONS_Debug(DBG_NETPLAY, "No WinSock(TCP/IP) 2.2 driver detected\n"); - } -#else - if (LOBYTE(WSAData.wVersion) != 1 || - HIBYTE(WSAData.wVersion) != 1) - { - WSACleanup(); - CONS_Debug(DBG_NETPLAY, "No WinSock(TCP/IP) 1.1 driver detected\n"); - } -#endif - CONS_Debug(DBG_NETPLAY, "WinSock description: %s\n",WSAData.szDescription); - CONS_Debug(DBG_NETPLAY, "WinSock System Status: %s\n",WSAData.szSystemStatus); -#endif -#ifdef HAVE_LWIP - lwip_kos_init(); -#elif defined(_arch_dreamcast) - //return; - net_init(); -#endif -#ifdef __DJGPP__ -#ifdef WATTCP // Alam_GBC: survive bootp, dhcp, rarp and wattcp/pktdrv from failing to load - survive_eth = 1; // would be needed to not exit if pkt_eth_init() fails - survive_bootp = 1; // ditto for BOOTP - survive_dhcp = 1; // ditto for DHCP/RARP - survive_rarp = 1; - //_watt_do_exit = false; - //_watt_handle_cbreak = false; - //_watt_no_config = true; - _outch = wattcp_outch; - init_misc(); -//#ifdef DEBUGFILE - dbug_init(); -//#endif - switch (sock_init()) - { - case 0: - init_tcp_driver = true; - break; - case 3: - CONS_Debug(DBG_NETPLAY, "No packet driver detected\n"); - break; - case 4: - CONS_Debug(DBG_NETPLAY, "Error while talking to packet driver\n"); - break; - case 5: - CONS_Debug(DBG_NETPLAY, "BOOTP failed\n"); - break; - case 6: - CONS_Debug(DBG_NETPLAY, "DHCP failed\n"); - break; - case 7: - CONS_Debug(DBG_NETPLAY, "RARP failed\n"); - break; - case 8: - CONS_Debug(DBG_NETPLAY, "TCP/IP failed\n"); - break; - case 9: - CONS_Debug(DBG_NETPLAY, "PPPoE login/discovery failed\n"); - break; - default: - CONS_Debug(DBG_NETPLAY, "Unknown error with TCP/IP stack\n"); - break; - } - hires_timer(0); -#else // wattcp - if (__lsck_init()) - init_tcp_driver = true; - else - CONS_Debug(DBG_NETPLAY, "No TCP/IP driver detected\n"); -#endif // libsocket -#endif // __DJGPP__ -#ifdef _PS3 - netInitialize(); -#endif -#ifndef __DJGPP__ - init_tcp_driver = true; -#endif - } -#endif - if (!tcp_was_up && init_tcp_driver) - { - I_AddExitFunc(I_ShutdownTcpDriver); -#ifdef HAVE_MINIUPNPC - if (M_CheckParm("-useUPnP")) - I_InitUPnP(); - else - UPNP_support = false; -#endif - } - return init_tcp_driver; -} - -#ifndef NONET -static void SOCK_CloseSocket(void) -{ - size_t i; - for (i=0; i < MAXNETNODES+1; i++) - { - if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET - && mysockets[i] != BADSOCKET - && FD_ISSET(mysockets[i], &masterset)) - { -#if !defined (__DJGPP__) || defined (WATTCP) - FD_CLR(mysockets[i], &masterset); - close(mysockets[i]); -#endif - } - mysockets[i] = BADSOCKET; - } -} -#endif - -void I_ShutdownTcpDriver(void) -{ -#ifndef NONET - SOCK_CloseSocket(); - - CONS_Printf("I_ShutdownTcpDriver: "); -#ifdef USE_WINSOCK - WS_addrinfocleanup(); - WSACleanup(); -#endif -#ifdef HAVE_LWIP - lwip_kos_shutdown(); -#elif defined(_arch_dreamcast) - net_shutdown(); -#endif -#ifdef __DJGPP__ -#ifdef WATTCP // wattcp - //_outch = NULL; - sock_exit(); -#else - __lsck_uninit(); -#endif // libsocket -#endif // __DJGPP__ -#ifdef _PS3 - netDeinitialize(); -#endif - CONS_Printf("shut down\n"); - init_tcp_driver = false; -#endif -} - -#ifndef NONET -static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) -{ - SINT8 newnode = -1; - struct my_addrinfo *ai, *runp, hints; - int gaie; - - if (!port || !port[0]) - port = port_name; - - DEBFILE(va("Creating new node: %s@%s\n", address, port)); - - memset (&hints, 0x00, sizeof (hints)); - hints.ai_flags = 0; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - - gaie = I_getaddrinfo(address, port, &hints, &ai); - if (gaie == 0) - { - cleanupnodes(); - newnode = getfreenode(); - } - if (newnode == -1) - { - I_freeaddrinfo(ai); - return -1; - } - else - runp = ai; - - while (runp != NULL) - { - // find ip of the server - memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); - runp = NULL; - } - I_freeaddrinfo(ai); - return newnode; -} -#endif - -static boolean SOCK_OpenSocket(void) -{ -#ifndef NONET - size_t i; - - memset(clientaddress, 0, sizeof (clientaddress)); - - nodeconnected[0] = true; // always connected to self - for (i = 1; i < MAXNETNODES; i++) - nodeconnected[i] = false; - nodeconnected[BROADCASTADDR] = true; - I_NetSend = SOCK_Send; - I_NetGet = SOCK_Get; - I_NetCloseSocket = SOCK_CloseSocket; - I_NetFreeNodenum = SOCK_FreeNodenum; - I_NetMakeNodewPort = SOCK_NetMakeNodewPort; - -#ifdef SELECTTEST - // seem like not work with libsocket : ( - I_NetCanSend = SOCK_CanSend; - I_NetCanGet = SOCK_CanGet; -#endif - - // build the socket but close it first - SOCK_CloseSocket(); - return UDP_Socket(); -#else - return false; -#endif -} - -static boolean SOCK_Ban(INT32 node) -{ - if (node > MAXNETNODES) - return false; -#ifdef NONET - return false; -#else - if (numbans == MAXBANS) - return false; - - M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (mysockaddr_t)); - if (banned[numbans].any.sa_family == AF_INET) - { - banned[numbans].ip4.sin_port = 0; - bannedmask[numbans] = 32; - } -#ifdef HAVE_IPV6 - else if (banned[numbans].any.sa_family == AF_INET6) - { - banned[numbans].ip6.sin6_port = 0; - bannedmask[numbans] = 128; - } -#endif - numbans++; - return true; -#endif -} - -static boolean SOCK_SetBanAddress(const char *address, const char *mask) -{ -#ifdef NONET - (void)address; - (void)mask; - return false; -#else - struct my_addrinfo *ai, *runp, hints; - int gaie; - - if (numbans == MAXBANS || !address) - return false; - - memset(&hints, 0x00, sizeof(hints)); - hints.ai_flags = 0; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - - gaie = I_getaddrinfo(address, "0", &hints, &ai); - if (gaie != 0) - return false; - - runp = ai; - - while(runp != NULL && numbans != MAXBANS) - { - memcpy(&banned[numbans], runp->ai_addr, runp->ai_addrlen); - - if (mask) - bannedmask[numbans] = (UINT8)atoi(mask); -#ifdef HAVE_IPV6 - else if (runp->ai_family == AF_INET6) - bannedmask[numbans] = 128; -#endif - else - bannedmask[numbans] = 32; - - if (bannedmask[numbans] > 32 && runp->ai_family == AF_INET) - bannedmask[numbans] = 32; -#ifdef HAVE_IPV6 - else if (bannedmask[numbans] > 128 && runp->ai_family == AF_INET6) - bannedmask[numbans] = 128; -#endif - numbans++; - runp = runp->ai_next; - } - - I_freeaddrinfo(ai); - - return true; -#endif -} - -static void SOCK_ClearBans(void) -{ - numbans = 0; -} - -boolean I_InitTcpNetwork(void) -{ - char serverhostname[255]; - boolean ret = false; - // initilize the OS's TCP/IP stack - if (!I_InitTcpDriver()) - return false; - - if (M_CheckParm("-udpport")) - { - if (M_IsNextParm()) - strcpy(port_name, M_GetNextParm()); - else - strcpy(port_name, "0"); - } - current_port = (UINT16)atoi(port_name); - - // parse network game options, - if (M_CheckParm("-server") || dedicated) - { - server = true; - - // If a number of clients (i.e. nodes) is specified, the server will wait for the clients - // to connect before starting. - // If no number is specified here, the server starts with 1 client, and others can join - // in-game. - // Since Boris has implemented join in-game, there is no actual need for specifying a - // particular number here. - // FIXME: for dedicated server, numnodes needs to be set to 0 upon start - if (dedicated) - doomcom->numnodes = 0; -/* else if (M_IsNextParm()) - doomcom->numnodes = (INT16)atoi(M_GetNextParm());*/ - else - doomcom->numnodes = 1; - - if (doomcom->numnodes < 0) - doomcom->numnodes = 0; - if (doomcom->numnodes > MAXNETNODES) - doomcom->numnodes = MAXNETNODES; - - // server - servernode = 0; - // FIXME: - // ??? and now ? - // server on a big modem ??? 4*isdn - net_bandwidth = 16000; - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - - ret = true; - } - else if (M_CheckParm("-connect")) - { - if (M_IsNextParm()) - strcpy(serverhostname, M_GetNextParm()); - else - serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it - - // server address only in ip - if (serverhostname[0]) - { - COM_BufAddText("connect \""); - COM_BufAddText(serverhostname); - COM_BufAddText("\"\n"); - - // probably modem - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - } - else - { - // so we're on a LAN - COM_BufAddText("connect any\n"); - - net_bandwidth = 800000; - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - } - } - - I_NetOpenSocket = SOCK_OpenSocket; - I_Ban = SOCK_Ban; - I_ClearBans = SOCK_ClearBans; - I_GetNodeAddress = SOCK_GetNodeAddress; - I_GetBanAddress = SOCK_GetBanAddress; - I_GetBanMask = SOCK_GetBanMask; - I_SetBanAddress = SOCK_SetBanAddress; - bannednode = SOCK_bannednode; - - return ret; -} - -#include "i_addrinfo.c" diff --git a/src/i_tcp.h b/src/i_tcp.h deleted file mode 100644 index ef0baace9..000000000 --- a/src/i_tcp.h +++ /dev/null @@ -1,31 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2014 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file i_tcp.h -/// \brief TCP driver, sockets. - -#ifndef __I_TCP__ -#define __I_TCP__ - -extern UINT16 current_port; - -/** \brief The I_InitTcpNetwork function - - \return true if going or in a netgame, else it's false -*/ -boolean I_InitTcpNetwork(void); - -/** \brief The I_InitTcpNetwork function - - \return true if TCP/IP stack was initilized, else it's false -*/ -boolean I_InitTcpDriver(void); -void I_ShutdownTcpDriver(void); - -#endif diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index abbd5f284..875c35cd5 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -21,7 +21,6 @@ set(SRB2_SDL2_SOURCES hwsym_sdl.c i_cdmus.c i_main.c - i_net.c i_system.c i_ttf.c i_video.c diff --git a/src/sdl/i_net.c b/src/sdl/i_net.c deleted file mode 100644 index ee4a34c13..000000000 --- a/src/sdl/i_net.c +++ /dev/null @@ -1,442 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program 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 2 -// of the License, or (at your option) any later version. -// -// This program 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL network interface - -#include "../doomdef.h" - -#include "../i_system.h" -#include "../d_event.h" -#include "../d_net.h" -#include "../m_argv.h" - -#include "../doomstat.h" - -#include "../i_net.h" - -#include "../z_zone.h" - -#include "../i_tcp.h" - -#ifdef HAVE_SDL - -#ifdef HAVE_SDLNET - -#include "SDL_net.h" - -#define MAXBANS 20 - -static IPaddress clientaddress[MAXNETNODES+1]; -static IPaddress banned[MAXBANS]; - -static UDPpacket mypacket; -static UDPsocket mysocket = NULL; -static SDLNet_SocketSet myset = NULL; - -static size_t numbans = 0; -static boolean NET_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? -static boolean init_SDLNet_driver = false; - -static const char *NET_AddrToStr(IPaddress* sk) -{ - static char s[22]; // 255.255.255.255:65535 - strcpy(s, SDLNet_ResolveIP(sk)); - if (sk->port != 0) strcat(s, va(":%d", sk->port)); - return s; -} - -static const char *NET_GetNodeAddress(INT32 node) -{ - if (!nodeconnected[node]) - return NULL; - return NET_AddrToStr(&clientaddress[node]); -} - -static const char *NET_GetBanAddress(size_t ban) -{ - if (ban > numbans) - return NULL; - return NET_AddrToStr(&banned[ban]); -} - -static boolean NET_cmpaddr(IPaddress* a, IPaddress* b) -{ - return (a->host == b->host && (b->port == 0 || a->port == b->port)); -} - -static boolean NET_CanGet(void) -{ - return myset?(SDLNet_CheckSockets(myset,0) == 1):false; -} - -static void NET_Get(void) -{ - INT32 mystatus; - INT32 newnode; - mypacket.len = MAXPACKETLENGTH; - if (!NET_CanGet()) - { - doomcom->remotenode = -1; // no packet - return; - } - mystatus = SDLNet_UDP_Recv(mysocket,&mypacket); - if (mystatus != -1) - { - if (mypacket.channel != -1) - { - doomcom->remotenode = mypacket.channel+1; // good packet from a game player - doomcom->datalength = mypacket.len; - return; - } - newnode = SDLNet_UDP_Bind(mysocket,-1,&mypacket.address); - if (newnode != -1) - { - size_t i; - newnode++; - M_Memcpy(&clientaddress[newnode], &mypacket.address, sizeof (IPaddress)); - DEBFILE(va("New node detected: node:%d address:%s\n", newnode, - NET_GetNodeAddress(newnode))); - doomcom->remotenode = newnode; // good packet from a game player - doomcom->datalength = mypacket.len; - for (i = 0; i < numbans; i++) - { - if (NET_cmpaddr(&mypacket.address, &banned[i])) - { - DEBFILE("This dude has been banned\n"); - NET_bannednode[newnode] = true; - break; - } - } - if (i == numbans) - NET_bannednode[newnode] = false; - return; - } - else - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } - else if (mystatus == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } - - DEBFILE("New node detected: No more free slots\n"); - doomcom->remotenode = -1; // no packet -} - -#if 0 -static boolean NET_CanSend(void) -{ - return true; -} -#endif - -static void NET_Send(void) -{ - if (!doomcom->remotenode) - return; - mypacket.len = doomcom->datalength; - if (SDLNet_UDP_Send(mysocket,doomcom->remotenode-1,&mypacket) == 0) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } -} - -static void NET_FreeNodenum(INT32 numnode) -{ - // can't disconnect from self :) - if (!numnode) - return; - - DEBFILE(va("Free node %d (%s)\n", numnode, NET_GetNodeAddress(numnode))); - - SDLNet_UDP_Unbind(mysocket,numnode-1); - - memset(&clientaddress[numnode], 0, sizeof (IPaddress)); -} - -static UDPsocket NET_Socket(void) -{ - UDPsocket temp = NULL; - Uint16 portnum = 0; - IPaddress tempip = {INADDR_BROADCAST,0}; - //Hurdler: I'd like to put a server and a client on the same computer - //Logan: Me too - //BP: in fact for client we can use any free port we want i have read - // in some doc that connect in udp can do it for us... - //Alam: where? - if (M_CheckParm("-clientport")) - { - if (!M_IsNextParm()) - I_Error("syntax: -clientport "); - portnum = atoi(M_GetNextParm()); - } - else - portnum = sock_port; - temp = SDLNet_UDP_Open(portnum); - if (!temp) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return NULL; - } - if (SDLNet_UDP_Bind(temp,BROADCASTADDR-1,&tempip) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - SDLNet_UDP_Close(temp); - return NULL; - } - clientaddress[BROADCASTADDR].port = sock_port; - clientaddress[BROADCASTADDR].host = INADDR_BROADCAST; - - doomcom->extratics = 1; // internet is very high ping - - return temp; -} - -static void I_ShutdownSDLNetDriver(void) -{ - if (myset) SDLNet_FreeSocketSet(myset); - myset = NULL; - SDLNet_Quit(); - init_SDLNet_driver = false; -} - -static void I_InitSDLNetDriver(void) -{ - if (init_SDLNet_driver) - I_ShutdownSDLNetDriver(); - if (SDLNet_Init() == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return; // No good! - } - D_SetDoomcom(); - mypacket.data = doomcom->data; - init_SDLNet_driver = true; -} - -static void NET_CloseSocket(void) -{ - if (mysocket) - SDLNet_UDP_Close(mysocket); - mysocket = NULL; -} - -static SINT8 NET_NetMakeNodewPort(const char *hostname, const char *port) -{ - INT32 newnode; - UINT16 portnum = sock_port; - IPaddress hostnameIP; - - // retrieve portnum from address! - if (port && !port[0]) - portnum = atoi(port); - - if (SDLNet_ResolveHost(&hostnameIP,hostname,portnum) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return -1; - } - newnode = SDLNet_UDP_Bind(mysocket,-1,&hostnameIP); - if (newnode == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return newnode; - } - newnode++; - M_Memcpy(&clientaddress[newnode],&hostnameIP,sizeof (IPaddress)); - return (SINT8)newnode; -} - - -static boolean NET_OpenSocket(void) -{ - memset(clientaddress, 0, sizeof (clientaddress)); - - //I_OutputMsg("SDL_Net Code starting up\n"); - - I_NetSend = NET_Send; - I_NetGet = NET_Get; - I_NetCloseSocket = NET_CloseSocket; - I_NetFreeNodenum = NET_FreeNodenum; - I_NetMakeNodewPort = NET_NetMakeNodewPort; - - //I_NetCanSend = NET_CanSend; - - // build the socket but close it first - NET_CloseSocket(); - mysocket = NET_Socket(); - - if (!mysocket) - return false; - - // for select - myset = SDLNet_AllocSocketSet(1); - if (!myset) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return false; - } - if (SDLNet_UDP_AddSocket(myset,mysocket) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return false; - } - return true; -} - -static boolean NET_Ban(INT32 node) -{ - if (numbans == MAXBANS) - return false; - - M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (IPaddress)); - banned[numbans].port = 0; - numbans++; - return true; -} - -static boolean NET_SetBanAddress(const char *address, const char *mask) -{ - (void)mask; - if (bans == MAXBANS) - return false; - - if (SDLNet_ResolveHost(&banned[numbans], address, 0) == -1) - return false; - numbans++; - return true; -} - -static void NET_ClearBans(void) -{ - numbans = 0; -} -#endif - -// -// I_InitNetwork -// Only required for DOS, so this is more a dummy -// -boolean I_InitNetwork(void) -{ -#ifdef HAVE_SDLNET - char serverhostname[255]; - boolean ret = false; - SDL_version SDLcompiled; - const SDL_version *SDLlinked = SDLNet_Linked_Version(); - SDL_NET_VERSION(&SDLcompiled) - I_OutputMsg("Compiled for SDL_Net version: %d.%d.%d\n", - SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); - I_OutputMsg("Linked with SDL_Net version: %d.%d.%d\n", - SDLlinked->major, SDLlinked->minor, SDLlinked->patch); - //if (!M_CheckParm ("-sdlnet")) - // return false; - // initilize the driver - I_InitSDLNetDriver(); - I_AddExitFunc(I_ShutdownSDLNetDriver); - if (!init_SDLNet_driver) - return false; - - if (M_CheckParm("-udpport")) - { - if (M_IsNextParm()) - sock_port = (UINT16)atoi(M_GetNextParm()); - else - sock_port = 0; - } - - // parse network game options, - if (M_CheckParm("-server") || dedicated) - { - server = true; - - // If a number of clients (i.e. nodes) is specified, the server will wait for the clients - // to connect before starting. - // If no number is specified here, the server starts with 1 client, and others can join - // in-game. - // Since Boris has implemented join in-game, there is no actual need for specifying a - // particular number here. - // FIXME: for dedicated server, numnodes needs to be set to 0 upon start -/* if (M_IsNextParm()) - doomcom->numnodes = (INT16)atoi(M_GetNextParm()); - else */if (dedicated) - doomcom->numnodes = 0; - else - doomcom->numnodes = 1; - - if (doomcom->numnodes < 0) - doomcom->numnodes = 0; - if (doomcom->numnodes > MAXNETNODES) - doomcom->numnodes = MAXNETNODES; - - // server - servernode = 0; - // FIXME: - // ??? and now ? - // server on a big modem ??? 4*isdn - net_bandwidth = 16000; - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - - ret = true; - } - else if (M_CheckParm("-connect")) - { - if (M_IsNextParm()) - strcpy(serverhostname, M_GetNextParm()); - else - serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it - - // server address only in ip - if (serverhostname[0]) - { - COM_BufAddText("connect \""); - COM_BufAddText(serverhostname); - COM_BufAddText("\"\n"); - - // probably modem - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - } - else - { - // so we're on a LAN - COM_BufAddText("connect any\n"); - - net_bandwidth = 800000; - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - } - } - - mypacket.maxlen = hardware_MAXPACKETLENGTH; - I_NetOpenSocket = NET_OpenSocket; - I_Ban = NET_Ban; - I_ClearBans = NET_ClearBans; - I_GetNodeAddress = NET_GetNodeAddress; - I_GetBenAddress = NET_GetBenAddress; - I_SetBanAddress = NET_SetBanAddress; - bannednode = NET_bannednode; - - return ret; -#else - if ( M_CheckParm ("-net") ) - { - I_Error("-net not supported, use -server and -connect\n" - "see docs for more\n"); - } - return false; -#endif -} -#endif diff --git a/src/sdl12/i_net.c b/src/sdl12/i_net.c deleted file mode 100644 index ee4a34c13..000000000 --- a/src/sdl12/i_net.c +++ /dev/null @@ -1,442 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1993-1996 by id Software, Inc. -// Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program 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 2 -// of the License, or (at your option) any later version. -// -// This program 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. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL network interface - -#include "../doomdef.h" - -#include "../i_system.h" -#include "../d_event.h" -#include "../d_net.h" -#include "../m_argv.h" - -#include "../doomstat.h" - -#include "../i_net.h" - -#include "../z_zone.h" - -#include "../i_tcp.h" - -#ifdef HAVE_SDL - -#ifdef HAVE_SDLNET - -#include "SDL_net.h" - -#define MAXBANS 20 - -static IPaddress clientaddress[MAXNETNODES+1]; -static IPaddress banned[MAXBANS]; - -static UDPpacket mypacket; -static UDPsocket mysocket = NULL; -static SDLNet_SocketSet myset = NULL; - -static size_t numbans = 0; -static boolean NET_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? -static boolean init_SDLNet_driver = false; - -static const char *NET_AddrToStr(IPaddress* sk) -{ - static char s[22]; // 255.255.255.255:65535 - strcpy(s, SDLNet_ResolveIP(sk)); - if (sk->port != 0) strcat(s, va(":%d", sk->port)); - return s; -} - -static const char *NET_GetNodeAddress(INT32 node) -{ - if (!nodeconnected[node]) - return NULL; - return NET_AddrToStr(&clientaddress[node]); -} - -static const char *NET_GetBanAddress(size_t ban) -{ - if (ban > numbans) - return NULL; - return NET_AddrToStr(&banned[ban]); -} - -static boolean NET_cmpaddr(IPaddress* a, IPaddress* b) -{ - return (a->host == b->host && (b->port == 0 || a->port == b->port)); -} - -static boolean NET_CanGet(void) -{ - return myset?(SDLNet_CheckSockets(myset,0) == 1):false; -} - -static void NET_Get(void) -{ - INT32 mystatus; - INT32 newnode; - mypacket.len = MAXPACKETLENGTH; - if (!NET_CanGet()) - { - doomcom->remotenode = -1; // no packet - return; - } - mystatus = SDLNet_UDP_Recv(mysocket,&mypacket); - if (mystatus != -1) - { - if (mypacket.channel != -1) - { - doomcom->remotenode = mypacket.channel+1; // good packet from a game player - doomcom->datalength = mypacket.len; - return; - } - newnode = SDLNet_UDP_Bind(mysocket,-1,&mypacket.address); - if (newnode != -1) - { - size_t i; - newnode++; - M_Memcpy(&clientaddress[newnode], &mypacket.address, sizeof (IPaddress)); - DEBFILE(va("New node detected: node:%d address:%s\n", newnode, - NET_GetNodeAddress(newnode))); - doomcom->remotenode = newnode; // good packet from a game player - doomcom->datalength = mypacket.len; - for (i = 0; i < numbans; i++) - { - if (NET_cmpaddr(&mypacket.address, &banned[i])) - { - DEBFILE("This dude has been banned\n"); - NET_bannednode[newnode] = true; - break; - } - } - if (i == numbans) - NET_bannednode[newnode] = false; - return; - } - else - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } - else if (mystatus == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } - - DEBFILE("New node detected: No more free slots\n"); - doomcom->remotenode = -1; // no packet -} - -#if 0 -static boolean NET_CanSend(void) -{ - return true; -} -#endif - -static void NET_Send(void) -{ - if (!doomcom->remotenode) - return; - mypacket.len = doomcom->datalength; - if (SDLNet_UDP_Send(mysocket,doomcom->remotenode-1,&mypacket) == 0) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - } -} - -static void NET_FreeNodenum(INT32 numnode) -{ - // can't disconnect from self :) - if (!numnode) - return; - - DEBFILE(va("Free node %d (%s)\n", numnode, NET_GetNodeAddress(numnode))); - - SDLNet_UDP_Unbind(mysocket,numnode-1); - - memset(&clientaddress[numnode], 0, sizeof (IPaddress)); -} - -static UDPsocket NET_Socket(void) -{ - UDPsocket temp = NULL; - Uint16 portnum = 0; - IPaddress tempip = {INADDR_BROADCAST,0}; - //Hurdler: I'd like to put a server and a client on the same computer - //Logan: Me too - //BP: in fact for client we can use any free port we want i have read - // in some doc that connect in udp can do it for us... - //Alam: where? - if (M_CheckParm("-clientport")) - { - if (!M_IsNextParm()) - I_Error("syntax: -clientport "); - portnum = atoi(M_GetNextParm()); - } - else - portnum = sock_port; - temp = SDLNet_UDP_Open(portnum); - if (!temp) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return NULL; - } - if (SDLNet_UDP_Bind(temp,BROADCASTADDR-1,&tempip) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - SDLNet_UDP_Close(temp); - return NULL; - } - clientaddress[BROADCASTADDR].port = sock_port; - clientaddress[BROADCASTADDR].host = INADDR_BROADCAST; - - doomcom->extratics = 1; // internet is very high ping - - return temp; -} - -static void I_ShutdownSDLNetDriver(void) -{ - if (myset) SDLNet_FreeSocketSet(myset); - myset = NULL; - SDLNet_Quit(); - init_SDLNet_driver = false; -} - -static void I_InitSDLNetDriver(void) -{ - if (init_SDLNet_driver) - I_ShutdownSDLNetDriver(); - if (SDLNet_Init() == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return; // No good! - } - D_SetDoomcom(); - mypacket.data = doomcom->data; - init_SDLNet_driver = true; -} - -static void NET_CloseSocket(void) -{ - if (mysocket) - SDLNet_UDP_Close(mysocket); - mysocket = NULL; -} - -static SINT8 NET_NetMakeNodewPort(const char *hostname, const char *port) -{ - INT32 newnode; - UINT16 portnum = sock_port; - IPaddress hostnameIP; - - // retrieve portnum from address! - if (port && !port[0]) - portnum = atoi(port); - - if (SDLNet_ResolveHost(&hostnameIP,hostname,portnum) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return -1; - } - newnode = SDLNet_UDP_Bind(mysocket,-1,&hostnameIP); - if (newnode == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return newnode; - } - newnode++; - M_Memcpy(&clientaddress[newnode],&hostnameIP,sizeof (IPaddress)); - return (SINT8)newnode; -} - - -static boolean NET_OpenSocket(void) -{ - memset(clientaddress, 0, sizeof (clientaddress)); - - //I_OutputMsg("SDL_Net Code starting up\n"); - - I_NetSend = NET_Send; - I_NetGet = NET_Get; - I_NetCloseSocket = NET_CloseSocket; - I_NetFreeNodenum = NET_FreeNodenum; - I_NetMakeNodewPort = NET_NetMakeNodewPort; - - //I_NetCanSend = NET_CanSend; - - // build the socket but close it first - NET_CloseSocket(); - mysocket = NET_Socket(); - - if (!mysocket) - return false; - - // for select - myset = SDLNet_AllocSocketSet(1); - if (!myset) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return false; - } - if (SDLNet_UDP_AddSocket(myset,mysocket) == -1) - { - I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); - return false; - } - return true; -} - -static boolean NET_Ban(INT32 node) -{ - if (numbans == MAXBANS) - return false; - - M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (IPaddress)); - banned[numbans].port = 0; - numbans++; - return true; -} - -static boolean NET_SetBanAddress(const char *address, const char *mask) -{ - (void)mask; - if (bans == MAXBANS) - return false; - - if (SDLNet_ResolveHost(&banned[numbans], address, 0) == -1) - return false; - numbans++; - return true; -} - -static void NET_ClearBans(void) -{ - numbans = 0; -} -#endif - -// -// I_InitNetwork -// Only required for DOS, so this is more a dummy -// -boolean I_InitNetwork(void) -{ -#ifdef HAVE_SDLNET - char serverhostname[255]; - boolean ret = false; - SDL_version SDLcompiled; - const SDL_version *SDLlinked = SDLNet_Linked_Version(); - SDL_NET_VERSION(&SDLcompiled) - I_OutputMsg("Compiled for SDL_Net version: %d.%d.%d\n", - SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); - I_OutputMsg("Linked with SDL_Net version: %d.%d.%d\n", - SDLlinked->major, SDLlinked->minor, SDLlinked->patch); - //if (!M_CheckParm ("-sdlnet")) - // return false; - // initilize the driver - I_InitSDLNetDriver(); - I_AddExitFunc(I_ShutdownSDLNetDriver); - if (!init_SDLNet_driver) - return false; - - if (M_CheckParm("-udpport")) - { - if (M_IsNextParm()) - sock_port = (UINT16)atoi(M_GetNextParm()); - else - sock_port = 0; - } - - // parse network game options, - if (M_CheckParm("-server") || dedicated) - { - server = true; - - // If a number of clients (i.e. nodes) is specified, the server will wait for the clients - // to connect before starting. - // If no number is specified here, the server starts with 1 client, and others can join - // in-game. - // Since Boris has implemented join in-game, there is no actual need for specifying a - // particular number here. - // FIXME: for dedicated server, numnodes needs to be set to 0 upon start -/* if (M_IsNextParm()) - doomcom->numnodes = (INT16)atoi(M_GetNextParm()); - else */if (dedicated) - doomcom->numnodes = 0; - else - doomcom->numnodes = 1; - - if (doomcom->numnodes < 0) - doomcom->numnodes = 0; - if (doomcom->numnodes > MAXNETNODES) - doomcom->numnodes = MAXNETNODES; - - // server - servernode = 0; - // FIXME: - // ??? and now ? - // server on a big modem ??? 4*isdn - net_bandwidth = 16000; - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - - ret = true; - } - else if (M_CheckParm("-connect")) - { - if (M_IsNextParm()) - strcpy(serverhostname, M_GetNextParm()); - else - serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it - - // server address only in ip - if (serverhostname[0]) - { - COM_BufAddText("connect \""); - COM_BufAddText(serverhostname); - COM_BufAddText("\"\n"); - - // probably modem - hardware_MAXPACKETLENGTH = INETPACKETLENGTH; - } - else - { - // so we're on a LAN - COM_BufAddText("connect any\n"); - - net_bandwidth = 800000; - hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; - } - } - - mypacket.maxlen = hardware_MAXPACKETLENGTH; - I_NetOpenSocket = NET_OpenSocket; - I_Ban = NET_Ban; - I_ClearBans = NET_ClearBans; - I_GetNodeAddress = NET_GetNodeAddress; - I_GetBenAddress = NET_GetBenAddress; - I_SetBanAddress = NET_SetBanAddress; - bannednode = NET_bannednode; - - return ret; -#else - if ( M_CheckParm ("-net") ) - { - I_Error("-net not supported, use -server and -connect\n" - "see docs for more\n"); - } - return false; -#endif -} -#endif