mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-15 23:21:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
343
Code/Commando/AnnounceEvent.cpp
Normal file
343
Code/Commando/AnnounceEvent.cpp
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/AnnounceEvent.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Client announcement
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 9 $
|
||||
* $Modtime: 1/12/02 9:33p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "announceevent.h"
|
||||
#include "networkobjectfactory.h"
|
||||
#include "apppackettypes.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "cnetwork.h"
|
||||
#include "gamemode.h"
|
||||
#include "playertype.h"
|
||||
#include "translateobj.h"
|
||||
#include "translatedb.h"
|
||||
#include "wwaudio.h"
|
||||
#include "messagewindow.h"
|
||||
#include <wwlib\widestring.h>
|
||||
#include "cncmodesettings.h"
|
||||
#include "floodprotectionmgr.h"
|
||||
|
||||
|
||||
DECLARE_NETWORKOBJECT_FACTORY(CSAnnouncement, NETCLASSID_CSANNOUNCEMENT);
|
||||
|
||||
|
||||
CSAnnouncement::CSAnnouncement(void) :
|
||||
mFromID(-1),
|
||||
mToID(-1),
|
||||
mAnnouncementID(0),
|
||||
mRadioCmdID(-1),
|
||||
mType(ANNOUNCEMENT_PUBLIC)
|
||||
{
|
||||
Set_App_Packet_Type(APPPACKETTYPE_CSANNOUNCEMENT);
|
||||
}
|
||||
|
||||
|
||||
CSAnnouncement::~CSAnnouncement()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CSAnnouncement::Init(int to_id, int announcementID, AnnouncementEnum type, int radio_cmd_id)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
mToID = to_id;
|
||||
mFromID = cNetwork::Get_My_Id();
|
||||
mAnnouncementID = announcementID;
|
||||
mRadioCmdID = radio_cmd_id;
|
||||
mType = type;
|
||||
|
||||
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
|
||||
|
||||
//
|
||||
// Is this user "flooding" the server with text?
|
||||
//
|
||||
if (FloodProtectionMgrClass::Detect_Flooding (L"") == false)
|
||||
{
|
||||
|
||||
if (cNetwork::I_Am_Server())
|
||||
{
|
||||
Act();
|
||||
}
|
||||
else
|
||||
{
|
||||
Set_Object_Dirty_Bit(0, BIT_CREATION, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Flooding detected -- don't send the message
|
||||
//
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSAnnouncement::Act(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
if (GameModeManager::Find("Combat")->Is_Active())
|
||||
{
|
||||
SCAnnouncement* announce = new SCAnnouncement;
|
||||
announce->Init(mToID, mFromID, mAnnouncementID, mType, mRadioCmdID);
|
||||
}
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
|
||||
void CSAnnouncement::Export_Creation(BitStreamClass& packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
cNetEvent::Export_Creation(packet);
|
||||
packet.Add(mToID);
|
||||
packet.Add(mFromID);
|
||||
packet.Add(mAnnouncementID);
|
||||
packet.Add(mRadioCmdID);
|
||||
packet.Add((BYTE)mType);
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
|
||||
void CSAnnouncement::Import_Creation(BitStreamClass& packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cNetEvent::Import_Creation(packet);
|
||||
packet.Get(mToID);
|
||||
packet.Get(mFromID);
|
||||
packet.Get(mAnnouncementID);
|
||||
packet.Get(mRadioCmdID);
|
||||
|
||||
BYTE type = 0;
|
||||
packet.Get(type);
|
||||
mType = (AnnouncementEnum)type;
|
||||
|
||||
Act();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DECLARE_NETWORKOBJECT_FACTORY(SCAnnouncement, NETCLASSID_SCANNOUNCEMENT);
|
||||
|
||||
|
||||
SCAnnouncement::SCAnnouncement(void) :
|
||||
mToID(-1),
|
||||
mFromID(-1),
|
||||
mAnnouncementID(0),
|
||||
mRadioCmdID(-1),
|
||||
mType(ANNOUNCEMENT_PUBLIC)
|
||||
{
|
||||
Set_App_Packet_Type(APPPACKETTYPE_SCANNOUNCEMENT);
|
||||
}
|
||||
|
||||
|
||||
SCAnnouncement::~SCAnnouncement()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SCAnnouncement::Init(int to_id, int from_id, int announcementID, AnnouncementEnum type, int radio_cmd_id)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
mToID = to_id;
|
||||
mFromID = from_id;
|
||||
mAnnouncementID = announcementID;
|
||||
mRadioCmdID = radio_cmd_id;
|
||||
mType = type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ANNOUNCEMENT_PUBLIC:
|
||||
Set_Object_Dirty_Bit(BIT_CREATION, true);
|
||||
break;
|
||||
|
||||
case ANNOUNCEMENT_TEAM:
|
||||
if (mToID >= 0)
|
||||
{
|
||||
Set_Dirty_Bit_For_Team(BIT_CREATION, mToID);
|
||||
}
|
||||
break;
|
||||
|
||||
case ANNOUNCEMENT_PRIVATE:
|
||||
if (mToID >= 0)
|
||||
{
|
||||
Set_Object_Dirty_Bit(mToID, BIT_CREATION, true);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Explicitly show the message on the server if he is among the recipients.
|
||||
if (cNetwork::I_Am_Client() && Is_Client_Dirty(cNetwork::Get_My_Id()))
|
||||
{
|
||||
Act();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCAnnouncement::Set_Dirty_Bit_For_Team(DIRTY_BIT bit, int team)
|
||||
{
|
||||
WWASSERT(team == PLAYERTYPE_NOD || team == PLAYERTYPE_GDI);
|
||||
|
||||
SList<cPlayer>* playerList = cPlayerManager::Get_Player_Object_List();
|
||||
|
||||
if (playerList)
|
||||
{
|
||||
SLNode<cPlayer>* playerNode = playerList->Head();
|
||||
|
||||
while (playerNode)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player && player->Is_Active() && (player->Get_Player_Type() == team))
|
||||
{
|
||||
Set_Object_Dirty_Bit(player->Get_Id(), bit, true);
|
||||
}
|
||||
|
||||
playerNode = playerNode->Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCAnnouncement::Act(void)
|
||||
{
|
||||
if (mAnnouncementID > 0)
|
||||
{
|
||||
// Lookup the translation object from the strings database
|
||||
TDBObjClass* translateObj = TranslateDBClass::Find_Object(mAnnouncementID);
|
||||
|
||||
cPlayer* sender = cPlayerManager::Find_Player(mFromID);
|
||||
|
||||
//
|
||||
// Display the emot icon as ncessary
|
||||
//
|
||||
if (sender != NULL && mRadioCmdID != -1)
|
||||
{
|
||||
|
||||
//
|
||||
// Dig the soldier game object out from the player data
|
||||
//
|
||||
SmartGameObj *game_obj = sender->Get_GameObj();
|
||||
if (game_obj != NULL && game_obj->As_SoldierGameObj () != NULL)
|
||||
{
|
||||
CNCModeSettingsDef* cncDef = CNCModeSettingsDef::Get_Instance();
|
||||
if (cncDef != NULL)
|
||||
{
|
||||
//
|
||||
// Display the emot icon
|
||||
//
|
||||
const float EMOT_ICON_DURATION = 2.0F;
|
||||
const char *emot_icon_name = cncDef->Get_Radio_Command_Emot_Icon (mRadioCmdID);
|
||||
game_obj->As_SoldierGameObj ()->Set_Emot_Icon (emot_icon_name, EMOT_ICON_DURATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (translateObj)
|
||||
{
|
||||
// Display the text on the screen
|
||||
const WCHAR* string = translateObj->Get_String();
|
||||
|
||||
if (string)
|
||||
{
|
||||
|
||||
if (sender)
|
||||
{
|
||||
WideStringClass message(0, true);
|
||||
message.Format(L"%s: %s", sender->Get_Name(), string);
|
||||
CombatManager::Get_Message_Window()->Add_Message(message, sender->Get_Color());
|
||||
}
|
||||
else
|
||||
{
|
||||
CombatManager::Get_Message_Window()->Add_Message(string, Vector3(1,1,1));
|
||||
}
|
||||
}
|
||||
|
||||
// Play the sound effect
|
||||
int soundID = (int)translateObj->Get_Sound_ID();
|
||||
|
||||
if (soundID > 0)
|
||||
{
|
||||
WWAudioClass::Get_Instance()->Create_Instant_Sound(soundID, Matrix3D(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SCAnnouncement::Export_Creation(BitStreamClass& packet)
|
||||
{
|
||||
cNetEvent::Export_Creation(packet);
|
||||
packet.Add(mToID);
|
||||
packet.Add(mFromID);
|
||||
packet.Add(mAnnouncementID);
|
||||
packet.Add(mRadioCmdID);
|
||||
packet.Add((BYTE)mType);
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SCAnnouncement::Import_Creation(BitStreamClass& packet)
|
||||
{
|
||||
cNetEvent::Import_Creation(packet);
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
packet.Get(mToID);
|
||||
packet.Get(mFromID);
|
||||
packet.Get(mAnnouncementID);
|
||||
packet.Add(mRadioCmdID);
|
||||
|
||||
BYTE type = 0;
|
||||
packet.Get(type);
|
||||
mType = (AnnouncementEnum)type;
|
||||
|
||||
Act();
|
||||
}
|
||||
108
Code/Commando/AnnounceEvent.h
Normal file
108
Code/Commando/AnnounceEvent.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/commando/AnnounceEvent.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Client announcement
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Patrick $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 5 $
|
||||
* $Modtime: 11/28/01 4:22p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __ANNOUNCEEVENT_H__
|
||||
#define __ANNOUNCEEVENT_H__
|
||||
|
||||
#include "NetEvent.h"
|
||||
#include "NetClassIDs.h"
|
||||
|
||||
enum AnnouncementEnum
|
||||
{
|
||||
ANNOUNCEMENT_PUBLIC = 0,
|
||||
ANNOUNCEMENT_TEAM,
|
||||
ANNOUNCEMENT_PRIVATE,
|
||||
};
|
||||
|
||||
class CSAnnouncement :
|
||||
public cNetEvent
|
||||
{
|
||||
public:
|
||||
CSAnnouncement();
|
||||
virtual ~CSAnnouncement();
|
||||
|
||||
void Init(int to_id, int announcementID, AnnouncementEnum type, int radio_cmd_id = -1);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass& packet);
|
||||
virtual void Import_Creation(BitStreamClass& packet);
|
||||
|
||||
virtual uint32 Get_Network_Class_ID(void) const
|
||||
{return NETCLASSID_CSANNOUNCEMENT;}
|
||||
|
||||
protected:
|
||||
CSAnnouncement(const CSAnnouncement&);
|
||||
const CSAnnouncement& operator=(const CSAnnouncement&);
|
||||
|
||||
virtual void Act(void);
|
||||
|
||||
int mToID;
|
||||
int mFromID;
|
||||
int mAnnouncementID;
|
||||
int mRadioCmdID;
|
||||
AnnouncementEnum mType;
|
||||
};
|
||||
|
||||
|
||||
class SCAnnouncement :
|
||||
public cNetEvent
|
||||
{
|
||||
public:
|
||||
SCAnnouncement();
|
||||
virtual ~SCAnnouncement();
|
||||
|
||||
void Init(int to_id, int from_id, int announcementID, AnnouncementEnum type, int radio_cmd_id = -1);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass& packet);
|
||||
virtual void Import_Creation(BitStreamClass& packet);
|
||||
|
||||
virtual uint32 Get_Network_Class_ID(void) const
|
||||
{return NETCLASSID_SCANNOUNCEMENT;}
|
||||
|
||||
protected:
|
||||
SCAnnouncement(const SCAnnouncement&);
|
||||
const SCAnnouncement& operator=(const SCAnnouncement&);
|
||||
|
||||
virtual void Act(void);
|
||||
void Set_Dirty_Bit_For_Team(DIRTY_BIT bit, int team);
|
||||
|
||||
int mToID;
|
||||
int mFromID;
|
||||
int mAnnouncementID;
|
||||
int mRadioCmdID;
|
||||
AnnouncementEnum mType;
|
||||
};
|
||||
|
||||
#endif // __ANNOUNCEEVENT_H__
|
||||
968
Code/Commando/AutoStart.cpp
Normal file
968
Code/Commando/AutoStart.cpp
Normal file
@@ -0,0 +1,968 @@
|
||||
/*
|
||||
** 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/AutoStart.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 8/13/02 4:58p $*
|
||||
* *
|
||||
* $Revision:: 24 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "always.h"
|
||||
#include "autostart.h"
|
||||
//#include "dlgmplangametype.h"
|
||||
#include "gameinitmgr.h"
|
||||
#include "registry.h"
|
||||
#include "_globals.h"
|
||||
#include "gamedata.h"
|
||||
#include "gameinitmgr.h"
|
||||
#include "campaign.h"
|
||||
#include "win.h"
|
||||
#include "except.h"
|
||||
#include "listctrl.h"
|
||||
#include "dlgwolautostart.h"
|
||||
#include "dlgdownload.h"
|
||||
#include "translatedb.h"
|
||||
#include "string_ids.h"
|
||||
#include "slavemaster.h"
|
||||
#include "gamesideservercontrol.h"
|
||||
#include "gamedata.h"
|
||||
#include "nat.h"
|
||||
#include "consolemode.h"
|
||||
#include "wwonline\wolserver.h"
|
||||
#include "notify.h"
|
||||
#include "serversettings.h"
|
||||
#include "wolbuddymgr.h"
|
||||
#include "bandwidthcheck.h"
|
||||
#include "bandwidth.h"
|
||||
#include "gamespyadmin.h"
|
||||
#include "specialbuilds.h"
|
||||
|
||||
/*
|
||||
** Single instance of restart class.
|
||||
*/
|
||||
AutoRestartClass AutoRestart;
|
||||
|
||||
/*
|
||||
** Registry entries.
|
||||
*/
|
||||
const char *AutoRestartClass::REG_VALUE_AUTO_RESTART_FLAG = "AutoRestartFlag";
|
||||
const char *AutoRestartClass::REG_VALUE_AUTO_RESTART_TYPE = "AutoRestartType";
|
||||
static const char *WINDOWS_SUB_KEY_RUN_ONCE = "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\";
|
||||
static const char *WINDOWS_SUB_KEY_RUN_ONCE_APP = "Renegade";
|
||||
|
||||
/*
|
||||
** Stupid extern for main loop exit.
|
||||
*/
|
||||
extern void Stop_Main_Loop (int exitCode);
|
||||
|
||||
|
||||
AutoRestartProgressDialogClass *AutoRestartProgressDialogClass::Instance;
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::AutoRestartClass -- Class constructor *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:21PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
AutoRestartClass::AutoRestartClass(void)
|
||||
{
|
||||
RestartState = STATE_DONE;
|
||||
CancelRequest = false;
|
||||
GameMode = 0;
|
||||
NumChannelCreateTries = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::Restart_Game -- Initiate the restart process *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:22PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::Restart_Game(void)
|
||||
{
|
||||
if (RestartState == STATE_DONE) {
|
||||
RestartState = STATE_FIRST;
|
||||
CancelRequest = false;
|
||||
RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
|
||||
if (registry.Is_Valid()) {
|
||||
GameMode = registry.Get_Int(REG_VALUE_AUTO_RESTART_TYPE, GameMode);
|
||||
}
|
||||
Set_Restart_Flag(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::Cancel -- Cancel game restart *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 9:42PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::Cancel(void)
|
||||
{
|
||||
CancelRequest = true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::Think -- Class service function *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:22PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::Think(void)
|
||||
{
|
||||
static unsigned long time;
|
||||
|
||||
bool can_render = ConsoleBox.Is_Exclusive() ? false : true;
|
||||
|
||||
switch (RestartState) {
|
||||
|
||||
/*
|
||||
** Idle, not doing anything.
|
||||
*/
|
||||
case STATE_DONE:
|
||||
break;
|
||||
|
||||
/*
|
||||
** This is the first restart state. Initialise WOL and login.
|
||||
*/
|
||||
case STATE_FIRST:
|
||||
|
||||
if (CancelRequest) {
|
||||
RestartState = STATE_CANCELLED;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create the progress dialog.
|
||||
*/
|
||||
if (can_render) {
|
||||
START_DIALOG(AutoRestartProgressDialogClass);
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Auto starting game. Type 'quit' at the console window to abort");
|
||||
}
|
||||
ConsoleBox.Print("*** Auto starting game. Type 'quit' to abort ***\n");
|
||||
|
||||
/*
|
||||
** Start listening for server control messages.
|
||||
*/
|
||||
GameSideServerControlClass::Init();
|
||||
|
||||
/*
|
||||
** Initialise WOL or LAN mode.
|
||||
*/
|
||||
if (!GameMode) {
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Initializing LAN Mode");
|
||||
}
|
||||
if (cGameSpyAdmin::Get_Is_Server_Gamespy_Listed()) {
|
||||
ConsoleBox.Print("Initializing GameSpy Mode\n");
|
||||
} else {
|
||||
ConsoleBox.Print("Initializing LAN Mode\n");
|
||||
}
|
||||
GameInitMgrClass::Initialize_LAN();
|
||||
RestartState = STATE_GAME_MODE_WAIT;
|
||||
} else {
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Initializing Westwood Online");
|
||||
}
|
||||
ConsoleBox.Print("Initializing Westwood Online Mode\n");
|
||||
GameInitMgrClass::Initialize_WOL();
|
||||
RestartState = STATE_GAME_MODE_WAIT;
|
||||
|
||||
/*
|
||||
** Force a new server list update. This will cause a complete WOLAPI reset too btw.
|
||||
*/
|
||||
RefPtr<WWOnline::Session> wol_session = WWOnline::Session::GetInstance(false);
|
||||
wol_session->Reset();
|
||||
|
||||
/*
|
||||
** Hide the page dialog - we don't want that sucker popping up when there's no-one around.
|
||||
*/
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->HidePagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case STATE_GAME_MODE_WAIT:
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
} else {
|
||||
|
||||
if (!GameMode) {
|
||||
GameModeClass *game_mode = GameModeManager::Find("LAN");
|
||||
if (game_mode && game_mode->Is_Active()) {
|
||||
RestartState = STATE_CREATE_GAME;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** It won't have initialzed above if a shutdown was already pending. Maybe we need to try again.
|
||||
*/
|
||||
if (game_mode && game_mode->Is_Inactive()) {
|
||||
GameInitMgrClass::Initialize_LAN();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GameModeClass *game_mode = GameModeManager::Find("WOL");
|
||||
if (game_mode && game_mode->Is_Active()) {
|
||||
/*
|
||||
** Logon to WOL.
|
||||
*/
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Logging on");
|
||||
}
|
||||
LogonAction = (WOLLogonAction) -1;
|
||||
WOLLogonMgr::Set_Quiet_Mode(true);
|
||||
RefPtr<WWOnline::Session> WOLSession = WWOnline::Session::GetInstance(false);
|
||||
Observer<WWOnline::ServerError>::NotifyMe(*WOLSession);
|
||||
WOLLogonMgr::Logon(this);
|
||||
RestartState = STATE_LOGIN;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** It won't have initialzed above if a shutdown was already pending. Maybe we need to try again.
|
||||
*/
|
||||
if (game_mode && game_mode->Is_Inactive()) {
|
||||
GameInitMgrClass::Initialize_WOL();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Wait for the login process to complete.
|
||||
*/
|
||||
case STATE_LOGIN:
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
}
|
||||
Observer<WWOnline::ServerError>::StopObserving();
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
switch (LogonAction) {
|
||||
|
||||
/*
|
||||
** Login failed. Might be that the user is still logged in from last time so retry.
|
||||
*/
|
||||
case WOLLOGON_FAILED:
|
||||
if (CancelRequest) {
|
||||
Observer<WWOnline::ServerError>::StopObserving();
|
||||
RestartState = STATE_CANCELLED;
|
||||
break;
|
||||
}
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Failed, retrying");
|
||||
}
|
||||
ConsoleBox.Print("Failed to log in, retrying\n");
|
||||
LogonAction = (WOLLogonAction) -1;
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Logging on");
|
||||
}
|
||||
ConsoleBox.Print("Logging on....\n");
|
||||
WOLLogonMgr::Logon(this);
|
||||
break;
|
||||
|
||||
/*
|
||||
** Logged in OK. Move onto the next step.
|
||||
*/
|
||||
case WOLLOGON_SUCCESS:
|
||||
if (CancelRequest) {
|
||||
Observer<WWOnline::ServerError>::StopObserving();
|
||||
WOLLogonMgr::Logoff();
|
||||
RestartState = STATE_CANCELLED;
|
||||
break;
|
||||
}
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Logged on OK");
|
||||
}
|
||||
ConsoleBox.Print("Logged on OK\n");
|
||||
WOLLogonMgr::Set_Quiet_Mode(false);
|
||||
RestartState = STATE_CREATE_GAME;
|
||||
time = TIMEGETTIME();
|
||||
Observer<WWOnline::ServerError>::StopObserving();
|
||||
break;
|
||||
|
||||
/*
|
||||
** Patch available. At this point we want to
|
||||
**
|
||||
** 1. Download the patch.
|
||||
** 2. Quit to apply the patch.
|
||||
** 3. Reload the level after the restart.
|
||||
**
|
||||
*/
|
||||
case WOLLOGON_PATCHREQUIRED:
|
||||
{
|
||||
RefPtr<WWOnline::Session> wol_session = WWOnline::Session::GetInstance(false);
|
||||
ConsoleBox.Print("Downloading patch\n");
|
||||
DlgDownload::DoDialog(TRANSLATE(IDS_WOL_DOWNLOAD), wol_session->GetPatchDownloadList(), true);
|
||||
Set_Restart_Flag(true);
|
||||
RestartState = STATE_DONE;
|
||||
Observer<WWOnline::ServerError>::StopObserving();
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** Fatal error. Abort restart process.
|
||||
*/
|
||||
case WOLLOGON_CANCEL:
|
||||
WOLLogonMgr::Set_Quiet_Mode(false);
|
||||
RestartState = STATE_CANCELLED;
|
||||
Observer<WWOnline::ServerError>::StopObserving();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
** Create the game object and initialise it with the settings from the last game.
|
||||
*/
|
||||
case STATE_CREATE_GAME:
|
||||
{
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CancelRequest) {
|
||||
if (GameMode) {
|
||||
WOLLogonMgr::Logoff();
|
||||
}
|
||||
RestartState = STATE_CANCELLED;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** We have to wait for the firewall thread to discover the local IP before we can build the game.
|
||||
*/
|
||||
if (GameMode) {
|
||||
if (FirewallHelper.Get_Local_Address() == 0) {
|
||||
if (TIMEGETTIME() - time < 1000 * 6) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Work out what type of game to create.
|
||||
*/
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Building game info");
|
||||
}
|
||||
|
||||
/*
|
||||
int last_game_type = 0;
|
||||
RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
|
||||
if (registry.Is_Valid ()) {
|
||||
last_game_type = registry.Get_Int(REG_VALUE_LAST_GAME_TYPE, last_game_type);
|
||||
}
|
||||
|
||||
last_game_type = min(last_game_type, NUM_GAME_TYPE_MENU_ENTRIES-1);
|
||||
last_game_type = max(last_game_type, 0);
|
||||
|
||||
int game_type = MPLanGameTypeMenuClass::GameTypeList[last_game_type].GameType;
|
||||
*/
|
||||
|
||||
int game_type = cGameData::GAME_TYPE_CNC;
|
||||
|
||||
/*
|
||||
** Create the new game data.
|
||||
*/
|
||||
PTheGameData = cGameData::Create_Game_Of_Type((cGameData::GameTypeEnum)game_type);
|
||||
WWASSERT(PTheGameData != NULL);
|
||||
|
||||
/*
|
||||
** Apply command line/ini settings.
|
||||
*/
|
||||
if (ServerSettingsClass::Parse(true) == false) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** Start listening for server control messages.
|
||||
*/
|
||||
//GameSideServerControlClass::Init();
|
||||
|
||||
/*
|
||||
** Load alternate server settings if required.
|
||||
*/
|
||||
if (SlaveMaster.Am_I_Slave()) {
|
||||
RegistryClass reg(APPLICATION_SUB_KEY_NAME_OPTIONS);
|
||||
char file_name[MAX_PATH];
|
||||
reg.Get_String("MultiplayerSettings", file_name, sizeof(file_name), "");
|
||||
if (strlen(file_name)) {
|
||||
WWDEBUG_SAY(("Loading multiplayer settings from file %s\n", file_name));
|
||||
The_Game()->Set_Ini_Filename(file_name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Load the game settings.
|
||||
*/
|
||||
The_Game()->Load_From_Server_Config();
|
||||
|
||||
|
||||
/*
|
||||
** Set MaxPlayers based on Bandwidth test results if MaxPlayers is
|
||||
** set to 0 in the INI file.
|
||||
*/
|
||||
if (ServerSettingsClass::Get_Game_Mode() == ServerSettingsClass::MODE_WOL &&
|
||||
The_Game()->Get_Max_Players() == 0 && BandwidthCheckerClass::Got_Bandwidth()) {
|
||||
|
||||
int max_players = (cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_AUTO) / 250000) * 4;
|
||||
if (max_players < 2) {
|
||||
if (cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_AUTO) > 100000) {
|
||||
max_players = 4;
|
||||
} else {
|
||||
max_players = 2;
|
||||
}
|
||||
} else if (max_players > 32) {
|
||||
max_players = 32;
|
||||
}
|
||||
The_Game()->Set_Max_Players(max_players);
|
||||
}
|
||||
|
||||
/*
|
||||
** Override gama settings in command line mode.
|
||||
*/
|
||||
if (ServerSettingsClass::Is_Command_Line_Mode()) {
|
||||
The_Game()->IsAutoRestart.Set(true);
|
||||
The_Game()->IsDedicated.Set(true);
|
||||
}
|
||||
|
||||
StringClass inifile = The_Game()->Get_Ini_Filename();
|
||||
StringClass nick(32, true);
|
||||
cNetInterface::Get_Nickname().Convert_To(nick);
|
||||
ConsoleBox.Set_Title(nick.Peek_Buffer(), inifile.Peek_Buffer());
|
||||
|
||||
if (GameMode) {
|
||||
NumChannelCreateTries = 0;
|
||||
RestartState = STATE_CREATE_CHANNEL;
|
||||
} else {
|
||||
RestartState = STATE_START_GAME;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create the game channel on the chat server.
|
||||
*/
|
||||
case STATE_CREATE_CHANNEL:
|
||||
{
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
|
||||
/*
|
||||
** Log off.
|
||||
*/
|
||||
WOLLogonMgr::Logoff();
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CancelRequest) {
|
||||
WOLLogonMgr::Logoff();
|
||||
RestartState = STATE_CANCELLED;
|
||||
break;
|
||||
}
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Creating game channel....");
|
||||
}
|
||||
ConsoleBox.Print("Creating game channel...\n");
|
||||
|
||||
/*
|
||||
** Create the game channel.
|
||||
*/
|
||||
GameModeClass *game_mode = GameModeManager::Find("WOL");
|
||||
LastChannelCreateTime = TIMEGETTIME();
|
||||
|
||||
if (game_mode && game_mode->Is_Active()) {
|
||||
WolGameModeClass* wol_game = (WolGameModeClass*) game_mode;
|
||||
WWASSERT(wol_game);
|
||||
wol_game->Set_Quiet_Mode(true);
|
||||
wol_game->SignalMe(*this);
|
||||
WWASSERT(PTheGameData != NULL);
|
||||
NumChannelCreateTries++;
|
||||
wol_game->Create_Game(The_Game());
|
||||
RestartState = STATE_WAIT_CHANNEL_CREATE;
|
||||
} else {
|
||||
RestartState = STATE_START_GAME;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** Wait for the game channel creation result.
|
||||
*/
|
||||
case STATE_WAIT_CHANNEL_CREATE:
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
|
||||
/*
|
||||
** Log off.
|
||||
*/
|
||||
WOLLogonMgr::Logoff();
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
}
|
||||
if (CancelRequest) {
|
||||
WOLLogonMgr::Logoff();
|
||||
RestartState = STATE_CANCELLED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
** Waiting to retry channel create.
|
||||
*/
|
||||
case STATE_WAIT_CHANNEL_CREATE_RETRY:
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
|
||||
/*
|
||||
** Log off.
|
||||
*/
|
||||
WOLLogonMgr::Logoff();
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
if (CancelRequest) {
|
||||
WOLLogonMgr::Logoff();
|
||||
RestartState = STATE_CANCELLED;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
** Give up and restart if we fail enough times when trying to create a channel.
|
||||
*/
|
||||
if (NumChannelCreateTries > 10) {
|
||||
Set_Exit_On_Exception(true);
|
||||
cGameData::Set_Manual_Exit(true);
|
||||
}
|
||||
if (TIMEGETTIME() - LastChannelCreateTime > 5*1000) {
|
||||
ConsoleBox.Print("Retrying channel create\n");
|
||||
RestartState = STATE_CREATE_CHANNEL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
** Load the game.
|
||||
*/
|
||||
case STATE_START_GAME:
|
||||
{
|
||||
if (cGameData::Is_Manual_Exit()) {
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
|
||||
/*
|
||||
** Log off.
|
||||
*/
|
||||
WOLLogonMgr::Logoff();
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Channel created OK");
|
||||
}
|
||||
|
||||
ConsoleBox.Print("Channel created OK\n");
|
||||
|
||||
SlaveMaster.Startup_Slaves();
|
||||
|
||||
GameModeClass *game_mode = GameModeManager::Find("WOL");
|
||||
if (game_mode && game_mode->Is_Active()) {
|
||||
WolGameModeClass* wol_game = (WolGameModeClass*) game_mode;
|
||||
WWASSERT(wol_game);
|
||||
wol_game->Set_Quiet_Mode(false);
|
||||
}
|
||||
|
||||
//ConsoleBox.Print("Loading level...\n");
|
||||
WWASSERT(PTheGameData != NULL);
|
||||
CampaignManager::Select_Backdrop_Number_By_MP_Type(The_Game()->Get_Game_Type());
|
||||
GameInitMgrClass::Set_Is_Client_Required(false);
|
||||
GameInitMgrClass::Set_Is_Server_Required(true);
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->End_Dialog();
|
||||
}
|
||||
GameInitMgrClass::Start_Game(The_Game()->Get_Map_Name(), -1, 0);
|
||||
//ConsoleBox.Print("Level loaded OK\n");
|
||||
RestartState = STATE_DONE;
|
||||
|
||||
/*
|
||||
** Allow the page dialog to display again (it can't really anyway since it's disabled when the game is in progress.
|
||||
*/
|
||||
if (GameMode) {
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** User cancelled.
|
||||
*/
|
||||
case STATE_CANCELLED:
|
||||
RestartState = STATE_DONE;
|
||||
|
||||
/*
|
||||
** Allow the page dialog to display again.
|
||||
*/
|
||||
WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
|
||||
if (buddy) {
|
||||
buddy->ShowPagedDialog();
|
||||
buddy->Release_Ref();
|
||||
}
|
||||
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->End_Dialog();
|
||||
}
|
||||
if (SlaveMaster.Am_I_Slave()) {
|
||||
if (GameMode) {
|
||||
WOLLogonMgr::Logoff();
|
||||
}
|
||||
RestartState = STATE_DONE;
|
||||
Stop_Main_Loop (EXIT_SUCCESS);
|
||||
} else {
|
||||
RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_MAIN_MENU);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::HandleNotification -- Notification callback for WOL login *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Success code *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:23PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::HandleNotification(WOLLogonAction& action)
|
||||
{
|
||||
LogonAction = action;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* WolGameModeClass::HandleNotification -- Handle server error notifications *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Server error tyoe *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/8/2001 10:21PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::HandleNotification(WWOnline::ServerError& server_error)
|
||||
{
|
||||
ConsoleBox.Print("Error - %S\n", server_error.GetDescription());
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::ReceiveSignal -- Channel creation signal handler *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Game mode *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:23PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::ReceiveSignal(WolGameModeClass &game_mode)
|
||||
{
|
||||
if (RestartState == STATE_WAIT_CHANNEL_CREATE) {
|
||||
if (game_mode.Channel_Create_OK()) {
|
||||
RestartState = STATE_START_GAME;
|
||||
} else {
|
||||
bool can_render = ConsoleBox.Is_Exclusive() ? false : true;
|
||||
if (can_render) {
|
||||
AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Failed, retrying");
|
||||
}
|
||||
ConsoleBox.Print("Failed to create channel\n");
|
||||
RestartState = STATE_WAIT_CHANNEL_CREATE_RETRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::Set_Restart_Flag -- Set state of auto restart mode *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: New state *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:32PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartClass::Set_Restart_Flag(bool enable)
|
||||
{
|
||||
RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
|
||||
if (registry.Is_Valid ()) {
|
||||
registry.Set_Int(REG_VALUE_AUTO_RESTART_FLAG, enable ? 1 : 0);
|
||||
|
||||
GameModeClass *game_mode = GameModeManager::Find("WOL");
|
||||
if (game_mode && game_mode->Is_Active()) {
|
||||
GameMode = 1;
|
||||
} else {
|
||||
GameModeClass *game_mode = GameModeManager::Find("LAN");
|
||||
if (game_mode && game_mode->Is_Active()) {
|
||||
GameMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
registry.Set_Int(REG_VALUE_AUTO_RESTART_TYPE, GameMode);
|
||||
Set_Exit_On_Exception(true);
|
||||
} else {
|
||||
Set_Exit_On_Exception(false);
|
||||
}
|
||||
|
||||
RegistryClass registry_too(WINDOWS_SUB_KEY_RUN_ONCE);
|
||||
if (registry_too.Is_Valid()) {
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
** The the current path and build a path/file combo that points to the launcher.
|
||||
*/
|
||||
char path_to_exe[256];
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char path[_MAX_PATH];
|
||||
GetModuleFileName(ProgramInstance, path_to_exe, sizeof(path_to_exe));
|
||||
_splitpath(path_to_exe, drive, dir, NULL, NULL);
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
_makepath(path, drive, dir, "renegadeserver", "exe");
|
||||
#else //FREEDEDICATEDSERVER
|
||||
_makepath(path, drive, dir, "renegade", "exe");
|
||||
|
||||
char options[256];
|
||||
options[0] = 0;
|
||||
if (ServerSettingsClass::Is_Active()) {
|
||||
sprintf(options, " /startserver=%s", ServerSettingsClass::Get_Settings_File_Name());
|
||||
}
|
||||
|
||||
if (ConsoleBox.Is_Exclusive()) {
|
||||
strcat(options, " /nodx");
|
||||
}
|
||||
|
||||
strcat(path, options);
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
WWDEBUG_SAY(("Writing %s to RunOnce key\n", path));
|
||||
registry_too.Set_String(WINDOWS_SUB_KEY_RUN_ONCE_APP, path);
|
||||
} else {
|
||||
WWDEBUG_SAY(("Removing RunOnce key\n"));
|
||||
registry_too.Delete_Value(WINDOWS_SUB_KEY_RUN_ONCE_APP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartClass::Get_Restart_Flag -- Is a restart indicated by the registry? *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: New state *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/2001 3:32PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
bool AutoRestartClass::Get_Restart_Flag(void)
|
||||
{
|
||||
bool flag = false;
|
||||
|
||||
RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
|
||||
if (registry.Is_Valid()) {
|
||||
int restart = registry.Get_Int(REG_VALUE_AUTO_RESTART_FLAG, 0);
|
||||
flag = restart ? true : false;
|
||||
}
|
||||
return(flag);
|
||||
}
|
||||
154
Code/Commando/AutoStart.h
Normal file
154
Code/Commando/AutoStart.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
** 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/AutoStart.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 8/13/02 4:57p $*
|
||||
* *
|
||||
* $Revision:: 6 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#pragma once
|
||||
#ifndef _AUTOSTART_H
|
||||
#define _AUTOSTART_H
|
||||
|
||||
#include "WOLLogonMgr.h"
|
||||
#include <wwlib\signaler.h>
|
||||
#include "wolgmode.h"
|
||||
#include "menudialog.h"
|
||||
#include "resource.h"
|
||||
#include <wwonline\refptr.h>
|
||||
#include <wwonline\wolsession.h>
|
||||
|
||||
namespace WOL {
|
||||
class WOLSession;
|
||||
class ServerError;
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** This class handles restarting a server after a crash or system reboot.
|
||||
**
|
||||
**
|
||||
*/
|
||||
class AutoRestartClass : public Observer<WOLLogonAction>, public Observer<WWOnline::ServerError>, protected Signaler<WolGameModeClass>
|
||||
{
|
||||
|
||||
public:
|
||||
/*
|
||||
** Constructor, destructor.
|
||||
*/
|
||||
AutoRestartClass(void);
|
||||
|
||||
/*
|
||||
** Misc public functions.
|
||||
*/
|
||||
void Restart_Game(void);
|
||||
void Think(void);
|
||||
bool Is_Active(void) {return((bool)(RestartState != STATE_DONE));}
|
||||
void Set_Restart_Flag(bool enable);
|
||||
bool Get_Restart_Flag(void);
|
||||
void Cancel(void);
|
||||
|
||||
|
||||
/*
|
||||
** Callbacks.
|
||||
*/
|
||||
void HandleNotification(WOLLogonAction&);
|
||||
void HandleNotification(WWOnline::ServerError& server_error);
|
||||
void ReceiveSignal(WolGameModeClass&);
|
||||
|
||||
/*
|
||||
** Enum of steps to go through to restart a game.
|
||||
*/
|
||||
typedef enum {
|
||||
STATE_FIRST,
|
||||
STATE_GAME_MODE_WAIT,
|
||||
STATE_LOGIN,
|
||||
STATE_CREATE_GAME,
|
||||
STATE_CREATE_CHANNEL,
|
||||
STATE_WAIT_CHANNEL_CREATE,
|
||||
STATE_WAIT_CHANNEL_CREATE_RETRY,
|
||||
STATE_START_GAME,
|
||||
STATE_CANCELLED,
|
||||
STATE_DONE,
|
||||
} RestartStateType;
|
||||
|
||||
static const char *REG_VALUE_AUTO_RESTART_FLAG;
|
||||
static const char *REG_VALUE_AUTO_RESTART_TYPE;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
** WOL Login state.
|
||||
*/
|
||||
WOLLogonAction LogonAction;
|
||||
|
||||
/*
|
||||
** Restart state.
|
||||
*/
|
||||
RestartStateType RestartState;
|
||||
|
||||
/*
|
||||
** Cancel request flag.
|
||||
*/
|
||||
bool CancelRequest;
|
||||
|
||||
/*
|
||||
** Game mode. 0 = LAN, 1 = internet.
|
||||
*/
|
||||
int GameMode;
|
||||
|
||||
/*
|
||||
** Reference pointer to WOLSession.
|
||||
*/
|
||||
RefPtr<WWOnline::Session> WOLSession;
|
||||
|
||||
/*
|
||||
** Time we last tried to create the game channel.
|
||||
*/
|
||||
unsigned long LastChannelCreateTime;
|
||||
|
||||
/*
|
||||
** Number of times we tried to create the channel.
|
||||
*/
|
||||
int NumChannelCreateTries;
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern AutoRestartClass AutoRestart;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //_AUTOSTART_H
|
||||
166
Code/Commando/CDKeyAuth.cpp
Normal file
166
Code/Commando/CDKeyAuth.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Renegade *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/CDKeyAuth.cpp $*
|
||||
* *
|
||||
* Original Author:: Brian Hayes *
|
||||
* *
|
||||
* $Author:: Bhayes $*
|
||||
* *
|
||||
* $Modtime:: 3/15/02 2:56p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <GameSpy\gcdkeyserver.h>
|
||||
#include <GameSpy\gcdkeyclient.h>
|
||||
#include <GameSpy\nonport.h>
|
||||
#include <GameSpy\gs_md5.h>
|
||||
#include <stdlib.h>
|
||||
#include "wwdebug.h"
|
||||
#include "CDKeyAuth.h"
|
||||
#include "gamespyauthmgr.h"
|
||||
#include "registry.h"
|
||||
#include "playermanager.h"
|
||||
#include "_globals.h"
|
||||
#include "ServerSettings.h"
|
||||
|
||||
// static void c_auth_callback(int localid, int authenticated, char *errmsg, void *instance)
|
||||
// {
|
||||
// ((CCDKeyAuth *)instance)->auth_callback(localid, authenticated, errmsg);
|
||||
// }
|
||||
|
||||
|
||||
//generate a rand nchar challenge
|
||||
char * CCDKeyAuth::GenChallenge(int nchars)
|
||||
{
|
||||
static char s[33];
|
||||
if (nchars > 32) nchars = 32;
|
||||
s[nchars] = 0;
|
||||
while (nchars--)
|
||||
{
|
||||
s[nchars] = (char)('a' + rand() % 26);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Callback function to indicate whether a client has been authorized or not.
|
||||
If the client has been, then we send them a "welcome" string, representative of
|
||||
allowing them to "enter" the game. If they have not been authenticated, we dump
|
||||
them after sending an error message */
|
||||
void CCDKeyAuth::auth_callback(int localid, int authenticated, char *errmsg, void *instance)
|
||||
{
|
||||
// client_t *clients = (client_t *)instance;
|
||||
// char outbuf[512];
|
||||
|
||||
WWDEBUG_SAY(("CDKeyAuth -- %d:%d:%s\n", localid, authenticated, errmsg));
|
||||
|
||||
cPlayer * p_player = cPlayerManager::Find_Player(localid);
|
||||
if (p_player != NULL) {
|
||||
|
||||
if (!authenticated) //doh.. bad!
|
||||
{
|
||||
// This client failed.
|
||||
//p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_REJECTING);
|
||||
//cGameSpyAuthMgr::Evict_Player(localid);
|
||||
cGameSpyAuthMgr::Initiate_Auth_Rejection(localid);
|
||||
|
||||
// printf("Client %d was NOT authenticated (%s)\n",localid, errmsg);
|
||||
// sprintf(outbuf,"E:%s\n",errmsg);
|
||||
// send(clients[localid].sock, outbuf, strlen(outbuf),0);
|
||||
// shutdown(clients[localid].sock, 2);
|
||||
// closesocket(clients[localid].sock);
|
||||
// clients[localid].sock = INVALID_SOCKET;
|
||||
} else
|
||||
{
|
||||
// This client passed.
|
||||
p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_ACCEPTED);
|
||||
// printf("Client %d was authenticated (%s)\n",localid, errmsg);
|
||||
// sprintf(outbuf,"M:Welcome to the game, have fun! (%s)\n",errmsg);
|
||||
// send(clients[localid].sock, outbuf, strlen(outbuf),0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCDKeyAuth::DisconnectUser(int localid) {
|
||||
gcd_disconnect_user(localid);
|
||||
|
||||
}
|
||||
|
||||
void CCDKeyAuth::AuthenticateUser(int localid, ULONG ip, char *challenge, char *authstring) {
|
||||
|
||||
// Customize this with our playerdata struct
|
||||
// Take the response from our challenge that we sent to the client
|
||||
// and send it off to the Authserver along with the original challenge
|
||||
|
||||
gcd_authenticate_user(localid, ip, challenge, authstring, CCDKeyAuth::auth_callback, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CCDKeyAuth::AuthSerial(const char *challenge, StringClass &resp) {
|
||||
|
||||
char response[RESPONSE_SIZE];
|
||||
StringClass sserial;
|
||||
|
||||
WWASSERT(challenge);
|
||||
|
||||
GetSerialNum(sserial);
|
||||
|
||||
const char *serial = sserial;
|
||||
|
||||
char *cdkey = new char [strlen(serial)+1];
|
||||
char *outb = cdkey;
|
||||
const char *linep = serial;
|
||||
char md5hash[33];
|
||||
|
||||
while (*linep) {
|
||||
if (*linep >= '0' && *linep <= '9') {
|
||||
*outb++ = *linep;
|
||||
}
|
||||
linep++;
|
||||
}
|
||||
*outb = 0;
|
||||
|
||||
// MD5 Hash Here.
|
||||
MD5Digest((BYTE *)cdkey, strlen(cdkey), md5hash);
|
||||
|
||||
// hashserial, challenge, outbuf
|
||||
gcd_compute_response(md5hash, challenge, response);
|
||||
|
||||
delete [] cdkey;
|
||||
resp = response;
|
||||
}
|
||||
|
||||
void CCDKeyAuth::GetSerialNum(StringClass &serial) {
|
||||
|
||||
RegistryClass main_reg(APPLICATION_SUB_KEY_NAME);
|
||||
StringClass stringval;
|
||||
StringClass serial_out;
|
||||
main_reg.Get_String("Serial", stringval);
|
||||
ServerSettingsClass::Encrypt_Serial(stringval, serial, false);
|
||||
}
|
||||
48
Code/Commando/CDKeyAuth.h
Normal file
48
Code/Commando/CDKeyAuth.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _CDKEYAUTH_H_
|
||||
#define _CDKEYAUTH_H_
|
||||
|
||||
/********
|
||||
INCLUDES
|
||||
********/
|
||||
#include <WWLib\wwstring.h>
|
||||
|
||||
/********
|
||||
DEFINES
|
||||
********/
|
||||
|
||||
class CCDKeyAuth
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
static void auth_callback(int localid, int authenticated, char *errmsg, void *instance);
|
||||
|
||||
public:
|
||||
static void GetSerialNum(StringClass &serial);
|
||||
static void DisconnectUser(int localid);
|
||||
static void AuthenticateUser(int localid, ULONG ip, char *challenge, char *authstring);
|
||||
static char *GenChallenge(int nchars);
|
||||
static void AuthSerial(const char *challenge, StringClass &resp);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // CDKEYAUTH
|
||||
1012
Code/Commando/ConsoleMode.cpp
Normal file
1012
Code/Commando/ConsoleMode.cpp
Normal file
File diff suppressed because it is too large
Load Diff
153
Code/Commando/ConsoleMode.h
Normal file
153
Code/Commando/ConsoleMode.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
** 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/ConsoleMode.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 8/14/02 12:00p $*
|
||||
* *
|
||||
* $Revision:: 10 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include <win.h>
|
||||
|
||||
class WideStringClass;
|
||||
class StringClass;
|
||||
class Vector3;
|
||||
|
||||
/*
|
||||
** This is a console interface for the game so you can do stuff even if you can't display the main game window.
|
||||
**
|
||||
**
|
||||
*/
|
||||
class ConsoleModeClass
|
||||
{
|
||||
public:
|
||||
/*
|
||||
** Constructor, destructor.
|
||||
*/
|
||||
ConsoleModeClass(void);
|
||||
~ConsoleModeClass(void);
|
||||
|
||||
/*
|
||||
** Init.
|
||||
*/
|
||||
void Init(void);
|
||||
void Set_Title(char *name, char *settings);
|
||||
|
||||
/*
|
||||
** Input processing.
|
||||
*/
|
||||
void Think();
|
||||
void Wait_For_Keypress(void);
|
||||
|
||||
/*
|
||||
** Console output.
|
||||
*/
|
||||
void Print(char const * string, ...);
|
||||
void Print_Maybe(char const * string, ...);
|
||||
static void Static_Print_Maybe(char const * string, ...);
|
||||
Add_Message(WideStringClass *formatted_text, Vector3 *text_color, bool forced = false);
|
||||
|
||||
/*
|
||||
** Profiling support.
|
||||
*/
|
||||
void Update_Profile(StringClass profile_string);
|
||||
void Set_Profile_Mode(bool set) {ProfileMode = set; LastProfileCRC = 0; LastProfilePrint = 0;}
|
||||
void Handle_Profile_Key(int key);
|
||||
|
||||
/*
|
||||
** Master/Slave console window settings/support.
|
||||
*/
|
||||
void Set_Exclusive(bool set) {IsExclusive = set;}
|
||||
bool Is_Exclusive(void) {return(IsExclusive);}
|
||||
HWND Get_Slave_Window_By_Title(char *name, char *settings);
|
||||
StringClass Compose_Window_Title(char *name, char *settings, bool slave);
|
||||
void cprintf(char const * string, ...);
|
||||
|
||||
/*
|
||||
** File logging.
|
||||
*/
|
||||
void Log_To_Disk(const char *string);
|
||||
const char *Get_Log_File_Name(void);
|
||||
|
||||
private:
|
||||
/*
|
||||
** Private functions.
|
||||
*/
|
||||
void Apply_Attributes(void);
|
||||
|
||||
/*
|
||||
** Input and output handles.
|
||||
*/
|
||||
HANDLE ConsoleInputHandle;
|
||||
HANDLE ConsoleOutputHandle;
|
||||
|
||||
/*
|
||||
** Window handle.
|
||||
*/
|
||||
HWND ConsoleWindow;
|
||||
|
||||
/*
|
||||
** Input parsing variables.
|
||||
*/
|
||||
unsigned long LastKeypressTime;
|
||||
int Pos;
|
||||
|
||||
/*
|
||||
** Console title bar contents.
|
||||
*/
|
||||
char Title[256];
|
||||
|
||||
/*
|
||||
** Is console mode the only mode?
|
||||
*/
|
||||
bool IsExclusive;
|
||||
|
||||
/*
|
||||
** Is the console in profile mode?
|
||||
*/
|
||||
bool ProfileMode;
|
||||
|
||||
/*
|
||||
** Last profile text CRC.
|
||||
*/
|
||||
unsigned long LastProfileCRC;
|
||||
|
||||
/*
|
||||
** Last time we printed the profile.
|
||||
*/
|
||||
unsigned long LastProfilePrint;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
** Single instance of console.
|
||||
*/
|
||||
extern ConsoleModeClass ConsoleBox;
|
||||
534
Code/Commando/DlgDownload.cpp
Normal file
534
Code/Commando/DlgDownload.cpp
Normal file
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgDownload.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* File download dialog.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Steve_t $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 11 $
|
||||
* $Modtime: 1/12/02 2:53p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgDownload.h"
|
||||
#include "DlgMessageBox.h"
|
||||
#include "DlgRestart.h"
|
||||
#include "Resource.h"
|
||||
#include <WWUI\ProgressCtrl.h>
|
||||
#include "String_IDs.h"
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
#include "mainloop.h"
|
||||
#include "consolemode.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push,3)
|
||||
#endif
|
||||
|
||||
#include "systimer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
static void PrintableSize(unsigned long size, WideStringClass& printable);
|
||||
static void PrintableTime(unsigned long seconds, WideStringClass& printable);
|
||||
|
||||
bool DlgDownload::mQuietMode = false;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Start download dialog
|
||||
*
|
||||
* INPUTS
|
||||
* Title - Dialog title
|
||||
* Files - List of files to download
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if dialog successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgDownload::DoDialog(const WCHAR* title, const DownloadList& files, bool quiet)
|
||||
{
|
||||
if (!files.empty())
|
||||
{
|
||||
mQuietMode = quiet;
|
||||
DlgDownload* popup = new DlgDownload;
|
||||
|
||||
if (popup)
|
||||
{
|
||||
if (popup->FinalizeCreate(files))
|
||||
{
|
||||
popup->Start_Dialog();
|
||||
popup->Set_Title(title);
|
||||
}
|
||||
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::DlgDownload
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgDownload::DlgDownload() :
|
||||
PopupDialogClass(IDD_WOL_DOWNLOAD),
|
||||
mDownloading(false)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgDownload: Instantiated\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::~DlgDownload
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgDownload::~DlgDownload()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgDownload: Destructing\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Finalize the dialog creation.
|
||||
*
|
||||
* INPUTS
|
||||
* Files - List of files to download.
|
||||
*
|
||||
* RESULT
|
||||
* True if successful.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgDownload::FinalizeCreate(const DownloadList& files)
|
||||
{
|
||||
mWait = DownloadWait::Create(files);
|
||||
return mWait.IsValid();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* One time dialog initialization.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgDownload::On_Init_Dialog(void)
|
||||
{
|
||||
// Set estimated time and read / total
|
||||
WideStringClass text(0, true);
|
||||
text.Format(TRANSLATE(IDS_MENU_TRANSFER_RATE_TIME), 0, 0, 0);
|
||||
Set_Dlg_Item_Text(IDC_PROGRESSTEXT, text);
|
||||
|
||||
// Update transfer rate.
|
||||
text.Format(TRANSLATE(IDS_MENU_TRANSFER_RATE), 0);
|
||||
Set_Dlg_Item_Text(IDC_TRANSFERTEXT, text);
|
||||
|
||||
// Start the wait condition
|
||||
mWait->SetCallback(DlgDownload::HandleCallback, (unsigned long)this);
|
||||
mWait->WaitBeginning();
|
||||
|
||||
PopupDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process command message
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control
|
||||
* Message -
|
||||
* Param -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgDownload::On_Command(int ctrl, int message, DWORD param)
|
||||
{
|
||||
if (ctrl == IDCANCEL)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgDownload: User Aborted\n"));
|
||||
mWait->EndWait(WaitCondition::UserCancel, TRANSLATE(IDS_WOL_CANCELED));
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Command(ctrl, message, param);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::On_Periodic
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgDownload::On_Periodic(void)
|
||||
{
|
||||
PopupDialogClass::On_Periodic();
|
||||
|
||||
// Check the status of the wait condition
|
||||
WaitCondition::WaitResult waitStatus = mWait->GetResult();
|
||||
|
||||
// If we are no longer waiting then process the result.
|
||||
if (waitStatus != WaitCondition::Waiting)
|
||||
{
|
||||
if (waitStatus == WaitCondition::ConditionMet)
|
||||
{
|
||||
if (mQuietMode)
|
||||
{
|
||||
ConsoleBox.Print("Restarting....\n");
|
||||
Stop_Main_Loop(RESTART_EXITCODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DlgRestart::DoDialog();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the download was aborted or errored then show a message dialog
|
||||
// describing the failure.
|
||||
DlgMsgBox::DoDialog(TRANSLATE(IDS_WOL_DOWNLOADERROR), mWait->GetResultText());
|
||||
}
|
||||
|
||||
End_Dialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::UpdateProgress
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgDownload::UpdateProgress(DownloadEvent& event)
|
||||
{
|
||||
const RefPtr<Download>& download = event.GetDownload();
|
||||
|
||||
switch (event.GetEvent())
|
||||
{
|
||||
case DownloadEvent::DOWNLOAD_STATUS:
|
||||
Set_Dlg_Item_Text(IDC_STATUSTEXT, download->GetStatusText());
|
||||
break;
|
||||
|
||||
case DownloadEvent::DOWNLOAD_PROGRESS:
|
||||
{
|
||||
int read = 0;
|
||||
int size = 0;
|
||||
int elapsed = 0;
|
||||
int remaining = 0;
|
||||
download->GetProgress(read, size, elapsed, remaining);
|
||||
|
||||
if (ConsoleBox.Is_Exclusive())
|
||||
{
|
||||
|
||||
if (!mDownloading)
|
||||
{
|
||||
mStartTime = TIMEGETTIME();
|
||||
mDownloading = true;
|
||||
}
|
||||
|
||||
// Calculate the transfer rate
|
||||
unsigned long transferRate = read;
|
||||
unsigned long elapsedTime = ((TIMEGETTIME() - mStartTime) / 1000);
|
||||
if (elapsedTime > 0)
|
||||
{
|
||||
transferRate = (read / elapsedTime);
|
||||
}
|
||||
|
||||
ConsoleBox.Print("Got %d Kb of %d at %d Kb per second \r", read/1024, size/1024, transferRate / 1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update progress bar
|
||||
ProgressCtrlClass* progress = (ProgressCtrlClass*)Get_Dlg_Item(IDC_PROGRESS);
|
||||
|
||||
if (progress)
|
||||
{
|
||||
// If we have just begun downloading then set the progress bar range
|
||||
// for the size of the new file.
|
||||
if (!mDownloading)
|
||||
{
|
||||
progress->Set_Range(0, size);
|
||||
mStartTime = TIMEGETTIME();
|
||||
mDownloading = true;
|
||||
}
|
||||
|
||||
progress->Set_Position(read);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Update download statistics
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
// Calculate the transfer rate
|
||||
unsigned long transferRate = read;
|
||||
unsigned long elapsedTime = ((TIMEGETTIME() - mStartTime) / 1000);
|
||||
|
||||
if (elapsedTime > 0)
|
||||
{
|
||||
transferRate = (read / elapsedTime);
|
||||
}
|
||||
|
||||
// Update transfer rate.
|
||||
WideStringClass sizetext(64, true);
|
||||
PrintableSize(transferRate, sizetext);
|
||||
|
||||
WideStringClass text(0, true);
|
||||
text.Format(TRANSLATE(IDS_MENU_TRANSFER_RATE_PER_SEC), (const WCHAR*)sizetext);
|
||||
Set_Dlg_Item_Text(IDC_TRANSFERTEXT, text);
|
||||
|
||||
// Calculate estimated time based on the current transfer rate.
|
||||
unsigned long estimatedTime = 0;
|
||||
|
||||
if (transferRate > 0)
|
||||
{
|
||||
estimatedTime = ((size - read) / transferRate);
|
||||
}
|
||||
|
||||
// Update estimated time and read / total
|
||||
WideStringClass timetext(64,true);
|
||||
PrintableTime(estimatedTime, timetext);
|
||||
|
||||
WideStringClass readtext(64, true);
|
||||
PrintableSize(read, readtext);
|
||||
|
||||
PrintableSize(size, sizetext);
|
||||
|
||||
text.Format(TRANSLATE(IDS_MENU_TRANSFER_TIME_LEFT),
|
||||
(const WCHAR*)timetext, (const WCHAR*)readtext, (const WCHAR*)sizetext);
|
||||
|
||||
Set_Dlg_Item_Text(IDC_PROGRESSTEXT, text);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DownloadEvent::DOWNLOAD_BEGIN:
|
||||
if (ConsoleBox.Is_Exclusive())
|
||||
{
|
||||
ConsoleBox.Print("\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case DownloadEvent::DOWNLOAD_END:
|
||||
if (ConsoleBox.Is_Exclusive())
|
||||
{
|
||||
ConsoleBox.Print("\nDownload complete\n");
|
||||
}
|
||||
WWDEBUG_SAY(("DlgDownload: Successful '%s' Elapsed time: %ld ms\n",
|
||||
download->GetFilename(), (TIMEGETTIME() - mStartTime)));
|
||||
|
||||
mDownloading = false;
|
||||
break;
|
||||
|
||||
case DownloadEvent::DOWNLOAD_STOPPED:
|
||||
WWDEBUG_SAY(("DlgDownload: Stopped '%s'\n", download->GetFilename()));
|
||||
mDownloading = false;
|
||||
break;
|
||||
|
||||
case DownloadEvent::DOWNLOAD_ERROR:
|
||||
WWDEBUG_SAY(("DlgDownload: Error '%s'\n", download->GetFilename()));
|
||||
mDownloading = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgDownload::HandleCallback
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgDownload::HandleCallback(DownloadEvent& event, unsigned long userdata)
|
||||
{
|
||||
DlgDownload* dialog = (DlgDownload*)userdata;
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
dialog->UpdateProgress(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* PrintableSize
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get filesize in a printable format.
|
||||
*
|
||||
* INPUTS
|
||||
* Size -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void PrintableSize(unsigned long size, WideStringClass& printable)
|
||||
{
|
||||
float value = ((float)size / (float)(1024 * 1024));
|
||||
|
||||
if (value >= 1.0)
|
||||
{
|
||||
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_MB_FORMAT), value);
|
||||
return;
|
||||
}
|
||||
|
||||
value = ((float)size / 1024.0);
|
||||
|
||||
if (value >= 1.0)
|
||||
{
|
||||
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_KB_FORMAT), value);
|
||||
return;
|
||||
}
|
||||
|
||||
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_BYTE_FORMAT), size);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* PrintableTime
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get time in a printable format.
|
||||
*
|
||||
* INPUTS
|
||||
* Size -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void PrintableTime(unsigned long time, WideStringClass& printable)
|
||||
{
|
||||
unsigned long minutes = (time / 60);
|
||||
unsigned long seconds = (time % 60);
|
||||
|
||||
if (minutes > 0)
|
||||
{
|
||||
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_MIN_SEC_FORMAT), minutes, seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
seconds = max<unsigned long>(seconds, 1);
|
||||
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_SEC_FORMAT), seconds);
|
||||
}
|
||||
}
|
||||
74
Code/Commando/DlgDownload.h
Normal file
74
Code/Commando/DlgDownload.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgDownload.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* File download dialog.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 5 $
|
||||
* $Modtime: 12/20/01 9:43a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGDOWNLOAD_H__
|
||||
#define __DLGDOWNLOAD_H__
|
||||
|
||||
#include <WWUI\PopupDialog.h>
|
||||
#include <WWOnline\WOLDownload.h>
|
||||
|
||||
class DlgDownload :
|
||||
public PopupDialogClass
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(const WCHAR* title, const WWOnline::DownloadList& files, bool quiet = false);
|
||||
|
||||
protected:
|
||||
DlgDownload();
|
||||
~DlgDownload();
|
||||
|
||||
// Prevent copy and assignment
|
||||
DlgDownload(const DlgDownload&);
|
||||
const DlgDownload& operator=(const DlgDownload&);
|
||||
|
||||
bool FinalizeCreate(const WWOnline::DownloadList& files);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
void On_Periodic(void);
|
||||
|
||||
void UpdateProgress(WWOnline::DownloadEvent& event);
|
||||
static void HandleCallback(WWOnline::DownloadEvent& event, unsigned long userdata);
|
||||
|
||||
private:
|
||||
RefPtr<WWOnline::DownloadWait> mWait;
|
||||
|
||||
unsigned long mStartTime;
|
||||
bool mDownloading;
|
||||
static bool mQuietMode;
|
||||
};
|
||||
|
||||
#endif // __DLGDOWNLOAD_H__
|
||||
294
Code/Commando/DlgMPConnect.cpp
Normal file
294
Code/Commando/DlgMPConnect.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgMPConnect.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Dialog to inform user that we are connecting to a game host.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Tom_s $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 12 $
|
||||
* $Modtime: 2/25/02 11:29a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "dlgmpconnect.h"
|
||||
#include "gamedata.h"
|
||||
#include "gameinitmgr.h"
|
||||
#include "campaign.h"
|
||||
#include "cnetwork.h"
|
||||
#include "resource.h"
|
||||
#include <wwdebug\wwdebug.h>
|
||||
#include "dlgmainmenu.h"
|
||||
#include "gamespyadmin.h"
|
||||
#include "specialbuilds.h"
|
||||
#include "dialogtests.h"
|
||||
#include "dialogmgr.h"
|
||||
#include "gamemode.h"
|
||||
#include "langmode.h"
|
||||
#include "wolgmode.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if dialog created successfully.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgMPConnect::DoDialog(int teamChoice, unsigned long clanID)
|
||||
{
|
||||
DlgMPConnect* popup = new DlgMPConnect(teamChoice, clanID);
|
||||
|
||||
if (popup)
|
||||
{
|
||||
popup->Start_Dialog();
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::DlgMPConnect
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgMPConnect::DlgMPConnect(int teamChoice, unsigned long clanID) :
|
||||
PopupDialogClass(IDD_MULTIPLAY_CONNECTING),
|
||||
mTeamChoice(teamChoice),
|
||||
mClanID(clanID),
|
||||
mTheGame(NULL),
|
||||
mFailed(false)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgMPConnect: Instantiated\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::~DlgMPConnect
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgMPConnect::~DlgMPConnect()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgMPConnect: Destructing\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::Connected
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle connection.
|
||||
*
|
||||
* INPUTS
|
||||
* GameData - Pointer to game data instance
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMPConnect::Connected(cGameData* theGame)
|
||||
{
|
||||
mTheGame = theGame;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::Connected
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle connection.
|
||||
*
|
||||
* INPUTS
|
||||
* GameData - Pointer to game data instance
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMPConnect::Failed_To_Connect(void)
|
||||
{
|
||||
mFailed = true;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process command messages from controls
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control
|
||||
* Message -
|
||||
* Param - 0 = User invoked abort. 1 = Connection refused by server.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMPConnect::On_Command(int ctrlID, int message, DWORD param)
|
||||
{
|
||||
if ((IDCANCEL == ctrlID) && (1 != param))
|
||||
{
|
||||
if (cNetwork::I_Am_Client())
|
||||
{
|
||||
cNetwork::Cleanup_Client();
|
||||
}
|
||||
if (cGameSpyAdmin::Get_Is_Launched_From_Gamespy())
|
||||
{
|
||||
extern void Stop_Main_Loop (int);
|
||||
Stop_Main_Loop(EXIT_SUCCESS);
|
||||
}
|
||||
else if (DialogMgrClass::Get_Dialog_Count () == 1)
|
||||
{
|
||||
START_DIALOG (MainMenuDialogClass);
|
||||
}
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Command(ctrlID, message, param);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnect::On_Periodic
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMPConnect::On_Periodic(void)
|
||||
{
|
||||
PopupDialogClass::On_Periodic();
|
||||
|
||||
if (mTheGame != NULL)
|
||||
{
|
||||
// Add a reference to keep us alive while we process the game start
|
||||
Add_Ref();
|
||||
|
||||
// Remove the dialog from menuing system
|
||||
End_Dialog();
|
||||
|
||||
// Check to ensure the settings are playable
|
||||
WideStringClass outMsg;
|
||||
|
||||
if (mTheGame->Is_Valid_Settings(outMsg))
|
||||
{
|
||||
WWDEBUG_SAY(("DlgMPConnect: Starting the game.\n"));
|
||||
|
||||
CampaignManager::Select_Backdrop_Number_By_MP_Type(mTheGame->Get_Game_Type());
|
||||
|
||||
// Start the game!
|
||||
GameInitMgrClass::Set_Is_Client_Required(true);
|
||||
GameInitMgrClass::Set_Is_Server_Required(false);
|
||||
GameInitMgrClass::Start_Game(mTheGame->Get_Map_Name(), mTeamChoice, mClanID);
|
||||
}
|
||||
else
|
||||
{
|
||||
WWDEBUG_SAY(("ERROR: %s\n", (const WCHAR*)outMsg));
|
||||
}
|
||||
|
||||
// Release the keep alive reference (this will delete this object)
|
||||
Release_Ref();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mFailed)
|
||||
{
|
||||
|
||||
Add_Ref();
|
||||
|
||||
// Remove the dialog from menuing system
|
||||
End_Dialog();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Release_Ref();
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Code/Commando/DlgMPConnect.h
Normal file
76
Code/Commando/DlgMPConnect.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgMPConnect.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Dialog to inform user that we are connecting to a game host.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Steve_t $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 4 $
|
||||
* $Modtime: 2/14/02 2:03p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGMPCONNECT_H__
|
||||
#define __DLGMPCONNECT_H__
|
||||
|
||||
#include <WWUI\PopupDialog.h>
|
||||
|
||||
class cGameData;
|
||||
|
||||
class DlgMPConnect :
|
||||
public PopupDialogClass
|
||||
{
|
||||
public:
|
||||
// Display connecting dialog.
|
||||
// TeamChoice - Team preference of connecting player
|
||||
// ClanID - ID of players clan (0 if not a clan game)
|
||||
static bool DoDialog(int teamChoice, unsigned long clanID);
|
||||
|
||||
void Connected(cGameData* theGame);
|
||||
void Failed_To_Connect(void);
|
||||
|
||||
|
||||
protected:
|
||||
DlgMPConnect(int teamChoice, unsigned long clanID);
|
||||
virtual ~DlgMPConnect();
|
||||
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
void On_Periodic(void);
|
||||
|
||||
private:
|
||||
// Prevent copy and assignment
|
||||
DlgMPConnect(const DlgMPConnect&);
|
||||
const DlgMPConnect& operator=(const DlgMPConnect&);
|
||||
|
||||
int mTeamChoice;
|
||||
unsigned long mClanID;
|
||||
|
||||
cGameData* mTheGame;
|
||||
bool mFailed;
|
||||
};
|
||||
|
||||
#endif // __DLGMPCONNECT_H__
|
||||
195
Code/Commando/DlgMPConnectionRefused.cpp
Normal file
195
Code/Commando/DlgMPConnectionRefused.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgMPConnectionRefused.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgMPConnectionRefused.h"
|
||||
#include "cnetwork.h"
|
||||
#include "resource.h"
|
||||
#include <wwdebug\wwdebug.h>
|
||||
#include "dlgmainmenu.h"
|
||||
#include "gamespyadmin.h"
|
||||
#include "specialbuilds.h"
|
||||
#include "dialogtests.h"
|
||||
#include "dialogmgr.h"
|
||||
#include "gameinitmgr.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnectionRefused::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if dialog created successfully.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgMPConnectionRefused::DoDialog(const WCHAR * text, bool show_splash_screen)
|
||||
{
|
||||
DlgMPConnectionRefused* popup = new DlgMPConnectionRefused(text, show_splash_screen);
|
||||
|
||||
if (popup)
|
||||
{
|
||||
popup->Start_Dialog();
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnectionRefused::DlgMPConnectionRefused
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgMPConnectionRefused::DlgMPConnectionRefused(const WCHAR * text, bool show_splash_screen) :
|
||||
PopupDialogClass(IDD_MULTIPLAY_CONNECTION_REFUSED)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgMPConnectionRefused: Instantiated\n"));
|
||||
|
||||
WWASSERT(text != NULL);
|
||||
Text.Format(text);
|
||||
|
||||
ShowSplashScreen = show_splash_screen;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnectionRefused::~DlgMPConnectionRefused
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgMPConnectionRefused::~DlgMPConnectionRefused()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgMPConnectionRefused: Destructing\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnectionRefused::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMPConnectionRefused::On_Init_Dialog(void)
|
||||
{
|
||||
Set_Dlg_Item_Text(IDC_REFUSAL_TEXT, Text);
|
||||
|
||||
PopupDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMPConnectionRefused::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process command messages from controls
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control
|
||||
* Message -
|
||||
* Param - 0 = User invoked abort. 1 = Connection refused by server.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMPConnectionRefused::On_Command(int ctrlID, int message, DWORD param)
|
||||
{
|
||||
if ((IDOK == ctrlID) && (1 != param))
|
||||
{
|
||||
if (cNetwork::I_Am_Client())
|
||||
{
|
||||
cNetwork::Cleanup_Client();
|
||||
}
|
||||
if (cGameSpyAdmin::Get_Is_Launched_From_Gamespy())
|
||||
{
|
||||
|
||||
#ifdef MULTIPLAYERDEMO
|
||||
GameInitMgrClass::End_Game ();
|
||||
if (ShowSplashScreen)
|
||||
{
|
||||
DialogMgrClass::Flush_Dialogs ();
|
||||
START_DIALOG (SplashOutroMenuDialogClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
extern void Stop_Main_Loop (int);
|
||||
Stop_Main_Loop(EXIT_SUCCESS);
|
||||
}
|
||||
#else
|
||||
extern void Stop_Main_Loop (int);
|
||||
Stop_Main_Loop(EXIT_SUCCESS);
|
||||
#endif // MULTIPLAYERDEMO
|
||||
}
|
||||
|
||||
else if (DialogMgrClass::Get_Dialog_Count () == 1)
|
||||
{
|
||||
START_DIALOG (MainMenuDialogClass);
|
||||
}
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Command(ctrlID, message, param);
|
||||
}
|
||||
55
Code/Commando/DlgMPConnectionRefused.h
Normal file
55
Code/Commando/DlgMPConnectionRefused.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgMPConnectionRefused.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGMPCONNECTIONREFUSED_H__
|
||||
#define __DLGMPCONNECTIONREFUSED_H__
|
||||
|
||||
#include <WWUI\PopupDialog.h>
|
||||
|
||||
class DlgMPConnectionRefused :
|
||||
public PopupDialogClass
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(const WCHAR * text, bool show_splash_screen);
|
||||
void On_Init_Dialog(void);
|
||||
|
||||
protected:
|
||||
DlgMPConnectionRefused(const WCHAR * text, bool show_splash_screen);
|
||||
virtual ~DlgMPConnectionRefused();
|
||||
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
|
||||
private:
|
||||
// Prevent copy and assignment
|
||||
DlgMPConnectionRefused(const DlgMPConnectionRefused&);
|
||||
const DlgMPConnectionRefused& operator=(const DlgMPConnectionRefused&);
|
||||
|
||||
WideStringClass Text;
|
||||
bool ShowSplashScreen;
|
||||
};
|
||||
|
||||
#endif // __DLGMPCONNECTIONREFUSED_H__
|
||||
1164
Code/Commando/DlgMPTeamSelect.cpp
Normal file
1164
Code/Commando/DlgMPTeamSelect.cpp
Normal file
File diff suppressed because it is too large
Load Diff
112
Code/Commando/DlgMPTeamSelect.h
Normal file
112
Code/Commando/DlgMPTeamSelect.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgMPTeamSelect.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Multiplayer team selection dialog.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 8 $
|
||||
* $Modtime: 2/11/02 11:28a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGMPTEAMSELECT_H__
|
||||
#define __DLGMPTEAMSELECT_H__
|
||||
|
||||
#include "PlayerManager.h"
|
||||
#include <WWUI\MenuDialog.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWLib\Signaler.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include "WOLGameInfo.h"
|
||||
|
||||
namespace WWOnline
|
||||
{
|
||||
class Session;
|
||||
class ChannelEvent;
|
||||
class UserEvent;
|
||||
class GameOptionsMessage;
|
||||
};
|
||||
|
||||
class cPlayer;
|
||||
|
||||
typedef TypedEventPair<bool, int> MPChooseTeamSignal;
|
||||
|
||||
class DlgMPTeamSelect :
|
||||
public MenuDialogClass,
|
||||
protected Signaler<MPChooseTeamSignal>,
|
||||
protected Observer<WWOnline::ChannelEvent>,
|
||||
protected Observer<WWOnline::UserEvent>,
|
||||
protected Observer<WWOnline::GameOptionsMessage>,
|
||||
protected Observer<PlayerMgrEvent>
|
||||
{
|
||||
public:
|
||||
static void DoDialog(Signaler<MPChooseTeamSignal>& target);
|
||||
|
||||
protected:
|
||||
DlgMPTeamSelect(void);
|
||||
~DlgMPTeamSelect();
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Frame_Update(void);
|
||||
void On_Command(int ctrlID, int message, DWORD param);
|
||||
void On_Last_Menu_Ending(void);
|
||||
|
||||
void InitSideChoice(int sidePref);
|
||||
void SelectSideChoice(int side);
|
||||
int GetSideChoice(void);
|
||||
|
||||
void RequestWOLGameInfo(void);
|
||||
|
||||
void ShowTimeRemaining(float remainingSecond);
|
||||
bool FindPlayerInListCtrl(const WCHAR* name, ListCtrlClass*& outList, int& outIndex);
|
||||
|
||||
void HandleNotification(WWOnline::ChannelEvent&);
|
||||
void HandleNotification(WWOnline::UserEvent&);
|
||||
void HandleNotification(WWOnline::GameOptionsMessage&);
|
||||
void HandleNotification(PlayerMgrEvent&);
|
||||
|
||||
static void ProcessWOLGameInfo(DlgMPTeamSelect& dialog, const char* data);
|
||||
static void ProcessWOLTeamInfo(DlgMPTeamSelect& dialog, const char* data);
|
||||
static void ProcessWOLPlayerInfo(DlgMPTeamSelect& dialog, const char* data);
|
||||
|
||||
void PopulateWithLANPlayers(void);
|
||||
void AddLANPlayerInfo(cPlayer* lanPlayer);
|
||||
void RemoveLANPlayerInfo(cPlayer* lanPlayer);
|
||||
|
||||
protected:
|
||||
bool mWOLGame;
|
||||
bool mCanChoose;
|
||||
float mTimeRemaining;
|
||||
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
WOLGameInfo mGameInfo;
|
||||
};
|
||||
|
||||
#endif // __DLGMPTEAMSELECT_H__
|
||||
277
Code/Commando/DlgMessageBox.cpp
Normal file
277
Code/Commando/DlgMessageBox.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgMessageBox.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Popup message dialog.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 7 $
|
||||
* $Modtime: 10/02/01 2:42p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgMessageBox.h"
|
||||
#include "Resource.h"
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include "WWDebug.h"
|
||||
|
||||
//
|
||||
// Class statics
|
||||
//
|
||||
int DlgMsgBox::CurrentCount = 0;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create a Popup message box dialog.
|
||||
*
|
||||
* INPUTS
|
||||
* Title - Message box title
|
||||
* Text - Message content
|
||||
*
|
||||
* RESULT
|
||||
* Object - Instance of message box
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgMsgBox::DoDialog(const WCHAR* title, const WCHAR* text,
|
||||
DlgMsgBox::Type type, Observer<DlgMsgBoxEvent>* observer, unsigned long user_data)
|
||||
{
|
||||
DlgMsgBox* popup = new DlgMsgBox;
|
||||
|
||||
if (popup)
|
||||
{
|
||||
popup->SetResourceType(type);
|
||||
popup->Start_Dialog();
|
||||
|
||||
popup->Set_Title(title);
|
||||
popup->Set_Dlg_Item_Text(IDC_MESSAGE, text);
|
||||
popup->Set_User_Data(user_data);
|
||||
|
||||
if (observer)
|
||||
{
|
||||
popup->AddObserver(*observer);
|
||||
}
|
||||
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create a Popup message box dialog.
|
||||
*
|
||||
* INPUTS
|
||||
* TitleID - ID of message box title
|
||||
* TextID - ID of message content
|
||||
*
|
||||
* RESULT
|
||||
* Object - Instance of message box
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgMsgBox::DoDialog(int titleID, int textID,
|
||||
DlgMsgBox::Type type, Observer<DlgMsgBoxEvent>* observer, unsigned long user_data)
|
||||
{
|
||||
const WCHAR* title = TranslateDBClass::Get_String(titleID);
|
||||
const WCHAR* text = TranslateDBClass::Get_String(textID);
|
||||
return DoDialog(title, text, type, observer, user_data);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::DlgMsgBox
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgMsgBox::DlgMsgBox() :
|
||||
mUserData(0),
|
||||
PopupDialogClass(IDD_MESSAGEBOX_OK)
|
||||
{
|
||||
CurrentCount++;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::~DlgMsgBox
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgMsgBox::~DlgMsgBox()
|
||||
{
|
||||
CurrentCount--;
|
||||
WWASSERT(CurrentCount >= 0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::SetResourceType
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set the type of dialog box to use.
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMsgBox::SetResourceType(DlgMsgBox::Type type)
|
||||
{
|
||||
static UINT _types[] =
|
||||
{
|
||||
IDD_MESSAGEBOX_OK,
|
||||
IDD_MESSAGEBOX_YESNO
|
||||
};
|
||||
|
||||
DialogResID = _types[type];
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::End_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMsgBox::End_Dialog(void)
|
||||
{
|
||||
Add_Ref();
|
||||
DlgMsgBoxEvent event(DlgMsgBoxEvent::Quitting, this, mUserData);
|
||||
NotifyObservers(event);
|
||||
Release_Ref();
|
||||
|
||||
PopupDialogClass::End_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgMsgBox::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process command message
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control
|
||||
* Message -
|
||||
* Param -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgMsgBox::On_Command(int ctrl, int message, DWORD param)
|
||||
{
|
||||
switch (ctrl)
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
Add_Ref();
|
||||
|
||||
DlgMsgBoxEvent event(DlgMsgBoxEvent::Okay, this, mUserData);
|
||||
NotifyObservers(event);
|
||||
|
||||
Release_Ref();
|
||||
End_Dialog();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDYES:
|
||||
{
|
||||
Add_Ref();
|
||||
|
||||
DlgMsgBoxEvent event(DlgMsgBoxEvent::Yes, this, mUserData);
|
||||
NotifyObservers(event);
|
||||
|
||||
Release_Ref();
|
||||
End_Dialog();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDNO:
|
||||
{
|
||||
Add_Ref();
|
||||
|
||||
DlgMsgBoxEvent event(DlgMsgBoxEvent::No, this, mUserData);
|
||||
NotifyObservers(event);
|
||||
|
||||
Release_Ref();
|
||||
End_Dialog();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
PopupDialogClass::On_Command(ctrl, message, param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
131
Code/Commando/DlgMessageBox.h
Normal file
131
Code/Commando/DlgMessageBox.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgMessageBox.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Popup message dialog.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 8 $
|
||||
* $Modtime: 10/13/01 4:50p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGMESSAGEBOX_H__
|
||||
#define __DLGMESSAGEBOX_H__
|
||||
|
||||
#include <WWUI\PopupDialog.h>
|
||||
#include <WWLib\Notify.h>
|
||||
|
||||
class DlgMsgBox;
|
||||
|
||||
class DlgMsgBoxEvent :
|
||||
public TypedEventPtr<DlgMsgBoxEvent, DlgMsgBox>
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
None = 0, // NULL event
|
||||
Okay, // Okay button pressed
|
||||
Yes, // Yes button pressed
|
||||
No, // No button pressed
|
||||
Quitting, // Dialog quitting.
|
||||
} EventID;
|
||||
|
||||
//! Retrieve event
|
||||
inline EventID Event(void) const
|
||||
{return mEvent;}
|
||||
|
||||
//! User data access
|
||||
inline unsigned long Get_User_Data(void) const
|
||||
{return mUserData;}
|
||||
|
||||
inline void Set_User_Data(unsigned long data)
|
||||
{mUserData = data;}
|
||||
|
||||
DlgMsgBoxEvent(EventID event, DlgMsgBox* object, unsigned long user_data) :
|
||||
TypedEventPtr<DlgMsgBoxEvent, DlgMsgBox>(object),
|
||||
mEvent(event), mUserData (user_data)
|
||||
{}
|
||||
|
||||
protected:
|
||||
// Prevent copy and assignment
|
||||
DlgMsgBoxEvent(const DlgMsgBoxEvent&);
|
||||
const DlgMsgBoxEvent& operator=(const DlgMsgBoxEvent&);
|
||||
|
||||
private:
|
||||
EventID mEvent;
|
||||
unsigned long mUserData;
|
||||
};
|
||||
|
||||
|
||||
class DlgMsgBox :
|
||||
public PopupDialogClass,
|
||||
public Notifier<DlgMsgBoxEvent>
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
Okay = 0, // Message box with okay button (Default)
|
||||
YesNo, // Yes/No message box
|
||||
} Type;
|
||||
|
||||
static bool DoDialog(const WCHAR* title, const WCHAR* text,
|
||||
DlgMsgBox::Type type = DlgMsgBox::Okay, Observer<DlgMsgBoxEvent>* observer = NULL,
|
||||
unsigned long user_data = 0);
|
||||
|
||||
static bool DoDialog(int titleID, int textID, DlgMsgBox::Type type = DlgMsgBox::Okay,
|
||||
Observer<DlgMsgBoxEvent>* observer = NULL, unsigned long user_data = 0);
|
||||
|
||||
void Set_User_Data(unsigned long user_data)
|
||||
{mUserData = user_data;}
|
||||
|
||||
unsigned long Get_User_Data(void) const
|
||||
{return mUserData;}
|
||||
|
||||
static int Get_Current_Count(void)
|
||||
{return CurrentCount;}
|
||||
|
||||
protected:
|
||||
DlgMsgBox();
|
||||
virtual ~DlgMsgBox();
|
||||
|
||||
void SetResourceType(DlgMsgBox::Type type);
|
||||
void End_Dialog(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
|
||||
DECLARE_NOTIFIER(DlgMsgBoxEvent)
|
||||
|
||||
private:
|
||||
// Prevent copy and assignment
|
||||
DlgMsgBox(const DlgMsgBox&);
|
||||
const DlgMsgBox& operator=(const DlgMsgBox&);
|
||||
|
||||
static int CurrentCount;
|
||||
unsigned long mUserData;
|
||||
};
|
||||
|
||||
#endif // __DLGMESSAGEBOX_H__
|
||||
256
Code/Commando/DlgPasswordPrompt.cpp
Normal file
256
Code/Commando/DlgPasswordPrompt.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgPasswordPrompt.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* General purpose password entry dialog for joining a game.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 3 $
|
||||
* $Modtime: 11/29/01 9:19p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgPasswordPrompt.h"
|
||||
#include <WWUI\EditCtrl.h>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create a dialog to prompt the user to enter a password.
|
||||
*
|
||||
* INPUTS
|
||||
* Target - Target to receive signal that a password was entered.
|
||||
*
|
||||
* RESULT
|
||||
* True if dialog created successfully.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgPasswordPrompt::DoDialog(Signaler<DlgPasswordPrompt>* target)
|
||||
{
|
||||
DlgPasswordPrompt* dialog = new DlgPasswordPrompt;
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
dialog->Start_Dialog();
|
||||
|
||||
if (target)
|
||||
{
|
||||
dialog->SignalMe(*target);
|
||||
}
|
||||
|
||||
dialog->Release_Ref();
|
||||
}
|
||||
|
||||
return (dialog != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::DlgPasswordPrompt
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgPasswordPrompt::DlgPasswordPrompt() :
|
||||
PopupDialogClass(IDD_MP_JOIN_PASSWORD)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgPasswordPrompt Instantiated\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::~DlgPasswordPrompt
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgPasswordPrompt::~DlgPasswordPrompt()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgPasswordPrompt Destroyed\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::GetPassword
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Retrieve the password entered by the user.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Password - Pointer to password string.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
const WCHAR* DlgPasswordPrompt::GetPassword(void) const
|
||||
{
|
||||
return Get_Dlg_Item_Text(IDC_PASSWORD_EDIT);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* One time dialog initialization.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgPasswordPrompt::On_Init_Dialog(void)
|
||||
{
|
||||
// Disable the join button until the user enters text.
|
||||
Enable_Dlg_Item(IDC_JOIN_GAME_BUTTON, false);
|
||||
|
||||
EditCtrlClass* edit = (EditCtrlClass*)Get_Dlg_Item(IDC_PASSWORD_EDIT);
|
||||
|
||||
if (edit)
|
||||
{
|
||||
edit->Set_Focus();
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle command messages from dialog controls.
|
||||
*
|
||||
* INPUTS
|
||||
* CtrlID - ID of control sending command.
|
||||
* Message - Message identifier.
|
||||
* Param - Message parameter
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgPasswordPrompt::On_Command(int ctrlID, int message, DWORD param)
|
||||
{
|
||||
if (IDC_JOIN_GAME_BUTTON == ctrlID)
|
||||
{
|
||||
Signaler<DlgPasswordPrompt>::SendSignal(*this);
|
||||
End_Dialog();
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Command(ctrlID, message, param);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::On_EditCtrl_Change
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle notification that the contents of the edit control has changed.
|
||||
*
|
||||
* INPUTS
|
||||
* Edit - Pointer to edit control whose contents has changed.
|
||||
* ID - Identifier of control.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgPasswordPrompt::On_EditCtrl_Change(EditCtrlClass* edit, int id)
|
||||
{
|
||||
if (IDC_PASSWORD_EDIT == id)
|
||||
{
|
||||
const WCHAR* text = edit->Get_Text();
|
||||
bool enableJoin = (text && (wcslen(text) > 0));
|
||||
Enable_Dlg_Item(IDC_JOIN_GAME_BUTTON, enableJoin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgPasswordPrompt::On_EditCtrl_Enter_Pressed
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle notification that the enter key was pressed in an edit control.
|
||||
*
|
||||
* INPUTS
|
||||
* Edit - Pointer to edit control whose contents has changed.
|
||||
* ID - Identifier of control.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgPasswordPrompt::On_EditCtrl_Enter_Pressed(EditCtrlClass* edit, int id)
|
||||
{
|
||||
if ((IDC_PASSWORD_EDIT == id) && Is_Dlg_Item_Enabled(IDC_JOIN_GAME_BUTTON))
|
||||
{
|
||||
On_Command(IDC_JOIN_GAME_BUTTON, 0, 0);
|
||||
}
|
||||
}
|
||||
63
Code/Commando/DlgPasswordPrompt.h
Normal file
63
Code/Commando/DlgPasswordPrompt.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgPasswordPrompt.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 3 $
|
||||
* $Modtime: 11/29/01 9:17p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "Resource.h"
|
||||
#include <WWUI\PopupDialog.h>
|
||||
#include <WWLib\Signaler.h>
|
||||
|
||||
class DlgPasswordPrompt :
|
||||
public PopupDialogClass,
|
||||
public Signaler<DlgPasswordPrompt>
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(Signaler<DlgPasswordPrompt>* target);
|
||||
|
||||
const WCHAR* GetPassword(void) const;
|
||||
|
||||
protected:
|
||||
DlgPasswordPrompt();
|
||||
~DlgPasswordPrompt();
|
||||
|
||||
// Prevent copy and assignment
|
||||
DlgPasswordPrompt(const DlgPasswordPrompt&);
|
||||
const DlgPasswordPrompt& operator=(const DlgPasswordPrompt&);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Command(int ctrlID, int mesage, DWORD param);
|
||||
void On_EditCtrl_Change(EditCtrlClass* edit, int id);
|
||||
void On_EditCtrl_Enter_Pressed(EditCtrlClass* edit, int id);
|
||||
};
|
||||
|
||||
|
||||
498
Code/Commando/DlgQuickmatch.cpp
Normal file
498
Code/Commando/DlgQuickmatch.cpp
Normal file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgQuickmatch.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Quick match dialog
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 21 $
|
||||
* $Modtime: 1/16/02 5:06p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgQuickMatch.h"
|
||||
#include "DlgWOLWait.h"
|
||||
#include "DlgMessageBox.h"
|
||||
#include "DlgMPWolQuickMatchOptions.h"
|
||||
#include "Resource.h"
|
||||
#include "DialogResource.h"
|
||||
#include "gameinitmgr.h"
|
||||
#include "WOLJoinGame.h"
|
||||
#include "String_IDs.h"
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include <WWOnline\WaitCondition.h>
|
||||
#include <WWUI\ListCtrl.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push,3)
|
||||
#endif
|
||||
|
||||
#include "systimer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if dialog successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgQuickMatch::DoDialog(void)
|
||||
{
|
||||
DlgQuickMatch* dialog = new DlgQuickMatch;
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
if (dialog->FinalizeCreate())
|
||||
{
|
||||
dialog->Start_Dialog();
|
||||
}
|
||||
|
||||
dialog->Release_Ref();
|
||||
}
|
||||
|
||||
return (dialog != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::DlgQuickMatch
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgQuickMatch::DlgQuickMatch() :
|
||||
MenuDialogClass(IDD_MP_WOL_QUICKMATCH_CONNECT),
|
||||
mTimeoutTime(0),
|
||||
mResendTime(0)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgQuickMatch: Instantiating\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::~DlgQuickMatch
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgQuickMatch::~DlgQuickMatch()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgQuickMatch: Destructing\n"));
|
||||
|
||||
if (mQuickMatch)
|
||||
{
|
||||
mQuickMatch->Release_Ref();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Finalize the creation of this object (Initialize).
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgQuickMatch::FinalizeCreate(void)
|
||||
{
|
||||
mQuickMatch = WOLQuickMatch::Create();
|
||||
|
||||
if (!mQuickMatch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Observer<QuickMatchEvent>::NotifyMe(*mQuickMatch);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::On_Init_Dialog(void)
|
||||
{
|
||||
ListCtrlClass* output = (ListCtrlClass*)Get_Dlg_Item(IDC_OUTPUT);
|
||||
WWASSERT_PRINT(output, "IDC_OUTOUT list control missing from dialog!");
|
||||
|
||||
if (output)
|
||||
{
|
||||
output->Add_Column(L"", 1.0F, Vector3 (1, 1, 1));
|
||||
}
|
||||
|
||||
Connect();
|
||||
|
||||
MenuDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::On_Frame_Update
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::On_Frame_Update(void)
|
||||
{
|
||||
if (mConnectWait.IsValid())
|
||||
{
|
||||
WaitCondition::WaitResult waitStatus = mConnectWait->GetResult();
|
||||
|
||||
if (waitStatus != WaitCondition::Waiting)
|
||||
{
|
||||
if (waitStatus == WaitCondition::ConditionMet)
|
||||
{
|
||||
SendMatchingInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputMessage(mConnectWait->GetResultText());
|
||||
}
|
||||
|
||||
mConnectWait.Release();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long theTime = TIMEGETTIME();
|
||||
|
||||
if ((mResendTime > 0) && (theTime >= mResendTime))
|
||||
{
|
||||
mQuickMatch->SendClientInfo();
|
||||
mResendTime = 0;
|
||||
}
|
||||
|
||||
// Watch for timeout
|
||||
if ((mTimeoutTime > 0) && (theTime >= mTimeoutTime))
|
||||
{
|
||||
OutputMessage(TRANSLATE(IDS_WOL_TIMEDOUT));
|
||||
mTimeoutTime = 0;
|
||||
}
|
||||
|
||||
MenuDialogClass::On_Frame_Update();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::On_Command(int ctrl, int message, DWORD param)
|
||||
{
|
||||
if (ctrl == IDC_MENU_BACK_BUTTON)
|
||||
{
|
||||
OutputMessage(IDS_QM_DISCONNECT);
|
||||
RefPtr<WaitCondition> wait = mQuickMatch->Disconnect();
|
||||
|
||||
if (wait.IsValid())
|
||||
{
|
||||
DlgWOLWait::DoDialog(IDS_QM_DISCONNECT, wait);
|
||||
}
|
||||
}
|
||||
|
||||
MenuDialogClass::On_Command(ctrl, message, param);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::Connect
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::Connect(void)
|
||||
{
|
||||
OutputMessage(IDS_QM_CONNECTING);
|
||||
mConnectWait = mQuickMatch->ConnectClient();
|
||||
|
||||
if (mConnectWait.IsValid())
|
||||
{
|
||||
mConnectWait->WaitBeginning();
|
||||
}
|
||||
|
||||
mTimeoutTime = (TIMEGETTIME() + 60000);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::SendMatchingInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::SendMatchingInfo(void)
|
||||
{
|
||||
OutputMessage(IDS_QM_SENDINGMATCHINFO);
|
||||
|
||||
bool sent = mQuickMatch->SendClientInfo();
|
||||
|
||||
if (sent)
|
||||
{
|
||||
OutputMessage(TRANSLATE (IDS_MENU_SEARCHING_FOR_MATCH));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputMessage(TRANSLATE (IDS_MENU_CANT_LOCATE_MATCH));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::OutputMessage
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Message - Message to add to output.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::OutputMessage(int messageID)
|
||||
{
|
||||
const WCHAR* message = TranslateDBClass::Get_String(messageID);
|
||||
OutputMessage(message);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::OutputMessage
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Message - Message to add to output.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::OutputMessage(const WCHAR* message)
|
||||
{
|
||||
WWDEBUG_SAY(("QM: %S\n", message));
|
||||
|
||||
ListCtrlClass* output = (ListCtrlClass*)Get_Dlg_Item(IDC_OUTPUT);
|
||||
|
||||
if (output)
|
||||
{
|
||||
int entryCount = output->Get_Entry_Count();
|
||||
output->Insert_Entry(entryCount, message);
|
||||
|
||||
// Limit message entries.
|
||||
if (entryCount > 100)
|
||||
{
|
||||
output->Delete_Entry(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::HandleNotification(QuickMatchEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle status information from quickmatch.
|
||||
*
|
||||
* INPUTS
|
||||
* Status -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::HandleNotification(QuickMatchEvent& status)
|
||||
{
|
||||
QuickMatchEvent::Event event = status.GetEvent();
|
||||
const WCHAR* msg = (const WCHAR*)status.Subject();
|
||||
|
||||
if (QuickMatchEvent::QMERROR == event)
|
||||
{
|
||||
const WideStringClass& statusMsg = status.Subject();
|
||||
|
||||
// If no match then resend the request in 10 seconds.
|
||||
if (statusMsg.Compare_No_Case(L"QM:NoMatch") == 0)
|
||||
{
|
||||
msg = TRANSLATE(IDS_QM_NOMATCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef QUICKMATCH_OPTIONS
|
||||
// Unable to match user because preferred modes are all zero.
|
||||
if (statusMsg.Compare_No_Case(L"QM:NoModes") == 0)
|
||||
{
|
||||
DlgMsgBox::DoDialog(TRANSLATE (IDS_MENU_INVALID_QM_SETTINGS_TITLE), TRANSLATE (IDS_MENU_INVALID_QM_SETTINGS),
|
||||
DlgMsgBox::Okay, this);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (QuickMatchEvent::QMMATCHED == event)
|
||||
{
|
||||
GameInitMgrClass::Set_WOL_Return_Dialog(RenegadeDialogMgrClass::LOC_INTERNET_MAIN);
|
||||
|
||||
// Join the game
|
||||
const WCHAR* gameName = (const WCHAR*)status.Subject();
|
||||
WOLJoinGame::JoinTheGame(gameName, L"", false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Assume any other message is for the user.
|
||||
OutputMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgQuickMatch::HandleNotification(DlgMsgBoxEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgQuickMatch::HandleNotification(DlgMsgBoxEvent& msgbox)
|
||||
{
|
||||
#ifdef QUICKMATCH_OPTIONS
|
||||
Add_Ref();
|
||||
|
||||
if (msgbox.Event() == DlgMsgBoxEvent::Okay)
|
||||
{
|
||||
End_Dialog();
|
||||
START_DIALOG(MPWolQuickMatchOptionsMenuClass);
|
||||
}
|
||||
|
||||
Release_Ref();
|
||||
#endif // QUICKMATCH_OPTIONS
|
||||
}
|
||||
85
Code/Commando/DlgQuickmatch.h
Normal file
85
Code/Commando/DlgQuickmatch.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgQuickmatch.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Quick match dialog
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 8 $
|
||||
* $Modtime: 8/23/01 8:30a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGQUICKMATCH_H__
|
||||
#define __DLGQUICKMATCH_H__
|
||||
|
||||
#include "WOLQuickMatch.h"
|
||||
#include <WWUI\MenuDialog.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
|
||||
class WaitCondition;
|
||||
class DlgMsgBoxEvent;
|
||||
|
||||
class DlgQuickMatch :
|
||||
public MenuDialogClass,
|
||||
public Observer<QuickMatchEvent>,
|
||||
public Observer<DlgMsgBoxEvent>
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(void);
|
||||
|
||||
protected:
|
||||
DlgQuickMatch();
|
||||
virtual ~DlgQuickMatch();
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Frame_Update(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
|
||||
void Connect(void);
|
||||
void SendMatchingInfo(void);
|
||||
|
||||
void OutputMessage(int messageID);
|
||||
void OutputMessage(const WCHAR* message);
|
||||
|
||||
void HandleNotification(QuickMatchEvent&);
|
||||
void HandleNotification(DlgMsgBoxEvent&);
|
||||
|
||||
private:
|
||||
DlgQuickMatch(const DlgQuickMatch&);
|
||||
const DlgQuickMatch& operator=(const DlgQuickMatch&);
|
||||
|
||||
WOLQuickMatch* mQuickMatch;
|
||||
RefPtr<WaitCondition> mConnectWait;
|
||||
DWORD mTimeoutTime;
|
||||
DWORD mResendTime;
|
||||
};
|
||||
|
||||
#endif // __DLGQUICKMATCH_H__
|
||||
167
Code/Commando/DlgRestart.cpp
Normal file
167
Code/Commando/DlgRestart.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgRestart.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Dialog to notify the user that the game requires a restart.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 3 $
|
||||
* $Modtime: 10/18/01 6:23p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgRestart.h"
|
||||
#include "Resource.h"
|
||||
#include "MainLoop.h"
|
||||
#include "String_IDs.h"
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgRestart::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if dialog created successfully.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgRestart::DoDialog(void)
|
||||
{
|
||||
DlgRestart* popup = new DlgRestart;
|
||||
|
||||
if (popup)
|
||||
{
|
||||
popup->Start_Dialog();
|
||||
popup->Set_Title(TRANSLATE(IDS_RESTART_TITLE));
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgRestart::DlgRestart
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgRestart::DlgRestart() :
|
||||
PopupDialogClass(IDD_MESSAGEBOX_OK)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgRestart: Instantiated\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgRestart::~DlgRestart
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgRestart::~DlgRestart()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgRestart: Destructing\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgRestart::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* One time initialzation.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgRestart::On_Init_Dialog(void)
|
||||
{
|
||||
Set_Dlg_Item_Text(IDC_MESSAGE, TRANSLATE(IDS_RESTART_PROMPT));
|
||||
PopupDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgRestart::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process command message
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control
|
||||
* Message -
|
||||
* Param -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgRestart::On_Command(int ctrl, int message, DWORD param)
|
||||
{
|
||||
if (IDOK == ctrl)
|
||||
{
|
||||
Stop_Main_Loop(RESTART_EXITCODE);
|
||||
End_Dialog();
|
||||
}
|
||||
}
|
||||
61
Code/Commando/DlgRestart.h
Normal file
61
Code/Commando/DlgRestart.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgRestart.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Dialog to notify the user that the game requires a restart.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 1 $
|
||||
* $Modtime: 10/15/01 3:12p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGRESTART_H__
|
||||
#define __DLGRESTART_H__
|
||||
|
||||
#include <WWUI\PopupDialog.h>
|
||||
|
||||
class DlgRestart :
|
||||
public PopupDialogClass
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(void);
|
||||
|
||||
protected:
|
||||
DlgRestart();
|
||||
virtual ~DlgRestart();
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
|
||||
private:
|
||||
// Prevent copy and assignment
|
||||
DlgRestart(const DlgRestart&);
|
||||
const DlgRestart& operator=(const DlgRestart&);
|
||||
};
|
||||
|
||||
#endif // __DLGRESTART_H__
|
||||
168
Code/Commando/DlgWOLAutoStart.cpp
Normal file
168
Code/Commando/DlgWOLAutoStart.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
** 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/DlgWOLAutoStart.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 12/06/01 2:04p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "always.h"
|
||||
#include "autostart.h"
|
||||
#include "win.h"
|
||||
#include "listctrl.h"
|
||||
#include "dlgwolautostart.h"
|
||||
#include "menubackdrop.h"
|
||||
#include "registry.h"
|
||||
#include "_globals.h"
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartProgressDialogClass::AutoRestartProgressDialogClass -- Constructor *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/6/2001 11:02AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
AutoRestartProgressDialogClass::AutoRestartProgressDialogClass(void) :
|
||||
MenuDialogClass (IDD_MP_AUTO_RESTART_PROGRESS)
|
||||
{
|
||||
Instance = this;
|
||||
AddItemIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartProgressDialogClass::On_Init_Dialog -- Initialise the dialog *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/6/2001 11:03AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartProgressDialogClass::On_Init_Dialog (void)
|
||||
{
|
||||
/*
|
||||
** Create the backdrop if necessary
|
||||
*/
|
||||
RegistryClass reg(APPLICATION_SUB_KEY_NAME_OPTIONS);
|
||||
if (reg.Get_Int("DisableMenuAnim", 0) == 0) {
|
||||
if (Get_BackDrop ()->Peek_Model () == NULL) {
|
||||
Get_BackDrop ()->Set_Model ("IF_BACK01");
|
||||
Get_BackDrop ()->Set_Animation ("IF_BACK01.IF_BACK01");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the columns up. Just one with nothing in it.
|
||||
*/
|
||||
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_PROGRESS_INFO);
|
||||
if (list_ctrl != NULL) {
|
||||
list_ctrl->Add_Column (L"", 1.0F, Vector3 (1, 1, 1));
|
||||
list_ctrl->Allow_Selection(false);
|
||||
list_ctrl->Set_Wants_Focus(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Start adding items at index 0.
|
||||
*/
|
||||
AddItemIndex = 0;
|
||||
|
||||
/*
|
||||
** Call the base class init.
|
||||
*/
|
||||
MenuDialogClass::On_Init_Dialog ();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartProgressDialogClass::On_Command -- Message handler for dialog *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: ID of control that message refers to *
|
||||
* ID of message *
|
||||
* misc param *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/6/2001 11:03AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartProgressDialogClass::On_Command (int ctrl_id, int message_id, DWORD param)
|
||||
{
|
||||
switch (ctrl_id)
|
||||
{
|
||||
case IDCANCEL:
|
||||
AutoRestart.Cancel();
|
||||
break;
|
||||
}
|
||||
|
||||
MenuDialogClass::On_Command (ctrl_id, message_id, param);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* AutoRestartProgressDialogClass::Add_Text -- Adds text to the progress info box *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Ptr to wide text string *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/6/2001 11:04AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void AutoRestartProgressDialogClass::Add_Text(unsigned short *txt)
|
||||
{
|
||||
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item(IDC_PROGRESS_INFO);
|
||||
if (list_ctrl) {
|
||||
list_ctrl->Insert_Entry(AddItemIndex++, txt);
|
||||
}
|
||||
}
|
||||
66
Code/Commando/DlgWOLAutoStart.h
Normal file
66
Code/Commando/DlgWOLAutoStart.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
** 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/DlgWOLAutoStart.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 11/06/01 11:06a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#pragma once
|
||||
#ifndef _DLGWOLAUTOSTART_H
|
||||
#define _DLGWOLAUTOSTART_H
|
||||
|
||||
#include "menudialog.h"
|
||||
#include "resource.h"
|
||||
|
||||
/*
|
||||
** This dialog just shows progress during a server auto start.
|
||||
**
|
||||
**
|
||||
*/
|
||||
class AutoRestartProgressDialogClass : public MenuDialogClass
|
||||
{
|
||||
public:
|
||||
AutoRestartProgressDialogClass(void);
|
||||
void On_Init_Dialog(void);
|
||||
void On_Command(int ctrl_id, int message_id, DWORD param);
|
||||
void Add_Text(unsigned short *txt);
|
||||
static AutoRestartProgressDialogClass *Get_Instance(void) {return(Instance);}
|
||||
|
||||
private:
|
||||
int AddItemIndex;
|
||||
static AutoRestartProgressDialogClass *Instance;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //_DLGWOLAUTOSTART_H
|
||||
|
||||
589
Code/Commando/DlgWOLLogon.cpp
Normal file
589
Code/Commando/DlgWOLLogon.cpp
Normal file
@@ -0,0 +1,589 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgWOLLogon.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Westwood Online Login Dialog. This is the dialog that gathers the login
|
||||
* information from the user.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 21 $
|
||||
* $Modtime: 1/19/02 12:05a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgWOLLogon.h"
|
||||
#include "RenegadeDialogMgr.h"
|
||||
#include "MPSettingsMgr.h"
|
||||
#include "DlgMessageBox.h"
|
||||
#include "DlgWOLSettings.h"
|
||||
#include <WWOnline\WOLLoginInfo.h>
|
||||
#include <WWUI\ComboBoxCtrl.h>
|
||||
#include <WWUI\EditCtrl.h>
|
||||
#include "DlgWebpage.h"
|
||||
#include "string_ids.h"
|
||||
#include "Resource.h"
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Login - Login to display
|
||||
* Observer - Observer to be notified.
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if dialog successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWOLLogon::DoDialog(const wchar_t* login, Observer<DlgWOLLogonEvent>* observer)
|
||||
{
|
||||
DlgWOLLogon* dialog = new DlgWOLLogon;
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
if (dialog->FinalizeCreate(login))
|
||||
{
|
||||
if (observer)
|
||||
{
|
||||
dialog->AddObserver(*observer);
|
||||
}
|
||||
|
||||
dialog->Start_Dialog();
|
||||
}
|
||||
|
||||
dialog->Release_Ref();
|
||||
}
|
||||
|
||||
return (dialog != NULL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::DlgWOLLogon
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgWOLLogon::DlgWOLLogon() :
|
||||
PopupDialogClass(IDD_WOL_LOGON),
|
||||
mIsPasswordEncrypted(false)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgWOLLogon: Instantiated\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::~DlgWOLLogon
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgWOLLogon::~DlgWOLLogon()
|
||||
{
|
||||
WWDEBUG_SAY(("DlgWOLLogon: Destroyed\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Finalize the creation of this object (Initialize).
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if successful.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWOLLogon::FinalizeCreate(const wchar_t* login)
|
||||
{
|
||||
mLogin = login;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Initialize the dialog.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::On_Init_Dialog(void)
|
||||
{
|
||||
Check_Dlg_Button(IDC_REMEMBER_LOGIN_CHECK, false);
|
||||
Enable_Dlg_Item(IDC_WOL_LOG_ON_BUTTON, false);
|
||||
|
||||
// Limit password length to 8 characters.
|
||||
EditCtrlClass* edit = (EditCtrlClass*)Get_Dlg_Item(IDC_PASSWORD_EDIT);
|
||||
|
||||
if (edit)
|
||||
{
|
||||
edit->Set_Text_Limit(8);
|
||||
}
|
||||
|
||||
UpdatePersonas();
|
||||
SelectPersona(mLogin);
|
||||
|
||||
PopupDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle command notification for the dialog.
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control originating command
|
||||
* Message - Command message
|
||||
* Param - Message parameter
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::On_Command(int ctrl, int message, DWORD param)
|
||||
{
|
||||
switch (ctrl)
|
||||
{
|
||||
case IDC_WOL_LOG_ON_BUTTON:
|
||||
{
|
||||
// If this login is not stored then always use the password typed by the user.
|
||||
const wchar_t* name = Get_Dlg_Item_Text(IDC_PERSONA_COMBO);
|
||||
RefPtr<LoginInfo> login = LoginInfo::Find(name);
|
||||
|
||||
if (login.IsValid() && !login->IsStored())
|
||||
{
|
||||
const wchar_t* password = Get_Dlg_Item_Text(IDC_PASSWORD_EDIT);
|
||||
login->SetPassword(password, false);
|
||||
mIsPasswordEncrypted = false;
|
||||
}
|
||||
|
||||
Add_Ref();
|
||||
DlgWOLLogonEvent event(DlgWOLLogonEvent::Login, *this);
|
||||
NotifyObservers(event);
|
||||
Release_Ref();
|
||||
|
||||
End_Dialog();
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_DELETE_ACCOUNT_BUTTON:
|
||||
{
|
||||
// Delete this login from our local cache and purge it from storage.
|
||||
const WCHAR* nickname = Get_Dlg_Item_Text(IDC_PERSONA_COMBO);
|
||||
RefPtr<LoginInfo> login = LoginInfo::Find(nickname);
|
||||
|
||||
if (login.IsValid())
|
||||
{
|
||||
login->Forget(true);
|
||||
}
|
||||
|
||||
// Refresh the UI
|
||||
UpdatePersonas();
|
||||
SelectPersona(NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_MANAGE_ACCOUNT_BUTTON:
|
||||
DlgWebPage::DoDialog("Signup");
|
||||
break;
|
||||
|
||||
case IDC_MENU_BACK_BUTTON:
|
||||
Add_Ref();
|
||||
DlgWOLLogonEvent event(DlgWOLLogonEvent::Cancel, *this);
|
||||
NotifyObservers(event);
|
||||
Release_Ref();
|
||||
break;
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Command(ctrl, message, param);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::GetLogin
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get the login information.
|
||||
*
|
||||
* INPUTS
|
||||
* Name - On return; Name to login in with.
|
||||
* Password - On return; Password to login with.
|
||||
* Encrypted - Flag indicating if the password is encrypted.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::GetLogin(const wchar_t** name, const wchar_t** password,
|
||||
bool& encrypted)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
*name = Get_Dlg_Item_Text(IDC_PERSONA_COMBO);
|
||||
}
|
||||
|
||||
if (password)
|
||||
{
|
||||
*password = Get_Dlg_Item_Text(IDC_PASSWORD_EDIT);
|
||||
}
|
||||
|
||||
encrypted = mIsPasswordEncrypted;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::IsRememberLoginChecked
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get the "checked" state of the remember login checkbox.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if remember login checkbox is selected; false otherwise.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWOLLogon::IsRememberLoginChecked(void)
|
||||
{
|
||||
return Is_Dlg_Button_Checked(IDC_REMEMBER_LOGIN_CHECK);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::UpdatePersonas
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Update the persona combo box with cached logins.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::UpdatePersonas(void)
|
||||
{
|
||||
ComboBoxCtrlClass* combo = (ComboBoxCtrlClass*)Get_Dlg_Item(IDC_PERSONA_COMBO);
|
||||
|
||||
if (combo)
|
||||
{
|
||||
combo->Reset_Content();
|
||||
|
||||
const LoginInfoList& personas = LoginInfo::GetList();
|
||||
const unsigned int count = personas.size();
|
||||
|
||||
for (unsigned int index = 0; index < count; ++index)
|
||||
{
|
||||
const WideStringClass& name = personas[index]->GetNickname();
|
||||
combo->Add_String(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::SelectPersona
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Select the persona with the specified name.
|
||||
*
|
||||
* INPUTS
|
||||
* Name - Name of persona.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::SelectPersona(const wchar_t* name)
|
||||
{
|
||||
ComboBoxCtrlClass* combo = (ComboBoxCtrlClass*)Get_Dlg_Item(IDC_PERSONA_COMBO);
|
||||
|
||||
if (combo)
|
||||
{
|
||||
// Select the specified persona or the first one in the list.
|
||||
if (name && (wcslen(name) > 0))
|
||||
{
|
||||
int index = combo->Select_String(name);
|
||||
|
||||
// If the persona is not in the list then put it into the edit field
|
||||
if (index == -1)
|
||||
{
|
||||
combo->Set_Text(name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = combo->Get_Text();
|
||||
}
|
||||
|
||||
AutoComplete(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::AutoComplete
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Automatically complete the login dialog fields if an existing login
|
||||
* matches the provided name.
|
||||
*
|
||||
* INPUTS
|
||||
* Name - Login name to auto complete.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::AutoComplete(const wchar_t* name)
|
||||
{
|
||||
// If the persona has a valid login then fill in the dialog with
|
||||
// the login information. Otherwise use the provided persona name.
|
||||
RefPtr<LoginInfo> login = LoginInfo::Find(name);
|
||||
|
||||
if (login.IsValid() && login->IsStored())
|
||||
{
|
||||
// Fill in password
|
||||
const WideStringClass& password = login->GetPassword();
|
||||
Set_Dlg_Item_Text(IDC_PASSWORD_EDIT, password);
|
||||
mIsPasswordEncrypted = login->IsPasswordEncrypted();
|
||||
|
||||
// WOL passwords must be exactly 8 characters
|
||||
WWASSERT(password.Get_Length() == 8);
|
||||
Enable_Dlg_Item(IDC_PASSWORD_EDIT, false);
|
||||
|
||||
Check_Dlg_Button(IDC_REMEMBER_LOGIN_CHECK, true);
|
||||
Enable_Dlg_Item(IDC_REMEMBER_LOGIN_CHECK, false);
|
||||
Enable_Dlg_Item(IDC_DELETE_ACCOUNT_BUTTON, true);
|
||||
Enable_Dlg_Item(IDC_WOL_LOG_ON_BUTTON, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Erase the password and enable the remember checkbox
|
||||
Set_Dlg_Item_Text(IDC_PASSWORD_EDIT, L"");
|
||||
mIsPasswordEncrypted = false;
|
||||
|
||||
Enable_Dlg_Item(IDC_PASSWORD_EDIT, true);
|
||||
Enable_Dlg_Item(IDC_REMEMBER_LOGIN_CHECK, true);
|
||||
Enable_Dlg_Item(IDC_DELETE_ACCOUNT_BUTTON, false);
|
||||
Enable_Dlg_Item(IDC_WOL_LOG_ON_BUTTON, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::On_ComboBoxCtrl_Sel_Change
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Notification sent by a combobox when the selection is changed by user
|
||||
* interaction.
|
||||
*
|
||||
* INPUTS
|
||||
* Combo - Pointer to notifying combobox control.
|
||||
* ID - ID of notifying combobox control.
|
||||
* OldSel - Index of previous selection.
|
||||
* NewSel - Index of new selection.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::On_ComboBoxCtrl_Sel_Change(ComboBoxCtrlClass* combo, int id, int, int)
|
||||
{
|
||||
if (IDC_PERSONA_COMBO == id)
|
||||
{
|
||||
const WCHAR* text = combo->Get_Text();
|
||||
AutoComplete(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::On_ComboBoxCtrl_Edit_Change
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Notification sent by a combobox when the text in the edit field is
|
||||
* changed by user interaction.
|
||||
*
|
||||
* INPUTS
|
||||
* Combo - Pointer to notifying combobox control.
|
||||
* ID - ID of notifying combobox control.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::On_ComboBoxCtrl_Edit_Change(ComboBoxCtrlClass* combo, int id)
|
||||
{
|
||||
if (IDC_PERSONA_COMBO == id)
|
||||
{
|
||||
const WCHAR* text = combo->Get_Text();
|
||||
AutoComplete(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::On_EditCtrl_Change
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Notification sent by an edit control when the text in the edit field is
|
||||
* changed by user interaction.
|
||||
*
|
||||
* INPUTS
|
||||
* Edit - Pointer to notifying edit control.
|
||||
* ID - ID of notifying edit control.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::On_EditCtrl_Change(EditCtrlClass* edit, int id)
|
||||
{
|
||||
if (IDC_PASSWORD_EDIT == id)
|
||||
{
|
||||
// If the user entered text then password is not encrypted.
|
||||
mIsPasswordEncrypted = false;
|
||||
|
||||
// WOL passwords must be exactly 8 characters
|
||||
int length = edit->Get_Text_Length();
|
||||
bool enable = (8 == length);
|
||||
Enable_Dlg_Item(IDC_WOL_LOG_ON_BUTTON, enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLLogon::On_EditCtrl_Enter_Pressed
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Notification sent by an edit control that the enter key was pressed.
|
||||
*
|
||||
* INPUTS
|
||||
* Edit - Pointer to notifying edit control.
|
||||
* ID - ID of notifying edit control.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLLogon::On_EditCtrl_Enter_Pressed(EditCtrlClass* edit, int id)
|
||||
{
|
||||
EditCtrlClass* passwordEdit = (EditCtrlClass*)Get_Dlg_Item(IDC_PASSWORD_EDIT);
|
||||
|
||||
if (passwordEdit)
|
||||
{
|
||||
const WCHAR* name = Get_Dlg_Item_Text(IDC_PERSONA_COMBO);
|
||||
bool nameOK = (name && (wcslen(name) > 0));
|
||||
bool passOK = (passwordEdit->Get_Text_Length() == 8);
|
||||
|
||||
if (nameOK && passOK)
|
||||
{
|
||||
Add_Ref();
|
||||
DlgWOLLogonEvent event(DlgWOLLogonEvent::Login, *this);
|
||||
NotifyObservers(event);
|
||||
Release_Ref();
|
||||
|
||||
End_Dialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
108
Code/Commando/DlgWOLLogon.h
Normal file
108
Code/Commando/DlgWOLLogon.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgWOLLogon.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Quick match dialog
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 14 $
|
||||
* $Modtime: 1/18/02 11:44p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGWOLLOGON_H__
|
||||
#define __DLGWOLLOGON_H__
|
||||
|
||||
#include "DlgWOLWait.h"
|
||||
#include <wwui\popupdialog.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
|
||||
class DlgWOLLogon;
|
||||
|
||||
class DlgWOLLogonEvent :
|
||||
public TypedEvent<DlgWOLLogonEvent, DlgWOLLogon>
|
||||
{
|
||||
public:
|
||||
enum Event {Cancel = 0, Login};
|
||||
|
||||
Event GetEvent(void) const
|
||||
{return mEvent;}
|
||||
|
||||
DlgWOLLogonEvent(Event event, DlgWOLLogon& dialog) :
|
||||
TypedEvent<DlgWOLLogonEvent, DlgWOLLogon>(dialog),
|
||||
mEvent(event)
|
||||
{}
|
||||
|
||||
~DlgWOLLogonEvent()
|
||||
{}
|
||||
|
||||
private:
|
||||
Event mEvent;
|
||||
};
|
||||
|
||||
|
||||
class DlgWOLLogon :
|
||||
public PopupDialogClass,
|
||||
public Notifier<DlgWOLLogonEvent>
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(const wchar_t* login, Observer<DlgWOLLogonEvent>* observer);
|
||||
|
||||
void GetLogin(const wchar_t** login, const wchar_t** password, bool& encrypted);
|
||||
bool IsRememberLoginChecked(void);
|
||||
|
||||
protected:
|
||||
DlgWOLLogon();
|
||||
virtual ~DlgWOLLogon();
|
||||
|
||||
bool FinalizeCreate(const wchar_t* login);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
|
||||
void UpdatePersonas(void);
|
||||
void SelectPersona(const wchar_t* name);
|
||||
void AutoComplete(const wchar_t* name);
|
||||
|
||||
// Notifications
|
||||
void On_ComboBoxCtrl_Sel_Change(ComboBoxCtrlClass* combo, int id, int oldsel, int newsel);
|
||||
void On_ComboBoxCtrl_Edit_Change(ComboBoxCtrlClass* combo, int id);
|
||||
void On_EditCtrl_Change(EditCtrlClass* edit, int id);
|
||||
void On_EditCtrl_Enter_Pressed(EditCtrlClass* edit, int id);
|
||||
|
||||
DECLARE_NOTIFIER(DlgWOLLogonEvent)
|
||||
|
||||
private:
|
||||
DlgWOLLogon(const DlgWOLLogon&);
|
||||
const DlgWOLLogon& operator=(const DlgWOLLogon&);
|
||||
|
||||
WideStringClass mLogin;
|
||||
bool mIsPasswordEncrypted;
|
||||
};
|
||||
|
||||
#endif // __DLGWOLLOGON_H__
|
||||
1202
Code/Commando/DlgWOLSettings.cpp
Normal file
1202
Code/Commando/DlgWOLSettings.cpp
Normal file
File diff suppressed because it is too large
Load Diff
99
Code/Commando/DlgWOLSettings.h
Normal file
99
Code/Commando/DlgWOLSettings.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgWOLSettings.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Quick match dialog
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 14 $
|
||||
* $Modtime: 1/19/02 2:29p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGWOLSETTINGS_H__
|
||||
#define __DLGWOLSETTINGS_H__
|
||||
|
||||
#include "DlgWOLWait.h"
|
||||
#include <WWUI\MenuDialog.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
|
||||
class LoginProfile;
|
||||
|
||||
class DlgWOLSettings :
|
||||
public MenuDialogClass,
|
||||
public Observer<DlgWOLWaitEvent>
|
||||
{
|
||||
public:
|
||||
static bool DoDialog(void);
|
||||
|
||||
protected:
|
||||
DlgWOLSettings();
|
||||
virtual ~DlgWOLSettings();
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Destroy(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
|
||||
bool SaveSettings(void);
|
||||
|
||||
void InitPersonaCombo(void);
|
||||
void ClearPersonaCombo(void);
|
||||
void DeleteSelectedPersona(void);
|
||||
void UpdateForPersona(void);
|
||||
|
||||
void InitServersCombo(const WWOnline::IRCServerList& servers);
|
||||
void SetServerCombo(const char* serverName);
|
||||
|
||||
void InitSideCombo(void);
|
||||
void SetSideCombo(int side);
|
||||
|
||||
void InitLocaleCombo(void);
|
||||
void SetLocaleCombo(WOL::Locale locale);
|
||||
|
||||
void InitConnectionSpeedCombo(void);
|
||||
|
||||
void On_ComboBoxCtrl_Sel_Change(ComboBoxCtrlClass* combo, int ctrl, int oldSel, int newSel);
|
||||
|
||||
void HandleNotification(DlgWOLWaitEvent&);
|
||||
|
||||
LoginProfile* GetLoginProfile(void);
|
||||
|
||||
private:
|
||||
DlgWOLSettings(const DlgWOLSettings&);
|
||||
const DlgWOLSettings& operator=(const DlgWOLSettings&);
|
||||
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
|
||||
bool DetectingBandwidth;
|
||||
bool WaitingToExitDialog;
|
||||
};
|
||||
|
||||
#endif // __DLGWOLSETTINGS_H__
|
||||
467
Code/Commando/DlgWOLWait.cpp
Normal file
467
Code/Commando/DlgWOLWait.cpp
Normal file
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgWOLWait.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Bhayes $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 21 $
|
||||
* $Modtime: 2/18/02 7:57p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgWOLWait.h"
|
||||
#include "DlgMessageBox.h"
|
||||
#include "Resource.h"
|
||||
#include "String_ids.h"
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWUI\MouseMgr.h>
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
#include "gamespyadmin.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push,3)
|
||||
#endif
|
||||
|
||||
#include "systimer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
DlgWOLWait* DlgWOLWait::mTheInstance = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Title - Title of dialog
|
||||
* Wait - Wait condition to process.
|
||||
* Observer - DlgWOLWaitEvent observer
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if dialog successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWOLWait::DoDialog(const WCHAR* title, RefPtr<WaitCondition>& wait,
|
||||
Observer<DlgWOLWaitEvent>* observer, unsigned long timeout, unsigned long dialog_timeout)
|
||||
{
|
||||
if (wait.IsValid())
|
||||
{
|
||||
DlgWOLWait* popup = new DlgWOLWait(wait, timeout, dialog_timeout);
|
||||
|
||||
if (popup)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgWOLWait: Starting dialog '%S'\n", title));
|
||||
popup->Start_Dialog();
|
||||
popup->Set_Title(title);
|
||||
|
||||
if (observer)
|
||||
{
|
||||
popup->AddObserver(*observer);
|
||||
}
|
||||
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Title - Title of dialog
|
||||
* Wait - Wait condition to process.
|
||||
* Observer - DlgWOLWaitEvent observer
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if dialog successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWOLWait::DoDialog(const WCHAR* title, const WCHAR* button_text, RefPtr<WaitCondition>& wait,
|
||||
Observer<DlgWOLWaitEvent>* observer, unsigned long timeout, unsigned long dialog_timeout)
|
||||
{
|
||||
if (wait.IsValid())
|
||||
{
|
||||
DlgWOLWait* popup = new DlgWOLWait(wait, timeout, dialog_timeout);
|
||||
|
||||
if (popup)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgWOLWait: Starting dialog '%S'\n", title));
|
||||
popup->Start_Dialog();
|
||||
popup->Set_Dlg_Item_Text(IDCANCEL, button_text);
|
||||
popup->Set_Title(title);
|
||||
|
||||
if (observer)
|
||||
{
|
||||
popup->AddObserver(*observer);
|
||||
}
|
||||
|
||||
popup->Release_Ref();
|
||||
}
|
||||
|
||||
return (popup != NULL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Title - Title ID of dialog
|
||||
* Wait - Wait condition to process.
|
||||
* Observer - DlgWOLWaitEvent observer
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if dialog successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWOLWait::DoDialog(int titleID, RefPtr<WaitCondition>& wait,
|
||||
Observer<DlgWOLWaitEvent>* observer, unsigned long timeout, unsigned long dialog_timeout)
|
||||
{
|
||||
const WCHAR* title = TranslateDBClass::Get_String(titleID);
|
||||
return DoDialog(title, wait, observer, timeout, dialog_timeout);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::DlgWOLWait
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* Wait - Wait condition to process.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgWOLWait::DlgWOLWait(RefPtr<WaitCondition>& wait, unsigned long timeout, unsigned long dialog_timeout) :
|
||||
PopupDialogClass(IDD_WOL_WAIT),
|
||||
mWait(wait),
|
||||
mStartTime(0),
|
||||
mTimeout(timeout),
|
||||
mDialogTimeout(dialog_timeout),
|
||||
mShowDialog(false)
|
||||
{
|
||||
mTheInstance = this;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::~DlgWOLWait
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgWOLWait::~DlgWOLWait()
|
||||
{
|
||||
mTheInstance = NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::On_Init_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* One time dialog initialization.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLWait::On_Init_Dialog(void)
|
||||
{
|
||||
if (mWait.IsValid())
|
||||
{
|
||||
if (!cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
mWOLSession = Session::GetInstance(false);
|
||||
WWASSERT(mWOLSession.IsValid());
|
||||
}
|
||||
|
||||
// Start the wait condition
|
||||
mWait->WaitBeginning();
|
||||
|
||||
// Set the dialogs wait text
|
||||
Set_Dlg_Item_Text(IDC_WAITTEXT, mWait->GetWaitText());
|
||||
|
||||
mStartTime = TIMEGETTIME();
|
||||
|
||||
if (mDialogTimeout != SHOW_NEVER)
|
||||
{
|
||||
// Initially the dialog is not shown so bring up the wait cursor.
|
||||
mShowDialog = false;
|
||||
MouseMgrClass::Begin_Wait_Cursor();
|
||||
}
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Init_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::On_Destroy
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLWait::On_Destroy(void)
|
||||
{
|
||||
WWDEBUG_SAY(("DlgWOLWait: Ending dialog '%S'\n", (const WCHAR*)Title));
|
||||
|
||||
if (!mShowDialog && mDialogTimeout != SHOW_NEVER)
|
||||
{
|
||||
MouseMgrClass::End_Wait_Cursor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::On_Periodic
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLWait::On_Periodic(void)
|
||||
{
|
||||
Add_Ref();
|
||||
|
||||
CheckCondition();
|
||||
PopupDialogClass::On_Periodic();
|
||||
|
||||
Release_Ref();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::CheckCondition
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check the condition of the wait.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLWait::CheckCondition(void)
|
||||
{
|
||||
// Quit if there is nothing to wait on or there is not WWOnline session.
|
||||
if (!mWait.IsValid() || (!mWOLSession.IsValid() && !cGameSpyAdmin::Is_Gamespy_Game()))
|
||||
{
|
||||
End_Dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the status of the wait condition
|
||||
WaitCondition::WaitResult waitStatus = mWait->GetResult();
|
||||
|
||||
// If we are no longer waiting then process the result.
|
||||
if (waitStatus != WaitCondition::Waiting)
|
||||
{
|
||||
// If there are no observers and the wait timed out or errored then
|
||||
// show a message dialog describing the failure.
|
||||
if ((Notifier<DlgWOLWaitEvent>::HasObservers() == false)
|
||||
&& ((waitStatus == WaitCondition::TimeOut) || (waitStatus == WaitCondition::Error)))
|
||||
{
|
||||
DlgMsgBox::DoDialog(mWait->GetWaitText(), mWait->GetResultText());
|
||||
}
|
||||
|
||||
// Notify the observers about the status of the wait.
|
||||
Add_Ref();
|
||||
DlgWOLWaitEvent event(waitStatus, mWait.ReferencedObject());
|
||||
NotifyObservers(event);
|
||||
Release_Ref();
|
||||
|
||||
End_Dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
// Change the waiting text if necessary.
|
||||
const WCHAR* text = Get_Dlg_Item_Text(IDC_WAITTEXT);
|
||||
const WideStringClass& waitText = mWait->GetWaitText();
|
||||
|
||||
if (waitText.Compare_No_Case(text) != 0)
|
||||
{
|
||||
Set_Dlg_Item_Text(IDC_WAITTEXT, waitText);
|
||||
PopupDialogClass::Build_Background_Renderers();
|
||||
}
|
||||
|
||||
// Watch for timeout
|
||||
unsigned long currTime = TIMEGETTIME();
|
||||
unsigned long timeout = mTimeout;
|
||||
unsigned long dialog_timeout = mDialogTimeout;
|
||||
|
||||
if (dialog_timeout == 0)
|
||||
{
|
||||
dialog_timeout = 2000;
|
||||
}
|
||||
|
||||
// If the dialog timeout is 0 then use the wait conditions timeout.
|
||||
if (timeout == 0)
|
||||
{
|
||||
timeout = mWait->GetTimeout();
|
||||
}
|
||||
|
||||
if ((currTime - mStartTime) > timeout)
|
||||
{
|
||||
mWait->EndWait(WaitCondition::TimeOut, TRANSLATE(IDS_WOL_TIMEDOUT));
|
||||
}
|
||||
|
||||
// Do not render until sufficient time has elapsed. This will prevent the
|
||||
// dialog from flashing in and out when the wait condition is satisfied quickly.
|
||||
if (!mShowDialog && mStartTime && dialog_timeout != SHOW_NEVER && ((currTime - mStartTime) > 2000))
|
||||
{
|
||||
mShowDialog = true;
|
||||
MouseMgrClass::End_Wait_Cursor();
|
||||
}
|
||||
|
||||
// Allow time for WWOnline processing.
|
||||
if (mWOLSession.IsValid()) mWOLSession->Process();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::On_Command
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process command message
|
||||
*
|
||||
* INPUTS
|
||||
* Ctrl - ID of control
|
||||
* Message -
|
||||
* Param -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLWait::On_Command(int ctrl, int message, DWORD param)
|
||||
{
|
||||
if ((ctrl == IDCANCEL) && mWait.IsValid())
|
||||
{
|
||||
WWDEBUG_SAY(("DlgWOLWait: UserAborted '%S'\n", (const WCHAR*)mWait->GetWaitText()));
|
||||
mWait->EndWait(WaitCondition::UserCancel, TRANSLATE(IDS_WOL_CANCELED));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWOLWait::Render
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWOLWait::Render(void)
|
||||
{
|
||||
// Do not render until sufficient time has elapsed. This will prevent the
|
||||
// dialog from flashing in and out when the wait condition is satisfied quickly.
|
||||
if (mShowDialog)
|
||||
{
|
||||
PopupDialogClass::Render();
|
||||
}
|
||||
}
|
||||
124
Code/Commando/DlgWOLWait.h
Normal file
124
Code/Commando/DlgWOLWait.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/DlgWOLWait.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Bhayes $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 14 $
|
||||
* $Modtime: 2/18/02 7:51p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGWOLWAIT_H__
|
||||
#define __DLGWOLWAIT_H__
|
||||
|
||||
#include <WWUI\PopupDialog.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include <WWOnline\WaitCondition.h>
|
||||
|
||||
namespace WWOnline
|
||||
{
|
||||
class Session;
|
||||
}
|
||||
|
||||
class DlgWOLWait;
|
||||
|
||||
class DlgWOLWaitEvent :
|
||||
public TypedEventPtr<DlgWOLWaitEvent, WaitCondition>
|
||||
{
|
||||
public:
|
||||
typedef WaitCondition::WaitResult WaitResult;
|
||||
|
||||
inline WaitResult Result(void) const
|
||||
{return mResult;}
|
||||
|
||||
DlgWOLWaitEvent(WaitResult result, WaitCondition* wait) :
|
||||
TypedEventPtr<DlgWOLWaitEvent, WaitCondition>(wait),
|
||||
mResult(result)
|
||||
{}
|
||||
|
||||
protected:
|
||||
// Prevent copy and assignment
|
||||
DlgWOLWaitEvent(const DlgWOLWaitEvent&);
|
||||
const DlgWOLWaitEvent& operator=(const DlgWOLWaitEvent&);
|
||||
|
||||
private:
|
||||
WaitResult mResult;
|
||||
};
|
||||
|
||||
|
||||
class DlgWOLWait :
|
||||
public PopupDialogClass,
|
||||
public Notifier<DlgWOLWaitEvent>
|
||||
{
|
||||
public:
|
||||
enum {SHOW_NEVER = 0xFFFFFFFF};
|
||||
|
||||
static bool DoDialog(const WCHAR* title, const WCHAR* button_text, RefPtr<WaitCondition>& wait,
|
||||
Observer<DlgWOLWaitEvent>* observer = NULL, unsigned long timeout = 0, unsigned long dialog_timeout = 0);
|
||||
|
||||
static bool DoDialog(const WCHAR* title, RefPtr<WaitCondition>& wait,
|
||||
Observer<DlgWOLWaitEvent>* observer = NULL, unsigned long timeout = 0, unsigned long dialog_timeout = 0);
|
||||
|
||||
static bool DoDialog(int titleID, RefPtr<WaitCondition>& wait,
|
||||
Observer<DlgWOLWaitEvent>* observer = NULL, unsigned long timeout = 0, unsigned long dialog_timeout = 0);
|
||||
|
||||
const RefPtr<WaitCondition>& GetWait(void)
|
||||
{return mWait;}
|
||||
|
||||
static DlgWOLWait *Get_Instance (void) { return mTheInstance; }
|
||||
|
||||
protected:
|
||||
DlgWOLWait(RefPtr<WaitCondition>& wait, unsigned long timeout, unsigned long dialog_timeout = 0);
|
||||
~DlgWOLWait();
|
||||
|
||||
// Prevent copy and assignment
|
||||
DlgWOLWait(const DlgWOLWait&);
|
||||
const DlgWOLWait& operator=(const DlgWOLWait&);
|
||||
|
||||
void CheckCondition(void);
|
||||
|
||||
void On_Init_Dialog(void);
|
||||
void On_Destroy(void);
|
||||
void On_Periodic(void);
|
||||
void On_Command(int ctrl, int message, DWORD param);
|
||||
void Render(void);
|
||||
|
||||
DECLARE_NOTIFIER(DlgWOLWaitEvent)
|
||||
|
||||
private:
|
||||
RefPtr<WaitCondition> mWait;
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
unsigned mStartTime;
|
||||
unsigned long mTimeout;
|
||||
unsigned long mDialogTimeout;
|
||||
bool mShowDialog;
|
||||
static DlgWOLWait * mTheInstance;
|
||||
};
|
||||
|
||||
#endif // __DLGWOLLOGON_H__
|
||||
361
Code/Commando/DlgWebPage.cpp
Normal file
361
Code/Commando/DlgWebPage.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgWebPage.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Web Browser dialog
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 9 $
|
||||
* $Modtime: 10/30/01 10:08p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "DlgWebPage.h"
|
||||
#include "WebBrowser.h"
|
||||
#include <WWUI\PopupDialog.h>
|
||||
#include <WWUI\DialogControl.h>
|
||||
#include <Combat\DirectInput.h>
|
||||
#include <WW3D2\WW3D.h>
|
||||
#include "DlgMessageBox.h"
|
||||
#include "Resource.h"
|
||||
#include <Combat\String_IDs.h>
|
||||
#include "WWDebug.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::DoDialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Show the specified web page.
|
||||
*
|
||||
* INPUTS
|
||||
* Page - Page to display.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWebPage::DoDialog(char* page)
|
||||
{
|
||||
WWASSERT_PRINT(page && (strlen(page) > 0), "Invalid parameter.\n");
|
||||
|
||||
if ((page == NULL) || (strlen(page) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DlgWebPage* dialog = new DlgWebPage;
|
||||
|
||||
if (dialog)
|
||||
{
|
||||
bool success = dialog->FinalizeCreate();
|
||||
|
||||
if (success)
|
||||
{
|
||||
// If we are using the embedded browser then show the webpage. Otherwise
|
||||
// ask the user if they want to launch an external browser to view the page.
|
||||
if (dialog->mBrowser->UsingEmbeddedBrowser())
|
||||
{
|
||||
dialog->Start_Dialog();
|
||||
dialog->mBrowser->ShowWebPage(page);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Increment the dialog reference so the dialog will be around for the
|
||||
// message box result.
|
||||
dialog->Add_Ref();
|
||||
|
||||
dialog->mPage = page;
|
||||
DlgMsgBox::DoDialog(0, IDS_WEB_LAUNCHBROWSER,
|
||||
DlgMsgBox::YesNo, static_cast< Observer<DlgMsgBoxEvent>* >(dialog));
|
||||
}
|
||||
}
|
||||
|
||||
// The dialog manager keeps a referenece to the dialog.
|
||||
dialog->Release_Ref();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::DlgWebPage
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Default constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgWebPage::DlgWebPage() :
|
||||
DialogBaseClass(IDD_WEBPAGE),
|
||||
mBrowser(NULL)
|
||||
{
|
||||
WWDEBUG_SAY(("Instantiating DlgWebPage\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::~DlgWebPage
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
DlgWebPage::~DlgWebPage()
|
||||
{
|
||||
WWDEBUG_SAY(("Destroying DlgWebPage\n"));
|
||||
|
||||
if (mBrowser)
|
||||
{
|
||||
mBrowser->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Finalize object creation. (Initialize object)
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if successful; False if failed.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool DlgWebPage::FinalizeCreate(void)
|
||||
{
|
||||
mBrowser = WebBrowser::CreateInstance(MainWindow);
|
||||
|
||||
if (mBrowser)
|
||||
{
|
||||
Observer<WebEvent>::NotifyMe(*mBrowser);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::Start_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWebPage::Start_Dialog(void)
|
||||
{
|
||||
DirectInput::Unacquire();
|
||||
WW3D::Flip_To_Primary();
|
||||
DialogBaseClass::Start_Dialog();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::End_Dialog
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWebPage::End_Dialog(void)
|
||||
{
|
||||
DirectInput::Acquire();
|
||||
DialogBaseClass::End_Dialog();
|
||||
SetFocus(MainWindow);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::On_Frame_Update
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWebPage::On_Frame_Update(void)
|
||||
{
|
||||
DialogBaseClass::On_Frame_Update();
|
||||
|
||||
if (mBrowser)
|
||||
{
|
||||
bool usingEmbedded = mBrowser->UsingEmbeddedBrowser();
|
||||
|
||||
if (!usingEmbedded)
|
||||
{
|
||||
bool externalRunning = mBrowser->IsExternalBrowserRunning();
|
||||
bool gameActivated = (GameInFocus || (GetTopWindow(NULL) == MainWindow)
|
||||
|| (GetForegroundWindow() == MainWindow));
|
||||
|
||||
if (!externalRunning || gameActivated)
|
||||
{
|
||||
WWDEBUG_SAY(("***** Reactivating Game *****\n"));
|
||||
|
||||
HWND topWindow = GetTopWindow(NULL);
|
||||
|
||||
if (topWindow != MainWindow)
|
||||
{
|
||||
SetForegroundWindow(MainWindow);
|
||||
ShowWindow(MainWindow, SW_RESTORE);
|
||||
}
|
||||
|
||||
End_Dialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::HandleNotification(WebEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle web event notifications
|
||||
*
|
||||
* INPUTS
|
||||
* WebEvent - WebEvent to handle
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWebPage::HandleNotification(WebEvent& event)
|
||||
{
|
||||
switch (event.Event())
|
||||
{
|
||||
case WebEvent::Quit:
|
||||
End_Dialog();
|
||||
break;
|
||||
|
||||
case WebEvent::CertificationFailed:
|
||||
{
|
||||
WebBrowser* browser = event.Subject();
|
||||
browser->Hide();
|
||||
|
||||
DlgMsgBox::DoDialog(IDS_WEB_ERROR, IDS_WEB_PAGEFAILED);
|
||||
|
||||
End_Dialog();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* DlgWebPage::HandleNotification(DlgMsgBoxEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle message box dialog event notifications
|
||||
*
|
||||
* INPUTS
|
||||
* DlgMsgBoxEvent - Message box event to handle.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void DlgWebPage::HandleNotification(DlgMsgBoxEvent& event)
|
||||
{
|
||||
switch (event.Event())
|
||||
{
|
||||
case DlgMsgBoxEvent::Yes:
|
||||
// Start the dialog to monitor the external browser.
|
||||
Start_Dialog();
|
||||
mBrowser->ShowWebPage(mPage);
|
||||
|
||||
// Release the reference we added to keep the dialog alive until this point.
|
||||
Release_Ref();
|
||||
break;
|
||||
|
||||
case DlgMsgBoxEvent::No:
|
||||
// Release the reference we added to keep the dialog alive until this point.
|
||||
Release_Ref();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
85
Code/Commando/DlgWebPage.h
Normal file
85
Code/Commando/DlgWebPage.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/DlgWebPage.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Web Browser dialog
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 4 $
|
||||
* $Modtime: 10/30/01 4:35p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __DLGWEBPAGE_H__
|
||||
#define __DLGWEBPAGE_H__
|
||||
|
||||
#include "DialogBase.h"
|
||||
#include <atlbase.h>
|
||||
#include <WWLib\Notify.h>
|
||||
|
||||
class WebBrowser;
|
||||
class WebEvent;
|
||||
class DlgMsgBoxEvent;
|
||||
|
||||
class DlgWebPage :
|
||||
public DialogBaseClass,
|
||||
public Observer<WebEvent>,
|
||||
public Observer<DlgMsgBoxEvent>
|
||||
{
|
||||
public:
|
||||
static void DoDialog(char* page);
|
||||
|
||||
protected:
|
||||
DlgWebPage();
|
||||
virtual ~DlgWebPage();
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
// Handle web browser events
|
||||
void HandleNotification(WebEvent& event);
|
||||
|
||||
// Handle message box dialog events
|
||||
void HandleNotification(DlgMsgBoxEvent& event);
|
||||
|
||||
// DialogBassClass methods
|
||||
protected:
|
||||
void Start_Dialog(void);
|
||||
void End_Dialog(void);
|
||||
void On_Frame_Update(void);
|
||||
|
||||
private:
|
||||
// Declare private to prevent copy and assignment
|
||||
DlgWebPage(const DlgWebPage&);
|
||||
const DlgWebPage& operator=(const DlgWebPage&);
|
||||
|
||||
private:
|
||||
WebBrowser* mBrowser;
|
||||
char* mPage;
|
||||
unsigned long mTimer;
|
||||
};
|
||||
|
||||
#endif // __DLGWEBPAGE_H__
|
||||
317
Code/Commando/FirewallWait.cpp
Normal file
317
Code/Commando/FirewallWait.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/FirewallWait.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Firewall negotiation wait condition.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Tom_s $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 16 $
|
||||
* $Modtime: 3/04/02 11:45a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "always.h"
|
||||
#include "FirewallWait.h"
|
||||
#include "nat.h"
|
||||
#include "string_ids.h"
|
||||
#include "translatedb.h"
|
||||
#include "natter.h"
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push,3)
|
||||
#endif
|
||||
|
||||
#include "systimer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Wait code for firewall/NAT detection.
|
||||
**
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
RefPtr<FirewallDetectWait> FirewallDetectWait::Create(void)
|
||||
{
|
||||
return new FirewallDetectWait();
|
||||
}
|
||||
|
||||
|
||||
FirewallDetectWait::FirewallDetectWait(void) :
|
||||
SingleWait(TRANSLATION(IDS_FIREWALL_NEGOTIATING_FIREWALL), 60000),
|
||||
mEvent(NULL),
|
||||
mPingsRemaining(UINT_MAX)
|
||||
{
|
||||
mWOLSession = WWOnline::Session::GetInstance(false);
|
||||
assert(mWOLSession.IsValid());
|
||||
}
|
||||
|
||||
|
||||
FirewallDetectWait::~FirewallDetectWait()
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallDetectWait: End - %S\n", mEndText));
|
||||
|
||||
mWOLSession->EnablePinging(true);
|
||||
|
||||
if (mEvent)
|
||||
{
|
||||
CloseHandle(mEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FirewallDetectWait::WaitBeginning(void)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallDetectWait: Beginning\n"));
|
||||
|
||||
mEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (mEvent == NULL)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallDetectWait: Can't create event\n"));
|
||||
EndWait(Error, TRANSLATION(IDS_FIREWALL_CREATE_EVENT_FAILED));
|
||||
}
|
||||
else
|
||||
{
|
||||
mWOLSession->EnablePinging(false);
|
||||
mTimeout = 15000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WaitCondition::WaitResult FirewallDetectWait::GetResult(void)
|
||||
{
|
||||
if (mEndResult == Waiting)
|
||||
{
|
||||
// Wait for pending pings to finish first
|
||||
unsigned int pingsWaiting = mWOLSession->GetPendingPingCount();
|
||||
|
||||
if (mPingsRemaining != pingsWaiting)
|
||||
{
|
||||
mPingsRemaining = pingsWaiting;
|
||||
mTimeout = 60000;
|
||||
FirewallHelper.Detect_Firewall(mEvent);
|
||||
}
|
||||
|
||||
if (mPingsRemaining == 0)
|
||||
{
|
||||
DWORD result = WaitForSingleObject(mEvent, 0);
|
||||
|
||||
if (result == WAIT_OBJECT_0)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallDetectWait: ConditionMet\n"));
|
||||
WOLNATInterface.Save_Firewall_Info_To_Registry();
|
||||
EndWait(ConditionMet, TRANSLATION(IDS_FIREWALL_NEGOTIATION_COMPLETE));
|
||||
}
|
||||
else if (result == WAIT_FAILED)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallDetectWait: WAIT_FAILED\n"));
|
||||
EndWait(Error, TRANSLATION(IDS_FIREWALL_NEGOTIATION_FAILED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mEndResult != Waiting)
|
||||
{
|
||||
mWOLSession->EnablePinging(true);
|
||||
}
|
||||
|
||||
return mEndResult;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Wait code for clients when trying to open up a firewall for a server connection.
|
||||
**
|
||||
*/
|
||||
RefPtr<FirewallConnectWait> FirewallConnectWait::Create(void)
|
||||
{
|
||||
return new FirewallConnectWait;
|
||||
}
|
||||
|
||||
|
||||
FirewallConnectWait::FirewallConnectWait(void) :
|
||||
SingleWait(TRANSLATION(IDS_FIREWALL_NEGOTIATING_WITH_SERVER)),
|
||||
mEvent(NULL),
|
||||
mCancelEvent(NULL),
|
||||
mSuccessFlag(FirewallHelperClass::FW_RESULT_UNKNOWN),
|
||||
mQueueCount(0),
|
||||
mLastQueueCount(0),
|
||||
mPingsRemaining(UINT_MAX)
|
||||
{
|
||||
mWOLSession = WWOnline::Session::GetInstance(false);
|
||||
assert(mWOLSession.IsValid());
|
||||
}
|
||||
|
||||
|
||||
FirewallConnectWait::~FirewallConnectWait()
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallConnectWait: End - %S\n", mEndText));
|
||||
|
||||
mWOLSession->EnablePinging(true);
|
||||
|
||||
if (mEvent)
|
||||
{
|
||||
CloseHandle(mEvent);
|
||||
}
|
||||
|
||||
if (mCancelEvent)
|
||||
{
|
||||
CloseHandle(mCancelEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FirewallConnectWait::WaitBeginning(void)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallConnectWait: Beginning\n"));
|
||||
|
||||
mEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
mCancelEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (mEvent == NULL)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallConnectWait: Can't create event\n"));
|
||||
EndWait(Error, TRANSLATION(IDS_FIREWALL_CREATE_EVENT_FAILED));
|
||||
}
|
||||
else
|
||||
{
|
||||
mWOLSession->EnablePinging(false);
|
||||
WOLNATInterface.Tell_Server_That_Client_Is_In_Channel();
|
||||
mTimeout = 15000;
|
||||
mStartTime = TIMEGETTIME();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WaitCondition::WaitResult FirewallConnectWait::GetResult(void)
|
||||
{
|
||||
if (mEndResult == Waiting)
|
||||
{
|
||||
// Wait for pending pings to finish first
|
||||
unsigned int pingsWaiting = mWOLSession->GetPendingPingCount();
|
||||
|
||||
if (mPingsRemaining != pingsWaiting)
|
||||
{
|
||||
mPingsRemaining = pingsWaiting;
|
||||
|
||||
if (mPingsRemaining == 0)
|
||||
{
|
||||
FirewallHelper.Set_Client_Connect_Event(mEvent, mCancelEvent, &mSuccessFlag, (int*)&mQueueCount);
|
||||
mTimeout = 32000;
|
||||
mStartTime = TIMEGETTIME();
|
||||
}
|
||||
}
|
||||
|
||||
if (mPingsRemaining == 0)
|
||||
{
|
||||
if ((TIMEGETTIME() - mStartTime) > mTimeout)
|
||||
{
|
||||
EndWait(TimeOut, TRANSLATION(IDS_FIREWALL_PORT_NEGOTIATION_TIMEOUT));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Maybe change the wait text if there are players queued in front of us.
|
||||
if (mQueueCount != mLastQueueCount)
|
||||
{
|
||||
wchar_t temp[256];
|
||||
swprintf(temp, TRANSLATION(IDS_FIREWALL_QUEUE_NOTIFICATION), mQueueCount);
|
||||
WideStringClass text(temp, true);
|
||||
SetWaitText(text);
|
||||
mLastQueueCount = mQueueCount;
|
||||
mTimeout = max((unsigned)32000, ((mQueueCount * 32000) + 32000));
|
||||
mStartTime = TIMEGETTIME();
|
||||
}
|
||||
|
||||
DWORD result = WaitForSingleObject(mEvent, 0);
|
||||
|
||||
if (result == WAIT_OBJECT_0)
|
||||
{
|
||||
if (mSuccessFlag == FirewallHelperClass::FW_RESULT_SUCCEEDED)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallConnectWait: ConditionMet\n"));
|
||||
EndWait(ConditionMet, TRANSLATION(IDS_FIREWALL_PORT_NEGOTIATION_COMPLETE));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(mSuccessFlag == FirewallHelperClass::FW_RESULT_FAILED);
|
||||
WWDEBUG_SAY(("FirewallConnectWait: ConditionMet\n"));
|
||||
EndWait(Error, TRANSLATION(IDS_FIREWALL_PORT_NEGOTIATION_FAILED));
|
||||
}
|
||||
}
|
||||
else if (result == WAIT_FAILED)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallConnectWait: WAIT_FAILED\n"));
|
||||
EndWait(Error, TRANSLATION(IDS_FIREWALL_PORT_NEGOTIATION_FAILED));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mEndResult != Waiting)
|
||||
{
|
||||
mWOLSession->EnablePinging(true);
|
||||
}
|
||||
|
||||
return mEndResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Override base class end wait to check for cancel being pressed.
|
||||
//
|
||||
void FirewallConnectWait::EndWait(WaitResult result, const wchar_t* endText)
|
||||
{
|
||||
WWDEBUG_SAY(("FirewallConnectWait: EndWait\n"));
|
||||
|
||||
if (result == UserCancel || result == TimeOut)
|
||||
{
|
||||
// Tell the firewall negotiation code to give up.
|
||||
SetEvent(mCancelEvent);
|
||||
}
|
||||
|
||||
// Give the firewall code a little time to respond then remove it's cancel event anyway. It'll figure it out.
|
||||
for (int i=0 ; i<100 ; i++)
|
||||
{
|
||||
if (mSuccessFlag == FirewallHelperClass::FW_RESULT_CANCELLED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
FirewallHelper.Set_Client_Connect_Event(NULL, NULL, NULL, NULL);
|
||||
|
||||
SingleWait::EndWait(result, endText);
|
||||
}
|
||||
119
Code/Commando/FirewallWait.h
Normal file
119
Code/Commando/FirewallWait.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/FirewallWait.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Firewall negotiation wait condition.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 6 $
|
||||
* $Modtime: 8/28/01 3:22p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __FIREWALLWAIT_H__
|
||||
#define __FIREWALLWAIT_H__
|
||||
|
||||
#include <WWOnline\WaitCondition.h>
|
||||
#include <windows.h>
|
||||
|
||||
namespace WWOnline
|
||||
{
|
||||
class Session;
|
||||
}
|
||||
|
||||
/*
|
||||
** Wait code for firewall/NAT detection.
|
||||
**
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
class FirewallDetectWait :
|
||||
public SingleWait
|
||||
{
|
||||
public:
|
||||
static RefPtr<FirewallDetectWait> Create(void);
|
||||
|
||||
void WaitBeginning(void);
|
||||
WaitResult GetResult(void);
|
||||
|
||||
protected:
|
||||
FirewallDetectWait();
|
||||
virtual ~FirewallDetectWait();
|
||||
|
||||
FirewallDetectWait(const FirewallDetectWait&);
|
||||
const FirewallDetectWait& operator=(const FirewallDetectWait&);
|
||||
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
unsigned int mPingsRemaining;
|
||||
|
||||
HANDLE mEvent;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Wait class for clients when trying to open up a firewall for a server connection.
|
||||
**
|
||||
*/
|
||||
class FirewallConnectWait :
|
||||
public SingleWait
|
||||
{
|
||||
public:
|
||||
static RefPtr<FirewallConnectWait> Create(void);
|
||||
|
||||
void WaitBeginning(void);
|
||||
WaitResult GetResult(void);
|
||||
virtual void EndWait(WaitResult, const wchar_t* endText);
|
||||
|
||||
protected:
|
||||
FirewallConnectWait();
|
||||
virtual ~FirewallConnectWait();
|
||||
|
||||
FirewallConnectWait(const FirewallConnectWait&);
|
||||
const FirewallConnectWait& operator=(const FirewallConnectWait&);
|
||||
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
unsigned int mPingsRemaining;
|
||||
|
||||
HANDLE mEvent;
|
||||
HANDLE mCancelEvent;
|
||||
|
||||
/*
|
||||
** Did the port negotiation succeed?
|
||||
*/
|
||||
int mSuccessFlag;
|
||||
|
||||
/*
|
||||
** How many players in the queue ahead of us?
|
||||
*/
|
||||
unsigned int mQueueCount;
|
||||
unsigned int mLastQueueCount;
|
||||
unsigned long mStartTime;
|
||||
};
|
||||
|
||||
#endif // __FIREWALLWAIT_H__
|
||||
416
Code/Commando/GameResSend.cpp
Normal file
416
Code/Commando/GameResSend.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/GameResSend.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 25 $
|
||||
* $Modtime: 1/14/02 10:40a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "GameResSend.h"
|
||||
#include "GameData.h"
|
||||
#include "Player.h"
|
||||
#include "consolemode.h"
|
||||
#include <Combat\PlayerType.h>
|
||||
#include <WWOnline\GameResPacket.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWOnline\WOLProduct.h>
|
||||
#include <WWOnline\WOLUser.h>
|
||||
#include <WWLib\CPUDetect.h>
|
||||
#include <WWLib\VerChk.h>
|
||||
#include <WWLib\CPUDetect.h>
|
||||
#include <WWLib\global.h>
|
||||
#include <WWLib\md5.h>
|
||||
#include <WW3D2\DX8Wrapper.h>
|
||||
#include <windows.h>
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
static void AddPlayerStats(GameResPacket& stats, cPlayer* player, WOL::Locale locale,
|
||||
int winnerID, bool teamGame);
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* SendGameResults
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Send game results for ladder ranking.
|
||||
*
|
||||
* INPUTS
|
||||
* TheGame - The game played.
|
||||
* Players - List of players.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void SendGameResults(unsigned long gameID, cGameData* theGame, SList<cPlayer>* playerList)
|
||||
{
|
||||
RefPtr<WWOnline::Session> session = WWOnline::Session::GetInstance(false);
|
||||
|
||||
if (!session.IsValid())
|
||||
{
|
||||
assert(session.IsValid() && "SendGameResults() WOLSession not instantiated.");
|
||||
WWDEBUG_SAY(("ERROR: SendGameResults() WOLSession not instantiated.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Gather game information
|
||||
//---------------------------------------------------------------------------
|
||||
GameResPacket stats;
|
||||
|
||||
// Unique identifier for this game session.
|
||||
stats.Add_Field("IDNO", gameID);
|
||||
|
||||
// Product SKU
|
||||
RefPtr<Product> product = Product::Current();
|
||||
unsigned long gameSKU = product->GetSKU();
|
||||
stats.Add_Field("GSKU", gameSKU);
|
||||
|
||||
// Version of executable.
|
||||
char filename[MAX_PATH];
|
||||
GetModuleFileName(NULL, filename, sizeof(filename));
|
||||
VS_FIXEDFILEINFO version;
|
||||
GetVersionInfo(filename, &version);
|
||||
stats.Add_Field("VERS", version.dwFileVersionMS);
|
||||
|
||||
// Executable build date
|
||||
FILETIME createTime;
|
||||
GetFileCreationTime(filename, &createTime);
|
||||
|
||||
SYSTEMTIME time;
|
||||
FileTimeToSystemTime(&createTime, &time);
|
||||
|
||||
char buildDate[20];
|
||||
sprintf(buildDate, "%02d/%02d/%04d %02d:%02d:%02d",
|
||||
time.wMonth, time.wDay, time.wYear, time.wHour, time.wMinute, time.wSecond);
|
||||
stats.Add_Field("DATE", buildDate);
|
||||
|
||||
// Proocessor information
|
||||
stats.Add_Field("PROC", (char*)CPUDetectClass::Get_Processor_String());
|
||||
stats.Add_Field("PSPD", (unsigned long)CPUDetectClass::Get_Processor_Speed());
|
||||
|
||||
// Amount of system memory on server
|
||||
MEMORYSTATUS memStatus;
|
||||
GlobalMemoryStatus(&memStatus);
|
||||
stats.Add_Field("SMEM", (unsigned long)memStatus.dwTotalPhys);
|
||||
|
||||
// Video card information
|
||||
DWORD cardInfo[4];
|
||||
if (ConsoleBox.Is_Exclusive()) {
|
||||
strcpy((char*)&cardInfo[0], "ConsoleMode");
|
||||
} else {
|
||||
const D3DADAPTER_IDENTIFIER8& adapter = DX8Wrapper::Get_Current_Adapter_Identifier();
|
||||
cardInfo[0] = adapter.VendorId;
|
||||
cardInfo[1] = adapter.DeviceId;
|
||||
cardInfo[2] = adapter.SubSysId;
|
||||
cardInfo[3] = adapter.Revision;
|
||||
}
|
||||
stats.Add_Field("SVID", (void*)cardInfo, sizeof(cardInfo));
|
||||
|
||||
// WOL Name of server
|
||||
const WideStringClass& owner = theGame->Get_Owner();
|
||||
StringClass serverName(true);
|
||||
owner.Convert_To(serverName);
|
||||
stats.Add_Field("SNAM", (char*)serverName.Peek_Buffer());
|
||||
|
||||
// Type of game played (Deathmatch, Capture the flag, CNC...)
|
||||
// char* gameMode = (char*)theGame->Get_Game_Type_Name();
|
||||
stats.Add_Field("MODE", "CNC");
|
||||
|
||||
// Name of the map used.
|
||||
char *map_name = (char*)(theGame->Get_Map_Name().Peek_Buffer());
|
||||
stats.Add_Field("GMAP", map_name);
|
||||
|
||||
// Was this a dedicated server?
|
||||
bool dedicatedServer = theGame->IsDedicated.Get();
|
||||
stats.Add_Field("DSVR", (char)dedicatedServer);
|
||||
|
||||
// Time game started
|
||||
LPSYSTEMTIME gameTime = theGame->Get_Game_Start_Time();
|
||||
char startTime[20];
|
||||
sprintf(startTime, "%02d/%02d/%04d %02d:%02d:%02d",
|
||||
gameTime->wMonth, gameTime->wDay, gameTime->wYear, gameTime->wHour, gameTime->wMinute, gameTime->wSecond);
|
||||
stats.Add_Field("TIME", startTime);
|
||||
|
||||
// Duration of game
|
||||
unsigned long duration = theGame->Get_Duration_Seconds();
|
||||
stats.Add_Field("DURA", duration);
|
||||
|
||||
// Average FPS
|
||||
unsigned long fps = theGame->Get_Frame_Count();
|
||||
|
||||
if (duration > 1)
|
||||
{
|
||||
fps = (fps / duration);
|
||||
}
|
||||
|
||||
stats.Add_Field("AFPS", fps);
|
||||
|
||||
// Type of tournament
|
||||
/*
|
||||
char gameType = 'I';
|
||||
|
||||
if (theGame->Is_Team_Game())
|
||||
{
|
||||
gameType = 'T';
|
||||
}
|
||||
*/
|
||||
char gameType = 'T';
|
||||
|
||||
if (theGame->IsClanGame.Is_True())
|
||||
{
|
||||
gameType = 'C';
|
||||
}
|
||||
|
||||
char ranked = (theGame->IsLaddered.Is_True() == true) ? 'Y' : 'N';
|
||||
|
||||
char tournament[5];
|
||||
sprintf(tournament, "%c%c ", gameType, ranked);
|
||||
stats.Add_Field("TRNY", tournament);
|
||||
|
||||
// Include clan information
|
||||
if (theGame->IsClanGame.Is_True())
|
||||
{
|
||||
unsigned long winningClan = 0;
|
||||
unsigned long losingClan = 0;
|
||||
|
||||
int winner = theGame->Get_Winner_ID();
|
||||
|
||||
SLNode<cPlayer>* playerNode = playerList->Head();
|
||||
|
||||
for (int index = 0; index < playerList->Get_Count(); index++)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player->Is_Human())
|
||||
{
|
||||
RefPtr<UserData> user = session->FindUser(player->Get_Name());
|
||||
|
||||
if (user.IsValid() && (user->GetSquadID() != 0))
|
||||
{
|
||||
int playerType = player->Get_Player_Type();
|
||||
|
||||
if ((playerType == winner) && (winningClan == 0))
|
||||
{
|
||||
winningClan = user->GetSquadID();
|
||||
}
|
||||
else if (losingClan == 0)
|
||||
{
|
||||
losingClan = user->GetSquadID();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stats.Add_Field("CLN1", winningClan);
|
||||
stats.Add_Field("CLN2", losingClan);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Player information
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Determine the number of players in the game
|
||||
unsigned long numPlayers = 0;
|
||||
SLNode<cPlayer>* playerNode = playerList->Head();
|
||||
|
||||
for (int index = 0; index < playerList->Get_Count(); index++)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player->Is_Human())
|
||||
{
|
||||
numPlayers++;
|
||||
}
|
||||
}
|
||||
|
||||
stats.Add_Field("PLRS", numPlayers);
|
||||
|
||||
// Gather per-player information
|
||||
int winnerID = theGame->Get_Winner_ID();
|
||||
playerNode = playerList->Head();
|
||||
|
||||
for (index = 0; index < playerList->Get_Count(); index++)
|
||||
{
|
||||
cPlayer* player = playerNode->Data();
|
||||
|
||||
if (player)
|
||||
{
|
||||
const WideStringClass& playerName = player->Get_Name();
|
||||
|
||||
// Player Location
|
||||
WOL::Locale locale = WOL::LOC_UNKNOWN;
|
||||
|
||||
RefPtr<UserData> user = session->FindUser((const WCHAR*)playerName);
|
||||
|
||||
if (user.IsValid())
|
||||
{
|
||||
locale = user->GetLocale();
|
||||
}
|
||||
|
||||
AddPlayerStats(stats, player, locale, winnerID, true);
|
||||
}
|
||||
|
||||
playerNode = playerNode->Next();
|
||||
}
|
||||
|
||||
unsigned long packetSize = 0;
|
||||
unsigned long sig_offset = 0;
|
||||
unsigned char* packet = stats.Create_Comms_Packet(packetSize, NULL, sig_offset);
|
||||
|
||||
WWDEBUG_SAY(("Sending game results packet. Size = %lu\n", packetSize));
|
||||
|
||||
#if(0)
|
||||
#ifdef _DEBUG
|
||||
HANDLE file = CreateFile("GameRes.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (INVALID_HANDLE_VALUE != file)
|
||||
{
|
||||
// Write generic contents
|
||||
DWORD written;
|
||||
WriteFile(file, packet, packetSize, &written, NULL);
|
||||
CloseHandle(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
WWDEBUG_SAY(("Failed to create GameRes.dat file."));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
session->SendGameResults(packet, packetSize);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* AddPlayerStats
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Stats - Game result packet to add player stats to.
|
||||
* Player - Player to add stats for.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void AddPlayerStats(GameResPacket& stats, cPlayer* player, WOL::Locale locale,
|
||||
int winnerID, bool isTeamed)
|
||||
{
|
||||
if (player->Is_Human())
|
||||
{
|
||||
// Players WOL name
|
||||
const WideStringClass& playerName = player->Get_Name();
|
||||
char name[10];
|
||||
int len = wcstombs(name, (const WCHAR*)playerName, 10);
|
||||
name[len] = 0;
|
||||
|
||||
stats.Add_Field("PNAM", name);
|
||||
stats.Add_Field("PLOC", (unsigned long)locale);
|
||||
|
||||
int playerType = player->Get_Player_Type();
|
||||
|
||||
// Team (bit 31:win/lose, bits 7-0:team (0 = none, 1 = GDI, 2= NOD)
|
||||
unsigned long team = 0;
|
||||
|
||||
if (isTeamed)
|
||||
{
|
||||
if (playerType == PLAYERTYPE_GDI)
|
||||
{
|
||||
team = 1;
|
||||
}
|
||||
else if (playerType == PLAYERTYPE_NOD)
|
||||
{
|
||||
team = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((isTeamed && playerType == winnerID) || (!isTeamed && player->Get_Id() == winnerID))
|
||||
{
|
||||
team |= 0x80000000;
|
||||
}
|
||||
|
||||
stats.Add_Field("TEAM", team);
|
||||
|
||||
// Score and other information
|
||||
unsigned long score = (unsigned long)max<int>(player->Get_Score(), 0);
|
||||
stats.Add_Field("PSCR", score);
|
||||
|
||||
stats.Add_Field("PPTS", (long)player->Get_Ladder_Points());
|
||||
stats.Add_Field("PTIM", (unsigned long)player->Get_Game_Time());
|
||||
stats.Add_Field("PHLT", (unsigned long)player->Get_Final_Health());
|
||||
stats.Add_Field("PKIL", (unsigned long)player->Get_Deaths());
|
||||
stats.Add_Field("EKIL", (unsigned long)player->Get_Enemies_Killed());
|
||||
stats.Add_Field("AKIL", (unsigned long)player->Get_Allies_Killed());
|
||||
stats.Add_Field("SHOT", (unsigned long)player->Get_Shots_Fired());
|
||||
stats.Add_Field("HEDF", (unsigned long)player->Get_Head_Shots());
|
||||
stats.Add_Field("TORF", (unsigned long)player->Get_Torso_Shots());
|
||||
stats.Add_Field("ARMF", (unsigned long)player->Get_Arm_Shots());
|
||||
stats.Add_Field("LEGF", (unsigned long)player->Get_Leg_Shots());
|
||||
stats.Add_Field("CRTF", (unsigned long)player->Get_Crotch_Shots());
|
||||
stats.Add_Field("PUPS", (unsigned long)player->Get_Powerups_Collected());
|
||||
stats.Add_Field("VKIL", (unsigned long)player->Get_Vehiclies_Destroyed());
|
||||
stats.Add_Field("VTIM", (unsigned long)player->Get_Vehicle_Time());
|
||||
stats.Add_Field("NKFV", (unsigned long)player->Get_Kills_From_Vehicle());
|
||||
stats.Add_Field("SQUI", (unsigned long)player->Get_Squishes());
|
||||
stats.Add_Field("PCRD", (unsigned long)player->Get_Credit_Grant());
|
||||
stats.Add_Field("BKIL", (unsigned long)player->Get_Building_Destroyed());
|
||||
stats.Add_Field("HEDR", (unsigned long)player->Get_Head_Hit());
|
||||
stats.Add_Field("TORR", (unsigned long)player->Get_Torso_Hit());
|
||||
stats.Add_Field("ARMR", (unsigned long)player->Get_Arm_Hit());
|
||||
stats.Add_Field("LEGR", (unsigned long)player->Get_Leg_Hit());
|
||||
stats.Add_Field("CRTR", (unsigned long)player->Get_Crotch_Hit());
|
||||
stats.Add_Field("FLGC", (unsigned long)0);//no more CTF! (unsigned long)player->Get_Flag_Caps());
|
||||
|
||||
// Weapon usage
|
||||
int numWeapons = min<int>(255, player->Get_Weapon_Fired_Count());
|
||||
|
||||
for (int wepIndex = 0; wepIndex < numWeapons; wepIndex++)
|
||||
{
|
||||
unsigned long weaponInfo[2] = {0,0};
|
||||
player->Get_Weapon_Fired(wepIndex, weaponInfo[0], weaponInfo[1]);
|
||||
|
||||
char token[5];
|
||||
sprintf(token, "WP%02X", wepIndex);
|
||||
stats.Add_Field(token, (void*)weaponInfo, sizeof(weaponInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Code/Commando/GameResSend.h
Normal file
49
Code/Commando/GameResSend.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/GameResSend.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 8/16/01 7:03p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __GAMERESSEND_H__
|
||||
#define __GAMERESSEND_H__
|
||||
|
||||
#include <WWLib\SList.h>
|
||||
|
||||
class cGameData;
|
||||
class cPlayer;
|
||||
|
||||
void SendGameResults(unsigned long gameID, cGameData* theGame, SList<cPlayer>* players);
|
||||
|
||||
#ifdef _DEBUG
|
||||
void SendTestGameResults(void);
|
||||
#endif
|
||||
|
||||
#endif // __GAMERESSEND_H__
|
||||
345
Code/Commando/GameSpyBanList.cpp
Normal file
345
Code/Commando/GameSpyBanList.cpp
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Renegade *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/GameSpyBanList.cpp $*
|
||||
* *
|
||||
* Original Author:: Brian Hayes *
|
||||
* *
|
||||
* $Author:: Bhayes $*
|
||||
* *
|
||||
* $Modtime:: 3/15/02 2:55p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
//
|
||||
// Filename: GameSpyBanList.cpp
|
||||
// Author: Brian Hayes
|
||||
// Date: Mar 2002
|
||||
// Description: Maintains a list of banned nicknames/hashes/ipaddresses for GameSpy Servers
|
||||
//
|
||||
|
||||
#include "cnetwork.h"
|
||||
#include "listnode.h"
|
||||
#include "GameSpyBanList.h"
|
||||
#include "ini.h"
|
||||
#include "registry.h"
|
||||
#include "rawfile.h"
|
||||
#include "gamespyauthmgr.h"
|
||||
#include "sctextobj.h"
|
||||
#include "consolemode.h"
|
||||
#include "gamesideservercontrol.h"
|
||||
|
||||
|
||||
cGameSpyBanList GameSpyBanList;
|
||||
|
||||
BanEntry::BanEntry(const char *name, const char *ip, const char *hash_id, const char *ip_mask, bool rtype) {
|
||||
|
||||
memset(nickname, 0, sizeof(nickname));
|
||||
ipaddress = 0;
|
||||
ipmask = 0xffffffff;
|
||||
memset(hashid, 0, sizeof(hashid));
|
||||
ruletype = rtype;
|
||||
|
||||
if (name) {
|
||||
strncpy(nickname, name, sizeof(nickname) - 1);
|
||||
}
|
||||
if (ip) ipaddress = inet_addr(ip);
|
||||
if (hash_id) {
|
||||
strncpy(hashid, hash_id, sizeof(hashid) - 1);
|
||||
}
|
||||
if (ip_mask) {
|
||||
ipmask = inet_addr(ip_mask);
|
||||
if (!ipmask) ipmask = 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
cGameSpyBanList::cGameSpyBanList() : BanList(NULL) {
|
||||
|
||||
BanList = new List<BanEntry *> ();
|
||||
}
|
||||
|
||||
cGameSpyBanList::~cGameSpyBanList() {
|
||||
|
||||
BanList->Delete();
|
||||
delete BanList;
|
||||
}
|
||||
|
||||
void cGameSpyBanList::Ban_User(const char *nickname, const char *challenge_response, DWORD ipaddr) {
|
||||
|
||||
char *buff = NULL;
|
||||
char *q = NULL;
|
||||
FILE *outf = NULL;
|
||||
BanEntry *t = NULL;
|
||||
|
||||
if (nickname && !challenge_response) {
|
||||
q = buff = new char[(strlen(nickname)*2)+1];
|
||||
const char *n = nickname;
|
||||
while (*n) {
|
||||
if (*n == '%') *q++ = '%';
|
||||
*q++ = *n++;
|
||||
}
|
||||
*q = 0;
|
||||
t = new BanEntry(buff);
|
||||
delete [] buff;
|
||||
} else if (challenge_response) {
|
||||
t = new BanEntry(NULL, NULL, challenge_response);
|
||||
} else if (ipaddr) {
|
||||
t = new BanEntry(NULL, cNetUtil::Address_To_String(ipaddr));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
BanList->Add_Tail(t);
|
||||
|
||||
outf = fopen("banlist.txt", "at");
|
||||
|
||||
if (outf) {
|
||||
fprintf(outf, "\"%s\" \"%s\" \"%s\" \"%s\" \"%s\"; \"%s\" console BAN\n", t->Get_Rule_Type() ? "Allow" : "Deny",
|
||||
t->Get_Nick_Name(), t->Get_Hash_ID(),
|
||||
t->Get_Ip_Address() ? cNetUtil::Address_To_String(t->Get_Ip_Address()) : "",
|
||||
t->Get_Ip_Address() ? "255.255.255.255" : "", nickname ? nickname : "");
|
||||
fclose(outf);
|
||||
}
|
||||
}
|
||||
|
||||
void cGameSpyBanList::Think(void) {
|
||||
|
||||
cPlayer *player = NULL;
|
||||
for (SLNode<cPlayer> *player_node = cPlayerManager::Get_Player_Object_List ()->Head ()
|
||||
; player_node != NULL; player_node = player_node->Next ()) {
|
||||
|
||||
player = player_node->Data ();
|
||||
WWASSERT (player != NULL);
|
||||
|
||||
if (player->Get_Is_Active().Is_False() || !player->Is_Human()) {
|
||||
continue;
|
||||
}
|
||||
if (player->Get_GameSpy_Kick_State() == GAMESPY_KICK_STATE_BEGIN &&
|
||||
TIMEGETTIME() - player->Get_GameSpy_Kick_State_Entry_Time_Ms() > 3000) {
|
||||
Final_Player_Kick(player->Get_Id());
|
||||
} else if (player->Get_GameSpy_Kick_State() == GAMESPY_KICK_STATE_INITIAL &&
|
||||
player->Get_GameSpy_Auth_State() == GAMESPY_AUTH_STATE_ACCEPTED) {
|
||||
if (Is_User_Banned(StringClass(player->Get_Name()), player->Get_GameSpy_Hash_Id(),
|
||||
player->Get_Ip_Address())) {
|
||||
Begin_Player_Kick(player->Get_Id());
|
||||
} else {
|
||||
player->Set_GameSpy_Kick_State(GAMESPY_KICK_STATE_APPROVED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool cGameSpyBanList::Begin_Player_Kick(int id) {
|
||||
|
||||
cPlayer *player = cPlayerManager::Find_Player(id);
|
||||
if (player && player->Get_Is_Active().Is_True() && player->Is_Human()) {
|
||||
|
||||
cScTextObj * p_message = new cScTextObj;
|
||||
p_message->Init(L"You've been kicked from the server. Please quit.", TEXT_MESSAGE_PRIVATE, true, HOST_TEXT_SENDER, player->Get_Id());
|
||||
player->Set_GameSpy_Kick_State(GAMESPY_KICK_STATE_BEGIN);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cGameSpyBanList::Final_Player_Kick(int id) {
|
||||
|
||||
cPlayer *player = cPlayerManager::Find_Player(id);
|
||||
if (player && player->Get_Is_Active().Is_True() && player->Is_Human()) {
|
||||
StringClass user_name = player->Get_Name();
|
||||
ConsoleBox.Print("%s was kicked\n", user_name);
|
||||
player->Set_GameSpy_Kick_State(GAMESPY_KICK_STATE_KICKED);
|
||||
cNetwork::Server_Kill_Connection(id);
|
||||
cNetwork::Cleanup_After_Client(id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cGameSpyBanList::Is_User_Banned(const char *nickname, const char *challenge_response,
|
||||
DWORD ipaddress) {
|
||||
|
||||
BanEntry *t = BanList->First();
|
||||
|
||||
bool ret = false;
|
||||
|
||||
for (;t && t->Is_Valid(); t = t->Next()) {
|
||||
|
||||
if (challenge_response && *challenge_response &&
|
||||
strcmp(challenge_response, t->Get_Hash_ID()) == 0) {
|
||||
ret = true;
|
||||
} else if (t->Get_Hash_ID() && strlen(t->Get_Hash_ID())){
|
||||
ret = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ipaddress && t->Get_Ip_Address() && ((ipaddress & t->Get_Ip_Netmask()) ==
|
||||
(t->Get_Ip_Address() & t->Get_Ip_Netmask()))) {
|
||||
ret = true;
|
||||
} else if (t->Get_Ip_Address()) {
|
||||
ret = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t->Get_Nick_Name() && nickname && strlen(t->Get_Nick_Name()) && strlen(nickname)) {
|
||||
char *a = strdup(t->Get_Nick_Name());
|
||||
char *b = strdup(nickname);
|
||||
|
||||
_strupr(a); _strupr(b);
|
||||
|
||||
//
|
||||
// This code means that you can put a BAN name in as
|
||||
// "%foo" == match on "foo" at the end of the string
|
||||
// "foo%" == match on "foo" at the beginning of the string
|
||||
// "%foo%" == match on "foo" anywhere in the string
|
||||
//
|
||||
// to match on a literal % in the nickname use %%
|
||||
//
|
||||
// Note the use of small var names to make it even more confusing
|
||||
if ( ((a[0] == '%') && (a[1] != '%')) &&
|
||||
((a[strlen(a)-1] == '%') && (a[strlen(a)-2] != '%')) ) {
|
||||
a[0] = 0;
|
||||
a[strlen(&a[1])] = 0;
|
||||
Strip_Escapes(&a[1]);
|
||||
ret = (strstr(b, &a[1]) != NULL);
|
||||
} else if ((a[0] == '%') && (a[1] != '%')) {
|
||||
a[0] = 0;
|
||||
Strip_Escapes(&a[1]);
|
||||
if (strlen(b) > (strlen(&a[1])-1)) {
|
||||
ret = (strcmp(&b[strlen(b)-strlen(&a[1])], &a[1]) == 0);
|
||||
}
|
||||
} else if (strlen(a) > 1 && (a[strlen(a)-1] == '%') && (a[strlen(a)-2] != '%')) {
|
||||
a[strlen(a)-1] = 0;
|
||||
Strip_Escapes(a);
|
||||
if (strlen(b) > (strlen(a)-1)) {
|
||||
b[strlen(a)] = 0;
|
||||
ret = (strcmp(b, a) == 0);
|
||||
}
|
||||
} else {
|
||||
Strip_Escapes(a);
|
||||
ret = (strcmp(b, a) == 0);
|
||||
}
|
||||
|
||||
free(a); free(b);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
ret = !t->Get_Rule_Type();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t && t->Is_Valid()) {
|
||||
// matched on a rule
|
||||
return ret;
|
||||
} else {
|
||||
// Everyone is good if they don't match a rule
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cGameSpyBanList::Strip_Escapes(char *var) {
|
||||
char *q = (char *)var;
|
||||
while ((q = strstr(q, "%%")) != NULL) {
|
||||
memmove(q, q+1, strlen(q));
|
||||
q++;
|
||||
}
|
||||
}
|
||||
|
||||
void cGameSpyBanList::LoadBans(void) {
|
||||
|
||||
char buff[512];
|
||||
FILE *outf = NULL;
|
||||
|
||||
if (!BanList->Is_Empty()) BanList->Delete();
|
||||
|
||||
outf = fopen("banlist.txt", "rt");
|
||||
if (!outf) return;
|
||||
buff[sizeof(buff)-1] = 0;
|
||||
|
||||
while (fgets(buff, sizeof(buff)-1, outf)) {
|
||||
// Format of each line "ruletype" "nickname" "hashid" "ip" "netmask"
|
||||
char *nickname = NULL;
|
||||
char *ruletype = NULL;
|
||||
char *ip = NULL;
|
||||
char *hashid = NULL;
|
||||
char *ipmask = NULL;
|
||||
|
||||
if (strlen(buff) < 3) continue;
|
||||
if (buff[0] == ';') continue;
|
||||
|
||||
char *s = strchr(buff, '"');
|
||||
if (!s) continue;
|
||||
*s++ = 0;
|
||||
char *q = strchr(s, '"');
|
||||
if (!q) continue;
|
||||
*q++ = 0;
|
||||
ruletype = s;
|
||||
|
||||
s = strchr(q, '"');
|
||||
if (!s) continue;
|
||||
*s++ = 0;
|
||||
q = strchr(s, '"');
|
||||
if (!q) continue;
|
||||
*q++ = 0;
|
||||
nickname = s;
|
||||
|
||||
while (q) {
|
||||
s = strchr(q, '"');
|
||||
if (!s) break;
|
||||
*s++ = 0;
|
||||
q = strchr(s, '"');
|
||||
if (!q) break;
|
||||
*q++ = 0;
|
||||
hashid = s;
|
||||
|
||||
s = strchr(q, '"');
|
||||
if (!s) break;
|
||||
*s++ = 0;
|
||||
q = strchr(s, '"');
|
||||
if (!q) break;
|
||||
*q++ = 0;
|
||||
ip = s;
|
||||
|
||||
s = strchr(q, '"');
|
||||
if (!s) break;
|
||||
*s++ = 0;
|
||||
q = strchr(s, '"');
|
||||
if (!q) break;
|
||||
*q++ = 0;
|
||||
ipmask = s;
|
||||
break;
|
||||
}
|
||||
|
||||
BanEntry *t = new BanEntry(nickname, ip, hashid, ipmask, stricmp(ruletype, "Allow") == 0);
|
||||
BanList->Add_Tail(t);
|
||||
}
|
||||
fclose(outf);
|
||||
}
|
||||
84
Code/Commando/GameSpyBanList.h
Normal file
84
Code/Commando/GameSpyBanList.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
** 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: GameSpyBanList.h
|
||||
// Author: Brian Hayes
|
||||
// Date: Mar 2002
|
||||
// Description: Maintains a list of banned nicknames/hashes/ipaddresses for GameSpy Servers
|
||||
//
|
||||
|
||||
#ifndef __GAMESPYBANLIST_H__
|
||||
#define __GAMESPYBANLIST_H__
|
||||
|
||||
#include "bittype.h"
|
||||
|
||||
enum GAMESPY_KICK_STATE_ENUM
|
||||
{
|
||||
GAMESPY_KICK_STATE_INITIAL = 0, // Just connected
|
||||
GAMESPY_KICK_STATE_APPROVED, // This user is not in the ban list
|
||||
GAMESPY_KICK_STATE_BEGIN, // Give them a message before we boot him
|
||||
GAMESPY_KICK_STATE_KICKED, // outta here.
|
||||
GAMESPY_KICK_STATE_COUNT
|
||||
};
|
||||
|
||||
class BanEntry : public Node<BanEntry *> {
|
||||
public:
|
||||
BanEntry(const char *name = NULL, const char *ip = NULL, const char *hash_id = NULL,
|
||||
const char *ip_mask = NULL, bool rtype = false);
|
||||
|
||||
protected:
|
||||
char hashid[33];
|
||||
char nickname[40];
|
||||
ULONG ipaddress;
|
||||
ULONG ipmask;
|
||||
bool ruletype;
|
||||
|
||||
public:
|
||||
const char *Get_Nick_Name(void) {return (const char *)nickname;}
|
||||
const char *Get_Hash_ID(void) {return (const char *)hashid;}
|
||||
ULONG Get_Ip_Address(void) {return ipaddress;}
|
||||
ULONG Get_Ip_Netmask(void) {return ipmask;}
|
||||
bool Get_Rule_Type(void) {return ruletype;}
|
||||
};
|
||||
|
||||
class cGameSpyBanList
|
||||
{
|
||||
|
||||
public:
|
||||
cGameSpyBanList();
|
||||
~cGameSpyBanList();
|
||||
|
||||
protected:
|
||||
List<BanEntry *> * BanList;
|
||||
bool Final_Player_Kick(int id);
|
||||
bool Begin_Player_Kick(int id);
|
||||
void Strip_Escapes(char *var);
|
||||
|
||||
public:
|
||||
void Think(void);
|
||||
bool Kick_Player(int id) { return Begin_Player_Kick(id);}
|
||||
void Ban_User(const char *nickname, const char *challenge_response = NULL,
|
||||
ULONG ipaddress = 0xffffffff);
|
||||
bool Is_User_Banned(const char *nickname, const char *challenge_response, ULONG ipaddress);
|
||||
void LoadBans(void);
|
||||
};
|
||||
|
||||
extern cGameSpyBanList GameSpyBanList;
|
||||
|
||||
#endif // __GAMESPYBANLIST_H__
|
||||
782
Code/Commando/GameSpy_QnR.cpp
Normal file
782
Code/Commando/GameSpy_QnR.cpp
Normal file
@@ -0,0 +1,782 @@
|
||||
/*
|
||||
** 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/GameSpy_QnR.cpp $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 7/08/02 5:55p $*
|
||||
* *
|
||||
* $Revision:: 17 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <Gamespy\gs_patch_usage.h>
|
||||
#include <Gamespy\gcdkeyserver.h>
|
||||
#include "specialbuilds.h"
|
||||
#include "dlgcncteaminfo.h"
|
||||
#include "resource.h"
|
||||
#include "listctrl.h"
|
||||
#include "imagectrl.h"
|
||||
#include "playertype.h"
|
||||
#include "combat.h"
|
||||
#include "teammanager.h"
|
||||
#include "playermanager.h"
|
||||
#include "player.h"
|
||||
#include "soldier.h"
|
||||
#include "gameinitmgr.h"
|
||||
#include "gamemode.h"
|
||||
#include "gamedata.h"
|
||||
#include "input.h"
|
||||
#include "healthbarctrl.h"
|
||||
#include "basecontroller.h"
|
||||
#include "building.h"
|
||||
#include "damage.h"
|
||||
#include "vehicle.h"
|
||||
#include "assets.h"
|
||||
#include "translatedb.h"
|
||||
#include "WOLGMode.h"
|
||||
#include <WWOnline\WOLUser.h>
|
||||
#include "string_ids.h"
|
||||
#include "mousemgr.h"
|
||||
#include "directinput.h"
|
||||
#include "GameSpy_QnR.h"
|
||||
#include "verchk.h"
|
||||
#include "buildnum.h"
|
||||
#include "serversettings.h"
|
||||
#include "consolemode.h"
|
||||
#include "useroptions.h"
|
||||
#include "gdcnc.h"
|
||||
#include "rawfile.h"
|
||||
#include "shellapi.h"
|
||||
#include "netutil.h"
|
||||
#include "gamespybanlist.h"
|
||||
|
||||
CGameSpyQnR GameSpyQnR;
|
||||
|
||||
#if defined(MULTIPLAYERDEMO)
|
||||
const char *CGameSpyQnR::gamename = "ccrenegadedemo";
|
||||
const char *CGameSpyQnR::bname = "Demo";
|
||||
const int CGameSpyQnR::prodid = 10063;
|
||||
const int CGameSpyQnR::cdkey_id = 0;
|
||||
#elif defined(FREEDEDICATEDSERVER)
|
||||
const char *CGameSpyQnR::bname = "FDS";
|
||||
const char *CGameSpyQnR::gamename = "ccrenegade";
|
||||
const int CGameSpyQnR::prodid = 10064;
|
||||
const int CGameSpyQnR::cdkey_id = 577;
|
||||
#elif defined(BETACLIENT)
|
||||
const char *CGameSpyQnR::bname = "Beta";
|
||||
const char *CGameSpyQnR::gamename = "ccrenegade";
|
||||
const int CGameSpyQnR::prodid = 10064;
|
||||
const int CGameSpyQnR::cdkey_id = 0;
|
||||
#else
|
||||
const char *CGameSpyQnR::bname = "Retail";
|
||||
const char *CGameSpyQnR::gamename = "ccrenegade";
|
||||
const int CGameSpyQnR::prodid = 10064;
|
||||
const int CGameSpyQnR::cdkey_id = 577;
|
||||
#endif
|
||||
|
||||
const char *CGameSpyQnR::default_heartbeat_list = "master.gamespy.com:27900, master.udpsoft.com:27900";
|
||||
|
||||
|
||||
|
||||
/*********
|
||||
These c-style callback stubs are used by the SDK. The current game object
|
||||
(passed in qr_init) is given in userdata, so we know what object to reference
|
||||
**********/
|
||||
|
||||
void c_players_callback(char *outbuf, int maxlen, void *userdata)
|
||||
{
|
||||
((CGameSpyQnR *)userdata)->players_callback(outbuf, maxlen);
|
||||
}
|
||||
|
||||
void c_rules_callback(char *outbuf, int maxlen, void *userdata)
|
||||
{
|
||||
((CGameSpyQnR *)userdata)->rules_callback(outbuf, maxlen);
|
||||
}
|
||||
|
||||
void c_info_callback(char *outbuf, int maxlen, void *userdata)
|
||||
{
|
||||
((CGameSpyQnR *)userdata)->info_callback(outbuf, maxlen);
|
||||
}
|
||||
|
||||
void c_basic_callback(char *outbuf, int maxlen, void *userdata)
|
||||
{
|
||||
((CGameSpyQnR *)userdata)->basic_callback(outbuf, maxlen);
|
||||
}
|
||||
|
||||
/***********
|
||||
A simple game object. Consists of some data and a main loop function.
|
||||
***********/
|
||||
CGameSpyQnR::CGameSpyQnR(void) : m_GSInit(FALSE), m_GSEnabled(FALSE)
|
||||
{
|
||||
// Secret keys removed per Security review requirements. LFeenanEA - 27th January 2025
|
||||
|
||||
//set the secret key, in a semi-obfuscated manner
|
||||
// tY1S8q = FULL , LsEwS3 = DEMO
|
||||
|
||||
#ifdef MULTIPLAYERDEMO
|
||||
secret_key[3] = 'R'; if (secret_key[3])
|
||||
secret_key[1] = 'E'; if (secret_key[1])
|
||||
secret_key[0] = 'M'; if (secret_key[0])
|
||||
secret_key[4] = 'O'; if (secret_key[4])
|
||||
secret_key[5] = 'V'; if (secret_key[5])
|
||||
secret_key[3] = 'E'; if (secret_key[3])
|
||||
secret_key[2] = 'D'; if (secret_key[2])
|
||||
secret_key[6] = '1'; if (secret_key[2])
|
||||
secret_key[5] = '2'; if (secret_key[5])
|
||||
secret_key[4] = '3';
|
||||
#else
|
||||
secret_key[5] = 'R'; if (secret_key[5])
|
||||
secret_key[4] = 'E'; if (secret_key[4])
|
||||
secret_key[6] = 'M'; if (secret_key[4])
|
||||
secret_key[1] = 'O'; if (secret_key[1])
|
||||
secret_key[5] = 'V'; if (secret_key[5])
|
||||
secret_key[2] = 'E'; if (secret_key[2])
|
||||
secret_key[3] = 'D'; if (secret_key[3])
|
||||
secret_key[6] = '1'; if (secret_key[3])
|
||||
secret_key[0] = '2'; if (secret_key[0])
|
||||
secret_key[3] = '3';
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
CGameSpyQnR::~CGameSpyQnR()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void CGameSpyQnR::LaunchArcade(void) {
|
||||
char *akey = "Software\\GameSpy\\GameSpy Arcade";
|
||||
BOOL launched = FALSE;
|
||||
HKEY key = NULL;
|
||||
int result = 0;
|
||||
|
||||
result = RegOpenKeyEx(HKEY_CURRENT_USER, akey, 0, KEY_READ, &key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
StringClass value(true);
|
||||
//
|
||||
// Get the size of the entry
|
||||
//
|
||||
DWORD data_size = 0;
|
||||
DWORD type = 0;
|
||||
result = ::RegQueryValueEx ((HKEY)key, "InstDir", NULL, &type, NULL, &data_size);
|
||||
if (result == ERROR_SUCCESS && type == REG_SZ) {
|
||||
|
||||
//
|
||||
// Read the entry from the registry
|
||||
//
|
||||
::RegQueryValueEx ((HKEY)key, "InstDir", NULL, &type,
|
||||
(LPBYTE)value.Get_Buffer(data_size), &data_size);
|
||||
}
|
||||
if (!value.Is_Empty()) {
|
||||
if (value[value.Get_Length()-1] == '\\') {
|
||||
value += "Aphex.exe";
|
||||
} else {
|
||||
value += "\\Aphex.exe";
|
||||
}
|
||||
|
||||
RawFileClass file(value);
|
||||
if (file.Is_Available()) {
|
||||
StringClass params("+svc ");
|
||||
params += gamename;
|
||||
if (((int)ShellExecute (NULL, "open", value, params, NULL, SW_SHOW)) > 32) {
|
||||
launched = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!launched) {
|
||||
char url[1000] = "";
|
||||
|
||||
#ifdef MULTIPLAYERDEMO
|
||||
::strcpy(url, "http://www.gamespyarcade.com/features/launch.asp?svcname=ccrenegadedemo&distID=432");
|
||||
#else
|
||||
::strcpy(url, "http://www.gamespyarcade.com/features/launch.asp?svcname=ccrenegade&distID=391");
|
||||
#endif
|
||||
|
||||
ShellExecute (NULL, "open", url, NULL, NULL, SW_SHOW);
|
||||
}
|
||||
}
|
||||
void CGameSpyQnR::Shutdown(void) {
|
||||
|
||||
#ifndef BETACLIENT
|
||||
if (m_GSInit) {
|
||||
/*
|
||||
We don't really need to set the mode to exiting here, since we immediately
|
||||
send the statechanged heartbeat and kill off the query sockets
|
||||
gamemode = "exiting";*/
|
||||
ConsoleBox.Print("Shutting down GameSpy Q&R\n");
|
||||
qr_send_exiting(query_reporting_rec);
|
||||
qr_shutdown(query_reporting_rec);
|
||||
m_GSEnabled = m_GSInit = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGameSpyQnR::TrackUsage(void) {
|
||||
|
||||
#ifndef WWDEBUG
|
||||
char filename[MAX_PATH];
|
||||
GetModuleFileName(NULL, filename, sizeof(filename));
|
||||
VS_FIXEDFILEINFO version;
|
||||
GetVersionInfo(filename, &version);
|
||||
int ver = version.dwFileVersionMS;
|
||||
|
||||
StringClass b(true);
|
||||
b.Format("%s %s V%d.%3.3d(%s-%d)", "Win-X86", bname, (ver&0xffff0000)>>16, ver&0xffff,
|
||||
BuildInfoClass::Get_Builder_Initials(), BuildInfoClass::Get_Build_Number());
|
||||
|
||||
// Send off usage Tracking info to GameSpy
|
||||
ptTrackUsage(0, prodid, b.Peek_Buffer(), (cUserOptions::Sku.Get()&0xff)+438, false);
|
||||
#endif // WWDEBUG
|
||||
}
|
||||
|
||||
void CGameSpyQnR::Init(void) {
|
||||
|
||||
#ifndef BETACLIENT
|
||||
|
||||
if (m_GSEnabled && !m_GSInit && The_Game() && The_Game()->Get_Game_Type() == cGameData::GAME_TYPE_CNC) {
|
||||
|
||||
ConsoleBox.Print("Initializing GameSpy Q&R\n");
|
||||
|
||||
BOOL test = FALSE;
|
||||
// Init the GameSpy QnR engine
|
||||
extern ULONG g_ip_override;
|
||||
char ipstr[32];
|
||||
char *ip = ipstr;
|
||||
|
||||
if (g_ip_override == INADDR_NONE) {
|
||||
if (cUserOptions::PreferredGameSpyNic.Get()) {
|
||||
strcpy(ip, cNetUtil::Address_To_String(cUserOptions::PreferredGameSpyNic.Get()));
|
||||
} else {
|
||||
ip = NULL;
|
||||
}
|
||||
} else {
|
||||
strcpy(ip, cNetUtil::Address_To_String(g_ip_override));
|
||||
}
|
||||
|
||||
if (!get_master_count()) {
|
||||
GameSpyQnR.Parse_HeartBeat_List(Get_Default_HeartBeat_List());
|
||||
}
|
||||
test = qr_init(&query_reporting_rec, ip, cUserOptions::GameSpyQueryPort.Get(),
|
||||
gamename, secret_key, c_basic_callback, c_info_callback, c_rules_callback,
|
||||
c_players_callback, this);
|
||||
WWASSERT(!test);
|
||||
gcd_init_qr(query_reporting_rec, cdkey_id);
|
||||
|
||||
StartTime = time(NULL);
|
||||
m_GSInit = TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******
|
||||
DoGameStuff
|
||||
Simulate whatever else a game server does
|
||||
********/
|
||||
void CGameSpyQnR::DoGameStuff(void)
|
||||
{
|
||||
// Sleep(100);
|
||||
}
|
||||
|
||||
#define BANLIST_RELOAD_TIME (1*60*1000)
|
||||
|
||||
/*******************
|
||||
CGameSpyQnR::run
|
||||
Simulates a main game loop
|
||||
*****************/
|
||||
void CGameSpyQnR::Think()
|
||||
{
|
||||
static DWORD stime = (DWORD)(0 - BANLIST_RELOAD_TIME);
|
||||
static DWORD ttime = 0;
|
||||
|
||||
if (TIMEGETTIME() - stime > BANLIST_RELOAD_TIME) {
|
||||
GameSpyBanList.LoadBans();
|
||||
stime = TIMEGETTIME();
|
||||
}
|
||||
// check twice a second
|
||||
if (TIMEGETTIME() - ttime > 500) {
|
||||
GameSpyBanList.Think();
|
||||
ttime = TIMEGETTIME();
|
||||
}
|
||||
|
||||
#ifndef BETACLIENT
|
||||
// DoGameStuff();
|
||||
if (m_GSInit && m_GSEnabled && GameInitMgrClass::Is_LAN_Initialized() &&
|
||||
!CombatManager::Is_Loading_Level()) {
|
||||
qr_process_queries(query_reporting_rec);
|
||||
gcd_think();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************
|
||||
basic_callback
|
||||
sends a (sample) response to the basic query
|
||||
includes the following keys:
|
||||
\gamename\
|
||||
\gamever\
|
||||
\location\
|
||||
*************/
|
||||
void CGameSpyQnR::basic_callback(char *outbuf, int maxlen)
|
||||
{
|
||||
|
||||
WWDEBUG_SAY(("-->GS_QnR -- Basic callback\n"));
|
||||
WWASSERT(!CombatManager::Is_Loading_Level());
|
||||
|
||||
if (!maxlen || !outbuf) return;
|
||||
|
||||
outbuf[0] = 0;
|
||||
|
||||
StringClass b(true);
|
||||
b.Format("%d", BuildInfoClass::Get_Build_Number());
|
||||
sprintf(outbuf, "\\gamename\\%s\\gamever\\%s", gamename, b.Peek_Buffer());
|
||||
// sprintf(outbuf, "\\gamename\\%s\\gamever\\%s\\location\\%d", gamename, b.Peek_Buffer(), 1);
|
||||
|
||||
#ifdef WWDEBUG
|
||||
StringClass tstr(true);
|
||||
tstr.Format("GS_QnR -- Basic callback, sent: %s\n",outbuf);
|
||||
OutputDebugString(tstr.Peek_Buffer());
|
||||
#endif
|
||||
WWDEBUG_SAY(("<--GS_QnR -- Basic callback\n"));
|
||||
|
||||
// printf("Basic callback, sent: %s\n\n",outbuf);
|
||||
}
|
||||
|
||||
/************
|
||||
info_callback
|
||||
Sends a (sample) response to the info query
|
||||
including the following keys:
|
||||
\hostname\
|
||||
\hostport\
|
||||
\mapname\
|
||||
\gametype\
|
||||
\numplayers\
|
||||
\maxplayers\
|
||||
\gamemode\
|
||||
************/
|
||||
void CGameSpyQnR::info_callback(char *outbuf, int maxlen)
|
||||
{
|
||||
|
||||
WWDEBUG_SAY(("-->GS_QnR -- Info callback\n"));
|
||||
WWASSERT(!CombatManager::Is_Loading_Level());
|
||||
|
||||
if (!maxlen || !outbuf) return;
|
||||
|
||||
outbuf[0] = 0;
|
||||
|
||||
while(1) {
|
||||
|
||||
StringClass value(true);
|
||||
|
||||
WideStringClass(The_Game()->Get_Game_Title()).Convert_To(value);
|
||||
if (value.Get_Length() > 25) {
|
||||
value[25] = 0;
|
||||
}
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "hostname", value)) break;
|
||||
|
||||
value.Format("%d", The_Game()->Get_Port());
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "hostport", value)) break;
|
||||
|
||||
value = The_Game()->Get_Map_Name();
|
||||
char *s = value.Peek_Buffer();
|
||||
char *t = strrchr(s, '.');
|
||||
if (t) value.Erase(t-s, s+strlen(s)-t);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "mapname", value)) break;
|
||||
|
||||
value = The_Game()->Get_Mod_Name();
|
||||
if (!value.Is_Empty()) {
|
||||
s = value.Peek_Buffer();
|
||||
t = strrchr(s, '.');
|
||||
if (t) value.Erase(t-s, s+strlen(s)-t);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "gametype", value)) break;
|
||||
} else {
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "gametype", "C&C")) break;
|
||||
}
|
||||
|
||||
int pcount = 0;
|
||||
for (SLNode<cPlayer> *player_node = cPlayerManager::Get_Player_Object_List ()->Head ()
|
||||
; player_node != NULL; player_node = player_node->Next ()) {
|
||||
|
||||
cPlayer *player = player_node->Data ();
|
||||
WWASSERT (player != NULL);
|
||||
|
||||
if (player->Get_Is_Active().Is_False()) {
|
||||
// if (player->Get_Is_Active().Is_False() || !player->Is_Human()) {
|
||||
continue;
|
||||
}
|
||||
pcount++;
|
||||
}
|
||||
|
||||
value.Format("%d", pcount);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "numplayers", value)) break;
|
||||
value.Format("%d", The_Game()->Get_Max_Players());
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "maxplayers", value)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "gamemode", "openplaying")) break;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef WWDEBUG
|
||||
StringClass tstr(true);
|
||||
tstr.Format("GS_QnR -- Info callback, sent: %s\n",outbuf);
|
||||
OutputDebugString(tstr.Peek_Buffer());
|
||||
#endif
|
||||
WWDEBUG_SAY(("<--GS_QnR -- Info callback\n"));
|
||||
|
||||
}
|
||||
|
||||
/***************
|
||||
rules_callback
|
||||
Sends a response to the rules query. You may
|
||||
need to add custom fields for your game in here. Some are provided
|
||||
as an example
|
||||
The following rules are included:
|
||||
\timelimit\
|
||||
\fraglimit\
|
||||
\teamplay\
|
||||
\rankedserver\
|
||||
****************/
|
||||
void CGameSpyQnR::rules_callback(char *outbuf, int maxlen)
|
||||
{
|
||||
static StringClass b;
|
||||
WWDEBUG_SAY(("-->GS_QnR -- Rules callback\n"));
|
||||
WWASSERT(!CombatManager::Is_Loading_Level());
|
||||
|
||||
if (!maxlen || !outbuf) return;
|
||||
|
||||
outbuf[0] = 0;
|
||||
|
||||
while(1) {
|
||||
|
||||
StringClass value(true);
|
||||
const char *zero = "0"; const char *one = "1";
|
||||
|
||||
// WideStringClass timelimit;
|
||||
// The_Game()->Get_Time_Limit_Text(timelimit);
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "timeleft", timelimit)) break;
|
||||
|
||||
// value.Format("%d", The_Game()->Get_Time_Limit_Minutes());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "timelimit", value)) break;
|
||||
|
||||
// if (b.Is_Empty()) {
|
||||
// char filename[MAX_PATH];
|
||||
// GetModuleFileName(NULL, filename, sizeof(filename));
|
||||
// VS_FIXEDFILEINFO version;
|
||||
// GetVersionInfo(filename, &version);
|
||||
// int ver = version.dwFileVersionMS;
|
||||
//
|
||||
// b.Format("%s %s V%d.%3.3d(%s-%d)", "Win-X86", bname, (ver&0xffff0000)>>16, ver&0xffff,
|
||||
// BuildInfoClass::Get_Builder_Initials(), BuildInfoClass::Get_Build_Number());
|
||||
// }
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "Version", b)) break;
|
||||
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "ServerMOTD", WideStringClass(The_Game()->Get_Motd()))) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "OwnerName", The_Game()->Get_Owner())) break;
|
||||
value.Format("%d", (int)cUserOptions::BandwidthBps.Get());
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "BW", value)) break;
|
||||
// int utime = time(NULL) - StartTime;
|
||||
// value.Format("%d:%d:%d:%d", utime/60/60/24, (utime/60/60)%24, (utime/60)%60, utime%60);
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "Uptime", value)) break;
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "CSVR", ConsoleBox.Is_Exclusive() ? one : zero)) break;
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "DED", The_Game()->IsDedicated.Get() ? one : zero)) break;
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "DG", The_Game()->DriverIsAlwaysGunner.Get() ? one : zero)) break;
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "password", The_Game()->IsPassworded.Get() ? one : zero)) break;
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "TC", The_Game()->IsTeamChangingAllowed.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "WeaponSpawning", The_Game()->SpawnWeapons.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "TeamRemix", The_Game()->RemixTeams.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "BuildingRepair", The_Game()->CanRepairBuildings.Get() ? one : zero)) break;
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "FF", The_Game()->IsFriendlyFirePermitted.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "BaseDestructionEndsGame", The_Game()->As_Cnc()->BaseDestructionEndsGame.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "BeaconPlacementEndsGame", The_Game()->As_Cnc()->BeaconPlacementEndsGame.Get() ? one : zero)) break;
|
||||
// value.Format("%d", (int)The_Game()->Get_Radar_Mode());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "RadarMode", value)) break;
|
||||
value.Format("%d", The_Game()->As_Cnc()->Get_Starting_Credits());
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, "SC", value)) break;
|
||||
|
||||
// cTeam * p_team;
|
||||
// for (SLNode<cTeam> * objnode = cTeamManager::Get_Team_Object_List()->Head()
|
||||
// ; objnode != NULL; objnode = objnode->Next()) {
|
||||
//
|
||||
// p_team = objnode->Data();
|
||||
// WWASSERT(p_team != NULL);
|
||||
//
|
||||
// if (p_team->Get_Id() == PLAYERTYPE_GDI) {
|
||||
// value.Format("%.0f", p_team->Get_Score());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "GDI_Score", value)) break;
|
||||
// } else if (p_team->Get_Id() == PLAYERTYPE_NOD) {
|
||||
// value.Format("%.0f", p_team->Get_Score());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "NOD_Score", value)) break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// These don't apply to LAN/GameSpy Games
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "ClanMatch", The_Game()->IsClanGame.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "Laddered", The_Game()->IsLaddered.Get() ? one : zero)) break;
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, "QuickMatch", The_Game()->Is_QuickMatch_Server() ? one : zero)) break;
|
||||
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
#ifdef WWDEBUG
|
||||
StringClass tstr(true);
|
||||
tstr.Format("GS_QnR -- Rules callback, sent: %s\n",outbuf);
|
||||
OutputDebugString(tstr.Peek_Buffer());
|
||||
#endif
|
||||
WWDEBUG_SAY(("<--GS_QnR -- Rules callback\n"));
|
||||
|
||||
}
|
||||
|
||||
BOOL CGameSpyQnR::Parse_HeartBeat_List(const char *list) {
|
||||
|
||||
BOOL master_added = false;
|
||||
|
||||
char *str = new char[strlen(list)+1];
|
||||
strcpy(str, list);
|
||||
|
||||
char *t = str;
|
||||
|
||||
clear_master_list();
|
||||
|
||||
while (t) {
|
||||
WORD port = 27900;
|
||||
struct sockaddr_in taddr;
|
||||
memset(&taddr, 0, sizeof(taddr));
|
||||
taddr.sin_family = AF_INET;
|
||||
char *q = strchr(t, ',');
|
||||
if (q) *q++ = 0;
|
||||
char *s = strchr(t, ':');
|
||||
if (s) {
|
||||
// Parse off the port value
|
||||
*s++ = 0;
|
||||
char *p = s;
|
||||
if (atoi(p)) port = atoi(p);
|
||||
}
|
||||
// skip white space
|
||||
while (*t == ' ' || *t == '\t') t++;
|
||||
// process the address
|
||||
if (*t && get_sockaddrin(t, port, &taddr, NULL)) {
|
||||
add_master(&taddr);
|
||||
master_added = true;
|
||||
}
|
||||
t = q;
|
||||
}
|
||||
|
||||
delete [] str;
|
||||
|
||||
if (!master_added) {
|
||||
ConsoleBox.Print("Error processing HeartBeat List: <%s>\n", list);
|
||||
ConsoleBox.Print("Assigning default HeartBeat List\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL CGameSpyQnR::Append_InfoKey_Pair(char *outbuf, int maxlen, const char *key, const char *value) {
|
||||
|
||||
WWASSERT(value);
|
||||
WWASSERT(outbuf);
|
||||
WWASSERT(key);
|
||||
|
||||
int clen = strlen(outbuf);
|
||||
|
||||
if (clen + strlen(key) + strlen(value) + 3 > (unsigned int)maxlen) return FALSE;
|
||||
|
||||
char *s = new char[strlen(value)+1];
|
||||
strcpy(s, value);
|
||||
char *t = s;
|
||||
while (*t) {
|
||||
if (*t == '\\') *t = '/';
|
||||
t++;
|
||||
}
|
||||
t = strtrim(s);
|
||||
sprintf(&outbuf[clen], "\\%s\\%s", key, t);
|
||||
delete [] s;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CGameSpyQnR::Append_InfoKey_Pair(char *outbuf, int maxlen, const char *key, const WideStringClass &value) {
|
||||
static StringClass text;
|
||||
|
||||
value.Convert_To(text);
|
||||
return Append_InfoKey_Pair(outbuf, maxlen, key, text.Peek_Buffer());
|
||||
}
|
||||
|
||||
BOOL CGameSpyQnR::Append_InfoKey_Pair(char *outbuf, int maxlen, const char *key, const StringClass &value) {
|
||||
|
||||
return Append_InfoKey_Pair(outbuf, maxlen, key, value.Peek_Buffer());
|
||||
}
|
||||
|
||||
/***************
|
||||
players_callback
|
||||
sends the players and their information.
|
||||
Note that \ characters are not stripped out of player names. If
|
||||
your game allows players or team names with the \ character, you will need
|
||||
to strip or change it here.
|
||||
The following keys are included for each player:
|
||||
\player_N\
|
||||
\frags_N\
|
||||
\deaths_N\
|
||||
\skill_N\
|
||||
\ping_N\
|
||||
\team_N\
|
||||
***************/
|
||||
void CGameSpyQnR::players_callback(char *outbuf, int maxlen)
|
||||
{
|
||||
|
||||
// Send the minimum for now to reduce Bandwidth usage.
|
||||
outbuf[0] = 0;
|
||||
return;
|
||||
|
||||
|
||||
|
||||
int pindex = 0;
|
||||
|
||||
WWDEBUG_SAY(("-->GS_QnR -- Players callback\n"));
|
||||
WWASSERT(!CombatManager::Is_Loading_Level());
|
||||
|
||||
if (!maxlen || !outbuf) return;
|
||||
|
||||
outbuf[0] = 0;
|
||||
|
||||
for (SLNode<cPlayer> *player_node = cPlayerManager::Get_Player_Object_List ()->Head ();
|
||||
player_node != NULL;
|
||||
player_node = player_node->Next ()) {
|
||||
|
||||
cPlayer *player = player_node->Data ();
|
||||
WWASSERT (player != NULL);
|
||||
|
||||
if (player->Get_Is_Active().Is_False()) {
|
||||
// if (player->Get_Is_Active().Is_False() || !player->Is_Human()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StringClass keyval(true);
|
||||
StringClass value(true);
|
||||
|
||||
// Set the Player's Name [Team]
|
||||
value = player->Get_Name();
|
||||
if (player->Get_Player_Type() == PLAYERTYPE_NOD) {
|
||||
value += " [NOD]";
|
||||
} else if (player->Get_Player_Type() == PLAYERTYPE_GDI) {
|
||||
value += " [GDI]";
|
||||
}
|
||||
|
||||
keyval.Format("player_%d", pindex);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), value)) break;
|
||||
|
||||
// Set the Player's Score
|
||||
keyval.Format("frags_%d", pindex);
|
||||
value.Format("%.0f", player->Get_Score());
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), value)) break;
|
||||
|
||||
// Set the Player's Credits
|
||||
// keyval.Format("credits_%d", pindex);
|
||||
// value.Format("%.0f", player->Get_Money());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), value)) break;
|
||||
|
||||
// Set the Player's Ping to Server
|
||||
keyval.Format("ping_%d", pindex);
|
||||
value.Format("%d", player->Get_Ping());
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), value)) break;
|
||||
|
||||
// Set the Player's Kills
|
||||
// keyval.Format("kills_%d", pindex);
|
||||
// value.Format("%d", player->Get_Kills());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), value)) break;
|
||||
|
||||
// Set the Player's Deaths
|
||||
// keyval.Format("deaths_%d", pindex);
|
||||
// value.Format("%d", player->Get_Deaths());
|
||||
// if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), value)) break;
|
||||
|
||||
/* SmartGameObj *game_obj = player->Get_GameObj ();
|
||||
if (game_obj != NULL && game_obj->As_SoldierGameObj () != NULL) {
|
||||
|
||||
// Set the Player's Class (ie: Technician,Sakura,Havok)
|
||||
keyval.Format("class_%d", pindex);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(),
|
||||
WideStringClass(TRANSLATE(game_obj->Get_Translated_Name_ID())) )) break;
|
||||
|
||||
SoldierGameObj *soldier = game_obj->As_SoldierGameObj();
|
||||
VehicleGameObj *vehicle = soldier->Get_Vehicle ();
|
||||
|
||||
// If they're in a vehicle set the vehicle name
|
||||
keyval.Format("vehicle_%d", pindex);
|
||||
if (vehicle != NULL) {
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(),
|
||||
WideStringClass(TRANSLATE(vehicle->Get_Translated_Name_ID())) )) break;
|
||||
} else {
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), "None")) break;
|
||||
}
|
||||
} else {
|
||||
// If there's no gameobj then set vehicle/class to unknown
|
||||
keyval.Format("class_%d", pindex);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), "Unknown")) break;
|
||||
keyval.Format("vehicle_%d", pindex);
|
||||
if (!Append_InfoKey_Pair(outbuf, maxlen, keyval.Peek_Buffer(), "Unknown")) break;
|
||||
} */
|
||||
|
||||
pindex++;
|
||||
|
||||
}
|
||||
|
||||
#ifdef WWDEBUG
|
||||
StringClass tstr(true);
|
||||
tstr.Format("GS_QnR -- Players callback, sent: %s\n",outbuf);
|
||||
OutputDebugString(tstr.Peek_Buffer());
|
||||
#endif
|
||||
|
||||
WWDEBUG_SAY(("<--GS_QnR -- Players callback\n"));
|
||||
return;
|
||||
}
|
||||
/************
|
||||
We'll actually start up two completely seperate "game servers"
|
||||
Each one initializes the Query & Reporting SDK and calls processs on it during
|
||||
their main loop
|
||||
************/
|
||||
/*
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
CGameSpyQnR mygame1("Test Game Server 1"), mygame2("Test Game Server 2");
|
||||
|
||||
srand( GetTickCount() );
|
||||
|
||||
printf("Press any key to quit\n");
|
||||
while (!_kbhit())
|
||||
{
|
||||
mygame1.run();
|
||||
mygame2.run();
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
*/
|
||||
75
Code/Commando/GameSpy_QnR.h
Normal file
75
Code/Commando/GameSpy_QnR.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _GAMESPY_QNR_H_
|
||||
#define _GAMESPY_QNR_H_
|
||||
|
||||
/********
|
||||
INCLUDES
|
||||
********/
|
||||
#include <GameSpy\gqueryreporting.h>
|
||||
#include <WWLib\WideString.h>
|
||||
#include "trim.h"
|
||||
|
||||
/********
|
||||
DEFINES
|
||||
********/
|
||||
|
||||
class CGameSpyQnR
|
||||
{
|
||||
|
||||
protected:
|
||||
char secret_key[9];
|
||||
BOOL m_GSInit;
|
||||
BOOL m_GSEnabled;
|
||||
qr_t query_reporting_rec;
|
||||
void DoGameStuff(void);
|
||||
BOOL Append_InfoKey_Pair(char *outbuf, int maxlen, const char *key, const char *value);
|
||||
BOOL Append_InfoKey_Pair(char *outbuf, int maxlen, const char *key, const StringClass &value);
|
||||
BOOL Append_InfoKey_Pair(char *outbuf, int maxlen, const char *key, const WideStringClass &value);
|
||||
static const char *gamename;
|
||||
static const char *bname;
|
||||
static const int prodid;
|
||||
static const int cdkey_id;
|
||||
static const char *default_heartbeat_list;
|
||||
int StartTime;
|
||||
|
||||
public:
|
||||
void Init(void);
|
||||
void LaunchArcade(void);
|
||||
void TrackUsage(void);
|
||||
void Shutdown(void);
|
||||
BOOL Parse_HeartBeat_List(const char *list);
|
||||
const char *Get_GameSpy_GameName(void) { return gamename; }
|
||||
const char *Get_Default_HeartBeat_List(void) { return default_heartbeat_list; }
|
||||
void Enable_Reporting(BOOL enable) { m_GSEnabled = enable; }
|
||||
BOOL IsEnabled(void) { return m_GSEnabled; }
|
||||
void Think();
|
||||
void basic_callback(char *outbuf, int maxlen);
|
||||
void info_callback(char *outbuf, int maxlen);
|
||||
void rules_callback(char *outbuf, int maxlen);
|
||||
void players_callback(char *outbuf, int maxlen);
|
||||
CGameSpyQnR();
|
||||
virtual ~CGameSpyQnR();
|
||||
|
||||
};
|
||||
|
||||
extern CGameSpyQnR GameSpyQnR;
|
||||
|
||||
#endif
|
||||
3690
Code/Commando/NAT.cpp
Normal file
3690
Code/Commando/NAT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Code/Commando/Renegade.ico
Normal file
BIN
Code/Commando/Renegade.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
892
Code/Commando/ServerSettings.cpp
Normal file
892
Code/Commando/ServerSettings.cpp
Normal file
@@ -0,0 +1,892 @@
|
||||
/*
|
||||
** 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/ServerSettings.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 8/09/02 2:12p $*
|
||||
* *
|
||||
* $Revision:: 17 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "ServerSettings.h"
|
||||
#include "slavemaster.h"
|
||||
#include "wwdebug.h"
|
||||
#include "gamedata.h"
|
||||
#include "gdcnc.h"
|
||||
#include "ini.h"
|
||||
#include "registry.h"
|
||||
#include "rawfile.h"
|
||||
#include "consolemode.h"
|
||||
#include "specialbuilds.h"
|
||||
#include "_globals.h"
|
||||
#include "bandwidth.h"
|
||||
#include "mpsettingsmgr.h"
|
||||
#include "wwonline\wolserver.h"
|
||||
#include "useroptions.h"
|
||||
#include "gamespyadmin.h"
|
||||
#include "servercontrol.h"
|
||||
#include "gamesideservercontrol.h"
|
||||
#include "autostart.h"
|
||||
#include "GameSpy_QnR.h"
|
||||
#include "bandwidthcheck.h"
|
||||
|
||||
|
||||
|
||||
const char *ConfigSettingsName = "Config";
|
||||
const char *MasterServerSection = "Server";
|
||||
const char *SlaveServerSection = "Slave";
|
||||
|
||||
#define ENCRYPTION_STRING_LENGTH 128
|
||||
#define KEY_SLAVE_SERIAL "Serial"
|
||||
|
||||
char ServerSettingsClass::SettingsFile[MAX_PATH];
|
||||
bool ServerSettingsClass::IsActive = false;
|
||||
char ServerSettingsClass::MasterPassword[128];
|
||||
ServerSettingsClass::GameModeTypeEnum ServerSettingsClass::GameMode = MODE_NONE;
|
||||
unsigned long ServerSettingsClass::MasterBandwidth = 0;
|
||||
char ServerSettingsClass::PreferredLoginServer[256];
|
||||
int ServerSettingsClass::DiskLogSize = -1;
|
||||
|
||||
const char *ServerListTag = "Available Westwood Servers:";
|
||||
const char *ServerListEnd = "; End generated section.";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Set_Settings_File_Name -- Set the name of the settings file *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: File name *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/1/2002 12:07PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void ServerSettingsClass::Set_Settings_File_Name(char *filename)
|
||||
{
|
||||
if (strlen(filename) < sizeof(SettingsFile)) {
|
||||
strcpy(SettingsFile, filename);
|
||||
IsActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Parse -- Pull the server info out of the settings file *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: True if we should apply the settings. False to parse for errors only. *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/1/2002 12:07PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
bool ServerSettingsClass::Parse(bool apply)
|
||||
{
|
||||
char master_settings[MAX_PATH];
|
||||
char slave_settings[MAX_PATH];
|
||||
char slave_section[256];
|
||||
char slave_nick[128];
|
||||
char slave_serial[128];
|
||||
char slave_pass[128];
|
||||
int slave_port;
|
||||
int slave_bw;
|
||||
char master_nick[128];
|
||||
char master_serial[128];
|
||||
int master_port;
|
||||
int master_bw;
|
||||
char master_pass[128];
|
||||
char remote_admin_pass[128];
|
||||
char game_type[32];
|
||||
char heartbeat_list[512];
|
||||
bool wol = true;
|
||||
char remote_admin_ip[128];
|
||||
|
||||
MasterPassword[0] = 0;
|
||||
|
||||
/*
|
||||
** IsActive is set when the settigns file name is set.
|
||||
*/
|
||||
if (IsActive) {
|
||||
|
||||
WWASSERT(The_Game() || !apply);
|
||||
if (apply) {
|
||||
WWDEBUG_SAY(("Applying server settings\n"));
|
||||
ConsoleBox.Print("Applying server settings\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure the server config file is there. It should be since it's verified at command line parsing time.
|
||||
*/
|
||||
RawFileClass file(SettingsFile);
|
||||
if (!file.Is_Available()) {
|
||||
WWDEBUG_SAY(("Server startup file '%s' not found\n", SettingsFile));
|
||||
ConsoleBox.Print("Error - server startup file '%s' not found - aborting\n", SettingsFile);
|
||||
ConsoleBox.Wait_For_Keypress();
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get the name of the master server settings file.
|
||||
*/
|
||||
INIClass ini(file);
|
||||
ini.Get_String(MasterServerSection, ConfigSettingsName, "", master_settings, sizeof(master_settings));
|
||||
if (strlen(master_settings) == 0) {
|
||||
if (apply) {
|
||||
WWDEBUG_SAY(("No master server settings specified - using defaults\n"));
|
||||
ConsoleBox.Print("No master server settings specified - using defaults\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Load the master server settings from the ini file.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Game Type.
|
||||
*/
|
||||
ini.Get_String(MasterServerSection, "GameType", "WOL", game_type, sizeof(game_type));
|
||||
if (cGameSpyAdmin::Get_Is_Server_Gamespy_Listed()) {
|
||||
strcpy(game_type, "GameSpy");
|
||||
}
|
||||
if (stricmp(game_type, "WOL") == 0) {
|
||||
GameMode = MODE_WOL;
|
||||
} else if (stricmp(game_type, "LAN") == 0) {
|
||||
wol = false;
|
||||
GameMode = MODE_LAN;
|
||||
} else if (stricmp(game_type, "GameSpy") == 0) {
|
||||
wol = false;
|
||||
cGameSpyAdmin::Set_Is_Server_Gamespy_Listed(true);
|
||||
GameSpyQnR.Enable_Reporting(true);
|
||||
GameMode = MODE_GAMESPY;
|
||||
} else {
|
||||
WWDEBUG_SAY(("Bad game type specified in server.ini\n"));
|
||||
ConsoleBox.Print("Error - Unknown game type in server settings. Use 'LAN', 'WOL', or 'GameSpy' - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Parse the list of GameSpy Style Master servers from the HeartBeat List
|
||||
*/
|
||||
heartbeat_list[sizeof(heartbeat_list)-1] = 0;
|
||||
ini.Get_String(MasterServerSection, "HeartBeatServers", GameSpyQnR.Get_Default_HeartBeat_List(), heartbeat_list, sizeof(heartbeat_list)-1);
|
||||
if (!GameSpyQnR.Parse_HeartBeat_List(heartbeat_list)) {
|
||||
GameSpyQnR.Parse_HeartBeat_List(GameSpyQnR.Get_Default_HeartBeat_List());
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure the master server settings file is there.
|
||||
*/
|
||||
char filename[MAX_PATH];
|
||||
sprintf(filename, "data\\%s", master_settings);
|
||||
file.Set_Name(filename);
|
||||
if (!file.Is_Available()) {
|
||||
WWDEBUG_SAY(("Server settings file '%s' not found\n", filename));
|
||||
ConsoleBox.Print("Error - server settings file '%s' not found - aborting\n", filename);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
} else {
|
||||
if (!Check_Game_Settings_File(master_settings)) {
|
||||
WWDEBUG_SAY(("Server settings file '%s' not usable\n", master_settings));
|
||||
ConsoleBox.Print("Error - server settings file '%s' contains errors - aborting\n", master_settings);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
if (apply && The_Game()) {
|
||||
The_Game()->Set_Ini_Filename(master_settings);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Restart Flag
|
||||
*/
|
||||
|
||||
RegistryClass restart_reg(APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
|
||||
if (restart_reg.Is_Valid ()) {
|
||||
restart_reg.Set_Int(AutoRestartClass::REG_VALUE_AUTO_RESTART_FLAG, 1);
|
||||
switch (GameMode) {
|
||||
case MODE_WOL:
|
||||
restart_reg.Set_Int(AutoRestartClass::REG_VALUE_AUTO_RESTART_TYPE, 1);
|
||||
break;
|
||||
case MODE_LAN:
|
||||
case MODE_GAMESPY:
|
||||
restart_reg.Set_Int(AutoRestartClass::REG_VALUE_AUTO_RESTART_TYPE, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Nickname.
|
||||
*/
|
||||
ini.Get_String(MasterServerSection, "Nickname", "", master_nick, sizeof(master_nick));
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
/*
|
||||
** We only need to validate this for the FDS. The regular game can allow the login name to be specified in the registry.
|
||||
*/
|
||||
if (wol && strlen(master_nick) == 0) {
|
||||
WWDEBUG_SAY(("Error - No login nickname specified for master server - aborting\n"));
|
||||
ConsoleBox.Print("Error - No login nickname specified for master server - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
|
||||
/*
|
||||
** Password.
|
||||
*/
|
||||
ini.Get_String(MasterServerSection, "Password", "", master_pass, sizeof(master_pass));
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
/*
|
||||
** We only need to validate this for the FDS. The regular game can allow the login name to be specified in the registry.
|
||||
*/
|
||||
if (wol && strlen(master_pass) == 0) {
|
||||
WWDEBUG_SAY(("Error - No login password specified for master server - aborting\n"));
|
||||
ConsoleBox.Print("Error - No login password specified for master server - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
|
||||
/*
|
||||
** Serial number.
|
||||
*/
|
||||
ini.Get_String(MasterServerSection, "Serial", "", master_serial, sizeof(master_serial));
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
/*
|
||||
** We only need to validate the serial number if we are the FDS. For the regular game, the master serial will be stored
|
||||
** in the registry.
|
||||
*/
|
||||
if (wol && strlen(master_serial) == 0) {
|
||||
WWDEBUG_SAY(("Error - No serial number specified for master server - aborting\n"));
|
||||
ConsoleBox.Print("Error - No serial number specified for master server - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
|
||||
/*
|
||||
** Get the port number.
|
||||
*/
|
||||
master_port = ini.Get_Int(MasterServerSection, "Port", 0xffffffff);
|
||||
if (wol && master_port != 0xffffffff && (master_port < 0 || master_port > 0xffff)) {
|
||||
WWDEBUG_SAY(("Error - Invalid port number %d specified for master server - aborting\n", master_port));
|
||||
ConsoleBox.Print("Error - Invalid port number %d specified for master server - aborting\n", master_port);
|
||||
ConsoleBox.Wait_For_Keypress();
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get the GameSpy Query port number.
|
||||
*/
|
||||
int gsqport = cUserOptions::GameSpyQueryPort.Get();
|
||||
gsqport = ini.Get_Int(MasterServerSection, "GameSpyQueryPort", gsqport);
|
||||
if (!gsqport) gsqport = cUserOptions::GameSpyQueryPort.Get();
|
||||
if (gsqport < 0 || gsqport > 0xffff) {
|
||||
WWDEBUG_SAY(("Error - Invalid port number %d specified for GameSpy Query Port - aborting\n", gsqport));
|
||||
ConsoleBox.Print("Error - Invalid port number %d specified for GameSpy Query Port - aborting\n", gsqport);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
cUserOptions::GameSpyQueryPort.Set(gsqport);
|
||||
|
||||
/*
|
||||
** Get the GameSpy Game port number.
|
||||
*/
|
||||
int gsgport = cUserOptions::GameSpyGamePort.Get();
|
||||
gsgport = ini.Get_Int(MasterServerSection, "GameSpyGamePort", gsgport);
|
||||
if (!gsgport) gsgport = cUserOptions::GameSpyGamePort.Get();
|
||||
if (gsgport < 0 || gsgport > 0xffff || gsgport == gsqport) {
|
||||
WWDEBUG_SAY(("Error - Invalid port number %d specified for GameSpy Game Port - aborting\n", gsgport));
|
||||
ConsoleBox.Print("Error - Invalid port number %d specified for GameSpy Game Port - aborting\n", gsgport);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
cUserOptions::GameSpyGamePort.Set(gsgport);
|
||||
|
||||
/*
|
||||
** Get the bandwidth allowance.
|
||||
*/
|
||||
master_bw = ini.Get_Int(MasterServerSection, "BandwidthUp", 0xffffffff);
|
||||
if (master_bw != 0 && master_bw != 0xffffffff && master_bw < 33600) {
|
||||
WWDEBUG_SAY(("Error - Insufficient bandwidth specified for master server - aborting\n"));
|
||||
ConsoleBox.Print("Error - Insufficient bandwidth specified for master server - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
MasterBandwidth = master_bw;
|
||||
|
||||
/*
|
||||
** Get the max size of the disk log in days.
|
||||
*/
|
||||
DiskLogSize = ini.Get_Int(MasterServerSection, "DiskLogSize", 7);
|
||||
if (DiskLogSize > 365) {
|
||||
WWDEBUG_SAY(("Error - Disk log size too large - aborting\n"));
|
||||
ConsoleBox.Print("Error - Disk log size too large - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get the preferred login server. No preference means use default from ping profile.
|
||||
*/
|
||||
ini.Get_String(MasterServerSection, "LoginServer", "", PreferredLoginServer, sizeof(PreferredLoginServer));
|
||||
|
||||
/*
|
||||
** Get the Network Update Rate override.
|
||||
*/
|
||||
int nur = ini.Get_Int(MasterServerSection, "NetUpdateRate", 8);
|
||||
if (nur < 5 || nur > 30) {
|
||||
WWDEBUG_SAY(("Error - Bad NetUpdateRate specified - aborting\n"));
|
||||
ConsoleBox.Print("Error - NetUpdateRate must be between 5 and 30 - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
cUserOptions::NetUpdateRate.Set(nur);
|
||||
|
||||
/*
|
||||
** Get the remote admin settings.
|
||||
*/
|
||||
bool allow_remote = ini.Get_Bool(MasterServerSection, "AllowRemoteAdmin", false);
|
||||
RegistryClass reg_remote(APPLICATION_SUB_KEY_NAME_NET_SERVER_CONTROL);
|
||||
if (allow_remote) {
|
||||
ini.Get_String(MasterServerSection, "RemoteAdminPassword", "", remote_admin_pass, sizeof(remote_admin_pass));
|
||||
int len = strlen(remote_admin_pass);
|
||||
if (len == 0) {
|
||||
ConsoleBox.Print("Error - Remote admin password must be specified - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
} else {
|
||||
if (len > 31) {
|
||||
ConsoleBox.Print("Error - Remote admin password too long - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
int admin_port = ini.Get_Int(MasterServerSection, "RemoteAdminPort", 0);
|
||||
if (admin_port != 0 && (admin_port < 1024 || admin_port > 65535-8)) {
|
||||
ConsoleBox.Print("Error - Remote admin port number out of range - aborting\n");
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
|
||||
ServerControl.Allow_Remote_Admin(true);
|
||||
|
||||
/*
|
||||
** Set the port number into the registry.
|
||||
*/
|
||||
if (admin_port == 0) {
|
||||
admin_port = DEFAULT_SERVER_CONTROL_PORT;
|
||||
}
|
||||
reg_remote.Set_Int(SERVER_CONTROL_PORT_KEY, admin_port);
|
||||
|
||||
/*
|
||||
** Set the password into the registry.
|
||||
*/
|
||||
reg_remote.Set_String(SERVER_CONTROL_PASSWORD_KEY, remote_admin_pass);
|
||||
|
||||
/*
|
||||
** We need to bind to more than just the loopback address when listening for control messages.
|
||||
*/
|
||||
reg_remote.Set_Int(SERVER_CONTROL_LOOPBACK_KEY, 0);
|
||||
|
||||
/*
|
||||
** There may be an IP override specified.
|
||||
*/
|
||||
ini.Get_String(MasterServerSection, "RemoteAdminIP", "0.0.0.0", remote_admin_ip, sizeof(remote_admin_ip));
|
||||
unsigned long admin_ip_long = ntohl(inet_addr(remote_admin_ip));
|
||||
reg_remote.Set_Int(SERVER_CONTROL_IP_KEY, admin_ip_long);
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Only listen to control messages on the loopback address.
|
||||
*/
|
||||
reg_remote.Set_Int(SERVER_CONTROL_LOOPBACK_KEY, 1);
|
||||
ServerControl.Allow_Remote_Admin(false);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Set the master settings into the registry.
|
||||
*/
|
||||
//if (apply) {
|
||||
|
||||
/*
|
||||
** Serial number.
|
||||
*/
|
||||
if (wol) {
|
||||
if (strlen(master_serial)) {
|
||||
StringClass serial(master_serial, true);
|
||||
StringClass encrypted_serial;
|
||||
Encrypt_Serial(serial, encrypted_serial);
|
||||
RegistryClass reg_base(APPLICATION_SUB_KEY_NAME);
|
||||
if (reg_base.Is_Valid()) {
|
||||
reg_base.Set_String(KEY_SLAVE_SERIAL, encrypted_serial.Peek_Buffer());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Nickname.
|
||||
*/
|
||||
if (strlen(master_nick)) {
|
||||
RegistryClass reg_wol(APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
|
||||
if (reg_wol.Is_Valid()) {
|
||||
reg_wol.Set_String("AutoLogin", master_nick);
|
||||
reg_wol.Set_String("LastLogin", master_nick);
|
||||
reg_wol.Set_Int("AutoLoginPrompt", 0);
|
||||
MPSettingsMgrClass::Set_Auto_Login(master_nick);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Password.
|
||||
*/
|
||||
MPSettingsMgrClass::Set_Auto_Password(master_pass);
|
||||
|
||||
/*
|
||||
** Port number.
|
||||
*/
|
||||
if (master_port != 0xffffffff) {
|
||||
RegistryClass reg_fw(APPLICATION_SUB_KEY_NAME_NET_FIREWALL);
|
||||
reg_fw.Set_Int("ForcePort", master_port);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Bandwidth.
|
||||
*/
|
||||
if (master_bw != 0xffffffff) {
|
||||
RegistryClass reg_netopt(APPLICATION_SUB_KEY_NAME_NETOPTIONS);
|
||||
if (reg_netopt.Is_Valid()) {
|
||||
if (cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
if (master_bw == 0) master_bw = 1000000;
|
||||
cUserOptions::Set_Bandwidth_Bps(master_bw);
|
||||
} else {
|
||||
if (wol) {
|
||||
reg_netopt.Set_Int("BandwidthType", BANDWIDTH_AUTO);
|
||||
|
||||
/*
|
||||
** We want this to be set always on the first time through, but not neccessarily on the second, apply, pass.
|
||||
*/
|
||||
if (master_bw != 0 || !apply) {
|
||||
RegistryClass reg_bw(APPLICATION_SUB_KEY_NAME_BANDTEST);
|
||||
if (reg_bw.Is_Valid()) {
|
||||
reg_bw.Set_Int("Up", master_bw);
|
||||
reg_bw.Set_Int("Down", master_bw);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cUserOptions::Set_Bandwidth_Type(BANDWIDTH_LANT1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
if (apply) {
|
||||
SlaveMaster.Reset();
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the slave server info.
|
||||
*/
|
||||
for (int i=0 ; i<MAX_SLAVES ; i++) {
|
||||
|
||||
slave_settings[0] = 0;
|
||||
slave_nick[0] = 0;
|
||||
slave_serial[0] = 0;
|
||||
slave_port = 0;
|
||||
slave_bw = 0xffffffff;
|
||||
|
||||
/*
|
||||
** See if this slave is enabled in the .ini
|
||||
*/
|
||||
sprintf(slave_section, "%s%d", SlaveServerSection, i+1);
|
||||
bool enabled = ini.Get_Bool(slave_section, "Enable", false);
|
||||
|
||||
if (enabled) {
|
||||
|
||||
/*
|
||||
** Make sure the slaves config file is present.
|
||||
*/
|
||||
ini.Get_String(slave_section, ConfigSettingsName, "", slave_settings, sizeof(slave_settings));
|
||||
if (strlen(slave_settings) != 0) {
|
||||
sprintf(filename, "data\\%s", slave_settings);
|
||||
file.Set_Name(filename);
|
||||
if (!file.Is_Available()) {
|
||||
WWDEBUG_SAY(("Slave server settings file '%s' not found\n", filename));
|
||||
ConsoleBox.Print("Error - Slave server settings file '%s' not found - aborting\n", filename);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
} else {
|
||||
if (!Check_Game_Settings_File(slave_settings)) {
|
||||
WWDEBUG_SAY(("Server settings file '%s' not usable\n", slave_settings));
|
||||
ConsoleBox.Print("Error - server settings file '%s' contains errors - aborting\n", slave_settings);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure there's a nickname and a serial.
|
||||
*/
|
||||
ini.Get_String(slave_section, "Nickname", "", slave_nick, sizeof(slave_nick));
|
||||
if (wol && strlen(slave_nick) == 0) {
|
||||
WWDEBUG_SAY(("Error - No login nickname specified for slave %d - aborting\n", i+1));
|
||||
ConsoleBox.Print("Error - No login nickname specified for slave %d - aborting\n", i+1);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
|
||||
ini.Get_String(slave_section, "Serial", "", slave_serial, sizeof(slave_serial));
|
||||
if (wol && strlen(slave_serial) == 0) {
|
||||
WWDEBUG_SAY(("Error - No serial number specified for slave %d - aborting\n", i+1));
|
||||
ConsoleBox.Print("Error - No serial number specified for slave %d - aborting\n", i+1);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get the password.
|
||||
*/
|
||||
ini.Get_String(slave_section, "Password", "", slave_pass, sizeof(slave_pass));
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
if (wol && strlen(slave_pass) == 0) {
|
||||
WWDEBUG_SAY(("Error - No login password specified for slave %d - aborting\n", i+1));
|
||||
ConsoleBox.Print("Error - No login password specified for slave %d - aborting\n", i+1);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
|
||||
/*
|
||||
** Get the port number.
|
||||
*/
|
||||
slave_port = ini.Get_Int(slave_section, "Port", 0);
|
||||
|
||||
if (slave_port < 0 || slave_port > 0xffff) {
|
||||
WWDEBUG_SAY(("Error - Invalid port number %d specified for slave %d - aborting\n", slave_port, i+1));
|
||||
ConsoleBox.Print("Error - Invalid port number %d specified for slave %d - aborting\n", slave_port, i+1);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get the bandwidth allowance.
|
||||
*/
|
||||
slave_bw = ini.Get_Int(slave_section, "BandwidthUp", 0xffffffff);
|
||||
if (slave_bw != 0 && slave_bw != 0xffffffff && slave_bw < 33600) {
|
||||
WWDEBUG_SAY(("Error - Insufficient bandwidth specified for slave %d - aborting\n", i+1));
|
||||
ConsoleBox.Print("Error - Insufficient bandwidth specified for slave %d - aborting\n", i+1);
|
||||
ConsoleBox.Wait_For_Keypress();;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Apply the settings.
|
||||
*/
|
||||
if (apply) {
|
||||
SlaveMaster.Add_Slave(enabled, slave_nick, slave_serial, (unsigned short)slave_port, slave_settings, slave_bw, slave_pass);
|
||||
}
|
||||
}
|
||||
if (apply) {
|
||||
SlaveMaster.Save();
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Encrypt_Serial -- Serial number encryption/decryption *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Input serial number *
|
||||
* Reference to output serial number *
|
||||
* Encrypt flag - true to encrypt, false to decrypt *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/1/2002 12:08PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void ServerSettingsClass::Encrypt_Serial(StringClass serial_in, StringClass &serial_out, bool encrypt)
|
||||
{
|
||||
char *s;
|
||||
int numberlength = serial_in.Get_Length();
|
||||
unsigned long bytesread;
|
||||
char stringbuffer[ENCRYPTION_STRING_LENGTH];
|
||||
int p;
|
||||
|
||||
WWASSERT(numberlength);
|
||||
|
||||
s = new char [numberlength + 1];
|
||||
memcpy(s, serial_in.Peek_Buffer(), numberlength + 1);
|
||||
|
||||
/*
|
||||
** See if the key file is available. If not, don't bother encrypting.
|
||||
*/
|
||||
HANDLE handle = CreateFile ("woldata.key", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
delete [] s;
|
||||
serial_out = serial_in;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the key.
|
||||
*/
|
||||
if (!ReadFile(handle, stringbuffer, sizeof (stringbuffer), &bytesread, NULL)) {
|
||||
WWDEBUG_SAY(("Unable to read serial encryption key file\n"));
|
||||
delete [] s;
|
||||
serial_out = serial_in;
|
||||
return;
|
||||
}
|
||||
|
||||
int sign = encrypt ? 1 : -1;
|
||||
|
||||
p = 0;
|
||||
for (unsigned i = 0; i < ENCRYPTION_STRING_LENGTH; i++) {
|
||||
|
||||
int t;
|
||||
char c;
|
||||
|
||||
t = s[p] - '0';
|
||||
t %= 10;
|
||||
t += (sign * stringbuffer[i]);
|
||||
t += 1000;
|
||||
t %= 10;
|
||||
c = t + '0';
|
||||
s[p] = c;
|
||||
p++;
|
||||
if (p == numberlength) {
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
serial_out = StringClass(s, true);
|
||||
|
||||
delete [] s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Decrypt_Serial -- Serial number decryption *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Input serial number *
|
||||
* Reference to output serial number *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/1/2002 12:08PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void ServerSettingsClass::Decrypt_Serial(StringClass serial_in, StringClass &serial_out)
|
||||
{
|
||||
Encrypt_Serial(serial_in, serial_out, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Get_Preferred_Server -- Get the users specified server *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Server list from servserv *
|
||||
* *
|
||||
* OUTPUT: Name of preferred server *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/1/2002 1:18PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *ServerSettingsClass::Get_Preferred_Server(const WWOnline::IRCServerList &server_list)
|
||||
{
|
||||
if (IsActive && server_list.size()) {
|
||||
Write_Server_List(server_list);
|
||||
}
|
||||
return(PreferredLoginServer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Write_Server_List -- Write the server list into the settings ini file *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Server list *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/1/2002 1:19PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void ServerSettingsClass::Write_Server_List(const WWOnline::IRCServerList &server_list)
|
||||
{
|
||||
WWASSERT(server_list.size());
|
||||
WWASSERT(strlen(SettingsFile) != 0);
|
||||
|
||||
char temp[256];
|
||||
|
||||
if (server_list.size()) {
|
||||
RawFileClass file(SettingsFile);
|
||||
|
||||
/*
|
||||
** This is a bit hacky. Basically we just want the .ini file commented with the latest server list.
|
||||
**
|
||||
** We will do this by reading in the file, looking for a tag that tells us where to write the server list, then writing
|
||||
** the file back out with the server list in place.
|
||||
*/
|
||||
if (file.Is_Available()) {
|
||||
unsigned long size = file.Size();
|
||||
if (size) {
|
||||
|
||||
/*
|
||||
** Read the file.
|
||||
*/
|
||||
char *file_buffer = new char[size + 8192];
|
||||
#ifdef WWDEBUG
|
||||
unsigned long read_size =
|
||||
#endif //WWDEBUG
|
||||
file.Read(file_buffer, size);
|
||||
WWASSERT(read_size == size);
|
||||
file.Close();
|
||||
|
||||
/*
|
||||
** Find the placeholder tag.
|
||||
*/
|
||||
char *tag = strstr(file_buffer, ServerListTag);
|
||||
char *end_tag = strstr(file_buffer, ServerListEnd);
|
||||
if (tag && end_tag) {
|
||||
|
||||
/*
|
||||
** Write out the first portion of the file unchanged.
|
||||
*/
|
||||
file.Open(FileClass::WRITE);
|
||||
file.Write(file_buffer, (tag - file_buffer) + strlen(ServerListTag));
|
||||
|
||||
/*
|
||||
** Insert the server list.
|
||||
*/
|
||||
char *server_list_text = new char [8192];
|
||||
strcpy(server_list_text, "\r\n;\r\n");
|
||||
|
||||
for (unsigned int i = 0; i < server_list.size(); i++) {
|
||||
const RefPtr<WWOnline::IRCServerData> &server = server_list[i];
|
||||
if (server->HasLanguageCode()) {
|
||||
const char *server_name = server->GetName();
|
||||
sprintf(temp, "; %s\r\n", server_name);
|
||||
strcat(server_list_text, temp);
|
||||
}
|
||||
}
|
||||
strcat(server_list_text, ";\r\n");
|
||||
file.Write(server_list_text, strlen(server_list_text));
|
||||
|
||||
/*
|
||||
** Write out the post server list sections of the original file.
|
||||
*/
|
||||
file.Write(end_tag, (file_buffer + size) - end_tag);
|
||||
file.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ServerSettingsClass::Check_Game_Settings_File -- Check game settings for validity *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Game settings .ini file name *
|
||||
* *
|
||||
* OUTPUT: True if valid. *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/3/2002 9:37PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
bool ServerSettingsClass::Check_Game_Settings_File(char *config_file)
|
||||
{
|
||||
cGameDataCnc *game_settings = (cGameDataCnc*) cGameData::Create_Game_Of_Type(cGameData::GAME_TYPE_CNC);
|
||||
WWASSERT(game_settings != NULL);
|
||||
|
||||
if (game_settings) {
|
||||
game_settings->Set_Ini_Filename(config_file);
|
||||
game_settings->Load_From_Server_Config();
|
||||
|
||||
WideStringClass outMsg;
|
||||
bool ok = game_settings->Is_Valid_Settings(outMsg, true);
|
||||
|
||||
delete game_settings;
|
||||
return(ok);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
88
Code/Commando/ServerSettings.h
Normal file
88
Code/Commando/ServerSettings.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
** 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/ServerSettings.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 8/08/02 1:00p $*
|
||||
* *
|
||||
* $Revision:: 7 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <win.h>
|
||||
#include "wwonline\wolsession.h"
|
||||
|
||||
class StringClass;
|
||||
|
||||
|
||||
class ServerSettingsClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
enum GameModeTypeEnum {
|
||||
MODE_NONE = 0,
|
||||
MODE_LAN,
|
||||
MODE_WOL,
|
||||
MODE_GAMESPY
|
||||
};
|
||||
|
||||
static void Set_Settings_File_Name(char *filename);
|
||||
static bool Is_Server_Settings_File_Set(void) {return((SettingsFile[0] == 0) ? false : true);}
|
||||
static bool Parse(bool apply = false);
|
||||
static bool Is_Command_Line_Mode(void) {return(IsActive);}
|
||||
static void Encrypt_Serial(StringClass serial_in, StringClass &serial_out, bool encrypt = true);
|
||||
static void Decrypt_Serial(StringClass serial_in, StringClass &serial_out);
|
||||
static const char *Get_Master_Server_Password(void) {return(MasterPassword);}
|
||||
static unsigned long Get_Master_Bandwidth(void) {return(MasterBandwidth);}
|
||||
static bool Is_Active(void) {return(IsActive);}
|
||||
static char *Get_Settings_File_Name(void) {return(SettingsFile);}
|
||||
static bool Check_Game_Settings_File(char *config_file);
|
||||
static GameModeTypeEnum Get_Game_Mode(void) {return(GameMode);}
|
||||
static int Get_Disk_Log_Size(void) {return(DiskLogSize);}
|
||||
|
||||
/*
|
||||
** Populating ini file with server list.
|
||||
*/
|
||||
static char *Get_Preferred_Server(const WWOnline::IRCServerList &server_list);
|
||||
static void Write_Server_List(const WWOnline::IRCServerList &server_listvoid);
|
||||
private:
|
||||
static char SettingsFile[MAX_PATH];
|
||||
static bool IsActive;
|
||||
|
||||
static char MasterPassword[128];
|
||||
static unsigned long MasterBandwidth;
|
||||
static char PreferredLoginServer[256];
|
||||
static GameModeTypeEnum GameMode;
|
||||
static int DiskLogSize;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
808
Code/Commando/WINMAIN.CPP
Normal file
808
Code/Commando/WINMAIN.CPP
Normal file
@@ -0,0 +1,808 @@
|
||||
/*
|
||||
** 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/WINMAIN.CPP $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 2/17/02 11:08a $*
|
||||
* *
|
||||
* $Revision:: 85 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* WinMain -- Win32 Program Entry Point! *
|
||||
* WIN_resize -- Surrender-required function which resizes the main window *
|
||||
* WIN_set_fullscreen -- Surrender-required function for toggling full-screen mode *
|
||||
* Main_Window_Proc -- Windows Proc for the main game window *
|
||||
* Create_Main_Window -- Creates the main game window *
|
||||
* On_Focus_Loss -- this function is called when the application loses focus *
|
||||
* On_Focus_Restore -- This function is called when the application gets focus *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "winmain.h"
|
||||
#define _WIN32_WINDOWS 0x0401
|
||||
#include "win.h"
|
||||
#include "resource.h"
|
||||
#include "WW3D.H"
|
||||
|
||||
#include "miscutil.h"
|
||||
#include "input.h"
|
||||
#include "useroptions.h"
|
||||
|
||||
#include "WWAudio.H"
|
||||
#include "FFactory.H"
|
||||
|
||||
#include "debug.h"
|
||||
#include "verchk.h"
|
||||
#include "devoptions.h"
|
||||
#include "dialogmgr.h"
|
||||
#include "renegadedialogmgr.h"
|
||||
#include "except.h"
|
||||
|
||||
#include "DirectInput.h"
|
||||
#include "WebBrowser.h"
|
||||
#include "wwmemlog.h"
|
||||
|
||||
#include "datasafe.h"
|
||||
|
||||
#include "combatgmode.h"
|
||||
#include "registry.h"
|
||||
#include "init.h"
|
||||
#include "_globals.h"
|
||||
#include "buildnum.h"
|
||||
#include "dx8wrapper.h"
|
||||
#include "formconv.h"
|
||||
#include "autostart.h"
|
||||
#include "consolemode.h"
|
||||
#include "specialbuilds.h"
|
||||
#include "slavemaster.h"
|
||||
|
||||
#include "serversettings.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <crtdbg.h>
|
||||
#endif //_DEBUG
|
||||
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(push,1)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include "singletoninstancekeeper.h"
|
||||
#include "packetmgr.h"
|
||||
|
||||
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Globals
|
||||
//----------------------------------------------------------------------------
|
||||
extern "C"
|
||||
{
|
||||
HWND hWndMain;
|
||||
bool WIN_fullscreen = true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
//----------------------------------------------------------------------------
|
||||
static BOOL Create_Main_Window(HANDLE hInstance, int nCmdShow);
|
||||
long FAR PASCAL Main_Window_Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
void On_Focus_Loss(void);
|
||||
void On_Focus_Restore(void);
|
||||
void Split_Command_Line_Args(HINSTANCE instance, char *path_to_exe, char *command_line);
|
||||
void Set_Working_Directory(char *old_path, char *new_path);
|
||||
int Start_Application( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
|
||||
void Set_Working_Directory(HINSTANCE hInstance);
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
long Top_Level_Exception_Filter(EXCEPTION_POINTERS *e_info)
|
||||
{
|
||||
return(Exception_Handler(e_info->ExceptionRecord->ExceptionCode, e_info));
|
||||
}
|
||||
#endif //_MSC_VER
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* WinMain -- Win32 Program Entry Point! *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* Standard WinMain inputs :-) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* Standard WinMain output *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
|
||||
{
|
||||
WWMemoryLogClass::Init(); // This switches memlog from static to dynamic allocations mode
|
||||
|
||||
#ifdef _DEBUG
|
||||
/*
|
||||
** Setup to track memory heap integrity and check for
|
||||
** memory leaks. Output is dumped to the debug string console.
|
||||
*/
|
||||
if (cDevOptions::CrtDbgEnabled.Is_True()) {
|
||||
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
}
|
||||
|
||||
/*
|
||||
** Leak test
|
||||
*/
|
||||
//char *flibble = new char [1024];
|
||||
//unsigned long *flibble2 = new unsigned long;
|
||||
//void *flibble3 = malloc(128);
|
||||
|
||||
//flibble = flibble;
|
||||
//flibble2 = flibble2;
|
||||
//flibble3 = flibble3;
|
||||
#endif //_DEBUG
|
||||
|
||||
#ifdef WWDEBUG
|
||||
//
|
||||
// If necessary, disable packet optimizations
|
||||
//
|
||||
if (cDevOptions::PacketOptimizationsEnabled.Is_False()) {
|
||||
PacketManager.Disable_Optimizations();
|
||||
}
|
||||
#endif //WWDEBUG
|
||||
|
||||
#ifdef _DEBUG // Denzil - DO NOT COMPILE INTO FINAL BUILD
|
||||
bool webInstalled = WebBrowser::InstallPrerequisites();
|
||||
|
||||
if (!webInstalled) {
|
||||
::MessageBox(NULL, "Embedded browser prerequisites missing\n\nBrowser functionality questionable.\n\n(Please call Denzil @ 27272)",
|
||||
"Renegade Warning!", MB_ICONWARNING|MB_OK);
|
||||
}
|
||||
#endif // WWDEBUG
|
||||
|
||||
if (!cUserOptions::Parse_Command_Line(lpCmdLine)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
//
|
||||
// There's a couple of options we need for the FDS
|
||||
//
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
if (!SlaveMaster.Am_I_Slave() && !ServerSettingsClass::Is_Server_Settings_File_Set()) {
|
||||
cUserOptions::Set_Server_INI_File("STARTSERVER=server.ini");
|
||||
}
|
||||
ConsoleBox.Set_Exclusive(true);
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
|
||||
//
|
||||
// Verify that we can execute (i.e. make sure there are no other instances running)
|
||||
//
|
||||
SingletonInstanceKeeperClass instance_keeper;
|
||||
if (instance_keeper.Verify_Safe_To_Execute () == false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Start the game!
|
||||
//
|
||||
int retval = Start_Application( hInstance, hPrevInstance, lpCmdLine, nCmdShow );
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool Graphics_Settings_Trouble_Shooting()
|
||||
{
|
||||
RegistryClass registry( APPLICATION_SUB_KEY_NAME_DEBUG );
|
||||
if (!registry.Is_Valid()) return true;
|
||||
|
||||
int progress=registry.Get_Int( VALUE_NAME_GAME_INITIALIZATION_IN_PROGRESS, 0 );
|
||||
if (progress) {
|
||||
StringClass options="wwconfig.exe ";
|
||||
char* opts=options.Peek_Buffer();
|
||||
STARTUPINFO startup_info;
|
||||
ZeroMemory(&startup_info,sizeof(STARTUPINFO));
|
||||
startup_info.cb=sizeof(STARTUPINFO);
|
||||
PROCESS_INFORMATION process_info;
|
||||
CreateProcess(
|
||||
NULL,
|
||||
opts,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&startup_info,
|
||||
&process_info);
|
||||
|
||||
unsigned long exit_code=STILL_ACTIVE;
|
||||
unsigned res=0;
|
||||
do {
|
||||
res=GetExitCodeProcess(process_info.hProcess,&exit_code);
|
||||
if (!res) {
|
||||
return true;
|
||||
}
|
||||
Sleep(100);
|
||||
}
|
||||
while (exit_code==STILL_ACTIVE);
|
||||
return !exit_code;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef IDirect3D8* (WINAPI *Direct3DCreate8Type) (UINT SDKVersion);
|
||||
static Direct3DCreate8Type Direct3DCreate8Ptr = NULL;
|
||||
static HINSTANCE D3D8Lib = NULL;
|
||||
|
||||
static bool Video_Card_Driver_Check()
|
||||
{
|
||||
RegistryClass render_registry(APPLICATION_SUB_KEY_NAME_RENDER);
|
||||
if (!render_registry.Is_Valid()) return true;
|
||||
|
||||
int disabled=render_registry.Get_Int( "DriverVersionCheckDisabled" );
|
||||
if (disabled>=87) return true;
|
||||
|
||||
IDirect3D8* d3d=NULL;
|
||||
D3DCAPS8 tmp_caps;
|
||||
const D3DCAPS8* d3dcaps=NULL;
|
||||
D3DADAPTER_IDENTIFIER8 adapter_id;
|
||||
|
||||
// Init D3D
|
||||
Init_D3D_To_WW3_Conversion();
|
||||
|
||||
D3D8Lib = LoadLibrary("D3D8.DLL");
|
||||
|
||||
if (D3D8Lib != NULL) {
|
||||
Direct3DCreate8Ptr = (Direct3DCreate8Type) GetProcAddress(D3D8Lib, "Direct3DCreate8");
|
||||
if (Direct3DCreate8Ptr) {
|
||||
d3d=Direct3DCreate8Ptr(D3D_SDK_VERSION); // TODO: handle failure cases...
|
||||
if (!d3d) {
|
||||
FreeLibrary(D3D8Lib);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
FreeLibrary(D3D8Lib);
|
||||
return(true);
|
||||
}
|
||||
} else {
|
||||
return(true);
|
||||
}
|
||||
|
||||
// Select device. If there is already a device selected in the registry, use it.
|
||||
|
||||
int current_adapter_index=D3DADAPTER_DEFAULT;
|
||||
|
||||
//
|
||||
// Load the render device settings from the registry
|
||||
//
|
||||
char device_name[256] = { 0 };
|
||||
render_registry.Get_String( VALUE_NAME_RENDER_DEVICE_NAME, device_name, sizeof(device_name));
|
||||
|
||||
int adapter_count = d3d->GetAdapterCount();
|
||||
for (int adapter_index=0; adapter_index<adapter_count; adapter_index++) {
|
||||
D3DADAPTER_IDENTIFIER8 id;
|
||||
::ZeroMemory(&id, sizeof(D3DADAPTER_IDENTIFIER8));
|
||||
HRESULT res = d3d->GetAdapterIdentifier(adapter_index,D3DENUM_NO_WHQL_LEVEL,&id);
|
||||
// If device ok, check if it matches the currently set adapter name
|
||||
if (res == D3D_OK) {
|
||||
StringClass name(id.Description,true);
|
||||
if (name==device_name) {
|
||||
current_adapter_index=adapter_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(d3d->GetDeviceCaps(
|
||||
current_adapter_index,
|
||||
D3DDEVTYPE_HAL,
|
||||
&tmp_caps))) {
|
||||
d3d->Release();
|
||||
FreeLibrary(D3D8Lib);
|
||||
return true;
|
||||
}
|
||||
|
||||
::ZeroMemory(&adapter_id, sizeof(D3DADAPTER_IDENTIFIER8));
|
||||
if (FAILED( d3d->GetAdapterIdentifier(
|
||||
current_adapter_index,
|
||||
D3DENUM_NO_WHQL_LEVEL,
|
||||
&adapter_id))) {
|
||||
d3d->Release();
|
||||
FreeLibrary(D3D8Lib);
|
||||
return true;
|
||||
}
|
||||
|
||||
d3dcaps=&tmp_caps;
|
||||
DX8Caps caps(d3d,*d3dcaps,WW3D_FORMAT_UNKNOWN,adapter_id);
|
||||
|
||||
DX8Caps::DriverVersionStatusType status=caps.Get_Driver_Version_Status();
|
||||
|
||||
d3d->Release();
|
||||
FreeLibrary(D3D8Lib);
|
||||
|
||||
switch (status) {
|
||||
default:
|
||||
case DX8Caps::DRIVER_STATUS_GOOD:
|
||||
case DX8Caps::DRIVER_STATUS_OK:
|
||||
case DX8Caps::DRIVER_STATUS_UNKNOWN:
|
||||
render_registry.Set_Int( "DriverVersionCheckDisabled",87 );
|
||||
return true;
|
||||
break;
|
||||
case DX8Caps::DRIVER_STATUS_BAD:
|
||||
break;
|
||||
}
|
||||
|
||||
StringClass options="wwconfig.exe -driverversion";
|
||||
char* opts=options.Peek_Buffer();
|
||||
STARTUPINFO startup_info;
|
||||
ZeroMemory(&startup_info,sizeof(STARTUPINFO));
|
||||
startup_info.cb=sizeof(STARTUPINFO);
|
||||
PROCESS_INFORMATION process_info;
|
||||
if (!CreateProcess(
|
||||
NULL,
|
||||
opts,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&startup_info,
|
||||
&process_info)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long exit_code=STILL_ACTIVE;
|
||||
unsigned res=0;
|
||||
do {
|
||||
res=GetExitCodeProcess(process_info.hProcess,&exit_code);
|
||||
if (!res) {
|
||||
return true;
|
||||
}
|
||||
Sleep(100);
|
||||
}
|
||||
while (exit_code==STILL_ACTIVE);
|
||||
return !exit_code;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Start_Application -- Handles WinMain execution. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* Standard WinMain inputs :-) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* Standard WinMain output *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/19/2001 PDS : Created. *
|
||||
*=============================================================================================*/
|
||||
int Start_Application( HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow )
|
||||
{
|
||||
{
|
||||
WWMEMLOG(MEM_GAMEINIT);
|
||||
//LPSTR command = lpCmdLine;
|
||||
|
||||
/*
|
||||
** Set the working directory.
|
||||
*/
|
||||
Set_Working_Directory(hInstance);
|
||||
|
||||
//
|
||||
// TEMP Dev code - check the working folder is correct!
|
||||
//
|
||||
char tmp_buffer[256];
|
||||
char* tmp_ptr;
|
||||
if (!SearchPath(
|
||||
"data",
|
||||
"always.dat",
|
||||
NULL,
|
||||
sizeof(tmp_buffer),
|
||||
tmp_buffer,
|
||||
&tmp_ptr)) {
|
||||
MessageBox(NULL,"Set working folder and try again...","Invalid working folder",MB_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Only do these checks if this isn't an auto-restart. If we are restarting then we must have run once OK already. Right?
|
||||
*/
|
||||
if (AutoRestart.Get_Restart_Flag() == false && !ConsoleBox.Is_Exclusive()) {
|
||||
if (!Video_Card_Driver_Check()) return 0;
|
||||
if (!Graphics_Settings_Trouble_Shooting()) return 0;
|
||||
}
|
||||
|
||||
//Debug_Say(("Started logging at time %s", cMiscUtil::Get_Text_Time()));
|
||||
|
||||
if (!Create_Main_Window(hInstance, nCmdShow)) return 0;
|
||||
|
||||
Register_Thread_ID(GetCurrentThreadId(), "Main Thread", true);
|
||||
}
|
||||
|
||||
int exitCode = EXIT_SUCCESS;
|
||||
|
||||
#ifdef WWDEBUG
|
||||
if (cDevOptions::EnableExceptionHandler.Is_False()) {
|
||||
exitCode = Game_Main_Loop();
|
||||
} else {
|
||||
#endif //WWDEBUG
|
||||
|
||||
Register_Application_Exception_Callback(&Application_Exception_Callback);
|
||||
Register_Application_Version_Callback(&BuildInfoClass::Composite_Build_Info);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/*
|
||||
** The __try/__except construct is part of the WIN32 interface. This is not the same
|
||||
** as C++ exception handling. There is no additional code overhead required
|
||||
** with this interface and the compilers exception handling options should be disabled
|
||||
** to prevent the compiler generating additional stack unwinding code.
|
||||
*/
|
||||
__try {
|
||||
#else
|
||||
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) &Top_Level_Exception_Filter);
|
||||
#endif
|
||||
WWDEBUG_SAY(("Game_Main_Loop\n"));
|
||||
exitCode = Game_Main_Loop();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
} __except(Exception_Handler(GetExceptionCode(), GetExceptionInformation())) {};
|
||||
|
||||
/*
|
||||
** Set the exception filter to use on shutdown.
|
||||
*/
|
||||
#else
|
||||
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) &Top_Level_Exception_Filter);
|
||||
#endif
|
||||
#ifdef WWDEBUG
|
||||
}
|
||||
#endif //WWDEBUG
|
||||
|
||||
Unregister_Thread_ID(GetCurrentThreadId(), "Main Thread");
|
||||
|
||||
//Debug_Say(("Finished logging at time %s", cMiscUtil::Get_Text_Time()));
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Main_Window_Proc -- Windows Proc for the main game window *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* Standard Windows Proc inputs *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* Standard Windows Proc output *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
long FAR PASCAL Main_Window_Proc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
static bool _reset = false;
|
||||
|
||||
/*
|
||||
** Pass this message through to the input handler. If the message
|
||||
** was processed and requires no further action, then return with
|
||||
** this information.
|
||||
*/
|
||||
if (_TheWWUIInput && Input::Is_Console_Enabled () == false) {
|
||||
LRESULT result = 0;
|
||||
|
||||
//DialogWalker->Process_Message(hwnd, message, wParam, lParam, result);
|
||||
|
||||
if (_TheWWUIInput->ProcessMessage(hwnd, message, wParam, lParam, result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
switch (message )
|
||||
{
|
||||
/*
|
||||
** basic management messages
|
||||
*/
|
||||
case WM_ACTIVATEAPP:
|
||||
if (wParam && !GameInFocus) {
|
||||
WWDEBUG_SAY(("***** FOCUS GAINED *****\n"));
|
||||
GameInFocus = true;
|
||||
On_Focus_Restore();
|
||||
} else if (!wParam && GameInFocus) {
|
||||
WWDEBUG_SAY(("***** FOCUS LOST *****\n"));
|
||||
GameInFocus = false;
|
||||
On_Focus_Loss();
|
||||
}
|
||||
return(0);
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
return 1;
|
||||
|
||||
case WM_PAINT:
|
||||
ValidateRect(hwnd, NULL);
|
||||
break;
|
||||
|
||||
/*
|
||||
** minimize/maximize
|
||||
*/
|
||||
case WM_SYSKEYDOWN:
|
||||
|
||||
if (wParam == VK_RETURN && ((lParam>>16) & KF_ALTDOWN) && !((lParam>>16) & KF_REPEAT))
|
||||
{
|
||||
if (WIN_fullscreen) {
|
||||
WIN_fullscreen = false;
|
||||
} else {
|
||||
WIN_fullscreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
** getch()
|
||||
*/
|
||||
case WM_CHAR:
|
||||
//Debug_Say(("WM_CHAR %d\n", wParam));
|
||||
Input::Console_Add_Key( wParam );
|
||||
break;
|
||||
|
||||
/*
|
||||
** Main window creation
|
||||
*/
|
||||
case WM_CREATE:
|
||||
break;
|
||||
|
||||
/*
|
||||
** Main window destruction
|
||||
*/
|
||||
case WM_DESTROY:
|
||||
ReleaseCapture ();
|
||||
PostQuitMessage (0);
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
switch (wParam) {
|
||||
|
||||
case SC_CLOSE:
|
||||
/*
|
||||
** Windows sent us a close message. Probably in response to Alt-F4. Ignore it by
|
||||
** pretending to handle the message and returning true;
|
||||
*/
|
||||
return (0);
|
||||
|
||||
case SC_KEYMENU:
|
||||
/*
|
||||
** Ignore all "menu-activation" commands.
|
||||
*/
|
||||
return (0);
|
||||
|
||||
case SC_SCREENSAVE:
|
||||
/*
|
||||
** Windoze is about to start the screen saver. If we just return without passing
|
||||
** this message to DefWindowProc then the screen saver will not be allowed to start.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
|
||||
// Denzil - Using WM_xxxFOCUS messages to switch to windowed / fullscreen fails.
|
||||
#if(0)
|
||||
case WM_KILLFOCUS:
|
||||
{
|
||||
if (WW3D::Is_Initted ()) {
|
||||
|
||||
// Get the current state of the redendering device
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int bits = 0;
|
||||
bool bwindowed = false;
|
||||
WW3D::Get_Device_Resolution (width, height, bits, bwindowed);
|
||||
|
||||
// If we are running fullscreen, then toggle to 'windowed'
|
||||
// and minimze the window.
|
||||
if (bwindowed == false) {
|
||||
//Debug_Say(("WM_KILLFOCUS minimize"));
|
||||
WW3D::Set_Device_Resolution (-1, -1, -1, true);
|
||||
::ShowWindow (hwnd, SW_MINIMIZE);
|
||||
_reset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
|
||||
// If we need to reset the app to 'fullscreen' mode then
|
||||
// do so an restore the window.
|
||||
if (_reset == true) {
|
||||
WW3D::Set_Device_Resolution (-1, -1, -1, false);
|
||||
::ShowWindow (hwnd, SW_RESTORE);
|
||||
_reset = false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case WM_COMMAND:
|
||||
if (LOWORD (wParam) == IDM_TOGGLE_FULLSCREEN) {
|
||||
|
||||
// Ask WW3D to toggle the fullscreen mode for us.
|
||||
WW3D::Toggle_Windowed ();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Create_Main_Window -- Creates the main game window *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* hInstance -- Instance handle of the application *
|
||||
* nCmdShow -- how the window is to be shown *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* TRUE = success, FALSE = failure *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
static BOOL Create_Main_Window(HANDLE hInstance, int nCmdShow)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
BOOL rc;
|
||||
|
||||
ProgramInstance = (HINSTANCE)hInstance;
|
||||
|
||||
if (!ConsoleBox.Is_Exclusive()) {
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||
wc.lpfnWndProc = Main_Window_Proc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = (HINSTANCE)hInstance;
|
||||
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = SingletonInstanceKeeperClass::Get_GUID ();
|
||||
|
||||
rc = RegisterClass( &wc);
|
||||
if (!rc ) return FALSE;
|
||||
|
||||
// Assume windowed mode
|
||||
MainWindow = CreateWindowEx(0, SingletonInstanceKeeperClass::Get_GUID(), "Renegade",
|
||||
WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX|WS_CLIPCHILDREN,
|
||||
0, 0, 0, 0, NULL, NULL, ProgramInstance, NULL);
|
||||
|
||||
if (!MainWindow) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetFocus(MainWindow);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* On_Focus_Loss -- this function is called when the application loses focus *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
void On_Focus_Loss(void)
|
||||
{
|
||||
DirectInput::Unacquire();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* On_Focus_Restore -- This function is called when the application gets focus *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
void On_Focus_Restore(void)
|
||||
{
|
||||
if (WebBrowser::IsWebPageDisplayed() == false) {
|
||||
DirectInput::Acquire();
|
||||
}
|
||||
|
||||
GameModeManager::Hide_Render_Frames(1); // Hide the first rendered frame
|
||||
}
|
||||
|
||||
|
||||
void Prog_End(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Set_Working_Directory -- Sets current directory to be the same as the .exe *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Program instance *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/6/2001 12:11PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void Set_Working_Directory(HINSTANCE instance)
|
||||
{
|
||||
char path_to_exe[256];
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char path[_MAX_PATH];
|
||||
|
||||
GetModuleFileName(instance, path_to_exe, sizeof(path_to_exe));
|
||||
_splitpath(path_to_exe, drive, dir, NULL, NULL);
|
||||
_makepath(path, drive, dir, NULL, NULL);
|
||||
SetCurrentDirectory(path);
|
||||
}
|
||||
47
Code/Commando/WINMAIN.H
Normal file
47
Code/Commando/WINMAIN.H
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/WINMAIN.H $*
|
||||
* *
|
||||
* $Author:: Denzil_l $*
|
||||
* *
|
||||
* $Modtime:: 10/15/01 2:45p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef WINMAIN_H
|
||||
#define WINMAIN_H
|
||||
|
||||
#ifndef ALWAYS_H
|
||||
#include "always.h"
|
||||
#endif
|
||||
|
||||
// This is the main entry point of the game, located in another library
|
||||
extern int Game_Main_Loop(void);
|
||||
|
||||
#endif
|
||||
1496
Code/Commando/WOLBuddyMgr.cpp
Normal file
1496
Code/Commando/WOLBuddyMgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
225
Code/Commando/WOLBuddyMgr.h
Normal file
225
Code/Commando/WOLBuddyMgr.h
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLBuddyMgr.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 14 $
|
||||
* $Modtime: 1/31/02 2:52p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLBUDDYMGR_H__
|
||||
#define __WOLBUDDYMGR_H__
|
||||
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWOnline\WOLPageMsg.h>
|
||||
#include <WWLib\RefCount.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWLib\Signaler.h>
|
||||
#include <WWLib\WideString.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
class DlgPasswordPrompt;
|
||||
class WOLBuddyMgr;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUDDYLIST_CHANGED = 1,
|
||||
IGNORELIST_CHANGED,
|
||||
BUDDYINFO_CHANGED
|
||||
} WOLBuddyMgrAction;
|
||||
|
||||
typedef TypedActionPtr<WOLBuddyMgrAction, WOLBuddyMgr> WOLBuddyMgrEvent;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PAGE_ERROR = 0,
|
||||
PAGE_NOT_THERE = 1,
|
||||
PAGE_TURNED_OFF,
|
||||
PAGE_SENT,
|
||||
PAGE_RECEIVED,
|
||||
INVITATION_RECEIVED,
|
||||
INVITATION_DECLINED
|
||||
} WOLPagedAction;
|
||||
|
||||
typedef TypedActionPtr<WOLPagedAction, WWOnline::PageMessage> WOLPagedEvent;
|
||||
|
||||
class WOLBuddyMgr :
|
||||
public RefCountClass,
|
||||
public Notifier<WOLBuddyMgrEvent>,
|
||||
public Notifier<WOLPagedEvent>,
|
||||
protected Observer<WWOnline::BuddyEvent>,
|
||||
protected Observer<WWOnline::UserEvent>,
|
||||
protected Observer<WWOnline::PageMessage>,
|
||||
protected Observer<WWOnline::PageSendStatus>,
|
||||
protected Signaler<DlgPasswordPrompt>
|
||||
{
|
||||
public:
|
||||
typedef std::vector< WideStringClass > IgnoreList;
|
||||
typedef WWOnline::PageMessageList PageList;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DECLINE_MIN = 0,
|
||||
DECLINE_BYUSER = 1,
|
||||
DECLINE_NOTBUDDY,
|
||||
DECLINE_NOTAPPLICABLE,
|
||||
DECLINE_BUSY,
|
||||
DECLINE_MAX
|
||||
} DECLINE_REASON;
|
||||
|
||||
static WOLBuddyMgr* GetInstance(bool createOK);
|
||||
|
||||
// Get a description of a users location.
|
||||
static void GetLocationDescription(const RefPtr<WWOnline::UserData>& user, WideStringClass& description);
|
||||
|
||||
// Request the buddy list anew.
|
||||
void RefreshBuddyList(void);
|
||||
|
||||
// Get list of buddies
|
||||
const WWOnline::UserList& GetBuddyList(void) const
|
||||
{return mWOLSession->GetBuddyList();}
|
||||
|
||||
// Get a user from our buddy list
|
||||
const RefPtr<WWOnline::UserData> FindBuddy(const WCHAR* name) const;
|
||||
|
||||
// Add a user to our buddy list
|
||||
void AddBuddy(const WCHAR* name);
|
||||
|
||||
// Remove a user from our buddy list
|
||||
void RemoveBuddy(const WCHAR* name);
|
||||
|
||||
// Check if a user is in our buddy list
|
||||
bool IsBuddy(const WCHAR* name) const;
|
||||
|
||||
// Request update to the location of our buddies.
|
||||
void RefreshBuddyInfo(void);
|
||||
|
||||
// Add a user to the ignore list
|
||||
void AddIgnore(const WCHAR* name);
|
||||
|
||||
// Remove a user from the ignore list.
|
||||
void RemoveIgnore(const WCHAR* name);
|
||||
|
||||
// Check if a user is in the ignore list.
|
||||
bool IsIgnored(const WCHAR* name) const;
|
||||
|
||||
// Get a list of usernames we are ignoring
|
||||
const IgnoreList& GetIngoreList(void) const
|
||||
{return mIgnoreList;}
|
||||
|
||||
const PageList& GetPageList(void) const
|
||||
{return mPageList;}
|
||||
|
||||
// Enable the display of a dialog when paged.
|
||||
// This function sets an internal counter that determines whether a dialog
|
||||
// should be displayed when a page message is received.
|
||||
void ShowPagedDialog(void);
|
||||
|
||||
// Disable the display of a dialog when paged.
|
||||
// This function sets an internal counter that determines whether a dialog
|
||||
// should be displayed when a page message is received.
|
||||
void HidePagedDialog(void);
|
||||
|
||||
// Clear all the queued pages.
|
||||
void ClearPageList(void);
|
||||
|
||||
// Get the name of the last user who we received a page from.
|
||||
const WCHAR* GetLastPagersName(void) const
|
||||
{return mLastPagersName;}
|
||||
|
||||
// Send a page message to user
|
||||
void PageUser(const WCHAR* name, const WCHAR* message);
|
||||
|
||||
// Join a user at his location
|
||||
void JoinUser(const RefPtr<WWOnline::UserData>& user);
|
||||
|
||||
// Check if we are in a position to invite users.
|
||||
bool CanInviteUsers(void) const;
|
||||
|
||||
// Invite a user to our location
|
||||
void InviteUser(const WCHAR* username, const WCHAR* message);
|
||||
|
||||
// Decline an invitation to join a user.
|
||||
void DeclineInvitation(const WCHAR* username, DECLINE_REASON reason = DECLINE_BYUSER);
|
||||
|
||||
protected:
|
||||
WOLBuddyMgr();
|
||||
~WOLBuddyMgr();
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
void LoadIgnoreList(void);
|
||||
void SaveIgnoreList(void);
|
||||
|
||||
bool IsCommand(const WCHAR* message);
|
||||
|
||||
void ProcessPendingJoin(void);
|
||||
void GotoPendingJoinLocation(const wchar_t* password);
|
||||
void ReceiveSignal(DlgPasswordPrompt&);
|
||||
|
||||
bool IsInvitation(const WCHAR* message);
|
||||
void InvitationReceived(WWOnline::PageMessage& page);
|
||||
void DisplayInvitation(const RefPtr<WWOnline::UserData>& user, const WCHAR* message);
|
||||
|
||||
bool IsInvitationDeclined(const WCHAR* message);
|
||||
void InvitationDeclined(const WCHAR* username, DECLINE_REASON reaon);
|
||||
|
||||
void HandleNotification(WWOnline::BuddyEvent&);
|
||||
void HandleNotification(WWOnline::UserEvent&);
|
||||
void HandleNotification(WWOnline::PageMessage&);
|
||||
void HandleNotification(WWOnline::PageSendStatus&);
|
||||
|
||||
DECLARE_NOTIFIER(WOLBuddyMgrEvent)
|
||||
DECLARE_NOTIFIER(WOLPagedEvent)
|
||||
|
||||
private:
|
||||
static WOLBuddyMgr* _mInstance;
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
|
||||
IgnoreList mIgnoreList;
|
||||
|
||||
PageList mPageList;
|
||||
PageList mInvitations;
|
||||
WideStringClass mLastPagersName;
|
||||
unsigned long mHidePagedDialog;
|
||||
|
||||
RefPtr<WWOnline::UserData> mPendingJoin;
|
||||
};
|
||||
|
||||
#endif __WOLBUDDYMGR_H__
|
||||
1560
Code/Commando/WOLChatMgr.cpp
Normal file
1560
Code/Commando/WOLChatMgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
151
Code/Commando/WOLChatMgr.h
Normal file
151
Code/Commando/WOLChatMgr.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLChatMgr.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 18 $
|
||||
* $Modtime: 11/08/01 2:31p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLCHATMGR_H__
|
||||
#define __WOLCHATMGR_H__
|
||||
|
||||
#include <WWLib\RefCount.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWLib\WideString.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWOnline\WOLChatMsg.h>
|
||||
|
||||
typedef std::vector< RefPtr<WWOnline::ChannelData> > LobbyList;
|
||||
|
||||
enum WOLChatMgrEvent
|
||||
{
|
||||
LobbyListChanged = 1,
|
||||
LobbyChanged,
|
||||
UserInListChanged,
|
||||
UserOutListChanged,
|
||||
MessageListChanged,
|
||||
KickedFromChannel,
|
||||
BannedFromChannel
|
||||
};
|
||||
|
||||
class WOLChatMgr :
|
||||
public RefCountClass,
|
||||
public Notifier<WOLChatMgrEvent>,
|
||||
public Observer<WWOnline::ServerError>,
|
||||
public Observer<WWOnline::ChannelListEvent>,
|
||||
public Observer<WWOnline::ChannelEvent>,
|
||||
public Observer<WWOnline::UserEvent>,
|
||||
public Observer<WWOnline::UserList>,
|
||||
public Observer<WWOnline::ChatMessage>
|
||||
{
|
||||
public:
|
||||
static WOLChatMgr* GetInstance(bool createOK);
|
||||
|
||||
void Start(void);
|
||||
void Stop(void);
|
||||
|
||||
// Lobby Methods
|
||||
void RefreshLobbyList(void);
|
||||
const LobbyList& GetLobbyList(void);
|
||||
|
||||
const RefPtr<WWOnline::ChannelData>& GetCurrentLobby(void);
|
||||
const RefPtr<WWOnline::ChannelData> FindLobby(const wchar_t* name);
|
||||
|
||||
void CreateLobby(const wchar_t* name, const wchar_t* password);
|
||||
void JoinLobby(const RefPtr<WWOnline::ChannelData>& channel);
|
||||
void LeaveLobby(void);
|
||||
void GetLobbyDisplayName(const RefPtr<WWOnline::ChannelData>& lobby, WideStringClass& outName);
|
||||
|
||||
// User Methods
|
||||
const RefPtr<WWOnline::UserData> FindUser(const wchar_t* name);
|
||||
|
||||
inline const WWOnline::UserList& GetUserInList(void)
|
||||
{return mUserInList;}
|
||||
|
||||
void ClearUserInList(void);
|
||||
|
||||
inline const WWOnline::UserList& GetUserOutList(void)
|
||||
{return mUserOutList;}
|
||||
|
||||
void ClearUserOutList(void);
|
||||
|
||||
bool SquelchUser(const RefPtr<WWOnline::UserData>& user, bool onoff);
|
||||
void LocateUser(const wchar_t* name);
|
||||
|
||||
// Message Methods
|
||||
inline const WWOnline::ChatMessageList& GetMessageList(void)
|
||||
{return mMessageList;}
|
||||
|
||||
void ClearMessageList(void);
|
||||
|
||||
void SendPublicMessage(const wchar_t* message, bool isAction);
|
||||
void SendPrivateMessage(const RefPtr<WWOnline::UserData>& user, const wchar_t* message, bool isAction);
|
||||
void SendPrivateMessage(WWOnline::UserList& users, const wchar_t* message, bool isAction);
|
||||
|
||||
protected:
|
||||
WOLChatMgr();
|
||||
~WOLChatMgr();
|
||||
|
||||
// Delcare here to prevent copy and assignment
|
||||
WOLChatMgr(const WOLChatMgr&);
|
||||
const WOLChatMgr& operator=(const WOLChatMgr&);
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
bool IsLobbyValid(const RefPtr<WWOnline::ChannelData>& lobby);
|
||||
|
||||
void AddMessage(const wchar_t* sender, const wchar_t* message, bool isPrivate, bool isAction);
|
||||
bool PassesFilters(const WWOnline::ChatMessage& msg);
|
||||
|
||||
void HandleNotification(WWOnline::ServerError&);
|
||||
void HandleNotification(WWOnline::ChannelListEvent&);
|
||||
void HandleNotification(WWOnline::ChannelEvent&);
|
||||
void HandleNotification(WWOnline::UserEvent&);
|
||||
void HandleNotification(WWOnline::UserList&);
|
||||
void HandleNotification(WWOnline::ChatMessage&);
|
||||
|
||||
bool ProcessCommand(const wchar_t* message);
|
||||
|
||||
private:
|
||||
static WOLChatMgr* _mInstance;
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
|
||||
WideStringClass mLobbyPrefix;
|
||||
LobbyList mLobbyList;
|
||||
|
||||
WWOnline::UserList mUserInList;
|
||||
WWOnline::UserList mUserOutList;
|
||||
WideStringClass mLocatingUserName;
|
||||
|
||||
WWOnline::ChatMessageList mMessageList;
|
||||
};
|
||||
|
||||
#endif __WOLCHATMGR_H__
|
||||
134
Code/Commando/WOLDiags.cpp
Normal file
134
Code/Commando/WOLDiags.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
#ifdef WWDEBUG
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLDiags.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 4 $
|
||||
* $Modtime: 1/11/02 5:43p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "WOLDiags.h"
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWOnline\WOLServer.h>
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
void ShowWOLVersion(const RefPtr<Session>& session)
|
||||
{
|
||||
unsigned long ver = 0;
|
||||
session->GetChatObject()->GetVersion(&ver);
|
||||
ConsoleFunctionClass::Print("WOLAPI V%u.%u\n", (ver >> 16), (ver & 0xFFFF));
|
||||
}
|
||||
|
||||
|
||||
void ShowServer(const RefPtr<Session>& session)
|
||||
{
|
||||
const RefPtr<IRCServerData>& server = session->GetCurrentServer();
|
||||
|
||||
if (server.IsValid())
|
||||
{
|
||||
WOL::Server& data = server->GetData();
|
||||
ConsoleFunctionClass::Print("Server: %s:%s TimeZone: %d Position:: %f/%f\n",
|
||||
(const char*)data.connlabel, (const char*)data.name, data.timezone, data.longitude, data.lattitude);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleFunctionClass::Print("WOL not connected\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ShowTopic(const RefPtr<Session>& session)
|
||||
{
|
||||
ConsoleFunctionClass::Print("Channel Topic: %s\n", session->GetChannelTopic());
|
||||
}
|
||||
|
||||
|
||||
void ShowPingServers(const RefPtr<Session>& session)
|
||||
{
|
||||
const PingServerList& pingServers = session->GetPingServerList();
|
||||
unsigned int count = pingServers.size();
|
||||
|
||||
for (unsigned int index = 0; index < count; index++)
|
||||
{
|
||||
const RefPtr<PingServerData>& ping = pingServers[index];
|
||||
ConsoleFunctionClass::Print("%-18s %-4dms - %s\n",
|
||||
ping->GetHostAddress(), ping->GetPingTime(), ping->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Dispatch
|
||||
{
|
||||
const char* Cmd;
|
||||
void (*Func)(const RefPtr<Session>&);
|
||||
};
|
||||
|
||||
|
||||
const char* WOLConsoleFunctionClass::Get_Help(void)
|
||||
{
|
||||
return ("WOL <command> - Show WOL information");
|
||||
}
|
||||
|
||||
void WOLConsoleFunctionClass::Activate(const char* input)
|
||||
{
|
||||
static Dispatch _dispatch[] =
|
||||
{
|
||||
{"pings", ShowPingServers},
|
||||
{"server", ShowServer},
|
||||
{"topic", ShowTopic},
|
||||
{"ver", ShowWOLVersion},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
RefPtr<Session> session = Session::GetInstance(false);
|
||||
|
||||
if (!session.IsValid())
|
||||
{
|
||||
ConsoleFunctionClass::Print("Westwood Online not active\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
const char* cmd = _dispatch[0].Cmd;
|
||||
|
||||
while (cmd != NULL)
|
||||
{
|
||||
if (stricmp(cmd, input) == 0)
|
||||
{
|
||||
_dispatch[index].Func(session);
|
||||
return;
|
||||
}
|
||||
|
||||
++index;
|
||||
cmd = _dispatch[index].Cmd;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // WWDEBUG
|
||||
51
Code/Commando/WOLDiags.h
Normal file
51
Code/Commando/WOLDiags.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
#ifdef WWDEBUG
|
||||
#ifndef __WOLDIAGS_H__
|
||||
#define __WOLDIAGS_H__
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLDiags.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 2 $
|
||||
* $Modtime: 9/21/01 3:14p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "ConsoleFunction.h"
|
||||
|
||||
class WOLConsoleFunctionClass : public ConsoleFunctionClass {
|
||||
public:
|
||||
const char* Get_Name(void)
|
||||
{return ("wol");}
|
||||
|
||||
const char* Get_Help(void);
|
||||
|
||||
void Activate(const char* input);
|
||||
};
|
||||
|
||||
#endif // __WOLDIAGS_H__
|
||||
#endif // WWDEBUG
|
||||
654
Code/Commando/WOLGameInfo.cpp
Normal file
654
Code/Commando/WOLGameInfo.cpp
Normal file
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLGameInfo.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Steve_t $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 18 $
|
||||
* $Modtime: 10/31/02 4:30p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "WOLGameInfo.h"
|
||||
#include "GameData.h"
|
||||
#include "CNetwork.h"
|
||||
#include <WWOnline\WOLUser.h>
|
||||
#include <WWOnline\WOLChannel.h>
|
||||
#include <WWOnline\PingProfile.h>
|
||||
#include <WWLib\RealCRC.h>
|
||||
#include "modpackagemgr.h"
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Default constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::WOLGameInfo(void) :
|
||||
mIsDataValid(false),
|
||||
mIsMapValid(true),
|
||||
mPingTime(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game.
|
||||
*
|
||||
* INPUTS
|
||||
* Game - Game to import information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::WOLGameInfo(const cGameData& theGame)
|
||||
{
|
||||
ImportFromGame(theGame);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game from a channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Channel to import game information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::WOLGameInfo(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
ImportFromChannel(channel);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::~WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::~WOLGameInfo(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::Reset
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::Reset(void)
|
||||
{
|
||||
mIsDataValid = false;
|
||||
mIsMapValid = true;
|
||||
|
||||
mVersion = 0;
|
||||
mGameType = 0;
|
||||
|
||||
mMapName[0] = 0;
|
||||
mModName[0] = 0;
|
||||
mTitle[0] = 0;
|
||||
|
||||
mMinPlayers = 0;
|
||||
mMaxPlayers = 0;
|
||||
mNumPlayers = 0;
|
||||
|
||||
mClanID1 = 0;
|
||||
mClanID2 = 0;
|
||||
|
||||
mIsMod = false;
|
||||
mIsLaddered = false;
|
||||
mIsPassworded = false;
|
||||
mIsQuickmatch = false;
|
||||
mIsDedicated = false;
|
||||
mIsFriendlyFire = false;
|
||||
mIsFreeWeapons = false;
|
||||
mIsTeamRemix = false;
|
||||
mIsTeamChange = false;
|
||||
mIsClanGame = false;
|
||||
mIsRepairBuildings = false;
|
||||
mIsDriverGunner = false;
|
||||
mSpawnWeapons = false;
|
||||
|
||||
mPingTime = -1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::ImportFromGame
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game.
|
||||
*
|
||||
* INPUTS
|
||||
* Game - Game to import information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::ImportFromGame(const cGameData& theGame)
|
||||
{
|
||||
Reset();
|
||||
|
||||
mIsDataValid = true;
|
||||
mIsMapValid = true;
|
||||
|
||||
mVersion = theGame.Get_Version_Number();
|
||||
mGameType = theGame.Get_Game_Type();
|
||||
|
||||
strncpy(mMapName, theGame.Get_Map_Name(), MAX_TEXT_LENGTH);
|
||||
mMapName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
strncpy(mModName, theGame.Get_Mod_Name(), MAX_TEXT_LENGTH);
|
||||
mModName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
wcstombs(mTitle, theGame.Get_Game_Title(), MAX_TEXT_LENGTH);
|
||||
mTitle[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
mMinPlayers = theGame.Get_Min_Players();
|
||||
mMaxPlayers = theGame.Get_Max_Players();
|
||||
mNumPlayers = theGame.Get_Current_Players();
|
||||
|
||||
mClanID1 = theGame.Get_Clan(0);
|
||||
mClanID2 = theGame.Get_Clan(1);
|
||||
|
||||
const WCHAR* password = theGame.Get_Password();
|
||||
mIsPassworded = ((password != NULL) && (wcslen(password) > 0));
|
||||
mIsLaddered = theGame.IsLaddered.Get();
|
||||
mIsQuickmatch = theGame.Is_QuickMatch_Server();
|
||||
mIsDedicated = theGame.IsDedicated.Get();
|
||||
|
||||
mIsFriendlyFire = theGame.IsFriendlyFirePermitted.Get();
|
||||
mIsFreeWeapons = theGame.IsFreeWeapons.Get();
|
||||
mIsTeamRemix = theGame.RemixTeams.Get();
|
||||
mIsTeamChange = theGame.IsTeamChangingAllowed.Get();
|
||||
mIsClanGame = theGame.IsClanGame.Get();
|
||||
|
||||
// C&C mode flags
|
||||
mIsRepairBuildings = theGame.CanRepairBuildings.Get();
|
||||
mIsDriverGunner = theGame.DriverIsAlwaysGunner.Get();
|
||||
mSpawnWeapons = theGame.SpawnWeapons.Get();
|
||||
|
||||
mIsMod = (theGame.Get_Mod_Name().Is_Empty() == false);
|
||||
|
||||
mPingTime = -1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::ImportFromChannel
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game from a channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Channel to import game information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::ImportFromChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
Reset();
|
||||
|
||||
if (channel.IsValid() == false)
|
||||
{
|
||||
mIsDataValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//ST - Test code
|
||||
//if (channel->GetName() != WideStringClass(L"ladtest07")) {
|
||||
// mIsDataValid = false;
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
const char* exInfo = channel->GetExtraInfo();
|
||||
|
||||
if ((exInfo == NULL) || (exInfo && (strlen(exInfo) != 36)))
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: Channel ExInfo NULL or wrong size\n"));
|
||||
mIsDataValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Assume the data will be valid
|
||||
mIsDataValid = true;
|
||||
|
||||
// Extract ExInfo settings
|
||||
unsigned long fileCRC = 0;
|
||||
unsigned long version = 0;
|
||||
unsigned long clanID1 = 0;
|
||||
unsigned long clanID2 = 0;
|
||||
unsigned char gameType = 0;
|
||||
unsigned char gameFlags1 = 0;
|
||||
unsigned char gameFlags2 = 0;
|
||||
unsigned char modMapIndex = 0;
|
||||
|
||||
int count = sscanf(exInfo, "%08lX%08lX%08lX%08lX%c%c%c%c", &version, &fileCRC,
|
||||
&clanID1, &clanID2, &gameType, &gameFlags1, &gameFlags2, &modMapIndex);
|
||||
|
||||
// There should be 8 parameters in the exinfo
|
||||
if (count != 8)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: Channel ExInfo malformed\n"));
|
||||
mIsDataValid = false;
|
||||
}
|
||||
|
||||
if (version != cNetwork::Get_Exe_Key()) {
|
||||
mIsDataValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mVersion = version;
|
||||
mGameType = (cGameData::GameTypeEnum)(gameType - '0');
|
||||
|
||||
if (mGameType != cGameData::GAME_TYPE_CNC)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: GameType '%d' out of range\n", mGameType));
|
||||
mIsDataValid = false;
|
||||
}
|
||||
|
||||
// Extract game flags
|
||||
mIsLaddered = (channel->GetTournament() != 0);
|
||||
mIsPassworded = channel->IsPassworded();
|
||||
|
||||
mIsDedicated = ((gameFlags1 & 0x40) == 0x40);
|
||||
mIsFriendlyFire = ((gameFlags1 & 0x10) == 0x10);
|
||||
mIsFreeWeapons = ((gameFlags1 & 0x08) == 0x08);
|
||||
mIsTeamRemix = ((gameFlags1 & 0x04) == 0x04);
|
||||
mIsTeamChange = ((gameFlags1 & 0x02) == 0x02);
|
||||
mIsClanGame = ((gameFlags1 & 0x01) == 0x01);
|
||||
|
||||
mIsMod = ((gameFlags2 & 0x40) == 0x40);
|
||||
mSpawnWeapons = ((gameFlags2 & 0x04) == 0x04);
|
||||
mIsRepairBuildings = ((gameFlags2 & 0x02) == 0x02);
|
||||
mIsDriverGunner = ((gameFlags2 & 0x01) == 0x01);
|
||||
|
||||
// Find the mod and map names from their CRC
|
||||
StringClass mapName(0, true);
|
||||
mapName = "<Unknown>";
|
||||
|
||||
StringClass modName(0, true);
|
||||
|
||||
bool got_map_name = true;
|
||||
if (mIsMod)
|
||||
{
|
||||
// Get the true index (+32 put the index into the printable range)
|
||||
modMapIndex -= 32;
|
||||
|
||||
// Find mod based on its crc and get map filename based on the index.
|
||||
if (ModPackageMgrClass::Get_Mod_Map_Name_From_CRC_Index(fileCRC, modMapIndex, &modName, &mapName) == false)
|
||||
{
|
||||
//mIsDataValid = false;
|
||||
got_map_name = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find mod based on its crc and get map filename based on the index.
|
||||
if (ModPackageMgrClass::Get_Mod_Map_Name_From_CRC (0, fileCRC, &modName, &mapName) == false)
|
||||
{
|
||||
//mIsDataValid = false;
|
||||
got_map_name = false;
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(mModName, modName, MAX_TEXT_LENGTH);
|
||||
mModName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
strncpy(mMapName, mapName, MAX_TEXT_LENGTH);
|
||||
mMapName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
mMinPlayers = channel->GetMinUsers();
|
||||
mMaxPlayers = channel->GetMaxUsers();
|
||||
mNumPlayers = channel->GetCurrentUsers();
|
||||
|
||||
// Do not count the host as a player for dedicated servers.
|
||||
if (mIsDedicated)
|
||||
{
|
||||
WWASSERT(mNumPlayers > 0);
|
||||
--mNumPlayers;
|
||||
|
||||
WWASSERT(mMaxPlayers > 0);
|
||||
--mMaxPlayers;
|
||||
}
|
||||
|
||||
mClanID1 = clanID1;
|
||||
mClanID2 = clanID2;
|
||||
|
||||
const char* topic = channel->GetTopic();
|
||||
|
||||
if (topic == NULL)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: Channel Topic is NULL\n"));
|
||||
mIsDataValid = false;
|
||||
}
|
||||
|
||||
// Quickmatch settings are marked by a pipe '|' character
|
||||
mIsQuickmatch = (strchr(topic, '|') != NULL);
|
||||
|
||||
// Extract game title from topic
|
||||
unsigned int titleLength = (topic[0] - 0x20);
|
||||
WWASSERT(titleLength <= 32);
|
||||
titleLength = min<unsigned int>(titleLength, 32);
|
||||
++topic;
|
||||
|
||||
strncpy(mTitle, topic, titleLength);
|
||||
mTitle[titleLength] = 0;
|
||||
WWASSERT(strlen(mTitle) == titleLength);
|
||||
topic += titleLength;
|
||||
|
||||
unsigned int mapLength = (topic[0] - 0x20);
|
||||
WWASSERT(mapLength <= 16);
|
||||
mapLength = min<unsigned int>(mapLength, 16);
|
||||
++topic;
|
||||
|
||||
if (!got_map_name) {
|
||||
strncpy(mMapName, topic, mapLength);
|
||||
mMapName[mapLength] = 0;
|
||||
WWASSERT(strlen(mMapName) == mapLength);
|
||||
mIsMapValid = false;
|
||||
}
|
||||
topic += mapLength;
|
||||
|
||||
// Calculate ping
|
||||
PingProfile pings;
|
||||
DecodePingProfile(topic, pings);
|
||||
|
||||
const PingProfile& localPings = GetLocalPingProfile();
|
||||
mPingTime = ComparePingProfile(localPings, pings);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::ExportToChannel
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Export game information into a channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Channel to export game information into.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::ExportToChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
if (channel.IsValid() && mIsDataValid)
|
||||
{
|
||||
// If this is a dedicated server then the max players must be incremented
|
||||
// by one to account for the host.
|
||||
unsigned int maxPlayers = (mIsDedicated == true) ? (mMaxPlayers + 1) : mMaxPlayers;
|
||||
|
||||
// Set the channels min and max players
|
||||
channel->SetMinMaxUsers(mMinPlayers, maxPlayers);
|
||||
|
||||
// Set the tournament type
|
||||
unsigned int tournamentType = (mIsLaddered ? 1 : 0);
|
||||
channel->SetTournament(tournamentType);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Encode ExInfo
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// For flags bit 6 must be set to keep the overall value at least a space character
|
||||
unsigned char gameFlags1 = 0x20;
|
||||
gameFlags1 |= mIsDedicated ? 0x40 : 0x00;
|
||||
gameFlags1 |= mIsFriendlyFire ? 0x10 : 0x00;
|
||||
gameFlags1 |= mIsFreeWeapons ? 0x08 : 0x00;
|
||||
gameFlags1 |= mIsTeamRemix ? 0x04 : 0x00;
|
||||
gameFlags1 |= mIsTeamChange ? 0x02 : 0x00;
|
||||
gameFlags1 |= mIsClanGame ? 0x01 : 0x00;
|
||||
|
||||
unsigned char gameFlags2 = 0x20;
|
||||
gameFlags2 |= mIsMod ? 0x40 : 0x00;
|
||||
gameFlags2 |= mSpawnWeapons ? 0x04: 0x00;
|
||||
gameFlags2 |= mIsRepairBuildings ? 0x02: 0x00;
|
||||
gameFlags2 |= mIsDriverGunner ? 0x01: 0x00;
|
||||
|
||||
// The file CRC is either the map name or the mod name depending on if
|
||||
// the mod flag is set.
|
||||
unsigned long fileCRC = 0;
|
||||
unsigned char modMapIndex = 0;
|
||||
|
||||
if (mIsMod)
|
||||
{
|
||||
ModPackageClass& package = ModPackageMgrClass::Get_Current_Package();
|
||||
fileCRC = package.Get_CRC();
|
||||
modMapIndex = package.Get_Map_Index(mMapName);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileCRC = ::CRC_Stringi(mMapName);
|
||||
}
|
||||
|
||||
// Put the map index into the printable ASCII range
|
||||
modMapIndex += 32;
|
||||
|
||||
// WARNING: The channels ExInfo field has a maximum size of 40 bytes.
|
||||
char exInfo[41];
|
||||
sprintf(exInfo, "%08lX%08lX%08lX%08lX%c%c%c%c", mVersion, fileCRC,
|
||||
mClanID1, mClanID2, (0x30 + mGameType), gameFlags1, gameFlags2, modMapIndex);
|
||||
|
||||
channel->SetExtraInfo(exInfo);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Encode topic
|
||||
//-------------------------------------------------------------------------
|
||||
unsigned int titleLength = min<unsigned int>(strlen(mTitle), 32);
|
||||
titleLength += 0x20;
|
||||
|
||||
// WARNING: The channels topic field has a maximum size of 80 bytes.
|
||||
// Ping profile and quickmatch settings are encoded in the topic in
|
||||
// addition to the the game title. The combined maximum of ALL these
|
||||
// entries MUST NEVER exceed 80 bytes.
|
||||
char topic[81];
|
||||
sprintf(topic, "%c%.32s", titleLength, mTitle);
|
||||
|
||||
//
|
||||
// Only using 61 max right now. Room for a map name maybe? ST - 10/31/2002 2:55PM
|
||||
//
|
||||
unsigned int mapLength = min<unsigned int>(strlen(mMapName), 16);
|
||||
mapLength += 0x20;
|
||||
|
||||
// WARNING: The channels topic field has a maximum size of 80 bytes.
|
||||
// Ping profile and quickmatch settings are encoded in the topic in
|
||||
// addition to the the game title. The combined maximum of ALL these
|
||||
// entries MUST NEVER exceed 80 bytes.
|
||||
char mapinfo[81];
|
||||
sprintf(mapinfo, "%c%.16s", mapLength, mMapName);
|
||||
strcat(topic, mapinfo);
|
||||
|
||||
// Add our ping profile
|
||||
const PingProfile& localPings = GetLocalPingProfile();
|
||||
EncodePingProfile(localPings, topic);
|
||||
|
||||
channel->SetTopic(topic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::IsValidGameChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
WOLGameInfo gameInfo(channel);
|
||||
return (gameInfo.IsDataValid() && (gameInfo.mVersion == (unsigned long)cNetwork::Get_Exe_Key()));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::IsClanCompeting
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check if the specified clan is competing in the game.
|
||||
*
|
||||
* INPUTS
|
||||
* Clan - ID of clan to check.
|
||||
*
|
||||
* RESULT
|
||||
* True if clan is competing.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::IsClanCompeting(unsigned long clanID) const
|
||||
{
|
||||
return (mIsClanGame && (clanID != 0) && ((clanID == mClanID1) || (clanID == mClanID2)));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::IsClanGameOpen
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check if the clan game is open for new clans to join.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if the game is open to clans.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::IsClanGameOpen(void) const
|
||||
{
|
||||
return (mIsClanGame && ((0 == mClanID1) || (0 == mClanID2)));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::CanUserJoin
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check if the user is able to join this game.
|
||||
*
|
||||
* INPUTS
|
||||
* User
|
||||
*
|
||||
* RESULT
|
||||
* True if user can join this game.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::CanUserJoin(const RefPtr<UserData>& user)
|
||||
{
|
||||
if (!user.IsValid() || !mIsDataValid || !mIsMapValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mVersion != (unsigned long)cNetwork::Get_Exe_Key())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mIsClanGame)
|
||||
{
|
||||
unsigned long userClanID = user->GetSquadID();
|
||||
return ((0 != userClanID) && (IsClanGameOpen() || IsClanCompeting(userClanID)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
194
Code/Commando/WOLGameInfo.h
Normal file
194
Code/Commando/WOLGameInfo.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLGameInfo.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Steve_t $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 11 $
|
||||
* $Modtime: 10/31/02 3:07p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLGAMEINFO_H__
|
||||
#define __WOLGAMEINFO_H__
|
||||
|
||||
#include <WWOnline\RefPtr.h>
|
||||
|
||||
class cGameData;
|
||||
|
||||
namespace WWOnline
|
||||
{
|
||||
class ChannelData;
|
||||
class UserData;
|
||||
}
|
||||
|
||||
// Game information used to describe the type of game.
|
||||
class WOLGameInfo
|
||||
{
|
||||
public:
|
||||
static bool IsValidGameChannel(const RefPtr<WWOnline::ChannelData>& channel);
|
||||
|
||||
enum {MAX_TEXT_LENGTH = 32};
|
||||
|
||||
WOLGameInfo(void);
|
||||
|
||||
WOLGameInfo(const cGameData& theGame);
|
||||
|
||||
WOLGameInfo(const RefPtr<WWOnline::ChannelData>& channel);
|
||||
|
||||
~WOLGameInfo(void);
|
||||
|
||||
void Reset(void);
|
||||
|
||||
bool IsDataValid(void) const
|
||||
{return mIsDataValid;}
|
||||
|
||||
bool IsMapValid(void) const
|
||||
{return mIsMapValid;}
|
||||
|
||||
void ImportFromGame(const cGameData& theGame);
|
||||
|
||||
void ImportFromChannel(const RefPtr<WWOnline::ChannelData>& channel);
|
||||
|
||||
void ExportToChannel(const RefPtr<WWOnline::ChannelData>& channel);
|
||||
|
||||
unsigned long Version(void) const
|
||||
{return mVersion;};
|
||||
|
||||
unsigned int GameType(void) const
|
||||
{return mGameType;}
|
||||
|
||||
const char* MapName(void) const
|
||||
{return mMapName;}
|
||||
|
||||
const char* ModName(void) const
|
||||
{return mModName;}
|
||||
|
||||
const char* Title(void) const
|
||||
{return mTitle;}
|
||||
|
||||
unsigned int MinPlayers(void) const
|
||||
{return mMinPlayers;}
|
||||
|
||||
unsigned int MaxPlayers(void) const
|
||||
{return mMaxPlayers;}
|
||||
|
||||
unsigned int NumPlayers(void) const
|
||||
{return mNumPlayers;}
|
||||
|
||||
unsigned long ClanID1(void) const
|
||||
{return mClanID1;}
|
||||
|
||||
unsigned long ClanID2(void) const
|
||||
{return mClanID2;}
|
||||
|
||||
bool IsLaddered(void) const
|
||||
{return mIsLaddered;}
|
||||
|
||||
bool IsPassworded(void) const
|
||||
{return mIsPassworded;}
|
||||
|
||||
bool IsQuickmatch(void) const
|
||||
{return mIsQuickmatch;}
|
||||
|
||||
bool IsDedicated(void) const
|
||||
{return mIsDedicated;}
|
||||
|
||||
bool IsFriendlyFire(void) const
|
||||
{return mIsFriendlyFire;}
|
||||
|
||||
bool IsFreeWeapons(void) const
|
||||
{return mIsFreeWeapons;}
|
||||
|
||||
bool IsTeamRemix(void) const
|
||||
{return mIsTeamRemix;}
|
||||
|
||||
bool IsTeamChange(void) const
|
||||
{return mIsTeamChange;}
|
||||
|
||||
bool IsClanGame(void) const
|
||||
{return mIsClanGame;}
|
||||
|
||||
bool IsRepairBuildings(void) const
|
||||
{return mIsRepairBuildings;}
|
||||
|
||||
bool IsDriverGunner(void) const
|
||||
{return mIsDriverGunner;}
|
||||
|
||||
bool IsSpawnWeapons(void) const
|
||||
{return mSpawnWeapons;}
|
||||
|
||||
int PingTime(void) const
|
||||
{return mPingTime;}
|
||||
|
||||
// Is the clan competing in the game.
|
||||
bool IsClanCompeting(unsigned long clanID) const;
|
||||
|
||||
bool IsClanGameOpen(void) const;
|
||||
|
||||
bool CanUserJoin(const RefPtr<WWOnline::UserData>& user);
|
||||
|
||||
protected:
|
||||
// Prevent copy and assignment
|
||||
WOLGameInfo(const WOLGameInfo&);
|
||||
const WOLGameInfo& operator=(const WOLGameInfo&);
|
||||
|
||||
protected:
|
||||
bool mIsDataValid;
|
||||
bool mIsMapValid;
|
||||
|
||||
unsigned long mVersion;
|
||||
unsigned int mGameType;
|
||||
|
||||
char mMapName[MAX_TEXT_LENGTH];
|
||||
char mModName[MAX_TEXT_LENGTH];
|
||||
char mTitle[MAX_TEXT_LENGTH];
|
||||
|
||||
unsigned int mMinPlayers;
|
||||
unsigned int mMaxPlayers;
|
||||
unsigned int mNumPlayers;
|
||||
|
||||
unsigned long mClanID1;
|
||||
unsigned long mClanID2;
|
||||
|
||||
bool mIsMod;
|
||||
bool mIsLaddered;
|
||||
bool mIsPassworded;
|
||||
bool mIsQuickmatch;
|
||||
bool mIsDedicated;
|
||||
bool mIsFriendlyFire;
|
||||
bool mIsFreeWeapons;
|
||||
bool mIsTeamRemix;
|
||||
bool mIsTeamChange;
|
||||
bool mIsClanGame;
|
||||
bool mIsRepairBuildings;
|
||||
bool mIsDriverGunner;
|
||||
bool mSpawnWeapons;
|
||||
|
||||
int mPingTime;
|
||||
};
|
||||
|
||||
#endif // __WOLGAMEINFO_H__
|
||||
609
Code/Commando/WOLJoinGame.cpp
Normal file
609
Code/Commando/WOLJoinGame.cpp
Normal file
@@ -0,0 +1,609 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLJoinGame.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 18 $
|
||||
* $Modtime: 1/17/02 11:43a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "WOLJoinGame.h"
|
||||
#include "DlgWOLWait.h"
|
||||
#include "DlgMessageBox.h"
|
||||
#include "DlgMPConnect.h"
|
||||
#include "Nat.h"
|
||||
#include "Natter.h"
|
||||
#include "FirewallWait.h"
|
||||
#include "CNetwork.h"
|
||||
#include "WOLGameInfo.h"
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWOnline\WOLProduct.h>
|
||||
#include <WWOnline\WOLChannel.h>
|
||||
#include "String_IDs.h"
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::JoinTheGame
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Join the specified game.
|
||||
*
|
||||
* INPUTS
|
||||
* GameName - Name of the game to join
|
||||
* Password - Game password
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::JoinTheGame(const wchar_t* gameName, const wchar_t* password, bool allowTeamSelect)
|
||||
{
|
||||
WWASSERT(gameName != NULL && "Invalid parameter");
|
||||
|
||||
if (gameName)
|
||||
{
|
||||
// Create the object to handle the game joining process.
|
||||
WOLJoinGame* joinGame = new WOLJoinGame;
|
||||
WWASSERT(joinGame && "WOLJoinGame failed to instantiate");
|
||||
|
||||
if (joinGame)
|
||||
{
|
||||
if (joinGame->FinalizeCreate())
|
||||
{
|
||||
// Start the join game process
|
||||
if (joinGame->Join(gameName, password, allowTeamSelect))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This will delete the WOLJoinGame object
|
||||
joinGame->Release_Ref();
|
||||
}
|
||||
|
||||
// If we got here then the join failed. Show a dialog telling the user
|
||||
// that we were unable to join the requested game.
|
||||
WideStringClass message(255, true);
|
||||
message.Format(TRANSLATE(IDS_GAME_JOINCHANNEL), gameName);
|
||||
DlgMsgBox::DoDialog(TRANSLATE(IDS_WOL_ERROR), message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::WOLJoinGame
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Default constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLJoinGame::WOLJoinGame() :
|
||||
mJoinState(IDLE_STATE),
|
||||
mAllowTeamSelect(true),
|
||||
mTeamChoice(-1),
|
||||
mClanID(0)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Instantiated\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::~WOLJoinGame
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLJoinGame::~WOLJoinGame()
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Destroyed\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if successful
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLJoinGame::FinalizeCreate(void)
|
||||
{
|
||||
mWOLSession = Session::GetInstance(false);
|
||||
return mWOLSession.IsValid();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::CreateGameFromChannel
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create a game data instance from a WWOnline game channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Game channel to create game data instance from.
|
||||
*
|
||||
* RESULT
|
||||
* Game - Instance to game.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
cGameData* WOLJoinGame::CreateGameFromChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
WWASSERT(channel.IsValid() && "Invalid paramter");
|
||||
WWDEBUG_SAY(("WOLJoinGame: Create game from channel '%S'\n", (const WCHAR*)channel->GetName()));
|
||||
|
||||
// Extract game information from the channel
|
||||
WOLGameInfo gameInfo(channel);
|
||||
|
||||
if (gameInfo.IsDataValid() == false)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create an instance of the correct type.
|
||||
cGameData* theGame = cGameData::Create_Game_Of_Type((cGameData::GameTypeEnum)gameInfo.GameType());
|
||||
|
||||
if (theGame)
|
||||
{
|
||||
// The game owner is the name of the channel
|
||||
const WideStringClass& channelName = channel->GetName();
|
||||
theGame->Set_Owner(const_cast<WideStringClass&>(channelName));
|
||||
|
||||
if (gameInfo.IsPassworded())
|
||||
{
|
||||
theGame->Set_Password(mPassword);
|
||||
}
|
||||
|
||||
theGame->Import_Tier_1_Data(gameInfo);
|
||||
}
|
||||
|
||||
return theGame;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::Join
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The steps to join a game successfully are as follows:
|
||||
*
|
||||
* 1) Join the game channel.
|
||||
* 2) Allow user to select his team.
|
||||
* 3) Receive team selection choice.
|
||||
* 4) Create an instance of the game.
|
||||
* 5) Perform firewall negotiation
|
||||
* 6) Connect to the server.
|
||||
*
|
||||
* INPUTS
|
||||
* Name - Name of game channel (This is usually the same as the hosts name).
|
||||
* Password - Password to enter game; NULL if not passworded.
|
||||
* AllowSelect - True if user is allowed to select their team.
|
||||
*
|
||||
* RESULT
|
||||
* True if join request is successful.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLJoinGame::Join(const wchar_t* gameName, const wchar_t* password, bool allowTeamSelect)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Joining game channel '%S' Password: '%S'\n", gameName, password));
|
||||
|
||||
mAllowTeamSelect = allowTeamSelect;
|
||||
|
||||
mGameName = gameName;
|
||||
mPassword = password;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// First we need to join the channel
|
||||
//---------------------------------------------------------------------------
|
||||
RefPtr<Product> product = Product::Current();
|
||||
WWASSERT(product.IsValid());
|
||||
|
||||
if (!product.IsValid())
|
||||
{
|
||||
WWDEBUG_SAY(("ERROR: WWOnline product not initialized.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int gameType = product->GetGameCode();
|
||||
|
||||
RefPtr<WaitCondition> wait = mWOLSession->JoinChannel(gameName, password, gameType);
|
||||
|
||||
if (!wait.IsValid())
|
||||
{
|
||||
WWDEBUG_SAY(("ERROR: Couldn't create JoinChannellWait\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tell the firewall code that we are connecting as a client.
|
||||
WOLNATInterface.Set_Server(false);
|
||||
|
||||
// Listen for channel events. We will use this to obtain the channel
|
||||
Observer<ChannelEvent>::NotifyMe(*mWOLSession);
|
||||
|
||||
// Generate message for user to see while we are attempting to join the channel.
|
||||
WideStringClass message(255, true);
|
||||
message.Format(TRANSLATE(IDS_GAME_JOINCHANNEL), gameName);
|
||||
|
||||
mJoinState = JOINING_STATE;
|
||||
return DlgWOLWait::DoDialog((const WCHAR*)message, wait, this);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::ProceedWithConnection
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::ProceedWithConnection(int teamChoice)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Proceeding with connection\n"));
|
||||
|
||||
bool success = StartServerConnect();
|
||||
|
||||
// If the connection is underway then wait for it to complete.
|
||||
if (success)
|
||||
{
|
||||
mTeamChoice = teamChoice;
|
||||
return;
|
||||
}
|
||||
|
||||
// An error has occured while attempting to connect.
|
||||
DlgMsgBox::DoDialog(IDS_WOL_ERROR, IDS_MP_UNABLE_CONNECT_TO_SERVER);
|
||||
|
||||
Leave();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::Leave
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::Leave(void)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Leaving channel\n"));
|
||||
|
||||
// If the user elected to leave the game or we encountered an error starting
|
||||
// the connection then leave the channel.
|
||||
RefPtr<WaitCondition> wait = mWOLSession->LeaveChannel();
|
||||
DlgWOLWait::DoDialog(IDS_GAME_LEAVECHANNEL, wait);
|
||||
|
||||
// This will delete the WOLJoinGame object
|
||||
Release_Ref();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::StartServerConnect
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Start server connection negotiation
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if negotiation successfully started.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLJoinGame::StartServerConnect(void)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Start server connect\n"));
|
||||
|
||||
// If the channel is NOT valid then bad things have happened.
|
||||
if (!mTheChannel.IsValid())
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: ERROR channel not valid when connecting to host\n"));
|
||||
WWASSERT(mTheChannel.IsValid() && "Bad channel connecting to host");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that the user can join this game.
|
||||
WOLGameInfo gameInfo(mTheChannel);
|
||||
RefPtr<UserData> user = mWOLSession->GetCurrentUser();
|
||||
|
||||
if (gameInfo.CanUserJoin(user) == false)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: ERROR - User cannot join this game\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are playing a clan game then we need the users clan ID in order to join.
|
||||
if (gameInfo.IsClanGame())
|
||||
{
|
||||
mClanID = user->GetSquadID();
|
||||
}
|
||||
|
||||
// Delete any existing game.
|
||||
if (PTheGameData)
|
||||
{
|
||||
delete PTheGameData;
|
||||
PTheGameData = NULL;
|
||||
}
|
||||
|
||||
// Create a new game from the channel
|
||||
cGameData* theGame = CreateGameFromChannel(mTheChannel);
|
||||
WWASSERT(theGame && "WOLJoinGame failed to create cGameData");
|
||||
|
||||
if (theGame == NULL)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: ERROR failed to create cGameData\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assign the new game instance
|
||||
PTheGameData = theGame;
|
||||
|
||||
// We are done with the channel
|
||||
mTheChannel.Release();
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Wait for the firewall negotiation. Will send DlgWOLWaitEvent when complete.
|
||||
//---------------------------------------------------------------------------
|
||||
RefPtr<WaitCondition> wait = FirewallConnectWait::Create();
|
||||
|
||||
if (!wait.IsValid())
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: ERROR couldn't create FireWallWait\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
mJoinState = FIREWALL_STATE;
|
||||
return DlgWOLWait::DoDialog(TRANSLATE (IDS_MENU_CONNECTING), wait, this);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::ConnectToServer
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Establish connection to game server.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::ConnectToServer(void)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Connect to server\n"));
|
||||
|
||||
// Start the client
|
||||
unsigned short my_port = FirewallHelper.Get_Client_Bind_Port();
|
||||
cNetwork::Init_Client(my_port);
|
||||
|
||||
// Display the "connecting" dialog.
|
||||
// Note: This dialog will close automatically when the connection has been
|
||||
// successfully completed.
|
||||
DlgMPConnect::DoDialog(mTeamChoice, mClanID);
|
||||
|
||||
// Our job is done. (This will delete the WOLJoinGame object)
|
||||
Release_Ref();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::HandleNotification(ChannelEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle channel events. Of particular interest during a join is the
|
||||
* channel data event. This event tells us that there is information
|
||||
* available from the channel encoded in the topic and exinfo fields that
|
||||
* we can use to create the game from.
|
||||
*
|
||||
* INPUTS
|
||||
* ChannelEvent
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::HandleNotification(ChannelEvent& event)
|
||||
{
|
||||
// The channel data is always updated immediately after a channel is joined.
|
||||
// Therefore use this event to start the creation of the game we are joining.
|
||||
if (event.GetStatus() == ChannelNewData)
|
||||
{
|
||||
// Get the channel that is the subject of this event.
|
||||
const RefPtr<ChannelData>& channel = event.Subject();
|
||||
WWASSERT(channel.IsValid());
|
||||
|
||||
// If the name of this channel is the name of the game we are joining
|
||||
// then create the game from this channel.
|
||||
const WideStringClass& channelName = channel->GetName();
|
||||
|
||||
if (channelName.Compare_No_Case(mGameName) == 0)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLJoinGame: Joined game channel '%S'\n", (const WCHAR*)channelName));
|
||||
|
||||
// Keep a reference to the channel so we can create the game from it latter
|
||||
mTheChannel = channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::HandleNotification(DlgWOLWaitEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle result of channel join and firewall negotiation. If everything
|
||||
* went okay then proceed with connecting to the game server. Otherwise
|
||||
* tell the user what went wrong.
|
||||
*
|
||||
* INPUTS
|
||||
* Event - Result event from joining WOL game wait condition.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::HandleNotification(DlgWOLWaitEvent& event)
|
||||
{
|
||||
// If the wait condition completed with success.
|
||||
if (event.Result() == WaitCondition::ConditionMet)
|
||||
{
|
||||
if (JOINING_STATE == mJoinState)
|
||||
{
|
||||
mJoinState = IDLE_STATE;
|
||||
|
||||
// If we just joined the channel we need to present the user with
|
||||
// the team selection dialog. This dialog will allow them to view
|
||||
// the current teams and / or change their team.
|
||||
if (mAllowTeamSelect)
|
||||
{
|
||||
// DlgMPTeamSelect will send a signal indicating if the user has opted
|
||||
// to continue with the game or to back out. See ReceiveSignal()
|
||||
DlgMPTeamSelect::DoDialog(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProceedWithConnection(-1);
|
||||
}
|
||||
}
|
||||
else if (FIREWALL_STATE == mJoinState)
|
||||
{
|
||||
// If we have finished the firewall negotiation then proceed with
|
||||
// the server connection.
|
||||
mJoinState = IDLE_STATE;
|
||||
ConnectToServer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the wait condition failed then report the reason for the failure and
|
||||
// leave the channel.
|
||||
const WideStringClass& text = event.Subject()->GetResultText();
|
||||
WWDEBUG_SAY(("WOLJoinGame: Wait failed - %S\n", (const WCHAR*)text));
|
||||
|
||||
DlgMsgBox::DoDialog(TRANSLATE(IDS_WOL_ERROR), text);
|
||||
|
||||
Leave();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLJoinGame::ReceiveSignal(MPChooseTeamSignal)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The team selection dialog will send a signal indicating the users choice
|
||||
* regarding his team preference.
|
||||
*
|
||||
* INPUTS
|
||||
* Signal
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLJoinGame::ReceiveSignal(MPChooseTeamSignal& signal)
|
||||
{
|
||||
// If the user wants to proceed then connect to the server othewise leave
|
||||
// the game channel.
|
||||
if (signal.GetItemA() == true)
|
||||
{
|
||||
ProceedWithConnection(signal.GetItemB());
|
||||
}
|
||||
else
|
||||
{
|
||||
Leave();
|
||||
}
|
||||
}
|
||||
104
Code/Commando/WOLJoinGame.h
Normal file
104
Code/Commando/WOLJoinGame.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLJoinGame.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 10 $
|
||||
* $Modtime: 1/16/02 4:25p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLJOINGAME_H__
|
||||
#define __WOLJOINGAME_H__
|
||||
|
||||
#include <WWLib\RefCount.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWLib\Signaler.h>
|
||||
#include <WWLib\WideString.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include "DlgMPTeamSelect.h"
|
||||
|
||||
namespace WWOnline
|
||||
{
|
||||
class Session;
|
||||
class ChannelData;
|
||||
class ChannelEvent;
|
||||
}
|
||||
|
||||
class cGameData;
|
||||
class DlgWOLWaitEvent;
|
||||
|
||||
class WOLJoinGame :
|
||||
public RefCountClass,
|
||||
public Observer<WWOnline::ChannelEvent>,
|
||||
public Observer<DlgWOLWaitEvent>,
|
||||
public Signaler<MPChooseTeamSignal>
|
||||
{
|
||||
public:
|
||||
static void JoinTheGame(const wchar_t* gameName, const wchar_t* password, bool allowTeamSelect);
|
||||
|
||||
protected:
|
||||
WOLJoinGame();
|
||||
~WOLJoinGame();
|
||||
|
||||
// Prevent copy and assignment
|
||||
WOLJoinGame(const WOLJoinGame&);
|
||||
const WOLJoinGame& operator=(const WOLJoinGame&);
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
cGameData* CreateGameFromChannel(const RefPtr<WWOnline::ChannelData>& channel);
|
||||
|
||||
bool Join(const wchar_t* gameName, const wchar_t* password, bool allowTeamSelect);
|
||||
void ProceedWithConnection(int teamChoice);
|
||||
void Leave(void);
|
||||
|
||||
bool StartServerConnect(void);
|
||||
void ConnectToServer(void);
|
||||
|
||||
void HandleNotification(WWOnline::ChannelEvent&);
|
||||
void HandleNotification(DlgWOLWaitEvent&);
|
||||
void ReceiveSignal(MPChooseTeamSignal&);
|
||||
|
||||
private:
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
|
||||
typedef enum {IDLE_STATE = 0, JOINING_STATE, FIREWALL_STATE} JoinState;
|
||||
JoinState mJoinState;
|
||||
|
||||
bool mAllowTeamSelect;
|
||||
|
||||
WideStringClass mGameName;
|
||||
WideStringClass mPassword;
|
||||
|
||||
RefPtr<WWOnline::ChannelData> mTheChannel;
|
||||
|
||||
int mTeamChoice;
|
||||
unsigned long mClanID;
|
||||
};
|
||||
|
||||
#endif __WOLJOINGAME_H__
|
||||
814
Code/Commando/WOLLoginProfile.cpp
Normal file
814
Code/Commando/WOLLoginProfile.cpp
Normal file
@@ -0,0 +1,814 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLLoginProfile.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Login profile holds the users login preferences as well as other
|
||||
* information that needs to be persistantly cached between game sessions.
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Greg_h $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 14 $
|
||||
* $Modtime: 6/21/02 11:40a $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "WOLLoginProfile.h"
|
||||
#include "_globals.h"
|
||||
#include "Resource.h"
|
||||
#include <WWOnline\WOLLoginInfo.h>
|
||||
#include <WWUI\DialogBase.h>
|
||||
#include <WWUI\ListCtrl.h>
|
||||
#include <WWLib\Registry.h>
|
||||
#include "String_IDs.h"
|
||||
#include <WWTranslateDB\TranslateDB.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
#define MAX_STRING_LEN 64;
|
||||
|
||||
static const char* REG_VALUE_SERVER = "Server";
|
||||
static const char* REG_VALUE_SIDEPREF = "SidePref";
|
||||
static const char* REG_VALUE_GAMESPLAYED = "Played";
|
||||
static const char* REG_VALUE_TEAMRANK = "RankTeam";
|
||||
static const char* REG_VALUE_CLANRANK = "RankClan";
|
||||
|
||||
// Profile ranking columns
|
||||
static enum
|
||||
{
|
||||
COL_LADDERNAME = 0,
|
||||
COL_WINS,
|
||||
COL_DEATHS,
|
||||
COL_POINTS,
|
||||
COL_RANK,
|
||||
|
||||
COL_MAXCOUNT
|
||||
};
|
||||
|
||||
static void ShowRanking(ListCtrlClass* list, LadderType type, const LoginProfile::Ranking* rank);
|
||||
|
||||
|
||||
bool LoginProfile::_mSaveAllowed = true;
|
||||
LoginProfile* LoginProfile::_mCurrentProfile = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::EnableSaving
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::EnableSaving(bool allowed)
|
||||
{
|
||||
_mSaveAllowed = allowed;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SetCurrent
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SetCurrent(LoginProfile* profile)
|
||||
{
|
||||
if (_mCurrentProfile != NULL)
|
||||
{
|
||||
_mCurrentProfile->Release_Ref();
|
||||
_mCurrentProfile = NULL;
|
||||
}
|
||||
|
||||
if (profile)
|
||||
{
|
||||
profile->Add_Ref();
|
||||
_mCurrentProfile = profile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::Get
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get the login profile for the specified user.
|
||||
*
|
||||
* INPUTS
|
||||
* Name - Name of profile to get.
|
||||
*
|
||||
* RESULT
|
||||
* Profile - Instance to login profile
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
LoginProfile* LoginProfile::Get(const wchar_t* loginName, bool createOK)
|
||||
{
|
||||
if (loginName && wcslen(loginName))
|
||||
{
|
||||
// Check the current profile first
|
||||
if (_mCurrentProfile)
|
||||
{
|
||||
if (wcsicmp(_mCurrentProfile->GetName(), loginName) == 0)
|
||||
{
|
||||
_mCurrentProfile->Add_Ref();
|
||||
return _mCurrentProfile;
|
||||
}
|
||||
}
|
||||
|
||||
StringClass regKey(255, true);
|
||||
regKey.Format("%s\\%S", APPLICATION_SUB_KEY_NAME_LOGINS, loginName);
|
||||
|
||||
if (RegistryClass::Exists(regKey) || createOK)
|
||||
{
|
||||
return Create(loginName);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::Create
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create an instance of a login profile.
|
||||
*
|
||||
* INPUTS
|
||||
* Login - Login to create profile for.
|
||||
*
|
||||
* RESULT
|
||||
* Profile - Instance to login profile
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
LoginProfile* LoginProfile::Create(const wchar_t* loginName)
|
||||
{
|
||||
LoginProfile* profile = NULL;
|
||||
|
||||
if (loginName && wcslen(loginName))
|
||||
{
|
||||
profile = new LoginProfile;
|
||||
|
||||
if (profile)
|
||||
{
|
||||
if (profile->FinalizeCreate(loginName) == false)
|
||||
{
|
||||
profile->Release_Ref();
|
||||
profile = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::Delete
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Delete a login profile.
|
||||
*
|
||||
* INPUTS
|
||||
* Name - Name of login profile to delete.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::Delete(const wchar_t* loginName)
|
||||
{
|
||||
if (loginName && wcslen(loginName))
|
||||
{
|
||||
RegistryClass registry(APPLICATION_SUB_KEY_NAME_LOGINS, false);
|
||||
|
||||
if (registry.Is_Valid())
|
||||
{
|
||||
char valueName[64];
|
||||
wcstombs(valueName, loginName, sizeof(valueName));
|
||||
registry.Delete_Value(valueName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::LoginProfile
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
LoginProfile::LoginProfile() :
|
||||
mLocale(WOL::LOC_UNKNOWN),
|
||||
mSidePref(-1),
|
||||
mGamesPlayed(0)
|
||||
{
|
||||
memset(&mTeamRank, 0, sizeof(Ranking));
|
||||
memset(&mClanRank, 0, sizeof(Ranking));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::~LoginProfile
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
LoginProfile::~LoginProfile()
|
||||
{
|
||||
WWDEBUG_SAY(("LoginProfile destroyed (%S)\n", (const WCHAR*)mName));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Finalize object creation
|
||||
*
|
||||
* INPUTS
|
||||
* Login - Login to initialize profile with.
|
||||
*
|
||||
* RESULT
|
||||
* True if successfull
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool LoginProfile::FinalizeCreate(const wchar_t* loginName)
|
||||
{
|
||||
WWDEBUG_SAY(("LoginProfile created %S\n", loginName));
|
||||
mName = loginName;
|
||||
LoadSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::GetName
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get the name of this profile
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Name of profile
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
const wchar_t* LoginProfile::GetName(void) const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SetPreferredServer
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set the preferred server for this login.
|
||||
*
|
||||
* INPUTS
|
||||
* Server - Name of preferred server.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SetPreferredServer(const char* name)
|
||||
{
|
||||
mServer = name;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SetSidePreference
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set the side preference
|
||||
*
|
||||
* INPUTS
|
||||
* Side - Prefered side
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SetSidePreference(int side)
|
||||
{
|
||||
mSidePref = side;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SetGamesPlayed
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set the number of games played for this login.
|
||||
*
|
||||
* INPUTS
|
||||
* Played - Number of games played.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SetGamesPlayed(unsigned long played)
|
||||
{
|
||||
mGamesPlayed = played;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SetLocale
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set locale for this profile
|
||||
*
|
||||
* INPUTS
|
||||
* Locale - New locale
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SetLocale(WOL::Locale locale)
|
||||
{
|
||||
mLocale = max<WOL::Locale>(locale, WOL::LOC_UNKNOWN);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::GetRanking
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Get ladder ranking information.
|
||||
*
|
||||
* INPUTS
|
||||
* Ladder - Type of ladder to get ranking information for.
|
||||
*
|
||||
* RESULT
|
||||
* Rank - Ladder ranking data
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
const LoginProfile::Ranking* LoginProfile::GetRanking(LadderType type) const
|
||||
{
|
||||
if (type == LadderType_Team)
|
||||
{
|
||||
return &mTeamRank;
|
||||
}
|
||||
else if (type == LadderType_Clan)
|
||||
{
|
||||
return &mClanRank;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SetRanking
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Set ladder ranking information
|
||||
*
|
||||
* INPUTS
|
||||
* Ladder - Type of ladder to set ranking for.
|
||||
* Rank - Ranking data
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SetRanking(WWOnline::LadderType type, Ranking& rank)
|
||||
{
|
||||
if (type == LadderType_Team)
|
||||
{
|
||||
memcpy(&mTeamRank, &rank, sizeof(Ranking));
|
||||
}
|
||||
else if (type == LadderType_Clan)
|
||||
{
|
||||
memcpy(&mClanRank, &rank, sizeof(Ranking));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::LoadSettings
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Load cached profile settings.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::LoadSettings(void)
|
||||
{
|
||||
// Get this logins locale
|
||||
mLocale = WOL::LOC_UNKNOWN;
|
||||
|
||||
RefPtr<LoginInfo> login = LoginInfo::Find(GetName());
|
||||
|
||||
if (login.IsValid())
|
||||
{
|
||||
mLocale = login->GetLocale();
|
||||
}
|
||||
|
||||
// Get login preferences
|
||||
StringClass regKey(255, true);
|
||||
regKey.Format("%s\\%S", APPLICATION_SUB_KEY_NAME_LOGINS, GetName());
|
||||
|
||||
RegistryClass registry(regKey, false);
|
||||
|
||||
if (registry.Is_Valid())
|
||||
{
|
||||
registry.Get_String(REG_VALUE_SERVER, mServer, "");
|
||||
mSidePref = registry.Get_Int(REG_VALUE_SIDEPREF, -1);
|
||||
mGamesPlayed = registry.Get_Int(REG_VALUE_GAMESPLAYED, 0);
|
||||
}
|
||||
|
||||
LoadRank(REG_VALUE_TEAMRANK, mTeamRank);
|
||||
LoadRank(REG_VALUE_CLANRANK, mClanRank);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SaveSettings
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Save current profile settings.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SaveSettings(void)
|
||||
{
|
||||
bool isStored = true;
|
||||
RefPtr<LoginInfo> login = LoginInfo::Find(GetName());
|
||||
|
||||
if (login.IsValid())
|
||||
{
|
||||
isStored = login->IsStored();
|
||||
|
||||
// Save locale
|
||||
login->SetLocale((WOL::Locale)mLocale);
|
||||
}
|
||||
|
||||
// If we are allowed to
|
||||
if (_mSaveAllowed && isStored)
|
||||
{
|
||||
// Save login preferences
|
||||
StringClass regKey(255, true);
|
||||
regKey.Format("%s\\%S", APPLICATION_SUB_KEY_NAME_LOGINS, GetName());
|
||||
|
||||
RegistryClass registry(regKey);
|
||||
|
||||
if (registry.Is_Valid())
|
||||
{
|
||||
registry.Set_String(REG_VALUE_SERVER, mServer);
|
||||
registry.Set_Int(REG_VALUE_SIDEPREF, mSidePref);
|
||||
registry.Set_Int(REG_VALUE_GAMESPLAYED, mGamesPlayed);
|
||||
}
|
||||
|
||||
SaveRank(REG_VALUE_TEAMRANK, mTeamRank);
|
||||
SaveRank(REG_VALUE_CLANRANK, mClanRank);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::LoadRank
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Load cached ranking data.
|
||||
*
|
||||
* INPUTS
|
||||
* Key - Registry key to load ranking from.
|
||||
* Rank - Ranking data to initialize.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::LoadRank(const char* valueName, LoginProfile::Ranking& rank)
|
||||
{
|
||||
WWASSERT(valueName);
|
||||
|
||||
StringClass regKey(255, true);
|
||||
regKey.Format("%s\\%S", APPLICATION_SUB_KEY_NAME_LOGINS, GetName());
|
||||
|
||||
RegistryClass registry(regKey, false);
|
||||
|
||||
if (registry.Is_Valid())
|
||||
{
|
||||
char rankData[255];
|
||||
registry.Get_String(valueName, rankData, sizeof(rankData), "");
|
||||
|
||||
sscanf(rankData, "%d,%d,%d,%d,%d,%d", &rank.Wins, &rank.Losses,
|
||||
&rank.Deaths, &rank.Kills, &rank.Points, &rank.Rank);
|
||||
}
|
||||
else
|
||||
{
|
||||
rank.Wins = (unsigned)-1;
|
||||
rank.Losses = (unsigned)-1;
|
||||
rank.Deaths = (unsigned)-1;
|
||||
rank.Kills = (unsigned)-1;
|
||||
rank.Points = (unsigned)-1;
|
||||
rank.Rank = (unsigned)-1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* LoginProfile::SaveRank
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Save current ranking data.
|
||||
*
|
||||
* INPUTS
|
||||
* Key - Registry key to save ranking data to.
|
||||
* Rank - Ranking data to save.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void LoginProfile::SaveRank(const char* valueName, const LoginProfile::Ranking& rank)
|
||||
{
|
||||
WWASSERT(valueName);
|
||||
|
||||
StringClass regKey(255, true);
|
||||
regKey.Format("%s\\%S", APPLICATION_SUB_KEY_NAME_LOGINS, GetName());
|
||||
|
||||
RegistryClass registry(regKey);
|
||||
|
||||
if (registry.Is_Valid())
|
||||
{
|
||||
char rankData[255];
|
||||
sprintf(rankData, "%d,%d,%d,%d,%d,%d", rank.Wins, rank.Losses, rank.Deaths,
|
||||
rank.Kills, rank.Points, rank.Rank);
|
||||
|
||||
registry.Set_String(valueName, rankData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* ShowProfileRanking
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* Dialog - Dialog to display ranking on. (Must have neccessary controls)
|
||||
* Profile - Profile to display
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void ShowProfileRanking(DialogBaseClass* dialog, const LoginProfile* profile)
|
||||
{
|
||||
dialog->Set_Dlg_Item_Text(IDC_PROFILENAME, L"");
|
||||
|
||||
ListCtrlClass* list = (ListCtrlClass*)dialog->Get_Dlg_Item(IDC_PROFILERANK);
|
||||
|
||||
if (list)
|
||||
{
|
||||
list->Allow_Selection(false);
|
||||
list->Delete_All_Entries();
|
||||
|
||||
if (list->Get_Column_Count() != COL_MAXCOUNT)
|
||||
{
|
||||
list->Delete_All_Columns();
|
||||
|
||||
// Configure the columns
|
||||
Vector3 color(1, 1, 1);
|
||||
|
||||
list->Add_Column(TRANSLATE(IDS_MENU_RANKING), 0.2F, color);
|
||||
list->Add_Column(TRANSLATE(IDS_MENU_WINS_LOSSES), 0.2F, color);
|
||||
list->Add_Column(TRANSLATE(IDS_BUDDY_COL_DEATHS_KILLS), 0.2F, color);
|
||||
list->Add_Column(TRANSLATE(IDS_BUDDY_COL_POINTS), 0.2F, color);
|
||||
list->Add_Column(TRANSLATE(IDS_BUDDY_COL_RANK), 0.2F, color);
|
||||
}
|
||||
|
||||
//(gth) Renegade day 120 Patch: re-translate these strings each time!
|
||||
struct {const wchar_t* name; WWOnline::LadderType type;} _ladders[] =
|
||||
{
|
||||
{TRANSLATE(IDS_MENU_INDIVIDUAL), WWOnline::LadderType_Team},
|
||||
{TRANSLATE(IDS_MENU_CLAN), WWOnline::LadderType_Clan}
|
||||
};
|
||||
|
||||
// Initialize with unknown data
|
||||
for (int index = 0; index < 2; ++index)
|
||||
{
|
||||
int item = list->Insert_Entry(index, _ladders[index].name);
|
||||
|
||||
if (item != -1)
|
||||
{
|
||||
list->Set_Entry_Data(item, COL_LADDERNAME, _ladders[index].type);
|
||||
list->Set_Entry_Text(item, COL_WINS, L"- / -");
|
||||
list->Set_Entry_Text(item, COL_DEATHS, L"- / -");
|
||||
list->Set_Entry_Text(item, COL_POINTS, L"-");
|
||||
list->Set_Entry_Text(item, COL_RANK, L"-");
|
||||
}
|
||||
}
|
||||
|
||||
// Show the profile's ranking
|
||||
if (profile)
|
||||
{
|
||||
WideStringClass profileName(128, true);
|
||||
profileName.Format(TRANSLATE(IDS_MENU_RANKING_PROFILE), profile->GetName());
|
||||
dialog->Set_Dlg_Item_Text(IDC_PROFILENAME, profileName);
|
||||
|
||||
ShowRanking(list, WWOnline::LadderType_Team, profile->GetRanking(WWOnline::LadderType_Team));
|
||||
ShowRanking(list, WWOnline::LadderType_Clan, profile->GetRanking(WWOnline::LadderType_Clan));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* ShowRanking
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* List - List control to show ranking in
|
||||
* Type - Type of ladder
|
||||
* Rank - Ladder ranking data
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void ShowRanking(ListCtrlClass* list, WWOnline::LadderType type, const LoginProfile::Ranking* rank)
|
||||
{
|
||||
WWASSERT(list != NULL);
|
||||
WWASSERT(rank != NULL);
|
||||
|
||||
int count = list->Get_Entry_Count();
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
if ((WWOnline::LadderType)list->Get_Entry_Data(index, COL_LADDERNAME) == type)
|
||||
{
|
||||
WideStringClass text(64, true);
|
||||
|
||||
if (rank->Wins != (unsigned)-1)
|
||||
{
|
||||
text.Format(L"%u / %u", rank->Wins, rank->Losses);
|
||||
list->Set_Entry_Text(index, COL_WINS, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
list->Set_Entry_Text(index, COL_WINS, L"- / -");
|
||||
}
|
||||
|
||||
if ((rank->Deaths != (unsigned)-1) && (rank->Kills != (unsigned)-1))
|
||||
{
|
||||
text.Format(L"%u / %u", rank->Deaths, rank->Kills);
|
||||
list->Set_Entry_Text(index, COL_DEATHS, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
list->Set_Entry_Text(index, COL_DEATHS, L"- / -");
|
||||
}
|
||||
|
||||
if (rank->Points != (unsigned)-1)
|
||||
{
|
||||
text.Format(L"%u", rank->Points);
|
||||
list->Set_Entry_Text(index, COL_POINTS, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
list->Set_Entry_Text(index, COL_POINTS, L"-");
|
||||
}
|
||||
|
||||
if (rank->Rank != (unsigned)-1)
|
||||
{
|
||||
text.Format(L"%u", rank->Rank);
|
||||
list->Set_Entry_Text(index, COL_RANK, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
list->Set_Entry_Text(index, COL_RANK, L"-");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
134
Code/Commando/WOLLoginProfile.h
Normal file
134
Code/Commando/WOLLoginProfile.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLLoginProfile.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 7 $
|
||||
* $Modtime: 1/19/02 2:23p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLLOGINPROFILE_H__
|
||||
#define __WOLLOGINPROFILE_H__
|
||||
|
||||
#include <WWLib\RefCount.h>
|
||||
#include <WWLib\WWString.h>
|
||||
#include <WWLib\WideString.h>
|
||||
#include <WWOnline\WOLLadder.h>
|
||||
|
||||
class LoginProfile :
|
||||
public RefCountClass
|
||||
{
|
||||
public:
|
||||
struct Ranking
|
||||
{
|
||||
unsigned int Wins;
|
||||
unsigned int Losses;
|
||||
unsigned int Deaths;
|
||||
unsigned int Kills;
|
||||
unsigned int Points;
|
||||
unsigned int Rank;
|
||||
};
|
||||
|
||||
static void EnableSaving(bool);
|
||||
|
||||
static void SetCurrent(LoginProfile*);
|
||||
|
||||
// Get the profile for the specified login.
|
||||
static LoginProfile* Get(const wchar_t* loginName, bool createOK = false);
|
||||
|
||||
// Create a login profile.
|
||||
static LoginProfile* Create(const wchar_t* loginName);
|
||||
|
||||
// Delete the profile.
|
||||
static void Delete(const wchar_t* loginName);
|
||||
|
||||
// Get login name
|
||||
const wchar_t* GetName(void) const;
|
||||
|
||||
// Set the preferred game server
|
||||
void SetPreferredServer(const char* name);
|
||||
|
||||
// Get the preferred game server
|
||||
const char* GetPreferredServer(void) const
|
||||
{return (const char*)mServer;}
|
||||
|
||||
void SetLocale(WOL::Locale locale);
|
||||
|
||||
WOL::Locale GetLocale(void) const
|
||||
{return mLocale;}
|
||||
|
||||
// Set the side preference
|
||||
void SetSidePreference(int side);
|
||||
|
||||
int GetSidePreference(void) const
|
||||
{return mSidePref;}
|
||||
|
||||
void SetGamesPlayed(unsigned long);
|
||||
|
||||
unsigned long GetGamesPlayed(void) const
|
||||
{return mGamesPlayed;}
|
||||
|
||||
// Get cached ranking
|
||||
const Ranking* GetRanking(WWOnline::LadderType type) const;
|
||||
|
||||
void SetRanking(WWOnline::LadderType type, Ranking& rank);
|
||||
|
||||
// Load profile settings
|
||||
void LoadSettings(void);
|
||||
|
||||
// Save profile settings
|
||||
void SaveSettings(void);
|
||||
|
||||
protected:
|
||||
LoginProfile();
|
||||
virtual ~LoginProfile();
|
||||
|
||||
bool FinalizeCreate(const wchar_t* loginName);
|
||||
|
||||
void LoadRank(const char* valueName, Ranking& rank);
|
||||
void SaveRank(const char* valueName, const Ranking& rank);
|
||||
|
||||
private:
|
||||
static bool _mSaveAllowed;
|
||||
static LoginProfile* _mCurrentProfile;
|
||||
|
||||
WideStringClass mName;
|
||||
StringClass mServer;
|
||||
WOL::Locale mLocale;
|
||||
int mSidePref;
|
||||
unsigned long mGamesPlayed;
|
||||
|
||||
Ranking mTeamRank;
|
||||
Ranking mClanRank;
|
||||
};
|
||||
|
||||
class DialogBaseClass;
|
||||
void ShowProfileRanking(DialogBaseClass* dialog, const LoginProfile* profile);
|
||||
|
||||
#endif // __WOLLOGINPROFILE_H__
|
||||
1344
Code/Commando/WOLLogonMgr.cpp
Normal file
1344
Code/Commando/WOLLogonMgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
129
Code/Commando/WOLLogonMgr.h
Normal file
129
Code/Commando/WOLLogonMgr.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLLogonMgr.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 25 $
|
||||
* $Modtime: 1/14/02 2:04p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLLOGONMGR_H__
|
||||
#define __WOLLOGONMGR_H__
|
||||
|
||||
#include "DlgWOLLogon.h"
|
||||
#include <WWLib\RefCount.h>
|
||||
#include <WWLib\Notify.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
|
||||
class DlgWOLWaitEvent;
|
||||
class DlgMsgBoxEvent;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WOLLOGON_FAILED = 0,
|
||||
WOLLOGON_SUCCESS,
|
||||
WOLLOGON_CANCEL,
|
||||
WOLLOGON_PATCHREQUIRED
|
||||
} WOLLogonAction;
|
||||
|
||||
class WOLLogonMgr :
|
||||
public RefCountClass,
|
||||
public Notifier<WOLLogonAction>,
|
||||
public Observer<DlgWOLLogonEvent>,
|
||||
public Observer<DlgWOLWaitEvent>,
|
||||
public Observer<DlgMsgBoxEvent>,
|
||||
public Observer<WWOnline::ServerError>,
|
||||
public Observer<WWOnline::ConnectionStatus>,
|
||||
public Observer<WWOnline::MessageOfTheDayEvent>
|
||||
{
|
||||
public:
|
||||
// Log onto Westwood Online
|
||||
static void Logon(Observer<WOLLogonAction>* observer);
|
||||
|
||||
// Log the current user off of Westwood Online.
|
||||
static void Logoff(void);
|
||||
|
||||
// Get the name of the logged in user.
|
||||
static bool GetLoginName(WideStringClass& name);
|
||||
|
||||
// Get the name of the server logged onto.
|
||||
static bool GetServerName(WideStringClass& name);
|
||||
|
||||
static RefPtr<WWOnline::IRCServerData> GetDefaultServer(void);
|
||||
|
||||
static void ConfigureSession(void);
|
||||
|
||||
static void Set_Quiet_Mode(bool mode) {mQuietMode = mode;}
|
||||
|
||||
protected:
|
||||
typedef enum {DISCONNECTED = 0, DETECTING_BANDWIDTH, FETCHING_SERVERLIST, WAITING_PINGS, WAITING_BANDWIDTH_DIALOG_OKAY, CONNECTING, CONNECTED} LogonState;
|
||||
|
||||
WOLLogonMgr();
|
||||
~WOLLogonMgr();
|
||||
|
||||
WOLLogonMgr(const WOLLogonMgr&);
|
||||
const WOLLogonMgr& operator=(const WOLLogonMgr&);
|
||||
|
||||
RefPtr<WWOnline::IRCServerData> GetPreferredServer(const wchar_t* loginname);
|
||||
|
||||
// Check if the user is connected to a server.
|
||||
bool IsConnectedToServer(const wchar_t* loginname, RefPtr<WWOnline::IRCServerData>& server);
|
||||
bool IsUserLoggedIn(const wchar_t* loginname);
|
||||
bool IsAutoLogin(const wchar_t* loginname);
|
||||
|
||||
bool HasServerList(void);
|
||||
bool HasValidPings(void);
|
||||
|
||||
void InitiateLogon(bool forced);
|
||||
|
||||
void RememberLogin(void);
|
||||
|
||||
DECLARE_NOTIFIER(WOLLogonAction)
|
||||
|
||||
void HandleNotification(DlgWOLLogonEvent&);
|
||||
void HandleNotification(DlgWOLWaitEvent&);
|
||||
void HandleNotification(DlgMsgBoxEvent&);
|
||||
void HandleNotification(WWOnline::ServerError&);
|
||||
void HandleNotification(WWOnline::ConnectionStatus&);
|
||||
void HandleNotification(WWOnline::MessageOfTheDayEvent&);
|
||||
|
||||
private:
|
||||
static bool mQuietMode;
|
||||
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
LogonState mState;
|
||||
|
||||
WideStringClass mLoginName;
|
||||
WideStringClass mPassword;
|
||||
bool mPasswordEncrypted;
|
||||
bool mRememberLogin;
|
||||
};
|
||||
|
||||
#endif // __WOLLOGONMGR_H__
|
||||
610
Code/Commando/WOLQuickMatch.cpp
Normal file
610
Code/Commando/WOLQuickMatch.cpp
Normal file
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLQuickMatch.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 37 $
|
||||
* $Modtime: 2/20/02 5:30p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "WOLQuickMatch.h"
|
||||
#include <WWOnline\PingProfile.h>
|
||||
#include <WWOnline\WaitCondition.h>
|
||||
#include <WWOnline\WOLProduct.h>
|
||||
#include <WWOnline\WOLConnect.h>
|
||||
#include <WWOnline\WOLServer.h>
|
||||
#include <WWOnline\WOLLadder.h>
|
||||
#include <WWLib\CPUDetect.h>
|
||||
#include <WWDebug\WWDebug.h>
|
||||
#include "cnetwork.h"
|
||||
#include "translatedb.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
typedef void (*QMDispatchFunc)(WOLQuickMatch*, const wchar_t*);
|
||||
|
||||
struct QMResponseDispatch
|
||||
{
|
||||
const wchar_t* Token;
|
||||
QMDispatchFunc Dispatch;
|
||||
};
|
||||
|
||||
|
||||
#define QUICKMATCH_CHANNELNAME L"lob_39_0"
|
||||
#define QUICKMATCH_BOTNAME L"matchbot"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::Create
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create an instance to a quickmatch game matcher.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Quickmatch - Quickmatch instance.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLQuickMatch* WOLQuickMatch::Create(void)
|
||||
{
|
||||
WOLQuickMatch* match = new WOLQuickMatch;
|
||||
|
||||
if (match)
|
||||
{
|
||||
if (match->FinalizeCreate())
|
||||
{
|
||||
return match;
|
||||
}
|
||||
|
||||
match->Release_Ref();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::WOLQuickMatch
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Default constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLQuickMatch::WOLQuickMatch()
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: Instantiating\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::~WOLQuickMatch
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLQuickMatch::~WOLQuickMatch()
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: Destructing\n"));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::FinalizeCreate
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Creation initializaton / finalization
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Success - True if successful
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLQuickMatch::FinalizeCreate(void)
|
||||
{
|
||||
mWOLSession = Session::GetInstance(false);
|
||||
|
||||
if (!mWOLSession.IsValid())
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: ERROR - WWOnline not instantiated\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::ConnectClient
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Connect a game client to the quickmatch bot.
|
||||
*
|
||||
* INPUTS
|
||||
* ChannelName - Name of matching channel
|
||||
* BotName - Name of matching bot
|
||||
*
|
||||
* RESULT
|
||||
* Wait - Wait condition to process.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
RefPtr<WaitCondition> WOLQuickMatch::ConnectClient(void)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: Connecting client to '%S' '%S'\n",
|
||||
QUICKMATCH_CHANNELNAME, QUICKMATCH_BOTNAME));
|
||||
|
||||
// Make sure that we are logged on to WWOnline
|
||||
if (mWOLSession->GetConnectionStatus() != ConnectionConnected)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: ERROR - Not connected to WWOnline server\n"));
|
||||
RefPtr<SingleWait> wait = SingleWait::Create(TRANSLATE(IDS_WOL_CONNECTING));
|
||||
wait->EndWait(WaitCondition::Error, TRANSLATE(IDS_WOL_NOTCONNECTED));
|
||||
return wait;
|
||||
}
|
||||
|
||||
// Generate client connect wait condition
|
||||
RefPtr<SerialWait> connectWait = SerialWait::Create();
|
||||
|
||||
if (connectWait.IsValid())
|
||||
{
|
||||
Observer<ServerError>::NotifyMe(*mWOLSession);
|
||||
Observer<ChatMessage>::NotifyMe(*mWOLSession);
|
||||
|
||||
// Request channel list
|
||||
RefPtr<WaitCondition> channelListWait = mWOLSession->GetNewChatChannelList();
|
||||
connectWait->Add(channelListWait);
|
||||
|
||||
// Join the matching channel
|
||||
RefPtr<Product> product = Product::Current();
|
||||
WWASSERT(product.IsValid() && "WOLProduct not initialized.");
|
||||
const wchar_t* password = product->GetChannelPassword();
|
||||
|
||||
RefPtr<WaitCondition> joinWait = mWOLSession->JoinChannel(QUICKMATCH_CHANNELNAME, password, 0);
|
||||
connectWait->Add(joinWait);
|
||||
|
||||
// Make sure the matching bot is there.
|
||||
RefPtr<WaitCondition> findBotWait = GetUserWait::Create(mWOLSession, QUICKMATCH_BOTNAME);
|
||||
connectWait->Add(findBotWait);
|
||||
}
|
||||
|
||||
return connectWait;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::Disconnect
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Disconnect from quickmatch
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Wait - Disconnect wait condition to process.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
RefPtr<WaitCondition> WOLQuickMatch::Disconnect(void)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: Disconnecting\n"));
|
||||
|
||||
Observer<ServerError>::StopObserving();
|
||||
Observer<ChatMessage>::StopObserving();
|
||||
|
||||
// If we are in the matching channel then disconnect.
|
||||
RefPtr<ChannelData> channel = mWOLSession->GetCurrentChannel();
|
||||
|
||||
if (channel.IsValid())
|
||||
{
|
||||
const WideStringClass& name = channel->GetName();
|
||||
|
||||
if (name.Compare_No_Case(QUICKMATCH_CHANNELNAME) == 0)
|
||||
{
|
||||
return mWOLSession->LeaveChannel();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::SendClientInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Send client matching preferences to the quickmatch bot.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if successful.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLQuickMatch::SendClientInfo(void)
|
||||
{
|
||||
unsigned long ver = cNetwork::Get_Exe_Key();
|
||||
|
||||
// Get CPU speed
|
||||
int speed = CPUDetectClass::Get_Processor_Speed();
|
||||
|
||||
// Get amount of physical memory
|
||||
MEMORYSTATUS memStatus;
|
||||
GlobalMemoryStatus(&memStatus);
|
||||
unsigned long memory = (memStatus.dwTotalPhys / 1048576);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Gather pings
|
||||
//-------------------------------------------------------------------------
|
||||
const PingProfile& pings = GetLocalPingProfile();
|
||||
char pseudoPings[18] = {0};
|
||||
EncodePingProfile(pings, pseudoPings);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Get clients ladder points
|
||||
//-------------------------------------------------------------------------
|
||||
RefPtr<UserData> client = mWOLSession->GetCurrentUser();
|
||||
WWASSERT(client.IsValid());
|
||||
|
||||
if (client.IsValid() == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int tpoints = 0;
|
||||
unsigned int played = 0;
|
||||
|
||||
RefPtr<LadderData> ladder = client->GetTeamLadder();
|
||||
|
||||
if (ladder.IsValid())
|
||||
{
|
||||
tpoints = ladder->GetPoints();
|
||||
played = ladder->GetReserved2();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Generate client information message
|
||||
//-------------------------------------------------------------------------
|
||||
WideStringClass clientMsg(256, true);
|
||||
clientMsg.Format(L"CINFO VER=%lu CPU=%lu MEM=%lu TPOINTS=%ld PLAYED=%lu PINGS=%S",
|
||||
ver, speed, memory, tpoints, played, pseudoPings);
|
||||
|
||||
WWDEBUG_SAY(("WOLQuickMatch: '%S'\n", (const WCHAR*)clientMsg));
|
||||
return mWOLSession->SendPrivateMessage(QUICKMATCH_BOTNAME, (const WCHAR*)clientMsg);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::SendServerInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Send information describing the game,
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::SendServerInfo(const char* exInfo, const char* topic)
|
||||
{
|
||||
if (exInfo && topic)
|
||||
{
|
||||
#pragma message(__FILE__" *** HACK ALERT *** SINFO msg is imitating WOLAPI IRC topic!")
|
||||
|
||||
// *** WARNING *** DANGER *** HACK ALERT ****
|
||||
//
|
||||
// The SINFO message sent to the matching bot is assembled in such
|
||||
// a way as to imitate the IRC topic string that WOLAPI produces.
|
||||
WideStringClass botMsg(0, true);
|
||||
botMsg.Format(L"SINFO %S%S", exInfo, topic);
|
||||
WWDEBUG_SAY(("WOLQuickMatch: '%S'\n", (const WCHAR*)botMsg));
|
||||
|
||||
mWOLSession->SendPrivateMessage(QUICKMATCH_BOTNAME, botMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::SendStatus
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::SendStatus(const wchar_t* statusMsg)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: Status '%S'\n", statusMsg));
|
||||
|
||||
WideStringClass msg(256, true);
|
||||
msg = statusMsg;
|
||||
QuickMatchEvent status(QuickMatchEvent::QMMSG, msg);
|
||||
NotifyObservers(status);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::ParseResponse
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle response messages from the quickmatch bot.
|
||||
*
|
||||
* INPUTS
|
||||
* Message - Response message from quickmatch bot.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::ParseResponse(const wchar_t* message)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
static QMResponseDispatch _dispatch[] =
|
||||
{
|
||||
{L"INFO ", WOLQuickMatch::ProcessInfo},
|
||||
{L"ERROR ", WOLQuickMatch::ProcessError},
|
||||
{L"START ", WOLQuickMatch::ProcessStart},
|
||||
{NULL, WOLQuickMatch::ProcessUnknown}
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
const wchar_t* token = _dispatch[index].Token;
|
||||
|
||||
while (token)
|
||||
{
|
||||
// Find the first occurance of the token in the message
|
||||
wchar_t* cmd = wcsstr(message, token);
|
||||
|
||||
// If the token was found and it is at the start of the message
|
||||
// then return the type of message this is.
|
||||
if (cmd && cmd == message)
|
||||
{
|
||||
const wchar_t* data = (message + wcslen(token));
|
||||
_dispatch[index].Dispatch(this, data);
|
||||
}
|
||||
|
||||
index++;
|
||||
token = _dispatch[index].Token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::ProcessInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process information messages.
|
||||
*
|
||||
* INPUTS
|
||||
* Message -
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::ProcessInfo(WOLQuickMatch* quickmatch, const wchar_t* data)
|
||||
{
|
||||
WideStringClass msg(255, true);
|
||||
msg = data;
|
||||
|
||||
QuickMatchEvent status(QuickMatchEvent::QMINFO, msg);
|
||||
quickmatch->NotifyObservers(status);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::ProcessError
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process error messages from the quickmatch bot.
|
||||
*
|
||||
* INPUTS
|
||||
* Message - Error message
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::ProcessError(WOLQuickMatch* quickmatch, const wchar_t* data)
|
||||
{
|
||||
WideStringClass msg(255, true);
|
||||
msg = data;
|
||||
|
||||
QuickMatchEvent status(QuickMatchEvent::QMERROR, msg);
|
||||
quickmatch->NotifyObservers(status);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::ProcessStart
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process start message from the quickmatch bot.
|
||||
*
|
||||
* INPUTS
|
||||
* Data - Start game parameters
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::ProcessStart(WOLQuickMatch* quickmatch, const wchar_t* data)
|
||||
{
|
||||
// Send message indicating successful match
|
||||
WideStringClass msg(255, true);
|
||||
msg.Format(TRANSLATE(IDS_MENU_QM_MATCHED_WITH), data);
|
||||
|
||||
QuickMatchEvent status(QuickMatchEvent::QMMSG, msg);
|
||||
quickmatch->NotifyObservers(status);
|
||||
|
||||
// Send message that we are matched.
|
||||
msg = data;
|
||||
QuickMatchEvent matchedEvent(QuickMatchEvent::QMMATCHED, msg);
|
||||
quickmatch->NotifyObservers(matchedEvent);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::ProcessUnknown
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process unknown messages from the quickmatch bot.
|
||||
*
|
||||
* INPUTS
|
||||
* Message - Unknown message
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::ProcessUnknown(WOLQuickMatch* quickmatch, const wchar_t* data)
|
||||
{
|
||||
WideStringClass msg(255, true);
|
||||
msg = data;
|
||||
|
||||
QuickMatchEvent status(QuickMatchEvent::QMUNKNOWN, msg);
|
||||
quickmatch->NotifyObservers(status);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::HandleNotification(ServerError)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle server errors.
|
||||
*
|
||||
* INPUTS
|
||||
* Error - Server error
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::HandleNotification(ServerError& error)
|
||||
{
|
||||
const wchar_t* errorMsg = error.GetDescription();
|
||||
WWDEBUG_SAY(("WOLQuickMatch: ERROR - ServerError '%S'\n", errorMsg));
|
||||
QuickMatchEvent status(QuickMatchEvent::QMERROR, errorMsg);
|
||||
NotifyObservers(status);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLQuickMatch::HandleNotification(ChatMessageEvent)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Handle private messages coming from the matchbot.
|
||||
*
|
||||
* INPUTS
|
||||
* Message - Chat message
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLQuickMatch::HandleNotification(ChatMessage& message)
|
||||
{
|
||||
const WideStringClass& sender = message.GetSendersName();
|
||||
|
||||
if (sender.Compare_No_Case(QUICKMATCH_BOTNAME) == 0)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLQuickMatch: BotMsg - '%S'\n", message.GetMessage()));
|
||||
ParseResponse(message.GetMessage());
|
||||
}
|
||||
}
|
||||
113
Code/Commando/WOLQuickMatch.h
Normal file
113
Code/Commando/WOLQuickMatch.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLQuickMatch.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 18 $
|
||||
* $Modtime: 2/20/02 5:07p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WOLQUICKMATCH_H__
|
||||
#define __WOLQUICKMATCH_H__
|
||||
|
||||
#include <WWLib\RefCount.h>
|
||||
#include <WWOnline\RefPtr.h>
|
||||
#include <WWOnline\WOLSession.h>
|
||||
#include <WWLib\Notify.h>
|
||||
|
||||
class WaitCondition;
|
||||
class DlgWOLWaitEvent;
|
||||
|
||||
class QuickMatchEvent :
|
||||
public TypedEvent<QuickMatchEvent, const WideStringClass>
|
||||
{
|
||||
public:
|
||||
enum Event {QMERROR = 0, QMINFO, QMMSG, QMMATCHED, QMUNKNOWN};
|
||||
|
||||
Event GetEvent(void) const
|
||||
{return mEvent;}
|
||||
|
||||
QuickMatchEvent(Event event, const WideStringClass& msg) :
|
||||
TypedEvent<QuickMatchEvent, const WideStringClass>(msg),
|
||||
mEvent(event)
|
||||
{}
|
||||
|
||||
~QuickMatchEvent()
|
||||
{}
|
||||
|
||||
private:
|
||||
Event mEvent;
|
||||
};
|
||||
|
||||
|
||||
class WOLQuickMatch :
|
||||
public RefCountClass,
|
||||
public Notifier<QuickMatchEvent>,
|
||||
public Observer<WWOnline::ServerError>,
|
||||
public Observer<WWOnline::ChatMessage>
|
||||
{
|
||||
public:
|
||||
static WOLQuickMatch* Create(void);
|
||||
|
||||
RefPtr<WaitCondition> ConnectClient(void);
|
||||
RefPtr<WaitCondition> Disconnect(void);
|
||||
|
||||
bool SendClientInfo(void);
|
||||
void SendServerInfo(const char* exInfo, const char* topic);
|
||||
|
||||
DECLARE_NOTIFIER(QuickMatchEvent)
|
||||
|
||||
protected:
|
||||
WOLQuickMatch();
|
||||
~WOLQuickMatch();
|
||||
|
||||
bool FinalizeCreate(void);
|
||||
|
||||
void SendStatus(const wchar_t* statusMsg);
|
||||
|
||||
void ParseResponse(const wchar_t* message);
|
||||
|
||||
void HandleNotification(WWOnline::ServerError&);
|
||||
void HandleNotification(WWOnline::ChatMessage&);
|
||||
|
||||
private:
|
||||
// Prevent copy and assignment
|
||||
WOLQuickMatch(const WOLQuickMatch&);
|
||||
const WOLQuickMatch& operator=(const WOLQuickMatch&);
|
||||
|
||||
static void ProcessInfo(WOLQuickMatch*, const wchar_t*);
|
||||
static void ProcessError(WOLQuickMatch*, const wchar_t*);
|
||||
static void ProcessStart(WOLQuickMatch*, const wchar_t*);
|
||||
static void ProcessUnknown(WOLQuickMatch*, const wchar_t*);
|
||||
|
||||
protected:
|
||||
RefPtr<WWOnline::Session> mWOLSession;
|
||||
};
|
||||
|
||||
#endif // __WOLQUICKMATCH_H__
|
||||
1150
Code/Commando/WebBrowser.cpp
Normal file
1150
Code/Commando/WebBrowser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
177
Code/Commando/WebBrowser.h
Normal file
177
Code/Commando/WebBrowser.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* $Archive: /Commando/Code/Commando/WebBrowser.h $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Web Browser
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
* $Author: Denzil_l $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 7 $
|
||||
* $Modtime: 1/15/02 3:06p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WEBBROWSER_H__
|
||||
#define __WEBBROWSER_H__
|
||||
|
||||
#include "WOLBrowser\WOLBrowser.h"
|
||||
#include <WWLib\Notify.h>
|
||||
#include <atlbase.h>
|
||||
#include <windows.h>
|
||||
|
||||
class WebBrowser;
|
||||
|
||||
class WebEvent :
|
||||
public TypedEventPtr<WebEvent, WebBrowser>
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
None = 0, // NULL event
|
||||
Quit, // User initiated quit
|
||||
CertificationFailed, // Requested page failed certification.
|
||||
} EventID;
|
||||
|
||||
//! Retrieve event
|
||||
inline EventID Event(void) const
|
||||
{return mEvent;}
|
||||
|
||||
WebEvent(EventID event, WebBrowser* object) :
|
||||
TypedEventPtr<WebEvent, WebBrowser>(object),
|
||||
mEvent(event)
|
||||
{}
|
||||
|
||||
protected:
|
||||
// Prevent copy and assignment
|
||||
WebEvent(const WebEvent&);
|
||||
const WebEvent& operator=(const WebEvent&);
|
||||
|
||||
private:
|
||||
EventID mEvent;
|
||||
};
|
||||
|
||||
|
||||
class WebBrowser :
|
||||
public IWOLBrowserEvent,
|
||||
public Notifier<WebEvent>
|
||||
{
|
||||
public:
|
||||
// Initialize browser prerequisites.
|
||||
// NOTE: This is for development purpose only; The game installer should handle
|
||||
// these tasks.
|
||||
#ifdef _DEBUG
|
||||
static bool InstallPrerequisites(void);
|
||||
#endif
|
||||
|
||||
//! Test if a web page is currently displayed
|
||||
static bool IsWebPageDisplayed(void);
|
||||
|
||||
//! Create an instance of the embedded browser for Dune Emperor.
|
||||
static WebBrowser* CreateInstance(HWND window);
|
||||
|
||||
//! Check if browser is embedded or external (True if embedded)
|
||||
bool UsingEmbeddedBrowser(void) const
|
||||
{return (mWOLBrowser != NULL);}
|
||||
|
||||
//! Test if the external browser is running
|
||||
bool IsExternalBrowserRunning(void) const;
|
||||
|
||||
//! Display the specified web content.
|
||||
bool ShowWebPage(char* page);
|
||||
|
||||
//! Launch the external browser
|
||||
bool LaunchExternal(const char* url);
|
||||
|
||||
//! Show the browser
|
||||
void Show(void);
|
||||
|
||||
//! Hide the browser
|
||||
void Hide(void);
|
||||
|
||||
//! Test if the browser is visible
|
||||
bool IsVisible(void) const
|
||||
{return mVisible;}
|
||||
|
||||
protected:
|
||||
// Protected to prevent direct construction via new, use CreateInstance() instead.
|
||||
WebBrowser();
|
||||
virtual ~WebBrowser();
|
||||
|
||||
// Protected to prevent copy and assignment
|
||||
WebBrowser(const WebBrowser&);
|
||||
const WebBrowser& operator=(const WebBrowser&);
|
||||
|
||||
bool FinalizeCreate(HWND window);
|
||||
|
||||
bool RetrievePageURL(const char* page, char* url, int size);
|
||||
bool RetrieveHTMLPath(char* path, int size);
|
||||
|
||||
DECLARE_NOTIFIER(WebEvent)
|
||||
|
||||
private:
|
||||
static WebBrowser* _mInstance;
|
||||
|
||||
ULONG mRefCount;
|
||||
CComPtr<IWOLBrowser> mWOLBrowser;
|
||||
wchar_t mPendingURL[512];
|
||||
bool mVisible;
|
||||
|
||||
PROCESS_INFORMATION mProcessInfo;
|
||||
|
||||
bool mSwitchedMode;
|
||||
int mRestoreWidth;
|
||||
int mRestoreHeight;
|
||||
int mRestoreBits;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// IUnknown methods
|
||||
//---------------------------------------------------------------------------
|
||||
public:
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef(void);
|
||||
ULONG STDMETHODCALLTYPE Release(void);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// IWOLBrowserEvent methods
|
||||
//---------------------------------------------------------------------------
|
||||
private:
|
||||
STDMETHOD(OnScriptQuit)(void);
|
||||
STDMETHOD(OnBeforeNavigate)(const wchar_t* url, const wchar_t* targetFrame);
|
||||
STDMETHOD(OnDocumentComplete)(const wchar_t* url, BOOL topFrame);
|
||||
STDMETHOD(OnDownloadBegin)(void);
|
||||
STDMETHOD(OnProgressChange)(LONG progress, LONG progressMax);
|
||||
STDMETHOD(OnDownloadComplete)(void);
|
||||
STDMETHOD(OnNavigateComplete)(const wchar_t* url);
|
||||
STDMETHOD(OnStatusTextChange)(const wchar_t* statusText);
|
||||
STDMETHOD(OnTitleChange)(const wchar_t* title);
|
||||
STDMETHOD(OnNewWindow)(void);
|
||||
STDMETHOD(OnShowMessage)(const wchar_t* text, const wchar_t* caption, ULONG type, LONG* result);
|
||||
STDMETHOD(OnFailedPageCertification)(void);
|
||||
STDMETHOD(OnErrorMsg)(const wchar_t* error);
|
||||
STDMETHOD(OnRegisterLogin)(const wchar_t* nick, const wchar_t* pass);
|
||||
};
|
||||
|
||||
#endif // __WEBBROWSER_H__
|
||||
107
Code/Commando/_globals.h
Normal file
107
Code/Commando/_globals.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
** 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/_globals.h $*
|
||||
* *
|
||||
* $Author:: Bhayes $*
|
||||
* *
|
||||
* $Modtime:: 3/06/02 5:36p $*
|
||||
* *
|
||||
* $Revision:: 25 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef _GLOBALS_H
|
||||
#define _GLOBALS_H
|
||||
|
||||
#include "specialbuilds.h"
|
||||
|
||||
/*
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
#define APP_SUB_KEY "Software\\Westwood\\RenegadeFDS"
|
||||
#else //FREEDEDICATEDSERVER
|
||||
|
||||
#ifdef MULTIPLAYERDEMO
|
||||
#define APP_SUB_KEY "Software\\Westwood\\RenegadeMPDemo"
|
||||
#else // MULTIPLAYERDEMO
|
||||
#define APP_SUB_KEY "Software\\Westwood\\Renegade"
|
||||
#endif //MULTIPLAYERDEMO
|
||||
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
*/
|
||||
|
||||
#if defined(FREEDEDICATEDSERVER)
|
||||
#define APP_SUB_KEY "Software\\Westwood\\RenegadeFDS"
|
||||
#elif defined(MULTIPLAYERDEMO)
|
||||
#define APP_SUB_KEY "Software\\Westwood\\RenegadeMPDemo"
|
||||
#elif defined(BETACLIENT)
|
||||
#define APP_SUB_KEY "Software\\Westwood\\RenegadeBeta"
|
||||
#elif defined(BETASERVER)
|
||||
#define APP_SUB_KEY "Software\\Westwood\\RenegadeBeta"
|
||||
#else
|
||||
#define APP_SUB_KEY "Software\\Westwood\\Renegade"
|
||||
#endif
|
||||
|
||||
|
||||
extern char *Build_Registry_Location_String(char *base, char *modifier, char *sub);
|
||||
|
||||
#define APPLICATION_SUB_KEY_NAME Build_Registry_Location_String(APP_SUB_KEY, NULL, "")
|
||||
|
||||
#define APPLICATION_SUB_KEY_NAME_RENDER Build_Registry_Location_String(APP_SUB_KEY, NULL, "Render")
|
||||
#define APPLICATION_SUB_KEY_NAME_OPTIONS Build_Registry_Location_String(APP_SUB_KEY, NULL, "Options")
|
||||
#define APPLICATION_SUB_KEY_NAME_DEBUG Build_Registry_Location_String(APP_SUB_KEY, NULL, "Debug")
|
||||
#define APPLICATION_SUB_KEY_NAME_SYSTEM_SETTINGS Build_Registry_Location_String(APP_SUB_KEY, NULL, "System Settings")
|
||||
#define APPLICATION_SUB_KEY_NAME_CONTROLS Build_Registry_Location_String(APP_SUB_KEY, NULL, "Controls")
|
||||
#define APPLICATION_SUB_KEY_NAME_SOUND Build_Registry_Location_String(APP_SUB_KEY, NULL, "Sound")
|
||||
#define APPLICATION_SUB_KEY_NAME_MOVIES Build_Registry_Location_String(APP_SUB_KEY, NULL, "Movies")
|
||||
#define APPLICATION_SUB_KEY_NAME_WOLSETTINGS Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings")
|
||||
#define APPLICATION_SUB_KEY_NAME_MISSION_RANKS Build_Registry_Location_String(APP_SUB_KEY, NULL, "Ranks")
|
||||
#define APPLICATION_SUB_KEY_NAME_INPUT Build_Registry_Location_String(APP_SUB_KEY, NULL, "Input")
|
||||
#define APPLICATION_SUB_KEY_NAME_GAMESPY Build_Registry_Location_String(APP_SUB_KEY, NULL, "GameSpy")
|
||||
#define APPLICATION_SUB_KEY_NAME_WOLSETTINGS Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings")
|
||||
#define APPLICATION_SUB_KEY_NAME_URL Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings\\URL")
|
||||
#define APPLICATION_SUB_KEY_NAME_LOGINS Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings\\Logins")
|
||||
#define APPLICATION_SUB_KEY_NAME_QUICKMATCH Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings\\QuickMatch")
|
||||
#define APPLICATION_SUB_KEY_NAME_IGNORE_LIST Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings\\Ignore List")
|
||||
#define APPLICATION_SUB_KEY_NAME_SERVER_LIST Build_Registry_Location_String(APP_SUB_KEY, NULL, "WOLSettings\\Servers")
|
||||
#define APPLICATION_SUB_KEY_NAME_SKIN_LIST Build_Registry_Location_String(APP_SUB_KEY, NULL, "MP Settings\\Skins")
|
||||
|
||||
#define APPLICATION_SUB_KEY_NAME_NETOPTIONS Build_Registry_Location_String(APP_SUB_KEY, NULL, "Networking\\Options")
|
||||
#define APPLICATION_SUB_KEY_NAME_NETDEBUG Build_Registry_Location_String(APP_SUB_KEY, NULL, "Networking\\Debug")
|
||||
#define APPLICATION_SUB_KEY_NAME_NET_FIREWALL Build_Registry_Location_String(APP_SUB_KEY, NULL, "Networking\\Firewall")
|
||||
#define APPLICATION_SUB_KEY_NAME_NET_SLAVE Build_Registry_Location_String(APP_SUB_KEY, NULL, "Networking\\Slave")
|
||||
#define APPLICATION_SUB_KEY_NAME_NET_SERVER_CONTROL Build_Registry_Location_String(APP_SUB_KEY, NULL, "Networking\\ServerControl")
|
||||
|
||||
#define COMBAT_SUB_KEY_NAME_DEBUG Build_Registry_Location_String(APP_SUB_KEY, NULL, "Debug")
|
||||
|
||||
#define APPLICATION_SUB_KEY_NAME_BANDTEST Build_Registry_Location_String(APP_SUB_KEY, NULL, "Bandtest")
|
||||
|
||||
#define RENEGADE_BASE_SKU 3072
|
||||
#define RENEGADE_FDS_SKU 12288
|
||||
#define RENEGADE_DEMO_SKU 13056
|
||||
|
||||
|
||||
#endif
|
||||
456
Code/Commando/apppacketstats.cpp
Normal file
456
Code/Commando/apppacketstats.cpp
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
** 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/apppacketstats.cpp $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 2/21/02 3:01p $*
|
||||
* *
|
||||
* $Revision:: 24 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "apppacketstats.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wwdebug.h"
|
||||
#include "mathutil.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "wwprofile.h"
|
||||
|
||||
//
|
||||
// Class statics
|
||||
//
|
||||
DWORD cAppPacketStats::PacketsSent[];
|
||||
DWORD cAppPacketStats::BitsSent[];
|
||||
DWORD cAppPacketStats::BitsSentTier[][PACKET_TIER_COUNT];
|
||||
DWORD cAppPacketStats::ObjectTally[];
|
||||
StringClass cAppPacketStats::WorkingString;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cAppPacketStats::Reset
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
::memset(&PacketsSent, 0, sizeof(PacketsSent));
|
||||
::memset(&BitsSent, 0, sizeof(BitsSent));
|
||||
::memset(&BitsSentTier, 0, sizeof(BitsSentTier));
|
||||
::memset(&ObjectTally, 0, sizeof(ObjectTally));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cAppPacketStats::Dump_Diagnostics
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
WWDEBUG_SAY(("\n"));
|
||||
WWDEBUG_SAY(("---------------------------------------------------------\n"));
|
||||
WWDEBUG_SAY(("cAppPacketStats::Dump_Diagnostics:\n"));
|
||||
WWDEBUG_SAY(("%s\n", Get_Heading()));
|
||||
|
||||
for (BYTE i = 0; i < APPPACKETTYPE_COUNT; i++)
|
||||
{
|
||||
WWDEBUG_SAY(("%s\n", Get_Description(i)));
|
||||
}
|
||||
|
||||
WWDEBUG_SAY(("\n"));
|
||||
WWDEBUG_SAY(("---------------------------------------------------------\n"));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cAppPacketStats::Increment_Packets_Sent
|
||||
(
|
||||
BYTE app_packet_type
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type != APPPACKETTYPE_ALL && app_packet_type < APPPACKETTYPE_COUNT);
|
||||
|
||||
PacketsSent[app_packet_type]++;
|
||||
|
||||
PacketsSent[APPPACKETTYPE_ALL]++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cAppPacketStats::Increment_Bits_Sent
|
||||
(
|
||||
BYTE app_packet_type,
|
||||
DWORD bits
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type != APPPACKETTYPE_ALL && app_packet_type < APPPACKETTYPE_COUNT);
|
||||
WWASSERT(bits >= 0);
|
||||
|
||||
BitsSent[app_packet_type] += bits;
|
||||
|
||||
BitsSent[APPPACKETTYPE_ALL] += bits;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cAppPacketStats::Increment_Bits_Sent_Tier
|
||||
(
|
||||
BYTE app_packet_type,
|
||||
PACKET_TIER_ENUM tier,
|
||||
DWORD bits
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type != APPPACKETTYPE_ALL && app_packet_type < APPPACKETTYPE_COUNT);
|
||||
WWASSERT(bits >= 0);
|
||||
|
||||
BitsSentTier[app_packet_type][tier] += bits;
|
||||
|
||||
BitsSentTier[APPPACKETTYPE_ALL][tier] += bits;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD
|
||||
cAppPacketStats::Get_Packets_Sent
|
||||
(
|
||||
BYTE app_packet_type
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
||||
|
||||
return PacketsSent[app_packet_type];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD
|
||||
cAppPacketStats::Get_Bits_Sent
|
||||
(
|
||||
BYTE app_packet_type
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
||||
|
||||
return BitsSent[app_packet_type];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD
|
||||
cAppPacketStats::Get_Bits_Sent_Tier
|
||||
(
|
||||
BYTE app_packet_type,
|
||||
PACKET_TIER_ENUM tier
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
||||
|
||||
return BitsSentTier[app_packet_type][tier];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#define ADD_CASE(exp) case exp: return #exp;
|
||||
|
||||
LPCSTR
|
||||
cAppPacketStats::Interpret_Type
|
||||
(
|
||||
BYTE app_packet_type
|
||||
)
|
||||
{
|
||||
switch (app_packet_type)
|
||||
{
|
||||
//
|
||||
// S->S
|
||||
//
|
||||
ADD_CASE(APPPACKETTYPE_UNKNOWN);
|
||||
ADD_CASE(APPPACKETTYPE_SIMPLE);
|
||||
ADD_CASE(APPPACKETTYPE_SOLDIER);
|
||||
ADD_CASE(APPPACKETTYPE_VEHICLE);
|
||||
ADD_CASE(APPPACKETTYPE_TURRET);
|
||||
ADD_CASE(APPPACKETTYPE_BUILDING);
|
||||
ADD_CASE(APPPACKETTYPE_PLAYER);
|
||||
ADD_CASE(APPPACKETTYPE_TEAM);
|
||||
ADD_CASE(APPPACKETTYPE_GAMEOPTIONSEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_PLAYERKILLEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_PURCHASERESPONSEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_SCTEXTOBJ);
|
||||
ADD_CASE(APPPACKETTYPE_SVRGOODBYEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_WINEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_POWERUP);
|
||||
ADD_CASE(APPPACKETTYPE_STATIC);
|
||||
ADD_CASE(APPPACKETTYPE_DOOR);
|
||||
ADD_CASE(APPPACKETTYPE_ELEVATOR);
|
||||
ADD_CASE(APPPACKETTYPE_DSAPO);
|
||||
ADD_CASE(APPPACKETTYPE_SERVERFPS);
|
||||
ADD_CASE(APPPACKETTYPE_CONSOLECOMMANDEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_RESETWINSEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_EVICTIONEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_NETWEATHER);
|
||||
ADD_CASE(APPPACKETTYPE_GAMEDATAUPDATEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_SCPINGRESPONSEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_BASECONTROLLER);
|
||||
ADD_CASE(APPPACKETTYPE_CINEMATIC);
|
||||
ADD_CASE(APPPACKETTYPE_C4);
|
||||
ADD_CASE(APPPACKETTYPE_BEACON);
|
||||
ADD_CASE(APPPACKETTYPE_SCEXPLOSIONEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_SCOBELISKEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_SCANNOUNCEMENT);
|
||||
ADD_CASE(APPPACKETTYPE_NETBACKGROUND);
|
||||
ADD_CASE(APPPACKETTYPE_GAMESPYSCCHALLENGEEVENT);
|
||||
|
||||
|
||||
//
|
||||
// C->S
|
||||
//
|
||||
ADD_CASE(APPPACKETTYPE_CLIENTCONTROL);
|
||||
ADD_CASE(APPPACKETTYPE_CSTEXTOBJ);
|
||||
ADD_CASE(APPPACKETTYPE_SUICIDEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CHANGETEAMEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_MONEYEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_WARPEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_PURCHASEREQUESTEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CLIENTGOODBYEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_BIOEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_LOADINGEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_GODMODEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_VIPMODEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_SCOREEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CLIENTBBOEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CLIENTFPS);
|
||||
ADD_CASE(APPPACKETTYPE_CSPINGREQUESTEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CSDAMAGEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_REQUESTKILLEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CSCONSOLECOMMANDEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_CSHINT);
|
||||
ADD_CASE(APPPACKETTYPE_CSANNOUNCEMENT);
|
||||
ADD_CASE(APPPACKETTYPE_DONATEEVENT);
|
||||
ADD_CASE(APPPACKETTYPE_GAMESPYCSCHALLENGERESPONSEEVENT);
|
||||
|
||||
//
|
||||
// Summation
|
||||
//
|
||||
ADD_CASE(APPPACKETTYPE_ALL);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "ERROR";
|
||||
DIE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cAppPacketStats::Update_Object_Tally
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
::memset(&ObjectTally, 0, sizeof(ObjectTally));
|
||||
|
||||
int count = NetworkObjectMgrClass::Get_Object_Count();
|
||||
|
||||
for (int index = 0; index < count; index ++)
|
||||
{
|
||||
NetworkObjectClass * p_object = NetworkObjectMgrClass::Get_Object(index);
|
||||
|
||||
if (p_object != NULL)
|
||||
{
|
||||
BYTE type = p_object->Get_App_Packet_Type();
|
||||
WWASSERT(type < APPPACKETTYPE_ALL);
|
||||
|
||||
ObjectTally[type]++;
|
||||
ObjectTally[APPPACKETTYPE_ALL]++;
|
||||
|
||||
/*
|
||||
if (type == APPPACKETTYPE_UNKNOWN)
|
||||
{
|
||||
WWDEBUG_SAY(("WTF is this?\n"));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD
|
||||
cAppPacketStats::Get_Object_Tally
|
||||
(
|
||||
BYTE app_packet_type
|
||||
)
|
||||
{
|
||||
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
||||
|
||||
return ObjectTally[app_packet_type];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
StringClass &
|
||||
cAppPacketStats::Get_Heading
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
//StringClass description;
|
||||
|
||||
WorkingString.Format(
|
||||
"%-30s %-8s %-10s %-10s %-7s %-7s %-7s %-7s %-7s %-7s",
|
||||
"Type",
|
||||
"Tally",
|
||||
"Packets",
|
||||
"Bytes",
|
||||
"PC",
|
||||
"Avg.",
|
||||
"PC TC",
|
||||
"PC TR",
|
||||
"PC TO",
|
||||
"PC TF"
|
||||
);
|
||||
|
||||
return WorkingString;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
StringClass &
|
||||
cAppPacketStats::Get_Description
|
||||
(
|
||||
BYTE type
|
||||
)
|
||||
{
|
||||
WWASSERT(type < APPPACKETTYPE_COUNT);
|
||||
|
||||
float num_bytes = BitsSent[type] / 8.0f;
|
||||
DWORD average_bytes = 0;
|
||||
if (PacketsSent[type] > 0)
|
||||
{
|
||||
average_bytes = cMathUtil::Round(num_bytes / (float) PacketsSent[type]);
|
||||
}
|
||||
|
||||
float percentage = 0;
|
||||
if (BitsSent[APPPACKETTYPE_ALL] > 0)
|
||||
{
|
||||
percentage = 100 * (BitsSent[type] / (float) BitsSent[APPPACKETTYPE_ALL]);
|
||||
}
|
||||
|
||||
//
|
||||
// Strip the leading "APPPACKETTYPE_"
|
||||
//
|
||||
WWASSERT(::strlen(Interpret_Type(type)) > 14);
|
||||
char name[200] = "";
|
||||
::strcpy(name, &Interpret_Type(type)[14]);
|
||||
|
||||
//
|
||||
// Tier percentages
|
||||
//
|
||||
DWORD t0 = 0;
|
||||
DWORD t1 = 0;
|
||||
DWORD t2 = 0;
|
||||
DWORD t3 = 0;
|
||||
if (BitsSent[type] > 0)
|
||||
{
|
||||
float bits = BitsSent[type];
|
||||
|
||||
t0 = cMathUtil::Round(100 * (BitsSentTier[type][0] / bits));
|
||||
t1 = cMathUtil::Round(100 * (BitsSentTier[type][1] / bits));
|
||||
t2 = cMathUtil::Round(100 * (BitsSentTier[type][2] / bits));
|
||||
t3 = cMathUtil::Round(100 * (BitsSentTier[type][3] / bits));
|
||||
}
|
||||
|
||||
//StringClass description;
|
||||
WorkingString.Format(
|
||||
"%-30s %-8d %-10d %-10d %-7.1f %-7d %-7d %-7d %-7d %-7d",
|
||||
name,
|
||||
ObjectTally[type],
|
||||
PacketsSent[type],
|
||||
cMathUtil::Round(num_bytes),
|
||||
percentage,
|
||||
average_bytes,
|
||||
t0,
|
||||
t1,
|
||||
t2,
|
||||
t3
|
||||
);
|
||||
|
||||
/**/
|
||||
//
|
||||
// Replace all solo zero's with a space.
|
||||
//
|
||||
char last = ' ';
|
||||
char next = ' ';
|
||||
char * p = WorkingString.Peek_Buffer();
|
||||
for (int i = 0; i < WorkingString.Get_Length(); i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
last = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
last = p[i - 1];
|
||||
}
|
||||
|
||||
if (i == WorkingString.Get_Length() - 1)
|
||||
{
|
||||
next = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
next = p[i + 1];
|
||||
}
|
||||
|
||||
if (last == ' ' && next == ' ' && p[i] == '0')
|
||||
{
|
||||
p[i] = ' ';
|
||||
}
|
||||
}
|
||||
/**/
|
||||
|
||||
return WorkingString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//ADD_CASE(APPPACKETTYPE_FLAGCAPEVENT);
|
||||
//ADD_CASE(APPPACKETTYPE_STEALTHEVENT);
|
||||
80
Code/Commando/apppacketstats.h
Normal file
80
Code/Commando/apppacketstats.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
** 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/apppacketstats.h $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 10/15/01 4:18p $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __APPPACKETSTATS_H__
|
||||
#define __APPPACKETSTATS_H__
|
||||
|
||||
#include "bittype.h"
|
||||
#include "apppackettypes.h"
|
||||
#include "networkobject.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Record and report app packet stats
|
||||
//
|
||||
class cAppPacketStats
|
||||
{
|
||||
public:
|
||||
static void Reset(void);
|
||||
static void Dump_Diagnostics(void);
|
||||
static LPCSTR Interpret_Type(BYTE app_packet_type);
|
||||
static void Update_Object_Tally(void);
|
||||
|
||||
static void Increment_Packets_Sent(BYTE app_packet_type);
|
||||
static void Increment_Bits_Sent(BYTE app_packet_type, DWORD bits);
|
||||
static void Increment_Bits_Sent_Tier(BYTE app_packet_type, PACKET_TIER_ENUM tier, DWORD bits);
|
||||
|
||||
static DWORD Get_Packets_Sent(BYTE app_packet_type);
|
||||
static DWORD Get_Bits_Sent(BYTE app_packet_type);
|
||||
static DWORD Get_Bits_Sent_Tier(BYTE app_packet_type, PACKET_TIER_ENUM tier);
|
||||
|
||||
static DWORD Get_Object_Tally(BYTE app_packet_type);
|
||||
|
||||
static StringClass & Get_Heading(void);
|
||||
static StringClass & Get_Description(BYTE app_packet_type);
|
||||
|
||||
private:
|
||||
static DWORD PacketsSent[APPPACKETTYPE_COUNT];
|
||||
static DWORD BitsSent[APPPACKETTYPE_COUNT];
|
||||
static DWORD BitsSentTier[APPPACKETTYPE_COUNT][PACKET_TIER_COUNT];
|
||||
static DWORD ObjectTally[APPPACKETTYPE_COUNT];
|
||||
|
||||
static StringClass WorkingString;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __APPPACKETSTATS_H__
|
||||
148
Code/Commando/bandwidth.cpp
Normal file
148
Code/Commando/bandwidth.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
** 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/bandwidth.cpp $*
|
||||
* *
|
||||
* $Author:: Bhayes $*
|
||||
* *
|
||||
* $Modtime:: 2/18/02 9:22p $*
|
||||
* *
|
||||
* $Revision:: 17 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "bandwidth.h" // I WANNA BE FIRST!
|
||||
|
||||
#include "miscutil.h"
|
||||
#include "wwdebug.h"
|
||||
#include "translatedb.h"
|
||||
#include "string_ids.h"
|
||||
#include "useroptions.h"
|
||||
|
||||
#include "bandwidthcheck.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ULONG cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_TYPE_ENUM bandwidth_type)
|
||||
{
|
||||
/*
|
||||
WWASSERT(bandwidth_type >= BANDWIDTH_FIRST &&
|
||||
bandwidth_type <= BANDWIDTH_LAST);
|
||||
*/
|
||||
|
||||
// WWASSERT(bandwidth_type != BANDWIDTH_CUSTOM);
|
||||
|
||||
switch (bandwidth_type) {
|
||||
case BANDWIDTH_CUSTOM:
|
||||
return cUserOptions::BandwidthBps.Get();
|
||||
case BANDWIDTH_MODEM_288:
|
||||
return 28800;
|
||||
case BANDWIDTH_MODEM_336:
|
||||
return 33600;
|
||||
case BANDWIDTH_MODEM_56:
|
||||
return 56000;
|
||||
case BANDWIDTH_ISDN:
|
||||
return 64000;
|
||||
case BANDWIDTH_CABLE:
|
||||
return 128000;
|
||||
case BANDWIDTH_LANT1:
|
||||
return 2000000;
|
||||
case BANDWIDTH_AUTO:
|
||||
{
|
||||
ULONG bps = BandwidthCheckerClass::Get_Upstream_Bandwidth();
|
||||
// WWASSERT(bps > 0);
|
||||
return bps;
|
||||
}
|
||||
default:
|
||||
DIE;
|
||||
return 0xffffffff; // to avoid compiler warning
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const unsigned short *cBandwidth::Get_Bandwidth_String_From_Type(BANDWIDTH_TYPE_ENUM bandwidth_type)
|
||||
{
|
||||
static char _bandwidth_auto_txt[128];
|
||||
static WideStringClass s;
|
||||
/*
|
||||
WWASSERT(bandwidth_type >= BANDWIDTH_FIRST &&
|
||||
bandwidth_type <= BANDWIDTH_LAST);
|
||||
*/
|
||||
|
||||
switch (bandwidth_type) {
|
||||
case BANDWIDTH_MODEM_288:
|
||||
return TRANSLATE(IDS_MP_CONNECTION_288); //"BANDWIDTH_MODEM_288";
|
||||
case BANDWIDTH_MODEM_336:
|
||||
return TRANSLATE(IDS_MP_CONNECTION_336); //"BANDWIDTH_MODEM_336";
|
||||
case BANDWIDTH_MODEM_56:
|
||||
return TRANSLATE(IDS_MP_CONNECTION_56); //"BANDWIDTH_MODEM_56";
|
||||
case BANDWIDTH_ISDN:
|
||||
return TRANSLATE(IDS_MP_CONNECTION_ISDN); //"BANDWIDTH_ISDN";
|
||||
case BANDWIDTH_CABLE:
|
||||
return TRANSLATE(IDS_MP_CONNECTION_CABLE); //"BANDWIDTH_CABLE";
|
||||
case BANDWIDTH_LANT1:
|
||||
return TRANSLATE(IDS_MP_CONNECTION_T1); //"BANDWIDTH_LANT1";
|
||||
case BANDWIDTH_CUSTOM:
|
||||
return L"BANDWIDTH_CUSTOM";
|
||||
case BANDWIDTH_AUTO:
|
||||
{
|
||||
//sprintf(_bandwidth_auto_txt, "BANDWIDTH_AUTO (%s)", BandwidthCheckerClass::Get_Bandwidth_As_String());
|
||||
s.Format(TRANSLATE(IDS_MP_CONNECTION_T1), Get_Bandwidth_Bps_From_Type(bandwidth_type));
|
||||
//wsprintf(_bandwidth_auto_txt, TRANSLATE(IDS_MP_CONNECTION_T1), Get_Bandwidth_Bps_From_Type(bandwidth_type));
|
||||
//return ((const)_bandwidth_auto_txt);
|
||||
return(s);
|
||||
}
|
||||
default:
|
||||
DIE;
|
||||
return L"ERROR"; // to avoid compiler warning
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BANDWIDTH_TYPE_ENUM cBandwidth::Get_Bandwidth_Type_From_String(LPCSTR bandwidth_string)
|
||||
{
|
||||
WWASSERT(bandwidth_string != NULL);
|
||||
|
||||
if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_MODEM_288")) {
|
||||
return BANDWIDTH_MODEM_288;
|
||||
} else if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_MODEM_336")) {
|
||||
return BANDWIDTH_MODEM_336;
|
||||
} else if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_MODEM_56")) {
|
||||
return BANDWIDTH_MODEM_56;
|
||||
} else if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_ISDN")) {
|
||||
return BANDWIDTH_ISDN;
|
||||
} else if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_CABLE")) {
|
||||
return BANDWIDTH_CABLE;
|
||||
} else if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_LANT1")) {
|
||||
return BANDWIDTH_LANT1;
|
||||
} else if (cMiscUtil::Is_String_Same(bandwidth_string, "BANDWIDTH_CUSTOM")) {
|
||||
return BANDWIDTH_CUSTOM;
|
||||
} else if (strnicmp(bandwidth_string, "BANDWIDTH_AUTO ", 15) == 0) {
|
||||
return BANDWIDTH_AUTO;
|
||||
} else {
|
||||
DIE;
|
||||
return BANDWIDTH_CUSTOM; // to avoid compiler warning
|
||||
}
|
||||
}
|
||||
75
Code/Commando/bandwidth.h
Normal file
75
Code/Commando/bandwidth.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
** 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/bandwidth.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 12/17/01 12:30p $*
|
||||
* *
|
||||
* $Revision:: 6 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSV_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BANDWIDTH_H
|
||||
#define BANDWIDTH_H
|
||||
|
||||
#include "bittype.h"
|
||||
|
||||
enum BANDWIDTH_TYPE_ENUM {
|
||||
|
||||
BANDWIDTH_FIRST = 100,
|
||||
|
||||
BANDWIDTH_MODEM_288 = BANDWIDTH_FIRST,
|
||||
BANDWIDTH_MODEM_336,
|
||||
BANDWIDTH_MODEM_56,
|
||||
BANDWIDTH_ISDN,
|
||||
BANDWIDTH_CABLE,
|
||||
BANDWIDTH_LANT1,
|
||||
BANDWIDTH_AUTO,
|
||||
BANDWIDTH_CUSTOM,
|
||||
|
||||
BANDWIDTH_LAST = BANDWIDTH_CUSTOM
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
class cBandwidth {
|
||||
public:
|
||||
cBandwidth(void);
|
||||
~cBandwidth(void) {};
|
||||
|
||||
static ULONG Get_Bandwidth_Bps_From_Type(BANDWIDTH_TYPE_ENUM bandwidth_type);
|
||||
static const unsigned short * Get_Bandwidth_String_From_Type(BANDWIDTH_TYPE_ENUM bandwidth_type);
|
||||
static BANDWIDTH_TYPE_ENUM Get_Bandwidth_Type_From_String(LPCSTR bandwidth_string);
|
||||
};
|
||||
|
||||
#endif // BANDWIDTH_H
|
||||
979
Code/Commando/bandwidthcheck.cpp
Normal file
979
Code/Commando/bandwidthcheck.cpp
Normal file
@@ -0,0 +1,979 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/bandwidthcheck.cpp $*
|
||||
* *
|
||||
* $Author:: Bhayes $*
|
||||
* *
|
||||
* $Modtime:: 3/06/02 11:48a $*
|
||||
* *
|
||||
* $Revision:: 25 $*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
/*
|
||||
** Disable warning about exception handling not being enabled.
|
||||
*/
|
||||
#pragma warning(disable : 4530)
|
||||
|
||||
#include "always.h"
|
||||
#include <windows.h>
|
||||
#include "systimer.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#include "bandwidthcheck.h"
|
||||
#include "autostart.h"
|
||||
#include "registry.h"
|
||||
#include "_globals.h"
|
||||
#include "useroptions.h"
|
||||
#include "translatedb.h"
|
||||
#include "string_ids.h"
|
||||
#include "consolemode.h"
|
||||
#include "specialbuilds.h"
|
||||
#include "gamespyadmin.h"
|
||||
|
||||
#include <WWOnline\WOLSession.h>
|
||||
|
||||
/*
|
||||
** Class statics.
|
||||
*/
|
||||
BandwidthCheckerClass::BandwidthCheckerThreadClass BandwidthCheckerClass::Thread;
|
||||
HANDLE BandwidthCheckerClass::EventNotify = NULL;
|
||||
unsigned long BandwidthCheckerClass::UpstreamBandwidth = 0;
|
||||
unsigned long BandwidthCheckerClass::ReportedUpstreamBandwidth = 0;
|
||||
unsigned short *BandwidthCheckerClass::UpstreamBandwidthString = NULL;
|
||||
unsigned long BandwidthCheckerClass::DownstreamBandwidth = 0;
|
||||
unsigned long BandwidthCheckerClass::ReportedDownstreamBandwidth = 0;
|
||||
unsigned short *BandwidthCheckerClass::DownstreamBandwidthString = NULL;
|
||||
int BandwidthCheckerClass::FailureCode = BANDTEST_OK;
|
||||
bool BandwidthCheckerClass::GotBandwidth = false;
|
||||
const char *BandwidthCheckerClass::DefaultServerName = "www.westwood.com";
|
||||
|
||||
/*
|
||||
** Possible error codes from the bandwidth test.
|
||||
*/
|
||||
char *BandwidthCheckerClass::ErrorList[13] = {
|
||||
"BANDTEST_OK",
|
||||
"BANDTEST_NO_WINSOCK2",
|
||||
"BANDTEST_NO_RAW_SOCKET_PERMISSION",
|
||||
"BANDTEST_NO_RAW_SOCKET_CREATE",
|
||||
"BANDTEST_NO_UDP_SOCKET_BIND",
|
||||
"BANDTEST_NO_TTL_SET",
|
||||
"BANDTEST_NO_PING_RESPONSE",
|
||||
"BANDTEST_NO_FINAL_PING_TIME",
|
||||
"BANDTEST_NO_EXTERNAL_ROUTER",
|
||||
"BANDTEST_NO_IP_DETECT",
|
||||
"BANDTEST_UNKNOWN_ERROR",
|
||||
"BANDTEST_WRONG_API_VERSION",
|
||||
"BANDTEST_BAD_PARAM"
|
||||
};
|
||||
|
||||
#define NUM_BANDS 12
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
#define DEFAULT_BAND 9
|
||||
#else //FREEDEDICATEDSERVER
|
||||
#define DEFAULT_BAND 3
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
|
||||
/*
|
||||
** Lower and upper limits for each level of bandwidth.
|
||||
*/
|
||||
unsigned long BandwidthCheckerClass::Bandwidths[NUM_BANDS * 2] = {
|
||||
12000, 14400,
|
||||
28000, 28800,
|
||||
29999, 33600,
|
||||
53000, 57600,
|
||||
62000, 67200,
|
||||
105000, 115200,
|
||||
125000, 128000,
|
||||
250000, 256000,
|
||||
500000, 512000,
|
||||
999999, 1024000,
|
||||
1999999, 2048000,
|
||||
3999999, 4096000
|
||||
};
|
||||
|
||||
/*
|
||||
** Human readable names for each bandwidth level.
|
||||
*/
|
||||
unsigned short *BandwidthCheckerClass::BandwidthNames [NUM_BANDS+1] = {
|
||||
L"14400",
|
||||
L"28800",
|
||||
L"33600",
|
||||
L"57600",
|
||||
L"67200",
|
||||
L"115200",
|
||||
L"128k",
|
||||
L"256k",
|
||||
L"512k",
|
||||
L"1M",
|
||||
L"2M",
|
||||
L"4M",
|
||||
L"> 4M"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Detect -- Create the bandwidth detect wait object *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:53PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
RefPtr<WaitCondition> BandwidthCheckerClass::Detect(void)
|
||||
{
|
||||
return(BandwidthDetectWait::Create());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Start the bandwidth detection thread *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:53PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void BandwidthCheckerClass::Check_Now(HANDLE event)
|
||||
{
|
||||
EventNotify = event;
|
||||
|
||||
/*
|
||||
** If the thread didn't finish for some reason then we need to take action.
|
||||
** This will stall the dialogs but at least it won't crash.
|
||||
*/
|
||||
if (Thread.Is_Running()) {
|
||||
unsigned long timeout = 10 * 1000;
|
||||
unsigned long time = TIMEGETTIME();
|
||||
while (Thread.Is_Running() && (TIMEGETTIME() - time) < timeout) {
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
if (Thread.Is_Running()) {
|
||||
Thread.Stop(2000);
|
||||
}
|
||||
WWASSERT(!Thread.Is_Running());
|
||||
Thread.Execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Ping_Server_Name -- Get the name of a server to ping *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to server name *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/27/2001 1:17PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
const char *BandwidthCheckerClass::Get_Ping_Server_Name(void)
|
||||
{
|
||||
static char server_name_copy[128];
|
||||
DynamicVectorClass<StringClass> list;
|
||||
const char *server_name = DefaultServerName;
|
||||
|
||||
/*
|
||||
** See if there are ping servers in the registry from a previous run.
|
||||
*/
|
||||
RegistryClass reg(APPLICATION_SUB_KEY_NAME_SERVER_LIST);
|
||||
WWASSERT(list.Count() == 0);
|
||||
reg.Get_Value_List(list);
|
||||
if (list.Count() > 0) {
|
||||
|
||||
/*
|
||||
** Get average and lowest ping server ping time.
|
||||
*/
|
||||
int num_times = 0;
|
||||
unsigned long total = 0;
|
||||
int lowest = 0xffff;
|
||||
int lowest_index = -1;
|
||||
for (int i=0 ; i<list.Count() ; i++) {
|
||||
int time = reg.Get_Int(list[i].Peek_Buffer(), 0);
|
||||
if (time > 0 && time < 0xffff) {
|
||||
total += (unsigned long) time;
|
||||
num_times++;
|
||||
|
||||
if (time < lowest) {
|
||||
lowest = time;
|
||||
lowest_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_times) {
|
||||
int average_time = (int) (total / (unsigned) num_times);
|
||||
|
||||
/*
|
||||
** Pick one a little closer.
|
||||
*/
|
||||
average_time = average_time / 2;
|
||||
|
||||
/*
|
||||
** Find the server closest to the average time.
|
||||
*/
|
||||
int closest_index = -1;
|
||||
int closest_diff = 0x7fffffff;
|
||||
|
||||
for (i=0 ; i<list.Count() ; i++) {
|
||||
int time = reg.Get_Int(list[i].Peek_Buffer(), 0);
|
||||
if (time > 0 && time < 0xffff) {
|
||||
int diff = abs(time - average_time);
|
||||
if (diff < closest_diff) {
|
||||
|
||||
/*
|
||||
** Ignore the nearest server.
|
||||
*/
|
||||
if (i != lowest_index) {
|
||||
closest_diff = diff;
|
||||
closest_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closest_index != -1) {
|
||||
WWASSERT(closest_index >= 0);
|
||||
WWASSERT(closest_index < list.Count());
|
||||
strncpy(server_name_copy, list[closest_index].Peek_Buffer(), sizeof(server_name_copy));
|
||||
server_name_copy[sizeof(server_name_copy) - 1] = 0;
|
||||
server_name = (const char*) server_name_copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(server_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Check -- Check bandwidth. This is called from bandwidth thread. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:54PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void BandwidthCheckerClass::Check(void)
|
||||
{
|
||||
struct hostent *host;
|
||||
struct sockaddr_in address;
|
||||
int failure_code;
|
||||
|
||||
/*
|
||||
** If we are auto starting then just use the previous settings from the registry.
|
||||
*/
|
||||
if (AutoRestart.Is_Active()) {
|
||||
RegistryClass reg(APPLICATION_SUB_KEY_NAME_BANDTEST);
|
||||
int up = reg.Get_Int("Up", 0);
|
||||
int down = reg.Get_Int("Down", up);
|
||||
UpstreamBandwidth = up;
|
||||
DownstreamBandwidth = down;
|
||||
if (up) {
|
||||
GotBandwidth = true;
|
||||
SetEvent(EventNotify);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleBox.Print("Detecting bandwidth...\n");
|
||||
|
||||
const char *host_name = NULL;
|
||||
if (cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
// US West Ping server
|
||||
host_name = "159.153.192.10";
|
||||
} else {
|
||||
host_name = Get_Ping_Server_Name();
|
||||
}
|
||||
WWDEBUG_SAY(("BandwidthCheckerClass::Check -- Trying server %s\n", host_name));
|
||||
|
||||
host = gethostbyname(host_name);
|
||||
if (host == NULL) {
|
||||
host_name = DefaultServerName;
|
||||
WWDEBUG_SAY(("BandwidthCheckerClass::Check -- Trying server %s\n", host_name));
|
||||
host = gethostbyname(host_name);
|
||||
}
|
||||
|
||||
if (host == NULL) {
|
||||
/*
|
||||
** No DNS or no connection at all. Either way we are in trouble.
|
||||
*/
|
||||
WWDEBUG_SAY(("BandwidthCheckerClass - Unable to resolve host name\n"));
|
||||
ConsoleBox.Print("Unable to resolve host name for bandwidth check\n");
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
UpstreamBandwidth = 1000000;
|
||||
DownstreamBandwidth = 1000000;
|
||||
ReportedUpstreamBandwidth = 1000000;
|
||||
ReportedDownstreamBandwidth = 1000000;
|
||||
#else //FREEDEDICATEDSERVER
|
||||
UpstreamBandwidth = 55000;
|
||||
DownstreamBandwidth = 55000;
|
||||
ReportedUpstreamBandwidth = 57600;
|
||||
ReportedDownstreamBandwidth = 57600;
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
UpstreamBandwidthString = BandwidthNames[DEFAULT_BAND];
|
||||
DownstreamBandwidthString = BandwidthNames[DEFAULT_BAND];
|
||||
FailureCode = BANDTEST_NO_IP_DETECT;
|
||||
GotBandwidth = false;
|
||||
} else {
|
||||
|
||||
memcpy(&(address.sin_addr), host->h_addr, host->h_length);
|
||||
|
||||
/*
|
||||
** Init the settings for the detection.
|
||||
*/
|
||||
BandtestSettingsStruct settings = {
|
||||
0, //AlwaysICMP
|
||||
0, //TTLScatter
|
||||
50, //FastPingPackets
|
||||
12, //SlowPingPackets
|
||||
25, //Fast ping threshold
|
||||
0 //PingProfile
|
||||
};
|
||||
|
||||
/*
|
||||
** Call the .dll function to do the actual detection.
|
||||
*/
|
||||
UpstreamBandwidth = Detect_Bandwidth(ntohl(address.sin_addr.s_addr), 0, 2, failure_code, DownstreamBandwidth, BANDTEST_API_VERSION, &settings, APPLICATION_SUB_KEY_NAME_BANDTEST);
|
||||
|
||||
/*
|
||||
** If we failed due to a missing final ping then try again with fewer packets and no retries.
|
||||
*/
|
||||
if (UpstreamBandwidth == 0) {
|
||||
if (failure_code == BANDTEST_NO_FINAL_PING_TIME ||
|
||||
(cGameSpyAdmin::Is_Gamespy_Game() &&
|
||||
failure_code == BANDTEST_NO_EXTERNAL_ROUTER)) {
|
||||
BandtestSettingsStruct settings = {
|
||||
0, //AlwaysICMP
|
||||
0, //TTLScatter
|
||||
25, //FastPingPackets
|
||||
8, //SlowPingPackets
|
||||
25, //Fast ping threshold
|
||||
0 //PingProfile
|
||||
};
|
||||
|
||||
if (cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
// US East Ping server
|
||||
address.sin_addr.s_addr = inet_addr("159.153.224.10");
|
||||
}
|
||||
UpstreamBandwidth = Detect_Bandwidth(ntohl(address.sin_addr.s_addr), 0, 0, failure_code, DownstreamBandwidth, BANDTEST_API_VERSION, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If it's 0, we failed.
|
||||
*/
|
||||
if (UpstreamBandwidth == 0) {
|
||||
WWDEBUG_SAY(("Failed to get bandwidth - error code %s\n", ErrorList[failure_code]));
|
||||
/*
|
||||
** Default to 57600.
|
||||
*/
|
||||
#ifdef FREEDEDICATEDSERVER
|
||||
ConsoleBox.Print("Failed to get bandwidth - error code %s, Setting 1Mbps bandwidth\n", ErrorList[failure_code]);
|
||||
UpstreamBandwidth = 1000000;
|
||||
DownstreamBandwidth = 1000000;
|
||||
#else //FREEDEDICATEDSERVER
|
||||
if (cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
UpstreamBandwidth = 128000;
|
||||
DownstreamBandwidth = 128000;
|
||||
} else {
|
||||
UpstreamBandwidth = 55000;
|
||||
DownstreamBandwidth = 55000;
|
||||
}
|
||||
#endif //FREEDEDICATEDSERVER
|
||||
FailureCode = failure_code;
|
||||
GotBandwidth = true; //false;
|
||||
} else {
|
||||
GotBandwidth = true;
|
||||
}
|
||||
|
||||
/*
|
||||
** Fix up the upstream bandwidth into one of our connection type bands.
|
||||
*/
|
||||
if (UpstreamBandwidth > 0x7fffffff) {
|
||||
WWDEBUG_SAY(("Upstream bandwidth is huge :-)\n"));
|
||||
WWDEBUG_SAY(("Reported upstream connection bandwidth is > 4M bits per second\n"));
|
||||
UpstreamBandwidth = 4096000;
|
||||
ReportedUpstreamBandwidth = 4096000;
|
||||
UpstreamBandwidthString = BandwidthNames[NUM_BANDS];
|
||||
} else {
|
||||
if (UpstreamBandwidth > 100000) {
|
||||
#ifdef WWDEBUG
|
||||
float floater = (float)UpstreamBandwidth / 1024;
|
||||
#endif //WWDEBUG
|
||||
WWDEBUG_SAY(("Upstream bandwidth to external router is %.1f kilobits per second\n", floater));
|
||||
} else {
|
||||
WWDEBUG_SAY(("Upstream bandwidth to external router is %d bits per second\n", UpstreamBandwidth));
|
||||
}
|
||||
|
||||
bool got_bw_str = false;
|
||||
for (int i=0 ; i<NUM_BANDS ; i++) {
|
||||
if (UpstreamBandwidth < Bandwidths[(i*2) + 1]) {
|
||||
//WWDEBUG_SAY(("\nReported upstream connection bandwidth is %s bits per second\n", BandwidthNames[i]));
|
||||
UpstreamBandwidthString = BandwidthNames[i];
|
||||
ReportedUpstreamBandwidth = Bandwidths[(i*2)+1];
|
||||
got_bw_str = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!got_bw_str) {
|
||||
WWDEBUG_SAY(("\nReported upstream connection bandwidth is > 4M bits per second\n"));
|
||||
ReportedUpstreamBandwidth = 4096000;
|
||||
UpstreamBandwidthString = BandwidthNames[NUM_BANDS];
|
||||
}
|
||||
StringClass little_string;
|
||||
WideStringClass(UpstreamBandwidthString, true).Convert_To(little_string);
|
||||
|
||||
ConsoleBox.Print("Upstream bandwidth of %s bps detected\n", little_string.Peek_Buffer());
|
||||
}
|
||||
|
||||
/*
|
||||
** Fix up the downstream bandwidth into one of our connection type bands.
|
||||
*/
|
||||
if (DownstreamBandwidth > 0x7fffffff) {
|
||||
WWDEBUG_SAY(("Downstream bandwidth is huge :-)\n"));
|
||||
WWDEBUG_SAY(("Reported downstream connection bandwidth is > 4M bits per second\n"));
|
||||
DownstreamBandwidth = 4096000;
|
||||
ReportedDownstreamBandwidth = 4096000;
|
||||
DownstreamBandwidthString = BandwidthNames[NUM_BANDS];
|
||||
} else {
|
||||
if (DownstreamBandwidth > 100000) {
|
||||
#ifdef WWDEBUG
|
||||
float floater = (float)DownstreamBandwidth / 1024;
|
||||
#endif //WWDEBUG
|
||||
WWDEBUG_SAY(("Downstream bandwidth to external router is %.1f kilobits per second\n", floater));
|
||||
} else {
|
||||
WWDEBUG_SAY(("Downstream bandwidth to external router is %d bits per second\n", DownstreamBandwidth));
|
||||
}
|
||||
|
||||
bool got_bw_str = false;
|
||||
for (int i=0 ; i<NUM_BANDS ; i++) {
|
||||
if (DownstreamBandwidth < Bandwidths[(i*2) + 1]) {
|
||||
//WWDEBUG_SAY(("\nReported downstream connection bandwidth is %s bits per second\n", BandwidthNames[i]));
|
||||
DownstreamBandwidthString = BandwidthNames[i];
|
||||
ReportedDownstreamBandwidth = Bandwidths[(i*2)+1];
|
||||
got_bw_str = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!got_bw_str) {
|
||||
WWDEBUG_SAY(("\nReported downstream connection bandwidth is > 4M bits per second\n"));
|
||||
ReportedDownstreamBandwidth = 4096000;
|
||||
DownstreamBandwidthString = BandwidthNames[NUM_BANDS];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Testy.
|
||||
*/
|
||||
#ifdef _DEBUG
|
||||
PackedBandwidthType packed = Get_Packed_Bandwidth();
|
||||
WWDEBUG_SAY(("Packed bandwidth as string = %s\n", Get_Bandwidth_As_String(packed)));
|
||||
#endif //_DEBUG
|
||||
|
||||
}
|
||||
SetEvent(EventNotify);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Force_Upstream_Bandwidth -- Set actual upstream bandwidth *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Upstream bandwidth in buts per second *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:54PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void BandwidthCheckerClass::Force_Upstream_Bandwidth(unsigned int up)
|
||||
{
|
||||
WWASSERT(up);
|
||||
WWASSERT(cGameSpyAdmin::Is_Gamespy_Game());
|
||||
|
||||
UpstreamBandwidth = up;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Upstream_Bandwidth -- Get actual upstream bandwidth *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Upstream bandwidth in buts per second *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:54PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned long BandwidthCheckerClass::Get_Upstream_Bandwidth(void)
|
||||
{
|
||||
return(UpstreamBandwidth);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Reported_Upstream_Bandwidth -- Get reported up bandwidth *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Reported upstream bandwidth in bits per second *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:55PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned long BandwidthCheckerClass::Get_Reported_Upstream_Bandwidth(void)
|
||||
{
|
||||
return(ReportedUpstreamBandwidth);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Upstream_Bandwidth_As_String -- Human readable upsream bw *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to bandwidth string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:56PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned short *BandwidthCheckerClass::Get_Upstream_Bandwidth_As_String(void)
|
||||
{
|
||||
return(UpstreamBandwidthString);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Downstream_Bandwidth -- Get actual downstream bandwidth *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Actual down bw in bits per second *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:56PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned long BandwidthCheckerClass::Get_Downstream_Bandwidth(void)
|
||||
{
|
||||
return(DownstreamBandwidth);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Reported_Downstream_Bandwidth -- Get reported down bw *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Reported down bw in bits per second *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:57PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned long BandwidthCheckerClass::Get_Reported_Downstream_Bandwidth(void)
|
||||
{
|
||||
return(ReportedDownstreamBandwidth);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Downstream_Bandwidth_As_String -- Get down bw as a string *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to down bw string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:57PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned short *BandwidthCheckerClass::Get_Downstream_Bandwidth_As_String(void)
|
||||
{
|
||||
return(DownstreamBandwidthString);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Bandwidth_As_String -- Get bandwidth description string *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:58PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned short *BandwidthCheckerClass::Get_Bandwidth_As_String(void)
|
||||
{
|
||||
|
||||
if (cUserOptions::Get_Bandwidth_Type() == BANDWIDTH_AUTO) {
|
||||
static unsigned short _build_string[256];
|
||||
swprintf(_build_string, L"%s,%s", DownstreamBandwidthString, UpstreamBandwidthString);
|
||||
return(_build_string);
|
||||
} else {
|
||||
return((unsigned short*)cBandwidth::Get_Bandwidth_String_From_Type(
|
||||
(BANDWIDTH_TYPE_ENUM)cUserOptions::Get_Bandwidth_Type()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Bandwidth_As_String -- Get bandwidth description string *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Packed up/down bandwidth *
|
||||
* *
|
||||
* OUTPUT: Ptr to bandwidth description string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:58PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned short *BandwidthCheckerClass::Get_Bandwidth_As_String(PackedBandwidthType bandwidth)
|
||||
{
|
||||
static unsigned short _build_string[256];
|
||||
|
||||
assert(bandwidth.Bandwidth.Up < NUM_BANDS + 1);
|
||||
assert(bandwidth.Bandwidth.Down < NUM_BANDS + 1);
|
||||
|
||||
swprintf(_build_string, L"%s,%s", BandwidthNames[bandwidth.Bandwidth.Down], BandwidthNames[bandwidth.Bandwidth.Up]);
|
||||
return(_build_string);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Packed_Bandwidth -- Get bandwidth packed into a byte *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Bandwidth as a byte *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 2:59PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BandwidthCheckerClass::PackedBandwidthType BandwidthCheckerClass::Get_Packed_Bandwidth(void)
|
||||
{
|
||||
PackedBandwidthType bandwidth = {0,0};
|
||||
assert(sizeof(bandwidth) == 1);
|
||||
|
||||
unsigned long bwu = ReportedUpstreamBandwidth;
|
||||
unsigned long bwd = ReportedDownstreamBandwidth;
|
||||
bool automode = true;
|
||||
|
||||
if (cUserOptions::Get_Bandwidth_Type() != BANDWIDTH_AUTO) {
|
||||
bwu = cBandwidth::Get_Bandwidth_Bps_From_Type((BANDWIDTH_TYPE_ENUM)cUserOptions::Get_Bandwidth_Type());
|
||||
bwd = bwu;
|
||||
automode = false;
|
||||
}
|
||||
|
||||
/*
|
||||
** Just return 0s if we haven't detected bandwidth yet.
|
||||
*/
|
||||
if (!automode || UpstreamBandwidth != 0) {
|
||||
|
||||
for (int i=0 ; i<NUM_BANDS+1 ; i++) {
|
||||
if (bwu <= Bandwidths[(i*2)+1]) {
|
||||
bandwidth.Bandwidth.Up = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0 ; i<NUM_BANDS+1 ; i++) {
|
||||
if (bwd <= Bandwidths[(i*2)+1]) {
|
||||
bandwidth.Bandwidth.Down = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(bandwidth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthCheckerClass::Get_Compact_Log -- Get basic log information to send to server *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: String to add info to *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/4/2001 1:12PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void BandwidthCheckerClass::Get_Compact_Log(StringClass &log_string)
|
||||
{
|
||||
char temp[128];
|
||||
sprintf(temp, "%d\t%d\t%d\t", UpstreamBandwidth, DownstreamBandwidth, cUserOptions::Get_Bandwidth_Type());
|
||||
log_string = temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthDetectWait::Create -- Create the wait object for bandwidth detection *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ref Ptr to bandwidth wait *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 3:00PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
RefPtr<BandwidthDetectWait> BandwidthDetectWait::Create(void)
|
||||
{
|
||||
return (new BandwidthDetectWait());
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthDetectWait::BandwidthDetectWait -- BandwidthDetectWait constructor *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 3:22PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BandwidthDetectWait::BandwidthDetectWait(void) :
|
||||
SingleWait(TRANSLATE (IDS_MENU_TESTING_BANDWIDTH), 60000),
|
||||
mEvent(NULL),
|
||||
mPingsRemaining(0xffffffff)
|
||||
{
|
||||
if (!cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
WOLSession = WWOnline::Session::GetInstance(false);
|
||||
assert(WOLSession.IsValid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthDetectWait::~BandwidthDetectWait -- BandwidthDetectWait destructor *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 3:22PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BandwidthDetectWait::~BandwidthDetectWait()
|
||||
{
|
||||
WWDEBUG_SAY(("BandwidthDetectWait: End - %S\n", mEndText));
|
||||
|
||||
if (WOLSession.IsValid()) WOLSession->EnablePinging(true);
|
||||
|
||||
if (mEvent) {
|
||||
CloseHandle(mEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthDetectWait::WaitBeginning -- Called to init the wait *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 3:22PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void BandwidthDetectWait::WaitBeginning(void)
|
||||
{
|
||||
WWDEBUG_SAY(("BandwidthDetectWait: Beginning\n"));
|
||||
|
||||
mEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (mEvent == NULL) {
|
||||
WWDEBUG_SAY(("BandwidthDetectWait: Can't create event\n"));
|
||||
EndWait(Error, TRANSLATE (IDS_MENU_FAILED_TO_CREATE_BW_EVENT));
|
||||
} else {
|
||||
if (WOLSession.IsValid()) WOLSession->EnablePinging(false);
|
||||
mTimeout = 15000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BandwidthDetectWait::GetResult -- See if there is a result for the wait condition *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Result code *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/21/2001 3:23PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
WaitCondition::WaitResult BandwidthDetectWait::GetResult(void)
|
||||
{
|
||||
if (mEndResult == Waiting) {
|
||||
/*
|
||||
** Wait for pings to finish first.
|
||||
*/
|
||||
|
||||
unsigned int pingsWaiting = 0;
|
||||
if (!cGameSpyAdmin::Is_Gamespy_Game()) {
|
||||
pingsWaiting = WOLSession->GetPendingPingCount();
|
||||
}
|
||||
|
||||
|
||||
if (mPingsRemaining != pingsWaiting) {
|
||||
mPingsRemaining = pingsWaiting;
|
||||
if (mPingsRemaining == 0) {
|
||||
mTimeout = 60000;
|
||||
BandwidthCheckerClass::Check_Now(mEvent);
|
||||
}
|
||||
}
|
||||
|
||||
if (mPingsRemaining == 0) {
|
||||
DWORD result = WaitForSingleObject(mEvent, 0);
|
||||
|
||||
if (result == WAIT_OBJECT_0) {
|
||||
WWDEBUG_SAY(("BandwidthDetectWait: ConditionMet\n"));
|
||||
EndWait(ConditionMet, TRANSLATE (IDS_MENU_BW_DETECTION_COMPLETE));
|
||||
} else {
|
||||
if (result == WAIT_FAILED) {
|
||||
WWDEBUG_SAY(("BandwidthDetectWait: WAIT_FAILED\n"));
|
||||
EndWait(Error, TRANSLATE (IDS_MENU_BW_DETECTION_FAILED));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mEndResult != Waiting && WOLSession.IsValid()) {
|
||||
WOLSession->EnablePinging(true);
|
||||
}
|
||||
|
||||
return(mEndResult);
|
||||
}
|
||||
167
Code/Commando/bandwidthcheck.h
Normal file
167
Code/Commando/bandwidthcheck.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/bandwidthcheck.h $*
|
||||
* *
|
||||
* $Author:: Bhayes $*
|
||||
* *
|
||||
* $Modtime:: 2/18/02 9:33p $*
|
||||
* *
|
||||
* $Revision:: 9 $*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef _BANDWIDTHCHECK_H
|
||||
#define _BANDWIDTHCHECK_H
|
||||
|
||||
#include <WWOnline\WaitCondition.h>
|
||||
#include <wwlib\except.h>
|
||||
#include <windows.h>
|
||||
#include <BandTest\BandTest.h>
|
||||
|
||||
|
||||
namespace WWOnline {
|
||||
class Session;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class BandwidthCheckerClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
** Struct for packing bandwidth levels into a single byte.
|
||||
*/
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct tInternalPackedBandwidthType {
|
||||
unsigned char Up : 4;
|
||||
unsigned char Down : 4;
|
||||
} InternalPackedBandwidthType;
|
||||
|
||||
typedef union tPackedBandwidthType {
|
||||
InternalPackedBandwidthType Bandwidth;
|
||||
unsigned char RawBandwidth;
|
||||
} PackedBandwidthType;
|
||||
#pragma pack(pop)
|
||||
|
||||
static RefPtr<WaitCondition> Detect(void);
|
||||
static void Check_Now(HANDLE event);
|
||||
|
||||
static bool Got_Bandwidth(void) {return(GotBandwidth);};
|
||||
static void Force_Upstream_Bandwidth(unsigned int up);
|
||||
static unsigned long Get_Upstream_Bandwidth(void);
|
||||
static unsigned long Get_Reported_Upstream_Bandwidth(void);
|
||||
static unsigned short *Get_Upstream_Bandwidth_As_String(void);
|
||||
static unsigned long Get_Downstream_Bandwidth(void);
|
||||
static unsigned long Get_Reported_Downstream_Bandwidth(void);
|
||||
static unsigned short *Get_Downstream_Bandwidth_As_String(void);
|
||||
static unsigned short *Get_Bandwidth_As_String(void);
|
||||
static unsigned short *Get_Bandwidth_As_String(PackedBandwidthType bandwidth);
|
||||
static PackedBandwidthType Get_Packed_Bandwidth(void);
|
||||
static bool Failed_Due_To_No_Connection(void) {return(FailureCode == BANDTEST_NO_IP_DETECT);}
|
||||
static void Get_Compact_Log(StringClass &log_string);
|
||||
static bool Is_Thread_Running(void) { return Thread.Is_Running(); }
|
||||
|
||||
private:
|
||||
|
||||
static void Check(void);
|
||||
static const char *Get_Ping_Server_Name(void);
|
||||
|
||||
static class BandwidthCheckerThreadClass : public ThreadClass {
|
||||
public:
|
||||
BandwidthCheckerThreadClass(const char *thread_name = "Bandwidth checker thread") : ThreadClass(thread_name, &Exception_Handler) {}
|
||||
void Thread_Function(void) {BandwidthCheckerClass::Check();};
|
||||
} Thread;
|
||||
friend BandwidthCheckerThreadClass;
|
||||
|
||||
static HANDLE EventNotify;
|
||||
static unsigned long UpstreamBandwidth;
|
||||
static unsigned long ReportedUpstreamBandwidth;
|
||||
static unsigned long DownstreamBandwidth;
|
||||
static unsigned long ReportedDownstreamBandwidth;
|
||||
static unsigned short *UpstreamBandwidthString;
|
||||
static unsigned short *DownstreamBandwidthString;
|
||||
|
||||
#define NUM_BANDS 12
|
||||
|
||||
static char *ErrorList[13];
|
||||
static unsigned long Bandwidths[NUM_BANDS * 2];
|
||||
static unsigned short *BandwidthNames[NUM_BANDS + 1];
|
||||
static int FailureCode;
|
||||
static bool GotBandwidth;
|
||||
static const char *DefaultServerName;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Wait code for bandwidth detection.
|
||||
**
|
||||
**
|
||||
**
|
||||
*/
|
||||
class BandwidthDetectWait : public SingleWait
|
||||
{
|
||||
public:
|
||||
static RefPtr<BandwidthDetectWait> Create(void);
|
||||
|
||||
void WaitBeginning(void);
|
||||
WaitResult GetResult(void);
|
||||
|
||||
|
||||
protected:
|
||||
BandwidthDetectWait();
|
||||
virtual ~BandwidthDetectWait();
|
||||
|
||||
BandwidthDetectWait(const BandwidthDetectWait&);
|
||||
const BandwidthDetectWait& operator = (const BandwidthDetectWait&);
|
||||
|
||||
RefPtr<WWOnline::Session> WOLSession;
|
||||
unsigned int mPingsRemaining;
|
||||
HANDLE mEvent;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //_BANDWIDTHCHECK_H
|
||||
336
Code/Commando/bandwidthgraph.cpp
Normal file
336
Code/Commando/bandwidthgraph.cpp
Normal file
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
** 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/bandwidthgraph.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 1/02/02 2:29a $*
|
||||
* *
|
||||
* $Revision:: 9 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "bandwidthgraph.h"
|
||||
|
||||
#include "assets.h"
|
||||
#include "font3d.h"
|
||||
#include "render2d.h"
|
||||
#include "cnetwork.h"
|
||||
#include "devoptions.h"
|
||||
#include "packetmgr.h"
|
||||
#include "serversettings.h"
|
||||
#include "consolemode.h"
|
||||
|
||||
|
||||
//
|
||||
// Class statics
|
||||
//
|
||||
Render2DTextClass * cBandwidthGraph::PTextRenderer = NULL;
|
||||
Font3DInstanceClass * cBandwidthGraph::PFont = NULL;
|
||||
int cBandwidthGraph::BandwidthScaler = 50000;
|
||||
float cBandwidthGraph::YPosition = 0;
|
||||
float cBandwidthGraph::BarHeight = 0;
|
||||
float cBandwidthGraph::BarWidth = 0;
|
||||
float cBandwidthGraph::YIncrement = 0;
|
||||
|
||||
#define COLOR_BLACK 0xFF000000
|
||||
#define COLOR_WHITE 0xFFFFFFFF
|
||||
#define COLOR_RED 0xFFFF0000
|
||||
#define COLOR_GREEN 0xFF48FF48
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBandwidthGraph::Onetime_Init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
WWDEBUG_SAY(("cBandwidthGraph::Onetime_Init\n"));
|
||||
|
||||
bool can_render = ConsoleBox.Is_Exclusive() ? false : true;
|
||||
if (can_render) {
|
||||
WWASSERT(WW3DAssetManager::Get_Instance() != NULL);
|
||||
PFont = WW3DAssetManager::Get_Instance()->Get_Font3DInstance("FONT6x8.TGA");
|
||||
WWASSERT(PFont != NULL);
|
||||
PFont->Set_Mono_Spaced();
|
||||
SET_REF_OWNER(PFont);
|
||||
|
||||
PTextRenderer = new Render2DTextClass(PFont);
|
||||
PTextRenderer->Set_Coordinate_Range(Render2DClass::Get_Screen_Resolution());
|
||||
|
||||
BarWidth = Render2DClass::Get_Screen_Resolution().Width() / 10.0f;
|
||||
BarHeight = PTextRenderer->Peek_Font()->Char_Height();
|
||||
YIncrement = BarHeight * 1.25f;
|
||||
}
|
||||
// This needs to be done somewhere else - we need a good value whether we have the graph or not.
|
||||
//PacketManager.Set_Stats_Sampling_Frequency_Delay(1000);
|
||||
//PacketManager.Set_Stats_Sampling_Frequency_Delay(250);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBandwidthGraph::Onetime_Shutdown
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
WWDEBUG_SAY(("cBandwidthGraph::Onetime_Close\n"));
|
||||
if (PTextRenderer != NULL)
|
||||
{
|
||||
delete PTextRenderer;
|
||||
PTextRenderer = NULL;
|
||||
}
|
||||
|
||||
if (PFont != NULL)
|
||||
{
|
||||
PFont->Release_Ref();
|
||||
PFont = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBandwidthGraph::Bandwidth_Graph
|
||||
(
|
||||
StringClass & label,
|
||||
int bps,
|
||||
int target_bps,
|
||||
float bandwidth_multiplier,
|
||||
float average_priority,
|
||||
bool is_loading
|
||||
)
|
||||
{
|
||||
if (PTextRenderer == NULL) {
|
||||
return;
|
||||
}
|
||||
WWASSERT(PTextRenderer != NULL);
|
||||
|
||||
float x1 = 0;
|
||||
float x2 = bps / (float) BandwidthScaler * BarWidth;
|
||||
float y1 = YPosition;
|
||||
float y2 = y1 + BarHeight;
|
||||
|
||||
//
|
||||
// Bandwidth used (graph)
|
||||
//
|
||||
PTextRenderer->Draw_Block(RectClass(x1, y1, x2, y2), COLOR_RED);
|
||||
PTextRenderer->Set_Location(Vector2(2, YPosition));
|
||||
PTextRenderer->Draw_Text(label);
|
||||
|
||||
//
|
||||
// Bandwidth used (text)
|
||||
//
|
||||
StringClass text;
|
||||
text.Format("%d", bps);
|
||||
PTextRenderer->Set_Location(Vector2(200, YPosition));
|
||||
PTextRenderer->Draw_Text(text);
|
||||
|
||||
//
|
||||
// Bandwidth budgeted (text)
|
||||
//
|
||||
if (target_bps >= 0)
|
||||
{
|
||||
StringClass text;
|
||||
text.Format("%d", target_bps);
|
||||
PTextRenderer->Set_Location(Vector2(245, YPosition));
|
||||
PTextRenderer->Draw_Text(text);
|
||||
float target_x = target_bps / (float) BandwidthScaler * BarWidth;
|
||||
PTextRenderer->Draw_Block(RectClass(target_x - 1, y1, target_x + 1, y2));
|
||||
}
|
||||
|
||||
//
|
||||
// Bandwidth multiplier and average object priority
|
||||
//
|
||||
if (bandwidth_multiplier >= 0.0f)
|
||||
{
|
||||
//
|
||||
// Graph mark
|
||||
//
|
||||
//float tp = threshold_priority * Render2DClass::Get_Screen_Resolution().Width();
|
||||
//PTextRenderer->Draw_Block(RectClass(tp - 1, y1, tp + 1, y2), COLOR_GREEN);
|
||||
|
||||
//
|
||||
// Text
|
||||
//
|
||||
// Bandwidth multiplier
|
||||
if (is_loading) {
|
||||
text.Format("BM:%-8.6f Ld", bandwidth_multiplier);
|
||||
} else {
|
||||
text.Format("BM:%-8.6f", bandwidth_multiplier);
|
||||
}
|
||||
PTextRenderer->Set_Location(Vector2(400, YPosition));
|
||||
PTextRenderer->Draw_Text(text);
|
||||
|
||||
// Average object priority on this client
|
||||
text.Format("AP:%-8.6f", average_priority);
|
||||
PTextRenderer->Set_Location(Vector2(500, YPosition));
|
||||
PTextRenderer->Draw_Text(text);
|
||||
|
||||
}
|
||||
|
||||
YPosition += YIncrement;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBandwidthGraph::Think
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
bool bail = true;
|
||||
|
||||
#ifdef WWDEBUG
|
||||
if (cDevOptions::ShowBandwidth.Is_True())
|
||||
{
|
||||
bail = false;
|
||||
}
|
||||
#endif // WWDEBUG
|
||||
|
||||
if (bail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PacketManager.Update_Stats();
|
||||
|
||||
if (PTextRenderer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
WWASSERT(PTextRenderer != NULL);
|
||||
|
||||
PTextRenderer->Reset();
|
||||
|
||||
//
|
||||
// Draw the scale at the top
|
||||
//
|
||||
YPosition = 50;
|
||||
|
||||
float x1 = 0;
|
||||
float x2 = 0;
|
||||
float y1 = YPosition;
|
||||
float y2 = y1 + BarHeight;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
x2 = x1 + BarWidth;
|
||||
PTextRenderer->Draw_Block(RectClass(x1, y1, x2, y2), (i % 2) ? COLOR_WHITE : COLOR_BLACK);
|
||||
x1 = x2;
|
||||
i++;
|
||||
} while (x2 < Render2DClass::Get_Screen_Resolution().Width());
|
||||
|
||||
//
|
||||
// Label the scale
|
||||
//
|
||||
StringClass text;
|
||||
text.Format("BW / %d", BandwidthScaler);
|
||||
PTextRenderer->Set_Location(Vector2(2, YPosition - 10));
|
||||
PTextRenderer->Draw_Text(text);
|
||||
|
||||
YPosition += YIncrement;
|
||||
|
||||
DWORD bps = 0;
|
||||
DWORD target_bps = 0;
|
||||
|
||||
//
|
||||
// Client bandwidth
|
||||
//
|
||||
if (cNetwork::I_Am_Client() && cNetwork::PClientConnection->Is_Established())
|
||||
{
|
||||
text.Format("c%d->s", cNetwork::Get_My_Id());
|
||||
bps = PacketManager.Get_Compressed_Bandwidth_Out(&cNetwork::Get_Client_Rhost()->Get_Address());
|
||||
target_bps = cNetwork::Get_Client_Rhost()->Get_Target_Bps();
|
||||
Bandwidth_Graph(text, bps, target_bps, -1.0f, -1.0f, false); //cNetwork::Get_Client_Rhost()->Get_Threshold_Priority());
|
||||
|
||||
text.Format("c%d<-s", cNetwork::Get_My_Id());
|
||||
bps = PacketManager.Get_Compressed_Bandwidth_In(&cNetwork::Get_Client_Rhost()->Get_Address());
|
||||
Bandwidth_Graph(text, bps, -1, -1, -1.0f, false);
|
||||
}
|
||||
|
||||
//
|
||||
// Server bandwidth
|
||||
//
|
||||
if (cNetwork::PServerConnection != NULL)
|
||||
{
|
||||
text.Format("s->c*");
|
||||
bps = PacketManager.Get_Total_Compressed_Bandwidth_Out();
|
||||
target_bps = cNetwork::PServerConnection->Get_Bandwidth_Budget_Out();
|
||||
Bandwidth_Graph(text, bps, target_bps, -1, -1.0f, false);
|
||||
|
||||
text.Format("s<-c*");
|
||||
bps = PacketManager.Get_Total_Compressed_Bandwidth_In();
|
||||
Bandwidth_Graph(text, bps, -1, -1, -1.0f, false);
|
||||
|
||||
for (int i = cNetwork::PServerConnection->Get_Min_RHost(); i <= cNetwork::PServerConnection->Get_Max_RHost(); i++)
|
||||
{
|
||||
cRemoteHost * p_rhost = cNetwork::Get_Server_Rhost(i);
|
||||
|
||||
if (p_rhost != NULL)
|
||||
{
|
||||
bool is_loading = p_rhost->Get_Flood();
|
||||
text.Format("s->c%d", i);
|
||||
bps = PacketManager.Get_Compressed_Bandwidth_Out(&p_rhost->Get_Address());
|
||||
target_bps = p_rhost->Get_Target_Bps();
|
||||
Bandwidth_Graph(text, bps, target_bps, p_rhost->Get_Bandwidth_Multiplier(), p_rhost->Get_Average_Priority(), is_loading);
|
||||
|
||||
text.Format("s<-c%d", i);
|
||||
bps = PacketManager.Get_Compressed_Bandwidth_In(&p_rhost->Get_Address());
|
||||
Bandwidth_Graph(text, bps, -1, -1, -1.0f, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBandwidthGraph::Render
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
bool bail = true;
|
||||
|
||||
#ifdef WWDEBUG
|
||||
if (cDevOptions::ShowBandwidth.Is_True())
|
||||
{
|
||||
bail = false;
|
||||
}
|
||||
#endif // WWDEBUG
|
||||
|
||||
if (bail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (PTextRenderer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
WWASSERT(PTextRenderer != NULL);
|
||||
PTextRenderer->Render();
|
||||
}
|
||||
73
Code/Commando/bandwidthgraph.h
Normal file
73
Code/Commando/bandwidthgraph.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
** 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/bandwidthgraph.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 10/26/01 12:45p $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __BANDWIDTHGRAPH_H__
|
||||
#define __BANDWIDTHGRAPH_H__
|
||||
|
||||
#include "bittype.h"
|
||||
#include "wwstring.h"
|
||||
|
||||
class Render2DTextClass;
|
||||
class Font3DInstanceClass;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class cBandwidthGraph
|
||||
{
|
||||
public:
|
||||
static void Onetime_Init(void);
|
||||
static void Onetime_Shutdown(void);
|
||||
|
||||
static void Think(void);
|
||||
static void Render(void);
|
||||
|
||||
static void Set_Scale(int scale) {BandwidthScaler = scale;}
|
||||
|
||||
private:
|
||||
static void Bandwidth_Graph(StringClass & label, int bps,
|
||||
int target_bps, float bandwidth_multiplier, float average_priority, bool is_loading);
|
||||
|
||||
static Render2DTextClass * PTextRenderer;
|
||||
static Font3DInstanceClass * PFont;
|
||||
static int BandwidthScaler;
|
||||
static float YPosition;
|
||||
static float BarHeight;
|
||||
static float BarWidth;
|
||||
static float YIncrement;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __BANDWIDTHGRAPH_H__
|
||||
235
Code/Commando/bioevent.cpp
Normal file
235
Code/Commando/bioevent.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
** 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/bioevent.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 2/20/02 11:01p $*
|
||||
* *
|
||||
* $Revision:: 26 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "bioevent.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "networkobjectfactory.h"
|
||||
#include "cnetwork.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "evictionevent.h"
|
||||
#include "playermanager.h"
|
||||
#include "god.h"
|
||||
#include "gametype.h"
|
||||
#include "apppackettypes.h"
|
||||
#include "gamedataupdateevent.h"
|
||||
#include "consolemode.h"
|
||||
#include "winevent.h"
|
||||
#include "gamespyadmin.h"
|
||||
|
||||
DECLARE_NETWORKOBJECT_FACTORY(cBioEvent, NETCLASSID_BIOEVENT);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
cBioEvent::cBioEvent(void) :
|
||||
SenderId(0),
|
||||
TeamChoice(-1),
|
||||
ClanID(0)
|
||||
{
|
||||
Set_App_Packet_Type(APPPACKETTYPE_BIOEVENT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBioEvent::Init(int teamChoice, unsigned long clanID)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
SenderId = cNetwork::Get_My_Id();
|
||||
Nickname = cNetInterface::Get_Nickname();
|
||||
TeamChoice = teamChoice;
|
||||
ClanID = clanID;
|
||||
|
||||
strcpy(MapName, The_Game()->Get_Map_Name().Peek_Buffer());
|
||||
|
||||
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
|
||||
|
||||
if (cNetwork::I_Am_Server()) {
|
||||
Act();
|
||||
} else {
|
||||
Set_Object_Dirty_Bit(0, BIT_CREATION, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBioEvent::Act(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
//
|
||||
// This is where we validate a player. If we don't want him to play,
|
||||
// for whichever reason, after learning all about him, evict him here.
|
||||
// Note that the server has already seen the player name in
|
||||
// cNetwork::Application_Acceptance_Handler.
|
||||
// Now the server will see additional data.
|
||||
//
|
||||
|
||||
bool is_accepted = true;
|
||||
EvictionCodeEnum eviction_code = EVICTION_POOR_BANDWIDTH;
|
||||
|
||||
if (is_accepted) {
|
||||
//
|
||||
// Tell the new guy about all existing players
|
||||
//
|
||||
for (SLNode<cPlayer> * player_node = cPlayerManager::Get_Player_Object_List()->Head();
|
||||
player_node;
|
||||
player_node = player_node->Next()) {
|
||||
|
||||
cPlayer * p_player = player_node->Data();
|
||||
WWASSERT(p_player != NULL);
|
||||
|
||||
cNetwork::Send_Object_Update(p_player, SenderId);
|
||||
}
|
||||
|
||||
//GAMESPY
|
||||
if (cGameSpyAdmin::Is_Gamespy_Game() &&
|
||||
cGameSpyAdmin::Is_Nickname_Collision(Nickname)) {
|
||||
|
||||
WideStringClass new_nickname;
|
||||
int count = 1;
|
||||
do {
|
||||
new_nickname.Format(L"%s(%d)", Nickname, count++);
|
||||
} while (cGameSpyAdmin::Is_Nickname_Collision(new_nickname));
|
||||
|
||||
Nickname = new_nickname;
|
||||
}
|
||||
|
||||
cPlayer * p_player = cGod::Create_Player(SenderId, Nickname, TeamChoice, ClanID);
|
||||
WWASSERT(p_player != NULL);
|
||||
|
||||
if (!IS_SOLOPLAY) {
|
||||
//
|
||||
// Record his IP address for diagnostic purposes
|
||||
//
|
||||
WWASSERT(cNetwork::Get_Server_Rhost(SenderId) != NULL);
|
||||
SOCKADDR_IN & address = cNetwork::Get_Server_Rhost(SenderId)->Get_Address();
|
||||
p_player->Set_Ip_Address(address.sin_addr.s_addr);
|
||||
|
||||
//
|
||||
// Tell the remote host object to expect a lot of temporary extra bandwidth.
|
||||
//
|
||||
if (cNetwork::PServerConnection != NULL) {
|
||||
cNetwork::PServerConnection->Set_Rhost_Expect_Packet_Flood(p_player->Get_Id(), true);
|
||||
}
|
||||
|
||||
//
|
||||
// Update him about any dynamic game data parameters.
|
||||
//
|
||||
WWDEBUG_SAY(("BioEvent acting\n"));
|
||||
cGameDataUpdateEvent * p_event = new cGameDataUpdateEvent();
|
||||
p_event->Init(p_player->Get_Id());
|
||||
|
||||
StringClass str(128, true);
|
||||
Nickname.Convert_To(str);
|
||||
ConsoleBox.Print_Maybe("Player %s joined the game\n", str.Peek_Buffer());
|
||||
|
||||
//
|
||||
// If we (the server) are already in intermission mode then deactivate the player until the next map starts. The player
|
||||
// will have already loaded the next map. ST - 1/17/2002 7:43PM
|
||||
//
|
||||
if (The_Game()->IsIntermission.Is_True()) {
|
||||
|
||||
//
|
||||
// If the new player has the old map loaded (which can happen if the intermission starts after the client has
|
||||
// started loading the old map) then send him a wineven so he knows to load the next map.
|
||||
//
|
||||
if (stricmp(MapName, The_Game()->Get_Map_Name().Peek_Buffer()) != 0) {
|
||||
cWinEvent * p_win = new cWinEvent;
|
||||
p_win->Init(The_Game()->Get_Winner_ID(), SenderId, The_Game()->Is_Map_Cycle_Over());
|
||||
cNetwork::Send_Object_Update(p_win, SenderId);
|
||||
} else {
|
||||
p_player->Set_Is_In_Game(false);
|
||||
p_player->Set_Is_Waiting_For_Intermission(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
cEvictionEvent * p_event = new cEvictionEvent;
|
||||
p_event->Init(SenderId, eviction_code);
|
||||
|
||||
cNetwork::Flush();
|
||||
|
||||
cNetwork::Server_Kill_Connection(SenderId);
|
||||
}
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBioEvent::Export_Creation(BitStreamClass & packet)
|
||||
{
|
||||
cNetEvent::Export_Creation(packet);
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
packet.Add(SenderId);
|
||||
packet.Add_Wide_Terminated_String(Nickname);
|
||||
packet.Add(TeamChoice);
|
||||
packet.Add(ClanID);
|
||||
packet.Add_Terminated_String(MapName, false);
|
||||
|
||||
WWDEBUG_SAY(("cBioEvent sent\n"));
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cBioEvent::Import_Creation(BitStreamClass & packet)
|
||||
{
|
||||
cNetEvent::Import_Creation(packet);
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
packet.Get(SenderId);
|
||||
packet.Get_Wide_Terminated_String(Nickname.Get_Buffer(256), 256, true);
|
||||
packet.Get(TeamChoice);
|
||||
packet.Get(ClanID);
|
||||
|
||||
packet.Get_Terminated_String(MapName, sizeof(MapName), false);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
WWDEBUG_SAY(("cBioEvent recd\n"));
|
||||
|
||||
Act();
|
||||
}
|
||||
74
Code/Commando/bioevent.h
Normal file
74
Code/Commando/bioevent.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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/bioevent.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 1/18/02 1:23p $*
|
||||
* *
|
||||
* $Revision:: 11 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __BIOEVENT_H__
|
||||
#define __BIOEVENT_H__
|
||||
|
||||
#include "netevent.h"
|
||||
#include "netclassids.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A C->S mirrored event object for transmitting initial player bio data.
|
||||
//
|
||||
class cBioEvent : public cNetEvent
|
||||
{
|
||||
public:
|
||||
cBioEvent(void);
|
||||
|
||||
void Init(int team_choice, unsigned long clanID);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass &packet);
|
||||
virtual void Import_Creation(BitStreamClass &packet);
|
||||
|
||||
virtual uint32 Get_Network_Class_ID(void) const {return NETCLASSID_BIOEVENT;}
|
||||
|
||||
private:
|
||||
|
||||
virtual void Act(void);
|
||||
|
||||
int SenderId;
|
||||
WideStringClass Nickname;
|
||||
char MapName[256];
|
||||
int TeamChoice;
|
||||
unsigned long ClanID;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __BIOEVENT_H__
|
||||
|
||||
|
||||
50
Code/Commando/boolean.h
Normal file
50
Code/Commando/boolean.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
** 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: boolean.h
|
||||
// Author: Tom Spencer-Smith
|
||||
// Date: Nov 1999
|
||||
// Description:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(_MSV_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOLEAN_H
|
||||
#define BOOLEAN_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class cBoolean
|
||||
{
|
||||
public:
|
||||
cBoolean(bool value = false) {Value = value;}
|
||||
bool Toggle(void) {Value = !Value; return Value;}
|
||||
bool Set(bool value) {Value = value; return Value;}
|
||||
bool Get(void) const {return Value;}
|
||||
bool Is_True(void) const {return Value == true;}
|
||||
bool Is_False(void) const {return Value == false;}
|
||||
|
||||
private:
|
||||
|
||||
bool Value;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#endif // BOOLEAN_H
|
||||
317
Code/Commando/buildnum.cpp
Normal file
317
Code/Commando/buildnum.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Combat *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/buildnum.cpp $*
|
||||
* *
|
||||
* Author:: Steve Tall *
|
||||
* *
|
||||
* $Modtime:: 10/29/01 10:06p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "always.h"
|
||||
#include "buildnum.h"
|
||||
#include "wwdebug.h"
|
||||
#include <stdio.h>
|
||||
#include "win.h"
|
||||
|
||||
/*
|
||||
**
|
||||
** This is just a placeholder for the build number.
|
||||
** A post build step will stamp the build number into here.
|
||||
**
|
||||
*/
|
||||
char BuildInfoClass::BuildNumber [64] = {"Insert1Build2Number3Here4 xxxx "};
|
||||
char BuildInfoClass::BuildDate [64] = {"Insert1Build2Date3Here4 xxxx "};
|
||||
|
||||
/*
|
||||
** Unreachable code warning.
|
||||
*/
|
||||
#pragma warning(disable : 4702)
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Build_Number -- Gets the 32 bit build number. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Build number *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 4:54PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
unsigned long BuildInfoClass::Get_Build_Number(void)
|
||||
{
|
||||
return (*(unsigned long*)(&BuildNumber[28]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Build_Number_String -- Gets the build number as a human readable string.*
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to build number string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 4:55PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Get_Build_Number_String(void)
|
||||
{
|
||||
static char _buffer[16];
|
||||
sprintf (_buffer, "%d", *(unsigned long*)(&BuildNumber[28]));
|
||||
return (_buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Builder_Name -- Gets the name of the person who built this executable. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to builder name string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 5:08PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Get_Builder_Name(void)
|
||||
{
|
||||
return(&BuildNumber[32]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Build_Date_String -- Gets the date this executable was built on. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to build date string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 5:10PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Get_Build_Date_String(void)
|
||||
{
|
||||
static char _buffer[64];
|
||||
SYSTEMTIME systime;
|
||||
|
||||
if (FileTimeToSystemTime ((LPFILETIME)(&BuildDate[28]), &systime) ) {
|
||||
sprintf(_buffer, "%02d/%02d/%04d - %02d:%02d:%02d", systime.wMonth, systime.wDay, systime.wYear, systime.wHour, systime.wMinute, systime.wSecond);
|
||||
} else {
|
||||
_buffer[0] = 0;
|
||||
}
|
||||
|
||||
return(_buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Builder_Initials -- Gets the initials of the builder *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to string containing initials *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 5:12PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Get_Builder_Initials(void)
|
||||
{
|
||||
static char _buffer[4];
|
||||
|
||||
_buffer[0] = BuildNumber[32];
|
||||
_buffer[1] = 0;
|
||||
_buffer[2] = 0;
|
||||
|
||||
char *lastname = strchr(&BuildNumber[32], '_');
|
||||
if (lastname) {
|
||||
_buffer[1] = lastname[1];
|
||||
}
|
||||
return (_buffer);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Build_Version_String -- Get composite version as string *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Version string *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 7:30PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Get_Build_Version_String(void)
|
||||
{
|
||||
static char _buffer[128];
|
||||
sprintf(_buffer, "%s-%s", Get_Builder_Initials(), Get_Build_Number_String());
|
||||
return(_buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Build_Type -- Get the type of build this is *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Build type *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 7:40PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BuildInfoClass::BuildType BuildInfoClass::Get_Build_Type(void)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
#ifdef WWDEBUG
|
||||
return(BUILD_PROFILE);
|
||||
#else //WWDEBUG
|
||||
return(BUILD_RELEASE);
|
||||
#endif //WWDEBUG
|
||||
#else //_DEBUG
|
||||
return(BUILD_DEBUG);
|
||||
#endif //_DEBUG
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Get_Build_Type_String -- Get the build type as a string. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 7:42PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Get_Build_Type_String(void)
|
||||
{
|
||||
switch (Get_Build_Type()) {
|
||||
case BUILD_DEBUG:
|
||||
return("DEBUG");
|
||||
|
||||
case BUILD_RELEASE:
|
||||
return("RELEASE");
|
||||
|
||||
case BUILD_PROFILE:
|
||||
return("PROFILE");
|
||||
|
||||
default:
|
||||
WWASSERT(false);
|
||||
return("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Composite_Build_Info -- Get lots of build info *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Ptr to info *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 7:49PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
char *BuildInfoClass::Composite_Build_Info(void)
|
||||
{
|
||||
static char _buffer[256];
|
||||
sprintf(_buffer, "%s Build %d by %s - Build time %s", Get_Build_Type_String(), Get_Build_Number(), Get_Builder_Name(), Get_Build_Date_String());
|
||||
return(_buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BuildInfoClass::Log_Build_Info -- Dump build info to the logfile. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/29/2001 7:49PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void BuildInfoClass::Log_Build_Info(void)
|
||||
{
|
||||
WWDEBUG_SAY((Composite_Build_Info()));
|
||||
WWDEBUG_SAY(("\n"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
112
Code/Commando/buildnum.h
Normal file
112
Code/Commando/buildnum.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Combat *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Commando/buildnum.h $*
|
||||
* *
|
||||
* Author:: Steve Tall *
|
||||
* *
|
||||
* $Modtime:: 10/29/01 9:58p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/*
|
||||
**
|
||||
** This is just a placeholder for the build number.
|
||||
** A post build step will stamp the build number into here.
|
||||
**
|
||||
*/
|
||||
class BuildInfoClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
** Build types.
|
||||
*/
|
||||
typedef enum {
|
||||
BUILD_RELEASE,
|
||||
BUILD_DEBUG,
|
||||
BUILD_PROFILE
|
||||
} BuildType;
|
||||
|
||||
/*
|
||||
** Gets the 32 bit build number.
|
||||
*/
|
||||
static unsigned long Get_Build_Number(void);
|
||||
|
||||
/*
|
||||
** Gets the 32 bit build number as a human readable string.
|
||||
*/
|
||||
static char *Get_Build_Number_String(void);
|
||||
|
||||
/*
|
||||
** Gets the name of the person who built this executable.
|
||||
*/
|
||||
static char *Get_Builder_Name(void);
|
||||
|
||||
/*
|
||||
** Gets the date this executable was built on.
|
||||
*/
|
||||
static char *Get_Build_Date_String(void);
|
||||
|
||||
/*
|
||||
** Gets the initials of the person who built this executable.
|
||||
*/
|
||||
static char *Get_Builder_Initials(void);
|
||||
|
||||
/*
|
||||
** Get a composite build number string with the works.
|
||||
*/
|
||||
static char *Get_Build_Version_String(void);
|
||||
|
||||
/*
|
||||
** Get build type.
|
||||
*/
|
||||
static BuildType Get_Build_Type(void);
|
||||
static char *Get_Build_Type_String(void);
|
||||
|
||||
/*
|
||||
** Dump build info to the log file
|
||||
*/
|
||||
static void Log_Build_Info(void);
|
||||
|
||||
/*
|
||||
** Lots of build info together.
|
||||
*/
|
||||
static char *Composite_Build_Info(void);
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
static char BuildNumber [64];
|
||||
static char BuildDate [64];
|
||||
};
|
||||
|
||||
|
||||
|
||||
471
Code/Commando/campaign.cpp
Normal file
471
Code/Commando/campaign.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
** 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/campaign.cpp $*
|
||||
* *
|
||||
* $Author:: Ian_l $*
|
||||
* *
|
||||
* $Modtime:: 1/19/02 12:30p $*
|
||||
* *
|
||||
* $Revision:: 33 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "campaign.h"
|
||||
#include "debug.h"
|
||||
#include "gamemode.h"
|
||||
#include "gamedata.h"
|
||||
#include "singlepl.h"
|
||||
#include "gdsingleplayer.h"
|
||||
#include "cnetwork.h"
|
||||
#include "playertype.h"
|
||||
#include "gameinitmgr.h"
|
||||
#include "scorescreen.h"
|
||||
#include "assets.h"
|
||||
#include "movie.h"
|
||||
#include "consolefunction.h"
|
||||
#include "renegadedialogmgr.h"
|
||||
#include "registry.h"
|
||||
#include "_globals.h"
|
||||
#include "crandom.h"
|
||||
#include "god.h"
|
||||
#include "dlgloadspgame.h"
|
||||
#include "ccamera.h"
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
int CampaignManager::State = 0;
|
||||
int CampaignManager::BackdropIndex = 0;
|
||||
|
||||
#define CAMPAIGN_INI_FILENAME "campaign.ini"
|
||||
#define SECTION_CAMPAIGN "Campaign"
|
||||
#define NOT_IN_CAMPAIGN_STATE -10
|
||||
#define REPLAY_LEVEL -11
|
||||
#define REPLAY_SCORE -12
|
||||
|
||||
DynamicVectorClass<StringClass> CampaignFlowDescriptions;
|
||||
|
||||
struct BackdropDescriptionStruct {
|
||||
int State;
|
||||
DynamicVectorClass<StringClass> Lines;
|
||||
|
||||
bool operator == (BackdropDescriptionStruct const & rec) const { return false; }
|
||||
bool operator != (BackdropDescriptionStruct const & rec) const { return true; }
|
||||
};
|
||||
|
||||
DynamicVectorClass<BackdropDescriptionStruct> BackdropDescriptions;
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
void CampaignManager::Init( void )
|
||||
{
|
||||
State = NOT_IN_CAMPAIGN_STATE;
|
||||
BackdropIndex = 0;
|
||||
|
||||
// Load CAMPAIGN.INI to get campain flow
|
||||
INIClass * campaignINI = Get_INI( CAMPAIGN_INI_FILENAME );
|
||||
if (campaignINI != NULL) {
|
||||
WWASSERT( campaignINI && campaignINI->Section_Count() > 0 );
|
||||
int count = campaignINI->Entry_Count( SECTION_CAMPAIGN );
|
||||
for ( int entry = 0; entry < count; entry++ ) {
|
||||
StringClass description(0,true);
|
||||
campaignINI->Get_String(description, SECTION_CAMPAIGN, campaignINI->Get_Entry( SECTION_CAMPAIGN, entry) );
|
||||
CampaignFlowDescriptions.Add( description );
|
||||
}
|
||||
|
||||
// Load Backdrop Descriptions
|
||||
// Load the first 100, because 90-95 are multiplay.. :)
|
||||
for ( int state = 0; state < 100; state++ ) {
|
||||
StringClass section_name;
|
||||
section_name.Format( "Backdrop%d", state );
|
||||
int count = campaignINI->Entry_Count( section_name );
|
||||
if ( count != 0 ) {
|
||||
int index = BackdropDescriptions.Count();
|
||||
BackdropDescriptions.Uninitialized_Add();
|
||||
BackdropDescriptions[index].State = state;
|
||||
for ( int entry = 0; entry < count; entry++ ) {
|
||||
StringClass description(0,true);
|
||||
campaignINI->Get_String(description, section_name, campaignINI->Get_Entry( section_name, entry) );
|
||||
BackdropDescriptions[index].Lines.Add( description );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Release_INI( campaignINI );
|
||||
} else {
|
||||
Debug_Say(("CampaignManager::Init - Unable to load %s\n", CAMPAIGN_INI_FILENAME));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
void CampaignManager::Shutdown( void )
|
||||
{
|
||||
CampaignFlowDescriptions.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
enum {
|
||||
CHUNKID_VARIABLES = 906011356,
|
||||
|
||||
MICROCHUNK_STATE = 1,
|
||||
MICROCHUNK_BACKDROP_INDEX,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CampaignManager::Save(ChunkSaveClass & csave)
|
||||
{
|
||||
csave.Begin_Chunk(CHUNKID_VARIABLES);
|
||||
WRITE_MICRO_CHUNK(csave, MICROCHUNK_STATE, State);
|
||||
WRITE_MICRO_CHUNK(csave, MICROCHUNK_BACKDROP_INDEX, BackdropIndex);
|
||||
csave.End_Chunk();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CampaignManager::Load(ChunkLoadClass &cload)
|
||||
{
|
||||
while (cload.Open_Chunk()) {
|
||||
switch(cload.Cur_Chunk_ID()) {
|
||||
|
||||
case CHUNKID_VARIABLES:
|
||||
while (cload.Open_Micro_Chunk()) {
|
||||
switch(cload.Cur_Micro_Chunk_ID()) {
|
||||
READ_MICRO_CHUNK(cload, MICROCHUNK_STATE, State);
|
||||
READ_MICRO_CHUNK(cload, MICROCHUNK_BACKDROP_INDEX, BackdropIndex);
|
||||
default:
|
||||
Debug_Say(( "Unrecognized Campaign Variable chunkID\n" ));
|
||||
break;
|
||||
}
|
||||
cload.Close_Micro_Chunk();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug_Say(( "Unrecognized campaign chunkID\n" ));
|
||||
break;
|
||||
}
|
||||
cload.Close_Chunk();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
void CampaignManager::Start_Campaign( int difficulty )
|
||||
{
|
||||
Debug_Say(( "CampaignManager::Start_Campaign( %d )\n", difficulty ));
|
||||
|
||||
State = -1;
|
||||
BackdropIndex = 0;
|
||||
|
||||
// Why was this commented out???
|
||||
CombatManager::Set_Difficulty_Level( difficulty );
|
||||
|
||||
StringClass diff_string;
|
||||
diff_string.Format( "difficulty %d", difficulty );
|
||||
ConsoleFunctionManager::Parse_Input( diff_string );
|
||||
|
||||
cGod::Reset_Inventory();
|
||||
|
||||
Continue();
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
void CampaignManager::Continue( bool success )
|
||||
{
|
||||
BackdropIndex = 0;
|
||||
|
||||
if ( State == REPLAY_LEVEL ) {
|
||||
State = REPLAY_SCORE;
|
||||
|
||||
// Activeate the Score screen before the combat deactivates, so we can get the stats
|
||||
ScoreScreenGameModeClass * ss = (ScoreScreenGameModeClass *)GameModeManager::Find ("ScoreScreen");
|
||||
if ( ss != NULL ) {
|
||||
ss->Save_Stats();
|
||||
}
|
||||
|
||||
GameModeManager::Find ("Movie")->Deactivate();
|
||||
GameModeManager::Find ("Combat")->Suspend();
|
||||
GameInitMgrClass::End_Game();
|
||||
GameModeManager::Find ("Menu")->Deactivate();
|
||||
|
||||
if ( ss != NULL ) {
|
||||
ss->Activate();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( State == NOT_IN_CAMPAIGN_STATE || State == REPLAY_SCORE || ( State >= CampaignFlowDescriptions.Count() - 1 ) ) {
|
||||
State = NOT_IN_CAMPAIGN_STATE;
|
||||
GameModeManager::Find ("Movie")->Deactivate();
|
||||
GameModeManager::Find ("ScoreScreen")->Deactivate(); // BMG???
|
||||
GameModeManager::Find ("Combat")->Suspend();
|
||||
GameInitMgrClass::End_Game();
|
||||
GameInitMgrClass::Display_End_Game_Menu();
|
||||
return;
|
||||
}
|
||||
|
||||
State = State+1;
|
||||
|
||||
Debug_Say(( "CampaignManager::Continue %d\n", State ));
|
||||
|
||||
const char * state_description = CampaignFlowDescriptions[State];
|
||||
|
||||
#define StringMatch(a,b) (!::strncmp( a,b,strlen(b) ))
|
||||
|
||||
if ( StringMatch( state_description, "Message " ) ) {
|
||||
|
||||
state_description += ::strlen( "Message " );
|
||||
|
||||
GameModeManager::Find ("Movie")->Deactivate();
|
||||
GameModeManager::Find ("Combat")->Suspend();
|
||||
GameInitMgrClass::End_Game();
|
||||
|
||||
GameModeManager::Find ("Menu")->Deactivate();
|
||||
GameModeManager::Find ("ScoreScreen")->Activate();
|
||||
|
||||
} else if ( StringMatch( state_description, "Score" ) ) {
|
||||
|
||||
state_description += ::strlen( "Score" );
|
||||
|
||||
// Activeate the Score screen before the combat deactivates, so we can get the stats
|
||||
ScoreScreenGameModeClass * ss = (ScoreScreenGameModeClass *)GameModeManager::Find ("ScoreScreen");
|
||||
if ( ss != NULL ) {
|
||||
ss->Save_Stats();
|
||||
}
|
||||
|
||||
GameModeManager::Find ("Movie")->Deactivate();
|
||||
GameModeManager::Find ("Combat")->Suspend();
|
||||
GameInitMgrClass::End_Game();
|
||||
GameModeManager::Find ("Menu")->Deactivate();
|
||||
|
||||
if ( ss != NULL ) {
|
||||
ss->Activate();
|
||||
}
|
||||
|
||||
} else if ( StringMatch( state_description, "Level " ) ) {
|
||||
|
||||
|
||||
GameModeManager::Find ("Combat")->Suspend();
|
||||
GameModeManager::Find ("Movie")->Deactivate();
|
||||
GameModeManager::Find ("ScoreScreen")->Deactivate ();
|
||||
|
||||
GameInitMgrClass::End_Game();
|
||||
|
||||
state_description += ::strlen( "Level " );
|
||||
|
||||
int mission = cGameData::Get_Mission_Number_From_Map_Name( state_description );
|
||||
Select_Backdrop_Number( mission );
|
||||
GameInitMgrClass::Start_Game ( state_description, PLAYERTYPE_RENEGADE, 0 );
|
||||
|
||||
// Hack to not autosave for Mission 0 (M13)
|
||||
if ( ::strnicmp( state_description, "M13", 3 ) != 0 ) {
|
||||
CombatManager::Request_Autosave();
|
||||
}
|
||||
|
||||
} else if ( StringMatch( state_description, "Movie " ) ) {
|
||||
|
||||
if (COMBAT_CAMERA != NULL) {
|
||||
COMBAT_CAMERA->Set_Host_Model (NULL);
|
||||
}
|
||||
|
||||
GameModeManager::Find ("Combat")->Suspend();
|
||||
GameInitMgrClass::End_Game();
|
||||
GameModeManager::Find ("Menu")->Deactivate();
|
||||
GameModeManager::Find ("ScoreScreen")->Deactivate ();
|
||||
|
||||
//
|
||||
// Parse the parameters
|
||||
//
|
||||
int len = ::strlen( state_description );
|
||||
StringClass foo( len + 1, true );
|
||||
StringClass filename( len + 1, true );
|
||||
StringClass description( len + 1, true );
|
||||
::sscanf (state_description, "%s %s %s", foo.Peek_Buffer (), filename.Peek_Buffer (), description.Peek_Buffer ());
|
||||
|
||||
MovieGameModeClass * mode = (MovieGameModeClass *)GameModeManager::Find ("Movie");
|
||||
if ( mode ) {
|
||||
mode->Activate();
|
||||
mode->Start_Movie( filename );
|
||||
|
||||
//
|
||||
// Add this movie name to the registry (that way the user
|
||||
// can watch it later)
|
||||
//
|
||||
RegistryClass registry( APPLICATION_SUB_KEY_NAME_MOVIES );
|
||||
if ( registry.Is_Valid() ) {
|
||||
registry.Set_String( filename, description );
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
Debug_Say(( "Failed to Parse Campaign Description %s\n", state_description ));
|
||||
|
||||
State = NOT_IN_CAMPAIGN_STATE;
|
||||
RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_MAIN_MENU);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CampaignManager::Reset()
|
||||
{
|
||||
State = NOT_IN_CAMPAIGN_STATE;
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
void CampaignManager::Replay_Level( const char * mission_name, int difficulty )
|
||||
{
|
||||
State = REPLAY_LEVEL;
|
||||
|
||||
cGod::Reset_Inventory();
|
||||
CombatManager::Set_Difficulty_Level( difficulty );
|
||||
|
||||
GameInitMgrClass::Start_Game( mission_name, PLAYERTYPE_RENEGADE, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
int CampaignManager::Get_Backdrop_Description_Count( void )
|
||||
{
|
||||
if (BackdropDescriptions.Count() > 0) {
|
||||
return BackdropDescriptions[BackdropIndex].Lines.Count();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * CampaignManager::Get_Backdrop_Description( int index )
|
||||
{
|
||||
return BackdropDescriptions[BackdropIndex].Lines[index];
|
||||
}
|
||||
|
||||
void CampaignManager::Select_Backdrop_Number( int state_number )
|
||||
{
|
||||
// Find Backdrop Index
|
||||
BackdropIndex = 0;
|
||||
for ( int i = 0; i < BackdropDescriptions.Count(); i++ ) {
|
||||
if ( BackdropDescriptions[i].State == state_number ) {
|
||||
BackdropIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( BackdropIndex == 0 ) {
|
||||
Debug_Say(( "Failed to find load menu for state %d\n", state_number ));
|
||||
}
|
||||
}
|
||||
|
||||
void CampaignManager::Select_Backdrop_Number_By_MP_Type( int type )
|
||||
{
|
||||
//
|
||||
// Setup Load Menu
|
||||
//
|
||||
/*
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_DEATHMATCH 91
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_TEAM_DEATHMATCH 92
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_CTF 93
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_CNC1 94
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_CNC2 95
|
||||
int load_menu_number = 0;
|
||||
if ( type == cGameData::GAME_TYPE_DEATHMATCH ) {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_DEATHMATCH;
|
||||
}
|
||||
if ( type == cGameData::GAME_TYPE_TEAM_DEATHMATCH ) {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_TEAM_DEATHMATCH;
|
||||
}
|
||||
if ( type == cGameData::GAME_TYPE_CNC ) {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_CNC1;
|
||||
if ( FreeRandom.Get_Int() & 1 ) {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_CNC2;
|
||||
}
|
||||
}
|
||||
Select_Backdrop_Number( load_menu_number );
|
||||
*/
|
||||
|
||||
WWASSERT(type == cGameData::GAME_TYPE_CNC);
|
||||
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_CNC1 94
|
||||
#define MULTIPLAY_LOAD_MENU_NUMBER_CNC2 95
|
||||
|
||||
int load_menu_number = 0;
|
||||
if (FreeRandom.Get_Int() & 1) {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_CNC1;
|
||||
} else {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_CNC2;
|
||||
}
|
||||
|
||||
// Select_Backdrop_Number(load_menu_number);
|
||||
//forget the random screen, alwayds do 94 (BMG 11/24/01)
|
||||
Select_Backdrop_Number( MULTIPLAY_LOAD_MENU_NUMBER_CNC1 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if ( type == cGameData::GAME_TYPE_CTF ) {
|
||||
load_menu_number = MULTIPLAY_LOAD_MENU_NUMBER_CTF;
|
||||
}
|
||||
*/
|
||||
79
Code/Commando/campaign.h
Normal file
79
Code/Commando/campaign.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
** 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/campaign.h $*
|
||||
* *
|
||||
* $Author:: Byon_g $*
|
||||
* *
|
||||
* $Modtime:: 12/01/01 12:02p $*
|
||||
* *
|
||||
* $Revision:: 8 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef CAMPAIGN_H
|
||||
#define CAMPAIGN_H
|
||||
|
||||
#ifndef ALWAYS_H
|
||||
#include "always.h"
|
||||
#endif
|
||||
|
||||
class ChunkSaveClass;
|
||||
class ChunkLoadClass;
|
||||
|
||||
/*
|
||||
** CampaignManager is responsible for controlling the flow of missions and sub-states through
|
||||
** the playing of a campaign. It also is the main entry point for single mission, and multi-play sessions.
|
||||
*/
|
||||
class CampaignManager {
|
||||
|
||||
public:
|
||||
static void Init( void );
|
||||
static void Shutdown( void );
|
||||
|
||||
static bool Save(ChunkSaveClass & csave);
|
||||
static bool Load(ChunkLoadClass &cload);
|
||||
|
||||
static void Start_Campaign( int difficulty );
|
||||
static void Continue( bool success = true );
|
||||
|
||||
static void Reset();
|
||||
|
||||
// Backdrop Descriptions
|
||||
static int Get_Backdrop_Description_Count( void );
|
||||
static const char * Get_Backdrop_Description( int index );
|
||||
|
||||
static void Select_Backdrop_Number( int state_number );
|
||||
static void Select_Backdrop_Number_By_MP_Type( int type );
|
||||
|
||||
static void Replay_Level( const char * mission_name, int difficulty );
|
||||
|
||||
private:
|
||||
static int State;
|
||||
static int BackdropIndex;
|
||||
};
|
||||
|
||||
#endif
|
||||
194
Code/Commando/cdverify.cpp
Normal file
194
Code/Commando/cdverify.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : commando *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/commando/cdverify.cpp $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 1/03/02 9:57a $*
|
||||
* *
|
||||
* $Revision:: 7 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "always.h"
|
||||
#include "cdverify.h"
|
||||
#include "wwstring.h"
|
||||
#include "popupdialog.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Local constants
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
static const char *RENEGADE_MOVIES_VOLUME = "Renegade Data";
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDVerifyDialogClass
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
class CDVerifyDialogClass : public PopupDialogClass
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Public constructors/destructors
|
||||
////////////////////////////////////////////////////////////////
|
||||
CDVerifyDialogClass (void) :
|
||||
Object (NULL),
|
||||
PopupDialogClass (IDD_CDVERIFY) {}
|
||||
|
||||
void On_Command (int ctrl_id, int mesage_id, DWORD param);
|
||||
void Set_Object (CDVerifyClass *object) { Object = object; }
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
////////////////////////////////////////////////////////////////
|
||||
CDVerifyClass * Object;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_CD_Path
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
CDVerifyClass::Get_CD_Path (StringClass &drive_path)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
char buffer[1024] = { 0 };
|
||||
::GetLogicalDriveStrings (sizeof (buffer), buffer);
|
||||
|
||||
//
|
||||
// Loop over all the drives
|
||||
//
|
||||
const char *drive_root_name = buffer;
|
||||
while (drive_root_name[0] != 0) {
|
||||
|
||||
//
|
||||
// Only check CD drives
|
||||
//
|
||||
if (::GetDriveType (drive_root_name) == DRIVE_CDROM) {
|
||||
|
||||
//
|
||||
// Get the name of this volume
|
||||
//
|
||||
char volume_name[256] = { 0 };
|
||||
if (::GetVolumeInformation (drive_root_name, volume_name, sizeof (volume_name),
|
||||
NULL, NULL, NULL, NULL, NULL))
|
||||
{
|
||||
int cmp_len = ::lstrlen (volume_name);
|
||||
cmp_len = max (cmp_len, 11);
|
||||
|
||||
//
|
||||
// Is this the movies CD?
|
||||
//
|
||||
if (::strnicmp (volume_name, RENEGADE_MOVIES_VOLUME, cmp_len) == 0) {
|
||||
retval = true;
|
||||
drive_path = drive_root_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Advance to the next drive
|
||||
//
|
||||
drive_root_name += ::lstrlen (drive_root_name) + 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_CD_Path
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CDVerifyClass::Display_UI (Observer<CDVerifyEvent> *observer)
|
||||
{
|
||||
AddObserver (*observer);
|
||||
|
||||
//
|
||||
// Display the dialog
|
||||
//
|
||||
CDVerifyDialogClass *dialog = new CDVerifyDialogClass;
|
||||
dialog->Set_Object (this);
|
||||
dialog->Start_Dialog ();
|
||||
REF_PTR_RELEASE (dialog);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// On_Command
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CDVerifyDialogClass::On_Command (int ctrl_id, int message_id, DWORD param)
|
||||
{
|
||||
//
|
||||
// Check to see if the CD is in the drive now...
|
||||
///
|
||||
if (ctrl_id == IDOK) {
|
||||
StringClass path;
|
||||
if (Object->Get_CD_Path (path)) {
|
||||
|
||||
//
|
||||
// Notify anybody who cares that the CD is in the drive
|
||||
//
|
||||
CDVerifyEvent event (CDVerifyEvent::VERIFIED, Object);
|
||||
Object->NotifyObservers (event);
|
||||
|
||||
//
|
||||
// Close the dialog
|
||||
//
|
||||
End_Dialog ();
|
||||
}
|
||||
} else if (ctrl_id == IDCANCEL) {
|
||||
|
||||
//
|
||||
// Notify anybody who cares that the user has cancelled the operation
|
||||
//
|
||||
CDVerifyEvent event (CDVerifyEvent::NOT_VERIFIED, Object);
|
||||
Object->NotifyObservers (event);
|
||||
|
||||
//
|
||||
// Close the dialog
|
||||
//
|
||||
End_Dialog ();
|
||||
}
|
||||
|
||||
PopupDialogClass::On_Command (ctrl_id, message_id, param);
|
||||
return ;
|
||||
}
|
||||
129
Code/Commando/cdverify.h
Normal file
129
Code/Commando/cdverify.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : commando *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/commando/cdverify.h $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 9/19/01 9:22a $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef __CDVERIFY_H
|
||||
#define __CDVERIFY_H
|
||||
|
||||
#include "notify.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class StringClass;
|
||||
class CDVerifyClass;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDVerifyEvent
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class CDVerifyEvent : public TypedEventPtr<CDVerifyEvent, CDVerifyClass>
|
||||
{
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Public constants
|
||||
///////////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
NOT_VERIFIED = 0,
|
||||
VERIFIED,
|
||||
} EventID;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Public constructors/destructors
|
||||
///////////////////////////////////////////////////////////////////
|
||||
CDVerifyEvent (EventID event, CDVerifyClass *object) :
|
||||
TypedEventPtr<CDVerifyEvent, CDVerifyClass>(object),
|
||||
MyEventID (event) {}
|
||||
|
||||
~CDVerifyEvent (void) {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Inherited
|
||||
//
|
||||
inline EventID Event (void) const { return MyEventID; }
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
///////////////////////////////////////////////////////////////////
|
||||
EventID MyEventID;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CDVerifyClass
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class CDVerifyClass : public Notifier<CDVerifyEvent>
|
||||
{
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Public constructors/destructors
|
||||
///////////////////////////////////////////////////////////////////
|
||||
CDVerifyClass (void) {}
|
||||
~CDVerifyClass (void) {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Get_CD_Path (StringClass &drive_path);
|
||||
void Display_UI (Observer<CDVerifyEvent> *observer);
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Private member data
|
||||
///////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
|
||||
#endif //__CDVERIFY_H
|
||||
233
Code/Commando/changeteamevent.cpp
Normal file
233
Code/Commando/changeteamevent.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
** 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/changeteamevent.cpp $*
|
||||
* *
|
||||
* $Author:: Patrick $*
|
||||
* *
|
||||
* $Modtime:: 1/17/02 3:30p $*
|
||||
* *
|
||||
* $Revision:: 22 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "changeteamevent.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "networkobjectfactory.h"
|
||||
#include "cnetwork.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "playertype.h"
|
||||
#include "playermanager.h"
|
||||
#include "gamemode.h"
|
||||
#include "gamedata.h"
|
||||
#include "gameobjmanager.h"
|
||||
#include "spawn.h"
|
||||
#include "apppackettypes.h"
|
||||
#include "sctextobj.h"
|
||||
#include "translatedb.h"
|
||||
#include "string_ids.h"
|
||||
#include "c4.h"
|
||||
#include "beacongameobj.h"
|
||||
#include "weaponview.h"
|
||||
|
||||
|
||||
DECLARE_NETWORKOBJECT_FACTORY(cChangeTeamEvent, NETCLASSID_CHANGETEAMEVENT);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
cChangeTeamEvent::cChangeTeamEvent(void)
|
||||
{
|
||||
SenderId = 0;
|
||||
|
||||
Set_App_Packet_Type(APPPACKETTYPE_CHANGETEAMEVENT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cChangeTeamEvent::Init(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
SenderId = cNetwork::Get_My_Id();
|
||||
|
||||
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
|
||||
|
||||
if (cNetwork::I_Am_Server()) {
|
||||
Act();
|
||||
} else {
|
||||
Set_Object_Dirty_Bit(0, BIT_CREATION, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cChangeTeamEvent::Act(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cPlayer * p_player = cPlayerManager::Find_Player(SenderId);
|
||||
|
||||
if (p_player != NULL &&
|
||||
The_Game() != NULL &&
|
||||
//The_Game()->Is_Team_Game() &&
|
||||
(The_Game()->IsTeamChangingAllowed.Is_True() || p_player->Invulnerable.Is_True()))
|
||||
{
|
||||
int team = p_player->Get_Player_Type();
|
||||
|
||||
WWASSERT(team == PLAYERTYPE_NOD || team == PLAYERTYPE_GDI);
|
||||
|
||||
int new_team = PLAYERTYPE_NOD;
|
||||
|
||||
if (team == PLAYERTYPE_NOD)
|
||||
{
|
||||
new_team = PLAYERTYPE_GDI;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_team = PLAYERTYPE_NOD;
|
||||
}
|
||||
|
||||
p_player->Set_Player_Type(new_team);
|
||||
|
||||
WWDEBUG_SAY(("Client %d changed team.\n", SenderId));
|
||||
|
||||
//
|
||||
// Only reset the player's cash if they've changed teams after 60 seconds
|
||||
// have elapsed.
|
||||
//
|
||||
DWORD playing_time = (TIMEGETTIME() - p_player->Get_Join_Time ());
|
||||
if (playing_time > 30000) {
|
||||
p_player->Set_Score(0);
|
||||
p_player->Set_Money(0);
|
||||
}
|
||||
|
||||
SoldierGameObj * p_soldier = GameObjManager::Find_Soldier_Of_Client_ID(SenderId);
|
||||
if (p_soldier != NULL)
|
||||
{
|
||||
|
||||
if ( COMBAT_STAR == p_soldier ) {
|
||||
WeaponViewClass::Reset();
|
||||
}
|
||||
|
||||
// Defuse all C4 belonging to this guy
|
||||
SLNode<BaseGameObj> *objnode;
|
||||
for ( objnode = GameObjManager::Get_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
|
||||
PhysicalGameObj *obj = objnode->Data()->As_PhysicalGameObj();
|
||||
if ( obj && obj->As_C4GameObj() ) {
|
||||
if ( obj->As_C4GameObj()->Get_Owner() == p_soldier ) {
|
||||
obj->As_C4GameObj()->Defuse();
|
||||
}
|
||||
}
|
||||
if ( obj && obj->As_BeaconGameObj() ) {
|
||||
if ( obj->As_BeaconGameObj()->Get_Owner() == p_soldier ) {
|
||||
// disarm C4
|
||||
OffenseObjectClass unused (0.0F, 0);
|
||||
obj->As_BeaconGameObj()->Completely_Damaged( unused );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// We have to respawn him and possibly change his model...
|
||||
// let's just destroy the soldier and leave the rest up to God.
|
||||
//
|
||||
p_soldier->Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//
|
||||
// Tell everyone
|
||||
//
|
||||
WideStringClass text;
|
||||
//text.Format(L"_%s_changed_teams!_", p_player->Get_Name());
|
||||
text.Format(L"%s %s", p_player->Get_Name(), TRANSLATE(IDS_MP_CHANGED_TEAMS));
|
||||
|
||||
cScTextObj * p_message = new cScTextObj;
|
||||
p_message->Init(text, TEXT_MESSAGE_PUBLIC, false, HOST_TEXT_SENDER, -1);
|
||||
}
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cChangeTeamEvent::Export_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
cNetEvent::Export_Creation(packet);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
packet.Add(SenderId);
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cChangeTeamEvent::Import_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cNetEvent::Import_Creation(packet);
|
||||
|
||||
packet.Get(SenderId);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
Act();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
cChangeTeamEvent::Is_Change_Team_Possible(void)
|
||||
{
|
||||
return
|
||||
cNetwork::I_Am_Client() &&
|
||||
GameModeManager::Find("Combat") != NULL &&
|
||||
GameModeManager::Find("Combat")->Is_Active() &&
|
||||
The_Game() != NULL &&
|
||||
//The_Game()->Is_Team_Game() &&
|
||||
The_Game()->IsTeamChangingAllowed.Is_True();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
70
Code/Commando/changeteamevent.h
Normal file
70
Code/Commando/changeteamevent.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
** 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/changeteamevent.h $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 9/21/01 2:42p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __CHANGETEAMEVENT_H__
|
||||
#define __CHANGETEAMEVENT_H__
|
||||
|
||||
#include "netevent.h"
|
||||
#include "netclassids.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A C->S mirrored object for player changing team
|
||||
//
|
||||
class cChangeTeamEvent : public cNetEvent
|
||||
{
|
||||
public:
|
||||
cChangeTeamEvent(void);
|
||||
|
||||
void Init(void);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass &packet);
|
||||
virtual void Import_Creation(BitStreamClass &packet);
|
||||
|
||||
virtual uint32 Get_Network_Class_ID(void) const {return NETCLASSID_CHANGETEAMEVENT;}
|
||||
|
||||
static bool Is_Change_Team_Possible(void);
|
||||
|
||||
private:
|
||||
|
||||
virtual void Act(void);
|
||||
|
||||
int SenderId;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __CHANGETEAMEVENT_H__
|
||||
3576
Code/Commando/chat.rc
Normal file
3576
Code/Commando/chat.rc
Normal file
File diff suppressed because it is too large
Load Diff
56
Code/Commando/chatshre.cpp
Normal file
56
Code/Commando/chatshre.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
** 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: chatshre.cpp
|
||||
// Project: Network.lib, for Commando
|
||||
// Author: Tom Spencer-Smith
|
||||
// Date: Dec 1998
|
||||
// Description:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "chatshre.h"
|
||||
|
||||
#include "wwdebug.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define ADD_CASE(exp) case exp: return #exp; break;
|
||||
LPCSTR Translate_Location(ChatLocationEnum location)
|
||||
{
|
||||
switch (location) {
|
||||
|
||||
ADD_CASE(WOLLOC_EXIT);
|
||||
ADD_CASE(WOLLOC_NOLIST);
|
||||
ADD_CASE(WOLLOC_LOBBYLIST);
|
||||
ADD_CASE(WOLLOC_LOBBY);
|
||||
ADD_CASE(WOLLOC_GAMESLIST);
|
||||
ADD_CASE(WOLLOC_GAMEDATA);
|
||||
ADD_CASE(WOLLOC_INGAME);
|
||||
|
||||
ADD_CASE(LANLOC_EXIT);
|
||||
ADD_CASE(LANLOC_LOBBY);
|
||||
ADD_CASE(LANLOC_GAMESLIST);
|
||||
ADD_CASE(LANLOC_GAMEDATA);
|
||||
ADD_CASE(LANLOC_INGAME);
|
||||
|
||||
default:
|
||||
WWASSERT(0);
|
||||
return ""; // to avoid compiler warning
|
||||
}
|
||||
}
|
||||
65
Code/Commando/chatshre.h
Normal file
65
Code/Commando/chatshre.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
** 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: chatshre.h
|
||||
// Project: Network.lib, for Commando
|
||||
// Author: Tom Spencer-Smith
|
||||
// Date: Dec 1998
|
||||
// Description:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined(_MSV_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef CHATSHRE_H
|
||||
#define CHATSHRE_H
|
||||
|
||||
#include "bittype.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
enum ChatLocationEnum {
|
||||
|
||||
//
|
||||
// Wol interface
|
||||
//
|
||||
WOLLOC_EXIT,
|
||||
WOLLOC_NOLIST,
|
||||
WOLLOC_LOBBYLIST,
|
||||
WOLLOC_LOBBY,
|
||||
WOLLOC_GAMESLIST,
|
||||
WOLLOC_GAMEDATA,
|
||||
WOLLOC_INGAME,
|
||||
|
||||
//
|
||||
// Lan interface
|
||||
//
|
||||
LANLOC_EXIT,
|
||||
LANLOC_LOBBY,
|
||||
LANLOC_GAMESLIST,
|
||||
LANLOC_GAMEDATA,
|
||||
LANLOC_INGAME,
|
||||
};
|
||||
|
||||
LPCSTR Translate_Location(ChatLocationEnum location);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // CHATSHRE_H
|
||||
|
||||
126
Code/Commando/clientbboevent.cpp
Normal file
126
Code/Commando/clientbboevent.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
** 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/clientbboevent.cpp $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 11/27/01 3:12p $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "clientbboevent.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "networkobjectfactory.h"
|
||||
#include "cnetwork.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "gameobjmanager.h"
|
||||
#include "apppackettypes.h"
|
||||
|
||||
|
||||
DECLARE_NETWORKOBJECT_FACTORY(cClientBboEvent, NETCLASSID_CLIENTBBOEVENT);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
cClientBboEvent::cClientBboEvent(void)
|
||||
{
|
||||
SenderId = 0;
|
||||
Bbo = 0;
|
||||
|
||||
Set_App_Packet_Type(APPPACKETTYPE_CLIENTBBOEVENT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientBboEvent::Init(int bbo)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
//WWASSERT(bbo > 0);
|
||||
|
||||
SenderId = cNetwork::Get_My_Id();
|
||||
Bbo = bbo;
|
||||
|
||||
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
|
||||
|
||||
if (cNetwork::I_Am_Server()) {
|
||||
Act();
|
||||
} else {
|
||||
Set_Object_Dirty_Bit(0, BIT_CREATION, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientBboEvent::Act(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cRemoteHost * p_rhost = cNetwork::Get_Server_Rhost(SenderId);
|
||||
if (p_rhost != NULL) {
|
||||
p_rhost->Set_Maximum_Bps(Bbo);
|
||||
WWDEBUG_SAY(("Client %d adjusted bbo to %d.\n", SenderId, Bbo));
|
||||
}
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientBboEvent::Export_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
cNetEvent::Export_Creation(packet);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
WWASSERT(Bbo > 0);
|
||||
|
||||
packet.Add(SenderId);
|
||||
packet.Add(Bbo);
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientBboEvent::Import_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cNetEvent::Import_Creation(packet);
|
||||
|
||||
packet.Get(SenderId);
|
||||
packet.Get(Bbo);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
WWASSERT(Bbo > 0);
|
||||
|
||||
Act();
|
||||
}
|
||||
69
Code/Commando/clientbboevent.h
Normal file
69
Code/Commando/clientbboevent.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
** 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/clientbboevent.h $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 9/21/01 2:42p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __CLIENTBBOEVENT_H__
|
||||
#define __CLIENTBBOEVENT_H__
|
||||
|
||||
#include "netevent.h"
|
||||
#include "netclassids.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A C->S mirrored object for client bandwidth adjustment
|
||||
//
|
||||
class cClientBboEvent : public cNetEvent
|
||||
{
|
||||
public:
|
||||
cClientBboEvent(void);
|
||||
|
||||
void Init(int bbo);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass &packet);
|
||||
virtual void Import_Creation(BitStreamClass &packet);
|
||||
|
||||
virtual uint32 Get_Network_Class_ID(void) const {return NETCLASSID_CLIENTBBOEVENT;}
|
||||
|
||||
private:
|
||||
|
||||
virtual void Act(void);
|
||||
|
||||
int SenderId;
|
||||
int Bbo;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __CLIENTBBOEVENT_H__
|
||||
150
Code/Commando/clientfps.cpp
Normal file
150
Code/Commando/clientfps.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
** 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/clientfps.cpp $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 9/20/01 11:28a $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "clientfps.h"
|
||||
|
||||
#include "networkobjectfactory.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "cnetwork.h"
|
||||
#include "playermanager.h"
|
||||
#include "apppackettypes.h"
|
||||
|
||||
|
||||
CClientFps * PClientFps = NULL;
|
||||
|
||||
DECLARE_NETWORKOBJECT_FACTORY(CClientFps, NETCLASSID_CLIENTFPS);
|
||||
|
||||
#pragma message("(TSS) high priority for me to fix this CClientFps bug...")
|
||||
//
|
||||
// TSS2001 problem: destruction of this object on the server. Quitting and rejoining
|
||||
// a game will crash the server.
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CClientFps::CClientFps(void)
|
||||
{
|
||||
ClientId = -1;
|
||||
Fps = 0;
|
||||
|
||||
Set_App_Packet_Type(APPPACKETTYPE_CLIENTFPS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CClientFps::~CClientFps(void)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Init(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
ClientId = cNetwork::Get_My_Id();
|
||||
|
||||
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
|
||||
|
||||
Set_Object_Dirty_Bit(0, NetworkObjectClass::BIT_CREATION, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Set_Fps(int fps)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
WWASSERT(fps >= 0);
|
||||
|
||||
Fps = (BYTE) fps;
|
||||
|
||||
Set_Object_Dirty_Bit(0, NetworkObjectClass::BIT_FREQUENT, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Act(void)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cPlayer * p_player = cPlayerManager::Find_Player(ClientId);
|
||||
if (p_player != NULL)
|
||||
{
|
||||
p_player->Set_Fps(Fps);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Export_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
NetworkObjectClass::Export_Creation(packet);
|
||||
|
||||
packet.Add(ClientId);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Import_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
NetworkObjectClass::Import_Creation(packet);
|
||||
|
||||
packet.Get(ClientId);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Export_Frequent(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
packet.Add(Fps);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
CClientFps::Import_Frequent(BitStreamClass & packet)
|
||||
{
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
packet.Get(Fps);
|
||||
|
||||
Act();
|
||||
}
|
||||
|
||||
80
Code/Commando/clientfps.h
Normal file
80
Code/Commando/clientfps.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
** 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/clientfps.h $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 9/18/01 5:12p $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __CLIENTFPS_H__
|
||||
#define __CLIENTFPS_H__
|
||||
|
||||
#include "networkobject.h"
|
||||
#include "netclassids.h"
|
||||
//#include "control.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A C-S mirrored object to inform server of client framerate
|
||||
//
|
||||
class CClientFps : public NetworkObjectClass
|
||||
{
|
||||
public:
|
||||
|
||||
CClientFps();
|
||||
~CClientFps();
|
||||
|
||||
void Init(void);
|
||||
virtual uint32 Get_Network_Class_ID(void) const {return NETCLASSID_CLIENTFPS;}
|
||||
virtual void Delete(void) {delete this;}
|
||||
|
||||
void Set_Fps(int fps);
|
||||
void Act(void);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass &packet);
|
||||
virtual void Import_Creation(BitStreamClass &packet);
|
||||
|
||||
virtual void Export_Frequent(BitStreamClass &packet);
|
||||
virtual void Import_Frequent(BitStreamClass &packet);
|
||||
|
||||
private:
|
||||
|
||||
int ClientId;
|
||||
BYTE Fps;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern CClientFps * PClientFps;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __CLIENTFPS_H__
|
||||
133
Code/Commando/clientgoodbyeevent.cpp
Normal file
133
Code/Commando/clientgoodbyeevent.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
** 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/clientgoodbyeevent.cpp $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 10/10/01 4:53p $*
|
||||
* *
|
||||
* $Revision:: 6 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "clientgoodbyeevent.h"
|
||||
|
||||
#include "networkobjectfactory.h"
|
||||
#include "cnetwork.h"
|
||||
#include "networkobjectmgr.h"
|
||||
#include "apppackettypes.h"
|
||||
|
||||
//
|
||||
// TSS2001 Problem - we have lost the unreliable multiblast effect for this message
|
||||
//
|
||||
|
||||
DECLARE_NETWORKOBJECT_FACTORY(cClientGoodbyeEvent, NETCLASSID_CLIENTGOODBYEEVENT);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
cClientGoodbyeEvent::cClientGoodbyeEvent(void)
|
||||
{
|
||||
WWDEBUG_SAY(("cClientGoodbyeEvent::cClientGoodbyeEvent\n"));
|
||||
|
||||
SenderId = -1;
|
||||
|
||||
Set_App_Packet_Type(APPPACKETTYPE_CLIENTGOODBYEEVENT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientGoodbyeEvent::Init(void)
|
||||
{
|
||||
WWDEBUG_SAY(("cClientGoodbyeEvent::Init\n"));
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Client());
|
||||
|
||||
SenderId = cNetwork::Get_My_Id();
|
||||
|
||||
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
|
||||
|
||||
if (cNetwork::I_Am_Server()) {
|
||||
Act();
|
||||
} else {
|
||||
Set_Object_Dirty_Bit(0, BIT_CREATION, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientGoodbyeEvent::Act(void)
|
||||
{
|
||||
WWDEBUG_SAY(("cClientGoodbyeEvent::Act\n"));
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
Set_Delete_Pending();
|
||||
|
||||
//
|
||||
// TSS092101 - crashy.
|
||||
// This cleanup probably deletes *this* object...
|
||||
//
|
||||
/**/
|
||||
cNetwork::Server_Kill_Connection(SenderId);
|
||||
cNetwork::Cleanup_After_Client(SenderId);
|
||||
/**/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientGoodbyeEvent::Export_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWDEBUG_SAY(("cClientGoodbyeEvent::Export_Creation\n"));
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
cNetEvent::Export_Creation(packet);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
packet.Add(SenderId);
|
||||
|
||||
Set_Delete_Pending();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientGoodbyeEvent::Import_Creation(BitStreamClass & packet)
|
||||
{
|
||||
WWDEBUG_SAY(("cClientGoodbyeEvent::Import_Creation\n"));
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Server());
|
||||
|
||||
cNetEvent::Import_Creation(packet);
|
||||
|
||||
packet.Get(SenderId);
|
||||
|
||||
WWASSERT(SenderId > 0);
|
||||
|
||||
Act();
|
||||
}
|
||||
67
Code/Commando/clientgoodbyeevent.h
Normal file
67
Code/Commando/clientgoodbyeevent.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
** 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/clientgoodbyeevent.h $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 9/21/01 2:42p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __CLIENTGOODBYEEVENT_H__
|
||||
#define __CLIENTGOODBYEEVENT_H__
|
||||
|
||||
#include "netevent.h"
|
||||
#include "netclassids.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A C->S mirrored object to represent client destruction
|
||||
//
|
||||
class cClientGoodbyeEvent : public cNetEvent
|
||||
{
|
||||
public:
|
||||
cClientGoodbyeEvent(void);
|
||||
|
||||
void Init(void);
|
||||
|
||||
virtual void Export_Creation(BitStreamClass &packet);
|
||||
virtual void Import_Creation(BitStreamClass &packet);
|
||||
virtual uint32 Get_Network_Class_ID(void) const {return NETCLASSID_CLIENTGOODBYEEVENT;}
|
||||
|
||||
private:
|
||||
|
||||
virtual void Act(void);
|
||||
|
||||
int SenderId;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __CLIENTGOODBYEEVENT_H__
|
||||
293
Code/Commando/clienthintmanager.cpp
Normal file
293
Code/Commando/clienthintmanager.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
** 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/clienthintmanager.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 12/09/01 6:40p $*
|
||||
* *
|
||||
* $Revision:: 6 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "clienthintmanager.h"
|
||||
|
||||
#include "cshint.h"
|
||||
#include "cnetwork.h"
|
||||
#include "combat.h"
|
||||
#include "gameobjmanager.h"
|
||||
#include "pscene.h"
|
||||
#include "apppackettypes.h"
|
||||
#include "vistable.h"
|
||||
#include "useroptions.h"
|
||||
#include "priority.h"
|
||||
#include "apppacketstats.h"
|
||||
|
||||
//
|
||||
// Class statics
|
||||
//
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientHintManager::Think
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
if (cNetwork::I_Am_Server() ||
|
||||
COMBAT_SCENE == NULL ||
|
||||
cUserOptions::ClientHintFactor.Get() < 1)
|
||||
{
|
||||
//
|
||||
// Bail:
|
||||
// Only dedicated clients send hints.
|
||||
// Also, ClientHintFactor is disabled by using any value < 1.
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
WWASSERT(cNetwork::I_Am_Only_Client());
|
||||
|
||||
SoldierGameObj * p_my_soldier = GameObjManager::Find_Soldier_Of_Client_ID(cNetwork::Get_My_Id());
|
||||
|
||||
if (p_my_soldier == NULL)
|
||||
{
|
||||
//
|
||||
// Bail...
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Do not allow hints to go out at too high a frequency.
|
||||
//
|
||||
static DWORD last_hint_time_ms = 0;
|
||||
DWORD time_now_ms = TIMEGETTIME();
|
||||
const DWORD MIN_HINT_DELAY_MS = 1000;
|
||||
if (time_now_ms - last_hint_time_ms < MIN_HINT_DELAY_MS)
|
||||
{
|
||||
//
|
||||
// Bail...
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Examine all the vis-visible soldiers and vehicles. If we find one that hasn't been
|
||||
// updated for a suspiciously long time, send a hint to the server, He'll follow
|
||||
// up with an update.
|
||||
//
|
||||
|
||||
Vector3 my_position;
|
||||
p_my_soldier->Get_Position(&my_position);
|
||||
my_position.Z += 1.5;
|
||||
|
||||
VisTableClass * pvs = COMBAT_SCENE->Get_Vis_Table(my_position);
|
||||
|
||||
int num_objects = 0;
|
||||
//ULONG total_delay_ms = 0;
|
||||
//ULONG maximum_delay_ms = 0;
|
||||
//int longest_delayed_index = -1;
|
||||
|
||||
int count = NetworkObjectMgrClass::Get_Object_Count();
|
||||
|
||||
NetworkObjectClass **object_list = (NetworkObjectClass **) _alloca((count * sizeof(NetworkObjectClass*)) + 128);
|
||||
WWASSERT(object_list != NULL);
|
||||
SmartGameObj * player_ptr = GameObjManager::Find_Soldier_Of_Client_ID(cNetwork::Get_My_Id());
|
||||
WWASSERT(player_ptr != NULL);
|
||||
|
||||
//
|
||||
// Traverse the vehicles and soldiers and gather data about update rates.
|
||||
//
|
||||
for (int index = 0; index < count; index ++)
|
||||
{
|
||||
NetworkObjectClass * p_object = NetworkObjectMgrClass::Get_Object(index);
|
||||
WWASSERT(p_object != NULL);
|
||||
|
||||
BYTE type = p_object->Get_App_Packet_Type();
|
||||
|
||||
if (type == APPPACKETTYPE_SOLDIER || type == APPPACKETTYPE_VEHICLE)
|
||||
{
|
||||
|
||||
if (p_object->Get_Clientside_Update_Frequency()) {
|
||||
|
||||
int vis_id = p_object->Get_Vis_ID();
|
||||
|
||||
//
|
||||
// If there is no vis data, proceed.
|
||||
// If vis data does exist then only proceed with this object if it is vis-visible.
|
||||
//
|
||||
|
||||
if (pvs == NULL || vis_id == -1 || pvs->Get_Bit(vis_id))
|
||||
{
|
||||
// Just add the object to the list on this pass.
|
||||
object_list[num_objects++] = p_object;
|
||||
|
||||
// Work out the priority of this object from the clients perspective.
|
||||
if (player_ptr) {
|
||||
Vector3 position;
|
||||
player_ptr->Get_Position(&position);
|
||||
float priority = cPriority::Compute_Object_Priority(cNetwork::Get_My_Id(), position, p_object, true);
|
||||
p_object->Set_Cached_Priority(priority);
|
||||
}
|
||||
|
||||
#if (0)
|
||||
ULONG delay_ms = time_now_ms - p_object->Get_Last_Clientside_Update_Time();
|
||||
|
||||
total_delay_ms += delay_ms;
|
||||
num_objects++;
|
||||
|
||||
if (delay_ms > maximum_delay_ms)
|
||||
{
|
||||
maximum_delay_ms = delay_ms;
|
||||
longest_delayed_index = index;
|
||||
}
|
||||
#endif //(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_objects < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Sort the object list. Lowest priority first.
|
||||
//
|
||||
qsort(object_list, num_objects, sizeof(unsigned long), (int (__cdecl *)(const void *,const void *)) &Priority_Compare);
|
||||
|
||||
|
||||
//
|
||||
// Look for an object that has a higher priority than it's neighbor but is getting updated much less frequently
|
||||
//
|
||||
// Ignore the worst priority object. This might have to change....?
|
||||
//
|
||||
int most_broken_object_index = -1;
|
||||
int worst_percentage = 0;
|
||||
unsigned long time = TIMEGETTIME();
|
||||
for (int i=1 ; i<num_objects ; i++) {
|
||||
int higher_priority_rate = object_list[i]->Get_Clientside_Update_Frequency();
|
||||
|
||||
//
|
||||
// Don't hint for objects with a recent updates. This should prevent us from hinting about objects we just hinted about.
|
||||
//
|
||||
if (time - object_list[i]->Get_Last_Clientside_Update_Time() > 1500) {
|
||||
|
||||
int lower_priority_rate = object_list[i-1]->Get_Clientside_Update_Frequency();
|
||||
if (lower_priority_rate && higher_priority_rate) {
|
||||
|
||||
// Lower priority rate should be higher in terms of milliseconds.
|
||||
if (lower_priority_rate < higher_priority_rate) {
|
||||
|
||||
// The higher priority object is being updated by the server less frequently. That doesn't seem right.
|
||||
int percentage = (higher_priority_rate * 100) / lower_priority_rate;
|
||||
if (percentage > worst_percentage) {
|
||||
worst_percentage = percentage;
|
||||
most_broken_object_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Calculate the average delay for this set of soldiers and vehicles
|
||||
//
|
||||
//float average_delay_ms = 0;
|
||||
//if (num_objects > 0)
|
||||
//{
|
||||
// average_delay_ms = total_delay_ms / (float) num_objects;
|
||||
//}
|
||||
|
||||
//
|
||||
// If the most OOD object is much more OOD than the average object, then request an update.
|
||||
//
|
||||
//if ((longest_delayed_index != -1) &&
|
||||
// (maximum_delay_ms > cUserOptions::ClientHintFactor.Get() * average_delay_ms))
|
||||
//{
|
||||
float hint_factor = cUserOptions::ClientHintFactor.Get();
|
||||
if (most_broken_object_index != -1 && worst_percentage > 100 + (10.0f * hint_factor)) {
|
||||
//NetworkObjectClass * p_object = NetworkObjectMgrClass::Get_Object(longest_delayed_index);
|
||||
NetworkObjectClass * p_object = object_list[most_broken_object_index];
|
||||
WWASSERT(p_object != NULL);
|
||||
|
||||
cCsHint * p_hint = new cCsHint;
|
||||
p_hint->Init(p_object->Get_Network_ID());
|
||||
|
||||
last_hint_time_ms = time_now_ms;
|
||||
|
||||
//WWDEBUG_SAY(("cClientHintManager::Think, requesting hint for object id %d, avg = %5.2f, max = %d\n",
|
||||
// p_object->Get_Network_ID(), average_delay_ms, maximum_delay_ms));
|
||||
WWDEBUG_SAY(("cClientHintManager::Think, requesting hint for object id %d (%s), priority = %5.2f, ave update rate = %dms\n",
|
||||
p_object->Get_Network_ID(),
|
||||
cAppPacketStats::Interpret_Type(p_object->Get_App_Packet_Type()),
|
||||
p_object->Get_Cached_Priority(),
|
||||
p_object->Get_Clientside_Update_Frequency()));
|
||||
WWDEBUG_SAY((" Compared to object id %d with priority %5.2f, avg update rate %dms\n",
|
||||
object_list[most_broken_object_index-1]->Get_Network_ID(),
|
||||
object_list[most_broken_object_index-1]->Get_Cached_Priority(),
|
||||
object_list[most_broken_object_index-1]->Get_Clientside_Update_Frequency()));
|
||||
WWDEBUG_SAY((" Client hint factor = %5.2f\n", hint_factor));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Qsort compare function for array of object pointers.
|
||||
//
|
||||
int __cdecl cClientHintManager::Priority_Compare(const void **object1, const void **object2)
|
||||
{
|
||||
WWASSERT(object1 != NULL);
|
||||
WWASSERT(object2 != NULL);
|
||||
|
||||
NetworkObjectClass *n1 = (NetworkObjectClass*) *object1;
|
||||
NetworkObjectClass *n2 = (NetworkObjectClass*) *object2;
|
||||
|
||||
float p1 = n1->Get_Cached_Priority();
|
||||
float p2 = n2->Get_Cached_Priority();
|
||||
|
||||
if (p1 == p2) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (p1 < p2) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
58
Code/Commando/clienthintmanager.h
Normal file
58
Code/Commando/clienthintmanager.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
** 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/clienthintmanager.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 10/19/01 3:01p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __CLIENTHINTMANAGER_H__
|
||||
#define __CLIENTHINTMANAGER_H__
|
||||
|
||||
#include "vector.h"
|
||||
class NetworkObjectClass;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class cClientHintManager
|
||||
{
|
||||
public:
|
||||
static void Think(void);
|
||||
|
||||
private:
|
||||
static int __cdecl Priority_Compare(const void **object1, const void **object2);
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __CLIENTHINTMANAGER_H__
|
||||
|
||||
|
||||
176
Code/Commando/clientpingmanager.cpp
Normal file
176
Code/Commando/clientpingmanager.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
** 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/clientpingmanager.cpp $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 12/09/01 6:40p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "clientpingmanager.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "systimer.h"
|
||||
|
||||
#include "gamemode.h"
|
||||
#include "cspingrequestevent.h"
|
||||
#include "cnetwork.h"
|
||||
|
||||
//
|
||||
// Class statics
|
||||
//
|
||||
int cClientPingManager::PingNumber = 0;
|
||||
DWORD cClientPingManager::TimeSentMs = 0;
|
||||
DWORD cClientPingManager::LastRoundTripPingMs = 0;
|
||||
DWORD cClientPingManager::AvgRoundTripPingMs = 0;
|
||||
bool cClientPingManager::IsAwaitingResponse = false;
|
||||
DWORD cClientPingManager::RoundTripPingSamplesMs[];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientPingManager::Init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
PingNumber = 0;
|
||||
TimeSentMs = 0;
|
||||
LastRoundTripPingMs = 0;
|
||||
AvgRoundTripPingMs = 0;
|
||||
IsAwaitingResponse = false;
|
||||
|
||||
for (int i = 0; i < MAX_SAMPLES; i++)
|
||||
{
|
||||
RoundTripPingSamplesMs[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientPingManager::Think
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
if (GameModeManager::Find("Combat")->Is_Active() && cNetwork::I_Am_Only_Client())
|
||||
{
|
||||
if (!IsAwaitingResponse)
|
||||
{
|
||||
DWORD time_now_ms = TIMEGETTIME();
|
||||
if (time_now_ms - TimeSentMs >= MIN_PING_DELAY_MS)
|
||||
{
|
||||
PingNumber++;
|
||||
TimeSentMs = time_now_ms;
|
||||
IsAwaitingResponse = true;
|
||||
|
||||
cCsPingRequestEvent * p_event = new cCsPingRequestEvent;
|
||||
p_event->Init(PingNumber);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Propagate latency data to combat
|
||||
//
|
||||
CombatManager::Set_Last_Round_Trip_Ping_Ms(LastRoundTripPingMs);
|
||||
CombatManager::Set_Avg_Round_Trip_Ping_Ms(AvgRoundTripPingMs);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD
|
||||
cClientPingManager::Get_Last_Round_Trip_Ping_Ms
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return LastRoundTripPingMs;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD
|
||||
cClientPingManager::Get_Avg_Round_Trip_Ping_Ms
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return AvgRoundTripPingMs;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientPingManager::Compute_Average_Round_Trip_Ping_Ms
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
//
|
||||
// This is the average of MAX_SAMPLES non-zero pings.
|
||||
//
|
||||
|
||||
AvgRoundTripPingMs = 0;
|
||||
|
||||
DWORD num_pings = 0;
|
||||
DWORD total_ping = 0;
|
||||
|
||||
for (int i = 0; i < MAX_SAMPLES; i++)
|
||||
{
|
||||
if (RoundTripPingSamplesMs[i] != 0)
|
||||
{
|
||||
num_pings++;
|
||||
total_ping += RoundTripPingSamplesMs[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (num_pings > 0)
|
||||
{
|
||||
AvgRoundTripPingMs = (DWORD)(total_ping / (float) num_pings);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
cClientPingManager::Response_Received
|
||||
(
|
||||
int ping_number
|
||||
)
|
||||
{
|
||||
if (ping_number == PingNumber)
|
||||
{
|
||||
LastRoundTripPingMs = TIMEGETTIME() - TimeSentMs;
|
||||
RoundTripPingSamplesMs[PingNumber % MAX_SAMPLES] = LastRoundTripPingMs;
|
||||
Compute_Average_Round_Trip_Ping_Ms();
|
||||
IsAwaitingResponse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WWDEBUG_SAY(("WARNING: cClientPingManager::Response_Received ping number mismatch (%d, %d)\n",
|
||||
ping_number, PingNumber));
|
||||
}
|
||||
}
|
||||
71
Code/Commando/clientpingmanager.h
Normal file
71
Code/Commando/clientpingmanager.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
** 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/clientpingmanager.h $*
|
||||
* *
|
||||
* $Author:: Tom_s $*
|
||||
* *
|
||||
* $Modtime:: 10/15/01 4:34p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef __CLIENTPINGMANAGER_H__
|
||||
#define __CLIENTPINGMANAGER_H__
|
||||
|
||||
#include "bittype.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class cClientPingManager
|
||||
{
|
||||
public:
|
||||
static void Init(void);
|
||||
static void Think(void);
|
||||
static DWORD Get_Last_Round_Trip_Ping_Ms(void);
|
||||
static DWORD Get_Avg_Round_Trip_Ping_Ms(void);
|
||||
static void Response_Received(int ping_number);
|
||||
|
||||
private:
|
||||
static void Compute_Average_Round_Trip_Ping_Ms(void);
|
||||
|
||||
enum {MAX_SAMPLES = 3};
|
||||
enum {MIN_PING_DELAY_MS = 1000};
|
||||
|
||||
static int PingNumber;
|
||||
static DWORD TimeSentMs;
|
||||
static DWORD LastRoundTripPingMs;
|
||||
static DWORD AvgRoundTripPingMs;
|
||||
static bool IsAwaitingResponse;
|
||||
static DWORD RoundTripPingSamplesMs[MAX_SAMPLES];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __CLIENTPINGMANAGER_H__
|
||||
|
||||
|
||||
|
||||
1667
Code/Commando/cnetwork.cpp
Normal file
1667
Code/Commando/cnetwork.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user