252 lines
8.4 KiB
C
252 lines
8.4 KiB
C
|
/*
|
||
|
** 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/>.
|
||
|
*/
|
||
|
|
||
|
//
|
||
|
// Filename: rhost.h
|
||
|
// Project: wwnet
|
||
|
// Author: Tom Spencer-Smith
|
||
|
// Date: June 1998
|
||
|
// Description:
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#if defined(_MSV_VER)
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
#ifndef RHOST_H
|
||
|
#define RHOST_H
|
||
|
|
||
|
#include "netstats.h"
|
||
|
#include "wwpacket.h"
|
||
|
#include "bittype.h"
|
||
|
#include "slist.h"
|
||
|
#include "wwdebug.h"
|
||
|
|
||
|
#include "win.h"
|
||
|
#include <winsock.h>
|
||
|
|
||
|
//const USHORT MAX_MESSAGE_TYPES = 256;
|
||
|
|
||
|
|
||
|
//
|
||
|
// ResendTimeoutMs is dynamic, and works like this: It starts out very low,
|
||
|
// say 10ms, as given by DEFAULT_RESEND_TIMEOUT_MS. Then it is kept 10%
|
||
|
// higher than the highest ping. Every 60s the stats are reset, and
|
||
|
// at that time ResendTimeoutMs is set to be min(3 * the average
|
||
|
// ping for that sample, max ping for that sample). This means that
|
||
|
// rare outlandishly large pings don't cause our ResendTimeoutMs to
|
||
|
// be too conservative.
|
||
|
// It's all very ad hoc of course and will need refinement...
|
||
|
//
|
||
|
|
||
|
enum {
|
||
|
RELIABLE_SEND_LIST = 0,
|
||
|
RELIABLE_RCV_LIST,
|
||
|
UNRELIABLE_SEND_LIST,
|
||
|
UNRELIABLE_RCV_LIST
|
||
|
};
|
||
|
|
||
|
class cRemoteHost
|
||
|
{
|
||
|
public:
|
||
|
cRemoteHost();
|
||
|
~cRemoteHost();
|
||
|
|
||
|
void Add_Packet(cPacket & packet, BYTE list_type);
|
||
|
void Remove_Packet(int reliable_packet_id, BYTE list_type);
|
||
|
void Toggle_Flow_Control();
|
||
|
void Init_Stats();
|
||
|
int Get_Last_Service_Count() {return LastServiceCount;}
|
||
|
void Set_Last_Service_Count(int service_count);
|
||
|
void Compute_List_Max(int list_type);
|
||
|
int Get_List_Max(int list_type);
|
||
|
void Set_List_Processing_Time(int list_type, int processing_time_ms);
|
||
|
int Get_List_Processing_Time(int list_type);
|
||
|
|
||
|
|
||
|
int Get_Last_Contact_Time() {return LastContactTime;}
|
||
|
void Set_Last_Contact_Time(int time) {LastContactTime = time;}
|
||
|
|
||
|
SOCKADDR_IN & Get_Address();
|
||
|
void Set_Address(SOCKADDR_IN & address) {Address = address;}
|
||
|
|
||
|
int Get_Target_Bps(void) const {return TargetBps;}
|
||
|
//void Set_Target_Bps(int bps) {WWASSERT(bps > 0); TargetBps = bps;}
|
||
|
void Set_Target_Bps(int bps) {TargetBps = bps;}
|
||
|
|
||
|
int Get_Maximum_Bps(void) const {return MaximumBps;}
|
||
|
//void Set_Maximum_Bps(int bps) {WWASSERT(bps > 0); MaximumBps = bps;}
|
||
|
void Set_Maximum_Bps(int bps) {MaximumBps = bps;}
|
||
|
|
||
|
cNetStats & Get_Stats() {return Stats;}
|
||
|
|
||
|
double Get_Threshold_Priority() const {return ThresholdPriority;}
|
||
|
float Get_Bandwidth_Multiplier(void) const {return BandwidthMultiplier;}
|
||
|
void Set_Average_Priority(float ave) {AverageObjectPriority = ave;}
|
||
|
float Get_Average_Priority(void) {return(AverageObjectPriority);}
|
||
|
|
||
|
|
||
|
USHORT Get_Resend_Timeout_Ms() const {return ResendTimeoutMs;}
|
||
|
|
||
|
//
|
||
|
// Ping
|
||
|
//
|
||
|
int Get_Num_Internal_Pings() const {return NumInternalPings;}
|
||
|
int Get_Total_Internal_Pingtime_Ms() const {return TotalInternalPingtimeMs;}
|
||
|
int Get_Average_Internal_Pingtime_Ms() const {return AverageInternalPingtimeMs;}
|
||
|
int Get_Min_Internal_Pingtime_Ms() const {return MinInternalPingtimeMs;}
|
||
|
int Get_Max_Internal_Pingtime_Ms() const {return MaxInternalPingtimeMs;}
|
||
|
|
||
|
int Get_Reliable_Packet_Send_Id() const {return ReliablePacketSendId;}
|
||
|
int Get_Unreliable_Packet_Send_Id() const {return UnreliablePacketSendId;}
|
||
|
int Get_Reliable_Packet_Rcv_Id() const {return ReliablePacketRcvId;}
|
||
|
int Get_Unreliable_Packet_Rcv_Id() const {return UnreliablePacketRcvId;}
|
||
|
|
||
|
void Set_Reliable_Packet_Send_Id(int id) {ReliablePacketSendId = id;}
|
||
|
void Set_Unreliable_Packet_Send_Id(int id) {UnreliablePacketSendId = id;}
|
||
|
void Set_Reliable_Packet_Rcv_Id(int id) {ReliablePacketRcvId = id;}
|
||
|
void Set_Unreliable_Packet_Rcv_Id(int id) {UnreliablePacketRcvId = id;}
|
||
|
|
||
|
void Increment_Reliable_Packet_Send_Id() {ReliablePacketSendId++;}
|
||
|
void Increment_Unreliable_Packet_Send_Id() {UnreliablePacketSendId++;}
|
||
|
void Increment_Reliable_Packet_Rcv_Id() {ReliablePacketRcvId++;}
|
||
|
void Increment_Unreliable_Packet_Rcv_Id() {UnreliablePacketRcvId++;}
|
||
|
|
||
|
unsigned long Get_Last_Keepalive_Time_Ms() const {return LastKeepaliveTimeMs;}
|
||
|
void Set_Last_Keepalive_Time_Ms(unsigned long time_ms) {LastKeepaliveTimeMs = time_ms;}
|
||
|
|
||
|
SList<cPacket> & Get_Packet_List(int index) {WWASSERT(index >= 0 && index < 4); return PacketList[index];}
|
||
|
|
||
|
bool Must_Evict() const {return MustEvict;}
|
||
|
void Set_Must_Evict(bool flag) {MustEvict = flag;}
|
||
|
|
||
|
void Adjust_Flow_If_Necessary(float sample_time_ms);
|
||
|
void Adjust_Resend_Timeout(void);
|
||
|
|
||
|
void Set_Id(int id) {WWASSERT(id >= 0); Id = id;}
|
||
|
int Get_Id(void) {WWASSERT(Id >= 0); return Id;}
|
||
|
|
||
|
void Set_Is_Loading(bool state);
|
||
|
bool Get_Is_Loading(void) {return(IsLoading);}
|
||
|
bool Was_Recently_Loading(unsigned long time = 0);
|
||
|
|
||
|
void Set_Flood(bool state);
|
||
|
bool Get_Flood(void) {return(ExpectPacketFlood);}
|
||
|
|
||
|
unsigned long Get_Creation_Time(void) {return(CreationTime);}
|
||
|
unsigned long Get_Total_Resends(void) {return(TotalResends);}
|
||
|
void Increment_Resends(void) {TotalResends++;}
|
||
|
void Set_Total_Resent_Packets_In_Queue (int resent_packets) {TotalResentPacketsInQueue = resent_packets;}
|
||
|
|
||
|
|
||
|
inline int Get_Priority_Update_Counter(void) {return(PriorityUpdateCounter);}
|
||
|
inline void Increment_Priority_Count(void) {PriorityUpdateCounter++; if (PriorityUpdateCounter > PriorityUpdateRate) PriorityUpdateCounter = 0;}
|
||
|
static void Set_Priority_Update_Rate(int rate) {PriorityUpdateRate = rate;}
|
||
|
|
||
|
static inline void Set_Allow_Extra_Modem_Bandwidth_Throttling(bool set) {AllowExtraModemBandwidthThrottling = set;}
|
||
|
|
||
|
private:
|
||
|
cRemoteHost(const cRemoteHost& rhs); // Disallow copy (compile/link time)
|
||
|
cRemoteHost& operator=(const cRemoteHost& rhs); // Disallow assignment (compile/link time)
|
||
|
void Dam_The_Flood(void);
|
||
|
bool Is_Outgoing_Flooded(void);
|
||
|
|
||
|
|
||
|
cNetStats Stats;
|
||
|
double ThresholdPriority;
|
||
|
double TPIncrement;
|
||
|
int LastReliableSendId;
|
||
|
int LastUnreliableSendId;
|
||
|
USHORT ResendTimeoutMs;
|
||
|
int NumInternalPings;
|
||
|
int TotalInternalPingtimeMs;
|
||
|
int AverageInternalPingtimeMs;
|
||
|
int MinInternalPingtimeMs;
|
||
|
int MaxInternalPingtimeMs;
|
||
|
SOCKADDR_IN Address;
|
||
|
int ReliablePacketSendId;
|
||
|
int UnreliablePacketSendId;
|
||
|
int ReliablePacketRcvId;
|
||
|
int UnreliablePacketRcvId;
|
||
|
SList<cPacket> PacketList[4]; // list of all player objects
|
||
|
int ListMax[4];
|
||
|
int ListProcessingTime[4];
|
||
|
unsigned long LastKeepaliveTimeMs;
|
||
|
bool MustEvict;
|
||
|
BOOL IsFlowControlEnabled;
|
||
|
int LastServiceCount;
|
||
|
int LastContactTime;
|
||
|
int TargetBps;
|
||
|
int MaximumBps;
|
||
|
int Id;
|
||
|
float BandwidthMultiplier;
|
||
|
float AverageObjectPriority;
|
||
|
bool IsLoading;
|
||
|
bool ExpectPacketFlood;
|
||
|
unsigned long FloodTimer;
|
||
|
unsigned long WasLoading;
|
||
|
unsigned long TotalResends;
|
||
|
unsigned long CreationTime;
|
||
|
int PriorityUpdateCounter;
|
||
|
|
||
|
//
|
||
|
// Variables for detecting outgoing packet floods.
|
||
|
//
|
||
|
unsigned long ExtendedAveragePingTime;
|
||
|
int ExtendedAverageCount;
|
||
|
int LastAveragePingTime;
|
||
|
bool IsOutgoingFlooded;
|
||
|
int TotalResentPacketsInQueue;
|
||
|
unsigned long NextOutgoingFloodActionTime;
|
||
|
int NumOutgoingFloods;
|
||
|
|
||
|
static bool AllowExtraModemBandwidthThrottling;
|
||
|
static int PriorityUpdateRate;
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif // RHOST_H
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// When this is set to true, sends to ALL will include this rhost.
|
||
|
// This is needed to allow a slot to be reserved for a rhost before
|
||
|
// using it extensively. Generally, when a client is accepted into a
|
||
|
// game he wil need to do an extensive data load during which there
|
||
|
// will be no network servicing. When that is finished he should signal
|
||
|
// readyness.
|
||
|
//
|
||
|
//bool IsReadyForAllData;
|
||
|
|
||
|
|
||
|
//int NumFailsInSampleTime;
|
||
|
//int NumConsecutiveTPCorrectionsDownwards;
|
||
|
//int NumConsecutiveTPCorrectionsUpwards;
|