Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
parent
2e338c00cb
commit
3d0ee53a05
6072 changed files with 2283311 additions and 0 deletions
106
Generals/Code/GameEngine/Include/GameNetwork/Connection.h
Normal file
106
Generals/Code/GameEngine/Include/GameNetwork/Connection.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Connection class handles queues for individual players, one connection per player.
|
||||
* Connections are identified by their names (m_name). This should accomodate changing IPs
|
||||
* in the face of modem disconnects, NAT irregularities, etc.
|
||||
* Messages can be guaranteed or non-guaranteed, sequenced or not.
|
||||
*
|
||||
*
|
||||
* So how this works is this:
|
||||
* The connection contains the incoming and outgoing commands to and from the player this
|
||||
* connection object represents. The incoming packets are separated into the different frames
|
||||
* of execution. This is done for efficiency reasons since we will be keeping track of commands
|
||||
* that are to be executed on many different frames, and they will need to be retrieved by the
|
||||
* connection manager on a per-frame basis. We don't really care what frame the outgoing
|
||||
* commands are executed on as they all need to be sent out right away to ensure that the commands
|
||||
* get to their destination in time.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CONNECTION_H
|
||||
#define __CONNECTION_H
|
||||
|
||||
#include "GameNetwork/NetCommandList.h"
|
||||
#include "GameNetwork/User.h"
|
||||
#include "GameNetwork/transport.h"
|
||||
#include "GameNetwork/NetPacket.h"
|
||||
|
||||
#define CONNECTION_LATENCY_HISTORY_LENGTH 200
|
||||
|
||||
class Connection : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Connection, "Connection")
|
||||
public:
|
||||
Connection();
|
||||
//~Connection();
|
||||
|
||||
void update();
|
||||
void init();
|
||||
void reset();
|
||||
|
||||
UnsignedInt doSend();
|
||||
void doRecv();
|
||||
|
||||
Bool allCommandsReady(UnsignedInt frame);
|
||||
Bool isQueueEmpty();
|
||||
void attachTransport(Transport *transport);
|
||||
void setUser(User *user);
|
||||
User *getUser();
|
||||
void setFrameGrouping(time_t frameGrouping);
|
||||
|
||||
void sendNetCommandMsg(NetCommandMsg *msg, UnsignedByte relay);
|
||||
|
||||
// These two processAck calls do the same thing, just take different types of ACK commands.
|
||||
NetCommandRef * processAck(NetAckBothCommandMsg *msg);
|
||||
NetCommandRef * processAck(NetAckStage1CommandMsg *msg);
|
||||
NetCommandRef * processAck(NetCommandMsg *msg);
|
||||
NetCommandRef * processAck(UnsignedShort commandID, UnsignedByte originalPlayerID);
|
||||
|
||||
void clearCommandsExceptFrom( Int playerIndex );
|
||||
|
||||
void setQuitting( void );
|
||||
Bool isQuitting( void ) { return m_isQuitting; }
|
||||
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
void debugPrintCommands();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void doRetryMetrics();
|
||||
|
||||
Bool m_isQuitting;
|
||||
UnsignedInt m_quitTime;
|
||||
|
||||
Transport *m_transport;
|
||||
User *m_user;
|
||||
|
||||
NetCommandList *m_netCommandList;
|
||||
time_t m_retryTime; ///< The time between sending retry packets for this connection. Time is in milliseconds.
|
||||
Real m_averageLatency; ///< The average time between sending a command and receiving an ACK.
|
||||
Real m_latencies[CONNECTION_LATENCY_HISTORY_LENGTH]; ///< List of the last 100 latencies.
|
||||
|
||||
time_t m_frameGrouping; ///< The minimum time between packet sends.
|
||||
time_t m_lastTimeSent; ///< The time of the last packet send.
|
||||
Int m_numRetries; ///< The number of retries for the last second.
|
||||
time_t m_retryMetricsTime; ///< The start time of the current retry metrics thing.
|
||||
};
|
||||
|
||||
#endif
|
221
Generals/Code/GameEngine/Include/GameNetwork/ConnectionManager.h
Normal file
221
Generals/Code/GameEngine/Include/GameNetwork/ConnectionManager.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The connection manager maintains a collection of Connections to each player. Messages are queued up
|
||||
* from here, as well as removed through here.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CONNECTIONMANAGER_H
|
||||
#define __CONNECTIONMANAGER_H
|
||||
|
||||
#include "GameNetwork/Connection.h"
|
||||
#include "GameNetwork/NetCommandList.h"
|
||||
#include "GameNetwork/Transport.h"
|
||||
#include "GameNetwork/FrameDataManager.h"
|
||||
#include "GameNetwork/FrameMetrics.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "GameNetwork/DisconnectManager.h"
|
||||
|
||||
class GameInfo;
|
||||
class NetCommandWrapperList;
|
||||
|
||||
typedef std::map<UnsignedShort, AsciiString> FileCommandMap;
|
||||
typedef std::map<UnsignedShort, UnsignedByte> FileMaskMap;
|
||||
typedef std::map<UnsignedShort, Int> FileProgressMap;
|
||||
|
||||
class ConnectionManager
|
||||
{
|
||||
public:
|
||||
ConnectionManager();
|
||||
~ConnectionManager();
|
||||
|
||||
virtual void init(); ///< Initialize this instance.
|
||||
virtual void reset(); ///< Take this instance back to the initial state.
|
||||
virtual void update(Bool isInGame); ///< Service the Connections being managed by this instance.
|
||||
|
||||
// End SubsystemInterface functions
|
||||
|
||||
void updateRunAhead(Int oldRunAhead, Int frameRate, Bool didSelfSlug, Int nextExecutionFrame); ///< Update the run ahead value. If we are the current packet router, issue the command.
|
||||
|
||||
void attachTransport(Transport *transport);
|
||||
|
||||
void parseUserList(const GameInfo *game);
|
||||
void sendChat(UnicodeString text, Int playerMask, UnsignedInt executionFrame);
|
||||
void sendDisconnectChat(UnicodeString text);
|
||||
void sendLocalCommand(NetCommandMsg *msg, UnsignedByte relay = 0xff); ///< Send command to the players specified in the relay, goes through packet router.
|
||||
void sendLocalCommandDirect(NetCommandMsg *msg, UnsignedByte relay); ///< Send command directly to the players specified, doesn't go through packet router.
|
||||
void sendLocalGameMessage(GameMessage *msg, UnsignedInt frame);
|
||||
void sendCommand(NetCommandMsg *msg);
|
||||
Bool allCommandsReady(UnsignedInt frame, Bool justTesting = FALSE);
|
||||
void handleAllCommandsReady(void);
|
||||
NetCommandList *getFrameCommandList(UnsignedInt frame);
|
||||
// void AddConnection(User *user, UnsignedInt slot);
|
||||
void determineRouterFallbackPlan();
|
||||
void zeroFrames(UnsignedInt startingFrame, UnsignedInt numFrames);
|
||||
void destroyGameMessages();
|
||||
// void createConnections(UnsignedInt numberOfPlayers, UnsignedInt localSlot);
|
||||
void setLocalAddress(UnsignedInt ip, UnsignedInt port);
|
||||
void initTransport();
|
||||
void processFrameTick(UnsignedInt frame);
|
||||
void handleLocalPlayerLeaving(UnsignedInt frame);
|
||||
|
||||
void sendFile(AsciiString path, UnsignedByte playerMask, UnsignedShort commandID);
|
||||
UnsignedShort sendFileAnnounce(AsciiString path, UnsignedByte playerMask);
|
||||
Int getFileTransferProgress(Int playerID, AsciiString path);
|
||||
Bool areAllQueuesEmpty(void);
|
||||
|
||||
UnsignedInt getLocalPlayerID();
|
||||
UnicodeString getPlayerName(Int playerNum);
|
||||
Int getNumPlayers();
|
||||
|
||||
UnsignedInt getPacketRouterFallbackSlot(Int packetRouterNumber); ///< Returns the slot of the given packet router number in the fallback plan.
|
||||
UnsignedInt getPacketRouterSlot(); ///< Returns the current packet router's slot.
|
||||
PlayerLeaveCode disconnectPlayer(Int slot); ///< Disconnect this player immediately. This should only be called by the disconnect manager.
|
||||
void disconnectLocalPlayer(); ///< Does whatever is necessary to get TheNetwork to realize that it should be leaving the game now.
|
||||
void quitGame(); ///< Disconnect from the game RIGHT NOW!! Tell everyone else we are disconnecting.
|
||||
|
||||
void voteForPlayerDisconnect(Int slot); ///< Register a vote for a player to be disconnected.
|
||||
|
||||
void resendPendingCommands(); ///< Resend the pending commands to the packet router.
|
||||
|
||||
void setFrameGrouping(time_t frameGrouping); ///< Set the number of frames that are grouped together into packets.
|
||||
|
||||
PlayerLeaveCode processPlayerLeave(NetPlayerLeaveCommandMsg *msg);
|
||||
Bool canILeave(); ///< Returns true if the local player is allowed to leave.
|
||||
|
||||
// Bandwidth metrics
|
||||
Real getIncomingBytesPerSecond( void );
|
||||
Real getIncomingPacketsPerSecond( void );
|
||||
Real getOutgoingBytesPerSecond( void );
|
||||
Real getOutgoingPacketsPerSecond( void );
|
||||
Real getUnknownBytesPerSecond( void );
|
||||
Real getUnknownPacketsPerSecond( void );
|
||||
UnsignedInt getPacketArrivalCushion( void );
|
||||
|
||||
UnsignedInt getMinimumCushion();
|
||||
|
||||
void flushConnections();
|
||||
|
||||
void processChat(NetChatCommandMsg *msg); // this actually needs to be public because it is frame-synchronized
|
||||
|
||||
void updateLoadProgress( Int progress );
|
||||
void loadProgressComplete( void );
|
||||
void sendTimeOutGameStart( void );
|
||||
|
||||
Bool isPacketRouter( void );
|
||||
|
||||
Bool isPlayerConnected( Int playerID );
|
||||
|
||||
void notifyOthersOfCurrentFrame(Int frame);
|
||||
void sendFrameDataToPlayer(UnsignedInt playerID, UnsignedInt startingFrame);
|
||||
void sendSingleFrameToPlayer(UnsignedInt playerID, UnsignedInt frame);
|
||||
void notifyOthersOfNewFrame(UnsignedInt frame);
|
||||
|
||||
UnsignedInt getNextPacketRouterSlot(UnsignedInt playerID); ///< returns the packet router player that comes after the given player.
|
||||
|
||||
Int getAverageFPS( void );
|
||||
Int getSlotAverageFPS(Int slot);
|
||||
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
void debugPrintConnectionCommands();
|
||||
#endif
|
||||
|
||||
// For disconnect blame assignment
|
||||
UnsignedInt getPingFrame();
|
||||
Int getPingsSent();
|
||||
Int getPingsRecieved();
|
||||
|
||||
private:
|
||||
void doRelay();
|
||||
void doKeepAlive();
|
||||
void sendRemoteCommand(NetCommandRef *msg);
|
||||
void ackCommand(NetCommandRef *ref, UnsignedInt localSlot);
|
||||
|
||||
Bool processNetCommand(NetCommandRef *ref);
|
||||
void processAckStage1(NetCommandMsg *msg);
|
||||
void processAckStage2(NetCommandMsg *msg);
|
||||
void processAck(NetCommandMsg *msg);
|
||||
void processFrameInfo(NetFrameCommandMsg *msg);
|
||||
void processRunAheadMetrics(NetRunAheadMetricsCommandMsg *msg);
|
||||
void processDisconnectChat(NetDisconnectChatCommandMsg *msg);
|
||||
void processProgress( NetProgressCommandMsg *msg );
|
||||
void processLoadComplete( NetCommandMsg *msg );
|
||||
void processTimeOutGameStart( NetCommandMsg *msg );
|
||||
void processWrapper(NetCommandRef *ref);
|
||||
void processFrameResendRequest(NetFrameResendRequestCommandMsg *msg);
|
||||
|
||||
void processFile(NetFileCommandMsg *ref);
|
||||
void processFileAnnounce(NetFileAnnounceCommandMsg *ref);
|
||||
void processFileProgress(NetFileProgressCommandMsg *ref);
|
||||
|
||||
// void doPerFrameMetrics(UnsignedInt frame);
|
||||
void getMinimumFps(Int &minFps, Int &minFpsPlayer); ///< Returns the smallest FPS in the m_fpsAverages list.
|
||||
Real getMaximumLatency(); ///< This actually sums the two biggest latencies in the m_latencyAverages list.
|
||||
|
||||
void requestFrameDataResend(Int playerID, UnsignedInt frame); ///< request of this player that he send the specified frame's data.
|
||||
|
||||
// The connections are set up like the slot list. The connection corresponding to the local
|
||||
// player's position in the slot list will be NULL. Connections corresponding to slots that
|
||||
// do not have a player will also be NULL.
|
||||
Connection *m_connections[MAX_SLOTS];
|
||||
|
||||
Transport *m_transport;
|
||||
UnsignedInt m_localSlot;
|
||||
UnsignedInt m_packetRouterSlot;
|
||||
UnsignedInt m_packetRouterFallback[MAX_SLOTS];
|
||||
UnsignedInt m_localAddr;
|
||||
UnsignedInt m_localPort;
|
||||
User* m_localUser;
|
||||
|
||||
DisconnectManager *m_disconnectManager; ///< Controls the disconnect dialog.
|
||||
|
||||
FrameDataManager *m_frameData[MAX_SLOTS];
|
||||
|
||||
NetCommandList *m_pendingCommands;
|
||||
NetCommandList *m_relayedCommands;
|
||||
|
||||
FrameMetrics m_frameMetrics;
|
||||
|
||||
NetCommandWrapperList *m_netCommandWrapperList;
|
||||
|
||||
// These variables are used to keep track of the other players' average fps and latency.
|
||||
// yup.
|
||||
Real m_latencyAverages[MAX_SLOTS];
|
||||
Int m_fpsAverages[MAX_SLOTS];
|
||||
Int m_minFpsPlayer;
|
||||
Int m_minFps;
|
||||
UnsignedInt m_smallestPacketArrivalCushion;
|
||||
Bool m_didSelfSlug;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
FileCommandMap s_fileCommandMap;
|
||||
FileMaskMap s_fileRecipientMaskMap;
|
||||
FileProgressMap s_fileProgressMap[MAX_SLOTS];
|
||||
// -----------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
#endif
|
133
Generals/Code/GameEngine/Include/GameNetwork/DisconnectManager.h
Normal file
133
Generals/Code/GameEngine/Include/GameNetwork/DisconnectManager.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DISCONNECTMANAGER_H
|
||||
#define __DISCONNECTMANAGER_H
|
||||
|
||||
#include "GameNetwork/NetCommandRef.h"
|
||||
#include "Lib/BaseType.h"
|
||||
//#include "GameNetwork/ConnectionManager.h"
|
||||
|
||||
enum DisconnectStateType {
|
||||
DISCONNECTSTATETYPE_SCREENON,
|
||||
DISCONNECTSTATETYPE_SCREENOFF
|
||||
// DISCONNECTSTATETYPE_WAITINGFORPACKETROUTER
|
||||
};
|
||||
|
||||
class ConnectionManager;
|
||||
|
||||
struct DisconnectVoteStruct {
|
||||
Bool vote;
|
||||
UnsignedInt frame;
|
||||
};
|
||||
|
||||
class DisconnectManager
|
||||
{
|
||||
public:
|
||||
DisconnectManager();
|
||||
virtual ~DisconnectManager();
|
||||
|
||||
void init();
|
||||
void update(ConnectionManager *conMgr);
|
||||
|
||||
void processDisconnectCommand(NetCommandRef *ref, ConnectionManager *conMgr);
|
||||
void allCommandsReady(UnsignedInt frame, ConnectionManager *conMgr, Bool waitForPacketRouter = TRUE);
|
||||
void nextFrame(UnsignedInt frame, ConnectionManager *conMgr);
|
||||
Bool allowedToContinue(); ///< Allow the next frame to go through?
|
||||
void playerHasAdvancedAFrame(Int slot, UnsignedInt frame); ///< this player has advanced to that frame.
|
||||
|
||||
void voteForPlayerDisconnect(Int slot, ConnectionManager *conMgr);
|
||||
|
||||
// For disconnect blame assignment
|
||||
UnsignedInt getPingFrame();
|
||||
Int getPingsSent();
|
||||
Int getPingsRecieved();
|
||||
|
||||
protected:
|
||||
void sendKeepAlive(ConnectionManager *conMgr);
|
||||
void populateDisconnectScreen(ConnectionManager *conMgr);
|
||||
Int translatedSlotPosition(Int slot, Int localSlot);
|
||||
Int untranslatedSlotPosition(Int slot, Int localSlot);
|
||||
void resetPlayerTimeouts(ConnectionManager *conMgr);
|
||||
void resetPlayerTimeout(Int slot);
|
||||
void resetPacketRouterTimeout();
|
||||
void updateDisconnectStatus(ConnectionManager *conMgr);
|
||||
void disconnectPlayer(Int slot, ConnectionManager *conMgr);
|
||||
void sendDisconnectCommand(Int slot, ConnectionManager *conMgr);
|
||||
void sendVoteCommand(Int slot, ConnectionManager *conMgr);
|
||||
void updateWaitForPacketRouter(ConnectionManager *conMgr);
|
||||
void recalculatePacketRouterIndex(ConnectionManager *conMgr);
|
||||
Bool allOnSameFrame(ConnectionManager *conMgr); ///< returns true if all players are stuck on the same frame.
|
||||
Bool isLocalPlayerNextPacketRouter(ConnectionManager *conMgr); ///< returns true if the local player is next in line to be the packet router with all the players that have timed out being taken out of the picture.
|
||||
Bool hasPlayerTimedOut(Int slot); ///< returns true if this player has timed out.
|
||||
void sendPlayerDestruct(Int slot, ConnectionManager *conMgr); ///< send a destruct player network message.
|
||||
Bool isPlayerVotedOut(Int slot, ConnectionManager *conMgr); ///< returns true if this player has been voted out.
|
||||
Bool isPlayerInGame(Int slot, ConnectionManager *conMgr); ///< returns true if the player has neither timed out or been voted out.
|
||||
UnsignedInt getMaxDisconnectFrame(); ///< returns the highest frame that people have got to.
|
||||
Int countVotesForPlayer(Int slot); ///< return the number of disconnect votes a player has.
|
||||
void resetPlayersVotes(Int playerID, UnsignedInt frame, ConnectionManager *conMgr); ///< reset the votes for this player.
|
||||
|
||||
void turnOnScreen(ConnectionManager *conMgr); ///< This gets called when the disconnect screen is first turned on.
|
||||
|
||||
void processDisconnectKeepAlive(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
void processDisconnectPlayer(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
void processPacketRouterQuery(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
void processPacketRouterAck(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
void processDisconnectVote(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
void processDisconnectFrame(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
void processDisconnectScreenOff(NetCommandMsg *msg, ConnectionManager *conMgr);
|
||||
|
||||
void applyDisconnectVote(Int slot, UnsignedInt frame, Int castingSlot, ConnectionManager *conMgr);
|
||||
|
||||
UnsignedInt m_lastFrame;
|
||||
time_t m_lastFrameTime;
|
||||
DisconnectStateType m_disconnectState;
|
||||
|
||||
UnsignedInt m_packetRouterFallback[MAX_SLOTS];
|
||||
UnsignedInt m_currentPacketRouterIndex;
|
||||
|
||||
time_t m_lastKeepAliveSendTime;
|
||||
|
||||
time_t m_playerTimeouts[MAX_SLOTS - 1];
|
||||
time_t m_packetRouterTimeout;
|
||||
|
||||
DisconnectVoteStruct m_playerVotes[MAX_SLOTS][MAX_SLOTS];
|
||||
// Bool m_myVotes[MAX_SLOTS - 1];
|
||||
|
||||
UnsignedInt m_disconnectFrames[MAX_SLOTS];
|
||||
Bool m_disconnectFramesReceived[MAX_SLOTS];
|
||||
Bool m_haveNotifiedOtherPlayersOfCurrentFrame;
|
||||
|
||||
time_t m_timeOfDisconnectScreenOn;
|
||||
|
||||
Int m_pingsSent;
|
||||
Int m_pingsRecieved;
|
||||
UnsignedInt m_pingFrame;
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef __DISCONNECTMANAGER_H
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DownloadManager.h //////////////////////////////////////////////////////
|
||||
// Generals download class definitions
|
||||
// Author: Matthew D. Campbell, July 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DOWNLOADMANAGER_H__
|
||||
#define __DOWNLOADMANAGER_H__
|
||||
|
||||
#include "WWDownload/downloadDefs.h"
|
||||
#include "WWDownload/download.h"
|
||||
|
||||
class CDownload;
|
||||
class QueuedDownload
|
||||
{
|
||||
public:
|
||||
AsciiString server;
|
||||
AsciiString userName;
|
||||
AsciiString password;
|
||||
AsciiString file;
|
||||
AsciiString localFile;
|
||||
AsciiString regKey;
|
||||
Bool tryResume;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DownloadManager
|
||||
|
||||
class DownloadManager : public IDownload
|
||||
{
|
||||
public:
|
||||
DownloadManager();
|
||||
virtual ~DownloadManager();
|
||||
|
||||
public:
|
||||
void init( void );
|
||||
HRESULT update( void );
|
||||
void reset( void );
|
||||
|
||||
virtual HRESULT OnError( Int error );
|
||||
virtual HRESULT OnEnd();
|
||||
virtual HRESULT OnQueryResume();
|
||||
virtual HRESULT OnProgressUpdate( Int bytesread, Int totalsize, Int timetaken, Int timeleft );
|
||||
virtual HRESULT OnStatusUpdate( Int status );
|
||||
|
||||
virtual HRESULT downloadFile( AsciiString server, AsciiString username, AsciiString password, AsciiString file, AsciiString localfile, AsciiString regkey, Bool tryResume );
|
||||
AsciiString getLastLocalFile( void );
|
||||
|
||||
Bool isDone( void ) { return m_sawEnd || m_wasError; }
|
||||
Bool isOk( void ) { return m_sawEnd; }
|
||||
Bool wasError( void ) { return m_wasError; }
|
||||
|
||||
UnicodeString getStatusString( void ) { return m_statusString; }
|
||||
UnicodeString getErrorString( void ) { return m_errorString; }
|
||||
|
||||
void queueFileForDownload( AsciiString server, AsciiString username, AsciiString password, AsciiString file, AsciiString localfile, AsciiString regkey, Bool tryResume );
|
||||
Bool isFileQueuedForDownload( void ) { return !m_queuedDownloads.empty(); }
|
||||
HRESULT downloadNextQueuedFile( void );
|
||||
|
||||
private:
|
||||
Bool m_winsockInit;
|
||||
CDownload *m_download;
|
||||
Bool m_wasError;
|
||||
Bool m_sawEnd;
|
||||
UnicodeString m_errorString;
|
||||
UnicodeString m_statusString;
|
||||
|
||||
protected:
|
||||
std::list<QueuedDownload> m_queuedDownloads;
|
||||
};
|
||||
|
||||
extern DownloadManager *TheDownloadManager;
|
||||
|
||||
#endif // __DOWNLOADMANAGER_H__
|
52
Generals/Code/GameEngine/Include/GameNetwork/FileTransfer.h
Normal file
52
Generals/Code/GameEngine/Include/GameNetwork/FileTransfer.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// FILE: FileTransfer.h
|
||||
// Author: Matthew D. Campbell, December 2002
|
||||
// Description: File Transfer wrapper using TheNetwork
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
#ifndef __FILE_TRANSFER_H__
|
||||
#define __FILE_TRANSFER_H__
|
||||
|
||||
class GameInfo;
|
||||
|
||||
// Convenience functions
|
||||
AsciiString GetBasePathFromPath( AsciiString path );
|
||||
AsciiString GetFileFromPath( AsciiString path );
|
||||
AsciiString GetExtensionFromFile( AsciiString fname );
|
||||
AsciiString GetBaseFileFromFile( AsciiString fname );
|
||||
AsciiString GetPreviewFromMap( AsciiString path );
|
||||
AsciiString GetINIFromMap( AsciiString path );
|
||||
AsciiString GetStrFileFromMap( AsciiString path );
|
||||
AsciiString GetSoloINIFromMap( AsciiString path );
|
||||
AsciiString GetAssetUsageFromMap( AsciiString path );
|
||||
AsciiString GetReadmeFromMap( AsciiString path );
|
||||
|
||||
// The meat of file (map) transfers
|
||||
Bool DoAnyMapTransfers(GameInfo *game);
|
||||
|
||||
#endif // __FILE_TRANSFER_H__
|
314
Generals/Code/GameEngine/Include/GameNetwork/FirewallHelper.h
Normal file
314
Generals/Code/GameEngine/Include/GameNetwork/FirewallHelper.h
Normal file
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /RedAlert2/NAT.CPP $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 3/15/01 12:00PM $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FIREWALLHELPER_H
|
||||
#define __FIREWALLHELPER_H
|
||||
|
||||
class UDP;
|
||||
|
||||
#define NUM_TEST_PORTS 4
|
||||
#define MAX_SPARE_SOCKETS 8
|
||||
|
||||
/*
|
||||
**
|
||||
** Class to help in dealing with firewalls.
|
||||
**
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
struct SpareSocketStruct {
|
||||
UDP *udp;
|
||||
UnsignedShort port;
|
||||
};
|
||||
|
||||
enum FirewallDetectionState {
|
||||
DETECTIONSTATE_IDLE,
|
||||
DETECTIONSTATE_BEGIN,
|
||||
DETECTIONSTATE_TEST1,
|
||||
DETECTIONSTATE_TEST2,
|
||||
DETECTIONSTATE_TEST3,
|
||||
DETECTIONSTATE_TEST3_WAITFORRESPONSES,
|
||||
DETECTIONSTATE_TEST4_1,
|
||||
DETECTIONSTATE_TEST4_2,
|
||||
DETECTIONSTATE_TEST5,
|
||||
DETECTIONSTATE_DONE
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// size = 16 bytes
|
||||
struct ManglerData {
|
||||
unsigned int CRC;
|
||||
unsigned short magic;
|
||||
unsigned short PacketID;
|
||||
unsigned short MyMangledPortNumber;
|
||||
unsigned short OriginalPortNumber;
|
||||
unsigned char MyMangledAddress[4];
|
||||
unsigned char NetCommandType;
|
||||
unsigned char BlitzMe;
|
||||
unsigned short Padding;
|
||||
};
|
||||
|
||||
// size = TransportMessageHeader + ManglerData + 10 bytes = 26 bytes
|
||||
struct ManglerMessage {
|
||||
ManglerData data;
|
||||
int length;
|
||||
unsigned int ip;
|
||||
unsigned short port;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static const Int MAX_NUM_MANGLERS = 4;
|
||||
static const UnsignedShort MANGLER_PORT = 4321;
|
||||
|
||||
class FirewallHelperClass {
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
** Enumeration of firewall behaviors we can detect.
|
||||
**
|
||||
** It is assumed that all port mangling firewalls change the mangled source port in response to
|
||||
** an application source port change.
|
||||
*/
|
||||
typedef enum tFirewallBehaviorType {
|
||||
|
||||
FIREWALL_MIN = 0,
|
||||
|
||||
/*
|
||||
** Just used as an initialiser.
|
||||
*/
|
||||
FIREWALL_TYPE_UNKNOWN = 0,
|
||||
|
||||
/*
|
||||
** This is a simple, non-port translating firewall, or there is no firewall at all.
|
||||
*/
|
||||
FIREWALL_TYPE_SIMPLE = 1,
|
||||
|
||||
/*
|
||||
** This is a firewall/NAT with port mangling but it's pretty dumb - it uses the same mangled
|
||||
** source port regardless of the destination address.
|
||||
*/
|
||||
FIREWALL_TYPE_DUMB_MANGLING = 2,
|
||||
|
||||
/*
|
||||
** This is a smarter firewall/NAT with port mangling that uses different mangled source ports
|
||||
** for different destination IPs.
|
||||
*/
|
||||
FIREWALL_TYPE_SMART_MANGLING = 4,
|
||||
|
||||
/*
|
||||
** This is a firewall that exhibits the bug as seen in the Netgear firewalls. A previously good
|
||||
** source port mapping will change in response to unsolicited traffic from a known IP.
|
||||
*/
|
||||
FIREWALL_TYPE_NETGEAR_BUG = 8,
|
||||
|
||||
/*
|
||||
** This firewall has a simple absolute offset port allocation scheme.
|
||||
*/
|
||||
FIREWALL_TYPE_SIMPLE_PORT_ALLOCATION = 16,
|
||||
|
||||
/*
|
||||
** This firewall has a relative offset port allocation scheme. For these firewalls, we have to
|
||||
** subtract the actual source port from the mangled source port to discover the allocation scheme.
|
||||
** The mangled port number is based in part on the original source port number.
|
||||
*/
|
||||
FIREWALL_TYPE_RELATIVE_PORT_ALLOCATION = 32,
|
||||
|
||||
/*
|
||||
** This firewall mangles source ports differently depending on the destination port.
|
||||
*/
|
||||
FIREWALL_TYPE_DESTINATION_PORT_DELTA = 64,
|
||||
|
||||
FIREWALL_MAX = 128
|
||||
|
||||
} FirewallBehaviorType;
|
||||
|
||||
|
||||
|
||||
FirewallHelperClass(void);
|
||||
virtual ~FirewallHelperClass(void);
|
||||
Bool detectFirewall(void);
|
||||
UnsignedShort getRawFirewallBehavior(void) {return((UnsignedShort)m_behavior);}
|
||||
Short getSourcePortAllocationDelta(void);
|
||||
Int getFirewallHardness(FirewallBehaviorType behavior);
|
||||
Int getFirewallRetries(FirewallBehaviorType behavior);
|
||||
void setSourcePortPoolStart(Int port) {m_sourcePortPool = port;};
|
||||
Int getSourcePortPool(void) {return(m_sourcePortPool);};
|
||||
void readFirewallBehavior(void);
|
||||
void reset(void);
|
||||
Bool behaviorDetectionUpdate(void);
|
||||
|
||||
FirewallBehaviorType getFirewallBehavior(void);
|
||||
void writeFirewallBehavior(void);
|
||||
|
||||
void flagNeedToRefresh(Bool flag);
|
||||
|
||||
static void getManglerName(Int manglerIndex, Char *nameBuf);
|
||||
Bool sendToManglerFromPort(UnsignedInt address, UnsignedShort port, UnsignedShort packetID, Bool blitzme = FALSE);
|
||||
UnsignedShort getManglerResponse(UnsignedShort packetID, Int time = 0);
|
||||
Bool openSpareSocket(UnsignedShort port);
|
||||
void closeSpareSocket(UnsignedShort port);
|
||||
void closeAllSpareSockets();
|
||||
UnsignedShort getNextTemporarySourcePort(Int skip);
|
||||
|
||||
Bool detectionBeginUpdate(void);
|
||||
Bool detectionTest1Update(void);
|
||||
Bool detectionTest2Update(void);
|
||||
Bool detectionTest3Update(void);
|
||||
Bool detectionTest3WaitForResponsesUpdate(void);
|
||||
Bool detectionTest4Stage1Update(void);
|
||||
Bool detectionTest4Stage2Update(void);
|
||||
Bool detectionTest5Update(void);
|
||||
|
||||
|
||||
/*
|
||||
** Behavior query functions.
|
||||
*/
|
||||
inline Bool isNAT(void) {
|
||||
if (m_behavior == FIREWALL_TYPE_UNKNOWN || (m_behavior & FIREWALL_TYPE_SIMPLE) != 0) {
|
||||
return(FALSE);
|
||||
}
|
||||
return(TRUE);
|
||||
};
|
||||
|
||||
inline Bool isNAT(FirewallBehaviorType behavior) {
|
||||
if (behavior == FIREWALL_TYPE_UNKNOWN || (behavior & FIREWALL_TYPE_SIMPLE) != 0) {
|
||||
return(FALSE);
|
||||
}
|
||||
return(TRUE);
|
||||
};
|
||||
|
||||
inline Bool isNetgear(FirewallBehaviorType behavior) {
|
||||
if ((behavior & FIREWALL_TYPE_NETGEAR_BUG) != 0) {
|
||||
return(TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
};
|
||||
|
||||
inline Bool isNetgear(void) {
|
||||
if ((m_behavior & FIREWALL_TYPE_NETGEAR_BUG) != 0) {
|
||||
return(TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Int getNATPortAllocationScheme(Int numPorts, UnsignedShort *originalPorts, UnsignedShort *mangledPorts, Bool &relativeDelta, Bool &looksGood);
|
||||
void detectFirewallBehavior(/*Bool &canRecord*/);
|
||||
Bool getReferencePort(void);
|
||||
|
||||
SpareSocketStruct * findSpareSocketByPort(UnsignedShort port);
|
||||
ManglerMessage * findEmptyMessage();
|
||||
|
||||
void byteAdjust(ManglerData *data);
|
||||
|
||||
/*
|
||||
** How does our firewall behave?
|
||||
*/
|
||||
FirewallBehaviorType m_behavior;
|
||||
|
||||
/*
|
||||
** How did the firewall behave the last time we ran the game.
|
||||
*/
|
||||
FirewallBehaviorType m_lastBehavior;
|
||||
|
||||
/*
|
||||
** What is the delta in our firewalls NAT port allocation scheme.
|
||||
*/
|
||||
Int m_sourcePortAllocationDelta;
|
||||
|
||||
/*
|
||||
** What was the delta the last time we ran?
|
||||
*/
|
||||
Int m_lastSourcePortAllocationDelta;
|
||||
|
||||
/*
|
||||
** Source ports used only to discover port allocation patterns.
|
||||
** Needs to be static so that previous communications with the manglers
|
||||
** don't affect the current one.
|
||||
*/
|
||||
static Int m_sourcePortPool;
|
||||
|
||||
/*
|
||||
** Spare sockets used for detecting mangling and such.
|
||||
*/
|
||||
SpareSocketStruct m_spareSockets[MAX_SPARE_SOCKETS];
|
||||
|
||||
UnsignedInt m_manglers[MAX_NUM_MANGLERS];
|
||||
Int m_numManglers;
|
||||
|
||||
UnsignedShort m_sparePorts[MAX_SPARE_SOCKETS];
|
||||
UnsignedShort m_mangledPorts[MAX_SPARE_SOCKETS];
|
||||
UnsignedShort m_packetID;
|
||||
|
||||
ManglerMessage m_messages[MAX_SPARE_SOCKETS];
|
||||
|
||||
FirewallDetectionState m_currentState;
|
||||
time_t m_timeoutStart;
|
||||
time_t m_timeoutLength;
|
||||
|
||||
Int m_numResponses;
|
||||
Int m_currentTry;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern FirewallHelperClass *TheFirewallHelper;
|
||||
FirewallHelperClass * createFirewallHelper();
|
||||
|
||||
|
||||
#endif // __FIREWALLHELPER_H
|
||||
|
69
Generals/Code/GameEngine/Include/GameNetwork/FrameData.h
Normal file
69
Generals/Code/GameEngine/Include/GameNetwork/FrameData.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRAMEDATA_H
|
||||
#define __FRAMEDATA_H
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
#include "GameNetwork/NetCommandList.h"
|
||||
|
||||
enum FrameDataReturnType {
|
||||
FRAMEDATA_NOTREADY,
|
||||
FRAMEDATA_RESEND,
|
||||
FRAMEDATA_READY
|
||||
};
|
||||
|
||||
class FrameData {
|
||||
public:
|
||||
FrameData();
|
||||
~FrameData();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void update();
|
||||
|
||||
UnsignedInt getFrame();
|
||||
void setFrame(UnsignedInt frame);
|
||||
FrameDataReturnType allCommandsReady(Bool debugSpewage);
|
||||
NetCommandList * getCommandList();
|
||||
void setFrameCommandCount(UnsignedInt totalCommandCount);
|
||||
UnsignedInt getFrameCommandCount();
|
||||
void addCommand(NetCommandMsg *msg);
|
||||
UnsignedInt getCommandCount();
|
||||
void zeroFrame();
|
||||
void destroyGameMessages();
|
||||
|
||||
protected:
|
||||
UnsignedInt m_frame;
|
||||
UnsignedInt m_frameCommandCount;
|
||||
UnsignedInt m_commandCount;
|
||||
NetCommandList *m_commandList;
|
||||
UnsignedInt m_lastFailedCC;
|
||||
UnsignedInt m_lastFailedFrameCC;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRAMEDATAMANAGER_H
|
||||
#define __FRAMEDATAMANAGER_H
|
||||
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "GameNetwork/FrameData.h"
|
||||
|
||||
class FrameDataManager : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(FrameDataManager, "FrameDataManager")
|
||||
public:
|
||||
FrameDataManager(Bool isLocal);
|
||||
//virtual ~FrameDataManager();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void update();
|
||||
|
||||
void addNetCommandMsg(NetCommandMsg *msg);
|
||||
void setIsLocal(Bool isLocal);
|
||||
FrameDataReturnType allCommandsReady(UnsignedInt frame, Bool debugSpewage);
|
||||
NetCommandList * getFrameCommandList(UnsignedInt frame);
|
||||
UnsignedInt getCommandCount(UnsignedInt frame);
|
||||
void setFrameCommandCount(UnsignedInt frame, UnsignedInt commandCount);
|
||||
UnsignedInt getFrameCommandCount(UnsignedInt frame);
|
||||
void zeroFrames(UnsignedInt startingFrame, UnsignedInt numFrames);
|
||||
void destroyGameMessages();
|
||||
void resetFrame(UnsignedInt frame, Bool isAdvancing = TRUE);
|
||||
void setQuitFrame(UnsignedInt frame);
|
||||
UnsignedInt getQuitFrame();
|
||||
Bool getIsQuitting();
|
||||
|
||||
protected:
|
||||
FrameData *m_frameData;
|
||||
Bool m_isLocal;
|
||||
|
||||
Bool m_isQuitting;
|
||||
UnsignedInt m_quitFrame;
|
||||
};
|
||||
|
||||
#endif
|
74
Generals/Code/GameEngine/Include/GameNetwork/FrameMetrics.h
Normal file
74
Generals/Code/GameEngine/Include/GameNetwork/FrameMetrics.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** FrameMetrics.h */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FRAMEMETRICS_H
|
||||
#define __FRAMEMETRICS_H
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
|
||||
class FrameMetrics {
|
||||
public:
|
||||
FrameMetrics();
|
||||
virtual ~FrameMetrics();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
|
||||
void doPerFrameMetrics(UnsignedInt frame);
|
||||
void processLatencyResponse(UnsignedInt frame);
|
||||
void addCushion(Int cushion);
|
||||
|
||||
Real getAverageLatency();
|
||||
Int getAverageFPS();
|
||||
Int getMinimumCushion();
|
||||
|
||||
protected:
|
||||
// These are used for keeping track of parameters to the run ahead equation.
|
||||
// frames per second history variables.
|
||||
Real *m_fpsList; ///< A record of how many game logic frames per second there were for the last 60 seconds.
|
||||
time_t m_lastFpsTimeThing; ///< The time when the last fps entry started being recorded.
|
||||
Int m_fpsListIndex; ///< Index into the array of the current fps list entry being measured.
|
||||
Real m_averageFps; ///< The current average logic fps, computed just like m_averageLatency below but with the fps numbers.
|
||||
|
||||
// round trip time to packet router variables.
|
||||
// The lists are indexed off the frame number of the frame info packet they are associated with.
|
||||
// The index used should be the frame number mod the array length.
|
||||
Real *m_latencyList; ///< A record of the round trip latencies of the frame info packets to the packet router. Values in seconds.
|
||||
time_t *m_pendingLatencies; ///< The latencies of frame info packets that are "in the air."
|
||||
Real m_averageLatency; ///< The current average latency, this is used to save calculation time.
|
||||
///< When a new latency value is received, the old one is subtracted out and the new
|
||||
///< one is added in.
|
||||
|
||||
// packet arrival cushion variables.
|
||||
// Keeps track of the cushion for the incoming commands.
|
||||
UnsignedInt m_cushionIndex; ///< The next index to use for the cushion list.
|
||||
Int m_minimumCushion; ///< The average cushion for the history.
|
||||
};
|
||||
|
||||
#endif // __FRAMEMETRICS_H
|
56
Generals/Code/GameEngine/Include/GameNetwork/GUIUtil.h
Normal file
56
Generals/Code/GameEngine/Include/GameNetwork/GUIUtil.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GUIUtil.h //////////////////////////////////////////////////////
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GUIUTIL_H__
|
||||
#define __GUIUTIL_H__
|
||||
|
||||
class GameWindow;
|
||||
class GameInfo;
|
||||
|
||||
void ShowUnderlyingGUIElements( Bool show, const char *layoutFilename, const char *parentName,
|
||||
const char **gadgetsToHide, const char **perPlayerGadgetsToHide );
|
||||
|
||||
void PopulateColorComboBox(Int comboBox, GameWindow *comboArray[], GameInfo *myGame, Bool isObserver = FALSE);
|
||||
void PopulatePlayerTemplateComboBox(Int comboBox, GameWindow *comboArray[], GameInfo *myGame, Bool allowObservers);
|
||||
void PopulateTeamComboBox(Int comboBox, GameWindow *comboArray[], GameInfo *myGame, Bool isObserver = FALSE);
|
||||
|
||||
void EnableSlotListUpdates( Bool val );
|
||||
Bool AreSlotListUpdatesEnabled( void );
|
||||
|
||||
void UpdateSlotList( GameInfo *myGame, GameWindow *comboPlayer[],
|
||||
GameWindow *comboColor[], GameWindow *comboPlayerTemplate[],
|
||||
GameWindow *comboTeam[], GameWindow *buttonAccept[],
|
||||
GameWindow *buttonStart, GameWindow *buttonMapStartPosition[] );
|
||||
|
||||
void EnableAcceptControls(Bool Enabled, GameInfo *myGame, GameWindow *comboPlayer[],
|
||||
GameWindow *comboColor[], GameWindow *comboPlayerTemplate[],
|
||||
GameWindow *comboTeam[], GameWindow *buttonAccept[], GameWindow *buttonStart,
|
||||
GameWindow *buttonMapStartPosition[], Int slotNum = -1);
|
||||
|
||||
#endif // __GUIUTIL_H__
|
288
Generals/Code/GameEngine/Include/GameNetwork/GameInfo.h
Normal file
288
Generals/Code/GameEngine/Include/GameNetwork/GameInfo.h
Normal file
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameInfo.h //////////////////////////////////////////////////////
|
||||
// Generals game setup information
|
||||
// Author: Matthew D. Campbell, December 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMEINFO_H__
|
||||
#define __GAMEINFO_H__
|
||||
|
||||
#include "Common/Snapshot.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "GameNetwork/FirewallHelper.h"
|
||||
|
||||
enum SlotState
|
||||
{
|
||||
SLOT_OPEN,
|
||||
SLOT_CLOSED,
|
||||
SLOT_EASY_AI,
|
||||
SLOT_MED_AI,
|
||||
SLOT_BRUTAL_AI,
|
||||
SLOT_PLAYER
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PLAYERTEMPLATE_RANDOM = -1,
|
||||
PLAYERTEMPLATE_OBSERVER = -2,
|
||||
PLAYERTEMPLATE_MIN = PLAYERTEMPLATE_OBSERVER
|
||||
};
|
||||
|
||||
/**
|
||||
* GameSlot class - maintains information about the contents of a
|
||||
* game slot. This persists throughout the game.
|
||||
*/
|
||||
class GameSlot
|
||||
{
|
||||
public:
|
||||
GameSlot();
|
||||
virtual void reset();
|
||||
|
||||
void setAccept( void ) { m_isAccepted = true; } ///< Accept the current options
|
||||
void unAccept( void ); ///< Unaccept (options changed, etc)
|
||||
Bool isAccepted( void ) const { return m_isAccepted; } ///< Non-human slots are always accepted
|
||||
|
||||
void setMapAvailability( Bool hasMap ); ///< Set whether the slot has the map
|
||||
Bool hasMap( void ) const { return m_hasMap; } ///< Non-human slots always have the map
|
||||
|
||||
void setState( SlotState state,
|
||||
UnicodeString name = UnicodeString::TheEmptyString,
|
||||
UnsignedInt IP = 0); ///< Set the slot's state (human, AI, open, etc)
|
||||
SlotState getState( void ) const { return m_state; } ///< Get the slot state
|
||||
|
||||
void setColor( Int color ) { m_color = color; }
|
||||
Int getColor( void ) const { return m_color; }
|
||||
|
||||
void setStartPos( Int startPos ) { m_startPos = startPos; }
|
||||
Int getStartPos( void ) const { return m_startPos; }
|
||||
|
||||
void setPlayerTemplate( Int playerTemplate )
|
||||
{ m_playerTemplate = playerTemplate;
|
||||
if (playerTemplate <= PLAYERTEMPLATE_MIN)
|
||||
m_startPos = -1;
|
||||
}
|
||||
Int getPlayerTemplate( void ) const { return m_playerTemplate; }
|
||||
|
||||
void setTeamNumber( Int teamNumber ) { m_teamNumber = teamNumber; }
|
||||
Int getTeamNumber( void ) const { return m_teamNumber; }
|
||||
|
||||
inline void setName( UnicodeString name ) { m_name = name; }
|
||||
inline UnicodeString getName( void ) const { return m_name; }
|
||||
|
||||
inline void setIP( UnsignedInt IP ) { m_IP = IP; }
|
||||
inline UnsignedInt getIP( void ) const { return m_IP; }
|
||||
|
||||
inline void setPort( UnsignedShort port ) { m_port = port; }
|
||||
inline UnsignedShort getPort( void ) const { return m_port; }
|
||||
|
||||
inline void setNATBehavior( FirewallHelperClass::FirewallBehaviorType NATBehavior) { m_NATBehavior = NATBehavior; }
|
||||
inline FirewallHelperClass::FirewallBehaviorType getNATBehavior() const { return m_NATBehavior; }
|
||||
|
||||
void saveOffOriginalInfo( void );
|
||||
inline Int getOriginalPlayerTemplate( void ) const { return m_origPlayerTemplate; }
|
||||
inline Int getOriginalColor( void ) const { return m_origColor; }
|
||||
inline Int getOriginalStartPos( void ) const { return m_origStartPos; }
|
||||
Int getApparentPlayerTemplate( void ) const;
|
||||
Int getApparentColor( void ) const;
|
||||
Int getApparentStartPos( void ) const;
|
||||
UnicodeString getApparentPlayerTemplateDisplayName( void ) const;
|
||||
|
||||
// Various tests
|
||||
Bool isHuman( void ) const; ///< Is this slot occupied by a human player?
|
||||
Bool isOccupied( void ) const; ///< Is this slot occupied (by a human or an AI)?
|
||||
Bool isAI( void ) const; ///< Is this slot occupied by an AI?
|
||||
Bool isPlayer( AsciiString userName ) const; ///< Does this slot contain the given user?
|
||||
Bool isPlayer( UnicodeString userName ) const; ///< Does this slot contain the given user?
|
||||
Bool isPlayer( UnsignedInt ip ) const; ///< Is this slot at this IP?
|
||||
Bool isOpen( void ) const;
|
||||
|
||||
void setLastFrameInGame( UnsignedInt frame ) { m_lastFrameInGame = frame; }
|
||||
void markAsDisconnected( void ) { m_disconnected = TRUE; }
|
||||
UnsignedInt lastFrameInGame( void ) const { return m_lastFrameInGame; }
|
||||
Bool disconnected( void ) const { return isHuman() && m_disconnected; }
|
||||
|
||||
void mute( Bool isMuted ) { m_isMuted = isMuted; }
|
||||
Bool isMuted( void ) const { return m_isMuted; }
|
||||
protected:
|
||||
SlotState m_state;
|
||||
Bool m_isAccepted;
|
||||
Bool m_hasMap;
|
||||
Bool m_isMuted;
|
||||
Int m_color; ///< color, or -1 for random
|
||||
Int m_startPos; ///< start position, or -1 for random
|
||||
Int m_playerTemplate; ///< PlayerTemplate
|
||||
Int m_teamNumber; ///< alliance, -1 for none
|
||||
Int m_origColor; ///< color, or -1 for random
|
||||
Int m_origStartPos; ///< start position, or -1 for random
|
||||
Int m_origPlayerTemplate; ///< PlayerTemplate
|
||||
UnicodeString m_name; ///< Only valid for human players
|
||||
UnsignedInt m_IP; ///< Only valid for human players in LAN/WOL
|
||||
UnsignedShort m_port; ///< Only valid for human players in LAN/WOL
|
||||
FirewallHelperClass::FirewallBehaviorType m_NATBehavior; ///< The NAT behavior for this slot's player.
|
||||
UnsignedInt m_lastFrameInGame; // only valid for human players
|
||||
Bool m_disconnected; // only valid for human players
|
||||
};
|
||||
|
||||
/**
|
||||
* GameInfo class - maintains information about the game setup and
|
||||
* the contents of its slot list hroughout the game.
|
||||
*/
|
||||
class GameInfo
|
||||
{
|
||||
public:
|
||||
GameInfo();
|
||||
|
||||
void init( void );
|
||||
virtual void reset( void );
|
||||
|
||||
void clearSlotList( void );
|
||||
|
||||
Int getNumPlayers( void ) const; ///< How many players (human and AI) are in the game?
|
||||
Int getNumNonObserverPlayers( void ) const; ///< How many non-observer players (human and AI) are in the game?
|
||||
Int getMaxPlayers( void ) const; ///< How many players (human and AI) can be in the game?
|
||||
|
||||
void enterGame( void ); ///< Mark us as having entered the game
|
||||
void leaveGame( void ); ///< Mark us as having left the game
|
||||
virtual void startGame( Int gameID ); ///< Mark our game as started, and record the game ID
|
||||
void endGame( void ); ///< Mark us as out of game
|
||||
inline Int getGameID( void ) const; ///< Get the game ID of the current game or the last one if we're not in game
|
||||
|
||||
inline void setInGame( void ); ///< set the m_inGame flag
|
||||
inline Bool isInGame( void ) const; ///< Are we (in game or in game setup)? As opposed to chatting, matching, etc
|
||||
inline Bool isGameInProgress( void ) const; ///< Is the game in progress?
|
||||
inline void setGameInProgress( Bool inProgress ); ///< Set whether the game is in progress or not.
|
||||
void setSlot( Int slotNum, GameSlot slotInfo ); ///< Set the slot state (human, open, AI, etc)
|
||||
GameSlot* getSlot( Int slotNum ); ///< Get the slot
|
||||
const GameSlot* getConstSlot( Int slotNum ) const; ///< Get the slot
|
||||
virtual Bool amIHost( void ) const; ///< Convenience function - is the local player the game host?
|
||||
virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
|
||||
Int getSlotNum( AsciiString userName ) const; ///< Get the slot number corresponding to a specific user, or -1 if he's not present
|
||||
|
||||
// Game options
|
||||
void setMap( AsciiString mapName ); ///< Set the map to play on
|
||||
void setMapCRC( UnsignedInt mapCRC ); ///< Set the map CRC
|
||||
void setMapSize( UnsignedInt mapSize ); ///< Set the map size
|
||||
void setMapContentsMask( Int mask ); ///< Set the map contents mask (1=map,2=preview,4=map.ini)
|
||||
inline AsciiString getMap( void ) const; ///< Get the game map
|
||||
inline UnsignedInt getMapCRC( void ) const; ///< Get the map CRC
|
||||
inline UnsignedInt getMapSize( void ) const; ///< Get the map size
|
||||
inline Int getMapContentsMask( void ) const; ///< Get the map contents mask
|
||||
void setSeed( Int seed ); ///< Set the random seed for the game
|
||||
inline Int getSeed( void ) const; ///< Get the game seed
|
||||
|
||||
void setSlotPointer( Int index, GameSlot *slot ); ///< Set the slot info pointer
|
||||
|
||||
void setLocalIP( UnsignedInt ip ) { m_localIP =ip; } ///< Set the local IP
|
||||
UnsignedInt getLocalIP( void ) const { return m_localIP; } ///< Get the local IP
|
||||
|
||||
Bool isColorTaken(Int colorIdx, Int slotToIgnore = -1 ) const;
|
||||
Bool isStartPositionTaken(Int positionIdx, Int slotToIgnore = -1 ) const;
|
||||
|
||||
virtual void resetAccepted(void); ///< Reset the accepted flag on all players
|
||||
virtual void resetStartSpots(void); ///< reset the start spots for the new map.
|
||||
virtual void adjustSlotsForMap(void); ///< adjusts the slots to open and closed depending on the players in the game and the number of players the map can hold.
|
||||
|
||||
virtual void closeOpenSlots(void); ///< close all slots that are currently unoccupied.
|
||||
|
||||
// CRC checking hack
|
||||
void setCRCInterval( Int val ) { m_crcInterval = (val<100)?val:100; }
|
||||
inline Int getCRCInterval( void ) const { return m_crcInterval; }
|
||||
|
||||
Bool haveWeSurrendered(void) { return m_surrendered; }
|
||||
void markAsSurrendered(void) { m_surrendered = TRUE; }
|
||||
|
||||
Bool isSkirmish(void); // TRUE if 1 human & 1+ AI are present && !isSandbox()
|
||||
Bool isMultiPlayer(void); // TRUE if 2+ human are present
|
||||
Bool isSandbox(void); // TRUE if everybody is on the same team
|
||||
|
||||
Bool isPlayerPreorder(Int index);
|
||||
void markPlayerAsPreorder(Int index);
|
||||
|
||||
protected:
|
||||
Int m_preorderMask;
|
||||
Int m_crcInterval;
|
||||
Bool m_inGame;
|
||||
Bool m_inProgress;
|
||||
Bool m_surrendered;
|
||||
Int m_gameID;
|
||||
GameSlot *m_slot[MAX_SLOTS];
|
||||
|
||||
UnsignedInt m_localIP;
|
||||
|
||||
// Game options
|
||||
AsciiString m_mapName;
|
||||
UnsignedInt m_mapCRC;
|
||||
UnsignedInt m_mapSize;
|
||||
Int m_mapMask;
|
||||
Int m_seed;
|
||||
};
|
||||
|
||||
extern GameInfo *TheGameInfo;
|
||||
|
||||
// Inline functions
|
||||
Int GameInfo::getGameID( void ) const { return m_gameID; }
|
||||
AsciiString GameInfo::getMap( void ) const { return m_mapName; }
|
||||
UnsignedInt GameInfo::getMapCRC( void ) const { return m_mapCRC; }
|
||||
UnsignedInt GameInfo::getMapSize( void ) const { return m_mapSize; }
|
||||
Int GameInfo::getMapContentsMask( void ) const { return m_mapMask; }
|
||||
Int GameInfo::getSeed( void ) const { return m_seed; }
|
||||
Bool GameInfo::isInGame( void ) const { return m_inGame; }
|
||||
void GameInfo::setInGame( void ) { m_inGame = true; }
|
||||
Bool GameInfo::isGameInProgress( void ) const { return m_inProgress; }
|
||||
void GameInfo::setGameInProgress( Bool inProgress ) { m_inProgress = inProgress; }
|
||||
|
||||
AsciiString GameInfoToAsciiString( const GameInfo *game );
|
||||
Bool ParseAsciiStringToGameInfo( GameInfo *game, AsciiString options );
|
||||
|
||||
|
||||
/**
|
||||
* The SkirmishGameInfo class holds information about the skirmish game and
|
||||
* the contents of its slot list.
|
||||
*/
|
||||
|
||||
class SkirmishGameInfo : public GameInfo, public Snapshot
|
||||
{
|
||||
private:
|
||||
GameSlot m_skirmishSlot[MAX_SLOTS];
|
||||
|
||||
protected:
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
public:
|
||||
SkirmishGameInfo()
|
||||
{
|
||||
for (Int i = 0; i< MAX_SLOTS; ++i)
|
||||
setSlotPointer(i, &m_skirmishSlot[i]);
|
||||
}
|
||||
};
|
||||
|
||||
extern SkirmishGameInfo *TheSkirmishGameInfo;
|
||||
|
||||
#endif // __GAMEINFO_H__
|
105
Generals/Code/GameEngine/Include/GameNetwork/GameMessageParser.h
Normal file
105
Generals/Code/GameEngine/Include/GameNetwork/GameMessageParser.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/MessageStream.h"
|
||||
#include "Common/GameMemory.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class GameMessageParserArgumentType : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(GameMessageParserArgumentType, "GameMessageParserArgumentType")
|
||||
public:
|
||||
GameMessageParserArgumentType(GameMessageArgumentDataType type, Int argCount);
|
||||
//virtual ~GameMessageParserArgumentType();
|
||||
|
||||
GameMessageParserArgumentType *getNext();
|
||||
void setNext(GameMessageParserArgumentType *next);
|
||||
Int getArgCount();
|
||||
GameMessageArgumentDataType getType();
|
||||
|
||||
protected:
|
||||
GameMessageParserArgumentType* m_next;
|
||||
GameMessageArgumentDataType m_type;
|
||||
Int m_argCount;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline GameMessageParserArgumentType * GameMessageParserArgumentType::getNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline void GameMessageParserArgumentType::setNext(GameMessageParserArgumentType *next)
|
||||
{
|
||||
m_next = next;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline GameMessageArgumentDataType GameMessageParserArgumentType::getType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline Int GameMessageParserArgumentType::getArgCount()
|
||||
{
|
||||
return m_argCount;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
class GameMessageParser : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(GameMessageParser, "GameMessageParser")
|
||||
public:
|
||||
GameMessageParser();
|
||||
GameMessageParser(GameMessage *msg);
|
||||
//virtual ~GameMessageParser();
|
||||
|
||||
GameMessageParserArgumentType *getFirstArgumentType();
|
||||
void addArgType(GameMessageArgumentDataType type, Int argCount);
|
||||
Int getNumTypes();
|
||||
|
||||
protected:
|
||||
GameMessageParserArgumentType *m_first, *m_last;
|
||||
Int m_argTypeCount;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline GameMessageParserArgumentType * GameMessageParser::getFirstArgumentType()
|
||||
{
|
||||
return m_first;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline Int GameMessageParser::getNumTypes()
|
||||
{
|
||||
return m_argTypeCount;
|
||||
}
|
||||
|
148
Generals/Code/GameEngine/Include/GameNetwork/GameSpy.h
Normal file
148
Generals/Code/GameEngine/Include/GameNetwork/GameSpy.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameSpy.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy stuff
|
||||
// Author: Matthew D. Campbell, February 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GameSpy_H__
|
||||
#define __GameSpy_H__
|
||||
|
||||
#include "GameSpy/Peer/Peer.h"
|
||||
|
||||
#include "GameClient/Color.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
|
||||
class GameSpyGroupRoom
|
||||
{
|
||||
public:
|
||||
GameSpyGroupRoom() { m_name = AsciiString::TheEmptyString; m_groupID = m_numWaiting = m_maxWaiting = m_numGames = m_numPlaying = 0; }
|
||||
AsciiString m_name;
|
||||
Int m_groupID;
|
||||
Int m_numWaiting;
|
||||
Int m_maxWaiting;
|
||||
Int m_numGames;
|
||||
Int m_numPlaying;
|
||||
};
|
||||
typedef std::map<Int, GameSpyGroupRoom> GroupRoomMap;
|
||||
|
||||
class GameSpyChatInterface : public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyChatInterface() { };
|
||||
|
||||
virtual void init( void ) = 0;
|
||||
virtual void reset( void ) = 0;
|
||||
virtual void update( void ) = 0;
|
||||
|
||||
virtual Bool isConnected( void ) = 0;
|
||||
virtual void login(AsciiString loginName, AsciiString password = AsciiString::TheEmptyString, AsciiString email = AsciiString::TheEmptyString) = 0;
|
||||
virtual void reconnectProfile( void ) = 0;
|
||||
virtual void disconnectFromChat( void ) = 0;
|
||||
|
||||
virtual void UTMRoom( RoomType roomType, const char *key, const char *val, Bool authenticate = FALSE ) = 0;
|
||||
virtual void UTMPlayer( const char *name, const char *key, const char *val, Bool authenticate = FALSE ) = 0;
|
||||
virtual void startGame( void ) = 0;
|
||||
virtual void leaveRoom( RoomType roomType ) = 0;
|
||||
virtual void setReady( Bool ready ) = 0;
|
||||
virtual void enumPlayers( RoomType roomType, peerEnumPlayersCallback callback, void *userData ) = 0;
|
||||
virtual void startListingGames( peerListingGamesCallback callback ) = 0;
|
||||
virtual void stopListingGames( void ) = 0;
|
||||
|
||||
virtual void joinGroupRoom( Int ID ) = 0;
|
||||
virtual void joinStagingRoom( GServer server, AsciiString password ) = 0;
|
||||
virtual void createStagingRoom( AsciiString gameName, AsciiString password, Int maxPlayers ) = 0;
|
||||
virtual void joinBestGroupRoom( void ) = 0;
|
||||
|
||||
inline PEER getPeer( void ) { return m_peer; }
|
||||
inline AsciiString getLoginName( void ) { return m_loginName; }
|
||||
inline AsciiString getPassword( void ) { return m_password; }
|
||||
inline GroupRoomMap* getGroupRooms( void ) { return &m_groupRooms; }
|
||||
inline Int getCurrentGroupRoomID( void ) { return m_currentGroupRoomID; }
|
||||
inline Bool getUsingProfile( void ) { return m_usingProfiles; }
|
||||
inline Int getProfileID( void ) { return m_profileID; }
|
||||
|
||||
inline void setCurrentGroupRoomID( Int ID ) { m_currentGroupRoomID = ID; }
|
||||
void clearGroupRoomList(void);
|
||||
inline Int getNumGroupRooms( void ) { return m_groupRooms.size(); }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
AsciiString m_loginName;
|
||||
AsciiString m_password;
|
||||
AsciiString m_email;
|
||||
Bool m_usingProfiles;
|
||||
Int m_profileID;
|
||||
PEER m_peer;
|
||||
|
||||
GroupRoomMap m_groupRooms;
|
||||
Int m_currentGroupRoomID;
|
||||
};
|
||||
|
||||
GameSpyChatInterface *createGameSpyChat( void );
|
||||
|
||||
extern GameSpyChatInterface *TheGameSpyChat;
|
||||
|
||||
|
||||
void JoinRoomCallback(PEER peer, PEERBool success,
|
||||
PEERJoinResult result, RoomType roomType,
|
||||
void *param); ///< Called when we (fail to) join a room. param is address of Bool to store result
|
||||
|
||||
void ListGroupRoomsCallback(PEER peer, PEERBool success,
|
||||
int groupID, GServer server,
|
||||
const char * name, int numWaiting,
|
||||
int maxWaiting, int numGames,
|
||||
int numPlaying, void * param); ///< Called while listing group rooms
|
||||
|
||||
enum GameSpyColors {
|
||||
GSCOLOR_DEFAULT = 0,
|
||||
GSCOLOR_CURRENTROOM,
|
||||
GSCOLOR_ROOM,
|
||||
GSCOLOR_GAME,
|
||||
GSCOLOR_PLAYER_NORMAL,
|
||||
GSCOLOR_PLAYER_OWNER,
|
||||
GSCOLOR_PLAYER_BUDDY,
|
||||
GSCOLOR_PLAYER_SELF,
|
||||
GSCOLOR_CHAT_NORMAL,
|
||||
GSCOLOR_CHAT_EMOTE,
|
||||
GSCOLOR_CHAT_OWNER,
|
||||
GSCOLOR_CHAT_OWNER_EMOTE,
|
||||
GSCOLOR_CHAT_PRIVATE,
|
||||
GSCOLOR_CHAT_PRIVATE_EMOTE,
|
||||
GSCOLOR_CHAT_PRIVATE_OWNER,
|
||||
GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE,
|
||||
GSCOLOR_CHAT_BUDDY,
|
||||
GSCOLOR_CHAT_SELF,
|
||||
GSCOLOR_ACCEPT_TRUE,
|
||||
GSCOLOR_ACCEPT_FALSE,
|
||||
GSCOLOR_MAX
|
||||
};
|
||||
|
||||
extern const Color GameSpyColor[GSCOLOR_MAX];
|
||||
|
||||
|
||||
#endif // __GameSpy_H__
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BuddyDefs.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Buddy (GP) definitions
|
||||
// Author: Matthew D. Campbell, July 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BUDDYDEFS_H__
|
||||
#define __BUDDYDEFS_H__
|
||||
|
||||
void HandleBuddyResponses(void);
|
||||
void PopulateOldBuddyMessages(void);
|
||||
|
||||
#endif // __BUDDYDEFS_H__
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BuddyThread.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy BuddyList thread class interface
|
||||
// Author: Matthew D. Campbell, June 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BUDDYTHREAD_H__
|
||||
#define __BUDDYTHREAD_H__
|
||||
|
||||
#include "GameSpy/GP/GP.h"
|
||||
|
||||
#define MAX_BUDDY_CHAT_LEN 128
|
||||
|
||||
// this class encapsulates a request for the buddy thread
|
||||
class BuddyRequest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
BUDDYREQUEST_LOGIN, // attempt to login
|
||||
BUDDYREQUEST_RELOGIN, // log in after being disconnected
|
||||
BUDDYREQUEST_LOGOUT, // log out if connected
|
||||
BUDDYREQUEST_MESSAGE,
|
||||
BUDDYREQUEST_LOGINNEW, // attempt to create a new nick and login
|
||||
//BUDDYREQUEST_DELETELOGIN,
|
||||
BUDDYREQUEST_ADDBUDDY, // add someone to your buddy list
|
||||
BUDDYREQUEST_DELBUDDY, // delete someone from your buddy list
|
||||
BUDDYREQUEST_OKADD, // allow someone to add you to their buddy list
|
||||
BUDDYREQUEST_DENYADD, // don't allow someone to add you to their buddy list
|
||||
BUDDYREQUEST_SETSTATUS, // Set our status
|
||||
BUDDYREQUEST_DELETEACCT, // Delete our account
|
||||
BUDDYREQUEST_MAX
|
||||
} buddyRequestType;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
GPProfile recipient;
|
||||
WideChar text[MAX_BUDDY_CHAT_LEN];
|
||||
} message;
|
||||
|
||||
struct
|
||||
{
|
||||
char nick[GP_NICK_LEN];
|
||||
char email[GP_EMAIL_LEN];
|
||||
char password[GP_PASSWORD_LEN];
|
||||
Bool hasFirewall;
|
||||
} login;
|
||||
|
||||
struct
|
||||
{
|
||||
GPProfile id;
|
||||
WideChar text[MAX_BUDDY_CHAT_LEN];
|
||||
} addbuddy;
|
||||
|
||||
struct
|
||||
{
|
||||
GPProfile id;
|
||||
} profile;
|
||||
|
||||
struct
|
||||
{
|
||||
GPEnum status;
|
||||
char statusString[GP_STATUS_STRING_LEN];
|
||||
char locationString[GP_LOCATION_STRING_LEN];
|
||||
} status;
|
||||
|
||||
} arg;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this class encapsulates an action the buddy thread wants from the UI
|
||||
class BuddyResponse
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
BUDDYRESPONSE_LOGIN,
|
||||
BUDDYRESPONSE_DISCONNECT,
|
||||
BUDDYRESPONSE_MESSAGE,
|
||||
BUDDYRESPONSE_REQUEST,
|
||||
BUDDYRESPONSE_STATUS,
|
||||
BUDDYRESPONSE_MAX
|
||||
} buddyResponseType;
|
||||
|
||||
GPProfile profile;
|
||||
GPResult result;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UnsignedInt date;
|
||||
char nick[GP_NICK_LEN];
|
||||
WideChar text[MAX_BUDDY_CHAT_LEN];
|
||||
} message;
|
||||
|
||||
struct
|
||||
{
|
||||
char nick[GP_NICK_LEN];
|
||||
char email[GP_EMAIL_LEN];
|
||||
char countrycode[GP_COUNTRYCODE_LEN];
|
||||
WideChar text[GP_REASON_LEN];
|
||||
} request;
|
||||
|
||||
struct
|
||||
{
|
||||
//GPResult result;
|
||||
GPErrorCode errorCode;
|
||||
char errorString[MAX_BUDDY_CHAT_LEN];
|
||||
GPEnum fatal;
|
||||
} error;
|
||||
|
||||
struct
|
||||
{
|
||||
char nick[GP_NICK_LEN];
|
||||
char email[GP_EMAIL_LEN];
|
||||
char countrycode[GP_COUNTRYCODE_LEN];
|
||||
char location[GP_LOCATION_STRING_LEN];
|
||||
GPEnum status;
|
||||
char statusString[GP_STATUS_STRING_LEN];
|
||||
} status;
|
||||
} arg;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this is the actual message queue used to pass messages between threads
|
||||
class GameSpyBuddyMessageQueueInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyBuddyMessageQueueInterface() {}
|
||||
virtual void startThread( void ) = 0;
|
||||
virtual void endThread( void ) = 0;
|
||||
virtual Bool isThreadRunning( void ) = 0;
|
||||
virtual Bool isConnected( void ) = 0;
|
||||
virtual Bool isConnecting( void ) = 0;
|
||||
|
||||
virtual void addRequest( const BuddyRequest& req ) = 0;
|
||||
virtual Bool getRequest( BuddyRequest& req ) = 0;
|
||||
|
||||
virtual void addResponse( const BuddyResponse& resp ) = 0;
|
||||
virtual Bool getResponse( BuddyResponse& resp ) = 0;
|
||||
|
||||
virtual GPProfile getLocalProfileID( void ) = 0;
|
||||
|
||||
static GameSpyBuddyMessageQueueInterface* createNewMessageQueue( void );
|
||||
};
|
||||
|
||||
extern GameSpyBuddyMessageQueueInterface *TheGameSpyBuddyMessageQueue;
|
||||
|
||||
|
||||
#endif // __BUDDYTHREAD_H__
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GSConfig.h ///////////////////////////////////////////////////////////
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
// Description: GameSpy online config
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GSCONFIG_H__
|
||||
#define __GSCONFIG_H__
|
||||
|
||||
#include "Common/AsciiString.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
|
||||
class GameSpyConfigInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyConfigInterface() {}
|
||||
|
||||
// Pings
|
||||
virtual std::list<AsciiString> getPingServers(void) = 0;
|
||||
virtual Int getNumPingRepetitions(void) = 0;
|
||||
virtual Int getPingTimeoutInMs(void) = 0;
|
||||
virtual Int getPingCutoffGood( void ) = 0;
|
||||
virtual Int getPingCutoffBad( void ) = 0;
|
||||
|
||||
// QM
|
||||
virtual std::list<AsciiString> getQMMaps(void) = 0;
|
||||
virtual Int getQMBotID(void) = 0;
|
||||
virtual Int getQMChannel(void) = 0;
|
||||
virtual void setQMChannel(Int channel) = 0;
|
||||
|
||||
// Player Info
|
||||
virtual Int getPointsForRank(Int rank) = 0;
|
||||
virtual Bool isPlayerVIP(Int id) = 0;
|
||||
|
||||
// mangler Info
|
||||
virtual Bool getManglerLocation(Int index, AsciiString& host, UnsignedShort& port) = 0;
|
||||
|
||||
// Ladder / Any other external parsing
|
||||
virtual AsciiString getLeftoverConfig(void) = 0;
|
||||
|
||||
// NAT Timeouts
|
||||
virtual Int getTimeBetweenRetries() = 0;
|
||||
virtual Int getMaxManglerRetries() = 0;
|
||||
virtual time_t getRetryInterval() = 0;
|
||||
virtual time_t getKeepaliveInterval() = 0;
|
||||
virtual time_t getPortTimeout() = 0;
|
||||
virtual time_t getRoundTimeout() = 0;
|
||||
|
||||
// Custom match
|
||||
virtual Bool restrictGamesToLobby() = 0;
|
||||
|
||||
static GameSpyConfigInterface* create(AsciiString config);
|
||||
};
|
||||
|
||||
extern GameSpyConfigInterface *TheGameSpyConfig;
|
||||
|
||||
#endif // __GSCONFIG_H__
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameResultsThread.h //////////////////////////////////////////////////////
|
||||
// Generals game results thread class interface
|
||||
// Author: Matthew D. Campbell, August 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMERESULTSTHREAD_H__
|
||||
#define __GAMERESULTSTHREAD_H__
|
||||
|
||||
#include "Common/SubsystemInterface.h"
|
||||
|
||||
// this class encapsulates a request for the thread
|
||||
class GameResultsRequest
|
||||
{
|
||||
public:
|
||||
std::string hostname;
|
||||
UnsignedShort port;
|
||||
std::string results;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this class encapsulates a response from the thread
|
||||
class GameResultsResponse
|
||||
{
|
||||
public:
|
||||
std::string hostname;
|
||||
UnsignedShort port;
|
||||
Bool sentOk;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this is the actual message queue used to pass messages between threads
|
||||
class GameResultsInterface : public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameResultsInterface() {}
|
||||
virtual void startThreads( void ) = 0;
|
||||
virtual void endThreads( void ) = 0;
|
||||
virtual Bool areThreadsRunning( void ) = 0;
|
||||
|
||||
virtual void addRequest( const GameResultsRequest& req ) = 0;
|
||||
virtual Bool getRequest( GameResultsRequest& resp ) = 0;
|
||||
|
||||
virtual void addResponse( const GameResultsResponse& resp ) = 0;
|
||||
virtual Bool getResponse( GameResultsResponse& resp ) = 0;
|
||||
|
||||
static GameResultsInterface* createNewGameResultsInterface( void );
|
||||
|
||||
virtual Bool areGameResultsBeingSent( void ) = 0;
|
||||
};
|
||||
|
||||
extern GameResultsInterface *TheGameResultsQueue;
|
||||
|
||||
|
||||
#endif // __GAMERESULTSTHREAD_H__
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: LadderDefs.h //////////////////////////////////////////////////////
|
||||
// Generals ladder definitions
|
||||
// Author: Matthew D. Campbell, August 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __LADDERDEFS_H__
|
||||
#define __LADDERDEFS_H__
|
||||
|
||||
#include "Common/UnicodeString.h"
|
||||
#include "Common/AsciiString.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
|
||||
class GameWindow;
|
||||
|
||||
class LadderInfo
|
||||
{
|
||||
public:
|
||||
LadderInfo();
|
||||
UnicodeString name;
|
||||
UnicodeString description;
|
||||
UnicodeString location;
|
||||
Int playersPerTeam;
|
||||
Int minWins;
|
||||
Int maxWins;
|
||||
Bool randomMaps;
|
||||
Bool randomFactions;
|
||||
Bool validQM;
|
||||
Bool validCustom;
|
||||
std::list<AsciiString> validMaps;
|
||||
std::list<AsciiString> validFactions;
|
||||
AsciiString cryptedPassword;
|
||||
AsciiString address;
|
||||
UnsignedShort port;
|
||||
AsciiString homepageURL;
|
||||
Bool submitReplay; // with game results
|
||||
Int index;
|
||||
};
|
||||
|
||||
typedef std::list<LadderInfo *> LadderInfoList;
|
||||
|
||||
class LadderList
|
||||
{
|
||||
public:
|
||||
LadderList();
|
||||
~LadderList();
|
||||
|
||||
const LadderInfo* findLadder( const AsciiString& addr, UnsignedShort port );
|
||||
const LadderInfo* findLadderByIndex( Int index ); // doesn't look in local ladders
|
||||
const LadderInfoList* getLocalLadders( void );
|
||||
const LadderInfoList* getSpecialLadders( void );
|
||||
const LadderInfoList* getStandardLadders( void );
|
||||
|
||||
private:
|
||||
void loadLocalLadders( void );
|
||||
void checkLadder( AsciiString fname, Int index );
|
||||
LadderInfoList m_localLadders;
|
||||
LadderInfoList m_specialLadders;
|
||||
LadderInfoList m_standardLadders;
|
||||
};
|
||||
|
||||
extern LadderList *TheLadderList;
|
||||
|
||||
#endif // __LADDERDEFS_H__
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: LobbyUtils.h //////////////////////////////////////////////////////
|
||||
// Generals lobby utils
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __LOBBYUTILS_H__
|
||||
#define __LOBBYUTILS_H__
|
||||
|
||||
class GameWindow;
|
||||
|
||||
GameWindow *GetGameListBox( void );
|
||||
GameWindow *GetGameInfoListBox( void );
|
||||
NameKeyType GetGameListBoxID( void );
|
||||
NameKeyType GetGameInfoListBoxID( void );
|
||||
void GrabWindowInfo( void );
|
||||
void ReleaseWindowInfo( void );
|
||||
void RefreshGameInfoListBox( GameWindow *mainWin, GameWindow *win );
|
||||
void RefreshGameListBoxes( void );
|
||||
void ToggleGameListType( void );
|
||||
|
||||
enum GameSortType
|
||||
{
|
||||
GAMESORT_ALPHA_ASCENDING = 0,
|
||||
GAMESORT_ALPHA_DESCENDING,
|
||||
GAMESORT_PING_ASCENDING,
|
||||
GAMESORT_PING_DESCENDING,
|
||||
GAMESORT_MAX,
|
||||
};
|
||||
|
||||
Bool HandleSortButton( NameKeyType sortButton );
|
||||
void PopulateLobbyPlayerListbox(void);
|
||||
|
||||
#endif // __LOBBYUTILS_H__
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: MainMenuUtils.h //////////////////////////////////////////////////////
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
// Description: GameSpy version check, patch download, etc utils
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __MAINMENUUTILS_H__
|
||||
#define __MAINMENUUTILS_H__
|
||||
|
||||
void HTTPThinkWrapper( void );
|
||||
void StopAsyncDNSCheck( void );
|
||||
void StartPatchCheck( void );
|
||||
void CancelPatchCheckCallback( void );
|
||||
void StartDownloadingPatches( void );
|
||||
void HandleCanceledDownload( Bool resetDropDown = TRUE );
|
||||
|
||||
enum OverallStatsPeriod
|
||||
{
|
||||
STATS_TODAY = 0,
|
||||
STATS_YESTERDAY,
|
||||
STATS_ALLTIME,
|
||||
STATS_LASTWEEK,
|
||||
STATS_MAX
|
||||
};
|
||||
|
||||
struct OverallStats
|
||||
{
|
||||
OverallStats();
|
||||
Int wins[STATS_MAX];
|
||||
Int losses[STATS_MAX];
|
||||
};
|
||||
|
||||
void CheckOverallStats( void );
|
||||
void HandleOverallStats( const OverallStats& USA, const OverallStats& China, const OverallStats& GLA );
|
||||
|
||||
void CheckNumPlayersOnline( void );
|
||||
void HandleNumPlayersOnline( Int numPlayersOnline );
|
||||
|
||||
#endif // __MAINMENUUTILS_H__
|
303
Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h
Normal file
303
Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h
Normal file
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: PeerDefs.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Peer (chat) definitions
|
||||
// Author: Matthew D. Campbell, June 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PEERDEFS_H__
|
||||
#define __PEERDEFS_H__
|
||||
|
||||
#include "GameSpy/Peer/Peer.h"
|
||||
#include "GameSpy/GP/GP.h"
|
||||
|
||||
#include "GameClient/Color.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "GameNetwork/GameSpy/StagingRoomGameInfo.h"
|
||||
|
||||
class GameWindow;
|
||||
class PSPlayerStats;
|
||||
|
||||
typedef std::set<AsciiString> IgnoreList;
|
||||
typedef std::map<Int, AsciiString> SavedIgnoreMap;
|
||||
|
||||
enum RCItemType
|
||||
{
|
||||
ITEM_BUDDY,
|
||||
ITEM_REQUEST,
|
||||
ITEM_NONBUDDY,
|
||||
ITEM_NONE,
|
||||
};
|
||||
|
||||
class GameSpyRCMenuData
|
||||
{
|
||||
public:
|
||||
AsciiString m_nick;
|
||||
GPProfile m_id;
|
||||
RCItemType m_itemType;
|
||||
};
|
||||
|
||||
class BuddyInfo
|
||||
{
|
||||
public:
|
||||
GPProfile m_id;
|
||||
AsciiString m_name;
|
||||
AsciiString m_email;
|
||||
AsciiString m_countryCode;
|
||||
GPEnum m_status;
|
||||
UnicodeString m_statusString;
|
||||
UnicodeString m_locationString;
|
||||
};
|
||||
typedef std::map<GPProfile, BuddyInfo> BuddyInfoMap;
|
||||
|
||||
class BuddyMessage
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_timestamp;
|
||||
GPProfile m_senderID;
|
||||
AsciiString m_senderNick;
|
||||
GPProfile m_recipientID;
|
||||
AsciiString m_recipientNick;
|
||||
UnicodeString m_message;
|
||||
};
|
||||
typedef std::list<BuddyMessage> BuddyMessageList;
|
||||
|
||||
class GameSpyGroupRoom
|
||||
{
|
||||
public:
|
||||
GameSpyGroupRoom() { m_name = AsciiString::TheEmptyString; m_translatedName = UnicodeString::TheEmptyString; m_groupID = m_numWaiting = m_maxWaiting = m_numGames = m_numPlaying = 0; }
|
||||
AsciiString m_name;
|
||||
UnicodeString m_translatedName;
|
||||
Int m_groupID;
|
||||
Int m_numWaiting;
|
||||
Int m_maxWaiting;
|
||||
Int m_numGames;
|
||||
Int m_numPlaying;
|
||||
};
|
||||
typedef std::map<Int, GameSpyGroupRoom> GroupRoomMap;
|
||||
|
||||
class Transport;
|
||||
class NAT;
|
||||
|
||||
typedef std::map<Int, GameSpyStagingRoom *> StagingRoomMap;
|
||||
|
||||
class PlayerInfo
|
||||
{
|
||||
public:
|
||||
PlayerInfo() { m_name = m_locale = AsciiString::TheEmptyString; m_wins = m_losses = m_rankPoints = m_side = m_preorder = m_profileID = m_flags = 0; }
|
||||
AsciiString m_name;
|
||||
AsciiString m_locale;
|
||||
Int m_wins;
|
||||
Int m_losses;
|
||||
Int m_profileID;
|
||||
Int m_flags;
|
||||
Int m_rankPoints;
|
||||
Int m_side;
|
||||
Int m_preorder;
|
||||
Bool isIgnored( void );
|
||||
};
|
||||
struct AsciiComparator
|
||||
{
|
||||
bool operator()(AsciiString s1, AsciiString s2) const;
|
||||
};
|
||||
|
||||
|
||||
typedef std::map<AsciiString, PlayerInfo, AsciiComparator> PlayerInfoMap;
|
||||
|
||||
enum GameSpyColors {
|
||||
GSCOLOR_DEFAULT = 0,
|
||||
GSCOLOR_CURRENTROOM,
|
||||
GSCOLOR_ROOM,
|
||||
GSCOLOR_GAME,
|
||||
GSCOLOR_GAME_FULL,
|
||||
GSCOLOR_GAME_CRCMISMATCH,
|
||||
GSCOLOR_PLAYER_NORMAL,
|
||||
GSCOLOR_PLAYER_OWNER,
|
||||
GSCOLOR_PLAYER_BUDDY,
|
||||
GSCOLOR_PLAYER_SELF,
|
||||
GSCOLOR_PLAYER_IGNORED,
|
||||
GSCOLOR_CHAT_NORMAL,
|
||||
GSCOLOR_CHAT_EMOTE,
|
||||
GSCOLOR_CHAT_OWNER,
|
||||
GSCOLOR_CHAT_OWNER_EMOTE,
|
||||
GSCOLOR_CHAT_PRIVATE,
|
||||
GSCOLOR_CHAT_PRIVATE_EMOTE,
|
||||
GSCOLOR_CHAT_PRIVATE_OWNER,
|
||||
GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE,
|
||||
GSCOLOR_CHAT_BUDDY,
|
||||
GSCOLOR_CHAT_SELF,
|
||||
GSCOLOR_ACCEPT_TRUE,
|
||||
GSCOLOR_ACCEPT_FALSE,
|
||||
GSCOLOR_MAP_SELECTED,
|
||||
GSCOLOR_MAP_UNSELECTED,
|
||||
GSCOLOR_MOTD,
|
||||
GSCOLOR_MOTD_HEADING,
|
||||
GSCOLOR_MAX
|
||||
};
|
||||
|
||||
extern Color GameSpyColor[GSCOLOR_MAX];
|
||||
|
||||
enum GameSpyBuddyStatus {
|
||||
BUDDY_OFFLINE,
|
||||
BUDDY_ONLINE,
|
||||
BUDDY_LOBBY,
|
||||
BUDDY_STAGING,
|
||||
BUDDY_LOADING,
|
||||
BUDDY_PLAYING,
|
||||
BUDDY_MATCHING,
|
||||
BUDDY_MAX
|
||||
};
|
||||
|
||||
// ---------------------------------------------------
|
||||
// this class holds info used in the main thread
|
||||
class GameSpyInfoInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyInfoInterface() {};
|
||||
virtual void reset( void ) {};
|
||||
virtual void clearGroupRoomList( void ) = 0;
|
||||
virtual GroupRoomMap* getGroupRoomList( void ) = 0;
|
||||
virtual void addGroupRoom( GameSpyGroupRoom room ) = 0;
|
||||
virtual Bool gotGroupRoomList( void ) = 0;
|
||||
virtual void joinGroupRoom( Int groupID ) = 0;
|
||||
virtual void leaveGroupRoom( void ) = 0;
|
||||
virtual void joinBestGroupRoom( void ) = 0;
|
||||
virtual void setCurrentGroupRoom( Int groupID ) = 0;
|
||||
virtual Int getCurrentGroupRoom( void ) = 0;
|
||||
virtual void updatePlayerInfo( PlayerInfo pi, AsciiString oldNick = AsciiString::TheEmptyString ) = 0;
|
||||
virtual void playerLeftGroupRoom( AsciiString nick ) = 0;
|
||||
virtual PlayerInfoMap* getPlayerInfoMap( void ) = 0;
|
||||
|
||||
virtual BuddyInfoMap* getBuddyMap( void ) = 0;
|
||||
virtual BuddyInfoMap* getBuddyRequestMap( void ) = 0;
|
||||
virtual BuddyMessageList* getBuddyMessages( void ) = 0;
|
||||
virtual Bool isBuddy( Int id ) = 0;
|
||||
|
||||
virtual void setLocalName( AsciiString name ) = 0;
|
||||
virtual AsciiString getLocalName( void ) = 0;
|
||||
virtual void setLocalProfileID( Int profileID ) = 0;
|
||||
virtual Int getLocalProfileID( void ) = 0;
|
||||
virtual AsciiString getLocalEmail( void ) = 0;
|
||||
virtual void setLocalEmail( AsciiString email ) = 0;
|
||||
virtual AsciiString getLocalPassword( void ) = 0;
|
||||
virtual void setLocalPassword( AsciiString passwd ) = 0;
|
||||
virtual void setLocalBaseName( AsciiString name ) = 0;
|
||||
virtual AsciiString getLocalBaseName( void ) = 0;
|
||||
|
||||
virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) = 0;
|
||||
virtual PSPlayerStats getCachedLocalPlayerStats( void ) = 0;
|
||||
|
||||
virtual void clearStagingRoomList( void ) = 0;
|
||||
virtual StagingRoomMap* getStagingRoomList( void ) = 0;
|
||||
virtual GameSpyStagingRoom* findStagingRoomByID( Int id ) = 0;
|
||||
virtual void addStagingRoom( GameSpyStagingRoom room ) = 0;
|
||||
virtual void updateStagingRoom( GameSpyStagingRoom room ) = 0;
|
||||
virtual void removeStagingRoom( GameSpyStagingRoom room ) = 0;
|
||||
virtual Bool hasStagingRoomListChanged( void ) = 0;
|
||||
virtual void leaveStagingRoom( void ) = 0;
|
||||
virtual void markAsStagingRoomHost( void ) = 0;
|
||||
virtual void markAsStagingRoomJoiner( Int game ) = 0;
|
||||
virtual void sawFullGameList( void ) = 0;
|
||||
|
||||
virtual Bool amIHost( void ) = 0;
|
||||
virtual GameSpyStagingRoom* getCurrentStagingRoom( void ) = 0;
|
||||
virtual void setGameOptions( void ) = 0;
|
||||
virtual Int getCurrentStagingRoomID( void ) = 0;
|
||||
|
||||
virtual void setDisallowAsianText( Bool val ) = 0;
|
||||
virtual void setDisallowNonAsianText( Bool val ) = 0;
|
||||
virtual Bool getDisallowAsianText( void ) = 0;
|
||||
virtual Bool getDisallowNonAsianText(void ) = 0;
|
||||
|
||||
// chat
|
||||
virtual void registerTextWindow( GameWindow *win ) = 0;
|
||||
virtual void unregisterTextWindow( GameWindow *win ) = 0;
|
||||
virtual Int addText( UnicodeString message, Color c, GameWindow *win ) = 0;
|
||||
virtual void addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win ) = 0;
|
||||
virtual void addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win ) = 0;
|
||||
virtual Bool sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox ) = 0;
|
||||
|
||||
virtual void setMOTD( const AsciiString& motd ) = 0;
|
||||
virtual const AsciiString& getMOTD( void ) = 0;
|
||||
|
||||
virtual void setConfig( const AsciiString& config ) = 0;
|
||||
virtual const AsciiString& getConfig( void ) = 0;
|
||||
|
||||
virtual void setPingString( const AsciiString& ping ) = 0;
|
||||
virtual const AsciiString& getPingString( void ) = 0;
|
||||
virtual Int getPingValue( const AsciiString& otherPing ) = 0;
|
||||
|
||||
static GameSpyInfoInterface* createNewGameSpyInfoInterface( void );
|
||||
|
||||
virtual void addToSavedIgnoreList( Int profileID, AsciiString nick ) = 0;
|
||||
virtual void removeFromSavedIgnoreList( Int profileID ) = 0;
|
||||
virtual Bool isSavedIgnored( Int profileID ) = 0;
|
||||
virtual SavedIgnoreMap returnSavedIgnoreList( void ) = 0;
|
||||
virtual void loadSavedIgnoreList( void ) = 0;
|
||||
|
||||
virtual IgnoreList returnIgnoreList( void ) = 0;
|
||||
virtual void addToIgnoreList( AsciiString nick ) = 0;
|
||||
virtual void removeFromIgnoreList( AsciiString nick ) = 0;
|
||||
virtual Bool isIgnored( AsciiString nick ) = 0;
|
||||
|
||||
virtual void setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP) = 0;
|
||||
virtual UnsignedInt getInternalIP(void) = 0;
|
||||
virtual UnsignedInt getExternalIP(void) = 0;
|
||||
|
||||
virtual Bool isDisconnectedAfterGameStart(Int *reason) const = 0;
|
||||
virtual void markAsDisconnectedAfterGameStart(Int reason) = 0;
|
||||
|
||||
virtual Bool didPlayerPreorder( Int profileID ) const = 0;
|
||||
virtual void markPlayerAsPreorder( Int profileID ) = 0;
|
||||
|
||||
virtual void setMaxMessagesPerUpdate( Int num ) = 0;
|
||||
virtual Int getMaxMessagesPerUpdate( void ) = 0;
|
||||
|
||||
virtual Int getAdditionalDisconnects( void ) = 0;
|
||||
virtual void clearAdditionalDisconnects( void ) = 0;
|
||||
virtual void readAdditionalDisconnects( void ) = 0;
|
||||
virtual void updateAdditionalGameSpyDisconnections(Int count) = 0;
|
||||
};
|
||||
|
||||
extern GameSpyInfoInterface *TheGameSpyInfo;
|
||||
|
||||
void WOLDisplayGameOptions( void );
|
||||
void WOLDisplaySlotList( void );
|
||||
Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP);
|
||||
void SetLobbyAttemptHostJoin(Bool start);
|
||||
void SendStatsToOtherPlayers(const GameInfo *game);
|
||||
|
||||
class PSPlayerStats;
|
||||
void GetAdditionalDisconnectsFromUserFile(PSPlayerStats *stats);
|
||||
extern Int GetAdditionalDisconnectsFromUserFile(Int playerID);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// These functions set up the globals and threads neccessary for our GameSpy impl.
|
||||
|
||||
void SetUpGameSpy( const char *motdBuffer, const char *configBuffer );
|
||||
void TearDownGameSpy( void );
|
||||
|
||||
#endif // __PEERDEFS_H__
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: PeerDefsImplementation.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Peer (chat) implementation definitions
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PEERDEFSIMPLEMENTATION_H__
|
||||
#define __PEERDEFSIMPLEMENTATION_H__
|
||||
|
||||
#include "GameNetwork/GameSpy/PeerDefs.h"
|
||||
#include "GameNetwork/GameSpy/PersistentStorageThread.h"
|
||||
|
||||
|
||||
class GameSpyInfo : public GameSpyInfoInterface
|
||||
{
|
||||
public:
|
||||
GameSpyInfo();
|
||||
virtual ~GameSpyInfo();
|
||||
virtual void reset( void );
|
||||
virtual void clearGroupRoomList( void ) { m_groupRooms.clear(); m_gotGroupRoomList = false; }
|
||||
virtual GroupRoomMap* getGroupRoomList( void ) { return &m_groupRooms; }
|
||||
virtual void addGroupRoom( GameSpyGroupRoom room );
|
||||
virtual Bool gotGroupRoomList( void ) { return m_gotGroupRoomList; }
|
||||
virtual void joinGroupRoom( Int groupID );
|
||||
virtual void leaveGroupRoom( void );
|
||||
virtual void joinBestGroupRoom( void );
|
||||
virtual void setCurrentGroupRoom( Int groupID ) { m_currentGroupRoomID = groupID; m_playerInfoMap.clear(); }
|
||||
virtual Int getCurrentGroupRoom( void ) { return m_currentGroupRoomID; }
|
||||
virtual void updatePlayerInfo( PlayerInfo pi, AsciiString oldNick = AsciiString::TheEmptyString );
|
||||
virtual void playerLeftGroupRoom( AsciiString nick );
|
||||
virtual PlayerInfoMap* getPlayerInfoMap( void ) { return &m_playerInfoMap; }
|
||||
|
||||
virtual void setLocalName( AsciiString name ) { m_localName = name; }
|
||||
virtual AsciiString getLocalName( void ) { return m_localName; }
|
||||
virtual void setLocalProfileID( Int profileID ) { m_localProfileID = profileID; }
|
||||
virtual Int getLocalProfileID( void ) { return m_localProfileID; }
|
||||
virtual AsciiString getLocalEmail( void ) { return m_localEmail; }
|
||||
virtual void setLocalEmail( AsciiString email ) { m_localEmail = email; }
|
||||
virtual AsciiString getLocalPassword( void ){ return m_localPasswd; }
|
||||
virtual void setLocalPassword( AsciiString passwd ) { m_localPasswd = passwd; }
|
||||
virtual void setLocalBaseName( AsciiString name ) { m_localBaseName = name; }
|
||||
virtual AsciiString getLocalBaseName( void ){ return m_localBaseName; }
|
||||
|
||||
virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) {m_cachedLocalPlayerStats = stats; }
|
||||
virtual PSPlayerStats getCachedLocalPlayerStats( void ){ return m_cachedLocalPlayerStats; }
|
||||
|
||||
virtual BuddyInfoMap* getBuddyMap( void ) { return &m_buddyMap; }
|
||||
virtual BuddyInfoMap* getBuddyRequestMap( void ) { return &m_buddyRequestMap; }
|
||||
virtual BuddyMessageList* getBuddyMessages( void ) { return &m_buddyMessages; }
|
||||
virtual Bool isBuddy( Int id );
|
||||
|
||||
virtual void clearStagingRoomList( void );
|
||||
virtual StagingRoomMap* getStagingRoomList( void ) { return &m_stagingRooms; }
|
||||
virtual GameSpyStagingRoom* findStagingRoomByID( Int id );
|
||||
virtual void addStagingRoom( GameSpyStagingRoom room );
|
||||
virtual void updateStagingRoom( GameSpyStagingRoom room );
|
||||
virtual void removeStagingRoom( GameSpyStagingRoom room );
|
||||
virtual Bool hasStagingRoomListChanged( void );
|
||||
virtual void leaveStagingRoom( void );
|
||||
virtual void markAsStagingRoomHost( void );
|
||||
virtual void markAsStagingRoomJoiner( Int game );
|
||||
virtual Int getCurrentStagingRoomID( void ) { return m_localStagingRoomID; }
|
||||
|
||||
virtual void sawFullGameList( void ) { m_sawFullGameList = TRUE; }
|
||||
|
||||
virtual void setDisallowAsianText( Bool val );
|
||||
virtual void setDisallowNonAsianText( Bool val );
|
||||
virtual Bool getDisallowAsianText( void );
|
||||
virtual Bool getDisallowNonAsianText(void );
|
||||
// chat
|
||||
virtual void registerTextWindow( GameWindow *win );
|
||||
virtual void unregisterTextWindow( GameWindow *win );
|
||||
virtual Int addText( UnicodeString message, Color c, GameWindow *win );
|
||||
virtual void addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win );
|
||||
virtual void addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win );
|
||||
virtual Bool sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox );
|
||||
|
||||
virtual void setMOTD( const AsciiString& motd );
|
||||
virtual const AsciiString& getMOTD( void );
|
||||
virtual void setConfig( const AsciiString& config );
|
||||
virtual const AsciiString& getConfig( void );
|
||||
|
||||
virtual void setPingString( const AsciiString& ping ) { m_pingString = ping; }
|
||||
virtual const AsciiString& getPingString( void ) { return m_pingString; }
|
||||
virtual Int getPingValue( const AsciiString& otherPing );
|
||||
|
||||
virtual Bool amIHost( void );
|
||||
virtual GameSpyStagingRoom* getCurrentStagingRoom( void );
|
||||
virtual void setGameOptions( void );
|
||||
|
||||
virtual void addToIgnoreList( AsciiString nick );
|
||||
virtual void removeFromIgnoreList( AsciiString nick );
|
||||
virtual Bool isIgnored( AsciiString nick );
|
||||
virtual IgnoreList returnIgnoreList( void );
|
||||
|
||||
virtual void loadSavedIgnoreList( void );
|
||||
virtual SavedIgnoreMap returnSavedIgnoreList( void );
|
||||
virtual void addToSavedIgnoreList( Int profileID, AsciiString nick);
|
||||
virtual void removeFromSavedIgnoreList( Int profileID );
|
||||
virtual Bool isSavedIgnored( Int profileID );
|
||||
virtual void setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP);
|
||||
virtual UnsignedInt getInternalIP(void) { return m_internalIP; }
|
||||
virtual UnsignedInt getExternalIP(void) { return m_externalIP; }
|
||||
|
||||
virtual Bool isDisconnectedAfterGameStart(Int *reason) const { if (reason) *reason = m_disconReason; return m_isDisconAfterGameStart; }
|
||||
virtual void markAsDisconnectedAfterGameStart(Int reason) { m_isDisconAfterGameStart = TRUE; m_disconReason = reason; }
|
||||
|
||||
virtual Bool didPlayerPreorder( Int profileID ) const;
|
||||
virtual void markPlayerAsPreorder( Int profileID );
|
||||
|
||||
virtual void setMaxMessagesPerUpdate( Int num );
|
||||
virtual Int getMaxMessagesPerUpdate( void );
|
||||
|
||||
virtual Int getAdditionalDisconnects( void );
|
||||
virtual void clearAdditionalDisconnects( void );
|
||||
virtual void readAdditionalDisconnects( void );
|
||||
virtual void updateAdditionalGameSpyDisconnections(Int count);
|
||||
private:
|
||||
Bool m_sawFullGameList;
|
||||
Bool m_isDisconAfterGameStart;
|
||||
Int m_disconReason;
|
||||
AsciiString m_rawMotd;
|
||||
AsciiString m_rawConfig;
|
||||
AsciiString m_pingString;
|
||||
GroupRoomMap m_groupRooms;
|
||||
StagingRoomMap m_stagingRooms;
|
||||
Bool m_stagingRoomsDirty;
|
||||
BuddyInfoMap m_buddyMap;
|
||||
BuddyInfoMap m_buddyRequestMap;
|
||||
PlayerInfoMap m_playerInfoMap;
|
||||
BuddyMessageList m_buddyMessages;
|
||||
Int m_currentGroupRoomID;
|
||||
Bool m_gotGroupRoomList;
|
||||
AsciiString m_localName;
|
||||
Int m_localProfileID;
|
||||
AsciiString m_localPasswd;
|
||||
AsciiString m_localEmail;
|
||||
AsciiString m_localBaseName;
|
||||
PSPlayerStats m_cachedLocalPlayerStats;
|
||||
Bool m_disallowAsainText;
|
||||
Bool m_disallowNonAsianText;
|
||||
UnsignedInt m_internalIP, m_externalIP;
|
||||
Int m_maxMessagesPerUpdate;
|
||||
|
||||
Int m_joinedStagingRoom; // if we join a staging room, this holds its ID (0 otherwise)
|
||||
Bool m_isHosting; // if we host, this is true, and
|
||||
GameSpyStagingRoom m_localStagingRoom; // this holds the GameInfo for it.
|
||||
Int m_localStagingRoomID;
|
||||
|
||||
IgnoreList m_ignoreList;
|
||||
SavedIgnoreMap m_savedIgnoreMap;
|
||||
|
||||
std::set<GameWindow *> m_textWindows;
|
||||
|
||||
std::set<Int> m_preorderPlayers;
|
||||
|
||||
Int m_additionalDisconnects;
|
||||
};
|
||||
|
||||
#endif // __PEERDEFS_H__
|
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: PeerThread.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Peer-to-peer chat thread class interface
|
||||
// Author: Matthew D. Campbell, June 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PEERTHREAD_H__
|
||||
#define __PEERTHREAD_H__
|
||||
|
||||
#include "GameSpy/Peer/Peer.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
|
||||
enum SerialAuthResult
|
||||
{
|
||||
SERIAL_NONEXISTENT,
|
||||
SERIAL_AUTHFAILED,
|
||||
SERIAL_BANNED,
|
||||
SERIAL_OK
|
||||
};
|
||||
|
||||
// this class encapsulates a request for the peer thread
|
||||
class PeerRequest
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PEERREQUEST_LOGIN, // attempt to login
|
||||
PEERREQUEST_LOGOUT, // log out if connected
|
||||
PEERREQUEST_MESSAGEPLAYER,
|
||||
PEERREQUEST_MESSAGEROOM,
|
||||
PEERREQUEST_JOINGROUPROOM,
|
||||
PEERREQUEST_LEAVEGROUPROOM,
|
||||
PEERREQUEST_STARTGAMELIST,
|
||||
PEERREQUEST_STOPGAMELIST,
|
||||
PEERREQUEST_CREATESTAGINGROOM,
|
||||
PEERREQUEST_SETGAMEOPTIONS,
|
||||
PEERREQUEST_JOINSTAGINGROOM,
|
||||
PEERREQUEST_LEAVESTAGINGROOM,
|
||||
PEERREQUEST_UTMPLAYER,
|
||||
PEERREQUEST_UTMROOM,
|
||||
PEERREQUEST_STARTGAME,
|
||||
PEERREQUEST_STARTQUICKMATCH,
|
||||
PEERREQUEST_WIDENQUICKMATCHSEARCH,
|
||||
PEERREQUEST_STOPQUICKMATCH,
|
||||
PEERREQUEST_PUSHSTATS,
|
||||
PEERREQUEST_GETEXTENDEDSTAGINGROOMINFO,
|
||||
PEERREQUEST_MAX
|
||||
} peerRequestType;
|
||||
|
||||
std::string nick; // only used by login, but must be outside the union b/c of copy constructor
|
||||
std::wstring text; // can't be in a union
|
||||
std::string password;
|
||||
std::string email;
|
||||
std::string id;
|
||||
|
||||
// gameopts
|
||||
std::string options; // full string for UTMs
|
||||
std::string ladderIP;
|
||||
std::string hostPingStr;
|
||||
std::string gameOptsMapName;
|
||||
std::string gameOptsPlayerNames[MAX_SLOTS];
|
||||
|
||||
std::vector<bool> qmMaps;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Int profileID;
|
||||
} login;
|
||||
|
||||
struct
|
||||
{
|
||||
Int id;
|
||||
} groupRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
Bool restrictGameList;
|
||||
} gameList;
|
||||
|
||||
struct
|
||||
{
|
||||
Bool isAction;
|
||||
} message;
|
||||
|
||||
struct
|
||||
{
|
||||
Int id;
|
||||
} stagingRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
UnsignedInt exeCRC;
|
||||
UnsignedInt iniCRC;
|
||||
UnsignedInt gameVersion;
|
||||
Bool allowObservers;
|
||||
UnsignedShort ladPort;
|
||||
UnsignedInt ladPassCRC;
|
||||
Bool restrictGameList;
|
||||
} stagingRoomCreation;
|
||||
|
||||
struct
|
||||
{
|
||||
Int wins[MAX_SLOTS];
|
||||
Int losses[MAX_SLOTS];
|
||||
Int profileID[MAX_SLOTS];
|
||||
Int faction[MAX_SLOTS];
|
||||
Int color[MAX_SLOTS];
|
||||
Int numPlayers;
|
||||
Int maxPlayers;
|
||||
Int numObservers;
|
||||
} gameOptions;
|
||||
|
||||
struct
|
||||
{
|
||||
Bool isStagingRoom;
|
||||
} UTM;
|
||||
|
||||
struct
|
||||
{
|
||||
Int minPointPercentage, maxPointPercentage, points;
|
||||
Int widenTime;
|
||||
Int ladderID;
|
||||
UnsignedInt ladderPassCRC;
|
||||
Int maxPing;
|
||||
Int maxDiscons, discons;
|
||||
char pings[17]; // 8 servers (0-ff), 1 NULL
|
||||
Int numPlayers;
|
||||
Int botID;
|
||||
Int roomID;
|
||||
Int side;
|
||||
Int color;
|
||||
Int NAT;
|
||||
UnsignedInt exeCRC;
|
||||
UnsignedInt iniCRC;
|
||||
} QM;
|
||||
|
||||
struct
|
||||
{
|
||||
Int locale;
|
||||
Int wins;
|
||||
Int losses;
|
||||
Int rankPoints;
|
||||
Int side;
|
||||
Bool preorder;
|
||||
} statsToPush;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
enum DisconnectReason
|
||||
{
|
||||
DISCONNECT_NICKTAKEN = 1,
|
||||
DISCONNECT_BADNICK,
|
||||
DISCONNECT_LOSTCON,
|
||||
DISCONNECT_COULDNOTCONNECT,
|
||||
DISCONNECT_GP_LOGIN_TIMEOUT,
|
||||
DISCONNECT_GP_LOGIN_BAD_NICK,
|
||||
DISCONNECT_GP_LOGIN_BAD_EMAIL,
|
||||
DISCONNECT_GP_LOGIN_BAD_PASSWORD,
|
||||
DISCONNECT_GP_LOGIN_BAD_PROFILE,
|
||||
DISCONNECT_GP_LOGIN_PROFILE_DELETED,
|
||||
DISCONNECT_GP_LOGIN_CONNECTION_FAILED,
|
||||
DISCONNECT_GP_LOGIN_SERVER_AUTH_FAILED,
|
||||
DISCONNECT_SERIAL_INVALID,
|
||||
DISCONNECT_SERIAL_NOT_PRESENT,
|
||||
DISCONNECT_SERIAL_BANNED,
|
||||
DISCONNECT_GP_NEWUSER_BAD_NICK,
|
||||
DISCONNECT_GP_NEWUSER_BAD_PASSWORD,
|
||||
DISCONNECT_GP_NEWPROFILE_BAD_NICK,
|
||||
DISCONNECT_GP_NEWPROFILE_BAD_OLD_NICK,
|
||||
DISCONNECT_MAX,
|
||||
};
|
||||
|
||||
enum QMStatus
|
||||
{
|
||||
QM_IDLE,
|
||||
QM_JOININGQMCHANNEL,
|
||||
QM_LOOKINGFORBOT,
|
||||
QM_SENTINFO,
|
||||
QM_WORKING,
|
||||
QM_POOLSIZE,
|
||||
QM_WIDENINGSEARCH,
|
||||
QM_MATCHED,
|
||||
QM_INCHANNEL,
|
||||
QM_NEGOTIATINGFIREWALLS,
|
||||
QM_STARTINGGAME,
|
||||
QM_COULDNOTFINDBOT,
|
||||
QM_COULDNOTFINDCHANNEL,
|
||||
QM_COULDNOTNEGOTIATEFIREWALLS,
|
||||
QM_STOPPED,
|
||||
};
|
||||
|
||||
// this class encapsulates an action the peer thread wants from the UI
|
||||
class PeerResponse
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PEERRESPONSE_LOGIN,
|
||||
PEERRESPONSE_DISCONNECT,
|
||||
PEERRESPONSE_MESSAGE,
|
||||
PEERRESPONSE_GROUPROOM,
|
||||
PEERRESPONSE_STAGINGROOM,
|
||||
PEERRESPONSE_STAGINGROOMLISTCOMPLETE,
|
||||
PEERRESPONSE_STAGINGROOMPLAYERINFO,
|
||||
PEERRESPONSE_JOINGROUPROOM,
|
||||
PEERRESPONSE_CREATESTAGINGROOM,
|
||||
PEERRESPONSE_JOINSTAGINGROOM,
|
||||
PEERRESPONSE_PLAYERJOIN,
|
||||
PEERRESPONSE_PLAYERLEFT,
|
||||
PEERRESPONSE_PLAYERCHANGEDNICK,
|
||||
PEERRESPONSE_PLAYERINFO,
|
||||
PEERRESPONSE_PLAYERCHANGEDFLAGS,
|
||||
PEERRESPONSE_ROOMUTM,
|
||||
PEERRESPONSE_PLAYERUTM,
|
||||
PEERRESPONSE_QUICKMATCHSTATUS,
|
||||
PEERRESPONSE_GAMESTART,
|
||||
PEERRESPONSE_FAILEDTOHOST,
|
||||
PEERRESPONSE_MAX
|
||||
} peerResponseType;
|
||||
|
||||
std::string groupRoomName; // can't be in union
|
||||
|
||||
std::string nick; // can't be in a union
|
||||
std::string oldNick; // can't be in a union
|
||||
std::wstring text; // can't be in a union
|
||||
std::string locale; // can't be in a union
|
||||
|
||||
std::string stagingServerGameOptions; // full string from UTMs
|
||||
|
||||
// game opts sent with PEERRESPONSE_STAGINGROOM
|
||||
std::wstring stagingServerName;
|
||||
std::string stagingServerPingString;
|
||||
std::string stagingServerLadderIP;
|
||||
std::string stagingRoomMapName;
|
||||
|
||||
// game opts sent with PEERRESPONSE_STAGINGROOMPLAYERINFO
|
||||
std::string stagingRoomPlayerNames[MAX_SLOTS];
|
||||
|
||||
std::string command;
|
||||
std::string commandOptions;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
DisconnectReason reason;
|
||||
} discon;
|
||||
|
||||
struct
|
||||
{
|
||||
Int id;
|
||||
Int numWaiting;
|
||||
Int maxWaiting;
|
||||
Int numGames;
|
||||
Int numPlaying;
|
||||
} groupRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
Int id;
|
||||
Bool ok;
|
||||
} joinGroupRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
Int result;
|
||||
} createStagingRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
Int id;
|
||||
Bool ok;
|
||||
Bool isHostPresent;
|
||||
Int result; // for failures
|
||||
} joinStagingRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
Bool isPrivate;
|
||||
Bool isAction;
|
||||
Int profileID;
|
||||
} message;
|
||||
|
||||
struct
|
||||
{
|
||||
Int profileID;
|
||||
Int wins;
|
||||
Int losses;
|
||||
RoomType roomType;
|
||||
Int flags;
|
||||
UnsignedInt IP;
|
||||
Int rankPoints;
|
||||
Int side;
|
||||
Int preorder;
|
||||
UnsignedInt internalIP; // for us, on connection
|
||||
UnsignedInt externalIP; // for us, on connection
|
||||
} player;
|
||||
|
||||
struct
|
||||
{
|
||||
Int id;
|
||||
Int action;
|
||||
Bool isStaging;
|
||||
Bool requiresPassword;
|
||||
Bool allowObservers;
|
||||
UnsignedInt version;
|
||||
UnsignedInt exeCRC;
|
||||
UnsignedInt iniCRC;
|
||||
UnsignedShort ladderPort;
|
||||
Int wins[MAX_SLOTS];
|
||||
Int losses[MAX_SLOTS];
|
||||
Int profileID[MAX_SLOTS];
|
||||
Int faction[MAX_SLOTS];
|
||||
Int color[MAX_SLOTS];
|
||||
Int numPlayers;
|
||||
Int numObservers;
|
||||
Int maxPlayers;
|
||||
Int percentComplete;
|
||||
} stagingRoom;
|
||||
|
||||
struct
|
||||
{
|
||||
QMStatus status;
|
||||
Int poolSize;
|
||||
Int mapIdx; // when matched
|
||||
Int seed; // when matched
|
||||
UnsignedInt IP[MAX_SLOTS]; // when matched
|
||||
Int side[MAX_SLOTS]; // when matched
|
||||
Int color[MAX_SLOTS]; // when matched
|
||||
Int nat[MAX_SLOTS];
|
||||
} qmStatus;
|
||||
};
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this is the actual message queue used to pass messages between threads
|
||||
class GameSpyPeerMessageQueueInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyPeerMessageQueueInterface() {}
|
||||
virtual void startThread( void ) = 0;
|
||||
virtual void endThread( void ) = 0;
|
||||
virtual Bool isThreadRunning( void ) = 0;
|
||||
virtual Bool isConnected( void ) = 0;
|
||||
virtual Bool isConnecting( void ) = 0;
|
||||
|
||||
virtual void addRequest( const PeerRequest& req ) = 0;
|
||||
virtual Bool getRequest( PeerRequest& req ) = 0;
|
||||
|
||||
virtual void addResponse( const PeerResponse& resp ) = 0;
|
||||
virtual Bool getResponse( PeerResponse& resp ) = 0;
|
||||
|
||||
virtual SerialAuthResult getSerialAuthResult( void ) = 0;
|
||||
|
||||
static GameSpyPeerMessageQueueInterface* createNewMessageQueue( void );
|
||||
};
|
||||
|
||||
extern GameSpyPeerMessageQueueInterface *TheGameSpyPeerMessageQueue;
|
||||
|
||||
#endif // __PEERTHREAD_H__
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: PersistentStorageDefs.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Persistent Storage definitions
|
||||
// Author: Matthew D. Campbell, July 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PERSISTENTSTORAGEDEFS_H__
|
||||
#define __PERSISTENTSTORAGEDEFS_H__
|
||||
|
||||
enum LocaleType
|
||||
{
|
||||
LOC_UNKNOWN = 0,
|
||||
LOC_MIN = 1,
|
||||
LOC_MAX = 37
|
||||
};
|
||||
|
||||
void HandlePersistentStorageResponses(void);
|
||||
void UpdateLocalPlayerStats(void);
|
||||
|
||||
void SetLookAtPlayer( Int id, AsciiString nick );
|
||||
void PopulatePlayerInfoWindows( AsciiString parentWindowName );
|
||||
|
||||
#endif // __PERSISTENTSTORAGEDEFS_H__
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: PersistentStorageThread.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Persistent Storage thread class interface
|
||||
// Author: Matthew D. Campbell, July 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PERSISTENTSTORAGETHREAD_H__
|
||||
#define __PERSISTENTSTORAGETHREAD_H__
|
||||
|
||||
#include "GameSpy/gstats/gpersist.h"
|
||||
|
||||
#define MAX_BUDDY_CHAT_LEN 128
|
||||
|
||||
typedef std::map<Int, UnsignedInt> PerGeneralMap;
|
||||
// this structure holds all info on a player that is stored online
|
||||
class PSPlayerStats
|
||||
{
|
||||
public:
|
||||
PSPlayerStats( void );
|
||||
PSPlayerStats( const PSPlayerStats& other );
|
||||
void reset(void);
|
||||
|
||||
Int id;
|
||||
PerGeneralMap wins;
|
||||
PerGeneralMap losses;
|
||||
PerGeneralMap games;
|
||||
PerGeneralMap duration;
|
||||
PerGeneralMap unitsKilled;
|
||||
PerGeneralMap unitsLost;
|
||||
PerGeneralMap unitsBuilt;
|
||||
PerGeneralMap buildingsKilled;
|
||||
PerGeneralMap buildingsLost;
|
||||
PerGeneralMap buildingsBuilt;
|
||||
PerGeneralMap earnings;
|
||||
PerGeneralMap techCaptured;
|
||||
PerGeneralMap discons;
|
||||
PerGeneralMap desyncs;
|
||||
PerGeneralMap surrenders;
|
||||
PerGeneralMap gamesOf2p;
|
||||
PerGeneralMap gamesOf3p;
|
||||
PerGeneralMap gamesOf4p;
|
||||
PerGeneralMap gamesOf5p;
|
||||
PerGeneralMap gamesOf6p;
|
||||
PerGeneralMap gamesOf7p;
|
||||
PerGeneralMap gamesOf8p;
|
||||
PerGeneralMap customGames;
|
||||
PerGeneralMap QMGames;
|
||||
Int locale;
|
||||
Int gamesAsRandom;
|
||||
std::string options;
|
||||
std::string systemSpec;
|
||||
Real lastFPS;
|
||||
Int lastGeneral;
|
||||
Int gamesInRowWithLastGeneral;
|
||||
Int challengeMedals;
|
||||
Int battleHonors;
|
||||
Int QMwinsInARow;
|
||||
Int maxQMwinsInARow;
|
||||
|
||||
Int winsInARow;
|
||||
Int maxWinsInARow;
|
||||
Int lossesInARow;
|
||||
Int maxLossesInARow;
|
||||
Int disconsInARow;
|
||||
Int maxDisconsInARow;
|
||||
Int desyncsInARow;
|
||||
Int maxDesyncsInARow;
|
||||
|
||||
Int builtParticleCannon;
|
||||
Int builtNuke;
|
||||
Int builtSCUD;
|
||||
|
||||
Int lastLadderPort;
|
||||
std::string lastLadderHost;
|
||||
|
||||
void incorporate( const PSPlayerStats& other );
|
||||
};
|
||||
|
||||
// this class encapsulates a request for the thread
|
||||
class PSRequest
|
||||
{
|
||||
public:
|
||||
PSRequest();
|
||||
enum
|
||||
{
|
||||
PSREQUEST_READPLAYERSTATS, // read stats for a player
|
||||
PSREQUEST_UPDATEPLAYERSTATS, // update stats on the server
|
||||
PSREQUEST_UPDATEPLAYERLOCALE, // update locale on the server
|
||||
PSREQUEST_READCDKEYSTATS, // read stats for a cdkey
|
||||
PSREQUEST_SENDGAMERESTOGAMESPY, // report game results to GameSpy
|
||||
PSREQUEST_MAX
|
||||
} requestType;
|
||||
|
||||
// player stats for the *PLAYERSTATS
|
||||
PSPlayerStats player;
|
||||
|
||||
// cdkey for READCDKEYSTATS;
|
||||
std::string cdkey;
|
||||
|
||||
// our info for UPDATEPLAYERSTATS
|
||||
std::string nick;
|
||||
std::string password;
|
||||
std::string email;
|
||||
Bool addDiscon;
|
||||
Bool addDesync;
|
||||
Int lastHouse;
|
||||
|
||||
// for GameRes
|
||||
std::string results;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this class encapsulates a response from the thread
|
||||
class PSResponse
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PSRESPONSE_PLAYERSTATS,
|
||||
PSRESPONSE_COULDNOTCONNECT,
|
||||
PSRESPONSE_PREORDER,
|
||||
PSRESPONSE_MAX
|
||||
} responseType;
|
||||
|
||||
// player stats for the *PLAYERSTATS
|
||||
PSPlayerStats player;
|
||||
|
||||
// preorder flag
|
||||
Bool preorder;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this is the actual message queue used to pass messages between threads
|
||||
class GameSpyPSMessageQueueInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyPSMessageQueueInterface() {}
|
||||
virtual void startThread( void ) = 0;
|
||||
virtual void endThread( void ) = 0;
|
||||
virtual Bool isThreadRunning( void ) = 0;
|
||||
|
||||
virtual void addRequest( const PSRequest& req ) = 0;
|
||||
virtual Bool getRequest( PSRequest& req ) = 0;
|
||||
|
||||
virtual void addResponse( const PSResponse& resp ) = 0;
|
||||
virtual Bool getResponse( PSResponse& resp ) = 0;
|
||||
|
||||
// called from the main thread
|
||||
virtual void trackPlayerStats( PSPlayerStats stats ) = 0;
|
||||
virtual PSPlayerStats findPlayerStatsByID( Int id ) = 0;
|
||||
|
||||
static GameSpyPSMessageQueueInterface* createNewMessageQueue( void );
|
||||
|
||||
static std::string formatPlayerKVPairs( PSPlayerStats stats );
|
||||
static PSPlayerStats parsePlayerKVPairs( std::string kvPairs );
|
||||
};
|
||||
|
||||
extern GameSpyPSMessageQueueInterface *TheGameSpyPSMessageQueue;
|
||||
|
||||
|
||||
#endif // __PERSISTENTSTORAGETHREAD_H__
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: PingThread.h //////////////////////////////////////////////////////
|
||||
// Generals ping thread class interface
|
||||
// Author: Matthew D. Campbell, August 2002
|
||||
// Note: adapted from WOLAPI
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PINGTHREAD_H__
|
||||
#define __PINGTHREAD_H__
|
||||
|
||||
// this class encapsulates a request for the thread
|
||||
class PingRequest
|
||||
{
|
||||
public:
|
||||
std::string hostname;
|
||||
Int repetitions;
|
||||
Int timeout;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this class encapsulates a response from the thread
|
||||
class PingResponse
|
||||
{
|
||||
public:
|
||||
std::string hostname;
|
||||
Int avgPing;
|
||||
Int repetitions;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// this is the actual message queue used to pass messages between threads
|
||||
class PingerInterface
|
||||
{
|
||||
public:
|
||||
virtual ~PingerInterface() {}
|
||||
virtual void startThreads( void ) = 0;
|
||||
virtual void endThreads( void ) = 0;
|
||||
virtual Bool areThreadsRunning( void ) = 0;
|
||||
|
||||
virtual void addRequest( const PingRequest& req ) = 0;
|
||||
virtual Bool getRequest( PingRequest& resp ) = 0;
|
||||
|
||||
virtual void addResponse( const PingResponse& resp ) = 0;
|
||||
virtual Bool getResponse( PingResponse& resp ) = 0;
|
||||
|
||||
static PingerInterface* createNewPingerInterface( void );
|
||||
|
||||
virtual Bool arePingsInProgress( void ) = 0;
|
||||
virtual Int getPing( AsciiString hostname ) = 0;
|
||||
virtual void clearPingMap( void ) = 0;
|
||||
virtual AsciiString getPingString( Int timeout ) = 0;
|
||||
};
|
||||
|
||||
extern PingerInterface *ThePinger;
|
||||
|
||||
|
||||
#endif // __PINGTHREAD_H__
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: StagingRoomGameInfo.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy GameInfo
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __STAGINGROOMGAMEINFO_H__
|
||||
#define __STAGINGROOMGAMEINFO_H__
|
||||
|
||||
#include "GameNetwork/GameInfo.h"
|
||||
#include "GameNetwork/Transport.h"
|
||||
|
||||
class GameSpyGameSlot : public GameSlot
|
||||
{
|
||||
public:
|
||||
GameSpyGameSlot();
|
||||
Int getProfileID( void ) const { return m_profileID; }
|
||||
void setProfileID( Int id ) { m_profileID = id; }
|
||||
AsciiString getLoginName( void ) const { return m_gameSpyLogin; }
|
||||
void setLoginName( AsciiString name ) { m_gameSpyLogin = name; }
|
||||
AsciiString getLocale( void ) const { return m_gameSpyLocale; }
|
||||
void setLocale( AsciiString name ) { m_gameSpyLocale = name; }
|
||||
Int getWins( void ) const { return m_wins; }
|
||||
Int getLosses( void ) const { return m_losses; }
|
||||
void setWins( Int wins ) { m_wins = wins; }
|
||||
void setLosses( Int losses ) { m_losses = losses; }
|
||||
|
||||
Int getSlotRankPoints( void ) const { return m_rankPoints; }
|
||||
Int getFavoriteSide( void ) const { return m_favoriteSide; }
|
||||
void setSlotRankPoints( Int val ) { m_rankPoints = val; }
|
||||
void setFavoriteSide( Int val ) { m_favoriteSide = val; }
|
||||
|
||||
void setPingString( AsciiString pingStr );
|
||||
inline AsciiString getPingString( void ) const { return m_pingStr; }
|
||||
inline Int getPingAsInt( void ) const { return m_pingInt; }
|
||||
|
||||
protected:
|
||||
Int m_profileID;
|
||||
AsciiString m_gameSpyLogin;
|
||||
AsciiString m_gameSpyLocale;
|
||||
|
||||
AsciiString m_pingStr;
|
||||
Int m_pingInt;
|
||||
Int m_wins, m_losses;
|
||||
Int m_rankPoints, m_favoriteSide;
|
||||
};
|
||||
|
||||
/**
|
||||
* GameSpyStagingRoom class - maintains information about the GameSpy game and
|
||||
* the contents of its slot list throughout the game.
|
||||
*/
|
||||
class GameSpyStagingRoom : public GameInfo
|
||||
{
|
||||
private:
|
||||
GameSpyGameSlot m_GameSpySlot[MAX_SLOTS]; ///< The GameSpy Games Slot List
|
||||
UnicodeString m_gameName;
|
||||
Int m_id;
|
||||
Transport *m_transport;
|
||||
AsciiString m_localName;
|
||||
Bool m_requiresPassword;
|
||||
Bool m_allowObservers;
|
||||
UnsignedInt m_version;
|
||||
UnsignedInt m_exeCRC;
|
||||
UnsignedInt m_iniCRC;
|
||||
Bool m_isQM;
|
||||
|
||||
AsciiString m_ladderIP;
|
||||
AsciiString m_pingStr;
|
||||
Int m_pingInt;
|
||||
UnsignedShort m_ladderPort;
|
||||
|
||||
Int m_reportedNumPlayers;
|
||||
Int m_reportedMaxPlayers;
|
||||
Int m_reportedNumObservers;
|
||||
|
||||
public:
|
||||
GameSpyStagingRoom();
|
||||
virtual void reset( void );
|
||||
|
||||
void cleanUpSlotPointers(void);
|
||||
inline void setID(Int id) { m_id = id; }
|
||||
inline Int getID( void ) const { return m_id; }
|
||||
|
||||
inline void setHasPassword(Bool val) { m_requiresPassword = val; }
|
||||
inline Bool getHasPassword(void) const { return m_requiresPassword; }
|
||||
inline void setAllowObservers(Bool val) { m_allowObservers = val; }
|
||||
inline Bool getAllowObservers(void) const { return m_allowObservers; }
|
||||
|
||||
inline void setVersion(UnsignedInt val) { m_version = val; }
|
||||
inline UnsignedInt getVersion(void) const { return m_version; }
|
||||
inline void setExeCRC(UnsignedInt val) { m_exeCRC = val; }
|
||||
inline UnsignedInt getExeCRC(void) const { return m_exeCRC; }
|
||||
inline void setIniCRC(UnsignedInt val) { m_iniCRC = val; }
|
||||
inline UnsignedInt getIniCRC(void) const { return m_iniCRC; }
|
||||
|
||||
inline void setReportedNumPlayers(Int val) { m_reportedNumPlayers = val; }
|
||||
inline Int getReportedNumPlayers(void) const { return m_reportedNumPlayers; }
|
||||
|
||||
inline void setReportedMaxPlayers(Int val) { m_reportedMaxPlayers = val; }
|
||||
inline Int getReportedMaxPlayers(void) const { return m_reportedMaxPlayers; }
|
||||
|
||||
inline void setReportedNumObservers(Int val) { m_reportedNumObservers = val; }
|
||||
inline Int getReportedNumObservers(void) const { return m_reportedNumObservers; }
|
||||
|
||||
inline void setLadderIP( AsciiString ladderIP ) { m_ladderIP = ladderIP; }
|
||||
inline AsciiString getLadderIP( void ) const { return m_ladderIP; }
|
||||
inline void setLadderPort( UnsignedShort ladderPort ) { m_ladderPort = ladderPort; }
|
||||
inline UnsignedShort getLadderPort( void ) const { return m_ladderPort; }
|
||||
void setPingString( AsciiString pingStr );
|
||||
inline AsciiString getPingString( void ) const { return m_pingStr; }
|
||||
inline Int getPingAsInt( void ) const { return m_pingInt; }
|
||||
|
||||
virtual Bool amIHost( void ) const; ///< Convenience function - is the local player the game host?
|
||||
|
||||
GameSpyGameSlot *getGameSpySlot( Int index );
|
||||
|
||||
AsciiString generateGameSpyGameResultsPacket( void );
|
||||
AsciiString generateLadderGameResultsPacket( void );
|
||||
void markGameAsQM( void ) { m_isQM = TRUE; }
|
||||
Bool isQMGame( void ) { return m_isQM; }
|
||||
|
||||
virtual void init(void);
|
||||
virtual void resetAccepted(void); ///< Reset the accepted flag on all players
|
||||
|
||||
virtual void startGame(Int gameID); ///< Mark our game as started and record the game ID.
|
||||
void launchGame( void ); ///< NAT negotiation has finished - really start
|
||||
virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
|
||||
|
||||
inline void setGameName( UnicodeString name ) { m_gameName = name; }
|
||||
inline UnicodeString getGameName( void ) const { return m_gameName; }
|
||||
|
||||
inline void setLocalName( AsciiString name ) { m_localName = name; }
|
||||
};
|
||||
|
||||
extern GameSpyStagingRoom *TheGameSpyGame;
|
||||
|
||||
#endif // __STAGINGROOMGAMEINFO_H__
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ThreadUtils.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy thread utils
|
||||
// Author: Matthew D. Campbell, July 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMESPY_THREADUTILS_H__
|
||||
#define __GAMESPY_THREADUTILS_H__
|
||||
|
||||
std::wstring MultiByteToWideCharSingleLine( const char *orig );
|
||||
std::string WideCharStringToMultiByte( const WideChar *orig );
|
||||
|
||||
#endif // __GAMESPY_THREADUTILS_H__
|
60
Generals/Code/GameEngine/Include/GameNetwork/GameSpyChat.h
Normal file
60
Generals/Code/GameEngine/Include/GameNetwork/GameSpyChat.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameSpyChat.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Chat
|
||||
// Author: Matthew D. Campbell, February 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMESPYCHAT_H__
|
||||
#define __GAMESPYCHAT_H__
|
||||
|
||||
#include "GameSpy/Peer/Peer.h"
|
||||
|
||||
class GameWindow;
|
||||
class WindowLayout;
|
||||
|
||||
Bool GameSpySendChat(UnicodeString message, Bool isEmote, GameWindow *playerListbox = NULL);
|
||||
void GameSpyAddText( UnicodeString message, GameSpyColors color = GSCOLOR_DEFAULT );
|
||||
|
||||
extern GameWindow *progressTextWindow; ///< Text box on the progress screen
|
||||
extern GameWindow *quickmatchTextWindow; ///< Text box on the quickmatch screen
|
||||
extern GameWindow *quickmatchTextWindow; ///< Text box on the quickmatch screen
|
||||
extern GameWindow *listboxLobbyChat; ///< Chat box on the custom lobby screen
|
||||
extern GameWindow *listboxLobbyPlayers; ///< Player box on the custom lobby screen
|
||||
extern GameWindow *listboxLobbyGames; ///< Game box on the custom lobby screen
|
||||
extern GameWindow *listboxLobbyChatChannels; ///< Chat channel box on the custom lobby screen
|
||||
extern GameWindow *listboxGameSetupChat; ///< Chat box on the custom game setup screen
|
||||
extern WindowLayout *WOLMapSelectLayout; ///< Map selection overlay
|
||||
|
||||
void RoomMessageCallback(PEER peer, RoomType roomType,
|
||||
const char * nick, const char * message,
|
||||
MessageType messageType, void * param); ///< Called when a message arrives in a room.
|
||||
|
||||
void PlayerMessageCallback(PEER peer, const char * nick,
|
||||
const char * message, MessageType messageType,
|
||||
void * param); ///< Called when a private message is received from another player.
|
||||
|
||||
#endif // __GAMESPYCHAT_H__
|
47
Generals/Code/GameEngine/Include/GameNetwork/GameSpyGP.h
Normal file
47
Generals/Code/GameEngine/Include/GameNetwork/GameSpyGP.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameSpyGP.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy GP (Buddy)
|
||||
// Author: Matthew D. Campbell, March 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMESPYGP_H__
|
||||
#define __GAMESPYGP_H__
|
||||
|
||||
#include "GameSpy/GP/GP.h"
|
||||
|
||||
void GPRecvBuddyRequestCallback(GPConnection * connection, GPRecvBuddyRequestArg * arg, void * param);
|
||||
void GPRecvBuddyMessageCallback(GPConnection * pconnection, GPRecvBuddyMessageArg * arg, void * param);
|
||||
void GPRecvBuddyStatusCallback(GPConnection * connection, GPRecvBuddyStatusArg * arg, void * param);
|
||||
void GPErrorCallback(GPConnection * pconnection, GPErrorArg * arg, void * param);
|
||||
void GPConnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param);
|
||||
void GameSpyUpdateBuddyOverlay(void);
|
||||
|
||||
extern GPConnection *TheGPConnection;
|
||||
|
||||
Bool IsGameSpyBuddy(GPProfile id);
|
||||
|
||||
#endif // __GAMESPYGP_H__
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameSpyGameInfo.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy game setup information
|
||||
// Author: Matthew D. Campbell, February 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#error this file is obsolete
|
||||
|
||||
#ifndef __GAMESPYGAMEINFO_H__
|
||||
#define __GAMESPYGAMEINFO_H__
|
||||
|
||||
#include "GameSpy/Peer/Peer.h"
|
||||
|
||||
#include "GameNetwork/GameInfo.h"
|
||||
|
||||
class Transport;
|
||||
class NAT;
|
||||
|
||||
class GameSpyGameSlot : public GameSlot
|
||||
{
|
||||
public:
|
||||
GameSpyGameSlot();
|
||||
Int getProfileID( void ) { return m_profileID; }
|
||||
void setProfileID( Int id ) { m_profileID = id; }
|
||||
AsciiString getLoginName( void ) { return m_gameSpyLogin; }
|
||||
void setLoginName( AsciiString name ) { m_gameSpyLogin = name; }
|
||||
AsciiString getLocale( void ) { return m_gameSpyLocale; }
|
||||
void setLocale( AsciiString name ) { m_gameSpyLocale = name; }
|
||||
protected:
|
||||
Int m_profileID;
|
||||
AsciiString m_gameSpyLogin;
|
||||
AsciiString m_gameSpyLocale;
|
||||
};
|
||||
|
||||
/**
|
||||
* GameSpyGameInfo class - maintains information about the GameSpy game and
|
||||
* the contents of its slot list throughout the game.
|
||||
*/
|
||||
class GameSpyGameInfo : public GameInfo
|
||||
{
|
||||
private:
|
||||
GameSpyGameSlot m_GameSpySlot[MAX_SLOTS]; ///< The GameSpy Games Slot List
|
||||
SBServer m_server;
|
||||
Bool m_hasBeenQueried;
|
||||
Transport *m_transport;
|
||||
Bool m_isQM;
|
||||
|
||||
public:
|
||||
GameSpyGameInfo();
|
||||
|
||||
inline void setServer(SBServer server) { m_server = server; }
|
||||
inline SBServer getServer( void ) { return m_server; }
|
||||
|
||||
AsciiString generateGameResultsPacket( void );
|
||||
|
||||
virtual void init(void);
|
||||
virtual void resetAccepted(void); ///< Reset the accepted flag on all players
|
||||
|
||||
void markGameAsQM( void ) { m_isQM = TRUE; }
|
||||
virtual void startGame(Int gameID); ///< Mark our game as started and record the game ID.
|
||||
virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
|
||||
|
||||
void gotGOACall( void ); ///< Mark the game info as having been queried
|
||||
};
|
||||
|
||||
extern GameSpyGameInfo *TheGameSpyGame;
|
||||
|
||||
void WOLDisplayGameOptions( void );
|
||||
void WOLDisplaySlotList( void );
|
||||
void GameSpyStartGame( void );
|
||||
void GameSpyLaunchGame( void );
|
||||
Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP);
|
||||
|
||||
#endif // __LANGAMEINFO_H__
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GamespyOverlay.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy overlay screens
|
||||
// Author: Matthew D. Campbell, March 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMESPYOVERLAY_H__
|
||||
#define __GAMESPYOVERLAY_H__
|
||||
|
||||
#include "Common/NameKeyGenerator.h"
|
||||
#include "GameClient/WindowLayout.h"
|
||||
#include "GameClient/Gadget.h"
|
||||
#include "GameClient/Shell.h"
|
||||
#include "GameClient/KeyDefs.h"
|
||||
#include "GameClient/GameWindowManager.h"
|
||||
|
||||
void ClearGSMessageBoxes( void ); ///< Tear down any GS message boxes (e.g. in case we have a new one to put up)
|
||||
void GSMessageBoxOk(UnicodeString titleString,UnicodeString bodyString, GameWinMsgBoxFunc okFunc = NULL); ///< Display a Message box with Ok button and track it
|
||||
void GSMessageBoxOkCancel(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc okFunc, GameWinMsgBoxFunc cancelFunc); ///< Display a Message box with Ok/Cancel buttons and track it
|
||||
void GSMessageBoxYesNo(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc yesFunc, GameWinMsgBoxFunc noFunc); ///< Display a Message box with Yes/No buttons and track it
|
||||
void RaiseGSMessageBox( void ); ///< Bring GS message box to the foreground (if we transition screens while a message box is up)
|
||||
|
||||
enum GSOverlayType
|
||||
{
|
||||
GSOVERLAY_PLAYERINFO,
|
||||
GSOVERLAY_MAPSELECT,
|
||||
GSOVERLAY_BUDDY,
|
||||
GSOVERLAY_PAGE,
|
||||
GSOVERLAY_GAMEOPTIONS,
|
||||
GSOVERLAY_GAMEPASSWORD,
|
||||
GSOVERLAY_LADDERSELECT,
|
||||
GSOVERLAY_LOCALESELECT,
|
||||
GSOVERLAY_OPTIONS,
|
||||
GSOVERLAY_MAX
|
||||
};
|
||||
|
||||
void GameSpyOpenOverlay( GSOverlayType );
|
||||
void GameSpyCloseOverlay( GSOverlayType );
|
||||
void GameSpyCloseAllOverlays( void );
|
||||
Bool GameSpyIsOverlayOpen( GSOverlayType );
|
||||
void GameSpyToggleOverlay( GSOverlayType );
|
||||
void GameSpyUpdateOverlays( void );
|
||||
void ReOpenPlayerInfo( void );
|
||||
void CheckReOpenPlayerInfo(void );
|
||||
#endif // __GAMESPYOVERLAY_H__
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameSpyPersistentStorage.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy Persistent Storage
|
||||
// Author: Matthew D. Campbell, March 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMESPYPersistentStorage_H__
|
||||
#define __GAMESPYPersistentStorage_H__
|
||||
|
||||
class GameSpyPlayerInfoInterface : public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GameSpyPlayerInfoInterface() { };
|
||||
|
||||
virtual void init( void ) = 0;
|
||||
virtual void reset( void ) = 0;
|
||||
virtual void update( void ) = 0;
|
||||
|
||||
virtual void setLocale( AsciiString locale, Bool setOnServer = true ) = 0;
|
||||
virtual AsciiString getLocale( void ) = 0;
|
||||
virtual void setWins( Int wins, Bool setOnServer = true ) = 0;
|
||||
virtual Int getWins( void ) = 0;
|
||||
virtual void setLosses( Int losses, Bool setOnServer = true ) = 0;
|
||||
virtual Int getLosses( void ) = 0;
|
||||
|
||||
virtual void readFromServer( void ) = 0;
|
||||
|
||||
virtual void threadReadFromServer( void ) = 0;
|
||||
virtual void threadSetLocale( AsciiString val ) = 0;
|
||||
virtual void threadSetWins ( AsciiString val ) = 0;
|
||||
virtual void threadSetLosses( AsciiString val ) = 0;
|
||||
};
|
||||
|
||||
GameSpyPlayerInfoInterface *createGameSpyPlayerInfo( void );
|
||||
|
||||
extern GameSpyPlayerInfoInterface *TheGameSpyPlayerInfo;
|
||||
|
||||
#endif // __GAMESPYPersistentStorage_H__
|
67
Generals/Code/GameEngine/Include/GameNetwork/GameSpyThread.h
Normal file
67
Generals/Code/GameEngine/Include/GameNetwork/GameSpyThread.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameSpyThread.h //////////////////////////////////////////////////////
|
||||
// Generals GameSpy thread class
|
||||
// Author: Matthew D. Campbell, March 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GAMESPYTHREAD_H__
|
||||
#define __GAMESPYTHREAD_H__
|
||||
|
||||
#include "mutex.h"
|
||||
#include "thread.h"
|
||||
|
||||
class GameSpyThreadClass : public ThreadClass
|
||||
{
|
||||
|
||||
public:
|
||||
GameSpyThreadClass::GameSpyThreadClass() : ThreadClass() { m_doLogin = false; m_readStats = false; m_updateWins = false; m_updateLosses = false; m_updateLocale = false; m_showLocaleSelect = false; m_nextShellScreen.clear(); }
|
||||
void queueLogin(AsciiString nick, AsciiString pass, AsciiString email) { m_nick = nick; m_pass = pass; m_email = email; m_doLogin = true; }
|
||||
void queueReadPersistentStatsFromServer( void ) { m_readStats = true; }
|
||||
void queueUpdateLocale( AsciiString locale ) { m_locale = locale; m_updateLocale = true; }
|
||||
void queueUpdateWins ( AsciiString wins ) { m_wins = wins; m_updateWins = true; }
|
||||
void queueUpdateLosses( AsciiString losses ) { m_losses = losses; m_updateLosses = true; }
|
||||
|
||||
void Thread_Function();
|
||||
|
||||
AsciiString getNextShellScreen( void );
|
||||
Bool showLocaleSelect( void );
|
||||
|
||||
void setNextShellScreen( AsciiString nextShellScreen );
|
||||
void setShowLocaleSelect( Bool val );
|
||||
|
||||
private:
|
||||
AsciiString m_nick, m_pass, m_email;
|
||||
Bool m_doLogin, m_readStats, m_updateWins, m_updateLosses, m_updateLocale;
|
||||
AsciiString m_locale, m_wins, m_losses;
|
||||
AsciiString m_nextShellScreen;
|
||||
Bool m_showLocaleSelect;
|
||||
};
|
||||
|
||||
extern GameSpyThreadClass *TheGameSpyThread;
|
||||
extern MutexClass TheGameSpyMutex;
|
||||
|
||||
#endif // __GAMESPYTHREAD_H__
|
82
Generals/Code/GameEngine/Include/GameNetwork/IPEnumeration.h
Normal file
82
Generals/Code/GameEngine/Include/GameNetwork/IPEnumeration.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// IPEnumeration.h ///////////////////////////////////////////////////////////////
|
||||
// Class for enumerating IP addresses
|
||||
// Author: Matthew D. Campbell, October 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _IPENUMERATION_H_
|
||||
#define _IPENUMERATION_H_
|
||||
|
||||
#include "GameNetwork/Transport.h"
|
||||
|
||||
/**
|
||||
* IP wrapper class.
|
||||
*/
|
||||
class EnumeratedIP : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(EnumeratedIP, "EnumeratedIP")
|
||||
public:
|
||||
EnumeratedIP() { m_IPstring = ""; m_next = NULL; m_IP = 0; }
|
||||
|
||||
// Access functions
|
||||
inline AsciiString getIPstring( void ) { return m_IPstring; }
|
||||
inline void setIPstring( AsciiString name ) { m_IPstring = name; }
|
||||
inline UnsignedInt getIP( void ) { return m_IP; }
|
||||
inline void setIP( UnsignedInt IP ) { m_IP = IP; }
|
||||
inline EnumeratedIP *getNext( void ) { return m_next; }
|
||||
inline void setNext( EnumeratedIP *next ) { m_next = next; }
|
||||
|
||||
protected:
|
||||
AsciiString m_IPstring;
|
||||
UnsignedInt m_IP;
|
||||
EnumeratedIP *m_next;
|
||||
};
|
||||
EMPTY_DTOR(EnumeratedIP)
|
||||
|
||||
|
||||
/**
|
||||
* The IPEnumeration class is used to obtain a list of IP addresses on the
|
||||
* local machine.
|
||||
*/
|
||||
class IPEnumeration
|
||||
{
|
||||
public:
|
||||
|
||||
IPEnumeration();
|
||||
~IPEnumeration();
|
||||
|
||||
EnumeratedIP * getAddresses( void ); ///< Return a linked list of local IP addresses
|
||||
AsciiString getMachineName( void ); ///< Return the Network Neighborhood machine name
|
||||
|
||||
protected:
|
||||
|
||||
EnumeratedIP *m_IPlist;
|
||||
Bool m_isWinsockInitialized;
|
||||
};
|
||||
|
||||
|
||||
#endif // _IPENUMERATION_H_
|
423
Generals/Code/GameEngine/Include/GameNetwork/LANAPI.h
Normal file
423
Generals/Code/GameEngine/Include/GameNetwork/LANAPI.h
Normal file
|
@ -0,0 +1,423 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// LANAPI.h ///////////////////////////////////////////////////////////////
|
||||
// LANAPI singleton class - defines interface to LAN broadcast communications
|
||||
// Author: Matthew D. Campbell, October 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _LANAPI_H_
|
||||
#define _LANAPI_H_
|
||||
|
||||
#include "GameNetwork/Transport.h"
|
||||
#include "GameNetwork/NetworkInterface.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "GameNetwork/LANPlayer.h"
|
||||
#include "GameNetwork/LANGameInfo.h"
|
||||
|
||||
//static const Int g_lanPlayerNameLength = 20;
|
||||
static const Int g_lanPlayerNameLength = 12; // reduced length because of game option length
|
||||
//static const Int g_lanLoginNameLength = 16;
|
||||
//static const Int g_lanHostNameLength = 16;
|
||||
static const Int g_lanLoginNameLength = 1;
|
||||
static const Int g_lanHostNameLength = 1;
|
||||
//static const Int g_lanGameNameLength = 32;
|
||||
static const Int g_lanGameNameLength = 16; // reduced length because of game option length
|
||||
static const Int g_lanGameNameReservedLength = 16; // save N wchars for ID info
|
||||
static const Int g_lanMaxChatLength = 100;
|
||||
static const Int m_lanMaxOptionsLength = MAX_PACKET_SIZE - ( 8 + (g_lanGameNameLength+1)*2 + 4 + (g_lanPlayerNameLength+1)*2
|
||||
+ (g_lanLoginNameLength+1) + (g_lanHostNameLength+1) );
|
||||
static const Int g_maxSerialLength = 23; // including the trailing '\0'
|
||||
|
||||
struct LANMessage;
|
||||
|
||||
/**
|
||||
* The LANAPI class is used to instantiate a singleton which
|
||||
* implements the interface to all LAN broadcast communications.
|
||||
*/
|
||||
class LANAPIInterface : public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~LANAPIInterface() { };
|
||||
|
||||
virtual void init( void ) = 0; ///< Initialize or re-initialize the instance
|
||||
virtual void reset( void ) = 0; ///< reset the logic system
|
||||
virtual void update( void ) = 0; ///< update the world
|
||||
|
||||
virtual void setIsActive(Bool isActive ) = 0; ///< Tell TheLAN whether or not the app is active.
|
||||
|
||||
// Possible types of chat messages
|
||||
enum ChatType
|
||||
{
|
||||
LANCHAT_NORMAL = 0,
|
||||
LANCHAT_EMOTE,
|
||||
LANCHAT_SYSTEM,
|
||||
LANCHAT_MAX
|
||||
};
|
||||
|
||||
// Request functions generate network traffic
|
||||
virtual void RequestLocations( void ) = 0; ///< Request everybody to respond with where they are
|
||||
virtual void RequestGameJoin( LANGameInfo *game, UnsignedInt ip = 0 ) = 0; ///< Request to join a game
|
||||
virtual void RequestGameJoinDirectConnect( UnsignedInt ipaddress ) = 0; ///< Request to join a game at an IP address
|
||||
virtual void RequestGameLeave( void ) = 0; ///< Tell everyone we're leaving
|
||||
virtual void RequestAccept( void ) = 0; ///< Indicate we're OK with the game options
|
||||
virtual void RequestHasMap( void ) = 0; ///< Send our map status
|
||||
virtual void RequestChat( UnicodeString message, ChatType format ) = 0; ///< Send a chat message
|
||||
virtual void RequestGameStart( void ) = 0; ///< Tell everyone the game is starting
|
||||
virtual void RequestGameStartTimer( Int seconds ) = 0;
|
||||
virtual void RequestGameOptions( AsciiString gameOptions, Bool isPublic, UnsignedInt ip = 0 ) = 0; ///< Change the game options
|
||||
virtual void RequestGameCreate( UnicodeString gameName, Bool isDirectConnect ) = 0; ///< Try to host a game
|
||||
virtual void RequestGameAnnounce( void ) = 0; ///< Sound out current game info if host
|
||||
// virtual void RequestSlotList( void ) = 0; ///< Pump out the Slot info.
|
||||
virtual void RequestSetName( UnicodeString newName ) = 0; ///< Pick a new name
|
||||
virtual void RequestLobbyLeave( Bool forced ) = 0; ///< Announce that we're leaving the lobby
|
||||
virtual void ResetGameStartTimer( void ) = 0;
|
||||
|
||||
// Possible result codes passed to On functions
|
||||
enum ReturnType
|
||||
{
|
||||
RET_OK, // Any function
|
||||
RET_TIMEOUT, // OnGameJoin/Leave/Start, etc
|
||||
RET_GAME_FULL, // OnGameJoin
|
||||
RET_DUPLICATE_NAME, // OnGameJoin
|
||||
RET_CRC_MISMATCH, // OnGameJoin
|
||||
RET_SERIAL_DUPE, // OnGameJoin
|
||||
RET_GAME_STARTED, // OnGameJoin
|
||||
RET_GAME_EXISTS, // OnGameCreate
|
||||
RET_GAME_GONE, // OnGameJoin
|
||||
RET_BUSY, // OnGameCreate/Join/etc if another action is in progress
|
||||
RET_UNKNOWN, // Default message for oddity
|
||||
RET_MAX
|
||||
};
|
||||
UnicodeString getErrorStringFromReturnType( ReturnType ret );
|
||||
|
||||
// On functions are (generally) the result of network traffic
|
||||
virtual void OnGameList( LANGameInfo *gameList ) = 0; ///< List of games
|
||||
virtual void OnPlayerList( LANPlayer *playerList ) = 0; ///< List of players in the Lobby
|
||||
virtual void OnGameJoin( ReturnType ret, LANGameInfo *theGame ) = 0; ///< Did we get in the game?
|
||||
virtual void OnPlayerJoin( Int slot, UnicodeString playerName ) = 0; ///< Someone else joined our game (host only; joiners get a slotlist)
|
||||
virtual void OnHostLeave( void ) = 0; ///< Host left the game
|
||||
virtual void OnPlayerLeave( UnicodeString player ) = 0; ///< Someone left the game
|
||||
virtual void OnAccept( UnsignedInt playerIP, Bool status ) = 0; ///< Someone's accept status changed
|
||||
virtual void OnHasMap( UnsignedInt playerIP, Bool status ) = 0; ///< Someone's map status changed
|
||||
virtual void OnChat( UnicodeString player, UnsignedInt ip,
|
||||
UnicodeString message, ChatType format ) = 0; ///< Chat message from someone
|
||||
virtual void OnGameStart( void ) = 0; ///< The game is starting
|
||||
virtual void OnGameStartTimer( Int seconds ) = 0;
|
||||
virtual void OnGameOptions( UnsignedInt playerIP, Int playerSlot, AsciiString options ) = 0; ///< Someone sent game options
|
||||
virtual void OnGameCreate( ReturnType ret ) = 0; ///< Your game is created
|
||||
// virtual void OnSlotList( ReturnType ret, LANGameInfo *theGame ) = 0; ///< Slotlist for a game in setup
|
||||
virtual void OnNameChange( UnsignedInt IP, UnicodeString newName ) = 0; ///< Someone has morphed
|
||||
|
||||
// Misc utility functions
|
||||
virtual LANGameInfo * LookupGame( UnicodeString gameName ) = 0; ///< return a pointer to a game we know about
|
||||
virtual LANGameInfo * LookupGameByListOffset( Int offset ) = 0; ///< return a pointer to a game we know about
|
||||
virtual Bool SetLocalIP( UnsignedInt localIP ) = 0; ///< For multiple NIC machines
|
||||
virtual void SetLocalIP( AsciiString localIP ) = 0; ///< For multiple NIC machines
|
||||
virtual Bool AmIHost( void ) = 0; ///< Am I hosting a game?
|
||||
virtual inline UnicodeString GetMyName( void ) = 0; ///< What's my name?
|
||||
virtual inline LANGameInfo *GetMyGame( void ) = 0; ///< What's my Game?
|
||||
virtual void fillInLANMessage( LANMessage *msg ) = 0; ///< Fill in default params
|
||||
virtual void checkMOTD( void ) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The LANAPI class is used to instantiate a singleton which
|
||||
* implements the interface to all LAN broadcast communications.
|
||||
*/
|
||||
class LANAPI : public LANAPIInterface
|
||||
{
|
||||
public:
|
||||
|
||||
LANAPI();
|
||||
virtual ~LANAPI();
|
||||
|
||||
virtual void init( void ); ///< Initialize or re-initialize the instance
|
||||
virtual void reset( void ); ///< reset the logic system
|
||||
virtual void update( void ); ///< update the world
|
||||
|
||||
virtual void setIsActive(Bool isActive); ///< tell TheLAN whether or not
|
||||
|
||||
// Request functions generate network traffic
|
||||
virtual void RequestLocations( void ); ///< Request everybody to respond with where they are
|
||||
virtual void RequestGameJoin( LANGameInfo *game, UnsignedInt ip = 0 ); ///< Request to join a game
|
||||
virtual void RequestGameJoinDirectConnect( UnsignedInt ipaddress ); ///< Request to join a game at an IP address
|
||||
virtual void RequestGameLeave( void ); ///< Tell everyone we're leaving
|
||||
virtual void RequestAccept( void ); ///< Indicate we're OK with the game options
|
||||
virtual void RequestHasMap( void ); ///< Send our map status
|
||||
virtual void RequestChat( UnicodeString message, ChatType format ); ///< Send a chat message
|
||||
virtual void RequestGameStart( void ); ///< Tell everyone the game is starting
|
||||
virtual void RequestGameStartTimer( Int seconds );
|
||||
virtual void RequestGameOptions( AsciiString gameOptions, Bool isPublic, UnsignedInt ip = 0 ); ///< Change the game options
|
||||
virtual void RequestGameCreate( UnicodeString gameName, Bool isDirectConnect ); ///< Try to host a game
|
||||
virtual void RequestGameAnnounce( void ); ///< Send out game info if host
|
||||
virtual void RequestSetName( UnicodeString newName ); ///< Pick a new name
|
||||
// virtual void RequestSlotList( void ); ///< Pump out the Slot info.
|
||||
virtual void RequestLobbyLeave( Bool forced ); ///< Announce that we're leaving the lobby
|
||||
virtual void ResetGameStartTimer( void );
|
||||
|
||||
// On functions are (generally) the result of network traffic
|
||||
virtual void OnGameList( LANGameInfo *gameList ); ///< List of games
|
||||
virtual void OnPlayerList( LANPlayer *playerList ); ///< List of players in the Lobby
|
||||
virtual void OnGameJoin( ReturnType ret, LANGameInfo *theGame ); ///< Did we get in the game?
|
||||
virtual void OnPlayerJoin( Int slot, UnicodeString playerName ); ///< Someone else joined our game (host only; joiners get a slotlist)
|
||||
virtual void OnHostLeave( void ); ///< Host left the game
|
||||
virtual void OnPlayerLeave( UnicodeString player ); ///< Someone left the game
|
||||
virtual void OnAccept( UnsignedInt playerIP, Bool status ); ///< Someone's accept status changed
|
||||
virtual void OnHasMap( UnsignedInt playerIP, Bool status ); ///< Someone's map status changed
|
||||
virtual void OnChat( UnicodeString player, UnsignedInt ip,
|
||||
UnicodeString message, ChatType format ); ///< Chat message from someone
|
||||
virtual void OnGameStart( void ); ///< The game is starting
|
||||
virtual void OnGameStartTimer( Int seconds );
|
||||
virtual void OnGameOptions( UnsignedInt playerIP, Int playerSlot, AsciiString options ); ///< Someone sent game options
|
||||
virtual void OnGameCreate( ReturnType ret ); ///< Your game is created
|
||||
//virtual void OnSlotList( ReturnType ret, LANGameInfo *theGame ); ///< Slotlist for a game in setup
|
||||
virtual void OnNameChange( UnsignedInt IP, UnicodeString newName ); ///< Someone has morphed
|
||||
virtual void OnInActive( UnsignedInt IP ); ///< Someone has alt-tabbed out.
|
||||
|
||||
|
||||
// Misc utility functions
|
||||
virtual LANGameInfo * LookupGame( UnicodeString gameName ); ///< return a pointer to a game we know about
|
||||
virtual LANGameInfo * LookupGameByListOffset( Int offset ); ///< return a pointer to a game we know about
|
||||
virtual LANPlayer * LookupPlayer( UnsignedInt playerIP ); ///< return a pointer to a player we know about
|
||||
virtual Bool SetLocalIP( UnsignedInt localIP ); ///< For multiple NIC machines
|
||||
virtual void SetLocalIP( AsciiString localIP ); ///< For multiple NIC machines
|
||||
virtual Bool AmIHost( void ); ///< Am I hosting a game?
|
||||
virtual inline UnicodeString GetMyName( void ) { return m_name; } ///< What's my name?
|
||||
virtual inline LANGameInfo* GetMyGame( void ) { return m_currentGame; } ///< What's my Game?
|
||||
virtual inline UnsignedInt GetLocalIP( void ) { return m_localIP; } ///< What's my IP?
|
||||
virtual void fillInLANMessage( LANMessage *msg ); ///< Fill in default params
|
||||
virtual void checkMOTD( void );
|
||||
protected:
|
||||
|
||||
enum PendingActionType
|
||||
{
|
||||
ACT_NONE = 0,
|
||||
ACT_JOIN,
|
||||
ACT_JOINDIRECTCONNECT,
|
||||
ACT_LEAVE,
|
||||
ACT_MAX
|
||||
};
|
||||
|
||||
static const UnsignedInt s_resendDelta; // in ms
|
||||
|
||||
protected:
|
||||
LANPlayer * m_lobbyPlayers; ///< List of players in the lobby
|
||||
LANGameInfo * m_games; ///< List of games
|
||||
UnicodeString m_name; ///< Who do we think we are?
|
||||
AsciiString m_userName; ///< login name
|
||||
AsciiString m_hostName; ///< machine name
|
||||
UnsignedInt m_gameStartTime;
|
||||
Int m_gameStartSeconds;
|
||||
|
||||
PendingActionType m_pendingAction; ///< What action are we performing?
|
||||
UnsignedInt m_expiration; ///< When should we give up on our action?
|
||||
UnsignedInt m_actionTimeout;
|
||||
UnsignedInt m_directConnectRemoteIP;///< The IP address of the game we are direct connecting to.
|
||||
|
||||
// Resend timer ---------------------------------------------------------------------------
|
||||
UnsignedInt m_lastResendTime; // in ms
|
||||
|
||||
Bool m_isInLANMenu; ///< true while we are in a LAN menu (lobby, game options, direct connect)
|
||||
Bool m_inLobby; ///< Are we in the lobby (not in a game)?
|
||||
LANGameInfo * m_currentGame; ///< Pointer to game (setup screen) we are currently in (NULL for lobby)
|
||||
//LANGameInfo *m_currentGameInfo; ///< Pointer to game setup info we are currently in.
|
||||
|
||||
UnsignedInt m_localIP;
|
||||
Transport* m_transport;
|
||||
|
||||
UnsignedInt m_broadcastAddr;
|
||||
|
||||
UnsignedInt m_lastUpdate;
|
||||
AsciiString m_lastGameopt; /// @todo: hack for demo - remove this
|
||||
|
||||
Bool m_isActive; ///< is the game currently active?
|
||||
|
||||
protected:
|
||||
void sendMessage(LANMessage *msg, UnsignedInt ip = 0); // Convenience function
|
||||
void removePlayer(LANPlayer *player);
|
||||
void removeGame(LANGameInfo *game);
|
||||
void addPlayer(LANPlayer *player);
|
||||
void addGame(LANGameInfo *game);
|
||||
AsciiString createSlotString( void );
|
||||
|
||||
// Functions to handle incoming messages -----------------------------------
|
||||
void handleRequestLocations( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleGameAnnounce( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleLobbyAnnounce( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleRequestGameInfo( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleRequestJoin( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleJoinAccept( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleJoinDeny( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleRequestGameLeave( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleRequestLobbyLeave( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleSetAccept( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleHasMap( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleChat( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleGameStart( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleGameStartTimer( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleGameOptions( LANMessage *msg, UnsignedInt senderIP );
|
||||
void handleInActive( LANMessage *msg, UnsignedInt senderIP );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* LAN message class
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
struct LANMessage
|
||||
{
|
||||
enum ///< What kind of message are we?
|
||||
{
|
||||
// Locating everybody
|
||||
MSG_REQUEST_LOCATIONS, ///< Hey, where is everybody?
|
||||
MSG_GAME_ANNOUNCE, ///< Here I am, and here's my game info!
|
||||
MSG_LOBBY_ANNOUNCE, ///< Hey, I'm in the lobby!
|
||||
|
||||
// Joining games
|
||||
MSG_REQUEST_JOIN, ///< Let me in! Let me in!
|
||||
MSG_JOIN_ACCEPT, ///< Okay, you can join.
|
||||
MSG_JOIN_DENY, ///< Go away! We don't want any!
|
||||
|
||||
// Leaving games
|
||||
MSG_REQUEST_GAME_LEAVE, ///< I want to leave the game
|
||||
MSG_REQUEST_LOBBY_LEAVE,///< I'm leaving the lobby
|
||||
|
||||
// Game options, chat, etc
|
||||
MSG_SET_ACCEPT, ///< I'm cool with everything as is.
|
||||
MSG_MAP_AVAILABILITY, ///< I do (not) have the map.
|
||||
MSG_CHAT, ///< Just spouting my mouth off.
|
||||
MSG_GAME_START, ///< Hold on; we're starting!
|
||||
MSG_GAME_START_TIMER, ///< The game will start in N seconds
|
||||
MSG_GAME_OPTIONS, ///< Here's some info about the game.
|
||||
MSG_INACTIVE, ///< I've alt-tabbed out. Unaccept me cause I'm a poo-flinging monkey.
|
||||
|
||||
MSG_REQUEST_GAME_INFO, ///< For direct connect, get the game info from a specific IP Address
|
||||
|
||||
MSG_MAX
|
||||
} LANMessageType;
|
||||
|
||||
WideChar name[g_lanPlayerNameLength+1]; ///< My name, for convenience
|
||||
char userName[g_lanLoginNameLength+1]; ///< login name, for convenience
|
||||
char hostName[g_lanHostNameLength+1]; ///< machine name, for convenience
|
||||
|
||||
// No additional data is required for REQUEST_LOCATIONS, LOBBY_ANNOUNCE,
|
||||
// REQUEST_LOBBY_LEAVE, GAME_START.
|
||||
union
|
||||
{
|
||||
// StartTimer is sent with GAME_START_TIMER
|
||||
struct
|
||||
{
|
||||
Int seconds;
|
||||
} StartTimer;
|
||||
|
||||
// GameJoined is sent with REQUEST_GAME_LEAVE
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
} GameToLeave;
|
||||
|
||||
// GameInfo if sent with GAME_ANNOUNCE
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
Bool inProgress;
|
||||
char options[m_lanMaxOptionsLength+1];
|
||||
Bool isDirectConnect;
|
||||
} GameInfo;
|
||||
|
||||
// PlayerInfo is sent with REQUEST_GAME_INFO for direct connect games.
|
||||
struct
|
||||
{
|
||||
UnsignedInt ip;
|
||||
WideChar playerName[g_lanPlayerNameLength+1];
|
||||
} PlayerInfo;
|
||||
|
||||
// GameToJoin is sent with REQUEST_JOIN
|
||||
struct
|
||||
{
|
||||
UnsignedInt gameIP;
|
||||
UnsignedInt exeCRC;
|
||||
UnsignedInt iniCRC;
|
||||
char serial[g_maxSerialLength];
|
||||
} GameToJoin;
|
||||
|
||||
// GameJoined is sent with JOIN_ACCEPT
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
UnsignedInt gameIP;
|
||||
UnsignedInt playerIP;
|
||||
Int slotPosition;
|
||||
} GameJoined;
|
||||
|
||||
// GameNotJoined is sent with JOIN_DENY
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
UnsignedInt gameIP;
|
||||
UnsignedInt playerIP;
|
||||
LANAPIInterface::ReturnType reason;
|
||||
} GameNotJoined;
|
||||
|
||||
// Accept is sent with SET_ACCEPT
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
Bool isAccepted;
|
||||
} Accept;
|
||||
|
||||
// Accept is sent with MAP_AVAILABILITY
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
UnsignedInt mapCRC; // to make sure we're talking about the same map
|
||||
Bool hasMap;
|
||||
} MapStatus;
|
||||
|
||||
// Chat is sent with CHAT
|
||||
struct
|
||||
{
|
||||
WideChar gameName[g_lanGameNameLength+1];
|
||||
LANAPIInterface::ChatType chatType;
|
||||
WideChar message[g_lanMaxChatLength+1];
|
||||
} Chat;
|
||||
|
||||
// GameOptions is sent with GAME_OPTIONS
|
||||
struct
|
||||
{
|
||||
char options[m_lanMaxOptionsLength+1];
|
||||
} GameOptions;
|
||||
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#endif // _LANAPI_H_
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// FILE: LANAPICallbacks.h
|
||||
// Author: Chris Huybregts, October 2001
|
||||
// Description: LAN API Callbacks header
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#ifndef _LANAPI_CALLBACKS_H_
|
||||
#define _LANAPI_CALLBACKS_H_
|
||||
|
||||
#include "Common/NameKeyGenerator.h"
|
||||
#include "GameClient/Shell.h"
|
||||
#include "GameClient/GadgetListBox.h"
|
||||
#include "GameClient/GadgetTextEntry.h"
|
||||
#include "GameNetwork/LANAPI.h"
|
||||
|
||||
|
||||
// LAN API Singleton ----------------------------------------------------------------------
|
||||
extern LANAPI *TheLAN;
|
||||
|
||||
//external declarations of the Gadgets the callbacks can use
|
||||
// LanLobby
|
||||
extern NameKeyType listboxChatWindowID;
|
||||
extern GameWindow *listboxChatWindow;
|
||||
extern GameWindow *listboxPlayers;
|
||||
extern NameKeyType listboxGamesID;
|
||||
extern GameWindow *listboxGames;
|
||||
//LanGame Options screen
|
||||
extern NameKeyType listboxChatWindowLanGameID;
|
||||
extern GameWindow *listboxChatWindowLanGame;
|
||||
extern WindowLayout *mapSelectLayout;
|
||||
// ScoreScreen
|
||||
extern NameKeyType listboxChatWindowScoreScreenID;
|
||||
extern GameWindow *listboxChatWindowScoreScreen;
|
||||
|
||||
|
||||
//Colors used for the chat dialogs
|
||||
extern const Color playerColor;
|
||||
extern const Color gameColor;
|
||||
extern const Color gameInProgressColor;
|
||||
extern const Color chatNormalColor;
|
||||
extern const Color chatActionColor;
|
||||
extern const Color chatLocalNormalColor;
|
||||
extern const Color chatLocalActionColor;
|
||||
extern const Color chatSystemColor;
|
||||
extern const Color chatSystemColor;
|
||||
extern const Color acceptTrueColor;
|
||||
extern const Color acceptFalseColor;
|
||||
|
||||
|
||||
void lanUpdateSlotList( void );
|
||||
void updateGameOptions( void );
|
||||
|
||||
|
||||
//Enum is used for the utility function so other windows do not need
|
||||
//to know about controls on LanGameOptions window.
|
||||
enum PostToLanGameType{ SEND_GAME_OPTS = 0,
|
||||
MAP_BACK,
|
||||
POST_TO_LAN_GAME_TYPE_COUNT };
|
||||
//the utility function mentioned above
|
||||
void PostToLanGameOptions(PostToLanGameType post);
|
||||
|
||||
|
||||
|
||||
#endif //_LANAPI_CALLBACKS_H_
|
185
Generals/Code/GameEngine/Include/GameNetwork/LANGameInfo.h
Normal file
185
Generals/Code/GameEngine/Include/GameNetwork/LANGameInfo.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: LANGameInfo.h //////////////////////////////////////////////////////
|
||||
// Generals LAN game setup information
|
||||
// Author: Matthew D. Campbell, December 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __LANGAMEINFO_H__
|
||||
#define __LANGAMEINFO_H__
|
||||
|
||||
#include "GameNetwork/GameInfo.h"
|
||||
#include "GameNetwork/LANPlayer.h"
|
||||
|
||||
class GameWindow;
|
||||
|
||||
/**
|
||||
* LANGameSlot class - maintains information about the contents of a
|
||||
* game slot. This persists throughout the game.
|
||||
*/
|
||||
class LANGameSlot : public GameSlot
|
||||
{
|
||||
public:
|
||||
LANGameSlot();
|
||||
|
||||
LANPlayer *getUser( void ); ///< Get the User structure associated with the slot (NULL for non-humans)
|
||||
|
||||
// Various tests
|
||||
Bool isUser( LANPlayer *user ); ///< Does this slot contain the given user? Based off user->name
|
||||
Bool isUser( UnicodeString userName ); ///< Does this slot contain the given user?
|
||||
Bool isLocalPlayer( void ) const; ///< Is this slot me?
|
||||
inline void setLogin( UnicodeString name ) { m_user.setLogin(name); }
|
||||
inline void setLogin( AsciiString name ) { m_user.setLogin(name); }
|
||||
inline void setHost( UnicodeString name ) { m_user.setHost(name); }
|
||||
inline void setHost( AsciiString name ) { m_user.setHost(name); }
|
||||
inline void setSerial( AsciiString serial ) { m_serial = serial; }
|
||||
inline AsciiString getSerial( void ) { return m_serial; }
|
||||
|
||||
inline void setLastHeard( UnsignedInt t ) { m_lastHeard = t; }
|
||||
inline UnsignedInt getLastHeard( void ) { return m_lastHeard; }
|
||||
|
||||
//LANGameSlot& operator=(const LANGameSlot& src);
|
||||
|
||||
private:
|
||||
|
||||
LANPlayer m_user; ///< filled in for each getUser() call
|
||||
AsciiString m_serial;
|
||||
|
||||
UnsignedInt m_lastHeard;
|
||||
};
|
||||
|
||||
/**
|
||||
* LANGameInfo class - maintains information about the LAN game and
|
||||
* the contents of its slot list hroughout the game.
|
||||
*/
|
||||
class LANGameInfo : public GameInfo
|
||||
{
|
||||
private:
|
||||
LANGameSlot m_LANSlot[MAX_SLOTS]; ///< The Lan Games Slot List
|
||||
|
||||
public:
|
||||
LANGameInfo();
|
||||
void setSlot( Int slotNum, LANGameSlot slotInfo ); ///< Set the slot state (human, open, AI, etc)
|
||||
LANGameSlot* getLANSlot( Int slotNum ); ///< Get the slot
|
||||
const LANGameSlot* getConstLANSlot( Int slotNum ) const; ///< Get the slot
|
||||
virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
|
||||
Int getSlotNum( UnicodeString userName ); ///< Get the slot number corresponding to a specific user, or -1 if he's not present
|
||||
|
||||
inline UnsignedInt getLastHeard( void ) { return m_lastHeard; }
|
||||
inline void setLastHeard( UnsignedInt lastHeard ) { m_lastHeard = lastHeard; }
|
||||
inline LANGameInfo *getNext( void ) { return m_next; }
|
||||
inline void setNext( LANGameInfo *next ) { m_next = next; }
|
||||
|
||||
// Game options
|
||||
void setMap( AsciiString mapName ); ///< Set the map to play on
|
||||
void setSeed( Int seed ); ///< Set the random seed for the game
|
||||
|
||||
inline void setName( UnicodeString name ) { m_gameName = name; } ///< Set the Name of the Game
|
||||
inline UnicodeString getName( void ) { return m_gameName; } ///< Get the Name of the Game
|
||||
|
||||
// Convinience functions that interface with the LANPlayer held in the slot list
|
||||
virtual void resetAccepted(void); ///< Reset the accepted flag on all players
|
||||
Bool amIHost( void ); ///< Convenience function - is the local player the game host?
|
||||
|
||||
/// Get the IP of selected player or return 0
|
||||
inline UnsignedInt getIP( int who )
|
||||
{
|
||||
return m_LANSlot[who].getIP();
|
||||
}
|
||||
|
||||
/// Set the IP of the Selected Player
|
||||
inline void setIP( int who, UnsignedInt IP )
|
||||
{
|
||||
m_LANSlot[who].setIP(IP);
|
||||
}
|
||||
|
||||
/// set whether or not this is a direct connect game or not.
|
||||
inline void setIsDirectConnect(Bool isDirectConnect)
|
||||
{
|
||||
m_isDirectConnect = isDirectConnect;
|
||||
}
|
||||
|
||||
/// returns whether or not this is a direct connect game or not.
|
||||
inline Bool getIsDirectConnect()
|
||||
{
|
||||
return m_isDirectConnect;
|
||||
}
|
||||
|
||||
/// Set the Player Name
|
||||
inline void setPlayerName( int who, UnicodeString name )
|
||||
{
|
||||
m_LANSlot[who].setName(name);
|
||||
}
|
||||
|
||||
/// Return the Player name or TheEmptyString
|
||||
inline UnicodeString getPlayerName(int who)
|
||||
{
|
||||
return m_LANSlot[who].getName();
|
||||
}
|
||||
|
||||
/// Return the time the player was heard from last, or 0
|
||||
inline UnsignedInt getPlayerLastHeard( int who )
|
||||
{
|
||||
if (m_LANSlot[who].isHuman())
|
||||
return m_LANSlot[who].getLastHeard();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Set the last time we heard from the player
|
||||
inline void setPlayerLastHeard( int who, UnsignedInt lastHeard )
|
||||
{
|
||||
DEBUG_LOG(("LANGameInfo::setPlayerLastHeard - changing player %d last heard from %d to %d\n", who, getPlayerLastHeard(who), lastHeard));
|
||||
if (m_LANSlot[who].isHuman())
|
||||
m_LANSlot[who].setLastHeard(lastHeard);
|
||||
}
|
||||
|
||||
/// Return the hosts IP or 0
|
||||
UnsignedInt getHostIP(void)
|
||||
{
|
||||
if (m_LANSlot[0].isHuman())
|
||||
return m_LANSlot[0].getIP();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LANGameInfo *m_next; ///< Pointer for linked list
|
||||
UnsignedInt m_lastHeard; ///< The last time we heard from this game (for timeout purposes)
|
||||
UnicodeString m_gameName; ///< Game name. @todo: are game names based off of host player names?
|
||||
Bool m_isDirectConnect; ///< Is this game a direct connect game, or a LAN game?
|
||||
};
|
||||
|
||||
void LANDisplayGameList( GameWindow *gameListbox, LANGameInfo *gameList ); ///< Displays the list of games in a listbox, preserving selections
|
||||
void LANEnableStartButton(Bool enabled);
|
||||
|
||||
void LANDisplaySlotList( void ); ///< Displays the slot list according to TheLANGameInfo
|
||||
void LANDisplayGameOptions( void ); ///< Displays the game options according to TheLANGameInfo
|
||||
|
||||
AsciiString GenerateGameOptionsString( void );
|
||||
Bool ParseGameOptionsString(LANGameInfo *game, AsciiString options);
|
||||
|
||||
|
||||
#endif // __LANGAMEINFO_H__
|
69
Generals/Code/GameEngine/Include/GameNetwork/LANPlayer.h
Normal file
69
Generals/Code/GameEngine/Include/GameNetwork/LANPlayer.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// LANPlayer.h ///////////////////////////////////////////////////////////////
|
||||
// LAN Player Class used for both the LANAPI and LANGameInfo
|
||||
// Author: Matthew D. Campbell, October 2001 (Pulled out of LANAPI.h by CLH on 12/21/01
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _LANPLAYER_H_
|
||||
#define _LANPLAYER_H_
|
||||
|
||||
|
||||
/**
|
||||
* LAN player class. This is for players sitting in the lobby. Players are
|
||||
* uniquely identified by their IP addresses.
|
||||
*/
|
||||
class LANPlayer
|
||||
{
|
||||
public:
|
||||
LANPlayer() { m_name = m_login = m_host = L""; m_lastHeard = 0; m_next = NULL; m_IP = 0; }
|
||||
|
||||
// Access functions
|
||||
inline UnicodeString getName( void ) { return m_name; }
|
||||
inline void setName( UnicodeString name ) { m_name = name; }
|
||||
inline UnicodeString getLogin( void ) { return m_login; }
|
||||
inline void setLogin( UnicodeString name ) { m_login = name; }
|
||||
inline void setLogin( AsciiString name ) { m_login.translate(name); }
|
||||
inline UnicodeString getHost( void ) { return m_host; }
|
||||
inline void setHost( UnicodeString name ) { m_host = name; }
|
||||
inline void setHost( AsciiString name ) { m_host.translate(name); }
|
||||
inline UnsignedInt getLastHeard( void ) { return m_lastHeard; }
|
||||
inline void setLastHeard( UnsignedInt lastHeard ) { m_lastHeard = lastHeard; }
|
||||
inline LANPlayer *getNext( void ) { return m_next; }
|
||||
inline void setNext( LANPlayer *next ) { m_next = next; }
|
||||
inline UnsignedInt getIP( void ) { return m_IP; }
|
||||
inline void setIP( UnsignedInt IP ) { m_IP = IP; }
|
||||
|
||||
protected:
|
||||
UnicodeString m_name; ///< Player name
|
||||
UnicodeString m_login; ///< login name
|
||||
UnicodeString m_host; ///< machine name
|
||||
UnsignedInt m_lastHeard; ///< The last time we heard from this player (for timeout purposes)
|
||||
LANPlayer *m_next; ///< Linked list pointer
|
||||
UnsignedInt m_IP; ///< Player's IP
|
||||
};
|
||||
|
||||
#endif //_LANPLAYER_H_
|
162
Generals/Code/GameEngine/Include/GameNetwork/NAT.h
Normal file
162
Generals/Code/GameEngine/Include/GameNetwork/NAT.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: NAT.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Bryan Cleveland April 2002
|
||||
// Desc: Resolves NAT'd IPs and port numbers for the other players in a game.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NAT_H
|
||||
#define __NAT_H
|
||||
|
||||
#include "Lib\BaseType.h"
|
||||
#include "GameNetwork/NetworkInterface.h"
|
||||
#include "GameNetwork/FirewallHelper.h"
|
||||
|
||||
class Transport;
|
||||
class GameSlot;
|
||||
|
||||
enum NATStateType {
|
||||
NATSTATE_IDLE,
|
||||
NATSTATE_DOCONNECTIONPATHS,
|
||||
NATSTATE_WAITFORSTATS,
|
||||
NATSTATE_DONE,
|
||||
NATSTATE_FAILED
|
||||
};
|
||||
|
||||
enum NATConnectionState {
|
||||
NATCONNECTIONSTATE_NOSTATE,
|
||||
NATCONNECTIONSTATE_WAITINGTOBEGIN,
|
||||
// NATCONNECTIONSTATE_NETGEARDELAY,
|
||||
NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE,
|
||||
NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT,
|
||||
NATCONNECTIONSTATE_WAITINGFORRESPONSE,
|
||||
NATCONNECTIONSTATE_DONE,
|
||||
NATCONNECTIONSTATE_FAILED
|
||||
};
|
||||
|
||||
struct ConnectionNodeType {
|
||||
FirewallHelperClass::tFirewallBehaviorType m_behavior; ///< the NAT/Firewall behavior of this node.
|
||||
UnsignedInt m_slotIndex; ///< the player list index of this node.
|
||||
};
|
||||
|
||||
class NAT {
|
||||
public:
|
||||
NAT();
|
||||
virtual ~NAT();
|
||||
|
||||
NATStateType update();
|
||||
|
||||
void attachSlotList(GameSlot **slotList, Int localSlot, UnsignedInt localIP);
|
||||
void establishConnectionPaths();
|
||||
|
||||
Int getSlotPort(Int slot);
|
||||
Transport * getTransport(); ///< return the newly created Transport layer that has all the connections and whatnot.
|
||||
|
||||
// Notification messages from GameSpy
|
||||
void processGlobalMessage(Int slotNum, const char *options);
|
||||
|
||||
protected:
|
||||
NATConnectionState connectionUpdate(); ///< the update function for the connections.
|
||||
void sendMangledSourcePort(); ///< starts the process to get the next mangled source port.
|
||||
void processManglerResponse(UnsignedShort mangledPort);
|
||||
|
||||
Bool allConnectionsDoneThisRound();
|
||||
Bool allConnectionsDone();
|
||||
|
||||
void generatePortNumbers(GameSlot **slotList, Int localSlot); ///< generate all of the slots' port numbers to be used.
|
||||
|
||||
void doThisConnectionRound(); ///< compute who will connect with who for this round.
|
||||
void setConnectionState(Int nodeNumber, NATConnectionState state); ///< central point for changing a connection's state.
|
||||
void sendAProbe(UnsignedInt ip, UnsignedShort port, Int fromNode); ///< send a "PROBE" packet to this IP and port.
|
||||
void notifyTargetOfProbe(GameSlot *targetSlot);
|
||||
void notifyUsersOfConnectionDone(Int nodeIndex);
|
||||
void notifyUsersOfConnectionFailed(Int nodeIndex);
|
||||
void sendMangledPortNumberToTarget(UnsignedShort mangledPort, GameSlot *targetSlot);
|
||||
|
||||
void probed(Int nodeNumber);
|
||||
void gotMangledPort(Int nodeNumber, UnsignedShort mangledPort);
|
||||
void gotInternalAddress(Int nodeNumber, UnsignedInt address);
|
||||
void connectionComplete(Int slotIndex);
|
||||
void connectionFailed(Int slotIndex);
|
||||
|
||||
Transport *m_transport;
|
||||
GameSlot **m_slotList;
|
||||
NATStateType m_NATState;
|
||||
Int m_localNodeNumber; ///< The node number of the local player.
|
||||
Int m_targetNodeNumber; ///< The node number of the player we are connecting to this round.
|
||||
UnsignedInt m_localIP; ///< The IP of the local computer.
|
||||
UnsignedInt m_numNodes; ///< The number of players we have to connect together.
|
||||
UnsignedInt m_connectionRound; ///< The "round" of connections we are currently on.
|
||||
|
||||
Int m_numRetries;
|
||||
Int m_maxNumRetriesAllowed;
|
||||
|
||||
UnsignedShort m_packetID;
|
||||
UnsignedShort m_spareSocketPort;
|
||||
time_t m_manglerRetryTime;
|
||||
Int m_manglerRetries;
|
||||
UnsignedShort m_previousSourcePort;
|
||||
|
||||
Bool m_beenProbed; ///< have I been notified that I've been probed this round?
|
||||
|
||||
UnsignedInt m_manglerAddress;
|
||||
|
||||
time_t m_timeTillNextSend; ///< The number of milliseconds till we send to the other guy's port again.
|
||||
NATConnectionState m_connectionStates[MAX_SLOTS]; ///< connection states for this round for all the nodes.
|
||||
|
||||
ConnectionNodeType m_connectionNodes[MAX_SLOTS]; ///< info regarding the nodes that are being connected.
|
||||
|
||||
UnsignedShort m_sourcePorts[MAX_SLOTS]; ///< the source ports that the other players communicate to us on.
|
||||
|
||||
Bool m_myConnections[MAX_SLOTS]; ///< keeps track of all the nodes I've connected to. For keepalive.
|
||||
time_t m_nextKeepaliveTime; ///< the next time we will send out our keepalive packets.
|
||||
|
||||
static Int m_connectionPairs[MAX_SLOTS-1][MAX_SLOTS-1][MAX_SLOTS];
|
||||
Int m_connectionPairIndex;
|
||||
|
||||
UnsignedShort m_startingPortNumber; ///< the starting port number for this game. The slots all get port numbers with their port numbers based on this number.
|
||||
///< this is done so that games that are played right after each other with the same players in the same
|
||||
///< slot order will not use the old source port allocation scheme in case their NAT
|
||||
///< hasn't timed out that connection.
|
||||
|
||||
time_t m_nextPortSendTime; ///< Last time we sent our mangled port number to our target this round.
|
||||
|
||||
time_t m_timeoutTime; ///< the time at which we will time out waiting for the other player's port number.
|
||||
time_t m_roundTimeout; ///< the time at which we will time out this connection round.
|
||||
|
||||
static Int m_timeBetweenRetries; // 1 second between retries sounds good to me.
|
||||
static time_t m_manglerRetryTimeInterval; // sounds good to me.
|
||||
static Int m_maxAllowedManglerRetries; // works for me.
|
||||
static time_t m_keepaliveInterval; // 15 seconds between keepalive packets seems good.
|
||||
static time_t m_timeToWaitForPort; // wait for ten seconds for the other player's port number.
|
||||
static time_t m_timeForRoundTimeout; // wait for at most ten seconds for each connection round to finish.
|
||||
|
||||
};
|
||||
|
||||
extern NAT *TheNAT;
|
||||
|
||||
#endif // #ifndef __NAT_H
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NETCOMMANDLIST_H
|
||||
#define __NETCOMMANDLIST_H
|
||||
|
||||
#include "Common/GameMemory.h"
|
||||
#include "GameNetwork/NetCommandRef.h"
|
||||
|
||||
/**
|
||||
* The NetCommandList is a ordered linked list of NetCommandRef objects.
|
||||
* The list is ordered based on the command id, player id, and command type.
|
||||
* It is ordered in this way to aid in constructing the packets efficiently.
|
||||
* The list keeps track of the last message inserted in order to accommodate
|
||||
* adding commands in order more efficiently since that is whats going to be
|
||||
* done most of the time. If the new message doesn't go after the last message
|
||||
* inserted, then the list will be traversed linearly until the proper spot is
|
||||
* found. We can get away with this inefficient method since these occurances
|
||||
* will be rare. Also, the list is not expected to ever have more than 30 or so
|
||||
* commands on it at a time. Five commands would probably be a normal amount.
|
||||
*/
|
||||
|
||||
class NetCommandList : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetCommandList, "NetCommandList")
|
||||
public:
|
||||
NetCommandList();
|
||||
//virtual ~NetCommandList();
|
||||
|
||||
void init(); ///< Initialize the list
|
||||
void reset(); ///< Reset the list to the initial state.
|
||||
NetCommandRef * addMessage(NetCommandMsg *cmdMsg); ///< Add message to the list in its properly ordered place.
|
||||
Bool isEqualCommandMsg(NetCommandMsg *msg1, NetCommandMsg *msg2);
|
||||
NetCommandRef * getFirstMessage(); ///< Get the first message on the list.
|
||||
NetCommandRef * findMessage(NetCommandMsg *msg); ///< Find and return a reference to the given message if one exists.
|
||||
NetCommandRef * findMessage(UnsignedShort commandID, UnsignedByte playerID); ///< Find and return a reference to the
|
||||
///< message given the player id and the command id.
|
||||
///< This will only check against messages of types that require
|
||||
///< a command id.
|
||||
void removeMessage(NetCommandRef *msg); ///< Remove the given message from the list.
|
||||
void appendList(NetCommandList *list); ///< Append the given list to the end of this list.
|
||||
Int length(); ///< Returns the number of nodes in this list. This is inefficient and is meant to be a debug tool.
|
||||
|
||||
protected:
|
||||
NetCommandRef *m_first; ///< Head of the list.
|
||||
NetCommandRef *m_last; ///< Tail of the list.
|
||||
NetCommandRef *m_lastMessageInserted; ///< The last message that was inserted to this list.
|
||||
};
|
||||
|
||||
#endif
|
526
Generals/Code/GameEngine/Include/GameNetwork/NetCommandMsg.h
Normal file
526
Generals/Code/GameEngine/Include/GameNetwork/NetCommandMsg.h
Normal file
|
@ -0,0 +1,526 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// The CommandMsg class is a linked-list wrapper around GameMessage objects that
|
||||
// are queued up to execute at a later time
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NETCOMMANDMSG_H
|
||||
#define __NETCOMMANDMSG_H
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "Common/UnicodeString.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetCommandMsg : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetCommandMsg, "NetCommandMsg")
|
||||
public:
|
||||
NetCommandMsg();
|
||||
//virtual ~NetCommandMsg();
|
||||
inline UnsignedInt GetTimestamp() { return m_timestamp; }
|
||||
inline void SetTimestamp(UnsignedInt timestamp) { m_timestamp = timestamp; }
|
||||
inline void setExecutionFrame(UnsignedInt frame) { m_executionFrame = frame; }
|
||||
inline void setPlayerID(UnsignedInt playerID) { m_playerID = playerID; }
|
||||
inline void setID(UnsignedShort id) { m_id = id; }
|
||||
inline UnsignedInt getExecutionFrame() { return m_executionFrame; }
|
||||
inline UnsignedInt getPlayerID() { return m_playerID; }
|
||||
inline UnsignedShort getID() { return m_id; }
|
||||
inline void setNetCommandType(NetCommandType type) { m_commandType = type; }
|
||||
inline NetCommandType getNetCommandType() { return m_commandType; }
|
||||
virtual Int getSortNumber();
|
||||
void attach();
|
||||
void detach();
|
||||
|
||||
// For debugging purposes
|
||||
virtual AsciiString getContentsAsAsciiString(void) { return AsciiString::TheEmptyString; }
|
||||
|
||||
protected:
|
||||
UnsignedInt m_timestamp;
|
||||
UnsignedInt m_executionFrame;
|
||||
UnsignedInt m_playerID;
|
||||
UnsignedShort m_id;
|
||||
|
||||
NetCommandType m_commandType;
|
||||
Int m_referenceCount;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* The NetGameCommandMsg is the NetCommandMsg representation of a GameMessage
|
||||
*/
|
||||
class NetGameCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetGameCommandMsg, "NetGameCommandMsg")
|
||||
public:
|
||||
NetGameCommandMsg();
|
||||
NetGameCommandMsg(GameMessage *msg);
|
||||
//virtual ~NetGameCommandMsg();
|
||||
|
||||
GameMessage *constructGameMessage();
|
||||
void addArgument(const GameMessageArgumentDataType type, GameMessageArgumentType arg);
|
||||
void setGameMessageType(GameMessage::Type type);
|
||||
|
||||
// For debugging purposes
|
||||
virtual AsciiString getContentsAsAsciiString(void);
|
||||
|
||||
protected:
|
||||
Int m_numArgs;
|
||||
Int m_argSize;
|
||||
GameMessage::Type m_type;
|
||||
GameMessageArgument *m_argList, *m_argTail;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* The NetAckBothCommandMsg is the NetCommandMsg representation of the combination of a
|
||||
* stage 1 ack and a stage 2 ack.
|
||||
*/
|
||||
class NetAckBothCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetAckBothCommandMsg, "NetAckBothCommandMsg")
|
||||
public:
|
||||
NetAckBothCommandMsg(NetCommandMsg *msg);
|
||||
NetAckBothCommandMsg();
|
||||
//virtual ~NetAckBothCommandMsg();
|
||||
|
||||
UnsignedShort getCommandID();
|
||||
void setCommandID(UnsignedShort commandID);
|
||||
UnsignedByte getOriginalPlayerID();
|
||||
void setOriginalPlayerID(UnsignedByte originalPlayerID);
|
||||
virtual Int getSortNumber();
|
||||
|
||||
protected:
|
||||
UnsignedShort m_commandID;
|
||||
UnsignedByte m_originalPlayerID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* The NetAckStage1CommandMsg is the NetCommandMsg representation of an ack message for the initial
|
||||
* recipient.
|
||||
*/
|
||||
class NetAckStage1CommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetAckStage1CommandMsg, "NetAckStage1CommandMsg")
|
||||
public:
|
||||
NetAckStage1CommandMsg(NetCommandMsg *msg);
|
||||
NetAckStage1CommandMsg();
|
||||
//virtual ~NetAckStage1CommandMsg();
|
||||
|
||||
UnsignedShort getCommandID();
|
||||
void setCommandID(UnsignedShort commandID);
|
||||
UnsignedByte getOriginalPlayerID();
|
||||
void setOriginalPlayerID(UnsignedByte originalPlayerID);
|
||||
virtual Int getSortNumber();
|
||||
|
||||
protected:
|
||||
UnsignedShort m_commandID;
|
||||
UnsignedByte m_originalPlayerID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* The NetAckStage2CommandMsg is the NetCommandMsg representation of an ack message for all eventual
|
||||
* recipients. (when this is returned, all the players in the relay mask have received the packet)
|
||||
*/
|
||||
class NetAckStage2CommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetAckStage2CommandMsg, "NetAckStage2CommandMsg")
|
||||
public:
|
||||
NetAckStage2CommandMsg(NetCommandMsg *msg);
|
||||
NetAckStage2CommandMsg();
|
||||
//virtual ~NetAckStage2CommandMsg();
|
||||
|
||||
UnsignedShort getCommandID();
|
||||
void setCommandID(UnsignedShort commandID);
|
||||
UnsignedByte getOriginalPlayerID();
|
||||
void setOriginalPlayerID(UnsignedByte originalPlayerID);
|
||||
virtual Int getSortNumber();
|
||||
|
||||
protected:
|
||||
UnsignedShort m_commandID;
|
||||
UnsignedByte m_originalPlayerID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetFrameCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetFrameCommandMsg, "NetFrameCommandMsg")
|
||||
public:
|
||||
NetFrameCommandMsg();
|
||||
//virtual ~NetFrameCommandMsg();
|
||||
|
||||
void setCommandCount(UnsignedShort commandCount);
|
||||
UnsignedShort getCommandCount();
|
||||
|
||||
protected:
|
||||
UnsignedShort m_commandCount;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetPlayerLeaveCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetPlayerLeaveCommandMsg, "NetPlayerLeaveCommandMsg")
|
||||
public:
|
||||
NetPlayerLeaveCommandMsg();
|
||||
//virtual ~NetPlayerLeaveCommandMsg();
|
||||
|
||||
UnsignedByte getLeavingPlayerID();
|
||||
void setLeavingPlayerID(UnsignedByte id);
|
||||
|
||||
protected:
|
||||
UnsignedByte m_leavingPlayerID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetRunAheadMetricsCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetRunAheadMetricsCommandMsg, "NetRunAheadMetricsCommandMsg")
|
||||
public:
|
||||
NetRunAheadMetricsCommandMsg();
|
||||
//virtual ~NetRunAheadMetricsCommandMsg();
|
||||
|
||||
Real getAverageLatency();
|
||||
void setAverageLatency(Real avgLat);
|
||||
Int getAverageFps();
|
||||
void setAverageFps(Int fps);
|
||||
|
||||
protected:
|
||||
Real m_averageLatency;
|
||||
Int m_averageFps;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetRunAheadCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetRunAheadCommandMsg, "NetRunAheadCommandMsg")
|
||||
public:
|
||||
NetRunAheadCommandMsg();
|
||||
//virtual ~NetRunAheadCommandMsg();
|
||||
|
||||
UnsignedShort getRunAhead();
|
||||
void setRunAhead(UnsignedShort runAhead);
|
||||
|
||||
UnsignedByte getFrameRate();
|
||||
void setFrameRate(UnsignedByte frameRate);
|
||||
|
||||
protected:
|
||||
UnsignedShort m_runAhead;
|
||||
UnsignedByte m_frameRate;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDestroyPlayerCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDestroyPlayerCommandMsg, "NetDestroyPlayerCommandMsg")
|
||||
public:
|
||||
NetDestroyPlayerCommandMsg();
|
||||
//virtual ~NetDestroyPlayerCommandMsg();
|
||||
|
||||
UnsignedInt getPlayerIndex();
|
||||
void setPlayerIndex(UnsignedInt playerIndex);
|
||||
|
||||
protected:
|
||||
UnsignedInt m_playerIndex;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetKeepAliveCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetKeepAliveCommandMsg, "NetKeepAliveCommandMsg")
|
||||
public:
|
||||
NetKeepAliveCommandMsg();
|
||||
//virtual ~NetKeepAliveCommandMsg();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDisconnectKeepAliveCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDisconnectKeepAliveCommandMsg, "NetDisconnectKeepAliveCommandMsg")
|
||||
public:
|
||||
NetDisconnectKeepAliveCommandMsg();
|
||||
//virtual ~NetDisconnectKeepAliveCommandMsg();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDisconnectPlayerCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDisconnectPlayerCommandMsg, "NetDisconnectPlayerCommandMsg")
|
||||
public:
|
||||
NetDisconnectPlayerCommandMsg();
|
||||
//virtual ~NetDisconnectPlayerCommandMsg();
|
||||
|
||||
UnsignedByte getDisconnectSlot();
|
||||
void setDisconnectSlot(UnsignedByte slot);
|
||||
|
||||
UnsignedInt getDisconnectFrame();
|
||||
void setDisconnectFrame(UnsignedInt frame);
|
||||
|
||||
protected:
|
||||
UnsignedByte m_disconnectSlot;
|
||||
UnsignedInt m_disconnectFrame;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetPacketRouterQueryCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetPacketRouterQueryCommandMsg, "NetPacketRouterQueryCommandMsg")
|
||||
public:
|
||||
NetPacketRouterQueryCommandMsg();
|
||||
//virtual ~NetPacketRouterQueryCommandMsg();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetPacketRouterAckCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetPacketRouterAckCommandMsg, "NetPacketRouterAckCommandMsg")
|
||||
public:
|
||||
NetPacketRouterAckCommandMsg();
|
||||
//virtual ~NetPacketRouterAckCommandMsg();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDisconnectChatCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDisconnectChatCommandMsg, "NetDisconnectChatCommandMsg")
|
||||
public:
|
||||
NetDisconnectChatCommandMsg();
|
||||
//virtual ~NetDisconnectChatCommandMsg();
|
||||
|
||||
UnicodeString getText();
|
||||
void setText(UnicodeString text);
|
||||
|
||||
protected:
|
||||
UnicodeString m_text;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetChatCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetChatCommandMsg, "NetChatCommandMsg")
|
||||
public:
|
||||
NetChatCommandMsg();
|
||||
//virtual ~NetChatCommandMsg();
|
||||
|
||||
UnicodeString getText();
|
||||
void setText(UnicodeString text);
|
||||
|
||||
Int getPlayerMask( void );
|
||||
void setPlayerMask( Int playerMask );
|
||||
|
||||
protected:
|
||||
UnicodeString m_text;
|
||||
Int m_playerMask;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDisconnectVoteCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDisconnectVoteCommandMsg, "NetDisconnectVoteCommandMsg")
|
||||
public:
|
||||
NetDisconnectVoteCommandMsg();
|
||||
//virtual ~NetDisconnectVoteCommandMsg();
|
||||
|
||||
UnsignedByte getSlot();
|
||||
void setSlot(UnsignedByte slot);
|
||||
|
||||
UnsignedInt getVoteFrame();
|
||||
void setVoteFrame(UnsignedInt voteFrame);
|
||||
|
||||
protected:
|
||||
UnsignedByte m_slot;
|
||||
UnsignedInt m_voteFrame;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetProgressCommandMsg: public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetProgressCommandMsg, "NetProgressCommandMsg")
|
||||
public:
|
||||
NetProgressCommandMsg( void );
|
||||
//virtual ~NetProgressCommandMsg( void );
|
||||
|
||||
UnsignedByte getPercentage();
|
||||
void setPercentage( UnsignedByte percent );
|
||||
protected:
|
||||
UnsignedByte m_percent;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetWrapperCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetWrapperCommandMsg, "NetWrapperCommandMsg")
|
||||
public:
|
||||
NetWrapperCommandMsg( void );
|
||||
//virtual ~NetWrapperCommandMsg();
|
||||
|
||||
UnsignedByte * getData();
|
||||
void setData(UnsignedByte *data, UnsignedInt dataLength);
|
||||
|
||||
UnsignedInt getChunkNumber();
|
||||
void setChunkNumber(UnsignedInt chunkNumber);
|
||||
|
||||
UnsignedInt getNumChunks();
|
||||
void setNumChunks(UnsignedInt numChunks);
|
||||
|
||||
UnsignedInt getDataLength();
|
||||
|
||||
UnsignedInt getTotalDataLength();
|
||||
void setTotalDataLength(UnsignedInt totalDataLength);
|
||||
|
||||
UnsignedInt getDataOffset();
|
||||
void setDataOffset(UnsignedInt offset);
|
||||
|
||||
UnsignedShort getWrappedCommandID();
|
||||
void setWrappedCommandID(UnsignedShort wrappedCommandID);
|
||||
|
||||
private:
|
||||
UnsignedByte *m_data;
|
||||
// using UnsignedInt's so we can send around files of effectively unlimited size easily
|
||||
UnsignedInt m_dataLength;
|
||||
UnsignedInt m_dataOffset;
|
||||
UnsignedInt m_totalDataLength;
|
||||
UnsignedInt m_chunkNumber;
|
||||
UnsignedInt m_numChunks;
|
||||
UnsignedShort m_wrappedCommandID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetFileCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetFileCommandMsg, "NetFileCommandMsg")
|
||||
public:
|
||||
NetFileCommandMsg();
|
||||
//virtual ~NetFileCommandMsg();
|
||||
|
||||
AsciiString getRealFilename();
|
||||
void setRealFilename(AsciiString filename);
|
||||
|
||||
AsciiString getPortableFilename() { return m_portableFilename; }
|
||||
void setPortableFilename(AsciiString filename) { m_portableFilename = filename; }
|
||||
|
||||
UnsignedInt getFileLength();
|
||||
|
||||
UnsignedByte * getFileData();
|
||||
void setFileData(UnsignedByte *data, UnsignedInt dataLength);
|
||||
|
||||
protected:
|
||||
AsciiString m_portableFilename;
|
||||
|
||||
UnsignedByte *m_data;
|
||||
UnsignedInt m_dataLength;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetFileAnnounceCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetFileAnnounceCommandMsg, "NetFileAnnounceCommandMsg")
|
||||
public:
|
||||
NetFileAnnounceCommandMsg();
|
||||
//virtual ~NetFileAnnounceCommandMsg();
|
||||
|
||||
AsciiString getRealFilename();
|
||||
void setRealFilename(AsciiString filename);
|
||||
|
||||
AsciiString getPortableFilename() { return m_portableFilename; }
|
||||
void setPortableFilename(AsciiString filename) { m_portableFilename = filename; }
|
||||
|
||||
UnsignedShort getFileID();
|
||||
void setFileID(UnsignedShort fileID);
|
||||
|
||||
UnsignedByte getPlayerMask(void);
|
||||
void setPlayerMask(UnsignedByte playerMask);
|
||||
|
||||
protected:
|
||||
AsciiString m_portableFilename;
|
||||
UnsignedShort m_fileID;
|
||||
UnsignedByte m_playerMask;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetFileProgressCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetFileProgressCommandMsg, "NetFileProgressCommandMsg")
|
||||
public:
|
||||
NetFileProgressCommandMsg();
|
||||
//virtual ~NetFileProgressCommandMsg();
|
||||
|
||||
UnsignedShort getFileID();
|
||||
void setFileID(UnsignedShort val);
|
||||
|
||||
Int getProgress();
|
||||
void setProgress(Int val);
|
||||
|
||||
protected:
|
||||
UnsignedShort m_fileID;
|
||||
Int m_progress;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDisconnectFrameCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDisconnectFrameCommandMsg, "NetDisconnectFrameCommandMsg")
|
||||
public:
|
||||
NetDisconnectFrameCommandMsg();
|
||||
|
||||
UnsignedInt getDisconnectFrame();
|
||||
void setDisconnectFrame(UnsignedInt disconnectFrame);
|
||||
|
||||
protected:
|
||||
UnsignedInt m_disconnectFrame;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetDisconnectScreenOffCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetDisconnectScreenOffCommandMsg, "NetDisconnectScreenOffCommandMsg")
|
||||
public:
|
||||
NetDisconnectScreenOffCommandMsg();
|
||||
|
||||
UnsignedInt getNewFrame();
|
||||
void setNewFrame(UnsignedInt newFrame);
|
||||
|
||||
protected:
|
||||
UnsignedInt m_newFrame;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class NetFrameResendRequestCommandMsg : public NetCommandMsg
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetFrameResendRequestCommandMsg, "NetFrameResendRequestCommandMsg")
|
||||
public:
|
||||
NetFrameResendRequestCommandMsg();
|
||||
|
||||
UnsignedInt getFrameToResend();
|
||||
void setFrameToResend(UnsignedInt frame);
|
||||
|
||||
protected:
|
||||
UnsignedInt m_frameToResend;
|
||||
};
|
||||
#endif
|
152
Generals/Code/GameEngine/Include/GameNetwork/NetCommandRef.h
Normal file
152
Generals/Code/GameEngine/Include/GameNetwork/NetCommandRef.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NETCOMMANDREF_H
|
||||
#define __NETCOMMANDREF_H
|
||||
|
||||
#include "GameNetwork/NetCommandMsg.h"
|
||||
#include "Common/GameMemory.h"
|
||||
|
||||
#if defined(_INTERNAL) || defined(_DEBUG)
|
||||
// #define DEBUG_NETCOMMANDREF
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_NETCOMMANDREF
|
||||
#define NEW_NETCOMMANDREF(msg) newInstance(NetCommandRef)(msg, __FILE__, __LINE__)
|
||||
#else
|
||||
#define NEW_NETCOMMANDREF(msg) newInstance(NetCommandRef)(msg)
|
||||
#endif
|
||||
|
||||
|
||||
class NetCommandRef : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetCommandRef, "NetCommandRef")
|
||||
public:
|
||||
#ifdef DEBUG_NETCOMMANDREF
|
||||
NetCommandRef(NetCommandMsg *msg, char *filename, int line);
|
||||
#else
|
||||
NetCommandRef(NetCommandMsg *msg);
|
||||
#endif
|
||||
//~NetCommandRef();
|
||||
|
||||
NetCommandMsg *getCommand();
|
||||
NetCommandRef *getNext();
|
||||
NetCommandRef *getPrev();
|
||||
void setNext(NetCommandRef *next);
|
||||
void setPrev(NetCommandRef *prev);
|
||||
|
||||
void setRelay(UnsignedByte relay);
|
||||
UnsignedByte getRelay() const;
|
||||
|
||||
time_t getTimeLastSent() const;
|
||||
void setTimeLastSent(time_t timeLastSent);
|
||||
|
||||
protected:
|
||||
NetCommandMsg *m_msg;
|
||||
NetCommandRef *m_next;
|
||||
NetCommandRef *m_prev;
|
||||
UnsignedByte m_relay; ///< Need this in the command reference since the relay value will be different depending on where this particular reference is being sent.
|
||||
time_t m_timeLastSent;
|
||||
|
||||
#ifdef DEBUG_NETCOMMANDREF
|
||||
UnsignedInt m_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the command message.
|
||||
*/
|
||||
inline NetCommandMsg * NetCommandRef::getCommand()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next command ref in the list.
|
||||
*/
|
||||
inline NetCommandRef * NetCommandRef::getNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the previous command ref in the list.
|
||||
*/
|
||||
inline NetCommandRef * NetCommandRef::getPrev()
|
||||
{
|
||||
return m_prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the next command ref in the list.
|
||||
*/
|
||||
inline void NetCommandRef::setNext(NetCommandRef *next)
|
||||
{
|
||||
m_next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the previous command ref in the list.
|
||||
*/
|
||||
inline void NetCommandRef::setPrev(NetCommandRef *prev)
|
||||
{
|
||||
m_prev = prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time for the last time this command was sent from this reference.
|
||||
*/
|
||||
inline time_t NetCommandRef::getTimeLastSent() const
|
||||
{
|
||||
return m_timeLastSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time for the last time this command was sent from this reference.
|
||||
*/
|
||||
inline void NetCommandRef::setTimeLastSent(time_t timeLastSent)
|
||||
{
|
||||
m_timeLastSent = timeLastSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the send relay for this reference of the command.
|
||||
*/
|
||||
inline void NetCommandRef::setRelay(UnsignedByte relay)
|
||||
{
|
||||
m_relay = relay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the send relay for this refreence of the command.
|
||||
*/
|
||||
inline UnsignedByte NetCommandRef::getRelay() const
|
||||
{
|
||||
return m_relay;
|
||||
}
|
||||
|
||||
#endif // #ifndef __NETCOMMANDREF_H
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////// NetCommandWrapperList.h ////////////////////////////////
|
||||
// Bryan Cleveland
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NETCOMMANDWRAPPERLIST_H
|
||||
#define __NETCOMMANDWRAPPERLIST_H
|
||||
|
||||
#include "GameNetwork/NetCommandList.h"
|
||||
|
||||
class NetCommandWrapperListNode : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetCommandWrapperListNode, "NetCommandWrapperListNode")
|
||||
public:
|
||||
NetCommandWrapperListNode(NetWrapperCommandMsg *msg);
|
||||
//virtual ~NetCommandWrapperListNode();
|
||||
|
||||
Bool isComplete();
|
||||
UnsignedShort getCommandID();
|
||||
UnsignedInt getRawDataLength();
|
||||
void copyChunkData(NetWrapperCommandMsg *msg);
|
||||
UnsignedByte * getRawData();
|
||||
|
||||
Int getPercentComplete(void);
|
||||
|
||||
NetCommandWrapperListNode *m_next;
|
||||
|
||||
protected:
|
||||
UnsignedShort m_commandID;
|
||||
UnsignedByte *m_data;
|
||||
UnsignedInt m_dataLength;
|
||||
Bool *m_chunksPresent;
|
||||
UnsignedInt m_numChunks;
|
||||
UnsignedInt m_numChunksPresent;
|
||||
|
||||
};
|
||||
|
||||
class NetCommandWrapperList : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetCommandWrapperList, "NetCommandWrapperList")
|
||||
public:
|
||||
NetCommandWrapperList();
|
||||
//virtual ~NetCommandWrapperList();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
|
||||
void processWrapper(NetCommandRef *ref);
|
||||
NetCommandList * getReadyCommands();
|
||||
|
||||
Int getPercentComplete(UnsignedShort wrappedCommandID);
|
||||
|
||||
protected:
|
||||
void removeFromList(NetCommandWrapperListNode *node);
|
||||
|
||||
NetCommandWrapperListNode *m_list;
|
||||
};
|
||||
|
||||
#endif
|
240
Generals/Code/GameEngine/Include/GameNetwork/NetPacket.h
Normal file
240
Generals/Code/GameEngine/Include/GameNetwork/NetPacket.h
Normal file
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
Ok, how this should have been done is to make each of the command types
|
||||
have a bitmask telling which command message header information
|
||||
each command type required. That would make finding out the size of
|
||||
a particular command easier to find, without so much repetitious code.
|
||||
We would still need to have a separate function for each command type
|
||||
for the data, but at least that wouldn't be repeating code, that would
|
||||
be specialized code.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NETPACKET_H
|
||||
#define __NETPACKET_H
|
||||
|
||||
#include "NetworkDefs.h"
|
||||
#include "GameNetwork/NetCommandList.h"
|
||||
#include "Common/MessageStream.h"
|
||||
#include "Common/GameMemory.h"
|
||||
|
||||
class NetPacket;
|
||||
|
||||
typedef std::list<NetPacket *> NetPacketList;
|
||||
typedef std::list<NetPacket *>::iterator NetPacketListIter;
|
||||
|
||||
class NetPacket : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetPacket, "NetPacket")
|
||||
public:
|
||||
NetPacket();
|
||||
NetPacket(TransportMessage *msg);
|
||||
//virtual ~NetPacket();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void setAddress(Int addr, Int port);
|
||||
Bool addCommand(NetCommandRef *msg);
|
||||
Int getNumCommands();
|
||||
|
||||
NetCommandList *getCommandList();
|
||||
|
||||
static NetCommandRef * ConstructNetCommandMsgFromRawData(UnsignedByte *data, UnsignedShort dataLength);
|
||||
static NetPacketList ConstructBigCommandPacketList(NetCommandRef *ref);
|
||||
|
||||
UnsignedByte *getData();
|
||||
Int getLength();
|
||||
UnsignedInt getAddr();
|
||||
UnsignedShort getPort();
|
||||
|
||||
protected:
|
||||
static UnsignedInt GetBufferSizeNeededForCommand(NetCommandMsg *msg);
|
||||
static void FillBufferWithCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
|
||||
// These functions return the size of the command without any compression, repetition, etc.
|
||||
// i.e. All of the required fields are taken into account when returning the size.
|
||||
static UnsignedInt GetGameCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetAckCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetFrameCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetPlayerLeaveCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetRunAheadMetricsCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetRunAheadCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDestroyPlayerCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetKeepAliveCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDisconnectKeepAliveCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDisconnectPlayerCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetPacketRouterQueryCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetPacketRouterAckCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDisconnectChatCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDisconnectVoteCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetChatCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetProgressMessageSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetLoadCompleteMessageSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetTimeOutGameStartMessageSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetWrapperCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetFileCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetFileAnnounceCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetFileProgressCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDisconnectFrameCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetDisconnectScreenOffCommandSize(NetCommandMsg *msg);
|
||||
static UnsignedInt GetFrameResendRequestCommandSize(NetCommandMsg *msg);
|
||||
|
||||
static void FillBufferWithGameCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithAckCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithFrameCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithPlayerLeaveCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithRunAheadMetricsCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithRunAheadCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDestroyPlayerCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithKeepAliveCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDisconnectKeepAliveCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDisconnectPlayerCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithPacketRouterQueryCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithPacketRouterAckCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDisconnectChatCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDisconnectVoteCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithChatCommand(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithProgressMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithLoadCompleteMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithTimeOutGameStartMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithFileMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithFileProgressMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithFileAnnounceMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDisconnectFrameMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithDisconnectScreenOffMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
static void FillBufferWithFrameResendRequestMessage(UnsignedByte *buffer, NetCommandRef *msg);
|
||||
|
||||
Bool addFrameCommand(NetCommandRef *msg);
|
||||
Bool isRoomForFrameMessage(NetCommandRef *msg);
|
||||
Bool addAckCommand(NetCommandRef *msg, UnsignedShort commandID, UnsignedByte originalPlayerID);
|
||||
Bool addAckStage1Command(NetCommandRef *msg);
|
||||
Bool addAckStage2Command(NetCommandRef *msg);
|
||||
Bool addAckBothCommand(NetCommandRef *msg);
|
||||
Bool isRoomForAckMessage(NetCommandRef *msg);
|
||||
Bool addGameCommand(NetCommandRef *msg);
|
||||
Bool isRoomForGameMessage(NetCommandRef *msg, GameMessage *gmsg);
|
||||
Bool addPlayerLeaveCommand(NetCommandRef *msg);
|
||||
Bool isRoomForPlayerLeaveMessage(NetCommandRef *msg);
|
||||
Bool addRunAheadMetricsCommand(NetCommandRef *msg);
|
||||
Bool isRoomForRunAheadMetricsMessage(NetCommandRef *msg);
|
||||
Bool addRunAheadCommand(NetCommandRef *msg);
|
||||
Bool isRoomForRunAheadMessage(NetCommandRef *msg);
|
||||
Bool addDestroyPlayerCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDestroyPlayerMessage(NetCommandRef *msg);
|
||||
Bool addKeepAliveCommand(NetCommandRef *msg);
|
||||
Bool isRoomForKeepAliveMessage(NetCommandRef *msg);
|
||||
Bool addDisconnectKeepAliveCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDisconnectKeepAliveMessage(NetCommandRef *msg);
|
||||
Bool addDisconnectPlayerCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDisconnectPlayerMessage(NetCommandRef *msg);
|
||||
Bool addPacketRouterQueryCommand(NetCommandRef *msg);
|
||||
Bool isRoomForPacketRouterQueryMessage(NetCommandRef *msg);
|
||||
Bool addPacketRouterAckCommand(NetCommandRef *msg);
|
||||
Bool isRoomForPacketRouterAckMessage(NetCommandRef *msg);
|
||||
Bool addDisconnectChatCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDisconnectChatMessage(NetCommandRef *msg);
|
||||
Bool addChatCommand(NetCommandRef *msg);
|
||||
Bool isRoomForChatMessage(NetCommandRef *msg);
|
||||
Bool addDisconnectVoteCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDisconnectVoteMessage(NetCommandRef *msg);
|
||||
Bool addProgressMessage( NetCommandRef *msg );
|
||||
Bool isRoomForProgressMessage( NetCommandRef *msg );
|
||||
Bool addLoadCompleteMessage( NetCommandRef *msg );
|
||||
Bool isRoomForLoadCompleteMessage( NetCommandRef *msg );
|
||||
Bool addTimeOutGameStartMessage( NetCommandRef *msg );
|
||||
Bool isRoomForTimeOutGameStartMessage( NetCommandRef *msg );
|
||||
Bool addWrapperCommand(NetCommandRef *msg);
|
||||
Bool isRoomForWrapperMessage(NetCommandRef *msg);
|
||||
Bool addFileCommand(NetCommandRef *msg);
|
||||
Bool isRoomForFileMessage(NetCommandRef *msg);
|
||||
Bool addFileAnnounceCommand(NetCommandRef *msg);
|
||||
Bool isRoomForFileAnnounceMessage(NetCommandRef *msg);
|
||||
Bool addFileProgressCommand(NetCommandRef *msg);
|
||||
Bool isRoomForFileProgressMessage(NetCommandRef *msg);
|
||||
Bool addDisconnectFrameCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDisconnectFrameMessage(NetCommandRef *msg);
|
||||
Bool addDisconnectScreenOffCommand(NetCommandRef *msg);
|
||||
Bool isRoomForDisconnectScreenOffMessage(NetCommandRef *msg);
|
||||
Bool addFrameResendRequestCommand(NetCommandRef *msg);
|
||||
Bool isRoomForFrameResendRequestMessage(NetCommandRef *msg);
|
||||
|
||||
Bool isAckRepeat(NetCommandRef *msg);
|
||||
Bool isAckBothRepeat(NetCommandRef *msg);
|
||||
Bool isAckStage1Repeat(NetCommandRef *msg);
|
||||
Bool isAckStage2Repeat(NetCommandRef *msg);
|
||||
Bool isFrameRepeat(NetCommandRef *msg);
|
||||
|
||||
static NetCommandMsg * readGameMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readAckBothMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readAckStage1Message(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readAckStage2Message(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readFrameMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readPlayerLeaveMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readRunAheadMetricsMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readRunAheadMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDestroyPlayerMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readKeepAliveMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDisconnectKeepAliveMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDisconnectPlayerMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readPacketRouterQueryMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readPacketRouterAckMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDisconnectChatMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDisconnectVoteMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readChatMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readProgressMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readLoadCompleteMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readTimeOutGameStartMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readWrapperMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readFileMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readFileAnnounceMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readFileProgressMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDisconnectFrameMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readDisconnectScreenOffMessage(UnsignedByte *data, Int &i);
|
||||
static NetCommandMsg * readFrameResendRequestMessage(UnsignedByte *data, Int &i);
|
||||
|
||||
void writeGameMessageArgumentToPacket(GameMessageArgumentDataType type, GameMessageArgumentType arg);
|
||||
static void readGameMessageArgumentFromPacket(GameMessageArgumentDataType type, NetGameCommandMsg *msg, UnsignedByte *data, Int &i);
|
||||
|
||||
void dumpPacketToLog();
|
||||
|
||||
protected:
|
||||
UnsignedByte m_packet[MAX_PACKET_SIZE];
|
||||
Int m_packetLen;
|
||||
UnsignedInt m_addr;
|
||||
Int m_numCommands;
|
||||
NetCommandRef* m_lastCommand;
|
||||
UnsignedInt m_lastFrame;
|
||||
UnsignedShort m_port;
|
||||
UnsignedShort m_lastCommandID;
|
||||
UnsignedByte m_lastPlayerID;
|
||||
UnsignedByte m_lastCommandType;
|
||||
UnsignedByte m_lastRelay;
|
||||
};
|
||||
|
||||
#endif // __NETPACKET_H
|
216
Generals/Code/GameEngine/Include/GameNetwork/NetworkDefs.h
Normal file
216
Generals/Code/GameEngine/Include/GameNetwork/NetworkDefs.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __NETWORKDEFS_H
|
||||
#define __NETWORKDEFS_H
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
#include "Common/MessageStream.h"
|
||||
|
||||
static const Int WOL_NAME_LEN = 64;
|
||||
|
||||
/// Max number of commands per frame
|
||||
static const Int MAX_COMMANDS = 256;
|
||||
|
||||
extern Int MAX_FRAMES_AHEAD;
|
||||
extern Int MIN_RUNAHEAD;
|
||||
|
||||
// FRAME_DATA_LENGTH needs to be MAX_FRAMES_AHEAD+1 because a player on a different
|
||||
// computer can send commands for a frame that is one beyond twice the max runahead.
|
||||
extern Int FRAME_DATA_LENGTH;
|
||||
extern Int FRAMES_TO_KEEP;
|
||||
|
||||
// This is the connection numbering: 1-8 are for players, 9 is a broadcast con.
|
||||
enum ConnectionNumbers
|
||||
{
|
||||
MAX_PLAYER = 7, // The index of the highest possible player number. This is 0 based, so the most players allowed in a game is MAX_PLAYER+1.
|
||||
NUM_CONNECTIONS
|
||||
};
|
||||
|
||||
static const Int MAX_SLOTS = MAX_PLAYER+1;
|
||||
|
||||
// UDP (8 bytes) + IP header (28 bytes) = 36 bytes total. We want a total packet size of 512, so 512 - 36 = 476
|
||||
static const Int MAX_PACKET_SIZE = 476;
|
||||
|
||||
/**
|
||||
* Command packet - contains frame #, total # of commands, and each command. This is what gets sent
|
||||
* to each player every frame
|
||||
*/
|
||||
#define MAX_MESSAGE_LEN 1024
|
||||
#define MAX_MESSAGES 128
|
||||
static const Int numCommandsPerCommandPacket = (MAX_MESSAGE_LEN - sizeof(UnsignedInt) - sizeof(UnsignedShort))/sizeof(GameMessage);
|
||||
#pragma pack(push, 1)
|
||||
struct CommandPacket
|
||||
{
|
||||
UnsignedInt m_frame;
|
||||
UnsignedShort m_numCommands;
|
||||
unsigned char m_commands[numCommandsPerCommandPacket * sizeof(GameMessage)];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#define MAX_TRANSPORT_STATISTICS_SECONDS 30
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TransportMessageHeader
|
||||
{
|
||||
UnsignedInt crc; ///< packet-level CRC (must be first in packet)
|
||||
UnsignedShort magic; ///< Magic number identifying Generals packets
|
||||
// Int id;
|
||||
// NetMessageFlags flags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/**
|
||||
* Transport message - encapsulating info kept by the transport layer about each
|
||||
* packet. These structs make up the in/out buffers at the transport layer.
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
struct TransportMessage
|
||||
{
|
||||
TransportMessageHeader header;
|
||||
UnsignedByte data[MAX_MESSAGE_LEN];
|
||||
Int length;
|
||||
UnsignedInt addr;
|
||||
UnsignedShort port;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
#pragma pack(push, 1)
|
||||
struct DelayedTransportMessage
|
||||
{
|
||||
UnsignedInt deliveryTime;
|
||||
TransportMessage message;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Message types
|
||||
*/
|
||||
enum NetMessageFlag {
|
||||
MSG_ACK = 1,
|
||||
MSG_NEEDACK = 2,
|
||||
MSG_SEQUENCED = 4,
|
||||
MSG_SUPERCEDING = 8
|
||||
};
|
||||
typedef UnsignedByte NetMessageFlags;
|
||||
|
||||
enum NetCommandType {
|
||||
NETCOMMANDTYPE_UNKNOWN = -1,
|
||||
NETCOMMANDTYPE_ACKBOTH = 0,
|
||||
NETCOMMANDTYPE_ACKSTAGE1,
|
||||
NETCOMMANDTYPE_ACKSTAGE2,
|
||||
NETCOMMANDTYPE_FRAMEINFO,
|
||||
NETCOMMANDTYPE_GAMECOMMAND,
|
||||
NETCOMMANDTYPE_PLAYERLEAVE,
|
||||
NETCOMMANDTYPE_RUNAHEADMETRICS,
|
||||
NETCOMMANDTYPE_RUNAHEAD,
|
||||
NETCOMMANDTYPE_DESTROYPLAYER,
|
||||
NETCOMMANDTYPE_KEEPALIVE,
|
||||
NETCOMMANDTYPE_DISCONNECTCHAT,
|
||||
NETCOMMANDTYPE_CHAT,
|
||||
NETCOMMANDTYPE_MANGLERQUERY,
|
||||
NETCOMMANDTYPE_MANGLERRESPONSE,
|
||||
NETCOMMANDTYPE_PROGRESS,
|
||||
NETCOMMANDTYPE_LOADCOMPLETE,
|
||||
NETCOMMANDTYPE_TIMEOUTSTART,
|
||||
NETCOMMANDTYPE_WRAPPER, // A wrapper command that holds a command thats too big to fit in a single packet.
|
||||
NETCOMMANDTYPE_FILE,
|
||||
NETCOMMANDTYPE_FILEANNOUNCE,
|
||||
NETCOMMANDTYPE_FILEPROGRESS,
|
||||
NETCOMMANDTYPE_FRAMERESENDREQUEST,
|
||||
|
||||
// Disconnect menu command section.
|
||||
NETCOMMANDTYPE_DISCONNECTSTART,
|
||||
NETCOMMANDTYPE_DISCONNECTKEEPALIVE,
|
||||
NETCOMMANDTYPE_DISCONNECTPLAYER,
|
||||
NETCOMMANDTYPE_PACKETROUTERQUERY,
|
||||
NETCOMMANDTYPE_PACKETROUTERACK,
|
||||
NETCOMMANDTYPE_DISCONNECTVOTE,
|
||||
NETCOMMANDTYPE_DISCONNECTFRAME,
|
||||
NETCOMMANDTYPE_DISCONNECTSCREENOFF,
|
||||
NETCOMMANDTYPE_DISCONNECTEND,
|
||||
|
||||
NETCOMMANDTYPE_MAX
|
||||
};
|
||||
|
||||
enum NetLocalStatus {
|
||||
NETLOCALSTATUS_PREGAME = 0,
|
||||
NETLOCALSTATUS_INGAME,
|
||||
NETLOCALSTATUS_LEAVING,
|
||||
NETLOCALSTATUS_LEFT,
|
||||
NETLOCALSTATUS_POSTGAME
|
||||
};
|
||||
|
||||
enum PlayerLeaveCode {
|
||||
PLAYERLEAVECODE_CLIENT = 0,
|
||||
PLAYERLEAVECODE_LOCAL,
|
||||
PLAYERLEAVECODE_PACKETROUTER,
|
||||
PLAYERLEAVECODE_UNKNOWN
|
||||
};
|
||||
|
||||
// Magic number for identifying a Generals packet.
|
||||
static const UnsignedShort GENERALS_MAGIC_NUMBER = 0xF00D;
|
||||
|
||||
// The number of fps history entries.
|
||||
//static const Int NETWORK_FPS_HISTORY_LENGTH = 30;
|
||||
|
||||
// The number of ping history entries.
|
||||
//static const Int NETWORK_LATENCY_HISTORY_LENGTH = 200;
|
||||
|
||||
// The number of miliseconds between run ahead metrics things
|
||||
//static const Int NETWORK_RUN_AHEAD_METRICS_TIME = 5000;
|
||||
|
||||
// The number of cushion values to keep.
|
||||
//static const Int NETWORK_CUSHION_HISTORY_LENGTH = 10;
|
||||
|
||||
// The amount of slack in the run ahead value. This is the percentage of the calculated run ahead that is added.
|
||||
//static const Int NETWORK_RUN_AHEAD_SLACK = 20;
|
||||
|
||||
// The number of seconds between when the connections to each player send a keep-alive packet.
|
||||
// This should be less than 30 just to keep firewall ports open.
|
||||
//static const Int NETWORK_KEEPALIVE_DELAY = 20;
|
||||
|
||||
// The number of milliseconds between when the game gets stuck on a frame for a network stall and
|
||||
// and when the disconnect dialog comes up.
|
||||
//static const Int NETWORK_DISCONNECT_TIME = 5000;
|
||||
|
||||
// The number of miliseconds between when a player's last disconnect keep alive command
|
||||
// was recieved and when they are considered disconnected from the game.
|
||||
//static const Int NETWORK_PLAYER_TIMEOUT_TIME = 60000;
|
||||
|
||||
// The base port number used for the transport socket. A players slot number is added to this
|
||||
// value to get their actual port number.
|
||||
static const Int NETWORK_BASE_PORT_NUMBER = 8088;
|
||||
|
||||
// the singleton
|
||||
class NetworkInterface;
|
||||
extern NetworkInterface *TheNetwork;
|
||||
|
||||
|
||||
#endif
|
140
Generals/Code/GameEngine/Include/GameNetwork/NetworkInterface.h
Normal file
140
Generals/Code/GameEngine/Include/GameNetwork/NetworkInterface.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// NetworkInterface.h ///////////////////////////////////////////////////////////////
|
||||
// Network singleton class - defines interface to Network methods
|
||||
// Author: Matthew D. Campbell, July 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _NETWORK_INTERFACE_H_
|
||||
#define _NETWORK_INTERFACE_H_
|
||||
|
||||
#include "Common/MessageStream.h"
|
||||
#include "GameNetwork/ConnectionManager.h"
|
||||
#include "GameNetwork/User.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
|
||||
// forward declarations
|
||||
|
||||
struct CommandPacket;
|
||||
class GameMessage;
|
||||
class GameInfo;
|
||||
|
||||
void ClearCommandPacket(UnsignedInt frame); ///< ClearCommandPacket clears the command packet at the start of the frame.
|
||||
CommandPacket *GetCommandPacket(void); ///< TheNetwork calls GetCommandPacket to get commands to send.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface definition for the Network.
|
||||
*/
|
||||
class NetworkInterface : public SubsystemInterface
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual ~NetworkInterface() { };
|
||||
|
||||
static NetworkInterface * createNetwork( void );
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
// SubsystemInterface functions
|
||||
virtual void init( void ) = 0; ///< Initialize the network
|
||||
virtual void reset( void ) = 0; ///< Re-initialize the network
|
||||
virtual void update( void ) = 0; ///< Updates the network
|
||||
virtual void liteupdate( void ) = 0; ///< does a lightweight update for passing messages around.
|
||||
|
||||
virtual void setLocalAddress(UnsignedInt ip, UnsignedInt port) = 0; ///< Tell the network what local ip and port to bind to.
|
||||
virtual Bool isFrameDataReady( void ) = 0; ///< Are the commands for the next frame available?
|
||||
virtual void parseUserList( const GameInfo *game ) = 0; ///< Parse a userlist, creating connections
|
||||
virtual void startGame(void) = 0; ///< Sets the network game frame counter to -1
|
||||
virtual UnsignedInt getRunAhead(void) = 0; ///< Get the current RunAhead value
|
||||
virtual UnsignedInt getFrameRate(void) = 0; ///< Get the current allowed frame rate.
|
||||
virtual UnsignedInt getPacketArrivalCushion(void) = 0; ///< Get the smallest packet arrival cushion since this was last called.
|
||||
|
||||
// Chat functions
|
||||
virtual void sendChat(UnicodeString text, Int playerMask) = 0; ///< Send a chat line using the normal system.
|
||||
virtual void sendDisconnectChat(UnicodeString text) = 0; ///< Send a chat line using the disconnect manager.
|
||||
|
||||
virtual void sendFile(AsciiString path, UnsignedByte playerMask, UnsignedShort commandID) = 0;
|
||||
virtual UnsignedShort sendFileAnnounce(AsciiString path, UnsignedByte playerMask) = 0;
|
||||
virtual Int getFileTransferProgress(Int playerID, AsciiString path) = 0;
|
||||
virtual Bool areAllQueuesEmpty(void) = 0;
|
||||
|
||||
virtual void quitGame() = 0; ///< Quit the game right now.
|
||||
|
||||
virtual void selfDestructPlayer(Int index) = 0;
|
||||
|
||||
virtual void voteForPlayerDisconnect(Int slot) = 0; ///< register a vote towards this player's disconnect.
|
||||
virtual Bool isPacketRouter( void ) = 0;
|
||||
|
||||
// Bandwidth metrics
|
||||
virtual Real getIncomingBytesPerSecond( void ) = 0;
|
||||
virtual Real getIncomingPacketsPerSecond( void ) = 0;
|
||||
virtual Real getOutgoingBytesPerSecond( void ) = 0;
|
||||
virtual Real getOutgoingPacketsPerSecond( void ) = 0;
|
||||
virtual Real getUnknownBytesPerSecond( void ) = 0;
|
||||
virtual Real getUnknownPacketsPerSecond( void ) = 0;
|
||||
|
||||
virtual void updateLoadProgress( Int percent ) = 0;
|
||||
virtual void loadProgressComplete( void ) = 0;
|
||||
virtual void sendTimeOutGameStart( void ) = 0;
|
||||
virtual UnsignedInt getLocalPlayerID()= 0;
|
||||
virtual UnicodeString getPlayerName(Int playerNum)= 0;
|
||||
virtual Int getNumPlayers() = 0;
|
||||
|
||||
virtual Int getAverageFPS() = 0;
|
||||
virtual Int getSlotAverageFPS(Int slot) = 0;
|
||||
|
||||
virtual void attachTransport(Transport *transport) = 0;
|
||||
virtual void initTransport() = 0;
|
||||
virtual Bool sawCRCMismatch() = 0;
|
||||
virtual void setSawCRCMismatch() = 0;
|
||||
|
||||
virtual Bool isPlayerConnected(Int playerID) = 0;
|
||||
|
||||
virtual void notifyOthersOfCurrentFrame() = 0; ///< Tells all the other players what frame we are on.
|
||||
virtual void notifyOthersOfNewFrame(UnsignedInt frame) = 0; ///< Tells all the other players that we are on a new frame.
|
||||
|
||||
virtual Int getExecutionFrame() = 0; ///< Returns the next valid frame for simultaneous command execution.
|
||||
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
virtual void toggleNetworkOn( void ) = 0; ///< toggle whether or not to send network traffic.
|
||||
#endif
|
||||
|
||||
// For disconnect blame assignment
|
||||
virtual UnsignedInt getPingFrame() = 0;
|
||||
virtual Int getPingsSent() = 0;
|
||||
virtual Int getPingsRecieved() = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ResolveIP turns a string ("games2.westwood.com", or "192.168.0.1") into
|
||||
* a 32-bit unsigned integer.
|
||||
*/
|
||||
UnsignedInt ResolveIP(AsciiString host);
|
||||
|
||||
#endif // _NETWORK_INTERFACE_H_
|
105
Generals/Code/GameEngine/Include/GameNetwork/RankPointValue.h
Normal file
105
Generals/Code/GameEngine/Include/GameNetwork/RankPointValue.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: RankPointValue.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// created: Sep 2002
|
||||
//
|
||||
// Filename: RankPointValue.h
|
||||
//
|
||||
// author: Chris Huybregts
|
||||
//
|
||||
// purpose:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __RANK_POINT_VALUE_H_
|
||||
#define __RANK_POINT_VALUE_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
class Image;
|
||||
class PSPlayerStats;
|
||||
//-----------------------------------------------------------------------------
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
RANK_PRIVATE = 0,
|
||||
RANK_CORPORAL,
|
||||
RANK_SERGEANT,
|
||||
RANK_LIEUTENANT,
|
||||
RANK_CAPTAIN,
|
||||
RANK_MAJOR,
|
||||
RANK_COLONEL,
|
||||
RANK_BRIGADIER_GENERAL,
|
||||
RANK_GENERAL,
|
||||
RANK_COMMANDER_IN_CHIEF,
|
||||
|
||||
MAX_RANKS // keep last
|
||||
};
|
||||
|
||||
struct RankPoints
|
||||
{
|
||||
RankPoints(void );
|
||||
Int m_ranks[MAX_RANKS];
|
||||
Real m_winMultiplier;
|
||||
Real m_lostMultiplier;
|
||||
Real m_hourSpentOnlineMultiplier;
|
||||
Real m_completedSoloCampaigns;
|
||||
Real m_disconnectMultiplier;
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
// INLINING ///////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
Int CalculateRank( const PSPlayerStats& stats );
|
||||
Int GetFavoriteSide( const PSPlayerStats& stats );
|
||||
const Image* LookupSmallRankImage(Int side, Int rankPoints);
|
||||
extern RankPoints *TheRankPointValues;
|
||||
|
||||
#endif // __RANK_POINT_VALUE_H_
|
105
Generals/Code/GameEngine/Include/GameNetwork/Transport.h
Normal file
105
Generals/Code/GameEngine/Include/GameNetwork/Transport.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Transport.h ///////////////////////////////////////////////////////////////
|
||||
// Transport layer - a thin layer around a UDP socket, with queues.
|
||||
// Author: Matthew D. Campbell, July 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _TRANSPORT_H_
|
||||
#define _TRANSPORT_H_
|
||||
|
||||
#include "GameNetwork/udp.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
|
||||
/**
|
||||
* The transport layer handles the UDP socket for the game, and will packetize and
|
||||
* de-packetize multiple ACK/CommandPacket/etc packets into larger aggregates.
|
||||
*/
|
||||
// we only ever allocate one of there, and it is quite large, so we really DON'T want
|
||||
// it to be a MemoryPoolObject (srj)
|
||||
class Transport //: public MemoryPoolObject
|
||||
{
|
||||
//MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Transport, "Transport")
|
||||
public:
|
||||
|
||||
Transport();
|
||||
~Transport();
|
||||
|
||||
Bool init( AsciiString ip, UnsignedShort port );
|
||||
Bool init( UnsignedInt ip, UnsignedShort port );
|
||||
void reset( void );
|
||||
Bool update( void ); ///< Call this once a GameEngine tick, regardless of whether the frame advances.
|
||||
|
||||
Bool doRecv( void ); ///< call this to service the receive packets
|
||||
Bool doSend( void ); ///< call this to service the send queue.
|
||||
|
||||
Bool queueSend(UnsignedInt addr, UnsignedShort port, const UnsignedByte *buf, Int len /*,
|
||||
NetMessageFlags flags, Int id */); ///< Queue a packet for sending to the specified address and port. This will be sent on the next update() call.
|
||||
|
||||
inline Bool allowBroadcasts(Bool val) { if (!m_udpsock) return false; return (m_udpsock->AllowBroadcasts(val))?true:false; }
|
||||
|
||||
// Latency insertion and packet loss
|
||||
void setLatency( Bool val ) { m_useLatency = val; }
|
||||
void setPacketLoss( Bool val ) { m_usePacketLoss = val; }
|
||||
|
||||
// Bandwidth metrics
|
||||
Real getIncomingBytesPerSecond( void );
|
||||
Real getIncomingPacketsPerSecond( void );
|
||||
Real getOutgoingBytesPerSecond( void );
|
||||
Real getOutgoingPacketsPerSecond( void );
|
||||
Real getUnknownBytesPerSecond( void );
|
||||
Real getUnknownPacketsPerSecond( void );
|
||||
|
||||
TransportMessage m_outBuffer[MAX_MESSAGES];
|
||||
TransportMessage m_inBuffer[MAX_MESSAGES];
|
||||
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
DelayedTransportMessage m_delayedInBuffer[MAX_MESSAGES];
|
||||
#endif
|
||||
|
||||
UnsignedShort m_port;
|
||||
private:
|
||||
Bool m_winsockInit;
|
||||
UDP *m_udpsock;
|
||||
|
||||
// Latency insertion and packet loss
|
||||
Bool m_useLatency;
|
||||
Bool m_usePacketLoss;
|
||||
|
||||
// Bandwidth metrics
|
||||
UnsignedInt m_incomingBytes[MAX_TRANSPORT_STATISTICS_SECONDS];
|
||||
UnsignedInt m_unknownBytes[MAX_TRANSPORT_STATISTICS_SECONDS];
|
||||
UnsignedInt m_outgoingBytes[MAX_TRANSPORT_STATISTICS_SECONDS];
|
||||
UnsignedInt m_incomingPackets[MAX_TRANSPORT_STATISTICS_SECONDS];
|
||||
UnsignedInt m_unknownPackets[MAX_TRANSPORT_STATISTICS_SECONDS];
|
||||
UnsignedInt m_outgoingPackets[MAX_TRANSPORT_STATISTICS_SECONDS];
|
||||
Int m_statisticsSlot;
|
||||
UnsignedInt m_lastSecond;
|
||||
|
||||
Bool isGeneralsPacket( TransportMessage *msg );
|
||||
};
|
||||
|
||||
#endif // _TRANSPORT_H_
|
62
Generals/Code/GameEngine/Include/GameNetwork/User.h
Normal file
62
Generals/Code/GameEngine/Include/GameNetwork/User.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* User class used by the network.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __USER_H
|
||||
#define __USER_H
|
||||
|
||||
#include "GameNetwork/networkdefs.h"
|
||||
#include "Common/UnicodeString.h"
|
||||
|
||||
class User : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(User, "User")
|
||||
public:
|
||||
User() {}
|
||||
User(UnicodeString name, UnsignedInt addr, UnsignedInt port);
|
||||
User &operator= (const User *other);
|
||||
Bool operator== (const User *other);
|
||||
Bool operator!= (const User *other);
|
||||
|
||||
inline UnicodeString GetName() { return m_name; }
|
||||
void setName(UnicodeString name);
|
||||
inline UnsignedShort GetPort() { return m_port; }
|
||||
inline UnsignedInt GetIPAddr() { return m_ipaddr; }
|
||||
inline void SetPort(UnsignedShort port) { m_port = port; }
|
||||
inline void SetIPAddr(UnsignedInt ipaddr) { m_ipaddr = ipaddr; }
|
||||
|
||||
|
||||
private:
|
||||
UnicodeString m_name;
|
||||
UnsignedShort m_port;
|
||||
UnsignedInt m_ipaddr;
|
||||
};
|
||||
EMPTY_DTOR(User)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// FEBDispatch class is a template class which, when inherited from, can implement the
|
||||
// IDispatch for a COM object with a type library.
|
||||
//
|
||||
|
||||
#ifndef _FEBDISPATCH_H__
|
||||
#define _FEBDISPATCH_H__
|
||||
|
||||
#include <atlbase.h>
|
||||
extern CComModule _Module;
|
||||
#include <atlcom.h>
|
||||
#include <comutil.h> // For _bstr_t.
|
||||
|
||||
#include "oleauto.h"
|
||||
|
||||
template <class T, class C, const IID *I>
|
||||
class FEBDispatch :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComCoClass<T>,
|
||||
public C
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_COM_MAP(T)
|
||||
COM_INTERFACE_ENTRY(C)
|
||||
COM_INTERFACE_ENTRY_AGGREGATE(IID_IDispatch, m_dispatch)
|
||||
END_COM_MAP()
|
||||
|
||||
FEBDispatch()
|
||||
{
|
||||
m_ptinfo = NULL;
|
||||
m_dispatch = NULL;
|
||||
|
||||
ITypeLib *ptlib;
|
||||
HRESULT hr;
|
||||
HRESULT TypeLibraryLoadResult;
|
||||
char filename[256];
|
||||
|
||||
GetModuleFileName(NULL, filename, sizeof(filename));
|
||||
_bstr_t bstr(filename);
|
||||
|
||||
TypeLibraryLoadResult = LoadTypeLib(bstr, &ptlib);
|
||||
|
||||
DEBUG_ASSERTCRASH(TypeLibraryLoadResult == 0, ("Can't load type library for Embedded Browser"));
|
||||
|
||||
if (TypeLibraryLoadResult == S_OK)
|
||||
{
|
||||
hr = ptlib->GetTypeInfoOfGuid(*I, &m_ptinfo);
|
||||
ptlib->Release();
|
||||
|
||||
if (hr == S_OK)
|
||||
{
|
||||
hr = CreateStdDispatch(static_cast<IUnknown*>(this), static_cast<C*>(this), m_ptinfo, &m_dispatch);
|
||||
|
||||
m_dispatch->AddRef();
|
||||
// Don't release the IUnknown from CreateStdDispatch without calling AddRef.
|
||||
// It looks like CreateStdDispatch doesn't call AddRef on the IUnknown it returns.
|
||||
}
|
||||
}
|
||||
|
||||
if ( (m_dispatch == NULL) )
|
||||
{
|
||||
DEBUG_LOG(("Error creating Dispatch for Web interface\n"));
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~FEBDispatch()
|
||||
{
|
||||
if (m_ptinfo)
|
||||
m_ptinfo->Release();
|
||||
|
||||
if (m_dispatch)
|
||||
m_dispatch->Release();
|
||||
}
|
||||
|
||||
IUnknown *m_dispatch;
|
||||
|
||||
private:
|
||||
ITypeInfo *m_ptinfo;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Web Browser
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Bryan Cleveland
|
||||
* $Author: $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: $
|
||||
* $Modtime: $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __WEBBROWSER_H__
|
||||
#define __WEBBROWSER_H__
|
||||
|
||||
#include "Common/SubsystemInterface.h"
|
||||
#include <atlbase.h>
|
||||
#include <windows.h>
|
||||
#include <Common/GameMemory.h>
|
||||
#include "EABrowserDispatch/BrowserDispatch.h"
|
||||
#include "FEBDispatch.h"
|
||||
|
||||
class GameWindow;
|
||||
|
||||
class WebBrowserURL : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( WebBrowserURL, "WebBrowserURL" )
|
||||
|
||||
public:
|
||||
|
||||
WebBrowserURL();
|
||||
// virtual destructor prototype defined by memory pool object
|
||||
|
||||
const FieldParse *getFieldParse( void ) const { return m_URLFieldParseTable; }
|
||||
|
||||
AsciiString m_tag;
|
||||
AsciiString m_url;
|
||||
|
||||
WebBrowserURL *m_next;
|
||||
|
||||
static const FieldParse m_URLFieldParseTable[]; ///< the parse table for INI definition
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class WebBrowser :
|
||||
public FEBDispatch<WebBrowser, IBrowserDispatch, &IID_IBrowserDispatch>,
|
||||
public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
void init( void );
|
||||
void reset( void );
|
||||
void update( void );
|
||||
|
||||
// Create an instance of the embedded browser for Dune Emperor.
|
||||
virtual Bool createBrowserWindow(char *tag, GameWindow *win) = 0;
|
||||
virtual void closeBrowserWindow(GameWindow *win) = 0;
|
||||
|
||||
WebBrowserURL *makeNewURL(AsciiString tag);
|
||||
WebBrowserURL *findURL(AsciiString tag);
|
||||
|
||||
protected:
|
||||
// Protected to prevent direct construction via new, use CreateInstance() instead.
|
||||
WebBrowser();
|
||||
virtual ~WebBrowser();
|
||||
|
||||
// Protected to prevent copy and assignment
|
||||
WebBrowser(const WebBrowser&);
|
||||
const WebBrowser& operator=(const WebBrowser&);
|
||||
|
||||
// Bool RetrievePageURL(const char* page, char* url, int size);
|
||||
// Bool RetrieveHTMLPath(char* path, int size);
|
||||
|
||||
protected:
|
||||
ULONG mRefCount;
|
||||
WebBrowserURL *m_urlList;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// IUnknown methods
|
||||
//---------------------------------------------------------------------------
|
||||
protected:
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef(void);
|
||||
ULONG STDMETHODCALLTYPE Release(void);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// IBrowserDispatch methods
|
||||
//---------------------------------------------------------------------------
|
||||
public:
|
||||
STDMETHOD(TestMethod)(Int num1);
|
||||
};
|
||||
|
||||
extern CComObject<WebBrowser> *TheWebBrowser;
|
||||
#endif // __WEBBROWSER_H__
|
48
Generals/Code/GameEngine/Include/GameNetwork/networkutil.h
Normal file
48
Generals/Code/GameEngine/Include/GameNetwork/networkutil.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef __NETWORKUTIL_H
|
||||
#define __NETWORKUTIL_H
|
||||
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "GameNetwork/NetworkInterface.h"
|
||||
|
||||
UnsignedInt ResolveIP(AsciiString host);
|
||||
UnsignedShort GenerateNextCommandID();
|
||||
Bool DoesCommandRequireACommandID(NetCommandType type);
|
||||
Bool CommandRequiresAck(NetCommandMsg *msg);
|
||||
Bool CommandRequiresDirectSend(NetCommandMsg *msg);
|
||||
Bool IsCommandSynchronized(NetCommandType type);
|
||||
AsciiString GetAsciiNetCommandType(NetCommandType type);
|
||||
|
||||
#ifdef DEBUG_LOGGING
|
||||
void dumpBufferToLog(const void *vBuf, Int len, const char *fname, Int line);
|
||||
#define LOGBUFFER(buf, len) dumpBufferToLog(buf, len, __FILE__, __LINE__)
|
||||
#else
|
||||
#define LOGBUFFER(buf, len) {}
|
||||
#endif // DEBUG_LOGGING
|
||||
|
||||
#endif
|
129
Generals/Code/GameEngine/Include/GameNetwork/udp.h
Normal file
129
Generals/Code/GameEngine/Include/GameNetwork/udp.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
** 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. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef UDP_HEADER
|
||||
#define UDP_HEADER
|
||||
|
||||
#ifdef _UNIX
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <winsock.h>
|
||||
#include <io.h>
|
||||
//#define close _close
|
||||
//#define read _read
|
||||
//#define write _write
|
||||
|
||||
#else //UNIX
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef AIX
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
|
||||
#define DEFAULT_PROTOCOL 0
|
||||
|
||||
//#include "wlib/wstypes.h"
|
||||
//#include "wlib/wtime.h"
|
||||
|
||||
class UDP
|
||||
{
|
||||
// DATA
|
||||
private:
|
||||
Int fd;
|
||||
UnsignedInt myIP;
|
||||
UnsignedShort myPort;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
public:
|
||||
// These defines specify a system independent way to
|
||||
// get error codes for socket services.
|
||||
enum sockStat
|
||||
{
|
||||
OK = 0, // Everything's cool
|
||||
UNKNOWN = -1, // There was an error of unknown type
|
||||
ISCONN = -2, // The socket is already connected
|
||||
INPROGRESS = -3, // The socket is non-blocking and the operation
|
||||
// isn't done yet
|
||||
ALREADY = -4, // The socket is already attempting a connection
|
||||
// but isn't done yet
|
||||
AGAIN = -5, // Try again.
|
||||
ADDRINUSE = -6, // Address already in use
|
||||
ADDRNOTAVAIL = -7, // That address is not available on the remote host
|
||||
BADF = -8, // Not a valid FD
|
||||
CONNREFUSED = -9, // Connection was refused
|
||||
INTR =-10, // Operation was interrupted
|
||||
NOTSOCK =-11, // FD wasn't a socket
|
||||
PIPE =-12, // That operation just made a SIGPIPE
|
||||
WOULDBLOCK =-13, // That operation would block
|
||||
INVAL =-14, // Invalid
|
||||
TIMEDOUT =-15 // Timeout
|
||||
};
|
||||
|
||||
// CODE
|
||||
private:
|
||||
Int SetBlocking(Int block);
|
||||
|
||||
Int m_lastError;
|
||||
|
||||
public:
|
||||
UDP();
|
||||
~UDP();
|
||||
Int Bind(UnsignedInt IP,UnsignedShort port);
|
||||
Int Bind(const char *Host,UnsignedShort port);
|
||||
Int Write(const unsigned char *msg,UnsignedInt len,UnsignedInt IP,UnsignedShort port);
|
||||
Int Read(unsigned char *msg,UnsignedInt len,sockaddr_in *from);
|
||||
sockStat GetStatus(void);
|
||||
void ClearStatus(void);
|
||||
//int Wait(Int sec,Int usec,fd_set &returnSet);
|
||||
//int Wait(Int sec,Int usec,fd_set &givenSet,fd_set &returnSet);
|
||||
|
||||
Int getLocalAddr(UnsignedInt &ip, UnsignedShort &port);
|
||||
Int getFD(void) { return(fd); }
|
||||
|
||||
Int SetInputBuffer(UnsignedInt bytes);
|
||||
Int SetOutputBuffer(UnsignedInt bytes);
|
||||
int GetInputBuffer(void);
|
||||
int GetOutputBuffer(void);
|
||||
Int AllowBroadcasts(Bool status);
|
||||
};
|
||||
|
||||
AsciiString GetWSAErrorString( Int error );
|
||||
|
||||
#endif
|
Reference in a new issue