Start.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #include <csignal>
  2. #include <cstdlib>
  3. #include <Datei.h>
  4. #include <fstream>
  5. #include <Globals.h>
  6. #include <iostream>
  7. #include <Klient.h>
  8. #ifndef _WINDOWS
  9. # include <sys/resource.h>
  10. #else
  11. # define NO_MAIN
  12. # include <main.h>
  13. #endif
  14. #include <AsynchronCall.h>
  15. #include <Console.h>
  16. #include <Logging.h>
  17. #include <Text.h>
  18. #include <Zeit.h>
  19. #include "Chat.h"
  20. #include "ChunkMap.h"
  21. #include "Server.h"
  22. FactoryCraftServer* mserver = 0;
  23. #ifdef _WINDOWS
  24. LONG WINAPI exceptionHandler(struct _EXCEPTION_POINTERS* apExceptionInfo)
  25. {
  26. Sleep(10000);
  27. Logging::error() << "Creating dump";
  28. createMinidump(apExceptionInfo);
  29. if (mserver)
  30. {
  31. Logging::error()
  32. << "The server terminated unexpectedly. Trying to save game "
  33. "progress.";
  34. mserver->close();
  35. }
  36. return EXCEPTION_CONTINUE_SEARCH;
  37. }
  38. #endif
  39. void onError(int i)
  40. {
  41. Sleep(10000);
  42. Logging::error() << "Creating dump";
  43. createMinidump(0);
  44. if (mserver)
  45. {
  46. Logging::error()
  47. << "The server terminated unexpectedly. Trying to save game "
  48. "progress.";
  49. mserver->close();
  50. }
  51. }
  52. void onExit()
  53. {
  54. Sleep(10000);
  55. Logging::info() << "Programm exited";
  56. onError(0);
  57. }
  58. bool exited = false;
  59. class StatusBar : public StickyConsoleContent
  60. {
  61. public:
  62. StatusBar()
  63. : StickyConsoleContent()
  64. {}
  65. int print() const override
  66. {
  67. if (!exited && Game::INSTANCE)
  68. {
  69. std::cout << "\r\33[0K"; // erase current line
  70. int tps = Game::INSTANCE->getTicksPerSecond();
  71. std::cout << "Players: " << Game::INSTANCE->getPlayerCount()
  72. << "\tChunks: " << Game::INSTANCE->getChunkCount()
  73. << "\ttps: ";
  74. if (tps < 15)
  75. { // red
  76. std::cout << "\033[1;31m";
  77. }
  78. else if (tps < 20)
  79. { // yellow
  80. std::cout << "\033[1;33m";
  81. }
  82. else
  83. { // green
  84. std::cout << "\033[1;32m";
  85. }
  86. std::cout << tps << /* reset color */ "\033[0m"
  87. << "\tAverage Tick Time: "
  88. << Game::INSTANCE->getAverageTickTime();
  89. return 1;
  90. }
  91. return 0;
  92. }
  93. };
  94. int main()
  95. {
  96. #ifdef _WINDOWS
  97. SetUnhandledExceptionFilter(exceptionHandler);
  98. #endif
  99. Framework::initFramework();
  100. Game::consoleHandler = new ConsoleHandler();
  101. #ifndef _WINDOWS
  102. struct rlimit core_limits;
  103. core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
  104. setrlimit(RLIMIT_CORE, &core_limits);
  105. #endif
  106. Zeit* z = getZeit();
  107. Text* pfad = new Text("log/");
  108. pfad->append(z->getZeit("y-m-d_h-i-s.log"));
  109. z->release();
  110. Datei* logFile = new Datei(pfad);
  111. Logging::LoggingChannel* fileLogger
  112. = new Logging::FileLoggingChannel(logFile);
  113. fileLogger->setFormat(Logging::LoggingFormatBuilder()
  114. .datetime("h:i:s")
  115. .level(false)
  116. .text(": ")
  117. .build());
  118. Logging::zLoggingHandler()->addChannel(fileLogger);
  119. Logging::zLoggingHandler()->removeLoggingChannel(
  120. Logging::LogLevel::Error, fileLogger);
  121. Logging::zLoggingHandler()->removeLoggingChannel(
  122. Logging::LogLevel::Warning, fileLogger);
  123. Logging::LoggingChannel* errorFileLogger = new Logging::FileLoggingChannel(
  124. dynamic_cast<Datei*>(logFile->getThis()));
  125. errorFileLogger->setFormat(Logging::LoggingFormatBuilder()
  126. .datetime("h:i:s")
  127. .level()
  128. .fileName()
  129. .functionName()
  130. .text("(")
  131. .fileLine(false)
  132. .text("): ")
  133. .build());
  134. Framework::Logging::zLoggingHandler()->addChannel(
  135. Logging::LogLevel::Warning,
  136. dynamic_cast<Logging::LoggingChannel*>(errorFileLogger->getThis()));
  137. Framework::Logging::zLoggingHandler()->addChannel(
  138. Logging::LogLevel::Error, errorFileLogger);
  139. Logging::LoggingChannel* consoleLogger
  140. = new Logging::ConsoleHandlerLoggingChannel(
  141. dynamic_cast<ConsoleHandler*>(Game::consoleHandler->getThis()));
  142. consoleLogger->setFormat(
  143. Logging::LoggingFormatBuilder()
  144. .color(Logging::LogLevel::Debug, Color::LIGHT_BLUE)
  145. .color(Logging::LogLevel::Trace, Color::LIGHT_CYAN)
  146. .datetime("h:i:s")
  147. .level(false)
  148. .text(": ")
  149. .build());
  150. Framework::Logging::zLoggingHandler()->addChannel(consoleLogger);
  151. Framework::Logging::zLoggingHandler()->removeLoggingChannel(
  152. Logging::LogLevel::Error, consoleLogger);
  153. Framework::Logging::zLoggingHandler()->removeLoggingChannel(
  154. Logging::LogLevel::Warning, consoleLogger);
  155. Logging::LoggingChannel* errorConsoleLogger
  156. = new Logging::ConsoleHandlerLoggingChannel(
  157. dynamic_cast<ConsoleHandler*>(Game::consoleHandler->getThis()));
  158. errorConsoleLogger->setFormat(
  159. Logging::LoggingFormatBuilder()
  160. .color(Logging::LogLevel::Warning, Color::LIGHT_YELLOW)
  161. .color(Logging::LogLevel::Error, Color::LIGHT_RED)
  162. .datetime("h:i:s")
  163. .level()
  164. .fileName()
  165. .functionName()
  166. .text("(")
  167. .fileLine(false)
  168. .text("): ")
  169. .build());
  170. Framework::Logging::zLoggingHandler()->addChannel(
  171. Logging::LogLevel::Warning,
  172. dynamic_cast<Logging::LoggingChannel*>(errorConsoleLogger->getThis()));
  173. Framework::Logging::zLoggingHandler()->addChannel(
  174. Logging::LogLevel::Error, errorConsoleLogger);
  175. Game::consoleInput = new InputLine();
  176. Game::consoleHandler->addContent(
  177. Game::consoleInput, ConsoleContentPosition::Bottom);
  178. Game::consoleHandler->addContent(
  179. new StatusBar(), ConsoleContentPosition::Bottom);
  180. Logging::info() << "Starting ...";
  181. Logging::info() << "Loading config file fcInit.ini ...";
  182. InitDatei* dat = new InitDatei("fcInit.ini");
  183. if (!dat->laden())
  184. {
  185. Logging::error() << "Datei konnte nicht gelesen werden. Das Programm "
  186. "wird geschlossen.";
  187. dat->release();
  188. Game::consoleHandler->release();
  189. Framework::releaseFramework();
  190. return 1;
  191. }
  192. const char* wichtig[]
  193. = {"SSLPort", "SSLCert", "SSLKey", "SSLPasswort", "Port"};
  194. for (const char* w : wichtig)
  195. {
  196. if (!dat->wertExistiert(w))
  197. {
  198. Logging::error()
  199. << "The value '" << w
  200. << "' was not specified. The Server can not start.";
  201. dat->release();
  202. Game::consoleHandler->release();
  203. Framework::releaseFramework();
  204. return 1;
  205. }
  206. }
  207. mserver = new FactoryCraftServer(dat);
  208. std::atexit(onExit);
  209. signal(SIGTERM, onError);
  210. signal(SIGSEGV, onError);
  211. signal(SIGILL, onError);
  212. signal(SIGABRT, onError);
  213. signal(SIGFPE, onError);
  214. signal(SIGINT, onError);
  215. Logging::info() << "The Server is now running.";
  216. mserver->run();
  217. exited = 1;
  218. mserver->release();
  219. mserver = 0;
  220. if (Game::INSTANCE)
  221. {
  222. Game* tmp = Game::INSTANCE;
  223. tmp->requestStop();
  224. tmp->warteAufThread(100000000);
  225. tmp->release();
  226. Game::INSTANCE = 0;
  227. }
  228. dat->release();
  229. Logging::info() << "The server was shut down successfully.";
  230. Game::consoleHandler->release();
  231. Framework::releaseFramework();
  232. return 0;
  233. }