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/wwpacket.cpp

349 lines
8.9 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: wwpacket.cpp
// Project: wwnet
// Author: Tom Spencer-Smith
// Date: June 1998
// Description: Adding and extracting data from byte streams
//
//------------------------------------------------------------------------------------
#include "wwpacket.h"
#include "win.h"
#include "systimer.h"
#include "crc.h"
#include "quat.h"
#include "fromaddress.h"
#include "packettype.h"
#include "bitpackids.h"
#define PACKET_ID_BITS 28 // Enough for about 100 packets per second for about a month.
#define PACKET_TYPE_BITS 4 // Enough for 16 packet types (we currently have 7 at 9/20/2001 11:33PM)
DEFINE_AUTO_POOL(cPacket, 256)
//
// Class statics
//
#ifdef WRAPPER_CRC
const USHORT cPacket::PACKET_HEADER_SIZE = 7;
#else //WRAPPER_CRC
const int cPacket::CRC_PLACEHOLDER = 99999;
const USHORT cPacket::PACKET_HEADER_SIZE = 11;
#endif //WRAPPER_CRC
int cPacket::RefCount = 0;
bool cPacket::EncoderInit = true;
const unsigned long cPacket::DefSendTime = 0xffffffff;
//------------------------------------------------------------------------------------
cPacket::cPacket() :
Type(UNDEFINED_TYPE),
Id(UNDEFINED_ID),
SenderId(UNDEFINED_ID),
SendTime(DefSendTime),
FirstSendTime(DefSendTime),
ResendCount(-1), // so that first send doesn't count as a resend
NumSends(1)
{
//cEncoderList::Set_Compression_Enabled(false);
RefCount++;
if (EncoderInit) {
Init_Encoder();
}
}
//---------------- --------------------------------------------------------------------
cPacket::~cPacket()
{
RefCount--;
}
//------------------------------------------------------------------------------------
//
// Assignment operator
//
cPacket& cPacket::operator=(const cPacket& source)
{
PFromAddressWrapper = source.PFromAddressWrapper;
Type = source.Type;
Id = source.Id;
SenderId = source.SenderId;
SendTime = source.SendTime;
FirstSendTime = source.FirstSendTime;
ResendCount = source.ResendCount;
#ifndef WRAPPER_CRC
IsCrcCorrect = source.IsCrcCorrect;
#endif //WRAPPER_CRC
BitStreamClass::operator=(source);
NumSends = source.NumSends;
return * this;
}
//------------------------------------------------------------------------------------
void cPacket::Add_Vector3(Vector3 & v)
{
WWASSERT(v.Is_Valid());
Add(v.X);
Add(v.Y);
Add(v.Z);
}
//------------------------------------------------------------------------------------
void cPacket::Get_Vector3(Vector3 & v)
{
Get(v.X);
Get(v.Y);
Get(v.Z);
WWASSERT(v.Is_Valid());
}
//------------------------------------------------------------------------------------
void cPacket::Add_Quaternion(Quaternion & q)
{
WWASSERT(q.Is_Valid());
Add(q.X);
Add(q.Y);
Add(q.Z);
Add(q.W);
}
//------------------------------------------------------------------------------------
void cPacket::Get_Quaternion(Quaternion & q)
{
Get(q.X);
Get(q.Y);
Get(q.Z);
Get(q.W);
WWASSERT(q.Is_Valid());
}
//------------------------------------------------------------------------------------
void cPacket::Set_Type(BYTE type)
{
WWASSERT(Type == UNDEFINED_TYPE || Type == type);
WWASSERT(type != UNDEFINED_TYPE);
Type = type;
}
//------------------------------------------------------------------------------------
void cPacket::Set_Id(int id)
{
WWASSERT(id != UNDEFINED_ID);
Id = id;
}
//------------------------------------------------------------------------------------
void cPacket::Set_Sender_Id(int sender_id)
{
SenderId = sender_id;
}
//------------------------------------------------------------------------------------
void cPacket::Set_Send_Time()
{
unsigned long time = TIMEGETTIME();
if (SendTime == DefSendTime) {
FirstSendTime = time;
}
SendTime = time;
}
//------------------------------------------------------------------------------------
void cPacket::Set_Num_Sends(int num_sends)
{
WWASSERT(num_sends > 0);
NumSends = num_sends;
}
/*
//------------------------------------------------------------------------------------
BYTE cPacket::Peek_Message_Type() const
{
//
// Note that using Get is the only valid way to read data from a packet!
//
cPacket temp_packet;
temp_packet = *this;
BYTE message_type;
temp_packet.Get(message_type);
temp_packet.Flush();
return message_type;
}
*/
void cPacket::Init_Encoder(void)
{
EncoderInit = false;
cEncoderList::Set_Precision(BITPACK_PACKET_ID, PACKET_ID_BITS);
cEncoderList::Set_Precision(BITPACK_PACKET_TYPE, PACKET_TYPE_BITS);
}
//------------------------------------------------------------------------------------
void cPacket::Construct_Full_Packet(cPacket & full_packet, cPacket & src_packet)
{
WWASSERT(
src_packet.Get_Type() >= PACKETTYPE_FIRST &&
src_packet.Get_Type() <= PACKETTYPE_LAST);
WWASSERT(src_packet.Get_Id() != UNDEFINED_ID);
#ifndef WRAPPER_CRC
full_packet.Add(CRC_PLACEHOLDER);
#endif //WRAPPER_CRC
full_packet.Add(src_packet.Get_Type(), BITPACK_PACKET_TYPE);
full_packet.Add(src_packet.Get_Id(), BITPACK_PACKET_ID);
full_packet.Add((BYTE)src_packet.Get_Sender_Id());
full_packet.Add((USHORT)src_packet.Get_Bit_Length());
int header_bit_length = full_packet.Get_Bit_Length();
WWASSERT(header_bit_length == PACKET_HEADER_SIZE * 8);
memcpy(
full_packet.Get_Data() + PACKET_HEADER_SIZE,
src_packet.Get_Data(),
src_packet.Get_Compressed_Size_Bytes());
unsigned int whole_bit_length = header_bit_length + src_packet.Get_Bit_Length();
full_packet.Set_Bit_Length(whole_bit_length);
//
// Compute a CRC for all the data following the CRC placeholder
//
//ULONG crc = CRC::Memory(
// (BYTE *) (full_packet.Get_Data() + sizeof(CRC_PLACEHOLDER)),
// full_packet.Get_Max_Size() - sizeof(CRC_PLACEHOLDER));
// Only CRC the meaningful data in the buffer - not the other 1300ish bytes as well. ST - 9/19/2001 11:18PM
#ifndef WRAPPER_CRC
ULONG crc = CRC::Memory((BYTE *) (full_packet.Get_Data() + sizeof(CRC_PLACEHOLDER)), (whole_bit_length / 8) - sizeof(CRC_PLACEHOLDER));
//
// Overwrite the crc placeholder with the computed crc.
//
cPacket temp_packet;
temp_packet.Add(crc);
memcpy(
full_packet.Get_Data(),
temp_packet.Get_Data(),
temp_packet.Get_Compressed_Size_Bytes());
#endif //WRAPPER_CRC
}
//------------------------------------------------------------------------------------
void cPacket::Construct_App_Packet(cPacket & packet, cPacket & full_packet)
{
#ifndef WRAPPER_CRC
int remote_crc;
#endif //WRAPPER_CRC
BYTE type;
int packet_id;
char sender_id;
USHORT bit_size;
#ifndef WRAPPER_CRC
full_packet.Get(remote_crc);
#endif //WRAPPER_CRC
full_packet.Get(type, BITPACK_PACKET_TYPE);
full_packet.Get(packet_id, BITPACK_PACKET_ID);
full_packet.Get(sender_id);
full_packet.Get(bit_size);
#ifdef WRAPPER_CRC
packet.Set_Type(type);
packet.Set_Id(packet_id);
packet.Set_Sender_Id(sender_id);
packet.Set_Bit_Length(bit_size);
packet.PFromAddressWrapper = full_packet.PFromAddressWrapper;
memcpy(packet.Get_Data(), full_packet.Get_Data() + PACKET_HEADER_SIZE, packet.Get_Compressed_Size_Bytes());
#else //WRAPPER_CRC
if (((bit_size / 8) + PACKET_HEADER_SIZE) < MAX_BUFFER_SIZE) {
//
// Only CRC the meaningful data in the buffer - not the other 1300ish bytes as well. ST - 9/19/2001 11:29PM
//
int local_crc = CRC::Memory((BYTE *) (full_packet.Get_Data() + sizeof(CRC_PLACEHOLDER)), ((bit_size / 8) + PACKET_HEADER_SIZE) - sizeof(CRC_PLACEHOLDER));
if (local_crc == remote_crc) {
packet.Set_Is_Crc_Correct(true);
packet.Set_Type(type);
packet.Set_Id(packet_id);
packet.Set_Sender_Id(sender_id);
packet.Set_Bit_Length(bit_size);
packet.PFromAddressWrapper = full_packet.PFromAddressWrapper;
memcpy(packet.Get_Data(), full_packet.Get_Data() + PACKET_HEADER_SIZE, packet.Get_Compressed_Size_Bytes());
} else {
packet.Set_Is_Crc_Correct(false);
}
} else {
packet.Set_Is_Crc_Correct(false);
}
#endif //WRAPPER_CRC
}
//ExecuteTime(0),
//ReturnCode(0),
//ExecuteTime = source.ExecuteTime;
//ReturnCode = source.ReturnCode;
//------------------------------------------------------------------------------------
/*
void cPacket::Set_Execute_Time(int execute_time)
{
WWASSERT(execute_time > 0);
ExecuteTime = execute_time;
}
*/
/*
if (!Is_Flushed()) {
WWDEBUG_SAY(("*** cPacket::~cPacket: !Is_Flushed()\n"));
DIE;
}
*/