Ver Fonte

add console command to shutdown the server without unsaved game data

Kolja Strohm há 1 ano atrás
pai
commit
6424fa64d5

+ 3 - 0
FactoryCraft/Game.cpp

@@ -451,6 +451,9 @@ void Game::thread()
         }
     }
     save();
+    generator->exitAndWait();
+    loader->exitAndWait();
+    ticker->exitAndWait();
 }
 
 void Game::api(Framework::InMemoryBuffer* zRequest, GameClient* zOrigin)

+ 0 - 1
FactoryCraft/Server.cpp

@@ -121,7 +121,6 @@ void FactoryCraftServer::close()
     EnterCriticalSection(&cs);
     for (int i = 0; i < klients->getEintragAnzahl(); i++)
         klients->z(i)->absturz();
-    klients = (RCArray<FCKlient>*)klients->release();
     Game::INSTANCE->save();
     LeaveCriticalSection(&cs);
 }

+ 21 - 3
FactoryCraft/Start.cpp

@@ -8,6 +8,7 @@
 #include <sys/resource.h>
 #include <Text.h>
 #include <Zeit.h>
+#include <AsynchronCall.h>
 
 #include "Server.h"
 
@@ -15,8 +16,11 @@ FactoryCraftServer* mserver = 0;
 
 void exit()
 {
-    std::cout << "Der Server wird beendet...\n";
-    if (mserver) mserver->close();
+    if (mserver)
+    {
+        std::cout << "Der Server wurde unerwartet beendet. Es wird versucht den spielfortschritt zu speichern.\n";
+        mserver->close();
+    }
 }
 
 int main()
@@ -81,12 +85,26 @@ int main()
     signal(SIGFPE, exit);
     signal(SIGINT, exit);
 
+    new Framework::AsynchronCall("Commander", []() { 
+        while (mserver)
+        {
+            std::string line;
+            std::getline(std::cin, line);
+            if (Text(line.c_str()) == Text("exit"))
+            {
+                std::cout << "Der Server wird beended und der Spielfortschritt wird gespeichert.\n";
+                mserver->close();
+                return;
+            }
+        }
+    });
+
     std::cout << "Der Server läuft. Startforgang beendet.\n";
     mserver->run();
     mserver->release();
     mserver = 0;
     dat->release();
-    std::cout << "Der Server ist heruntergefahren.\n";
+    std::cout << "Der Server ist erfolgreich heruntergefahren.\n";
     file.close();
     std::cout.rdbuf(sbuf);
     Framework::releaseFramework();

+ 11 - 7
FactoryCraft/TickOrganizer.cpp

@@ -14,13 +14,6 @@ TickOrganizer::TickOrganizer()
 
 TickOrganizer::~TickOrganizer()
 {
-    queue->requestExit();
-    for (int i = 0; i < workerCount; i++)
-    {
-        workers[i]->warteAufThread(10000);
-        workers[i]->ende();
-        workers[i]->release();
-    }
     queue->release();
     delete[] workers;
 }
@@ -60,4 +53,15 @@ void TickOrganizer::removeTickSource(Tickable* zObj)
         }
     }
     sourceCs.unlock();
+}
+
+void TickOrganizer::exitAndWait()
+{
+    queue->requestExit();
+    for (int i = 0; i < workerCount; i++)
+    {
+        workers[i]->warteAufThread(1000000);
+        workers[i]->ende();
+        workers[i]->release();
+    }
 }

+ 2 - 0
FactoryCraft/TickOrganizer.h

@@ -22,4 +22,6 @@ public:
 
     void addTickSource(Tickable* zObj);
     void removeTickSource(Tickable* zObj);
+
+    void exitAndWait();
 };

+ 5 - 0
FactoryCraft/TickQueue.cpp

@@ -67,6 +67,11 @@ Tickable* TickQueue::zNext(bool& waiting)
         hasNoBlocks.notify_all();
         lk.lock();
         waiting = 1;
+        if (exit)
+        {
+            lk.unlock();
+            return 0;
+        }
         hasBlocks.wait(
             lk, [this] { return readPosition < writePosition || exit; });
         waiting = 0;

+ 2 - 3
FactoryCraft/TickWorker.cpp

@@ -11,9 +11,7 @@ TickWorker::TickWorker(TickQueue* queue)
 }
 
 TickWorker::~TickWorker()
-{
-    queue->release();
-}
+{}
 
 void TickWorker::thread()
 {
@@ -23,6 +21,7 @@ void TickWorker::thread()
         zTick->tick(queue);
         zTick = queue->zNext(waiting);
     }
+    std::cout << "exiting tick worker " << GetThreadId(this->getThreadHandle());
 }
 
 bool TickWorker::isWaiting() const