Start.cpp 7.6 KB

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