Browse Source

Master server/client cleanups and refactoring

Josh Engebretson 9 years ago
parent
commit
cbae3c9b03

+ 0 - 0
Source/AtomicMasterServer/app.js → Script/AtomicMasterServer/app.js


+ 0 - 0
Source/AtomicMasterServer/package.json → Script/AtomicMasterServer/package.json


+ 45 - 6
Source/Atomic/Network/MasterServerClient.cpp

@@ -8,6 +8,7 @@
 #include "../Network/NetworkPriority.h"
 #include "../Network/NetworkPriority.h"
 #include "../Network/Network.h"
 #include "../Network/Network.h"
 #include "../Core/Profiler.h"
 #include "../Core/Profiler.h"
+#include "../Core/CoreEvents.h"
 #include "../Network/NetworkEvents.h"
 #include "../Network/NetworkEvents.h"
 
 
 #include <rapidjson/document.h>
 #include <rapidjson/document.h>
@@ -18,7 +19,6 @@ namespace Atomic
 {
 {
 
 
 MasterServerClient::MasterServerClient(Context *context) :
 MasterServerClient::MasterServerClient(Context *context) :
-
         readingMasterMessageLength(true),
         readingMasterMessageLength(true),
         Object(context),
         Object(context),
         udpSecondsTillRetry_(0.5f),
         udpSecondsTillRetry_(0.5f),
@@ -31,7 +31,7 @@ MasterServerClient::MasterServerClient(Context *context) :
         masterTCPConnection_(NULL),
         masterTCPConnection_(NULL),
         clientToServerSocket_(NULL)
         clientToServerSocket_(NULL)
 {
 {
-
+    SubscribeToEvent(E_BEGINFRAME, HANDLER(MasterServerClient, HandleBeginFrame));
 }
 }
 
 
 MasterServerClient::~MasterServerClient()
 MasterServerClient::~MasterServerClient()
@@ -42,7 +42,8 @@ MasterServerClient::~MasterServerClient()
     }
     }
 }
 }
 
 
-void MasterServerClient::ConnectToMaster(const String &address, unsigned short port) {
+void MasterServerClient::ConnectToMaster(const String &address, unsigned short port)
+{
     PROFILE(ConnectToMaster);
     PROFILE(ConnectToMaster);
 
 
     if (connectToMasterState_ != MASTER_NOT_CONNECTED)
     if (connectToMasterState_ != MASTER_NOT_CONNECTED)
@@ -66,7 +67,8 @@ void MasterServerClient::DisconnectFromMaster()
     SetConnectToMasterState(MASTER_NOT_CONNECTED);
     SetConnectToMasterState(MASTER_NOT_CONNECTED);
 }
 }
 
 
-void MasterServerClient::ConnectToMasterAndRegister(const String &address, unsigned short port, const String& serverName) {
+void MasterServerClient::ConnectToMasterAndRegister(const String &address, unsigned short port, const String& serverName)
+{
     PROFILE(ConnectToMaster);
     PROFILE(ConnectToMaster);
 
 
     if (connectToMasterState_ != MASTER_NOT_CONNECTED)
     if (connectToMasterState_ != MASTER_NOT_CONNECTED)
@@ -114,7 +116,9 @@ void MasterServerClient::RegisterServerWithMaster(const String &name)
     sprintf(str, "%d.%d.%d.%d", (unsigned int)ip[0], (unsigned int)ip[1], (unsigned int)ip[2], (unsigned int)ip[3]);
     sprintf(str, "%d.%d.%d.%d", (unsigned int)ip[0], (unsigned int)ip[1], (unsigned int)ip[2], (unsigned int)ip[3]);
 
 
     Atomic::Network* network = GetSubsystem<Network>();
     Atomic::Network* network = GetSubsystem<Network>();
-    unsigned int localPort = network->GetServerPort();
+
+    // FIXME
+    unsigned int localPort = 9;//network->GetServerPort();
 
 
     String msg = String("{") +
     String msg = String("{") +
                  String("\"cmd\":") + String("\"registerServer\",") +
                  String("\"cmd\":") + String("\"registerServer\",") +
@@ -281,9 +285,18 @@ void MasterServerClient::ConnectToMasterUpdate(float dt)
 
 
 }
 }
 
 
