summaryrefslogtreecommitdiff
path: root/Runtime/Network/PlayerCommunicator/GeneralConnection.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Network/PlayerCommunicator/GeneralConnection.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Network/PlayerCommunicator/GeneralConnection.h')
-rw-r--r--Runtime/Network/PlayerCommunicator/GeneralConnection.h266
1 files changed, 266 insertions, 0 deletions
diff --git a/Runtime/Network/PlayerCommunicator/GeneralConnection.h b/Runtime/Network/PlayerCommunicator/GeneralConnection.h
new file mode 100644
index 0000000..1f253d8
--- /dev/null
+++ b/Runtime/Network/PlayerCommunicator/GeneralConnection.h
@@ -0,0 +1,266 @@
+#pragma once
+
+#if ENABLE_PLAYERCONNECTION
+#define ENABLE_MULTICAST (!UNITY_FLASH)
+
+#include "Runtime/Serialize/SwapEndianBytes.h"
+#include "Runtime/Network/MulticastSocket.h"
+#include "Runtime/Network/ServerSocket.h"
+#include "Runtime/Network/SocketStreams.h"
+
+
+#if UNITY_WIN
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#elif UNITY_XENON
+#include <xtl.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <errno.h>
+#endif
+#include "Runtime/Profiler/TimeHelper.h"
+#include "Runtime/Threads/Mutex.h"
+
+
+// used ports:
+// MulticastPort : 54998
+// ListenPorts : 55000 - 55511
+// Multicast(unittests) : 55512 - 56023
+
+#define ENABLE_PLAYER_CONNECTION_DEBUG_LOG 0
+
+#if ENABLE_PLAYER_CONNECTION_DEBUG_LOG
+#define LOG_PLAYER_CONNECTION(str) { \
+ bool oldlog = IsLogEnabled(); \
+ SetLogEnabled(false); \
+ printf_console ("[%04x] %s\n", Thread::GetCurrentThreadID(), (str).c_str()); \
+ SetLogEnabled(oldlog); \
+}
+#else
+#define LOG_PLAYER_CONNECTION(str)
+#endif
+
+#if SUPPORT_THREADS
+#define LOG_PLAYER_CONNECTION_CRITICAL(str) printf_console ("[%04x] %s\n", Thread::GetCurrentThreadID(), (str).c_str())
+#else
+#define LOG_PLAYER_CONNECTION_CRITICAL(str) printf_console ("[] %s\n", (str).c_str())
+#endif
+
+#define PLAYER_MULTICAST_GROUP "225.0.0.222"
+#define PLAYER_MULTICAST_PORT 54997
+
+#define PLAYER_DIRECTCONNECT_PORT 54999
+#define PLAYER_DIRECTCONNECT_GUID 1337
+
+#define PLAYER_DIRECT_IP_CONNECT_GUID 0xFEED
+
+#define PLAYER_LISTEN_PORT 55000
+#define PLAYER_UNITTEST_MULTICAST_PORT 55512
+#define PLAYER_PORT_MASK 511
+#define PLAYER_MESSAGE_MAGIC_NUMBER 0x4E8F
+
+#define PLAYER_CONNECTION_CONFIG_DATA_FORMAT_LISTEN "listen %u %d %d %d"
+#define PLAYER_CONNECTION_CONFIG_DATA_FORMAT_LISTEN_PRINT "listen <guid> <debugging> <waitonstartup> <startprofiler>"
+#define PLAYER_CONNECTION_CONFIG_DATA_FORMAT_CONNECT_LIST "connect %s %s %s %s %s %s %s %s %s %s"
+#define PLAYER_CONNECTION_CONFIG_DATA_FORMAT_CONNECT "connect %s"
+#define PLAYER_CONNECTION_CONFIG_DATA_FORMAT_CONNECT_PRINT "connect <ip>"
+
+#define SERVER_IDENTIFICATION_FORMAT "[IP] %s [Port] %lu [Flags] %lu [Guid] %lu [EditorId] %lu [Version] %d [Id] %s [Debug] %d"
+
+
+#define ANY_PLAYERCONNECTION 0
+
+bool SocketCallSucceeded(int res);
+
+class GeneralConnection
+{
+public:
+ enum MulticastFlags
+ {
+ kRequestImmediateConnect = 1<<0,
+ kSupportsProfile = 1<<1,
+ kCustomMessage = 1<<2
+ };
+
+ enum { kMulticastBufferSize = 256 };
+ enum { kDataBufferMaxSize = 8*1024*1024 };
+ enum { kDataBufferFlushThreshold = 7*1024*1024 };
+
+#if ENABLE_MULTICAST
+ // Parsed struct from a buffer that contains all the information sent by the player to the editor
+ // Used for showing a list of all available profilers and performing autoconnect on the profiler
+ struct MulticastInfo
+ {
+ MulticastInfo();
+
+ bool Parse (const char* buffer, void* in = NULL);
+
+ bool IsValid () const { return m_Valid; }
+ bool IsLocalhost() const { return m_IsLocalhost; }
+
+ UInt32 GetGuid () const { return m_Guid; }
+ UInt32 GetEditorGuid () const { return m_EditorGuid; }
+
+ UInt32 GetPort () const { return m_Port; }
+ std::string const& GetIP () const { return m_Ip; }
+
+ bool ImmediateConnect() const { return (m_Flags & kRequestImmediateConnect) != 0; }
+ bool HasCustomMessage() const { return (m_Flags & kCustomMessage) != 0; }
+ bool HasProfiler() const { return (m_Flags & kSupportsProfile) != 0; }
+
+ std::string const& GetIdentifier() const { return m_Identifier; }
+ private:
+
+ void Clear ();
+ void SetLocalhostFlag();
+
+ std::string m_Buffer;
+ std::string m_Ip;
+ UInt32 m_Port;
+ UInt32 m_Flags;
+ UInt32 m_Guid;
+ UInt32 m_EditorGuid;
+ std::string m_Identifier;
+ bool m_Valid;
+ bool m_IsLocalhost;
+ };
+#endif
+
+ enum MessageID{
+ // messageID 1 - 31 reserved for (future) internal use
+ kProfileDataMessage = 32,
+ kProfileStartupInformation = 33,
+
+ kObjectMemoryProfileSnapshot = 40, //request the memory profile
+ kObjectMemoryProfileDataMessage = 41, //send the object memory profile
+
+ kLogMessage = 100,
+ kCleanLogMessage = 101,
+
+ kFileTransferMessage = 200,
+ kFileReadyMessage = 201,
+ kCaptureHeaphshotMessage = 202,
+
+ kPingAliveMessage = 300,
+ kApplicationQuitMessage = 301,
+ kLastMessageID,
+ };
+
+ struct NetworkMessage
+ {
+ void InitializeMessage();
+ bool CheckMessageValidity();
+ void SetID (MessageID id);
+ MessageID GetID ();
+ void SetDataSize (UInt32 size);
+ UInt32 GetDataSize ();
+
+ bool AllowSkip(){return m_ID == kProfileDataMessage;}
+
+ private:
+ UInt16 m_MagicNumber; // in little endian
+ UInt16 m_ID; // in little endian
+ UInt32 m_Size; // in little endian
+ };
+
+ struct Connection
+ {
+ public:
+ Connection(TSocketHandle socketHandle);
+ ~Connection();
+
+ bool IsValid() const { return m_SocketStream.IsConnected(); };
+ bool Poll() { return m_SocketStream.Poll(5); }
+ bool HasBytesToSend() const { return m_SocketStream.SendBuffer().GetAvailableSize() > 0; }
+ const void* ReceiveMessage(NetworkMessage* message);
+ void ReleaseReceivedMessage();
+ void SendMessage(NetworkMessage& message, const void* data);
+
+ UInt32 GetSendBufferSize() const { return m_SocketStream.SendBuffer().GetAllocatedSize(); }
+ UInt32 GetRecvBufferSize() const { return m_SocketStream.RecvBuffer().GetAllocatedSize(); }
+
+ private:
+ Mutex m_SendMutex;
+ Mutex m_RecvMutex;
+ NetworkMessage m_PendingMessage;
+ void* m_PendingMessageData;
+ bool m_LocallyAllocatedMessageData;
+ bool m_HasPendingMessage;
+#if UNITY_FLASH
+ BufferedSocketStream m_SocketStream;
+#elif UNITY_WINRT
+ BufferedSocketStream m_SocketStream;
+#else
+ ThreadedSocketStream m_SocketStream;
+#endif
+ };
+
+ virtual ~GeneralConnection ();
+
+ bool IsConnected () { return !m_Connections.empty(); }
+ void SetLogEnabled (bool v) { m_LogEnabled = v; }
+ bool IsLogEnabled () const { return m_LogEnabled; }
+ void DisconnectAll ();
+
+ void SendMessage (UInt32 guid, MessageID id, const void* data, UInt32 size);
+
+ typedef void (*MessageHandlerFunc) (const void* data, UInt32 size, UInt32 guid);
+ void RegisterMessageHandler (MessageID messageID, MessageHandlerFunc func);
+ void UnregisterMessageHandler (MessageID messageID, MessageHandlerFunc func);
+
+ typedef void (*ConnectionHandlerFunc) (UInt32 guid);
+ void RegisterDisconnectionHandler( ConnectionHandlerFunc func );
+ void RegisterConnectionHandler( ConnectionHandlerFunc func );
+ void UnregisterDisconnectionHandler( ConnectionHandlerFunc func );
+ void UnregisterConnectionHandler( ConnectionHandlerFunc func );
+
+ virtual void WaitForFinish();
+
+ UInt32 GetLocalGuid() const;
+
+ static void RunningUnitTest() { ms_RunningUnitTests = true;}
+
+protected:
+ GeneralConnection ();
+
+ bool HasBytesToSend() const;
+
+ static void Initialize ();
+ static void Cleanup ();
+
+ void RegisterConnection (UInt32 guid, TSocketHandle socketHandle);
+ void Disconnect (UInt32 guid);
+
+ Connection* GetConnection(UInt32 guid);
+
+ virtual bool IsServer () = 0;
+
+ void Poll ();
+
+protected:
+ std::string m_LocalIP;
+
+#if ENABLE_MULTICAST
+ MulticastSocket m_MulticastSocket;
+#endif
+
+ typedef std::map< int, Connection* > ConnectionMap;
+ ConnectionMap m_Connections;
+
+ std::map< MessageID, MessageHandlerFunc > m_HandlerMap;
+ std::vector< ConnectionHandlerFunc > m_ConnectionHandlers;
+ std::vector< ConnectionHandlerFunc > m_DisconnectionHandlers;
+
+ UInt32 m_LocalGuid;
+
+ bool m_LogEnabled;
+
+ static bool ms_RunningUnitTests;
+ static int ms_Version;
+};
+
+#endif // ENABLE_PLAYERCONNECTION