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

928 lines
32 KiB
C++
Raw Permalink Normal View History

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** 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/dlgserversaveload.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 2/25/02 4:29p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "dlgserversaveload.h"
#include "resource.h"
#include "listctrl.h"
#include "dialogresource.h"
#include "inputconfigmgr.h"
#include "string_ids.h"
#include "rawfile.h"
#include "ini.h"
#include "gamedata.h"
#include "assets.h"
#include "dlgmplanhostoptions.h"
#include "renegadedialogmgr.h"
#include "dlgmpslaveservers.h"
DynamicVectorClass<ServerSettingsClass*> ServerSettingsManagerClass::ServerSettingsList;
bool ServerSaveLoadMenuClass::FromSlaveConfig = false;
const char *DEFAULT_SERVER_SETTINGS_FILE_NAME = "svrcfg_cnc_%04d.ini";
////////////////////////////////////////////////////////////////
//
// ServerSaveLoadMenuClass
//
////////////////////////////////////////////////////////////////
ServerSaveLoadMenuClass::ServerSaveLoadMenuClass (void) :
MenuDialogClass (IDD_MENU_SERVER_SETTINGS_SAVELOAD)
{
}
////////////////////////////////////////////////////////////////
//
// On_Init_Dialog
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::On_Init_Dialog (void)
{
if (FromSlaveConfig) {
Get_Dlg_Item(IDC_DELETE_BUTTON)->Enable(false);
Get_Dlg_Item(IDC_SAVE_BUTTON)->Enable(false);
} else {
Get_Dlg_Item(IDC_DELETE_BUTTON)->Enable(true);
Get_Dlg_Item(IDC_SAVE_BUTTON)->Enable(true);
}
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
if (list_ctrl != NULL) {
//
// Configure the column
//
list_ctrl->Add_Column (L"", 1.0F, Vector3 (1, 1, 1));
//
// Loop over all the configurations
//
ServerSettingsManagerClass::Scan();
int count = ServerSettingsManagerClass::Get_Num_Settings_Files();
for (int index = 0; index < count; index ++) {
//
// Get information about this configuration
//
ServerSettingsClass *config = ServerSettingsManagerClass::Get_Settings(index);
Insert_Configuration (config);
}
//
// Add an entry so the user can add new configurations
//
int item_index = list_ctrl->Insert_Entry (index, TRANSLATE(IDS_MENU_EMPTY_SLOT));
list_ctrl->Set_Curr_Sel (item_index);
//
// Sort the entries
//
list_ctrl->Sort (ListSortCallback, 0);
}
MenuDialogClass::On_Init_Dialog ();
}
////////////////////////////////////////////////////////////////
//
// On_Command
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::On_Command (int ctrl_id, int message_id, DWORD param)
{
switch (ctrl_id)
{
case IDC_DELETE_BUTTON:
Delete_Config ();
break;
case IDC_SAVE_BUTTON:
Save_Config (true);
break;
case IDC_LOAD_BUTTON:
Load_Config ();
break;
case IDC_MENU_BACK_BUTTON:
Next_Dialog();
break;
}
MenuDialogClass::On_Command (ctrl_id, message_id, param);
}
void ServerSaveLoadMenuClass::Next_Dialog(void)
{
if (FromSlaveConfig) {
} else {
START_DIALOG(MPLanHostOptionsMenuClass);
}
}
////////////////////////////////////////////////////////////////
//
// Delete_Config
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::Delete_Config (void)
{
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
if (list_ctrl == NULL) {
return ;
}
//
// Get the current selection
//
int curr_sel = list_ctrl->Get_Curr_Sel ();
if (curr_sel != -1) {
//
// Get the configuration object associated with this entry
//
ServerSettingsClass *config = (ServerSettingsClass *)list_ctrl->Get_Entry_Data (curr_sel, 0);
if (config != NULL) {
//
// Delete the configuration (if possible)
//
if (config->IsCustom && !config->Is_Default_Custom()) {
ServerSettingsManagerClass::Delete_Configuration(config);
list_ctrl->Delete_Entry(curr_sel);
list_ctrl->Sort (ListSortCallback, 0);
}
}
}
}
////////////////////////////////////////////////////////////////
//
// Load_Config
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::Load_Config (void)
{
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
if (list_ctrl == NULL) {
return ;
}
//
// Get the current selection
//
int curr_sel = list_ctrl->Get_Curr_Sel ();
if (curr_sel != -1) {
//
// Get the configuration object associated with this entry
//
ServerSettingsClass *config = (ServerSettingsClass *)list_ctrl->Get_Entry_Data(curr_sel, 0);
if (config != NULL) {
if (FromSlaveConfig) {
//
// Inform the slave settings dialog of the choice.
//
SlaveServerDialogClass::Set_Slave_Settings(&config->RawFileName);
} else {
//
// Load this configuration
//
ServerSettingsManagerClass::Load_Settings(config);
}
End_Dialog ();
Next_Dialog();
}
}
}
////////////////////////////////////////////////////////////////
//
// Save_Config
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::Save_Config (bool prompt)
{
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
if (list_ctrl == NULL) {
return ;
}
//
// Get the current selection
//
int curr_sel = list_ctrl->Get_Curr_Sel();
if (curr_sel != -1) {
//
// Get the configuration object associated with this entry
//
ServerSettingsClass *config = (ServerSettingsClass *)list_ctrl->Get_Entry_Data(curr_sel, 0);
if (config != NULL) {
//
// We can only save custom configurations...
//
if (config->IsCustom) {
WideStringClass outMsg;
if (The_Game()->Is_Valid_Settings(outMsg, true)) {
//
// Get the new display name for this configuration
//
const WCHAR *display_name = Get_Dlg_Item_Text (IDC_NAME_EDIT);
if (display_name[0] != 0) {
//
// Display a message to the user asking if they really want to do this...
//
if (prompt) {
DlgMsgBox::DoDialog (IDS_MENU_CONTROLS_OVERWRITE_PROMPT_TITLE, IDS_MENU_CONTROLS_OVERWRITE_PROMPT_MSG, DlgMsgBox::YesNo, this);
} else {
//
// Just save it.
//
Save_Now();
}
} else {
//
// Let the user know they can't save a configuration without a name
//
DlgMsgBox::DoDialog(IDS_MENU_CANT_SAVE_CONFIG, IDS_MENU_CONFIG_NEEDS_NAME, DlgMsgBox::Okay, NULL, 0);
}
} else {
#if(0) // Denzil
//
// Let the user know the settings are not correct
//
RenegadeDialogMgrClass::Do_Simple_Dialog(IDD_MP_INVALID_SERVER_CONFIG);
#else
WideStringClass errorMsg(0, true);
errorMsg.Format(L"%s\n\n%s", TRANSLATE(IDS_MENU_TEXT330), (const WCHAR*)outMsg);
DlgMsgBox::DoDialog(TRANSLATE(IDS_MENU_TEXT329), errorMsg);
#endif
}
}
} else {
//
// Get the new display name for this configuration
//
const WCHAR *display_name = Get_Dlg_Item_Text (IDC_NAME_EDIT);
if (display_name[0] != 0) {
//
// Add a new configuration
//
WideStringClass name(display_name, true);
config = ServerSettingsManagerClass::Add_Configuration(&name);
if (config != NULL) {
Insert_Configuration(config);
ServerSettingsManagerClass::Save_Configuration(config);
list_ctrl->Sort (ListSortCallback, 0);
}
} else {
//
// Let the user know they can't save a configuration without a name
//
DlgMsgBox::DoDialog (IDS_MENU_CANT_SAVE_CONFIG, IDS_MENU_CONFIG_NEEDS_NAME, DlgMsgBox::Okay, NULL, 0);
}
}
}
}
////////////////////////////////////////////////////////////////
//
// On_ListCtrl_Delete_Entry
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::On_ListCtrl_Delete_Entry
(
ListCtrlClass *list_ctrl,
int ctrl_id,
int item_index
)
{
//
// Remove the data we associated with this entry
//
ServerSettingsClass *config = (ServerSettingsClass *)list_ctrl->Get_Entry_Data (item_index, 0);
list_ctrl->Set_Entry_Data (item_index, 0, NULL);
//
// Free the config object
//
if (config != NULL) {
delete config;
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Insert_Configuration
//
////////////////////////////////////////////////////////////////
int
ServerSaveLoadMenuClass::Insert_Configuration (ServerSettingsClass *config)
{
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
if (list_ctrl == NULL) {
return -1;
}
//
// Add an entry for this configuration to the list
//
int item_index = list_ctrl->Insert_Entry (0xFFFF, config->ConfigName);
if (item_index != -1) {
//
// Make a copy of the config object and store it with the entry
//
ServerSettingsClass *local_copy = new ServerSettingsClass(config);
list_ctrl->Set_Entry_Data (item_index, 0, (DWORD)local_copy);
//
// Change the color of this configuration if the user cannot edit it
//
if (!config->IsCustom) {
list_ctrl->Set_Entry_Color (item_index, 0, Vector3 (1.0F, 1.0F, 1.0F));
}
}
return item_index;
}
////////////////////////////////////////////////////////////////
//
// On_ListCtrl_Sel_Change
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::On_ListCtrl_Sel_Change
(
ListCtrlClass * list_ctrl,
int ctrl_id,
int old_index,
int new_index
)
{
bool enable_edit = true;
//
// Remove the data we associated with this entry
//
ServerSettingsClass *config = (ServerSettingsClass *)list_ctrl->Get_Entry_Data(new_index, 0);
if (config != NULL) {
//
// We want to disable the edit control if the user can't edit this entry
//
if (!config->IsCustom || config->Is_Default_Custom()) {
enable_edit = false;
}
//
// Put the name of the currently selected configuration in the control
//
Set_Dlg_Item_Text (IDC_NAME_EDIT, config->ConfigName);
} else {
//
// Clear the name of the current configuration
//
Set_Dlg_Item_Text (IDC_NAME_EDIT, L"");
}
//
// Fix the enable state of the edit control
//
Enable_Dlg_Item (IDC_NAME_EDIT, enable_edit);
return ;
}
////////////////////////////////////////////////////////////////
//
// ListSortCallback
//
////////////////////////////////////////////////////////////////
int CALLBACK
ServerSaveLoadMenuClass::ListSortCallback
(
ListCtrlClass * list_ctrl,
int item_index1,
int item_index2,
uint32 user_param
)
{
ServerSettingsClass *config1 = (ServerSettingsClass *)list_ctrl->Get_Entry_Data (item_index1, 0);
ServerSettingsClass *config2 = (ServerSettingsClass *)list_ctrl->Get_Entry_Data (item_index2, 0);
if (config1 == NULL) {
return(1);
} else if (config2 == NULL) {
return(-1);
} else {
//
// Sort based on the type of configuration
//
if (!config1->IsCustom && config2->IsCustom) {
return(-1);
}
if (config1->IsCustom && !config2->IsCustom) {
return(1);
}
if (config1->Is_Default_Custom() && !config2->Is_Default_Custom()) {
return(-1);
}
if (!config1->Is_Default_Custom() && config2->Is_Default_Custom()) {
return(1);
}
}
return(wcsicmp(config1->ConfigName, config2->ConfigName));
}
////////////////////////////////////////////////////////////////
//
// On_EditCtrl_Enter_Pressed
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::On_EditCtrl_Enter_Pressed (EditCtrlClass *edit_ctrl, int ctrl_id)
{
if (ctrl_id == IDC_NAME_EDIT) {
Save_Config (true);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// HandleNotification
//
////////////////////////////////////////////////////////////////
void
ServerSaveLoadMenuClass::HandleNotification (DlgMsgBoxEvent &event)
{
//
// The user has confirmed the overwrite, so save the configuration
//
if (event.Event () == DlgMsgBoxEvent::Yes) {
Save_Now();
}
}
////////////////////////////////////////////////////////////////
//
// Save_Now
//
////////////////////////////////////////////////////////////////
void ServerSaveLoadMenuClass::Save_Now(void)
{
ListCtrlClass *list_ctrl = (ListCtrlClass *)Get_Dlg_Item (IDC_LIST_CTRL);
if (list_ctrl == NULL) {
return ;
}
//
// Get the current selection
//
int curr_sel = list_ctrl->Get_Curr_Sel();
if (curr_sel != -1) {
//
// Get the configuration object associated with this entry
//
ServerSettingsClass *config = (ServerSettingsClass *)list_ctrl->Get_Entry_Data(curr_sel, 0);
if (config != NULL) {
//
// We can only save custom configurations...
//
if (config->IsCustom) {
WideStringClass outMsg;
if (The_Game()->Is_Valid_Settings(outMsg, true)) {
//
// Get the new display name for this configuration
//
const WCHAR *display_name = Get_Dlg_Item_Text (IDC_NAME_EDIT);
if (display_name[0] != 0) {
//
// Update the name of this configuration
//
config->ConfigName = display_name;
list_ctrl->Set_Entry_Text (curr_sel, 0, display_name);
//
// Save the configuration
//
ServerSettingsManagerClass::Save_Configuration(config);
End_Dialog ();
Next_Dialog();
}
}
}
}
}
}
/***********************************************************************************************
* ServerSettingsClass::ServerSettingsClass -- Class constructor *
* *
* *
* *
* INPUT: File name of config file *
* Name of config file *
* File number *
* *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:11PM ST : Created *
*=============================================================================================*/
ServerSettingsClass::ServerSettingsClass(char *filename, unsigned short *configname, int file_number)
{
ConfigName = configname; //"Default C&C Server Settings";
RawFileName = filename; //"svrcfg_cnc.ini"
FileNumber = file_number;
IsCustom = true;
}
/***********************************************************************************************
* ServerSettingsClass::ServerSettingsClass -- Class copy constructor *
* *
* *
* *
* INPUT: Other class *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:11PM ST : Created *
*=============================================================================================*/
ServerSettingsClass::ServerSettingsClass(ServerSettingsClass *other)
{
ConfigName = other->ConfigName;
RawFileName = other->RawFileName;
FileNumber = other->FileNumber;
IsCustom = other->IsCustom;
}
/***********************************************************************************************
* ServerSettingsManagerClass::Get_Settings -- Get settings by index *
* *
* *
* *
* INPUT: Index *
* *
* OUTPUT: Settings *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:12PM ST : Created *
*=============================================================================================*/
ServerSettingsClass *ServerSettingsManagerClass::Get_Settings(int index)
{
WWASSERT(index >= 0 && index < ServerSettingsList.Count());
return(ServerSettingsList[index]);
}
/***********************************************************************************************
* ServerSettingsManagerClass::Scan -- Scan for server settings files on the disk *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:13PM ST : Created *
*=============================================================================================*/
void ServerSettingsManagerClass::Scan(void)
{
char file_name[MAX_PATH];
char whole_file_name[MAX_PATH];
//char description[256];
WideStringClass description(128, true);
StringClass char_description(128, true);
/*
** Clear out old configs.
*/
Clear_Settings_List();
/*
** Add in the default as the first entry.
*/
ServerSettingsList.Add(new ServerSettingsClass("def_svrcfg_cnc.ini", (unsigned short *)TRANSLATE(IDS_SERVER_SAVELOAD_DEFAULT), 0));
ServerSettingsList[0]->IsCustom = false;
/*
** Add in the custom default as the second entry.
*/
ServerSettingsList.Add(new ServerSettingsClass("svrcfg_cnc.ini", (unsigned short *)TRANSLATE(IDS_SERVER_SAVELOAD_CUSTOM_DEFAULT), 1));
ServerSettingsList[1]->IsCustom = true;
for (int i=2 ; i<MAX_SETTINGS_FILES ; i++) {
sprintf(file_name, DEFAULT_SERVER_SETTINGS_FILE_NAME, i);
sprintf(whole_file_name, "data\\%s", file_name);
RawFileClass file(whole_file_name);
if (file.Is_Available()) {
INIClass *ini = Get_INI(file_name);
if (ini) {
description = ini->Get_Wide_String(description, "Settings", "wConfigName", L""); //(unsigned short *)TRANSLATE(IDS_SERVER_SAVELOAD_DEFAULT));
if (description.Get_Length()) {
ServerSettingsList.Add(new ServerSettingsClass(file_name, description.Peek_Buffer(), i));
} else {
StringClass defaultstr((unsigned short *)TRANSLATE(IDS_SERVER_SAVELOAD_DEFAULT), true);
ini->Get_String("Settings", "bConfigName", defaultstr.Peek_Buffer(), char_description.Peek_Buffer(), 128);
ServerSettingsList.Add(new ServerSettingsClass(file_name, WideStringClass(char_description, true).Peek_Buffer(), i));
}
}
}
}
}
/***********************************************************************************************
* ServerSettingsManagerClass::Clear_Settings_List -- Reset the settings list *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:13PM ST : Created *
*=============================================================================================*/
void ServerSettingsManagerClass::Clear_Settings_List(void)
{
for (int i=0 ; i<ServerSettingsList.Count() ; i++) {
delete ServerSettingsList[i];
}
ServerSettingsList.Reset_Active();
}
/***********************************************************************************************
* ServerSettingsManagerClass::Load_Settings -- Load settings into the game *
* *
* *
* *
* INPUT: Settings *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:14PM ST : Created *
*=============================================================================================*/
void ServerSettingsManagerClass::Load_Settings(ServerSettingsClass *settings)
{
WWASSERT(settings != NULL);
WWASSERT(The_Game() != NULL);
if (settings && The_Game()) {
char filename[MAX_PATH];
sprintf(filename, "data\\%s", settings->RawFileName);
RawFileClass file(filename);
if (file.Is_Available()) {
The_Game()->Set_Ini_Filename(settings->RawFileName);
The_Game()->Load_From_Server_Config();
settings->ConfigName = The_Game()->Get_Settings_Description();
}
}
}
/***********************************************************************************************
* ServerSettingsManagerClass::Delete_Configuration -- Delete a settings file from disk *
* *
* *
* *
* INPUT: Settings *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:14PM ST : Created *
*=============================================================================================*/
void ServerSettingsManagerClass::Delete_Configuration(ServerSettingsClass *settings)
{
if (!settings->Is_Default()) {
char filename[MAX_PATH];
sprintf(filename, "data\\%s", settings->RawFileName);
DeleteFile(filename);
for (int i=0 ; i<ServerSettingsList.Count() ; i++) {
if (strcmp(settings->RawFileName, ServerSettingsList[i]->RawFileName) == 0) {
delete ServerSettingsList[i];
ServerSettingsList.Delete(i);
break;
}
}
}
}
/***********************************************************************************************
* ServerSettingsManagerClass::Save_Configuration -- Save settings from the game *
* *
* *
* *
* INPUT: Settings *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:14PM ST : Created *
*=============================================================================================*/
void ServerSettingsManagerClass::Save_Configuration(ServerSettingsClass *settings)
{
WWASSERT(settings != NULL);
WWASSERT(The_Game() != NULL);
if (settings && The_Game()) {
char filename[MAX_PATH];
sprintf(filename, "data\\%s", settings->RawFileName);
RawFileClass file(filename);
if (!file.Is_Available()) {
file.Create();
WWASSERT(file.Is_Available());
}
if (file.Is_Available()) {
//StringClass string(128, true);
//settings->ConfigName.Convert_To(string);
The_Game()->Set_Settings_Description(settings->ConfigName);
The_Game()->Set_Ini_Filename(settings->RawFileName);
The_Game()->Save_To_Server_Config();
}
}
}
/***********************************************************************************************
* ServerSettingsManagerClass::Add_Configuration -- Create a new settings file entry *
* *
* *
* *
* INPUT: Settings name *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 12/17/2001 5:15PM ST : Created *
*=============================================================================================*/
ServerSettingsClass *ServerSettingsManagerClass::Add_Configuration(WideStringClass *display_name)
{
WWASSERT(display_name != NULL);
WWASSERT(The_Game());
if (display_name != NULL) {
if (The_Game()) {
/*
** Find an unused filename.
*/
char population[MAX_SETTINGS_FILES];
memset(population, 0, sizeof(population));
char filename[MAX_PATH];
int file_number = -1;
for (int i=0 ; i<ServerSettingsList.Count() ; i++) {
ServerSettingsClass *settings = ServerSettingsList[i];
if (settings) {
WWASSERT(settings->FileNumber >= 0);
WWASSERT(settings->FileNumber < MAX_SETTINGS_FILES);
population[settings->FileNumber] = 1;
}
}
for (i=0 ; i<MAX_SETTINGS_FILES ; i++) {
if (population[i] == 0) {
sprintf(filename, DEFAULT_SERVER_SETTINGS_FILE_NAME, i);
file_number = i;
break;
}
}
if (file_number != -1) {
ServerSettingsClass *new_settings = new ServerSettingsClass(filename, display_name->Peek_Buffer(), file_number);
ServerSettingsList.Add(new_settings);
return(new_settings);
}
}
}
return(NULL);
}