+void MasterServerClient::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
+{
+    using namespace BeginFrame;
+
+    Update(eventData[P_TIMESTEP].GetFloat());
+}
+
+
 void MasterServerClient::SetConnectToMasterState(ConnectToMasterState state)
 void MasterServerClient::SetConnectToMasterState(ConnectToMasterState state)
 {
 {
     Atomic::Network* network = GetSubsystem<Network>();
     Atomic::Network* network = GetSubsystem<Network>();
+
     kNet::Network* kNetNetwork = network->GetKnetNetwork();
     kNet::Network* kNetNetwork = network->GetKnetNetwork();
 
 
     if (connectToMasterState_ == MASTER_NOT_CONNECTED &&
     if (connectToMasterState_ == MASTER_NOT_CONNECTED &&
@@ -553,4 +566,30 @@ void MasterServerClient::HandleMasterServerMessage(const String &msg)
 }
 }
 
 
 
 
-}
+bool MasterServerClient::StartServerAndRegisterWithMaster(unsigned short serverPort, const String &masterAddress,
+                                                          unsigned short masterPort, const String &serverName)
+{
+    Network* network = GetSubsystem<Network>();
+
+    if (!network)
+    {
+        LOGERROR("MasterServerClient::StartServerAndRegisterWithMaster - Unable to get Network subsystem");
+        return false;
+    }
+
+    // First start the server
+    bool rc = network->StartServer(serverPort);
+
+    if (!rc)
+    {
+        LOGERROR("MasterServerClient::StartServerAndRegisterWithMaster - Unable to start server");
+        return false;
+    }
+
+    // Connect to the master server
+    ConnectToMasterAndRegister(masterAddress, masterPort, serverName);
+
+    return true;
+}
+
+}

+ 18 - 7
Source/Atomic/Network/MasterServerClient.h

@@ -53,37 +53,48 @@ struct RemoteGameServer
 };
 };
 
 
 
 
-/// %MasterServerClient subsystem.
+/// Client for master server, see Script/AtomicMasterServer for example master server implementation
 class ATOMIC_API MasterServerClient : public Object
 class ATOMIC_API MasterServerClient : public Object
 {
 {
     OBJECT(MasterServerClient);
     OBJECT(MasterServerClient);
 
 
 public:
 public:
+
     /// Construct.
     /// Construct.
     MasterServerClient(Context* context);
     MasterServerClient(Context* context);
     /// Destruct.
     /// Destruct.
     ~MasterServerClient();
     ~MasterServerClient();
 
 
-    /// Process messages
-    void Update(float timeStep);
-
     void ConnectToMaster(const String& address, unsigned short port);
     void ConnectToMaster(const String& address, unsigned short port);
-    void DisconnectFromMaster();
 
 
-    void ConnectToMasterAndRegister(const String& address, unsigned short port, const String& serverName);
+    void DisconnectFromMaster();
 
 
     void RequestServerListFromMaster();
     void RequestServerListFromMaster();
+
     void ConnectToServerViaMaster(const String& serverId,
     void ConnectToServerViaMaster(const String& serverId,
                                   const String& internalAddress, unsigned short internalPort,
                                   const String& internalAddress, unsigned short internalPort,
                                   const String& externalAddress, unsigned short externalPort,
                                   const String& externalAddress, unsigned short externalPort,
                                   Scene* scene);
                                   Scene* scene);
 
 
+    void ConnectToMasterAndRegister(const String& address, unsigned short port, const String& serverName);
+
+    /// Convenience method to start server and register it with the master server
+    bool StartServerAndRegisterWithMaster(unsigned short serverPort, const String &masterAddress,
+                                          unsigned short masterPort, const String &serverName);
+
 private:
 private:
+
+    void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
+
     void SendMessageToMasterServer(const String& message);
     void SendMessageToMasterServer(const String& message);
+
     void HandleMasterServerMessage(const String& msg);
     void HandleMasterServerMessage(const String& msg);
 
 
     void RegisterServerWithMaster(const String& serverName);
     void RegisterServerWithMaster(const String& serverName);
 
 
+    /// Process messages
+    void Update(float timeStep);
+
     float udpConnectionSecondsRemaining_;
     float udpConnectionSecondsRemaining_;
     float udpSecondsTillRetry_;
     float udpSecondsTillRetry_;
 
 
@@ -125,4 +136,4 @@ private:
     void CheckForNatPunchThroughRequests(float dt);
     void CheckForNatPunchThroughRequests(float dt);
 };
 };
 
 
-}
+}

+ 3 - 51
Source/Atomic/Network/Network.cpp

@@ -39,6 +39,8 @@
 #include "../Scene/Scene.h"
 #include "../Scene/Scene.h"
 
 
 #include <kNet/include/kNet.h>
 #include <kNet/include/kNet.h>
+#include <kNet/include/kNet/EndPoint.h>
+
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
 
 
@@ -54,7 +56,7 @@ Network::Network(Context* context) :
     simulatedPacketLoss_(0.0f),
     simulatedPacketLoss_(0.0f),
     updateInterval_(1.0f / (float)DEFAULT_UPDATE_FPS),
     updateInterval_(1.0f / (float)DEFAULT_UPDATE_FPS),
     updateAcc_(0.0f),
     updateAcc_(0.0f),
