mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-29 23:07:48 +02:00
Settings: savefrequency is now configurable in launcher
* Client command-line can modify arbitrary settings now * Only launcher auto-saves to settings.json
This commit is contained in:
committed by
ArseniyShestakov
parent
ce0b4b222d
commit
2ede3783dd
@@ -61,6 +61,7 @@
|
|||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
#include "mainmenu/CPrologEpilogVideo.h"
|
#include "mainmenu/CPrologEpilogVideo.h"
|
||||||
|
#include <vstd/StringUtils.h>
|
||||||
|
|
||||||
#ifdef VCMI_WINDOWS
|
#ifdef VCMI_WINDOWS
|
||||||
#include "SDL_syswm.h"
|
#include "SDL_syswm.h"
|
||||||
@@ -259,7 +260,29 @@ int main(int argc, char * argv[])
|
|||||||
preinitDLL(::console);
|
preinitDLL(::console);
|
||||||
settings.init();
|
settings.init();
|
||||||
Settings session = settings.write["session"];
|
Settings session = settings.write["session"];
|
||||||
session["onlyai"].Bool() = vm.count("onlyAI");
|
auto setSettingBool = [](std::string key, std::string arg) {
|
||||||
|
Settings s = settings.write(vstd::split(key, "/"));
|
||||||
|
if(::vm.count(arg))
|
||||||
|
s->Bool() = true;
|
||||||
|
else if(s->isNull())
|
||||||
|
s->Bool() = false;
|
||||||
|
};
|
||||||
|
auto setSettingInteger = [](std::string key, std::string arg, si64 defaultValue) {
|
||||||
|
Settings s = settings.write(vstd::split(key, "/"));
|
||||||
|
if(::vm.count(arg))
|
||||||
|
s->Integer() = ::vm[arg].as<si64>();
|
||||||
|
else if(s->isNull())
|
||||||
|
s->Integer() = defaultValue;
|
||||||
|
};
|
||||||
|
auto setSettingString = [](std::string key, std::string arg, std::string defaultValue) {
|
||||||
|
Settings s = settings.write(vstd::split(key, "/"));
|
||||||
|
if(::vm.count(arg))
|
||||||
|
s->String() = ::vm[arg].as<std::string>();
|
||||||
|
else if(s->isNull())
|
||||||
|
s->String() = defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
setSettingBool("session/onlyai", "onlyAI");
|
||||||
if(vm.count("headless"))
|
if(vm.count("headless"))
|
||||||
{
|
{
|
||||||
session["headless"].Bool() = true;
|
session["headless"].Bool() = true;
|
||||||
@@ -277,19 +300,20 @@ int main(int argc, char * argv[])
|
|||||||
session["spectate-battle-speed"].Float() = vm["spectate-battle-speed"].as<int>();
|
session["spectate-battle-speed"].Float() = vm["spectate-battle-speed"].as<int>();
|
||||||
}
|
}
|
||||||
// Server settings
|
// Server settings
|
||||||
session["donotstartserver"].Bool() = vm.count("donotstartserver");
|
setSettingBool("session/donotstartserver", "donotstartserver");
|
||||||
|
|
||||||
// Shared memory options
|
// Shared memory options
|
||||||
session["disable-shm"].Bool() = vm.count("disable-shm");
|
setSettingBool("session/disable-shm", "disable-shm");
|
||||||
session["enable-shm-uuid"].Bool() = vm.count("enable-shm-uuid");
|
setSettingBool("session/enable-shm-uuid", "enable-shm-uuid");
|
||||||
|
|
||||||
// Init special testing settings
|
// Init special testing settings
|
||||||
session["serverport"].Integer() = vm.count("serverport") ? vm["serverport"].as<si64>() : 0;
|
setSettingInteger("session/serverport", "serverport", 0);
|
||||||
session["saveprefix"].String() = vm.count("saveprefix") ? vm["saveprefix"].as<std::string>() : "";
|
setSettingString("session/saveprefix", "saveprefix", "");
|
||||||
session["savefrequency"].Integer() = vm.count("savefrequency") ? vm["savefrequency"].as<si64>() : 1;
|
setSettingInteger("general/saveFrequency", "savefrequency", 1);
|
||||||
|
|
||||||
// Initialize logging based on settings
|
// Initialize logging based on settings
|
||||||
logConfig.configure();
|
logConfig.configure();
|
||||||
|
logGlobal->debug("settings = %s", settings.toJsonNode().toJson());
|
||||||
|
|
||||||
// Some basic data validation to produce better error messages in cases of incorrect install
|
// Some basic data validation to produce better error messages in cases of incorrect install
|
||||||
auto testFile = [](std::string filename, std::string message) -> bool
|
auto testFile = [](std::string filename, std::string message) -> bool
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ void CPlayerInterface::yourTurn()
|
|||||||
adventureInt->selection = nullptr;
|
adventureInt->selection = nullptr;
|
||||||
|
|
||||||
std::string prefix = settings["session"]["saveprefix"].String();
|
std::string prefix = settings["session"]["saveprefix"].String();
|
||||||
|
int frequency = settings["general"]["saveFrequency"].Integer();
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
if(CSH->howManyPlayerInterfaces() == 1)
|
if(CSH->howManyPlayerInterfaces() == 1)
|
||||||
@@ -180,7 +181,7 @@ void CPlayerInterface::yourTurn()
|
|||||||
}
|
}
|
||||||
firstCall = 0;
|
firstCall = 0;
|
||||||
}
|
}
|
||||||
else if (cb->getDate() % static_cast<int>(settings["session"]["savefrequency"].Integer()) == 0)
|
else if(frequency > 0 && cb->getDate() % frequency == 0)
|
||||||
{
|
{
|
||||||
LOCPLINT->cb->save("Saves/" + prefix + "Autosave_" + boost::lexical_cast<std::string>(autosaveCount++ + 1));
|
LOCPLINT->cb->save("Saves/" + prefix + "Autosave_" + boost::lexical_cast<std::string>(autosaveCount++ + 1));
|
||||||
autosaveCount %= 5;
|
autosaveCount %= 5;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"type" : "object",
|
"type" : "object",
|
||||||
"default": {},
|
"default": {},
|
||||||
"additionalProperties" : false,
|
"additionalProperties" : false,
|
||||||
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps" ],
|
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps", "saveFrequency" ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"playerName" : {
|
"playerName" : {
|
||||||
"type":"string",
|
"type":"string",
|
||||||
@@ -58,6 +58,10 @@
|
|||||||
"lastCampaign" : {
|
"lastCampaign" : {
|
||||||
"type":"string",
|
"type":"string",
|
||||||
"default" : ""
|
"default" : ""
|
||||||
|
},
|
||||||
|
"saveFrequency" : {
|
||||||
|
"type" : "number",
|
||||||
|
"default" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
6
include/vstd/StringUtils.h
Normal file
6
include/vstd/StringUtils.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace vstd
|
||||||
|
{
|
||||||
|
|
||||||
|
DLL_LINKAGE std::vector<std::string> split(std::string s, std::string separators);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ void MainWindow::load()
|
|||||||
QDir::addSearchPath("icons", pathToQString(string / "launcher" / "icons"));
|
QDir::addSearchPath("icons", pathToQString(string / "launcher" / "icons"));
|
||||||
QDir::addSearchPath("icons", pathToQString(VCMIDirs::get().userDataPath() / "launcher" / "icons"));
|
QDir::addSearchPath("icons", pathToQString(VCMIDirs::get().userDataPath() / "launcher" / "icons"));
|
||||||
|
|
||||||
settings.init();
|
settings.init(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget * parent) :
|
MainWindow::MainWindow(QWidget * parent) :
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ void CSettingsView::loadSettings()
|
|||||||
size_t encodingIndex = boost::range::find(knownEncodingsList, encoding) - knownEncodingsList;
|
size_t encodingIndex = boost::range::find(knownEncodingsList, encoding) - knownEncodingsList;
|
||||||
if (encodingIndex < ui->comboBoxEncoding->count())
|
if (encodingIndex < ui->comboBoxEncoding->count())
|
||||||
ui->comboBoxEncoding->setCurrentIndex(encodingIndex);
|
ui->comboBoxEncoding->setCurrentIndex(encodingIndex);
|
||||||
|
ui->comboBoxAutoSave->setCurrentIndex(settings["general"]["saveFrequency"].Integer() > 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSettingsView::CSettingsView(QWidget *parent) :
|
CSettingsView::CSettingsView(QWidget *parent) :
|
||||||
@@ -223,3 +224,9 @@ void CSettingsView::on_changeGameDataDir_clicked()
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSettingsView::on_comboBoxAutoSave_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
Settings node = settings.write["general"]["saveFrequency"];
|
||||||
|
node->Integer() = index;
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ private slots:
|
|||||||
|
|
||||||
void on_comboBoxDisplayIndex_currentIndexChanged(int index);
|
void on_comboBoxDisplayIndex_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
void on_comboBoxAutoSave_currentIndexChanged(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::CSettingsView *ui;
|
Ui::CSettingsView *ui;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -603,6 +603,30 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="11" column="6">
|
||||||
|
<widget class="QLabel" name="labelAutoSave">
|
||||||
|
<property name="text">
|
||||||
|
<string>Autosave</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="7">
|
||||||
|
<widget class="QComboBox" name="comboBoxAutoSave">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Off</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>On</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ SettingsStorage::NodeAccessor<Accessor>::operator Accessor() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Accessor>
|
template<typename Accessor>
|
||||||
SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>::operator () (std::vector<std::string> _path)
|
SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>::operator () (std::vector<std::string> _path) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> newPath = path;
|
std::vector<std::string> newPath = path;
|
||||||
newPath.insert( newPath.end(), _path.begin(), _path.end());
|
newPath.insert( newPath.end(), _path.begin(), _path.end());
|
||||||
@@ -51,11 +51,12 @@ SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>:
|
|||||||
|
|
||||||
SettingsStorage::SettingsStorage():
|
SettingsStorage::SettingsStorage():
|
||||||
write(NodeAccessor<Settings>(*this, std::vector<std::string>() )),
|
write(NodeAccessor<Settings>(*this, std::vector<std::string>() )),
|
||||||
listen(NodeAccessor<SettingsListener>(*this, std::vector<std::string>() ))
|
listen(NodeAccessor<SettingsListener>(*this, std::vector<std::string>() )),
|
||||||
|
autoSaveConfig(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsStorage::init()
|
void SettingsStorage::init(bool autoSave)
|
||||||
{
|
{
|
||||||
std::string confName = "config/settings.json";
|
std::string confName = "config/settings.json";
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ void SettingsStorage::init()
|
|||||||
|
|
||||||
JsonUtils::maximize(config, "vcmi:settings");
|
JsonUtils::maximize(config, "vcmi:settings");
|
||||||
JsonUtils::validate(config, "vcmi:settings", "settings");
|
JsonUtils::validate(config, "vcmi:settings", "settings");
|
||||||
|
autoSaveConfig = autoSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath)
|
void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath)
|
||||||
@@ -74,14 +76,14 @@ void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath
|
|||||||
for(SettingsListener * listener : listeners)
|
for(SettingsListener * listener : listeners)
|
||||||
listener->nodeInvalidated(changedPath);
|
listener->nodeInvalidated(changedPath);
|
||||||
|
|
||||||
JsonNode savedConf = config;
|
if(autoSaveConfig)
|
||||||
JsonNode schema(ResourceID("config/schemas/settings.json"));
|
{
|
||||||
|
JsonNode savedConf = config;
|
||||||
|
JsonUtils::minimize(savedConf, "vcmi:settings");
|
||||||
|
|
||||||
savedConf.Struct().erase("session");
|
FileStream file(*CResourceHandler::get()->getResourceName(ResourceID("config/settings.json")), std::ofstream::out | std::ofstream::trunc);
|
||||||
JsonUtils::minimize(savedConf, "vcmi:settings");
|
file << savedConf.toJson();
|
||||||
|
}
|
||||||
FileStream file(*CResourceHandler::get()->getResourceName(ResourceID("config/settings.json")), std::ofstream::out | std::ofstream::trunc);
|
|
||||||
file << savedConf.toJson();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode & SettingsStorage::getNode(std::vector<std::string> path)
|
JsonNode & SettingsStorage::getNode(std::vector<std::string> path)
|
||||||
@@ -98,11 +100,16 @@ Settings SettingsStorage::get(std::vector<std::string> path)
|
|||||||
return Settings(*this, path);
|
return Settings(*this, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JsonNode& SettingsStorage::operator [](std::string value)
|
const JsonNode & SettingsStorage::operator [](std::string value) const
|
||||||
{
|
{
|
||||||
return config[value];
|
return config[value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const JsonNode & SettingsStorage::toJsonNode() const
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
SettingsListener::SettingsListener(SettingsStorage &_parent, const std::vector<std::string> &_path):
|
SettingsListener::SettingsListener(SettingsStorage &_parent, const std::vector<std::string> &_path):
|
||||||
parent(_parent),
|
parent(_parent),
|
||||||
path(_path)
|
path(_path)
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ class DLL_LINKAGE SettingsStorage
|
|||||||
|
|
||||||
NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path);
|
NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path);
|
||||||
NodeAccessor<Accessor> operator [] (std::string nextNode) const;
|
NodeAccessor<Accessor> operator [] (std::string nextNode) const;
|
||||||
NodeAccessor<Accessor> operator () (std::vector<std::string> _path);
|
NodeAccessor<Accessor> operator () (std::vector<std::string> _path) const;
|
||||||
operator Accessor() const;
|
operator Accessor() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::set<SettingsListener*> listeners;
|
std::set<SettingsListener*> listeners;
|
||||||
JsonNode config;
|
JsonNode config;
|
||||||
|
bool autoSaveConfig;
|
||||||
|
|
||||||
JsonNode & getNode(std::vector<std::string> path);
|
JsonNode & getNode(std::vector<std::string> path);
|
||||||
|
|
||||||
// Calls all required listeners
|
// Calls all required listeners
|
||||||
@@ -41,7 +43,7 @@ class DLL_LINKAGE SettingsStorage
|
|||||||
public:
|
public:
|
||||||
// Initialize config structure
|
// Initialize config structure
|
||||||
SettingsStorage();
|
SettingsStorage();
|
||||||
void init();
|
void init(bool autoSave=false);
|
||||||
|
|
||||||
// Get write access to config node at path
|
// Get write access to config node at path
|
||||||
const NodeAccessor<Settings> write;
|
const NodeAccessor<Settings> write;
|
||||||
@@ -50,7 +52,8 @@ public:
|
|||||||
const NodeAccessor<SettingsListener> listen;
|
const NodeAccessor<SettingsListener> listen;
|
||||||
|
|
||||||
//Read access, see JsonNode::operator[]
|
//Read access, see JsonNode::operator[]
|
||||||
const JsonNode& operator [](std::string value);
|
const JsonNode & operator [](std::string value) const;
|
||||||
|
const JsonNode & toJsonNode() const;
|
||||||
|
|
||||||
friend class SettingsListener;
|
friend class SettingsListener;
|
||||||
friend class Settings;
|
friend class Settings;
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ set(lib_SRCS
|
|||||||
spells/effects/RemoveObstacle.cpp
|
spells/effects/RemoveObstacle.cpp
|
||||||
spells/effects/Sacrifice.cpp
|
spells/effects/Sacrifice.cpp
|
||||||
|
|
||||||
|
vstd/StringUtils.cpp
|
||||||
|
|
||||||
CAndroidVMHelper.cpp
|
CAndroidVMHelper.cpp
|
||||||
CArtHandler.cpp
|
CArtHandler.cpp
|
||||||
CBonusTypeHandler.cpp
|
CBonusTypeHandler.cpp
|
||||||
@@ -169,6 +171,7 @@ set(lib_HEADERS
|
|||||||
${CMAKE_HOME_DIRECTORY}/include/vstd/CLoggerBase.h
|
${CMAKE_HOME_DIRECTORY}/include/vstd/CLoggerBase.h
|
||||||
${CMAKE_HOME_DIRECTORY}/include/vstd/ContainerUtils.h
|
${CMAKE_HOME_DIRECTORY}/include/vstd/ContainerUtils.h
|
||||||
${CMAKE_HOME_DIRECTORY}/include/vstd/RNG.h
|
${CMAKE_HOME_DIRECTORY}/include/vstd/RNG.h
|
||||||
|
${CMAKE_HOME_DIRECTORY}/include/vstd/StringUtils.h
|
||||||
StdInc.h
|
StdInc.h
|
||||||
../Global.h
|
../Global.h
|
||||||
|
|
||||||
|
|||||||
14
lib/vstd/StringUtils.cpp
Normal file
14
lib/vstd/StringUtils.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "StdInc.h"
|
||||||
|
#include <vstd/StringUtils.h>
|
||||||
|
|
||||||
|
namespace vstd
|
||||||
|
{
|
||||||
|
|
||||||
|
DLL_LINKAGE std::vector<std::string> split(std::string s, std::string separators)
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
boost::split(result, s, boost::is_any_of(separators));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user