Start.cpp 8.1 KB

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