123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #include <csignal>
- #include <cstdlib>
- #include <Datei.h>
- #include <fstream>
- #include <Globals.h>
- #include <iostream>
- #include <Klient.h>
- #ifndef _WINDOWS
- # include <sys/resource.h>
- #else
- # define NO_MAIN
- # include <main.h>
- #endif
- #include <AsynchronCall.h>
- #include <Console.h>
- #include <Logging.h>
- #include <Text.h>
- #include <Zeit.h>
- #include "Chat.h"
- #include "ChunkMap.h"
- #include "Server.h"
- FactoryCraftServer* mserver = 0;
- #ifdef _WINDOWS
- LONG WINAPI exceptionHandler(struct _EXCEPTION_POINTERS* apExceptionInfo)
- {
- Sleep(10000);
- Logging::error() << "Creating dump";
- createMinidump(apExceptionInfo);
- if (mserver)
- {
- Logging::error()
- << "The server terminated unexpectedly. Trying to save game "
- "progress.";
- mserver->close();
- }
- return EXCEPTION_CONTINUE_SEARCH;
- }
- #endif
- void onError(int i)
- {
- Sleep(10000);
- Logging::error() << "Creating dump";
- createMinidump(0);
- if (mserver)
- {
- Logging::error()
- << "The server terminated unexpectedly. Trying to save game "
- "progress.";
- mserver->close();
- }
- }
- void onExit()
- {
- Sleep(10000);
- Logging::info() << "Programm exited";
- onError(0);
- }
- bool exited = false;
- class StatusBar : public StickyConsoleContent
- {
- public:
- StatusBar()
- : StickyConsoleContent()
- {}
- int print() const override
- {
- if (!exited && Game::INSTANCE)
- {
- std::cout << "\r\33[0K"; // erase current line
- int tps = Game::INSTANCE->getTicksPerSecond();
- std::cout << "Players: " << Game::INSTANCE->getPlayerCount()
- << "\tChunks: " << Game::INSTANCE->getChunkCount()
- << "\ttps: ";
- if (tps < 15)
- { // red
- std::cout << "\033[1;31m";
- }
- else if (tps < 20)
- { // yellow
- std::cout << "\033[1;33m";
- }
- else
- { // green
- std::cout << "\033[1;32m";
- }
- std::cout << tps << /* reset color */ "\033[0m"
- << "\tAverage Tick Time: "
- << Game::INSTANCE->getAverageTickTime();
- return 1;
- }
- return 0;
- }
- };
- int main()
- {
- #ifdef _WINDOWS
- SetUnhandledExceptionFilter(exceptionHandler);
- #endif
- Framework::initFramework();
- Game::consoleHandler = new ConsoleHandler();
- #ifndef _WINDOWS
- struct rlimit core_limits;
- core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_CORE, &core_limits);
- #endif
- Zeit* z = getZeit();
- Text* pfad = new Text("log/");
- pfad->append(z->getZeit("y-m-d_h-i-s.log"));
- z->release();
- Datei* logFile = new Datei(pfad);
- Logging::LoggingChannel* fileLogger
- = new Logging::FileLoggingChannel(logFile);
- fileLogger->setFormat(Logging::LoggingFormatBuilder()
- .datetime("h:i:s")
- .level(false)
- .text(": ")
- .build());
- Logging::zLoggingHandler()->addChannel(fileLogger);
- Logging::zLoggingHandler()->removeLoggingChannel(
- Logging::LogLevel::Error, fileLogger);
- Logging::zLoggingHandler()->removeLoggingChannel(
- Logging::LogLevel::Warning, fileLogger);
- Logging::LoggingChannel* errorFileLogger = new Logging::FileLoggingChannel(
- dynamic_cast<Datei*>(logFile->getThis()));
- errorFileLogger->setFormat(Logging::LoggingFormatBuilder()
- .datetime("h:i:s")
- .level()
- .fileName()
- .functionName()
- .text("(")
- .fileLine(false)
- .text("): ")
- .build());
- Framework::Logging::zLoggingHandler()->addChannel(
- Logging::LogLevel::Warning,
- dynamic_cast<Logging::LoggingChannel*>(errorFileLogger->getThis()));
- Framework::Logging::zLoggingHandler()->addChannel(
- Logging::LogLevel::Error, errorFileLogger);
- Logging::LoggingChannel* consoleLogger
- = new Logging::ConsoleHandlerLoggingChannel(
- dynamic_cast<ConsoleHandler*>(Game::consoleHandler->getThis()));
- consoleLogger->setFormat(
- Logging::LoggingFormatBuilder()
- .color(Logging::LogLevel::Debug, Color::LIGHT_BLUE)
- .color(Logging::LogLevel::Trace, Color::LIGHT_CYAN)
- .datetime("h:i:s")
- .level(false)
- .text(": ")
- .build());
- Framework::Logging::zLoggingHandler()->addChannel(consoleLogger);
- Framework::Logging::zLoggingHandler()->removeLoggingChannel(
- Logging::LogLevel::Error, consoleLogger);
- Framework::Logging::zLoggingHandler()->removeLoggingChannel(
- Logging::LogLevel::Warning, consoleLogger);
- Logging::LoggingChannel* errorConsoleLogger
- = new Logging::ConsoleHandlerLoggingChannel(
- dynamic_cast<ConsoleHandler*>(Game::consoleHandler->getThis()));
- errorConsoleLogger->setFormat(
- Logging::LoggingFormatBuilder()
- .color(Logging::LogLevel::Warning, Color::LIGHT_YELLOW)
- .color(Logging::LogLevel::Error, Color::LIGHT_RED)
- .datetime("h:i:s")
- .level()
- .fileName()
- .functionName()
- .text("(")
- .fileLine(false)
- .text("): ")
- .build());
- Framework::Logging::zLoggingHandler()->addChannel(
- Logging::LogLevel::Warning,
- dynamic_cast<Logging::LoggingChannel*>(errorConsoleLogger->getThis()));
- Framework::Logging::zLoggingHandler()->addChannel(
- Logging::LogLevel::Error, errorConsoleLogger);
- Game::consoleInput = new InputLine();
- Game::consoleHandler->addContent(
- Game::consoleInput, ConsoleContentPosition::Bottom);
- Game::consoleHandler->addContent(
- new StatusBar(), ConsoleContentPosition::Bottom);
- Logging::info() << "Starting ...";
- Logging::info() << "Loading config file fcInit.ini ...";
- InitDatei* dat = new InitDatei("fcInit.ini");
- if (!dat->laden())
- {
- Logging::error() << "Datei konnte nicht gelesen werden. Das Programm "
- "wird geschlossen.";
- dat->release();
- Game::consoleHandler->release();
- Framework::releaseFramework();
- return 1;
- }
- const char* wichtig[]
- = {"SSLPort", "SSLCert", "SSLKey", "SSLPasswort", "Port"};
- for (const char* w : wichtig)
- {
- if (!dat->wertExistiert(w))
- {
- Logging::error()
- << "The value '" << w
- << "' was not specified. The Server can not start.";
- dat->release();
- Game::consoleHandler->release();
- Framework::releaseFramework();
- return 1;
- }
- }
- mserver = new FactoryCraftServer(dat);
- std::atexit(onExit);
- signal(SIGTERM, onError);
- signal(SIGSEGV, onError);
- signal(SIGILL, onError);
- signal(SIGABRT, onError);
- signal(SIGFPE, onError);
- signal(SIGINT, onError);
- Logging::info() << "The Server is now running.";
- mserver->run();
- exited = 1;
- mserver->release();
- mserver = 0;
- if (Game::INSTANCE)
- {
- Game* tmp = Game::INSTANCE;
- tmp->requestStop();
- tmp->warteAufThread(100000000);
- tmp->release();
- Game::INSTANCE = 0;
- }
- dat->release();
- Logging::info() << "The server was shut down successfully.";
- Game::consoleHandler->release();
- Framework::releaseFramework();
- return 0;
- }
|