-    masterServerClient_(context)
+    serverPort_(0xFFFF)
 {
 {
     network_ = new kNet::Network();
     network_ = new kNet::Network();
 
 
@@ -204,11 +206,6 @@ void Network::ClientDisconnected(kNet::MessageConnection* connection)
     }
     }
 }
 }
 
 
-bool Network::ConnectSimple(const String& address, unsigned short port, Scene* scene)
-{
-    return Connect(address, port, scene, Variant::emptyVariantMap);
-}
-
 bool Network::ConnectWithExistingSocket(kNet::Socket* existingSocket, Scene* scene)
 bool Network::ConnectWithExistingSocket(kNet::Socket* existingSocket, Scene* scene)
 {
 {
     PROFILE(ConnectWithExistingSocket);
     PROFILE(ConnectWithExistingSocket);
@@ -535,8 +532,6 @@ void Network::Update(float timeStep)
     kNet::SharedPtr<kNet::NetworkServer> server = network_->GetServer();
     kNet::SharedPtr<kNet::NetworkServer> server = network_->GetServer();
     if (server)
     if (server)
         server->Process();
         server->Process();
-
-    masterServerClient_.Update(timeStep);
 }
 }
 
 
 void Network::PostUpdate(float timeStep)
 void Network::PostUpdate(float timeStep)
@@ -654,49 +649,6 @@ void Network::ConfigureNetworkSimulator()
         i->second_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
         i->second_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
 }
 }
 
 
