| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** 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 3 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.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "GameNetwork/NetworkUtil.h"
- Int MAX_FRAMES_AHEAD = 128;
- Int MIN_RUNAHEAD = 10;
- Int FRAME_DATA_LENGTH = (MAX_FRAMES_AHEAD+1)*2;
- Int FRAMES_TO_KEEP = (MAX_FRAMES_AHEAD/2) + 1;
- #ifdef DEBUG_LOGGING
- void dumpBufferToLog(const void *vBuf, Int len, const char *fname, Int line)
- {
- DEBUG_LOG(("======= dumpBufferToLog() %d bytes =======\n", len));
- DEBUG_LOG(("Source: %s:%d\n", fname, line));
- const char *buf = (const char *)vBuf;
- Int numLines = len / 8;
- if ((len % 8) != 0)
- {
- ++numLines;
- }
- for (Int dumpindex = 0; dumpindex < numLines; ++dumpindex)
- {
- Int offset = dumpindex*8;
- DEBUG_LOG(("\t%5.5d\t", offset));
- Int dumpindex2;
- Int numBytesThisLine = min(8, len - offset);
- for (dumpindex2 = 0; dumpindex2 < numBytesThisLine; ++dumpindex2)
- {
- Int c = (buf[offset + dumpindex2] & 0xff);
- DEBUG_LOG(("%02X ", c));
- }
- for (; dumpindex2 < 8; ++dumpindex2)
- {
- DEBUG_LOG((" "));
- }
- DEBUG_LOG((" | "));
- for (dumpindex2 = 0; dumpindex2 < numBytesThisLine; ++dumpindex2)
- {
- char c = buf[offset + dumpindex2];
- DEBUG_LOG(("%c", (isprint(c)?c:'.')));
- }
- DEBUG_LOG(("\n"));
- }
- DEBUG_LOG(("End of packet dump\n"));
- }
- #endif // DEBUG_LOGGING
- /**
- * ResolveIP turns a string ("games2.westwood.com", or "192.168.0.1") into
- * a 32-bit unsigned integer.
- */
- UnsignedInt ResolveIP(AsciiString host)
- {
- struct hostent *hostStruct;
- struct in_addr *hostNode;
- if (host.getLength() == 0)
- {
- DEBUG_LOG(("ResolveIP(): Can't resolve NULL\n"));
- return 0;
- }
- // String such as "127.0.0.1"
- if (isdigit(host.getCharAt(0)))
- {
- return ( ntohl(inet_addr(host.str())) );
- }
- // String such as "localhost"
- hostStruct = gethostbyname(host.str());
- if (hostStruct == NULL)
- {
- DEBUG_LOG(("ResolveIP(): Can't resolve %s\n", host.str()));
- return 0;
- }
- hostNode = (struct in_addr *) hostStruct->h_addr;
- return ( ntohl(hostNode->s_addr) );
- }
- /**
- * Returns the next network command ID.
- */
- UnsignedShort GenerateNextCommandID() {
- static UnsignedShort commandID = 64000;
- ++commandID;
- return commandID;
- }
- /**
- * Returns true if this type of command requires a unique command ID.
- */
- Bool DoesCommandRequireACommandID(NetCommandType type) {
- if ((type == NETCOMMANDTYPE_GAMECOMMAND) ||
- (type == NETCOMMANDTYPE_FRAMEINFO) ||
- (type == NETCOMMANDTYPE_PLAYERLEAVE) ||
- (type == NETCOMMANDTYPE_DESTROYPLAYER) ||
- (type == NETCOMMANDTYPE_RUNAHEADMETRICS) ||
- (type == NETCOMMANDTYPE_RUNAHEAD) ||
- (type == NETCOMMANDTYPE_CHAT) ||
- (type == NETCOMMANDTYPE_DISCONNECTVOTE) ||
- (type == NETCOMMANDTYPE_LOADCOMPLETE) ||
- (type == NETCOMMANDTYPE_TIMEOUTSTART) ||
- (type == NETCOMMANDTYPE_WRAPPER) ||
- (type == NETCOMMANDTYPE_FILE) ||
- (type == NETCOMMANDTYPE_FILEANNOUNCE) ||
- (type == NETCOMMANDTYPE_FILEPROGRESS) ||
- (type == NETCOMMANDTYPE_DISCONNECTPLAYER) ||
- (type == NETCOMMANDTYPE_DISCONNECTFRAME) ||
- (type == NETCOMMANDTYPE_DISCONNECTSCREENOFF) ||
- (type == NETCOMMANDTYPE_FRAMERESENDREQUEST))
- {
- return TRUE;
- }
- return FALSE;
- }
- /**
- * Returns true if this type of network command requires an ack.
- */
- Bool CommandRequiresAck(NetCommandMsg *msg) {
- if ((msg->getNetCommandType() == NETCOMMANDTYPE_GAMECOMMAND) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FRAMEINFO) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_PLAYERLEAVE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DESTROYPLAYER) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_RUNAHEADMETRICS) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_RUNAHEAD) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_CHAT) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTVOTE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTPLAYER) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_LOADCOMPLETE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_TIMEOUTSTART) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_WRAPPER) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FILE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FILEANNOUNCE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FILEPROGRESS) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTPLAYER) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTFRAME) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTSCREENOFF) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FRAMERESENDREQUEST))
- {
- return TRUE;
- }
- return FALSE;
- }
- Bool IsCommandSynchronized(NetCommandType type) {
- if ((type == NETCOMMANDTYPE_GAMECOMMAND) ||
- (type == NETCOMMANDTYPE_FRAMEINFO) ||
- (type == NETCOMMANDTYPE_PLAYERLEAVE) ||
- (type == NETCOMMANDTYPE_DESTROYPLAYER) ||
- (type == NETCOMMANDTYPE_RUNAHEAD))
- {
- return TRUE;
- }
- return FALSE;
- }
- /**
- * Returns true if this type of network command requires the ack to be sent directly to the player
- * rather than going through the packet router. This should really only be used by commands
- * used on the disconnect screen.
- */
- Bool CommandRequiresDirectSend(NetCommandMsg *msg) {
- if ((msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTVOTE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTPLAYER) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_LOADCOMPLETE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_TIMEOUTSTART) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FILE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FILEANNOUNCE) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FILEPROGRESS) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTFRAME) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_DISCONNECTSCREENOFF) ||
- (msg->getNetCommandType() == NETCOMMANDTYPE_FRAMERESENDREQUEST)) {
- return TRUE;
- }
- return FALSE;
- }
- AsciiString GetAsciiNetCommandType(NetCommandType type) {
- AsciiString s;
- if (type == NETCOMMANDTYPE_FRAMEINFO) {
- s.set("NETCOMMANDTYPE_FRAMEINFO");
- } else if (type == NETCOMMANDTYPE_GAMECOMMAND) {
- s.set("NETCOMMANDTYPE_GAMECOMMAND");
- } else if (type == NETCOMMANDTYPE_PLAYERLEAVE) {
- s.set("NETCOMMANDTYPE_PLAYERLEAVE");
- } else if (type == NETCOMMANDTYPE_RUNAHEADMETRICS) {
- s.set("NETCOMMANDTYPE_RUNAHEADMETRICS");
- } else if (type == NETCOMMANDTYPE_RUNAHEAD) {
- s.set("NETCOMMANDTYPE_RUNAHEAD");
- } else if (type == NETCOMMANDTYPE_DESTROYPLAYER) {
- s.set("NETCOMMANDTYPE_DESTROYPLAYER");
- } else if (type == NETCOMMANDTYPE_ACKBOTH) {
- s.set("NETCOMMANDTYPE_ACKBOTH");
- } else if (type == NETCOMMANDTYPE_ACKSTAGE1) {
- s.set("NETCOMMANDTYPE_ACKSTAGE1");
- } else if (type == NETCOMMANDTYPE_ACKSTAGE2) {
- s.set("NETCOMMANDTYPE_ACKSTAGE2");
- } else if (type == NETCOMMANDTYPE_FRAMEINFO) {
- s.set("NETCOMMANDTYPE_FRAMEINFO");
- } else if (type == NETCOMMANDTYPE_KEEPALIVE) {
- s.set("NETCOMMANDTYPE_KEEPALIVE");
- } else if (type == NETCOMMANDTYPE_DISCONNECTCHAT) {
- s.set("NETCOMMANDTYPE_DISCONNECTCHAT");
- } else if (type == NETCOMMANDTYPE_CHAT) {
- s.set("NETCOMMANDTYPE_CHAT");
- } else if (type == NETCOMMANDTYPE_MANGLERQUERY) {
- s.set("NETCOMMANDTYPE_MANGLERQUERY");
- } else if (type == NETCOMMANDTYPE_MANGLERRESPONSE) {
- s.set("NETCOMMANDTYPE_MANGLERRESPONSE");
- } else if (type == NETCOMMANDTYPE_DISCONNECTKEEPALIVE) {
- s.set("NETCOMMANDTYPE_DISCONNECTKEEPALIVE");
- } else if (type == NETCOMMANDTYPE_DISCONNECTPLAYER) {
- s.set("NETCOMMANDTYPE_DISCONNECTPLAYER");
- } else if (type == NETCOMMANDTYPE_PACKETROUTERQUERY) {
- s.set("NETCOMMANDTYPE_PACKETROUTERQUERY");
- } else if (type == NETCOMMANDTYPE_PACKETROUTERACK) {
- s.set("NETCOMMANDTYPE_PACKETROUTERACK");
- } else if (type == NETCOMMANDTYPE_DISCONNECTVOTE) {
- s.set("NETCOMMANDTYPE_DISCONNECTVOTE");
- } else if (type == NETCOMMANDTYPE_PROGRESS) {
- s.set("NETCOMMANDTYPE_PROGRESS");
- } else if (type == NETCOMMANDTYPE_LOADCOMPLETE) {
- s.set("NETCOMMANDTYPE_LOADCOMPLETE");
- } else if (type == NETCOMMANDTYPE_TIMEOUTSTART) {
- s.set("NETCOMMANDTYPE_TIMEOUTSTART");
- } else if (type == NETCOMMANDTYPE_WRAPPER) {
- s.set("NETCOMMANDTYPE_WRAPPER");
- } else if (type == NETCOMMANDTYPE_FILE) {
- s.set("NETCOMMANDTYPE_FILE");
- } else if (type == NETCOMMANDTYPE_FILEANNOUNCE) {
- s.set("NETCOMMANDTYPE_FILEANNOUNCE");
- } else if (type == NETCOMMANDTYPE_FILEPROGRESS) {
- s.set("NETCOMMANDTYPE_FILEPROGRESS");
- } else if (type == NETCOMMANDTYPE_DISCONNECTFRAME) {
- s.set("NETCOMMANDTYPE_DISCONNECTFRAME");
- } else if (type == NETCOMMANDTYPE_DISCONNECTSCREENOFF) {
- s.set("NETCOMMANDTYPE_DISCONNECTSCREENOFF");
- } else if (type == NETCOMMANDTYPE_FRAMERESENDREQUEST) {
- s.set("NETCOMMANDTYPE_FRAMERESENDREQUEST");
- } else {
- s.set("UNKNOWN");
- }
- return s;
- }
|