mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
418
Code/Commando/natter.h
Normal file
418
Code/Commando/natter.h
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(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 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:: /Commando/Code/Commando/natter.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 3/01/02 2:27p $*
|
||||
* *
|
||||
* $Revision:: 18 $*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NATTER_H
|
||||
#define NATTER_H
|
||||
|
||||
#include "always.h"
|
||||
//#include "nat.h"
|
||||
#include "nataddr.h"
|
||||
|
||||
|
||||
/*
|
||||
** Project specific includes.
|
||||
*/
|
||||
#include <Notify.h>
|
||||
#include <wwonline\wolsession.h>
|
||||
#include <wwonline\woluser.h>
|
||||
#include <combat\combat.h>
|
||||
#include <wwnet\wwpacket.h>
|
||||
|
||||
|
||||
/*
|
||||
** Commonly available components.
|
||||
*/
|
||||
#include <wwlib\vector.h>
|
||||
|
||||
|
||||
#ifdef WWASSERT
|
||||
#ifndef fw_assert
|
||||
#define fw_assert WWASSERT
|
||||
#endif //fw_assert
|
||||
#else //WWASSERT
|
||||
#define fw_assert assert
|
||||
#endif //WWASSERT
|
||||
|
||||
/*
|
||||
** Size of temporary game options storage buffers.
|
||||
*/
|
||||
#define OPTIONS_STAGING_BUFFER_SIZE 512
|
||||
|
||||
|
||||
#define PORT_BASE_MIN 1024
|
||||
#define PORT_BASE_MAX 4095
|
||||
|
||||
#define PORT_POOL_MIN 4096
|
||||
#define PORT_POOL_MAX 65535
|
||||
|
||||
/*
|
||||
** Forward declarations.
|
||||
*/
|
||||
class SocketHandlerClass;
|
||||
class RegistryClass;
|
||||
|
||||
|
||||
/*
|
||||
** This class performs the inevitable task of interfacing with whatever piece of code happens to be talking to WOLAPI.
|
||||
**
|
||||
** Will have to be completely replaced per project.
|
||||
**
|
||||
*/
|
||||
class WOLNATInterfaceClass : public Observer<WWOnline::UserEvent>,
|
||||
public Observer<WWOnline::GameOptionsMessage>,
|
||||
public Observer<WWOnline::ConnectionStatus>,
|
||||
public Observer<WWOnline::UserIPEvent>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
** Constructor, destructor.
|
||||
*/
|
||||
WOLNATInterfaceClass(void);
|
||||
~WOLNATInterfaceClass(void);
|
||||
|
||||
/*
|
||||
** Startup, shutdown.
|
||||
*/
|
||||
void Init(void);
|
||||
void Shutdown(void);
|
||||
|
||||
/*
|
||||
** Service.
|
||||
*/
|
||||
void Service(void);
|
||||
void Set_Service_Socket_Handler(SocketHandlerClass *socket);
|
||||
void Service_Receive_Queue(SocketHandlerClass *socket);
|
||||
|
||||
/*
|
||||
** User event notification.
|
||||
*/
|
||||
void HandleNotification(WWOnline::UserEvent&);
|
||||
|
||||
/*
|
||||
** Game options notificaton.
|
||||
*/
|
||||
void HandleNotification(WWOnline::GameOptionsMessage&);
|
||||
|
||||
/*
|
||||
** Server connection notification.
|
||||
*/
|
||||
void HandleNotification(WWOnline::ConnectionStatus&);
|
||||
|
||||
/*
|
||||
** User IP event.
|
||||
*/
|
||||
void HandleNotification(WWOnline::UserIPEvent&);
|
||||
|
||||
/*
|
||||
** Server query.
|
||||
*/
|
||||
void Get_Current_Server_ConnData(char *buffer, int size);
|
||||
|
||||
/*
|
||||
** Private game options.
|
||||
*/
|
||||
void Send_Private_Game_Options(WOL::User *user, char *options);
|
||||
bool Get_Private_Game_Options(WOL::User *user, char *options, int option_buffer_len);
|
||||
|
||||
/*
|
||||
** Conversion.
|
||||
*/
|
||||
char *Get_Silly_String(WideStringClass *silly_string, char *buffer, int buffer_size);
|
||||
|
||||
/*
|
||||
** Game packet handling.
|
||||
*/
|
||||
bool Get_Packet(char *packet_buffer, int buffer_size, IPAddressClass &address);
|
||||
void Intercept_Game_Packet(cPacket &packet);
|
||||
bool Send_Game_Format_Packet_To(IPAddressClass *address, char *payload, int payload_size, SocketHandlerClass *socket_handler = NULL);
|
||||
|
||||
/*
|
||||
** General game helper functions.
|
||||
*/
|
||||
bool Get_My_Name(char *namebuf);
|
||||
bool Am_I_Server(void) {return(IsServer);};
|
||||
void Set_Server(bool is_server);
|
||||
void Set_Server_Negotiated_Address(IPAddressClass *server_address);
|
||||
DynamicVectorClass<WOL::Server*> Get_Mangler_Server_List(void);
|
||||
unsigned short Get_Mangler_Port_By_Index(int index);
|
||||
bool Get_Mangler_Name_By_Index(int index, char *mangler_name);
|
||||
int Get_Num_Mangler_Servers(void);
|
||||
unsigned long Get_Local_Address(void) {
|
||||
return(0);//return(FirewallHelper.Get_Local_Address());
|
||||
};
|
||||
void Tell_Server_That_Client_Is_In_Channel(void);
|
||||
bool Is_NAT_Thread_Busy(void);
|
||||
|
||||
/*
|
||||
** Game port management.
|
||||
*/
|
||||
unsigned short Get_Next_Client_Port(void);
|
||||
unsigned short Get_Port_As_Server(void);
|
||||
unsigned short Get_Port_As_Server_Client(void);
|
||||
unsigned short Get_Force_Port(void) {return(ForcePort);};
|
||||
|
||||
/*
|
||||
** Config.
|
||||
*/
|
||||
void Get_Config(RegistryClass *reg, int &port_number, bool &send_delay);
|
||||
void Set_Config(RegistryClass *reg, int port_number, bool send_delay);
|
||||
void Save_Firewall_Info_To_Registry(void);
|
||||
unsigned long Get_Reg_External_IP(void) {return(RegExternalIP);}
|
||||
unsigned long Get_Reg_External_Port(void) {return(RegExternalPort);}
|
||||
void Get_Compact_Log(StringClass &log_string);
|
||||
unsigned long Get_Chat_External_IP(void) {return(ChatExternalIP);}
|
||||
|
||||
|
||||
/*
|
||||
** Game options string types.
|
||||
*/
|
||||
enum {
|
||||
OPTION_ERROR = 'a',
|
||||
OPTION_INVITE_PORT_NEGOTIATION,
|
||||
OPTION_ACCEPT_PORT_NEGOTIATION_INVITATION,
|
||||
OPTION_PORT_NOTIFICATION,
|
||||
OPTION_CONNECTION_RESULT,
|
||||
OPTION_QUEUE_STATE,
|
||||
OPTION_ABORT_NEGOTIATION,
|
||||
OPTION_CLIENT_IN_CHANNEL
|
||||
};
|
||||
|
||||
/*
|
||||
** Game options format for the firewall code only. All firewall options packets are prefixed with "NAT:"
|
||||
*/
|
||||
typedef struct tPrivateGameOptions {
|
||||
|
||||
/*
|
||||
** Option previx (Always "NAT:" for us.
|
||||
*/
|
||||
char NATOptionsPrefix[4];
|
||||
|
||||
/*
|
||||
** Option type. See list above.
|
||||
*/
|
||||
char Option;
|
||||
|
||||
/*
|
||||
** Option payload union. Each type of option has a different payload.
|
||||
*/
|
||||
union tOptionData {
|
||||
|
||||
/*
|
||||
** Data for OPTION_INVITE_PORT_NEGOTIATION.
|
||||
*/
|
||||
struct InvitationStruct {
|
||||
char LocalIP[9]; // 00000000,
|
||||
char LocalPort[5]; // 0000,
|
||||
char ExternalIP[9]; // 00000000,
|
||||
char FirewallType[9]; // 00000000,
|
||||
char Queued[5]; // 0000(null)
|
||||
} Invitation;
|
||||
|
||||
/*
|
||||
** Data for OPTION_ACCEPT_PORT_NEGOTIATION_INVITATION.
|
||||
*/
|
||||
struct AcceptStruct {
|
||||
char LocalIP[9]; // 00000000,
|
||||
char LocalPort[5]; // 0000,
|
||||
char ExternalIP[9]; // 00000000,
|
||||
char FirewallType[9]; // 00000000(null)
|
||||
} Accept;
|
||||
|
||||
/*
|
||||
** Data for OPTION_PORT_NOTIFICATION.
|
||||
*/
|
||||
struct PortStruct {
|
||||
char MangledPort[5]; // 0000,
|
||||
char Name[64]; // "Players name......"(null)
|
||||
} Port;
|
||||
|
||||
/*
|
||||
** Data for OPTION_CONNECTION_RESULT.
|
||||
*/
|
||||
struct ConnectionResultStruct {
|
||||
char Result[2]; // n,
|
||||
char Port[5]; // 0000,
|
||||
char Name[64]; // "Players name......"(null)
|
||||
} ConnectionResult;
|
||||
|
||||
/*
|
||||
** Data for OPTION_QUEUE_STATE
|
||||
*/
|
||||
struct QueueStateStruct {
|
||||
char Position[3]; // 00(null)
|
||||
} QueueState;
|
||||
|
||||
/*
|
||||
** Data for OPTION_ABORT_NEGOTIATION
|
||||
*/
|
||||
struct QuitTalkingStruct {
|
||||
char Nothing; // 00
|
||||
} QuitTalking;
|
||||
|
||||
/*
|
||||
** Data for OPTION_CLIENT_IN_CHANNEL
|
||||
*/
|
||||
struct ClientInChannelStruct {
|
||||
char Name[64]; // "Players name......"(null)
|
||||
} ClientInChannel;
|
||||
|
||||
} OptionData;
|
||||
} PrivateGameOptionsStruct;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
** PortBase is the start of the current port number range we are using. The range is added to the port base every time
|
||||
** we start a new game so we are always using a fresh port. The server uses 2 ports per game and the client uses 1 port.
|
||||
*/
|
||||
unsigned short PortBase;
|
||||
|
||||
/*
|
||||
** Set this to non-zero to force it to be used as the local port.
|
||||
*/
|
||||
unsigned short ForcePort;
|
||||
|
||||
/*
|
||||
** External IP and port from the registry.
|
||||
*/
|
||||
unsigned long RegExternalIP;
|
||||
unsigned short RegExternalPort;
|
||||
|
||||
/*
|
||||
** Our IP according to westwood chat.
|
||||
*/
|
||||
unsigned long ChatExternalIP;
|
||||
|
||||
/*
|
||||
** Bloat pointer to the Session class.
|
||||
*/
|
||||
RefPtr<WWOnline::Session> SessionPtr;
|
||||
|
||||
/*
|
||||
** Address we used to send to the server.
|
||||
*/
|
||||
IPAddressClass ServerNegotiatedAddress;
|
||||
|
||||
/*
|
||||
** Holding area for incoming game packets.
|
||||
*/
|
||||
struct GamePacketStruct {
|
||||
IPAddressClass FromAddress;
|
||||
unsigned char Payload[512];
|
||||
};
|
||||
|
||||
DynamicVectorClass<GamePacketStruct*> IncomingPackets;
|
||||
|
||||
/*
|
||||
** This is the socket handler to use when sending or receiving game packets. It's only used on the client side since
|
||||
** the server side has to use the games mechanisms to send and receive (the game already has a socket bound to the port
|
||||
** we want to use in the server case).
|
||||
*/
|
||||
SocketHandlerClass *ServiceSocketHandler;
|
||||
|
||||
/*
|
||||
** Am I a game server?
|
||||
*/
|
||||
bool IsServer;
|
||||
|
||||
/*
|
||||
** Game options staging areas.
|
||||
*/
|
||||
typedef struct tGameOptionsStagingStruct {
|
||||
WOL::User User;
|
||||
char Options[OPTIONS_STAGING_BUFFER_SIZE];
|
||||
} GameOptionsStagingStruct;
|
||||
|
||||
DynamicVectorClass<GameOptionsStagingStruct*> IncomingOptions;
|
||||
DynamicVectorClass<GameOptionsStagingStruct*> OutgoingOptions;
|
||||
|
||||
/*
|
||||
** Mutex to serialise access to game options.
|
||||
*/
|
||||
HANDLE GameOptionsMutex;
|
||||
|
||||
/*
|
||||
** Thread safety for game options.
|
||||
*/
|
||||
class ThreadLockClass
|
||||
{
|
||||
public:
|
||||
/*
|
||||
** Constructor. Grabs the mutex.
|
||||
*/
|
||||
inline ThreadLockClass(WOLNATInterfaceClass *wnptr) {
|
||||
WNPtr = wnptr;
|
||||
int deadlock = WaitForSingleObject(wnptr->GameOptionsMutex, 10 * 1000);
|
||||
if (deadlock == WAIT_TIMEOUT) {
|
||||
WWDEBUG_SAY(("FirewallHelper - Timeout waiting for firewall helper data mutex\n"));
|
||||
fw_assert(deadlock != WAIT_TIMEOUT);
|
||||
}
|
||||
};
|
||||
|
||||
WOLNATInterfaceClass *WNPtr;
|
||||
|
||||
/*
|
||||
** Destructor, releases the mutex.
|
||||
*/
|
||||
inline ~ThreadLockClass(void) {
|
||||
ReleaseMutex(WNPtr->GameOptionsMutex);
|
||||
};
|
||||
};
|
||||
friend ThreadLockClass;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Extern for single instance of the WOLNATInterface.
|
||||
*/
|
||||
extern WOLNATInterfaceClass WOLNATInterface;
|
||||
|
||||
|
||||
#endif //NATTER_H
|
||||
Reference in New Issue
Block a user