Browse Source

Send identity VariantMap on connecting to server.
Fixed possible bug in WriteString/ReadString if the string contains zeroes in the middle.

Lasse Öörni 14 years ago
parent
commit
f28728b3e2

+ 5 - 0
Bin/Data/Scripts/Chat.as

@@ -34,6 +34,11 @@ void InitUI()
     uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml");
     font = cache.GetResource("Font", "Fonts/Anonymous Pro.ttf");
 
+    engine.CreateDebugHud();
+    debugHud.style = uiStyle;
+    debugHud.mode = DEBUGHUD_SHOW_PROFILER;
+    debugHud.profilerText.opacity = 0.5;
+
     Cursor@ newCursor = Cursor("Cursor");
     newCursor.style = uiStyle;
     newCursor.position = IntVector2(graphics.width / 2, graphics.height / 2);

+ 1 - 1
Docs/ScriptAPI.dox

@@ -3445,7 +3445,7 @@ Properties:<br>
 Network
 
 Methods:<br>
-- bool Connect(const String&, uint16)
+- bool Connect(const String&, uint16, const VariantMap& arg2 = VariantMap ( ))
 - void Disconnect(int arg0 = 0)
 - bool StartServer(uint16)
 - void StopServer()

+ 1 - 1
Engine/Engine/NetworkAPI.cpp