-void Network::ClientConnectToMaster(const String& address, unsigned short port)
-{
-    masterServerClient_.ConnectToMaster(address, port);
-}
-
-void Network::ClientDisconnectFromMaster()
-{
-    masterServerClient_.DisconnectFromMaster();
-}
-
-void Network::RequestServerListFromMaster()
-{
-    masterServerClient_.RequestServerListFromMaster();
-}
-
-void Network::ClientConnectToServerViaMaster(const String &serverId,
-                                       const String &internalAddress, unsigned short internalPort,
-                                       const String &externalAddress, unsigned short externalPort,
-                                       Scene* scene)
-{
-    masterServerClient_.ConnectToServerViaMaster(serverId,
-                                                 internalAddress, internalPort,
-                                                 externalAddress, externalPort,
-                                                 scene);
-}
-
-bool Network::StartServerAndRegisterWithMaster(unsigned short serverPort, const String &masterAddress,
-                                               unsigned short masterPort, const String &serverName)
-{
-    // First start the server
-    bool rc = StartServer(serverPort);
-
-    if (!rc)
-    {
-        return false;
-    }
-
-    // Connect to the master server
-    masterServerClient_.ConnectToMasterAndRegister(masterAddress, masterPort, serverName);
-
-    return true;
-}
-
 void RegisterNetworkLibrary(Context* context)
 void RegisterNetworkLibrary(Context* context)
 {
 {
     NetworkPriority::RegisterObject(context);
     NetworkPriority::RegisterObject(context);

+ 8 - 26
Source/Atomic/Network/Network.h

@@ -26,11 +26,9 @@
 #include "../Core/Object.h"
 #include "../Core/Object.h"
 #include "../IO/VectorBuffer.h"
 #include "../IO/VectorBuffer.h"
 #include "../Network/Connection.h"
 #include "../Network/Connection.h"
-#include "../Network/MasterServerClient.h"
 
 
 #include <kNet/IMessageHandler.h>
 #include <kNet/IMessageHandler.h>
 #include <kNet/INetworkServerListener.h>
 #include <kNet/INetworkServerListener.h>
-#include <ThirdParty/kNet/include/kNet/EndPoint.h>
 
 
 namespace Atomic
 namespace Atomic
 {
 {
@@ -48,6 +46,8 @@ template <class T> unsigned MakeHash(kNet::MessageConnection* value)
 /// %Network subsystem. Manages client-server communications using the UDP protocol.
 /// %Network subsystem. Manages client-server communications using the UDP protocol.
 class ATOMIC_API Network : public Object, public kNet::IMessageHandler, public kNet::INetworkServerListener
 class ATOMIC_API Network : public Object, public kNet::IMessageHandler, public kNet::INetworkServerListener
 {
 {
+    friend class MasterServerClient;
+
     OBJECT(Network);
     OBJECT(Network);
 
 
 public:
 public:
@@ -68,29 +68,13 @@ public:
 
 
     /// Connect to a server using UDP protocol. Return true if connection process successfully started.
     /// Connect to a server using UDP protocol. Return true if connection process successfully started.
     bool Connect(const String& address, unsigned short port, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
     bool Connect(const String& address, unsigned short port, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
-
-    bool ConnectSimple(const String& address, unsigned short port, Scene* scene);
-
+    /// Connect to a server, reusing an existing Socket
     bool ConnectWithExistingSocket(kNet::Socket* existingSocket, Scene* scene);
     bool ConnectWithExistingSocket(kNet::Socket* existingSocket, Scene* scene);
 
 
-    void ClientConnectToMaster(const String& address, unsigned short port);
-    void ClientDisconnectFromMaster();
-
-    void ClientConnectToServerViaMaster(const String& serverId,
-                                        const String& internalAddress, unsigned short internalPort,
-                                        const String& externalAddress, unsigned short externalPort,
-                                        Scene* scene);
-    void RequestServerListFromMaster();
-
     /// Disconnect the connection to the server. If wait time is non-zero, will block while waiting for disconnect to finish.
     /// Disconnect the connection to the server. If wait time is non-zero, will block while waiting for disconnect to finish.
     void Disconnect(int waitMSec = 0);
     void Disconnect(int waitMSec = 0);
     /// Start a server on a port using UDP protocol. Return true if successful.
     /// Start a server on a port using UDP protocol. Return true if successful.
     bool StartServer(unsigned short port);
     bool StartServer(unsigned short port);
-
-    /// Start a server on a port using UDP protocol. Return true if successful.
-    /// Also register the server with the master server.
-    bool StartServerAndRegisterWithMaster(unsigned short serverPort, const String& masterAddress, unsigned short masterPort, const String& serverName);
-
     /// Stop the server.
     /// Stop the server.
     void StopServer();
     void StopServer();
     /// Broadcast a message with content ID to all client connections.
     /// Broadcast a message with content ID to all client connections.
@@ -158,11 +142,10 @@ public:
     /// Send outgoing messages after frame logic. Called by HandleRenderUpdate.
     /// Send outgoing messages after frame logic. Called by HandleRenderUpdate.
     void PostUpdate(float timeStep);
     void PostUpdate(float timeStep);
 
 
-    kNet::Network* GetKnetNetwork() { return network_; }
-
-    unsigned int GetServerPort() { return serverPort_; }
+    unsigned short GetServerPort() const { return serverPort_; }
 
 
 private:
 private:
+
     /// Handle begin frame event.
     /// Handle begin frame event.
     void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
     void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
     /// Handle render update frame event.
     /// Handle render update frame event.
@@ -175,6 +158,7 @@ private:
     void ConfigureNetworkSimulator();
     void ConfigureNetworkSimulator();
     void HandleClientConnected(StringHash eventType, VariantMap& eventData);
     void HandleClientConnected(StringHash eventType, VariantMap& eventData);
 
 
+    kNet::Network* GetKnetNetwork() { return network_; }
 
 
     /// kNet instance.
     /// kNet instance.
     kNet::Network* network_;
     kNet::Network* network_;
@@ -200,10 +184,8 @@ private:
     float updateAcc_;
     float updateAcc_;
     /// Package cache directory.
     /// Package cache directory.
     String packageCacheDir_;
     String packageCacheDir_;
-    // MasterServerClient
-    MasterServerClient masterServerClient_;
-    // Server Port
-    unsigned int serverPort_;
+
+    unsigned short serverPort_;
 };
 };
 
 
 /// Register Network library objects.
 /// Register Network library objects.

+ 16 - 1
Source/ToolCore/JSBind/JSBHeaderVisitor.h

@@ -201,6 +201,11 @@ public:
         if (!jtype)
         if (!jtype)
         {
         {
             jtype = processTypeConversion(type);
             jtype = processTypeConversion(type);
+
+            // explicit script string -> StringHash required
+            if (jtype && jtype->asStringHashType())
+                isReference = false;
+
             if (fst.isUnsigned() && jtype->asPrimitiveType())
             if (fst.isUnsigned() && jtype->asPrimitiveType())
                 jtype->asPrimitiveType()->isUnsigned_ = true;
                 jtype->asPrimitiveType()->isUnsigned_ = true;
 
 
@@ -315,13 +320,23 @@ public:
             for (unsigned i = 0; i < function->argumentCount(); i++)
             for (unsigned i = 0; i < function->argumentCount(); i++)
             {
             {
                 Symbol* symbol = function->argumentAt(i);
                 Symbol* symbol = function->argumentAt(i);
+
                 if (symbol->isArgument())
                 if (symbol->isArgument())
                 {
                 {
                     Argument* arg = symbol->asArgument();
                     Argument* arg = symbol->asArgument();
 
 
                     JSBFunctionType* ftype = processFunctionArgType(arg);
                     JSBFunctionType* ftype = processFunctionArgType(arg);
+
                     if (!ftype)
                     if (!ftype)
-                        return NULL;
+                    {
+                        // if we don't have an initializer, the function cannot be bound
+                        // as unscriptable type
+                        if (!arg->hasInitializer())
+                            return NULL;
+
+                        // otherwise, break and the optional args will be ignored
+                        break;
+                    }
 
 
                     if (arg->hasInitializer())
                     if (arg->hasInitializer())
                     {
                     {