182 Zeilen
4.4 KiB
C++
182 Zeilen
4.4 KiB
C++
/**
|
|
* server/src/main.cpp
|
|
*
|
|
* This file is part of the traintastic source code.
|
|
*
|
|
* Copyright (C) 2019-2024 Reinder Feenstra
|
|
*
|
|
* 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 2
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <functional>
|
|
#include "options.hpp"
|
|
#include "traintastic/traintastic.hpp"
|
|
#include "log/log.hpp"
|
|
#include <traintastic/locale/locale.hpp>
|
|
#include <traintastic/utils/standardpaths.hpp>
|
|
#ifdef __unix__
|
|
#include "os/unix/daemonize.hpp"
|
|
#include "os/unix/writepidfile.hpp"
|
|
#include "os/unix/setgroupid.hpp"
|
|
#include "os/unix/setuserid.hpp"
|
|
#elif defined(WIN32)
|
|
#include "os/windows/consolewindow.hpp"
|
|
#include "os/windows/trayicon.hpp"
|
|
#endif
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
// parse command line options:
|
|
const Options options(argc, argv);
|
|
|
|
std::filesystem::path dataDir{options.dataDir};
|
|
if(dataDir.empty())
|
|
{
|
|
#ifdef __unix__
|
|
if(const char* home = getenv("HOME"))
|
|
dataDir += std::filesystem::path(home) / ".config" / "traintastic-server";
|
|
#elif defined(WIN32)
|
|
dataDir = getLocalAppDataPath() / "traintastic" / "server";
|
|
#endif
|
|
}
|
|
|
|
bool enableConsoleLogger = true;
|
|
|
|
#ifdef __unix__
|
|
if(options.daemonize)
|
|
{
|
|
enableConsoleLogger = false;
|
|
Unix::daemonize(dataDir);
|
|
}
|
|
|
|
try
|
|
{
|
|
if(!options.pidFile.empty())
|
|
Unix::writePIDFile(options.pidFile);
|
|
|
|
if(!options.group.empty())
|
|
Unix::setGroupID(options.group);
|
|
|
|
if(!options.user.empty())
|
|
Unix::setUserID(options.user, options.group.empty());
|
|
}
|
|
catch(const std::exception& e)
|
|
{
|
|
if(!options.daemonize)
|
|
std::cerr << e.what() << std::endl;
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#elif defined(WIN32)
|
|
if(options.tray)
|
|
{
|
|
Windows::setConsoleWindowVisible(false);
|
|
enableConsoleLogger = Windows::hasConsoleWindow();
|
|
}
|
|
#endif
|
|
|
|
const auto localePath = getLocalePath();
|
|
try
|
|
{
|
|
Locale::instance = std::make_unique<Locale>(localePath / "en-us.lang", std::make_unique<Locale>(localePath / "neutral.lang"));
|
|
}
|
|
catch(const std::exception& e)
|
|
{
|
|
std::cerr << e.what() << std::endl;
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if(enableConsoleLogger)
|
|
Log::enableConsoleLogger();
|
|
|
|
int status = EXIT_SUCCESS;
|
|
bool restart = false;
|
|
|
|
do
|
|
{
|
|
{
|
|
const auto settings = Settings::getPreStartSettings(dataDir);
|
|
|
|
if(settings.memoryLoggerSize > 0)
|
|
Log::enableMemoryLogger(settings.memoryLoggerSize);
|
|
else
|
|
Log::disableMemoryLogger();
|
|
|
|
if(settings.enableFileLogger)
|
|
Log::enableFileLogger(dataDir / "log" / "traintastic.txt");
|
|
else
|
|
Log::disableFileLogger();
|
|
}
|
|
|
|
#ifdef WIN32
|
|
if(options.tray)
|
|
Windows::TrayIcon::add(restart);
|
|
#endif
|
|
|
|
try
|
|
{
|
|
Traintastic::instance = std::make_shared<Traintastic>(dataDir);
|
|
|
|
if(!restart) // initial startup
|
|
status = Traintastic::instance->run(options.world, options.simulate, options.online, options.power, options.run);
|
|
else
|
|
status = Traintastic::instance->run();
|
|
|
|
switch(status)
|
|
{
|
|
case Traintastic::ExitSuccess:
|
|
restart = false;
|
|
status = EXIT_SUCCESS;
|
|
break;
|
|
|
|
case Traintastic::Restart:
|
|
restart = true;
|
|
break;
|
|
|
|
case Traintastic::ExitFailure:
|
|
restart = false;
|
|
status = EXIT_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
catch(const std::exception& e)
|
|
{
|
|
std::cerr << e.what() << std::endl;
|
|
restart = false;
|
|
status = EXIT_FAILURE;
|
|
}
|
|
|
|
#ifdef WIN32
|
|
if(options.tray)
|
|
Windows::TrayIcon::remove();
|
|
#endif
|
|
|
|
if(Traintastic::instance)
|
|
{
|
|
#ifndef NDEBUG
|
|
std::weak_ptr<Traintastic> weak = Traintastic::instance;
|
|
#endif
|
|
Traintastic::instance->destroy(); // notify others to release the object
|
|
Traintastic::instance.reset();
|
|
#ifndef NDEBUG
|
|
assert(weak.expired());
|
|
#endif
|
|
}
|
|
}
|
|
while(restart);
|
|
|
|
return status;
|
|
}
|