Start.cpp 7.6 KB

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