This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/wwnet/rhost.h

252 lines
8.4 KiB
C
Raw Permalink Normal View History

/*
** 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;