Files
firestorm/Gameleap/code/mw4/Code/MW4/NetAutoPacketSpliter.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

394 lines
9.9 KiB
C++

//===========================================================================//
// File: NetAutoPacketSpliter.cpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 01/06/1999 JSE Inital coding
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Microsoft Corp. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "MWEntityManager.hpp"
#include "NetUpdateManager.hpp"
#include "Dictionary.hpp"
#include "NetAutoPacketSpliter.hpp"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetUpdateSortEntry::NetUpdateSortEntry(Entity *entity, int size, int type, UpdateRate rate):
Plug(DefaultData),
m_rate(rate)
{
m_entity = entity;
m_size = size;
m_type = type;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetUpdatePageHolder::NetUpdatePageHolder(int page_overhead):
Plug(DefaultData),
m_UpdateEntries(NULL)
{
entryCount = 0;
totalMaxSize = page_overhead;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetUpdatePageHolder::~NetUpdatePageHolder()
{
m_UpdateEntries.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetUpdatePageHolder::AddToList(NetUpdateSortEntry *entry, int paragraph_overhead)
{
++entryCount;
totalMaxSize += entry->m_size + paragraph_overhead;
m_UpdateEntries.Add(entry);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool NetUpdatePageHolder::IsThereRoom(NetUpdateSortEntry *entry, int paragraph_overhead)
{
//if (entryCount+1 >= 64)
// return false;
if (totalMaxSize + entry->m_size + paragraph_overhead < (Network::DefaultPacketSize*8))
return true;
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef LAB_ONLY
char* Text_Table[DictionaryPage::UpdateCycleCount] =
{
"HalfhzType",
"OneHzType",
"TwoHzType",
"ThreeHzType",
"FourHzType",
"SixHzType",
"EightHzType",
"NineHzType",
"TwelveHzType",
"SixteenHzType"
};
char* Update_Text_Table[UpdateManager::UpdateCount] =
{
"MechPositionUpdateID",
"MechAnimationUpdateID",
"MechMovemntUpdateID",
"MechExternalDamageUpdateID",
"MechFirstPersonPositionUpdateID",
"MechFirstPersonControlUpdateID",
"WeaponCommandID",
"MissionObjectiveUpdateID",
"MechInternalDamageUpdateID",
"MechInternalHeatUpdateID",
"SubsystemUpdateID",
"FlushUpdateID",
"SearchLightUpdateID",
"InternalAMSAmmoUpdateID",
"ExternalAMSAmmoUpdateID",
"NearBuildingExternalDamageUpdateID",
"SecondaryBuildingExternalDamageUpdateID",
"FarBuildingExternalDamageUpdateID",
"ExternalJumpJetUpdateID",
"InternalJumpJetUpdateID",
"VehicleDamageUpdateID",
"AirMovementUpdateID",
"GroundMovementUpdateID",
"TurretMovementUpdateID",
"TorsoMovementUpdateID",
"NavPointUpdateID",
"FlagUpdateID",
"TimeUpdateID",
"SecurityQueryID",
"SecurityResponseID",
"PingUpdateID"
};
#endif
void NetUpdatePageHolder::AddSelfToDictionary(Dictionary *dictionary, int page_number)
{
DictionaryPage *page = dictionary->MakeDictionaryPage(page_number);
//SPEW(("jerryeds", "\n\nADDING PAGE : %d, UPDATE COUNT : %d - SIZE %d", page_number, entryCount, totalMaxSize));
Stuff::ChainIteratorOf<NetUpdateSortEntry*> iterator(&m_UpdateEntries);
NetUpdateSortEntry *entry;
while ((entry = iterator.ReadAndNext()) != NULL)
{
//SPEW(("jerryeds", "%s : %s : size %d", Update_Text_Table[entry->m_type], Text_Table[entry->m_rate], entry->m_size));
page->MakeDictionaryParagraph(entry->m_entity, entry->m_type, entry->m_rate);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetUpdateSorter::NetUpdateSorter(int debug_level, int connection_rate):
Plug(DefaultData),
m_halfhzList(NULL),
m_oneHzList(NULL),
m_twoHzList(NULL),
m_threeHzList(NULL),
m_fourHzList(NULL),
m_sixHzList(NULL),
m_eightHzList(NULL),
m_nineHzList(NULL),
m_twelveHzList(NULL),
m_sixteenHzList(NULL)
{
m_bandwidth = connection_rate;
m_debugLevel = debug_level;
updateList[0] = &m_halfhzList;
updateList[1] = &m_oneHzList;
updateList[2] = &m_twoHzList;
updateList[3] = &m_threeHzList;
updateList[4] = &m_fourHzList;
updateList[5] = &m_sixHzList;
updateList[6] = &m_eightHzList;
updateList[7] = &m_nineHzList;
updateList[8] = &m_twelveHzList;
updateList[9] = &m_sixteenHzList;
// dictionary version 8bit
// page number 8bit
// full ping time stamp 64bit
pageOverhead = 16+64;
paragraphOverhead = 1;
switch(debug_level)
{
case 1:
pageOverhead += 8;
break;
case 2:
pageOverhead += 16;
paragraphOverhead += 8;
break;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NetUpdateSorter::~NetUpdateSorter()
{
updateList[0]->DeletePlugs();
updateList[1]->DeletePlugs();
updateList[2]->DeletePlugs();
updateList[3]->DeletePlugs();
updateList[4]->DeletePlugs();
updateList[5]->DeletePlugs();
updateList[6]->DeletePlugs();
updateList[7]->DeletePlugs();
updateList[8]->DeletePlugs();
updateList[9]->DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetUpdateSorter::AddUpdateToList(Entity *entity, int type, UpdateRate rate)
{
UpdateEntry *update = &UpdateManager::UpdateEntries[type];
int size = (update->m_maxSize)(entity, m_debugLevel, m_bandwidth);
NetUpdateSortEntry *entry = new NetUpdateSortEntry(entity, size, type, rate);
Verify(rate.m_ActiveRate >= 0);
Verify(rate.m_ActiveRate < 10);
Verify(rate.m_InactiveRate >= 0);
Verify(rate.m_InactiveRate < 10);
Check_Object(updateList[rate.m_ActiveRate]);
updateList[rate.m_ActiveRate]->Add(entry);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetUpdateSorter::MakeDictionaryPages(Dictionary *dictionary)
{
// sort by like packets first...
// remember: anyway i cut it the cull bit will allways be sent
// the cull bit costs only go down if I only use like
// update rates
ChainOf<NetUpdatePageHolder*> twos_pages(NULL);
ChainOf<NetUpdatePageHolder*> threes_pages(NULL);
ChainOf<NetUpdateSortEntry*> *sub_list[4];
int twos_count = 0;
sub_list[0] = &m_sixteenHzList;
sub_list[1] = &m_eightHzList;
sub_list[2] = &m_fourHzList;
sub_list[3] = &m_twoHzList;
for (int i = 0; i < 4; ++i)
{
Stuff::ChainIteratorOf<NetUpdateSortEntry*> iterator(sub_list[i]);
NetUpdateSortEntry *entry;
while ((entry = iterator.GetCurrent()) != NULL)
{
++twos_count;
FindPageWithRoom(&twos_pages, entry);
iterator.Remove();
}
}
sub_list[0] = &m_twelveHzList;
sub_list[1] = &m_nineHzList;
sub_list[2] = &m_sixHzList;
sub_list[3] = &m_threeHzList;
int threes_count = 0;
for (i = 0; i < 4; ++i)
{
Stuff::ChainIteratorOf<NetUpdateSortEntry*> iterator(sub_list[i]);
NetUpdateSortEntry *entry;
while ((entry = iterator.GetCurrent()) != NULL)
{
++threes_count;
FindPageWithRoom(&threes_pages, entry);
iterator.Remove();
}
}
sub_list[0] = &m_oneHzList;
sub_list[1] = &m_halfhzList;
int page_count = 0;
if (twos_count)
{
for (i = 0; i < 2; ++i)
{
Stuff::ChainIteratorOf<NetUpdateSortEntry*> iterator(sub_list[i]);
NetUpdateSortEntry *entry;
while ((entry = iterator.GetCurrent()) != NULL)
{
++twos_count;
FindPageWithRoom(&twos_pages, entry);
iterator.Remove();
}
}
Stuff::ChainIteratorOf<NetUpdatePageHolder*> iterator(&twos_pages);
NetUpdatePageHolder *page;
while ((page = iterator.ReadAndNext()) != NULL)
{
page->AddSelfToDictionary(dictionary, page_count);
++page_count;
}
}
if (threes_count)
{
for (i = 0; i < 2; ++i)
{
Stuff::ChainIteratorOf<NetUpdateSortEntry*> iterator(sub_list[i]);
NetUpdateSortEntry *entry;
while ((entry = iterator.GetCurrent()) != NULL)
{
++threes_count;
FindPageWithRoom(&threes_pages, entry);
iterator.Remove();
}
}
Stuff::ChainIteratorOf<NetUpdatePageHolder*> iterator(&threes_pages);
NetUpdatePageHolder *page;
while ((page = iterator.ReadAndNext()) != NULL)
{
page->AddSelfToDictionary(dictionary, page_count);
++page_count;
}
}
#ifdef _ARMOR
Verify(!updateList[0]->GetSize());
Verify(!updateList[1]->GetSize());
Verify(!updateList[2]->GetSize());
Verify(!updateList[3]->GetSize());
Verify(!updateList[4]->GetSize());
Verify(!updateList[5]->GetSize());
Verify(!updateList[6]->GetSize());
Verify(!updateList[7]->GetSize());
Verify(!updateList[8]->GetSize());
Verify(!updateList[9]->GetSize());
#endif
twos_pages.DeletePlugs();
threes_pages.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetUpdateSorter::FindPageWithRoom(ChainOf<NetUpdatePageHolder*> *pages, NetUpdateSortEntry *entry)
{
Stuff::ChainIteratorOf<NetUpdatePageHolder*> iterator(pages);
NetUpdatePageHolder *page;
while ((page = iterator.ReadAndNext()) != NULL)
{
if (page->IsThereRoom(entry, paragraphOverhead))
{
page->AddToList(entry, paragraphOverhead);
return;
}
}
NetUpdatePageHolder *new_page = new NetUpdatePageHolder(pageOverhead);
pages->Add(new_page);
new_page->AddToList(entry, paragraphOverhead);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~