Redo command line parsing
This commit is contained in:
parent
1da7438e39
commit
edab57887d
@ -2,6 +2,7 @@
|
|||||||
#include "common/tpt-minmax.h"
|
#include "common/tpt-minmax.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#ifdef WIN
|
#ifdef WIN
|
||||||
@ -296,109 +297,6 @@ unsigned int GetTicks()
|
|||||||
return SDL_GetTicks();
|
return SDL_GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<ByteString, ByteString> readArguments(int argc, char * argv[])
|
|
||||||
{
|
|
||||||
std::map<ByteString, ByteString> arguments;
|
|
||||||
|
|
||||||
//Defaults
|
|
||||||
arguments["scale"] = "";
|
|
||||||
arguments["proxy"] = "";
|
|
||||||
arguments["cafile"] = "";
|
|
||||||
arguments["capath"] = "";
|
|
||||||
arguments["nohud"] = "false"; //the nohud, sound, and scripts commands currently do nothing.
|
|
||||||
arguments["sound"] = "false";
|
|
||||||
arguments["kiosk"] = "false";
|
|
||||||
arguments["redirect"] = "false";
|
|
||||||
arguments["nobluescreen"] = "false";
|
|
||||||
arguments["scripts"] = "false";
|
|
||||||
arguments["open"] = "";
|
|
||||||
arguments["ddir"] = "";
|
|
||||||
arguments["ptsave"] = "";
|
|
||||||
|
|
||||||
for (int i=1; i<argc; i++)
|
|
||||||
{
|
|
||||||
if (!strncmp(argv[i], "scale:", 6) && argv[i][6])
|
|
||||||
{
|
|
||||||
arguments["scale"] = &argv[i][6];
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "proxy:", 6))
|
|
||||||
{
|
|
||||||
if(argv[i][6])
|
|
||||||
arguments["proxy"] = &argv[i][6];
|
|
||||||
else
|
|
||||||
arguments["proxy"] = "false";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "cafile:", 7))
|
|
||||||
{
|
|
||||||
if(argv[i][7])
|
|
||||||
arguments["cafile"] = &argv[i][7];
|
|
||||||
else
|
|
||||||
arguments["cafile"] = "false";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "capath:", 7))
|
|
||||||
{
|
|
||||||
if(argv[i][7])
|
|
||||||
arguments["capath"] = &argv[i][7];
|
|
||||||
else
|
|
||||||
arguments["capath"] = "false";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "nohud", 5))
|
|
||||||
{
|
|
||||||
arguments["nohud"] = "true";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "kiosk", 5))
|
|
||||||
{
|
|
||||||
arguments["kiosk"] = "true";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "redirect", 8))
|
|
||||||
{
|
|
||||||
arguments["redirect"] = "true";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "nobluescreen", 12))
|
|
||||||
{
|
|
||||||
arguments["nobluescreen"] = "true";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "sound", 5))
|
|
||||||
{
|
|
||||||
arguments["sound"] = "true";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "scripts", 8))
|
|
||||||
{
|
|
||||||
arguments["scripts"] = "true";
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "file:", 5) && strlen(argv[i]) >= 7)
|
|
||||||
{
|
|
||||||
arguments["open"] = format::URLDecode(argv[i] + 7); // skip "file://"
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "open", 5) && i+1<argc)
|
|
||||||
{
|
|
||||||
arguments["open"] = argv[i+1];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "ddir", 5) && i+1<argc)
|
|
||||||
{
|
|
||||||
arguments["ddir"] = argv[i+1];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "ptsave:", 7) && strlen(argv[i]) >= 8)
|
|
||||||
{
|
|
||||||
arguments["ptsave"] = argv[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "ptsave", 7) && i+1<argc)
|
|
||||||
{
|
|
||||||
arguments["ptsave"] = argv[i+1];
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (!strncmp(argv[i], "disable-network", 16))
|
|
||||||
{
|
|
||||||
arguments["disable-network"] = "true";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
int elapsedTime = 0, currentTime = 0, lastTime = 0, currentFrame = 0;
|
int elapsedTime = 0, currentTime = 0, lastTime = 0, currentFrame = 0;
|
||||||
unsigned int lastTick = 0;
|
unsigned int lastTick = 0;
|
||||||
unsigned int lastFpsUpdate = 0;
|
unsigned int lastFpsUpdate = 0;
|
||||||
@ -731,14 +629,53 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
Platform::originalCwd = Platform::GetCwd();
|
Platform::originalCwd = Platform::GetCwd();
|
||||||
|
|
||||||
std::map<ByteString, ByteString> arguments = readArguments(argc, argv);
|
using Argument = std::optional<ByteString>;
|
||||||
|
std::map<ByteString, Argument> arguments;
|
||||||
|
|
||||||
if (arguments["ddir"].length())
|
for (auto i = 1; i < argc; ++i)
|
||||||
|
{
|
||||||
|
auto str = ByteString(argv[i]);
|
||||||
|
if (str.BeginsWith("file://"))
|
||||||
|
{
|
||||||
|
arguments.insert({ "open", format::URLDecode(str.substr(7 /* length of the "file://" prefix */)) });
|
||||||
|
}
|
||||||
|
else if (str.BeginsWith("ptsave:"))
|
||||||
|
{
|
||||||
|
arguments.insert({ "ptsave", str });
|
||||||
|
}
|
||||||
|
else if (auto split = str.SplitBy(':'))
|
||||||
|
{
|
||||||
|
arguments.insert({ split.Before(), split.After() });
|
||||||
|
}
|
||||||
|
else if (auto split = str.SplitBy('='))
|
||||||
|
{
|
||||||
|
arguments.insert({ split.Before(), split.After() });
|
||||||
|
}
|
||||||
|
else if (str == "open" || str == "ptsave" || str == "ddir")
|
||||||
|
{
|
||||||
|
if (i + 1 < argc)
|
||||||
|
{
|
||||||
|
arguments.insert({ str, argv[i + 1] });
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "no value provided for command line parameter " << str << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arguments.insert({ str, "" }); // so .has_value() is true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ddirArg = arguments["ddir"];
|
||||||
|
if (ddirArg.has_value())
|
||||||
{
|
{
|
||||||
#ifdef WIN
|
#ifdef WIN
|
||||||
int failure = _chdir(arguments["ddir"].c_str());
|
int failure = _chdir(ddirArg.value().c_str());
|
||||||
#else
|
#else
|
||||||
int failure = chdir(arguments["ddir"].c_str());
|
int failure = chdir(ddirArg.value().c_str());
|
||||||
#endif
|
#endif
|
||||||
if (!failure)
|
if (!failure)
|
||||||
Platform::sharedCwd = Platform::GetCwd();
|
Platform::sharedCwd = Platform::GetCwd();
|
||||||
@ -787,14 +724,27 @@ int main(int argc, char * argv[])
|
|||||||
momentumScroll = Client::Ref().GetPrefBool("MomentumScroll", true);
|
momentumScroll = Client::Ref().GetPrefBool("MomentumScroll", true);
|
||||||
showAvatars = Client::Ref().GetPrefBool("ShowAvatars", true);
|
showAvatars = Client::Ref().GetPrefBool("ShowAvatars", true);
|
||||||
|
|
||||||
|
auto true_string = [](ByteString str) {
|
||||||
|
str = str.ToLower();
|
||||||
|
return str == "true" ||
|
||||||
|
str == "t" ||
|
||||||
|
str == "on" ||
|
||||||
|
str == "yes" ||
|
||||||
|
str == "y" ||
|
||||||
|
str == ""; // standalone "redirect" or "disable-bluescreen" or similar arguments
|
||||||
|
};
|
||||||
|
auto true_arg = [&true_string](Argument arg) {
|
||||||
|
return arg.has_value() && true_string(arg.value());
|
||||||
|
};
|
||||||
|
|
||||||
if(arguments["kiosk"] == "true")
|
auto kioskArg = arguments["kiosk"];
|
||||||
|
if (kioskArg.has_value())
|
||||||
{
|
{
|
||||||
fullscreen = true;
|
fullscreen = true_string(kioskArg.value());
|
||||||
Client::Ref().SetPref("Fullscreen", fullscreen);
|
Client::Ref().SetPref("Fullscreen", fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(arguments["redirect"] == "true")
|
if (true_arg(arguments["redirect"]))
|
||||||
{
|
{
|
||||||
FILE *new_stdout = freopen("stdout.log", "w", stdout);
|
FILE *new_stdout = freopen("stdout.log", "w", stdout);
|
||||||
FILE *new_stderr = freopen("stderr.log", "w", stderr);
|
FILE *new_stderr = freopen("stderr.log", "w", stderr);
|
||||||
@ -804,26 +754,33 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(arguments["scale"].length())
|
auto scaleArg = arguments["scale"];
|
||||||
|
if (scaleArg.has_value())
|
||||||
{
|
{
|
||||||
scale = arguments["scale"].ToNumber<int>();
|
try
|
||||||
|
{
|
||||||
|
scale = scaleArg.value().ToNumber<int>();
|
||||||
Client::Ref().SetPref("Scale", scale);
|
Client::Ref().SetPref("Scale", scale);
|
||||||
}
|
}
|
||||||
|
catch (const std::runtime_error &e)
|
||||||
auto clientConfig = [](ByteString cmdlineValue, ByteString configName, ByteString defaultValue) {
|
|
||||||
ByteString value;
|
|
||||||
if (cmdlineValue.length())
|
|
||||||
{
|
{
|
||||||
value = cmdlineValue;
|
std::cerr << "failed to set scale: " << e.what() << std::endl;
|
||||||
if (value == "false")
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto clientConfig = [](Argument arg, ByteString name, ByteString defaultValue) {
|
||||||
|
ByteString value;
|
||||||
|
if (arg.has_value())
|
||||||
|
{
|
||||||
|
if (value == "")
|
||||||
{
|
{
|
||||||
value = defaultValue;
|
value = defaultValue;
|
||||||
}
|
}
|
||||||
Client::Ref().SetPref(configName, value);
|
Client::Ref().SetPref(name, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = Client::Ref().GetPrefByteString(configName, defaultValue);
|
value = Client::Ref().GetPrefByteString(name, defaultValue);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
@ -831,9 +788,7 @@ int main(int argc, char * argv[])
|
|||||||
ByteString cafileString = clientConfig(arguments["cafile"], "CAFile", "");
|
ByteString cafileString = clientConfig(arguments["cafile"], "CAFile", "");
|
||||||
ByteString capathString = clientConfig(arguments["capath"], "CAPath", "");
|
ByteString capathString = clientConfig(arguments["capath"], "CAPath", "");
|
||||||
|
|
||||||
bool disableNetwork = false;
|
bool disableNetwork = true_arg(arguments["disable-network"]);
|
||||||
if (arguments.find("disable-network") != arguments.end())
|
|
||||||
disableNetwork = true;
|
|
||||||
|
|
||||||
Client::Ref().Initialise(proxyString, cafileString, capathString, disableNetwork);
|
Client::Ref().Initialise(proxyString, cafileString, capathString, disableNetwork);
|
||||||
|
|
||||||
@ -871,11 +826,7 @@ int main(int argc, char * argv[])
|
|||||||
engine->SetFastQuit(Client::Ref().GetPrefBool("FastQuit", true));
|
engine->SetFastQuit(Client::Ref().GetPrefBool("FastQuit", true));
|
||||||
|
|
||||||
#if !defined(DEBUG)
|
#if !defined(DEBUG)
|
||||||
bool enableBluescreen = true;
|
bool enableBluescreen = !true_arg(arguments["disable-bluescreen"]);
|
||||||
if(arguments["nobluescreen"] == "true")
|
|
||||||
{
|
|
||||||
enableBluescreen = false;
|
|
||||||
}
|
|
||||||
if (enableBluescreen)
|
if (enableBluescreen)
|
||||||
{
|
{
|
||||||
//Get ready to catch any dodgy errors
|
//Get ready to catch any dodgy errors
|
||||||
@ -899,23 +850,24 @@ int main(int argc, char * argv[])
|
|||||||
gameController = new GameController();
|
gameController = new GameController();
|
||||||
engine->ShowWindow(gameController->GetView());
|
engine->ShowWindow(gameController->GetView());
|
||||||
|
|
||||||
if(arguments["open"].length())
|
auto openArg = arguments["open"];
|
||||||
|
if (openArg.has_value())
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cout << "Loading " << arguments["open"] << std::endl;
|
std::cout << "Loading " << openArg.value() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (Platform::FileExists(arguments["open"]))
|
if (Platform::FileExists(openArg.value()))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::vector<char> gameSaveData;
|
std::vector<char> gameSaveData;
|
||||||
if (!Platform::ReadFile(gameSaveData, arguments["open"]))
|
if (!Platform::ReadFile(gameSaveData, openArg.value()))
|
||||||
{
|
{
|
||||||
new ErrorMessage("Error", "Could not read file");
|
new ErrorMessage("Error", "Could not read file");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SaveFile * newFile = new SaveFile(arguments["open"]);
|
SaveFile * newFile = new SaveFile(openArg.value());
|
||||||
GameSave * newSave = new GameSave(std::move(gameSaveData));
|
GameSave * newSave = new GameSave(std::move(gameSaveData));
|
||||||
newFile->SetGameSave(newSave);
|
newFile->SetGameSave(newSave);
|
||||||
gameController->LoadSaveFile(newFile);
|
gameController->LoadSaveFile(newFile);
|
||||||
@ -934,18 +886,18 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments["ptsave"].length())
|
auto ptsaveArg = arguments["ptsave"];
|
||||||
|
if (ptsaveArg.has_value())
|
||||||
{
|
{
|
||||||
engine->g->fillrect((engine->GetWidth()/2)-101, (engine->GetHeight()/2)-26, 202, 52, 0, 0, 0, 210);
|
engine->g->fillrect((engine->GetWidth()/2)-101, (engine->GetHeight()/2)-26, 202, 52, 0, 0, 0, 210);
|
||||||
engine->g->drawrect((engine->GetWidth()/2)-100, (engine->GetHeight()/2)-25, 200, 50, 255, 255, 255, 180);
|
engine->g->drawrect((engine->GetWidth()/2)-100, (engine->GetHeight()/2)-25, 200, 50, 255, 255, 255, 180);
|
||||||
engine->g->drawtext((engine->GetWidth()/2)-(Graphics::textwidth("Loading save...")/2), (engine->GetHeight()/2)-5, "Loading save...", style::Colour::InformationTitle.Red, style::Colour::InformationTitle.Green, style::Colour::InformationTitle.Blue, 255);
|
engine->g->drawtext((engine->GetWidth()/2)-(Graphics::textwidth("Loading save...")/2), (engine->GetHeight()/2)-5, "Loading save...", style::Colour::InformationTitle.Red, style::Colour::InformationTitle.Green, style::Colour::InformationTitle.Blue, 255);
|
||||||
|
|
||||||
blit(engine->g->vid);
|
blit(engine->g->vid);
|
||||||
ByteString ptsaveArg = arguments["ptsave"];
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ByteString saveIdPart;
|
ByteString saveIdPart;
|
||||||
if (ByteString::Split split = arguments["ptsave"].SplitBy(':'))
|
if (ByteString::Split split = ptsaveArg.value().SplitBy(':'))
|
||||||
{
|
{
|
||||||
if (split.Before() != "ptsave")
|
if (split.Before() != "ptsave")
|
||||||
throw std::runtime_error("Not a ptsave link");
|
throw std::runtime_error("Not a ptsave link");
|
||||||
|
Reference in New Issue
Block a user