@@ -109,7 +109,7 @@ static CScriptArray* NetworkGetClientConnections(Network* ptr)
 void RegisterNetwork(asIScriptEngine* engine)
 {
     RegisterObject<Network>(engine, "Network");
-    engine->RegisterObjectMethod("Network", "bool Connect(const String& in, uint16)", asMETHOD(Network, Connect), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Network", "bool Connect(const String&in, uint16, const VariantMap&in identity = VariantMap())", asMETHOD(Network, Connect), asCALL_THISCALL);
     engine->RegisterObjectMethod("Network", "void Disconnect(int waitMSec = 0)", asMETHOD(Network, Disconnect), asCALL_THISCALL);
     engine->RegisterObjectMethod("Network", "bool StartServer(uint16)", asMETHOD(Network, StartServer), asCALL_THISCALL);
     engine->RegisterObjectMethod("Network", "void StopServer()", asMETHOD(Network, StopServer), asCALL_THISCALL);

+ 4 - 1
Engine/IO/Serializer.cpp

@@ -149,7 +149,10 @@ bool Serializer::WriteBoundingBox(const BoundingBox& value)
 
 bool Serializer::WriteString(const String& value)
 {
-    return Write(value.CString(), value.Length() + 1) == value.Length() + 1;
+    const char* chars = value.CString();
+    // Count length to the first zero, because ReadString() does the same
+    unsigned length = strlen(chars);
+    return Write(chars, length + 1) == length + 1;
 }
 
 bool Serializer::WriteID(const String& value)

+ 5 - 4
Engine/Network/Connection.cpp

@@ -76,14 +76,15 @@ bool Connection::IsConnected() const
 
 String Connection::GetAddress() const
 {
-    kNet::Socket* socket = const_cast<kNet::MessageConnection*>(connection_.ptr())->GetSocket();
-    return socket ? String(socket->DestinationAddress()) : String();
+    const unsigned char* ip = connection_->RemoteEndPoint().ip;
+    char str[256];
+    sprintf(str, "%d.%d.%d.%d", (unsigned)ip[0], (unsigned)ip[1], (unsigned)ip[2], (unsigned)ip[3]);
+    return String(str);
 }
 
 unsigned short Connection::GetPort() const
 {
-    kNet::Socket* socket = const_cast<kNet::MessageConnection*>(connection_.ptr())->GetSocket();;
-    return socket ? socket->DestinationPort() : 0;
+    return connection_->RemoteEndPoint().port;
 }
 
 String Connection::ToString() const

+ 4 - 0
Engine/Network/Connection.h

@@ -55,6 +55,8 @@ public:
     
     /// Return the kNet message connection
     kNet::MessageConnection* GetMessageConnection() const;
+    /// Return client identity
+    const VariantMap& GetIdentity() const { return identity_; }
     /// Return whether is fully connected
     bool IsConnected() const;
     /// Return whether connection is pending
@@ -69,6 +71,8 @@ public:
 private:
     /// kNet message connection
     kNet::SharedPtr<kNet::MessageConnection> connection_;
+    /// Identity map
+    VariantMap identity_;
     /// Connection pending flag
     bool connectPending_;
 };

+ 61 - 34
Engine/Network/Network.cpp

@@ -28,6 +28,7 @@
 #include "MemoryBuffer.h"
 #include "Network.h"
 #include "NetworkEvents.h"
+#include "Profiler.h"
 #include "Protocol.h"
 #include "StringUtils.h"
 
@@ -47,6 +48,10 @@ Network::Network(Context* context) :
 
 Network::~Network()
 {
+    // If server connection exists, disconnect, but do not send an event because we are shutting down
+    Disconnect(100);
+    serverConnection_.Reset();
+    
     clientConnections_.Clear();
     
     delete network_;
@@ -55,6 +60,8 @@ Network::~Network()
 
 void Network::HandleMessage(kNet::MessageConnection* source, kNet::message_id_t id, const char *data, size_t numBytes)
 {
+    PROFILE(HandleMessage);
+    
     // Only process messages from known sources
     Connection* connection = GetConnection(source);
     if (connection)
@@ -117,9 +124,11 @@ void Network::ClientDisconnected(kNet::MessageConnection* connection)
     }
 }
 
-bool Network::Connect(const String& address, unsigned short port)
+bool Network::Connect(const String& address, unsigned short port, const VariantMap& identity)
 {
-    // If connection already exists, disconnect it and wait for some time for the connection to terminate
+    PROFILE(Connect);
+    
+    // If a previous connection already exists, disconnect it and wait for some time for the connection to terminate
     if (serverConnection_)
     {
         serverConnection_->Disconnect(100);
@@ -131,6 +140,7 @@ bool Network::Connect(const String& address, unsigned short port)
     {
         LOGINFO("Connecting to server " + address + ":" + String(port));
         serverConnection_ = new Connection(context_, connection);
+        serverConnection_->identity_ = identity;
         serverConnection_->connectPending_ = true;
         return true;
     }
@@ -144,8 +154,11 @@ bool Network::Connect(const String& address, unsigned short port)
 
 void Network::Disconnect(int waitMSec)
 {
-    if (serverConnection_)
-        serverConnection_->Disconnect(waitMSec);
+    if (!serverConnection_)
+        return;
+    
+    PROFILE(Disconnect);
+    serverConnection_->Disconnect(waitMSec);
 }
 
 bool Network::StartServer(unsigned short port)
@@ -153,6 +166,8 @@ bool Network::StartServer(unsigned short port)
     if (IsServerRunning())
         return true;
     
+    PROFILE(StartServer);
+    
     /// \todo Investigate why server fails to restart after stopping when false is specified for reuse
     if (network_->StartServer(port, kNet::SocketOverUDP, this, true) != 0)
     {
@@ -168,37 +183,20 @@ bool Network::StartServer(unsigned short port)
 
 void Network::StopServer()
 {
-    if (IsServerRunning())
-    {
-        clientConnections_.Clear();
-        network_->StopServer();
-        LOGINFO("Stopped server");
-    }
-}
-
-Connection* Network::GetConnection(kNet::MessageConnection* connection) const
-{
-    Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Find(connection);
-    if (i != clientConnections_.End())
-        return i->second_;
-    else if (serverConnection_ && serverConnection_->GetMessageConnection() == connection)
-        return serverConnection_;
-    else
-        return 0;
-}
-
-Connection* Network::GetServerConnection() const
-{
-    return serverConnection_;
-}
-
-bool Network::IsServerRunning() const
-{
-    return network_->GetServer();
+    if (!IsServerRunning())
+        return;
+    
+    PROFILE(StopServer);
+    
+    clientConnections_.Clear();
+    network_->StopServer();
+    LOGINFO("Stopped server");
 }
 
 void Network::Update()
 {
+    PROFILE(UpdateNetwork);
+    
     // Process server connection if it exists
     if (serverConnection_)
     {
@@ -221,10 +219,37 @@ void Network::Update()
         server->Process();
 }
 
+Connection* Network::GetConnection(kNet::MessageConnection* connection) const
+{
+    Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Find(connection);
+    if (i != clientConnections_.End())
+        return i->second_;
+    else if (serverConnection_ && serverConnection_->GetMessageConnection() == connection)
+        return serverConnection_;
+    else
+        return 0;
+}
+
+Connection* Network::GetServerConnection() const
+{
+    return serverConnection_;
+}
+
+bool Network::IsServerRunning() const
+{
+    return network_->GetServer();
+}
+
 void Network::OnServerConnected()
 {
     serverConnection_->connectPending_ = false;
     LOGINFO("Connected to server");
+    
+    // Send the identity map now
+    VectorBuffer msg;
+    msg.WriteVariantMap(serverConnection_->GetIdentity());
+    serverConnection_->SendMessage(MSG_IDENTITY, true, true, msg);
+    
     SendEvent(E_SERVERCONNECTED);
 }
 
@@ -257,15 +282,17 @@ bool Network::OnClientMessage(Connection* connection, kNet::message_id_t id, con
     {
     case MSG_IDENTITY:
         {
+            MemoryBuffer msg(data, numBytes);
+            connection->identity_ = msg.ReadVariantMap();
+            
             using namespace ClientIdentity;
             
-            MemoryBuffer msg(data, numBytes);
-            VariantMap eventData = msg.ReadVariantMap();
+            VariantMap eventData = connection->identity_;
             eventData[P_CONNECTION] = (void*)connection;
             eventData[P_ALLOW] = true;
             connection->SendEvent(E_CLIENTIDENTITY, eventData);
             
-            // Check if connection was denied
+            // If connection was denied as a response to the event, disconnect the client now
             if (!eventData[P_ALLOW].GetBool())
                 connection->Disconnect();
         }

+ 1 - 1
Engine/Network/Network.h

@@ -49,7 +49,7 @@ public:
     virtual void ClientDisconnected(kNet::MessageConnection* connection);
     
     /// Connect to a server using UDP protocol. Return true if connection process successfully started
-    bool Connect(const String& address, unsigned short port);
+    bool Connect(const String& address, unsigned short port, const VariantMap& identity = VariantMap());
     /// 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);
     /// Start a server on a port using UDP protocol. Return true if successful

+ 1 - 1
Engine/Network/NetworkEvents.h

@@ -52,7 +52,7 @@ EVENT(E_CLIENTDISCONNECTED, ClientDisconnected)
     PARAM(P_CONNECTION, Connection);      // Connection pointer
 }
 
-/// Client has sent identity
+/// Client has sent identity: identity map is in the event data
 EVENT(E_CLIENTIDENTITY, ClientIdentity)
 {
     PARAM(P_CONNECTION, Connection);      // Connection pointer