diff -Burb qsrc-pq350/net_dgrm.c qsrc-pq350-ssp/net_dgrm.c --- qsrc-pq350/net_dgrm.c 2002-09-18 10:04:46.000000000 -0700 +++ qsrc-pq350-ssp/net_dgrm.c 2003-10-20 12:22:54.000000000 -0700 @@ -1,3 +1,8 @@ +/* *** EXPERIMENTAL *** */ +#define SINGLE_SERVER_PORT +/* *** EXPERIMENTAL *** */ + + /* Copyright (C) 1996-1997 Id Software, Inc. @@ -1083,7 +1088,30 @@ if (control == -1) return NULL; if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + { +#ifdef SINGLE_SERVER_PORT + /* ProQuake 3.4 (and up) clients close their request socket + ** and make a new socket for the session. This means we + ** connected back to the wrong socket when accepting the + ** connection. So we look for a "bogus" request packet + ** from that client on a different port, and re-connect + ** back to that port instead. + */ + for (s = net_activeSockets; s; s = s->next) + { + if (s->driver != net_driverlevel || !s->net_wait) + continue; + ret = dfunc.AddrCompare(&clientaddr, &s->addr); + if (ret == 1) + { //same client, different port: reconnect back + dfunc.Connect (s->socket, &clientaddr); + /* TODO: check for failure, report error, etc */ return NULL; + } + } +#endif //SINGLE_SERVER_PORT + return NULL; + } if ((control & NETFLAG_LENGTH_MASK) != len) return NULL; @@ -1309,7 +1337,15 @@ return Datagram_Reject("Server is full.\n", acceptsock, &clientaddr); // allocate a network socket +#ifdef SINGLE_SERVER_PORT + { + struct qsockaddr oldaddr; + dfunc.GetSocketAddr(acceptsock, &oldaddr); + newsock = dfunc.OpenSocket(dfunc.GetSocketPort(&oldaddr)); + } +#else //SINGLE_SERVER_PORT newsock = dfunc.OpenSocket(0); +#endif //SINGLE_SERVER_PORT if (newsock == -1) { NET_FreeQSocket(sock); diff -Burb qsrc-pq350/net_udp.c qsrc-pq350-ssp/net_udp.c --- qsrc-pq350/net_udp.c 2002-05-27 11:27:18.000000000 -0700 +++ qsrc-pq350-ssp/net_udp.c 2003-10-16 13:11:13.000000000 -0700 @@ -1,3 +1,8 @@ +/* *** EXPERIMENTAL *** */ +#define SINGLE_SERVER_PORT +/* *** EXPERIMENTAL *** */ + + /* Copyright (C) 1996-1997 Id Software, Inc. @@ -175,6 +180,14 @@ if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1) goto ErrorReturn; +#ifdef SINGLE_SERVER_PORT + if (port) + { + int fReuse = 1; + setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, &fReuse, sizeof(fReuse)); + } +#endif //SINGLE_SERVER_PORT + memset(&address, 0, sizeof(struct sockaddr_in)); // JPG 1.05 - fix by JDC address.sin_family = AF_INET; address.sin_addr.s_addr = myAddr; // JPG - changed INADDR_ANY to myAddr @@ -260,7 +273,11 @@ int UDP_Connect (int socket, struct qsockaddr *addr) { +#ifdef SINGLE_SERVER_PORT + return connect(socket, (struct sockaddr *)addr, sizeof(*addr)); +#else //SINGLE_SERVER_PORT return 0; +#endif //SINGLE_SERVER_PORT } //=============================================================================