| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667 |
- /*
- ** 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/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Commando/cnetwork.cpp $*
- * *
- * $Author:: Byon_g $*
- * *
- * $Modtime:: 3/29/02 5:02p $*
- * *
- * $Revision:: 152 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "cnetwork.h"
- #include <shellapi.h>
- #include <stdio.h>
- #include "specialbuilds.h"
- #include "langmode.h"
- #include "wolgmode.h"
- #include "playermanager.h"
- #include "textdisplay.h"
- #include "gameobjmanager.h"
- #include "multihud.h"
- #include "WWAudio.H"
- #include "useroptions.h"
- #include "devoptions.h"
- #include "translatedb.h"
- #include "string_ids.h"
- #include "msgstatlistgroup.h"
- #include "wwprofile.h"
- #include "gametype.h"
- #include "crc.h"
- #include "render2d.h"
- #include "wwmemlog.h"
- #include "svrgoodbyeevent.h"
- #include "gameoptionsevent.h"
- #include "evictionevent.h"
- #include "changeteamevent.h"
- #include "clientcontrol.h"
- #include "serverfps.h"
- #include "sbbomanager.h"
- #include "clientgoodbyeevent.h"
- //#include "helptext.h"
- #include "natter.h"
- #include "vistable.h"
- #include "gameinitmgr.h"
- #include "dlgmessagebox.h"
- #include "apppacketstats.h"
- #include "clientfps.h"
- #include "gamechanlist.h"
- #include "packetmgr.h"
- #include "clientpingmanager.h"
- #include "bandwidthgraph.h"
- #include "buildnum.h"
- #include "messagewindow.h"
- #include "wwmemlog.h"
- #include "consolemode.h"
- #include "slavemaster.h"
- #include "gamedataupdateevent.h"
- #include "gamespyadmin.h"
- #include "demosupport.h"
- #include "serversettings.h"
- #include "dlgmpconnectionrefused.h"
- #include "Resource.h"
- #include <WWUI\DialogMgr.h>
- #include "ffactory.h"
- #include "realcrc.h"
- extern bool g_is_loading;
- //
- // Networking cNetwork statics
- //
- char cNetwork::MessageToSend[];
- char cNetwork::Command[];
- int cNetwork::ExeKey = 0;
- int cNetwork::ExeCRC = 0;
- int cNetwork::StringsCRC = 0;
- char cNetwork::ClientString[];
- char cNetwork::ClientEnumerationString[];
- CombatNetworkReceiverInstanceClass * cNetwork::NetworkReceiver = NULL;
- GameCombatNetworkHandlerClass cNetwork::NetHandler;
- int cNetwork::Fps = 0;
- int cNetwork::ThinkCount = 0;
- cMsgStatList * cNetwork::PClientStatList = NULL;
- cMsgStatListGroup * cNetwork::PServerStatListGroup = NULL;
- cConnection * cNetwork::PClientConnection = NULL;
- cConnection * cNetwork::PServerConnection = NULL;
- CombatNetworkReceiver * cNetwork::Receiver = NULL;
- float cNetwork::GraphingY;
- float cNetwork::BandwidthBarLength = 0;
- //int cNetwork::BandwidthScaler = 28800;
- int cNetwork::BandwidthScaler = 50000;
- bool cNetwork::HaveDoneTeamChangeDialog = false;
- bool cNetwork::HaveDoneMotdDialog = false;
- VisTableClass * cNetwork::VisTable = NULL;
- bool cNetwork::LastServerConnectionStateBad = false;
- bool cNetwork::SensibleUpdates = true;
- //-----------------------------------------------------------------------------
- void cNetwork::Init_Client(unsigned short my_port)
- {
- WWMEMLOG(MEM_NETWORK);
- #ifndef FREEDEDICATEDSERVER
- WWDEBUG_SAY(("cNetwork::Init_Client\n"));
- if (PClientConnection != NULL) {
- Cleanup_Client();
- }
- PClientStatList = new cMsgStatList;
- WWASSERT(PClientStatList != NULL);
- //PClientStatList->Init(MESSAGE_COUNT);
- PClientStatList->Init(1);
- for (int i = 0; i < PClientStatList->Get_Num_Stats(); i++) {
- //PClientStatList->Set_Name(i, Message_Type_Translation(i));
- /*
- char message_trans[200];
- strcpy(message_trans, Message_Type_Translation(i));
- PClientStatList->Set_Name(i, &message_trans[8]);
- */
- PClientStatList->Set_Name(i, "message");
- }
- WWASSERT(PClientConnection == NULL);
- PClientConnection = new cConnection;
- WWASSERT(PClientConnection != NULL);
- CombatManager::Set_I_Am_Client(true);
- PClientConnection->Install_Accept_Handler(Accept_Handler);
- PClientConnection->Install_Refusal_Handler(Refusal_Handler);
- PClientConnection->Install_Client_Broken_Connection_Handler(Client_Broken_Connection_Handler);
- PClientConnection->Install_Client_Packet_Handler(Client_Packet_Handler);
- if (cGameSpyAdmin::Is_Gamespy_Game()) {
- WWASSERT(PTheGameData != NULL);
- The_Game()->Set_Password(cGameSpyAdmin::Get_Password_Attempt());
- }
- ULONG bbo = 0;
- //if (IS_SOLOPLAY || GameModeManager::Find("LAN")->Is_Active()) {
- if (IS_SOLOPLAY ||
- (GameModeManager::Find("LAN")->Is_Active() && !cGameSpyAdmin::Is_Gamespy_Game())) {
- bbo = cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_LANT1);
- WWASSERT(bbo > 0);
- cBandwidthGraph::Set_Scale(200000);
- HaveDoneTeamChangeDialog = false;
- } else {
- //WWASSERT(GameModeManager::Find("WOL")->Is_Active());
- bbo = cBandwidth::Get_Bandwidth_Bps_From_Type((BANDWIDTH_TYPE_ENUM)cUserOptions::Get_Bandwidth_Type());
- //bbo = cUserOptions::BandwidthBps.Get();
- WWASSERT(bbo > 0);
- int bw_scale = (bbo * 2) / 10;
- bw_scale = (bw_scale / 1000) * 1000;
- cBandwidthGraph::Set_Scale(bw_scale);
- if (GameModeManager::Find("WOL")->Is_Active()) {
- HaveDoneTeamChangeDialog = true;
- }
- }
- PClientConnection->Set_Bandwidth_Budget_Out(bbo);
- BOOL is_flow_control_enabled = !IS_SOLOPLAY;
- PClientConnection->Enable_Flow_Control(is_flow_control_enabled);
- WWASSERT(PTheGameData != NULL);
- PClientConnection->Init_As_Client(
- The_Game()->Get_Ip_Address(), The_Game()->Get_Port(), my_port);
- //
- // This packet resurfaces on the server in Application_Acceptance_Handler
- //
- cPacket packet;
- packet.Add_Wide_Terminated_String(cNetInterface::Get_Nickname());
- packet.Add_Wide_Terminated_String(The_Game()->Get_Password(), true);
- packet.Add(ExeKey);
- packet.Add(bbo); // note, this field is consumed by wwnet
- PClientConnection->Connect_Cs(packet);
- packet.Flush();
- /*
- if (I_Am_Only_Client()) {
- ServerFps.Init();
- }
- */
- HaveDoneMotdDialog = false;
- if (I_Am_Only_Client())
- {
- cAppPacketStats::Reset();
- }
- LastServerConnectionStateBad = false;
- cClientPingManager::Init();
- #endif // !FREEDEDICATEDSERVER
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Cleanup_Client(void)
- {
- WWMEMLOG(MEM_NETWORK);
- #ifndef FREEDEDICATEDSERVER
- WWDEBUG_SAY(("cNetwork::Cleanup_Client\n"));
- if (I_Am_Client()) {
- if (PClientConnection->Is_Established()) { // i.e we did have a connection
- cClientGoodbyeEvent * p_event = new cClientGoodbyeEvent;
- p_event->Init();
- Flush();
- }
- delete PClientConnection;
- PClientConnection = NULL;
- }
- CombatManager::Set_I_Am_Client(false);
- delete PClientStatList;
- PClientStatList = NULL;
- delete PClientControl;
- PClientControl = NULL;
- delete PClientFps;
- PClientFps = NULL;
- #endif // !FREEDEDICATEDSERVER
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Accept_Handler(void)
- {
- WWMEMLOG(MEM_NETWORK);
- #ifndef FREEDEDICATEDSERVER
- WWDEBUG_SAY(("cNetwork::Accept_Handler\n"));
- WWASSERT(I_Am_Client());
- CombatManager::Set_My_Id(Get_My_Id());
- NetworkObjectMgrClass::Init_New_Client_ID(Get_My_Id());
- if (I_Am_Only_Client()) {
- //
- // Create C->S mirrored client control object
- //
- WWASSERT(PClientControl == NULL);
- PClientControl = new CClientControl;
- PClientControl->Init();
- //
- // Create C->S mirrored client fps object
- //
- WWASSERT(PClientFps == NULL);
- PClientFps = new CClientFps;
- PClientFps->Init();
- }
- if (!I_Am_Server()) {
- if (GameModeManager::Find("LAN")->Is_Active()) {
- PLC->Accept_Actions();
- } else {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- WolGameModeClass* wolGame = static_cast<WolGameModeClass*>(gameMode);
- WWASSERT(wolGame);
- wolGame->Accept_Actions();
- }
- }
- }
- #endif // !FREEDEDICATEDSERVER
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Refusal_Handler(REFUSAL_CODE refusal_code)
- {
- #ifndef FREEDEDICATEDSERVER
- WWDEBUG_SAY(("cNetwork::Refusal_Handler\n"));
- // Close connecting dialog as neccessary.
- DialogBaseClass* dialog = DialogMgrClass::Find_Dialog(IDD_MULTIPLAY_CONNECTING);
- if (dialog != NULL) {
- // Sending 1 as the parameter tells the dialog that it is being closed
- // as a result of a refusal from the server.
- dialog->On_Command(IDCANCEL, 0, 1);
- }
- // Verify refusal code is within valid range
- WWASSERT(REFUSAL_CLIENT_ACCEPTED <= refusal_code && REFUSAL_BY_APPLICATION >= refusal_code);
- WWASSERT(I_Am_Client());
- if (GameModeManager::Find("LAN")->Is_Active()) {
- PLC->Refusal_Actions();
- } else {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- WolGameModeClass* wolGame = static_cast<WolGameModeClass*>(gameMode);
- WWASSERT(wolGame);
- wolGame->Refusal_Actions();
- }
- }
- //
- // The server refused our connection request! At this stage this
- // is fatal. Later on we would have to re-init the connection etc.
- //
- static const unsigned long _refusalStrings[] = {
- IDS_MP_CONNECTION_REFUSED_GAME_FULL, // REFUSAL_GAME_FULL
- IDS_MP_PASSWORD_WRONG, // REFUSAL_BAD_PASSWORD
- IDS_MENU_VERSION_MISMATCH, // REFUSAL_VERSION_MISMATCH
- IDS_MP_CONNECTION_REFUSED_BY_APPLICATION, // REFUSAL_PLAYER_EXISTS
- IDS_MP_CONNECTION_REFUSED_BY_APPLICATION // REFUSAL_BY_APPLICATION
- };
- const unsigned long refusalMsg = _refusalStrings[refusal_code - 1];
- if (cGameSpyAdmin::Is_Gamespy_Game()) {
- if (refusal_code == REFUSAL_VERSION_MISMATCH) {
- WideStringClass tval;
- tval.Format(L"%s...%s", TRANSLATE(IDS_MP_CONNECTION_REFUSED_BY_APPLICATION),
- TRANSLATE(IDS_MENU_VERSION_MISMATCH));
- DlgMPConnectionRefused::DoDialog(tval, false);
- } else {
- DlgMPConnectionRefused::DoDialog(TRANSLATE(refusalMsg), false);
- }
- } else {
- DlgMsgBox::DoDialog(TRANSLATE (IDS_MENU_SERVER_MESSAGE_TITLE), TRANSLATE(refusalMsg));
- }
-
-
- //
- // N.B. We cannot destroy the connection from inside this callback.
- //
- #endif // !FREEDEDICATEDSERVER
- }
- //-----------------------------------------------------------------------------
- int cNetwork::Get_Data_Files_CRC(void)
- {
- #define UNINITIALLIZED_CRC 0x4592abf1
- static int crc = UNINITIALLIZED_CRC;
- if ( crc == UNINITIALLIZED_CRC ) {
- char * filelist[] = {
- "jgo`fqv+aag", //"objects.ddb",
- "dwhjw+lkl", //"armor.ini",
- "gjk`v+lkl", //"bones.ini",
- "vpwcdf``cc`fqv+lkl", //"surfaceeffects.ini",
- "fdh`wdv+lkl", //"cameras.ini",
- "fZkjaZhbZi5+r6a", //"c_nod_mg_l0.w3d",
- "fZkjaZwnZi5+r6a", //"c_nod_rk_l0.w3d",
- "fZkjaZciZi5+r6a", //"c_nod_fl_l0.w3d",
- "fZkjaZ`kZi5+r6a", //"c_nod_en_l0.w3d",
- "fZkjaZhbjZi5+r6a", //"c_nod_mgo_l0.w3d",
- "fZkjaZwnjZi5+r6a", //"c_nod_rko_l0.w3d",
- "fZkjaZfm`hqZi5+r6a", //"c_nod_chemt_l0.w3d",
- "fZkjaZvklu`wZi5+r6a", //"c_nod_sniper_l0.w3d",
- "fZkjaZwvjiaZi5+r6a", //"c_nod_rsold_l0.w3d",
- "fZkjaZvqiqmZi5+r6a", //"c_nod_stlth_l0.w3d",
- "fZkjaZvdnpZi5+r6a", //"c_nod_saku_l0.w3d",
- "fZkjaZvdnp7Zi5+r6a", //"c_nod_saku2_l0.w3d",
- "fZkjaZwdsZi5+r6a", //"c_nod_rav_l0.w3d",
- "fZkjaZhwdsZi5+r6a", //"c_nod_mrav_l0.w3d",
- "fZkjaZhaZi5+r6a", //"c_nod_mdz_l0.w3d",
- "fZkjaZha7Zi5+r6a", //"c_nod_mdz2_l0.w3d",
- "fZkjaZqfZi5+r6a", //"c_nod_tc_l0.w3d",
- "fZkjaZhpqdkqZi5+r6a", //"c_nod_mutant_l0.w3d",
- "fZkjaZhviaZi5+r6a", //"c_nod_msld_l0.w3d",
- "fZkjaZvvjiaZi5+r6a", //"c_nod_ssold_l0.w3d",
- "fZkjaZu`qhZi5+r6a", //"c_nod_petm_l0.w3d",
- "fZkjaZndk`Zi5+r6a", //"c_nod_kane_l0.w3d",
- "fZbalZhbZi5+r6a", //"c_gdi_mg_l0.w3d",
- "fZbalZwnZi5+r6a", //"c_gdi_rk_l0.w3d",
- "fZbalZbwZi5+r6a", //"c_gdi_gr_l0.w3d",
- "fZbalZ`kZi5+r6a", //"c_gdi_en_l0.w3d",
- "fZbalZhbjZi5+r6a", //"c_gdi_mgo_l0.w3d",
- "fZbalZwnjZi5+r6a", //"c_gdi_rko_l0.w3d",
- "fZbalZv|aZi5+r6a", //"c_gdi_syd_l0.w3d",
- "fZbalZa`daZi5+r6a", //"c_gdi_dead_l0.w3d",
- "fZbalZbpkZi5+r6a", //"c_gdi_gun_l0.w3d",
- "fZbalZuqfmZi5+r6a", //"c_gdi_ptch_l0.w3d",
- "fZmdsjfZi5+r6a", //"c_havoc_l0.w3d",
- "fZmdsjfkZi5+r6a", //"c_havocn_l0.w3d",
- "fZmdsjfrZi5+r6a", //"c_havocw_l0.w3d",
- "fZmdsjfaZi5+r6a", //"c_havocd_l0.w3d",
- "fZbalZv|aZi5+r6a", //"c_gdi_syd_l0.w3d",
- "fZbalZv|a7Zi5+r6a", //"c_gdi_syd2_l0.w3d",
- "fZbalZhjglZi5+r6a", //"c_gdi_mobi_l0.w3d",
- "fZbalZmjqrZi5+r6a", //"c_gdi_hotw_l0.w3d",
- "fZbalZiqZi5+r6a", //"c_gdi_lt_l0.w3d",
- "fZkjaZu`qwZi5+r6a", //"c_nod_petr_l0.w3d",
- "fZijbdkZi5+r6a", //"c_logan_l0.w3d",
- "fZbalZijfn`Zi5+r6a", //"c_gdi_locke_l0.w3d",
- "sZkjaZgpbb|+r6a", //"v_nod_buggy.w3d",
- "sZkjaZdufZh+r6a", //"v_nod_apc_m.w3d",
- "sZkjaZdwqiw|+r6a", //"v_nod_artlry.w3d",
- "sZkjaZcidh`+r6a", //"v_nod_flame.w3d",
- "sZkjaZiqdkn+r6a", //"v_nod_ltank.w3d",
- "sZkjaZvqiqm+r6a", //"v_nod_stlth.w3d",
- "sZkjaZqwkvuqZh+r6a", //"v_nod_trnspt_m.w3d",
- "sZkjaZdudfm`Zh+r6a", //"v_nod_apache_m.w3d",
- "sZfmdh`i`jk+r6a", //"v_chameleon.w3d",
- "sZbalZmphs``+r6a", //"v_gdi_humvee.w3d",
- "sZbalZdufZh+r6a", //"v_gdi_apc_m.w3d",
- "sZbalZhwiv+r6a", //"v_gdi_mrls.w3d",
- "sZbalZh`aqkn+r6a", //"v_gdi_medtnk.w3d",
- "sZbalZhdhhqm+r6a", //"v_gdi_mammth.w3d",
- "sZulfnpu54+r6a", //"v_pickup01.w3d",
- "sZv`adk54+r6a", //"v_sedan01.w3d",
- "sZbalZjwfdZh+r6a", //"v_gdi_orca_m.w3d",
- "sZbalZqwkvuqZh+r6a", //"v_gdi_trnspt_m.w3d",
- };
- #define NUM_CRC_FILES (sizeof( filelist ) / sizeof( filelist[0] ) )
- crc = 0;
- for ( int i = 0; i < NUM_CRC_FILES; i++ ) {
- StringClass name = filelist[i];
- // Obfuscate name
- char * n = &name[0];
- while ( *n ) *n++ ^= 0x5;
- // Debug_Say(( " \"%s\",\n", name ));
- FileClass * file = _TheFileFactory->Get_File( name );
- if ( file && file->Is_Available() ) {
- int size = file->Size();
- file->Open();
- while ( size > 0 ) {
- unsigned char buffer[ 4096 ];
- int amount = min( (int)size, (int)sizeof(buffer) );
- amount = file->Read( buffer, amount );
- crc = CRC_Memory( buffer, amount, crc );
- size -= amount;
- }
- file->Close();
- } else {
- // Debug_Say(( "******%s not found\n", name ));
- }
- }
- }
- return crc;
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Compute_Exe_Key(void)
- {
- WWDEBUG_SAY(("cNetwork::Compute_Exe_Key\n"));
- char exe_filename[500];
- int succeeded = 0;
- succeeded = ::GetModuleFileName(NULL, exe_filename, sizeof(exe_filename));
- WWASSERT(succeeded);
- StringClass key_string;
- StringClass string;
- StringClass build_string;
- //
- // 11/07/01
- // We now match only on build number.
- //
- string.Format("RENEGADE %u", BuildInfoClass::Get_Build_Number());
- WWDEBUG_SAY(("File id string: %s\n", string));
- key_string += string;
- key_string += " ";
- ExeCRC = CRCEngine()(string, strlen(string));
- //
- // TSS 09/07/01
- // N.B. Do not require scripts to be in sync any more, since they do not run on the client.
- // Furthermore we would have to match the correct scripts target (d/p/r) and
- // also handle the registry flag that forces scriptsd.dll.
- //
- //
- // TSS102401
- // We cannot match on exact strings.tdb because foreign language versions
- // are different files. Instead, match on filename and internal version number.
- //
- //cMiscUtil::Get_File_Id_String("Data\\strings.tdb", string);
- string.Format("strings.tdb %u", TranslateDBClass::Get_Version_Number());
- WWDEBUG_SAY(("File id string: %s\n", string));
- key_string += string;
- key_string += " ";
- StringsCRC = CRCEngine()(string, strlen(string));
- //
- // TSS102401 - we can't match always.dbs either.
- // always.dbs will not match among foreign language version for numerous reasons.
- //
- //
- // Use the crc of the keystring as the key
- //
- ExeKey = CRCEngine()(key_string, strlen(key_string));
- //
- // Include data file crc
- //
- int data_file_crc = Get_Data_Files_CRC();
- ExeKey ^= data_file_crc;
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Onetime_Init(void)
- {
- WWMEMLOG(MEM_NETWORK);
- WWDEBUG_SAY(("cNetwork::Onetime_Init\n"));
- Compute_Exe_Key();
- NetworkReceiver = new CombatNetworkReceiverInstanceClass;
- Set_Receiver(NetworkReceiver);
- CombatManager::Set_Combat_Network_Handler(&NetHandler);
- //Clear_Help_Text();
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Onetime_Shutdown(void)
- {
- WWDEBUG_SAY(("cNetwork::Onetime_Shutdown\n"));
- Set_Receiver(NULL);
- delete NetworkReceiver;
- #if 0
- UINT comp_bytes = cConnection::Get_Total_Compressed_Bytes_Sent();
- UINT uncomp_bytes = cConnection::Get_Total_Uncompressed_Bytes_Sent();
- Debug_Say(("\n"));
- Debug_Say(("TotalCompressedBytesSent = %d\n", comp_bytes));
- Debug_Say(("Without compression = %d\n", uncomp_bytes));
- if (uncomp_bytes > 0) {
- Debug_Say(("Compressed/Uncompressed = %-5.2f\n\n",
- comp_bytes / (float) uncomp_bytes));
- }
- #endif // 0
- #pragma message("(TSS) This packet ref count assert very occasionally fails.")
- //WWASSERT(cPacket::Get_Ref_Count() == 0);
- REF_PTR_RELEASE(VisTable);
- cGameChannelList::Remove_All();//TSS092201 added
- //
- // These are only printed once. So only run one game on a test run.
- //
- cAppPacketStats::Dump_Diagnostics();
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Init_Server(void)
- {
- WWMEMLOG(MEM_NETWORK);
- WWDEBUG_SAY(("cNetwork::Init_Server\n"));
- #ifndef BETACLIENT
- NetworkObjectClass::Set_Is_Server(true);
- PServerStatListGroup = new cMsgStatListGroup;
- WWASSERT(PServerStatListGroup != NULL);
- //PServerStatListGroup->Init(The_Game()->Get_Max_Players(), MESSAGE_COUNT);
- WWASSERT(PTheGameData != NULL);
- PServerStatListGroup->Init(The_Game()->Get_Max_Players(), 1);
- /*
- for (int message_type = 0; message_type < MESSAGE_COUNT; message_type++) {
- char message_trans[200];
- strcpy(message_trans, Message_Type_Translation(message_type));
- PServerStatListGroup->Set_Name(message_type, &message_trans[8]);
- }
- */
- WWASSERT(PServerConnection == NULL);
- PServerConnection = new cConnection;
- WWASSERT(PServerConnection != NULL);
- CombatManager::Set_I_Am_Server(true);
- PServerConnection->Install_Server_Broken_Connection_Handler(Server_Broken_Connection_Handler);
- PServerConnection->Install_Eviction_Handler(Eviction_Handler);
- PServerConnection->Install_Conn_Handler(Connection_Handler);
- PServerConnection->Install_Application_Acceptance_Handler(Application_Acceptance_Handler);
- PServerConnection->Install_Server_Packet_Handler(Server_Packet_Handler);
- //if (IS_SOLOPLAY || GameModeManager::Find("LAN")->Is_Active()) {
- if (IS_SOLOPLAY ||
- (GameModeManager::Find("LAN")->Is_Active() && !cGameSpyAdmin::Is_Gamespy_Game())) {
- ULONG bbo = cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_LANT1);
- WWASSERT(bbo > 0);
- PServerConnection->Set_Bandwidth_Budget_Out(bbo);
- cBandwidthGraph::Set_Scale(200000);
- } else {
- //WWASSERT(GameModeManager::Find("WOL")->Is_Active());
- WWASSERT(cUserOptions::BandwidthBps.Get() > 0);
- unsigned long bw = cBandwidth::Get_Bandwidth_Bps_From_Type((BANDWIDTH_TYPE_ENUM)cUserOptions::Get_Bandwidth_Type());
- /*
- ** Only use a portion of the bandwidth based on how many slave servers there are.
- */
- if (The_Game()->IsDedicated.Get() && !SlaveMaster.Am_I_Slave()) {
- if (cUserOptions::Get_Bandwidth_Type() == BANDWIDTH_AUTO) {
- if (ServerSettingsClass::Get_Master_Bandwidth() == 0 || ServerSettingsClass::Get_Master_Bandwidth() == 0xffffffff) {
- int num_slaves = SlaveMaster.Get_Num_Enabled_Slaves();
- if (num_slaves) {
- bw = bw / (num_slaves+1);
- }
- }
- }
- }
- PServerConnection->Set_Bandwidth_Budget_Out(bw);
- //PServerConnection->Set_Bandwidth_Budget_Out(cUserOptions::BandwidthBps.Get());
- int bw_scale = (cUserOptions::BandwidthBps.Get() * 2) / 10;
- bw_scale = (bw_scale / 1000) * 1000;
- cBandwidthGraph::Set_Scale(bw_scale);
- }
- double max_acceptable_packetloss_pc = 10;
- PServerConnection->Set_Max_Acceptable_Packetloss_Pc(max_acceptable_packetloss_pc);
- BOOL is_flow_control_enabled = !IS_SOLOPLAY;
- PServerConnection->Enable_Flow_Control(is_flow_control_enabled);
- WWASSERT(PTheGameData != NULL);
- PServerConnection->Init_As_Server(
- The_Game()->Get_Port(),
- The_Game()->Get_Max_Players(),
- The_Game()->IsDedicated.Get(),
- ntohl(The_Game()->Get_Ip_Address()));
- //
- // Create teams
- //
- //if (The_Game()->Is_Team_Game()) {
- for (int team_num = 0; team_num < MAX_TEAMS; team_num++) {
- cTeam * p_team = new cTeam;
- p_team->Init(team_num);
- }
- //}
- cSbboManager::Reset();
- cAppPacketStats::Reset();
- #endif // not BETACLIENT
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Cleanup_Server(void)
- {
- WWDEBUG_SAY(("cNetwork::Cleanup_Server\n"));
- if (I_Am_Server()) {
- delete PServerConnection;
- PServerConnection = NULL;
- }
- CombatManager::Set_I_Am_Server(false);
- delete PServerStatListGroup;
- PServerStatListGroup = NULL;
- NetworkObjectClass::Set_Is_Server(false);
- }
- //-----------------------------------------------------------------------------
- enum {
- CHUNKID_PLAYERMANAGER = 9876543,
- };
- //-----------------------------------------------------------------------------
- bool cNetwork::Save(ChunkSaveClass & csave)
- {
- csave.Begin_Chunk(CHUNKID_PLAYERMANAGER);
- cPlayerManager::Save(csave);
- csave.End_Chunk();
- return true;
- }
- //-----------------------------------------------------------------------------
- bool cNetwork::Load(ChunkLoadClass &cload)
- {
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_PLAYERMANAGER:
- //cPlayerManager::Remove_All();
- cPlayerManager::Load(cload);
- break;
- default:
- Debug_Say(( "Unrecognized cNetwork chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Update_Fps(void)
- {
- static DWORD last_time_ms = 0;
- static int frame_count = 0;
- DWORD time_now_ms = TIMEGETTIME();
- // Handle timer resetting.
- if (time_now_ms < last_time_ms) {
- last_time_ms = time_now_ms;
- }
- frame_count++;
- DWORD time_interval = time_now_ms - last_time_ms;
- if (time_interval > 1000) {
- Fps = (int) (frame_count * 1000 / (float) time_interval + 0.5f);
- last_time_ms = time_now_ms;
- frame_count = 0;
- // Needed for release mode too. ST - 1/23/2002 11:02PM
- //#ifdef WWDEBUG
- if (I_Am_Server()) {
- WWASSERT(cServerFps::Get_Instance() != NULL);
- cServerFps::Get_Instance()->Set_Fps(Fps);
- }
- //#endif // WWDEBUG
- if (I_Am_Client() && PClientFps != NULL) {
- PClientFps->Set_Fps(Fps);
- }
- }
- }
- void cNetwork::Connection_Status_Change_Feedback(void)
- {
- static unsigned long _last_print = TIMEGETTIME();
- static bool _last_print_bad = false;
- static unsigned long _print_good_soon = 0;
- unsigned long time = TIMEGETTIME();
- const WCHAR *string = NULL;
- if (LastServerConnectionStateBad) {
- if (_last_print_bad && time - _last_print < 4000) {
- return;
- }
- string = TRANSLATE (IDS_MENU_CONNECTION_INTERRUPTED);
- _last_print_bad = true;
- } else {
- /*
- ** Wait 2 secs after connection restore before printing message.
- */
- if (_last_print_bad && _print_good_soon == 0) {
- _print_good_soon = time;
- return;
- }
- if (!_last_print_bad) {
- return;
- }
- if (time - _print_good_soon < 2000) {
- return;
- }
- string = TRANSLATE (IDS_MENU_CONNECTION_RESTORED);
- _last_print_bad = false;
- }
- _last_print = time;
- WideStringClass widestring(string, true);
- if (CombatManager::Get_Message_Window() != NULL) {
- //
- // Display the message...
- //
- CombatManager::Get_Message_Window ()->Add_Message (widestring);
- }
- //
- // Write it to the logfile
- //
- StringClass temp_string;
- widestring.Convert_To(temp_string);
- WWDEBUG_SAY(("\n***%s\n", temp_string.Peek_Buffer()));
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Update(void)
- {
- WWPROFILE( "cNetwork::Update" );
- WWMEMLOG(MEM_GAMEDATA);
- bool flush_packets = false;
- ThinkCount++;
- //
- // Coding bugs may result in this function being called recursively.
- // Detect and assert!
- //
- static int recursion_level = 0;
- recursion_level++;
- WWASSERT(recursion_level == 1);
- Update_Fps();
- #ifdef WWDEBUG
- //
- // Watch out for unexpected slow frames. They may interrupt networking.
- //
- static DWORD last_time_ms = TIMEGETTIME();
- DWORD time_now_ms = TIMEGETTIME();
- if (time_now_ms - last_time_ms > 2000) {
- Debug_Say(("\n***cNetwork::Update: warning, think # %d was slow (%u ms)\n\n",
- ThinkCount,
- time_now_ms - last_time_ms));
- }
- last_time_ms = time_now_ms;
- #endif // WWDEBUG
- if (I_Am_Server()) {
- if (I_Am_Client()) {
- WWPROFILE( "Client Send" );
- PClientConnection->Service_Send();
- if (PClientConnection->Is_Bad_Connection() != LastServerConnectionStateBad) {
- LastServerConnectionStateBad = PClientConnection->Is_Bad_Connection();
- //Connection_Status_Change_Feedback();
- }
- Connection_Status_Change_Feedback();
- }
- // { WWPROFILE("GameSpy_QnR");
- // GameSpyQnR.Think();
- // }
- WWPROFILE( "Server Read" );
- PServerConnection->Service_Read();
- if (!g_is_loading) {
- WWPROFILE( "Shared CS Think" );
- Shared_Client_And_Server_Think();
- }
- if (I_Am_Client() && !g_is_loading) {
- WWPROFILE( "Client_Think" );
- if (Client_Think()) {
- flush_packets = true;
- }
- }
- if (!g_is_loading) {
- WWPROFILE( "Server_Think" );
- if (Server_Think()) {
- flush_packets = true;
- } else {
- // Server only sends packets in response to server think, not client think.
- flush_packets = false;
- }
- }
- {
- WWPROFILE( "Server Send" );
- PServerConnection->Service_Send();
- }
- if (I_Am_Client()) {
- WWPROFILE( "Client Read" );
- PClientConnection->Service_Read();
- }
- } else if (I_Am_Client()) {
- {
- WWPROFILE( "Client Read" );
- PClientConnection->Service_Read();
- }
- if (PClientConnection->Is_Bad_Connection() != LastServerConnectionStateBad) {
- LastServerConnectionStateBad = PClientConnection->Is_Bad_Connection();
- Connection_Status_Change_Feedback();
- }
- if (!g_is_loading) {
- WWPROFILE( "Shared CS Think" );
- Shared_Client_And_Server_Think();
- }
- if (!g_is_loading) {
- WWPROFILE( "Client_Think" );
- if (Client_Think()) {
- flush_packets = true;
- }
- }
- {
- WWPROFILE( "Client Send" );
- if (PClientConnection != NULL) {
- PClientConnection->Service_Send();
- }
- }
- }
- DEMO_SECURITY_CHECK;
- NetworkObjectMgrClass::Delete_Pending();
- if (flush_packets) {
- PacketManager.Flush(true);
- }
- recursion_level--;
- WWASSERT(recursion_level == 0);
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Client_Send_Packet(cPacket & packet, int mode)
- {
- #ifndef FREEDEDICATEDSERVER
- WWASSERT(I_Am_Client());
- if (cNetwork::PClientConnection->Is_Established()) {
- PClientConnection->Send_Packet_To_Individual(packet, 0, mode);
- /*
- BYTE message_type = packet.Peek_Message_Type();
- PClientStatList->Increment_Num_Msg_Sent(message_type);
- PClientStatList->Increment_Num_Byte_Sent(message_type, packet.Get_Compressed_Size_Bytes());
- */
- } else {
- WWDEBUG_SAY(("cNetwork::Client_Send_Packet: warning: Connection not yet established.\n"));
- //TSS2001 XXX DIE;
- }
- #endif // !FREEDEDICATEDSERVER
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Server_Send_Packet(cPacket & packet, int mode, int recipient)
- {
- #ifndef BETACLIENT
- WWASSERT(I_Am_Server());
- WWASSERT(PServerConnection->Is_Established());
- if (recipient == ALL) {
- //
- // We cannot just send to all rhosts because that includes anyone
- // browsing the server settings, whereas here we wish to send to the
- // ingame players.
- //
- //PServerConnection->Send_Packet_To_All(*p_packet, mode);
- SLNode<cPlayer> * objnode;
- for (objnode = cPlayerManager::Get_Player_Object_List()->Head();
- objnode; objnode = objnode->Next()) {
- cPlayer * p_player = objnode->Data();
- WWASSERT(p_player != NULL);
- //if (p_player->Is_Human()) {
- if (p_player->Get_Is_Active().Is_True() &&
- p_player->Is_Human() &&
- p_player->Get_Is_In_Game().Is_True()) {
- int client_id = p_player->Get_Id();
- PServerConnection->Send_Packet_To_Individual(
- packet, client_id, mode);
- /*
- BYTE message_type = packet.Peek_Message_Type();
- PServerStatListGroup->Increment_Num_Msg_Sent(client_id - 1, message_type);
- PServerStatListGroup->Increment_Num_Byte_Sent(client_id - 1, message_type, packet.Get_Compressed_Size_Bytes());
- */
- }
- }
- } else {
- PServerConnection->Send_Packet_To_Individual(packet, recipient, mode);
- /*
- BYTE message_type = packet.Peek_Message_Type();
- PServerStatListGroup->Increment_Num_Msg_Sent(recipient - 1, message_type);
- PServerStatListGroup->Increment_Num_Byte_Sent(recipient - 1, message_type, packet.Get_Compressed_Size_Bytes());
- */
- }
- #endif // not BETACLIENT
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Server_Send_Packet_To_All_Connected(cPacket & packet, int mode)
- {
- #ifndef BETACLIENT
- //
- // Traverse the rhost list here in the application level, so that
- // we can record message stats.
- //
- WWASSERT(I_Am_Server());
- WWASSERT(PServerConnection->Is_Established());
- //BYTE message_type = packet.Peek_Message_Type();
- for (int rhost_id = PServerConnection->Get_Min_RHost(); rhost_id <= PServerConnection->Get_Max_RHost(); rhost_id++) {
- if (Get_Server_Rhost(rhost_id) != NULL) {
- PServerConnection->Send_Packet_To_Individual(packet, rhost_id, mode);
- /*
- PServerStatListGroup->Increment_Num_Msg_Sent(rhost_id - 1, message_type);
- PServerStatListGroup->Increment_Num_Byte_Sent(rhost_id - 1, message_type, packet.Get_Compressed_Size_Bytes());
- */
- }
- }
- #endif // not BETACLIENT
- }
- //-----------------------------------------------------------------------------
- LPCSTR cNetwork::Get_Client_Enumeration_String(void)
- {
- WWASSERT(I_Am_Server());
- WWASSERT(PServerConnection->Is_Established());
- char temp_str[10];
- strcpy(ClientEnumerationString, "");
- for (int rhost_id = PServerConnection->Get_Min_RHost(); rhost_id <= PServerConnection->Get_Max_RHost(); rhost_id++) {
- if (Get_Server_Rhost(rhost_id) != NULL) {
- strcat(ClientEnumerationString, itoa(rhost_id, temp_str, 10));
- strcat(ClientEnumerationString, " ");
- }
- if (strlen(ClientEnumerationString) > 20) {
- strcpy(ClientEnumerationString, "many");
- break;
- }
- }
- return ClientEnumerationString;
- }
- //-----------------------------------------------------------------------------
- cRemoteHost * cNetwork::Get_Server_Rhost(int client_id)
- {
- WWASSERT(I_Am_Server());
- return PServerConnection->Get_Remote_Host(client_id);
- }
- //-----------------------------------------------------------------------------
- cRemoteHost * cNetwork::Get_Client_Rhost(void)
- {
- WWASSERT(I_Am_Client());
- return PClientConnection->Get_Remote_Host(SERVER_RHOST_ID);
- }
- //-----------------------------------------------------------------------------
- float cNetwork::Get_Server_Rhost_Threshold_Priority(int client_id)
- {
- WWASSERT(I_Am_Server());
- WWASSERT(Get_Server_Rhost(client_id) != NULL);
- return Get_Server_Rhost(client_id)->Get_Threshold_Priority();
- }
- //-----------------------------------------------------------------------------
- float cNetwork::Get_Client_Rhost_Threshold_Priority(void)
- {
- WWASSERT(I_Am_Client());
- WWASSERT(Get_Client_Rhost() != NULL);
- return Get_Client_Rhost()->Get_Threshold_Priority();
- }
- //-----------------------------------------------------------------------------
- int cNetwork::Get_My_Id(void)
- {
- WWASSERT(I_Am_Client());
- return PClientConnection->Get_Local_Id();
- }
- //-----------------------------------------------------------------------------
- LPCSTR cNetwork::Get_Client_String(int recipient)
- {
- //WWASSERT(I_Am_Server());
- if (recipient > 0) {
- WWASSERT(PServerConnection->Is_Established());
- if (recipient == ALL) {
- sprintf(ClientString, "all %d clients (%s)",
- PServerConnection->Get_Num_RHosts(),
- Get_Client_Enumeration_String());
- } else {
- sprintf(ClientString, "client %d", recipient);
- }
- } else {
- sprintf(ClientString, "server");
- }
- //
- // Note: This WWASSERT would catch the overwrite AFTER it has happened...
- //
- WWASSERT(strlen(ClientString) < sizeof(ClientString));
- return(ClientString);
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Server_Broken_Connection_Handler(int broken_rhost_id)
- {
- WWASSERT(broken_rhost_id >= 0);
- //
- // The net lib calls this when a reliable packet fails after
- // many attempts. The connection data has already been destroyed.
- //
- WWDEBUG_SAY(("\n***Connection to client %d broken \n\n", broken_rhost_id));
- WideStringClass widestring;
- widestring.Format(
- L"%s %d\n",
- TRANSLATION(IDS_MP_CONNECTION_TO_CLIENT_BROKEN),
- broken_rhost_id);
- WWASSERT(CombatManager::Get_Message_Window () != NULL);
- //Get_Text_Display()->Print_System(widestring);
- //
- // Display the message...
- //
- CombatManager::Get_Message_Window ()->Add_Message (widestring);
- Vector3 color(1.0f, 1.0f, 0.0f);
- ConsoleBox.Add_Message(&widestring, &color);
- WWAudioClass::Get_Instance()->Create_Instant_Sound("Broken_Connection", Matrix3D(1));
- cNetwork::Cleanup_After_Client(broken_rhost_id);
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Client_Broken_Connection_Handler(void)
- {
- //
- // The net lib calls this when a reliable packet fails after
- // many attempts. The connection data has already been destroyed.
- //
- WWASSERT(Get_Text_Display() != NULL);
- WWASSERT(PClientConnection != NULL);
- /**/
- if (PClientConnection->Have_Id()) {
- //cHelpText::Set(TRANSLATION(IDS_MP_CONNECTION_TO_SERVER_BROKEN));
- DlgMsgBox::DoDialog(L"", TRANSLATION(IDS_MP_CONNECTION_TO_SERVER_BROKEN));
- } else {
- //cHelpText::Set(TRANSLATION(IDS_MP_UNABLE_CONNECT_TO_SERVER));
- }
- //TSS090401
- //
- // The client needs to quit back to the game list
- //
- extern bool g_client_quit;
- g_client_quit = true;
- //WWAudioClass::Get_Instance()->Create_Instant_Sound("Broken_Connection", Matrix3D(1));
- /**/
- /*
- WWDEBUG_SAY(("Connection to server broken.\n"));
- if (PClientConnection->Have_Id()) {
- DlgMPConnectionRefused::DoDialog(TRANSLATION(IDS_MP_CONNECTION_TO_SERVER_BROKEN), true);
- } else {
- extern bool g_client_quit;
- g_client_quit = true;
- }
- */
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Process_Eviction_Sc(cPacket & packet)
- {
- WWDEBUG_SAY(("cNetwork::Process_Eviction_Sc\n"));
- WWAudioClass::Get_Instance()->Create_Instant_Sound("Evicted_By_Server", Matrix3D(1));
- WWASSERT(I_Am_Client());
- UINT min_bps;
- packet.Get(min_bps);//naughty... type conversion
- float max_packetloss;
- packet.Get(max_packetloss);
- //UINT sustainable_bps = (UINT) packet.Get();
- WWDEBUG_SAY(("\n* You were evicted from the server for inadequate bandwidth performance.\n"
- "* This server requires packetloss of less than %5.2f %%, and a minimum\n"
- "* sustainable bandwidth of %d bps.\n", max_packetloss, min_bps));
- //
- // At this stage, just signal to close down. This is
- // a convenience during development
- //
- DIE;
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Eviction_Handler(int evicted_rhost_id)
- {
- WWMEMLOG(MEM_NETWORK);
- WWDEBUG_SAY(("cNetwork::Eviction_Handler\n"));
- WWASSERT(evicted_rhost_id >= 0);
- WWASSERT(I_Am_Server());
- //Send_Eviction_Sc(evicted_rhost_id);
- cEvictionEvent * p_event = new cEvictionEvent;
- p_event->Init(evicted_rhost_id, EVICTION_POOR_BANDWIDTH);
- cNetwork::Flush();
- //WWAudioClass::Get_Instance()->Create_Instant_Sound("Broken_Connection", Matrix3D(1));
- }
- //-----------------------------------------------------------------------------
- bool cNetwork::I_Am_God(void)
- {
- bool i_am_god = false;
- if (I_Am_Client()) {
- cPlayer * p_player = cPlayerManager::Find_Player(Get_My_Id());
- if (p_player != NULL && p_player->Invulnerable.Is_True()) {
- i_am_god = true;
- }
- }
- return i_am_god;
- }
- //-----------------------------------------------------------------------------
- cPlayer * cNetwork::Get_My_Player_Object(void)
- {
- cPlayer * p_me = NULL;
- if (I_Am_Client()) {
- p_me = cPlayerManager::Find_Player(Get_My_Id());
- }
- return p_me;
- }
- //-----------------------------------------------------------------------------
- int cNetwork::Get_My_Team_Number(void)
- {
- cPlayer * p_me = Get_My_Player_Object();
- WWASSERT(p_me != NULL);
- return p_me->Get_Player_Type();
- }
- //-----------------------------------------------------------------------------
- Vector3 cNetwork::Get_My_Color(void)
- {
- cPlayer * p_me = cPlayerManager::Find_Player(Get_My_Id());
- WWASSERT(p_me != NULL);
- return p_me->Get_Color();
- }
- //-----------------------------------------------------------------------------
- int cNetwork::Show_Welcome_Message(WideStringClass & name)
- {
- int show = false;
- if (!IS_MISSION && (name == cNetInterface::Get_Nickname())) {
- show = true;
- }
- return show;
- }
- //---------------------------------------------------------------------------
- float cNetwork::Get_Distance_Priority(Vector3 & pos1, Vector3 & pos2)
- {
- Vector3 gap = pos2 - pos1;
- float d = gap.Length();
- WWASSERT(PTheGameData != NULL);
- float max_distance = The_Game()->Get_Maximum_World_Distance();
- WWASSERT(max_distance > 0);
- float range1 = max_distance / 25.0f;
- float range2 = max_distance / 5.0f;
- float range3 = max_distance + 1;
- float priority;
- if (d < range1) {
- priority = (float) ((range1 - d) / range1 * 0.499 + 0.50);
- } else if (d < range2) {
- priority = (float) ((range2 - d) / (range2 - range1) * 0.40 + 0.10);
- } else if (d < range3) {
- priority = (float) ((range3 - d) / (range3 - range2) * 0.10 + 0.00);
- } else {
- //WWASSERT(0);
- static bool already_warned = false;
- if (!already_warned) {
- Debug_Say(("Someone went outside the world box! (possibly numerous times)\n"));
- already_warned = true;
- }
- priority = 0;
- }
- WWASSERT(priority > -WWMATH_EPSILON && priority < 1 + WWMATH_EPSILON);
- return(priority);
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Shell_Command(LPCSTR command)
- {
- WWASSERT(command != NULL);
- HINSTANCE hinst = ShellExecute(NULL, NULL, command, NULL, "", SW_SHOW);
- if ((int) hinst <= 32) {
- WWDEBUG_SAY(("Error: ShellExecute failed.\n"));
- }
- }
- //-----------------------------------------------------------------------------
- REFUSAL_CODE cNetwork::Application_Acceptance_Handler(cPacket & packet)
- {
- #ifndef BETACLIENT
- WWDEBUG_SAY(("cNetwork::Application_Acceptance_Handler\n"));
- WWASSERT(I_Am_Server());
- //
- // Get player name
- // This is not supposed to be empty, but if for whatever reason it it, we should
- // just refuse, rather than crash.
- //
- WideStringClass player_name(0, true);
- //packet.Get_Wide_Terminated_String(player_name.Get_Buffer(256), 256);
- packet.Get_Wide_Terminated_String(player_name.Get_Buffer(256), 256, true);
- if (player_name.Get_Length() == 0) {
- return REFUSAL_VERSION_MISMATCH;
- }
- // Get the clients password
- WideStringClass password(0, true);
- packet.Get_Wide_Terminated_String(password.Get_Buffer(256), 256, true);
- // Get clients exe version
- int client_exe_key = packet.Get(client_exe_key);
- // Make sure the clients password matches the games password.
- WWASSERT(PTheGameData != NULL);
- if (The_Game()->IsPassworded.Is_True() && password.Compare(The_Game()->Get_Password()) != 0) {
- return REFUSAL_BAD_PASSWORD;
- }
- // Make sure the exe versions match
- if (client_exe_key != cNetwork::Get_Exe_Key()) {
- return REFUSAL_VERSION_MISMATCH;
- }
- // Make sure we haven't exceeded our max player limit
- if (cPlayerManager::Count() >= The_Game()->Get_Max_Players()) {
- return REFUSAL_GAME_FULL;
- }
- //
- // TSS100501
- //
- // Make sure the player is not already in the game
- //GAMESPY
- //if (cPlayerManager::Find_Player(player_name)) {
- if (!cGameSpyAdmin::Is_Gamespy_Game() &&
- cPlayerManager::Find_Player(player_name)) {
- return REFUSAL_PLAYER_EXISTS;
- }
- #endif // not BETACLIENT
- return REFUSAL_CLIENT_ACCEPTED;
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Connection_Handler(int new_rhost_id)
- {
- WWMEMLOG(MEM_NETWORK);
- #ifndef BETACLIENT
- WWDEBUG_SAY(("cNetwork::Connection_Handler\n"));
- WWASSERT(new_rhost_id >= 0);
- WWASSERT(I_Am_Server());
- WWASSERT(Receiver != NULL);
- /*
- //
- // Tell the new guy about all the teams. He needs this early in case he
- // needs to choose a team
- //
- SLNode<cTeam> * team_node;
- cTeam * p_team;
- for (team_node = cTeamManager::Get_Team_Object_List()->Head(); team_node; team_node = team_node->Next()) {
- p_team = team_node->Data();
- WWASSERT(p_team != NULL);
- Send_Server_New_Team(p_team, new_rhost_id);
- }
- */
- //TSS2001 - normal update mechanism won't catch this in time.
- //
- // Tell the new guy about all the teams. He needs this early in case he
- // needs to choose a team
- //
- if (!cNetwork::I_Am_Client() || new_rhost_id != cNetwork::Get_My_Id()) {
- for (
- SLNode<cTeam> * team_node = cTeamManager::Get_Team_Object_List()->Head();
- team_node;
- team_node = team_node->Next()) {
- cTeam * p_team = team_node->Data();
- WWASSERT(p_team != NULL);
- Send_Object_Update(p_team, new_rhost_id);
- }
- }
- //
- // Next, send info about any remaining game options. This is only those
- // options that he doesn't pick up from the channel listing.
- //
- //Send_Server_Game_Options(new_rhost_id);
- cGameOptionsEvent * p_event = new cGameOptionsEvent;
- p_event->Init(new_rhost_id);
- Send_Object_Update(p_event, new_rhost_id);
- #endif // not BETACLIENT
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Set_Desired_Frame_Sleep_Ms(int b)
- {
- WWASSERT(b >= 0);
- #ifdef WWDEBUG
- cDevOptions::DesiredFrameSleepMs.Set(b);
- #endif //WWDEBUG
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Set_Simulated_Packet_Loss_Pc(int b)
- {
- WWASSERT(b >= 0);
- if (PClientConnection != NULL) {
- PClientConnection->Set_Packet_Loss(b);
- }
- if (PServerConnection != NULL) {
- PServerConnection->Set_Packet_Loss(b);
- }
- //SimulatedPacketLossPc = b;
- #ifdef WWDEBUG
- cDevOptions::SimulatedPacketLossPc.Set(b);
- #endif //WWDEBUG
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Set_Simulated_Packet_Duplication_Pc(int b)
- {
- WWASSERT(b >= 0);
- if (PClientConnection != NULL) {
- PClientConnection->Set_Packet_Duplication(b);
- }
- if (PServerConnection != NULL) {
- PServerConnection->Set_Packet_Duplication(b);
- }
- //SimulatedPacketDuplicationPc = b;
- #ifdef WWDEBUG
- cDevOptions::SimulatedPacketDuplicationPc.Set(b);
- #endif
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Set_Simulated_Latency_Range_Ms(int lower, int upper)
- {
- WWASSERT(lower >= 0);
- WWASSERT(upper >= 0);
- WWASSERT(lower <= upper);
- if (PClientConnection != NULL) {
- PClientConnection->Set_Packet_Latency_Range(lower, upper);
- }
- if (PServerConnection != NULL) {
- PServerConnection->Set_Packet_Latency_Range(lower, upper);
- }
- //SimulatedLatencyRangeMsLower = lower;
- //SimulatedLatencyRangeMsUpper = upper;
- #ifdef WWDEBUG
- cDevOptions::SimulatedLatencyRangeMsLower.Set(lower);
- cDevOptions::SimulatedLatencyRangeMsUpper.Set(upper);
- #endif
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Set_Spam_Count(int spam_count)
- {
- WWASSERT(spam_count >= 0);
- //SpamCount = spam_count;
- #ifdef WWDEBUG
- cDevOptions::SpamCount.Set(spam_count);
- #endif
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Get_Simulated_Latency_Range_Ms(int & lower, int & upper)
- {
- #ifdef WWDEBUG
- lower = cDevOptions::SimulatedLatencyRangeMsLower.Get();
- upper = cDevOptions::SimulatedLatencyRangeMsUpper.Get();
- #endif
- }
- //-----------------------------------------------------------------------------
- void
- cNetwork::Flush(void)
- {
- WWDEBUG_SAY(("cNetwork::Flush\n"));
- const bool is_urgent = true;
- //if (GameModeManager::Find ("Combat")->Is_Active() && Receiver != NULL) {
- if (Receiver != NULL) {
- if (I_Am_Server()) {
- Receiver->Server_Update_Dynamic_Objects(is_urgent);
- }
- if (I_Am_Client()) {
- Receiver->Client_Update_Dynamic_Objects(is_urgent);
- }
- }
- if (I_Am_Server()) {
- PServerConnection->Service_Send(is_urgent);
- }
- if (I_Am_Client()) {
- PClientConnection->Service_Send(is_urgent);
- }
- PacketManager.Flush(true);
- }
- void cNetwork::SwitchTeam(int newTeam)
- {
- cPlayer* player = cPlayerManager::Find_Player(Get_My_Id());
- if (player) {
- int team = player->Get_Player_Type();
- if (newTeam != team) {
- cChangeTeamEvent* event = new cChangeTeamEvent;
- event->Init();
- }
- }
- }
- //-----------------------------------------------------------------------------
- void cNetwork::Enable_Waiting_Players(void)
- {
- SLNode<cPlayer> * objnode;
- for (objnode = cPlayerManager::Get_Player_Object_List()->Head() ; objnode != NULL ; objnode = objnode->Next()) {
- cPlayer * p_player = objnode->Data();
- WWASSERT(p_player != NULL);
- if (p_player->Is_Human() && p_player->Get_Is_Waiting_For_Intermission().Is_True()) {
- p_player->Set_Is_In_Game(true);
- p_player->Set_Is_Waiting_For_Intermission(false);
- if (cNetwork::PServerConnection) {
- cNetwork::PServerConnection->Set_Rhost_Is_In_Game(p_player->Get_Id(), true);
- }
- cGameDataUpdateEvent * p_event = new cGameDataUpdateEvent();
- p_event->Init(p_player->Get_Id());
- }
- }
- }
|