Пример #1
0
        private void GetHostsRequestToServer(NetworkingPlayer sender, NetworkingStream stream)
        {
            ushort pageNumber = ObjectMapper.Map <ushort>(stream);

            List <HostInfo> subList = new List <HostInfo>();

            for (int i = pageNumber * COUNT_PER_PAGE; i < COUNT_PER_PAGE; i++)
            {
                if (hosts.Count <= i)
                {
                    break;
                }

                subList.Add(hosts[i]);
            }

            BMSByte data = new BMSByte();

            ObjectMapper.MapBytes(data, subList.Count);

            foreach (HostInfo host in hosts)
            {
                ObjectMapper.MapBytes(data, host.IpAddress, host.port, host.maxPlayers, host.name, host.password, host.gameType, host.connectedPlayers, host.comment, host.sceneName);
            }

            Networking.WriteCustom(WriteCustomMapping.MASTER_SERVER_GET_HOSTS, socket, data, sender, true);
        }
Пример #2
0
        /// <summary>
        /// Disconnect from the server
        /// </summary>
        public override void Disconnect()
        {
            BMSByte tmp = new BMSByte();

            ObjectMapper.MapBytes(tmp, "disconnect");

            lock (writeMutex)
            {
                writeStream.SetProtocolType(Networking.ProtocolType.TCP);
                writeStream.Prepare(this, NetworkingStream.IdentifierType.Disconnect, 0, tmp, NetworkReceivers.Server, noBehavior: true);

                Write(writeStream);
            }

            if (readWorker != null)
#if UNITY_IOS
            { readWorker.Interrupt(); }
#else
            { readWorker.Abort(); }
#endif

            if (netStream != null)
            {
                netStream.Close();
            }

            if (client != null)
            {
                client.Close();
            }

            OnDisconnected();
        }
Пример #3
0
        private async void ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
        {
            BMSByte tmp = new BMSByte();

            if (Connections >= MaxConnections)
            {
                ObjectMapper.MapBytes(tmp, "Max Players Reached On Server");

                WriteAndClose(args.Socket, new NetworkingStream(Networking.ProtocolType.TCP).Prepare(this,
                                                                                                     NetworkingStream.IdentifierType.Disconnect, null, tmp));

                return;
            }

            // TODO:  Setup name
            string name = string.Empty;

            NetworkingPlayer player = new NetworkingPlayer(ServerPlayerCounter, args.Socket.Information.RemoteAddress.CanonicalName, args.Socket, name);

            Players.Add(player);
            OnPlayerConnected(player);

            tmp.Clear();
            ObjectMapper.MapBytes(tmp, player.NetworkId);

            Write(player, new NetworkingStream(Networking.ProtocolType.TCP).Prepare(this,
                                                                                    NetworkingStream.IdentifierType.Player, null, tmp));
        }
Пример #4
0
        private void TellServerLevelLoaded(int level)
        {
            if (OwningNetWorker == null || OwningNetWorker.IsServer)
            {
                return;
            }

            loadLevelPing.Clear();
            ObjectMapper.MapBytes(loadLevelPing, level);
            Networking.WriteCustom(WriteCustomMapping.NETWORKING_MANAGER_PLAYER_LOADED_LEVEL, OwningNetWorker, loadLevelPing, true, NetworkReceivers.Server);
        }
Пример #5
0
        // TODO:  Support updating the master server on scene change to "Application.loadedLevelName"

        /// <summary>
        /// This method is used to update the current player count on the master server for this server
        /// </summary>
        /// <param name="host">The host of the master server</param>
        /// <param name="port">The port number that this server is running on</param>
        /// <param name="playerCount">The current player count for this server</param>
        public static void UpdateServer(string host, ushort port, int playerCount)
        {
            Action <NetWorker> call = delegate(NetWorker socket)
            {
                BMSByte data = new BMSByte();
                ObjectMapper.MapBytes(data, port, playerCount);
                Networking.WriteCustom(WriteCustomMapping.MASTER_SERVER_UPDATE_SERVER, socket, data, true, NetworkReceivers.Server);
            };

            Request(host, call);
        }
Пример #6
0
        /// <summary>
        /// This method is used to register a server to the master server to be retreived by clients
        /// </summary>
        /// <param name="host">The master server host address</param>
        /// <param name="port">The port that this server will be running on</param>
        /// <param name="maxPlayers">The maximum amount of players allowed on this server</param>
        /// <param name="name">The name for this server</param>
        /// <param name="gameType">The type of game for this server (ie. deathmatch, capture the flag, etc.)</param>
        /// <param name="comment">The comment for this server (usually user populated for loading screens)</param>
        /// <param name="password">The password for this server</param>
        /// <param name="sceneName">The scene name that this server is currently on</param>
        public static void RegisterServer(string host, ushort port, int maxPlayers, string name, string gameType = "", string comment = "", string password = "", string sceneName = "")
        {
            Action <NetWorker> call = delegate(NetWorker socket)
            {
                BMSByte data = new BMSByte();
                ObjectMapper.MapBytes(data, port, maxPlayers, name, gameType, comment, password, sceneName);
                Networking.WriteCustom(WriteCustomMapping.MASTER_SERVER_REGISTER_SERVER, socket, data, true, NetworkReceivers.Server);
            };

            Request(host, call);
        }
Пример #7
0
        /// <summary>
        /// This method requests all of the hosts from the master server
        /// </summary>
        /// <param name="host">The host of the master server</param>
        /// <param name="pageNumber">This is the page number (starting from 0). So if you want to get entries 0-n then you will pass 0, if you want n-n+n then pass 1</param>
        /// <param name="callback">This is the method that will be called once the master server responds with the host list</param>
        public static void GetHosts(string host, ushort pageNumber, Action <HostInfo[]> callback)
        {
            requestHostsCallback = callback;

            Action <NetWorker> call = delegate(NetWorker socket)
            {
                BMSByte data = new BMSByte();
                ObjectMapper.MapBytes(data, pageNumber);
                Networking.WriteCustom(WriteCustomMapping.MASTER_SERVER_GET_HOSTS, socket, data, true, NetworkReceivers.Server);
            };

            Request(host, call);
        }
        private void listenWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lock (writeMutex)
            {
                writeBuffer.Clear();
                ObjectMapper.MapBytes(writeBuffer, ((NetworkingPlayer)e.UserState).NetworkId);

                writeStream.SetProtocolType(Networking.ProtocolType.TCP);
                Write((NetworkingPlayer)e.UserState, writeStream.Prepare(this,
                                                                         NetworkingStream.IdentifierType.Player, 0, writeBuffer, noBehavior: true));

                OnPlayerConnected((NetworkingPlayer)e.UserState);
            }
        }
Пример #9
0
        /// <summary>
        /// Sends the forge transport object
        /// </summary>
        /// <param name="receivers">who will receive the transport object</param>
        /// <param name="reliable">send the packet reliably/unreliably</param>
        /// <remarks>
        /// Serializes the forge transport object, then sends it to all clients specified by the receivers.
        /// Subscribe a method to ForgeTransportObject.transportObject.transportFinished to decide what method should
        /// be executed when the object is received.
        /// </remarks>
        public void Send(NetworkReceivers receivers = NetworkReceivers.Others, bool reliable = true)
        {
            lock (serializerMutex)
            {
                serializer.Clear();
                ObjectMapper.MapBytes(serializer, id);

                foreach (FieldInfo field in fields)
                {
                    ObjectMapper.MapBytes(serializer, field.GetValue(this));
                }

                Networking.WriteCustom(WriteCustomMapping.TRANSPORT_OBJECT, Networking.PrimarySocket, serializer, reliable, receivers);
            }
        }
Пример #10
0
        /// <summary>
        /// Get all the new player updates
        /// </summary>
        public override void GetNewPlayerUpdates()
        {
            Me = new NetworkingPlayer(Uniqueidentifier, "127.0.0.1", null, string.Empty);

            BMSByte tmp = new BMSByte();

            ObjectMapper.MapBytes(tmp, "update");

            lock (writeMutex)
            {
                writeStream.SetProtocolType(Networking.ProtocolType.TCP);
                writeStream.Prepare(this, NetworkingStream.IdentifierType.None, 0, tmp, NetworkReceivers.Server, noBehavior: true);

                Write(writeStream);
            }
        }
Пример #11
0
        public BMSByte Serialized()
        {
            serializeBuffer.Clear();

            foreach (var property in Properties)
            {
                object val = property.GetValue(this, null);
                if (property.PropertyType == typeof(string))
                {
                    serializeBuffer.Append(BitConverter.GetBytes(((string)val).Length));
                }

                ObjectMapper.MapBytes(serializeBuffer, val);
            }

            return(serializeBuffer);
        }
Пример #12
0
        /// <summary>
        /// Creates a network stream for the method with the specified string name and returns the method info
        /// </summary>
        /// <param name="methodName">The name of the method to call from this class</param>
        /// <param name="receivers">The players on the network that will be receiving RPC</param>
        /// <param name="arguments">The list of arguments that will be sent for the RPC</param>
        /// <returns></returns>
        private int GetStreamRPC(string methodName, NetworkReceivers receivers, params object[] arguments)
        {
            foreach (KeyValuePair <int, KeyValuePair <MethodInfo, List <IBRPCIntercept> > > rpc in RPCs)
            {
                if (rpc.Value.Key.Name == methodName)
                {
                    if (!NetworkingManager.IsOnline)
                    {
                        return(rpc.Key);
                    }

                    getStreamBuffer.Clear();
                    ObjectMapper.MapBytes(getStreamBuffer, rpc.Key);

#if UNITY_EDITOR
                    int argCount = 0;
                    foreach (var param in rpc.Value.Key.GetParameters())
                    {
                        if (param.ParameterType != typeof(MessageInfo))
                        {
                            argCount++;
                        }
                    }

                    if (arguments.Length != argCount)
                    {
                        throw new NetworkException("The number of arguments [" + arguments.Length + "] provided for the " + methodName + " RPC call do not match the method signature argument count [" + rpc.Value.Key.GetParameters().Length + "]");
                    }
#endif

                    if (arguments != null && arguments.Length > 0)
                    {
                        ObjectMapper.MapBytes(getStreamBuffer, arguments);
                    }

                    bool buffered = receivers == NetworkReceivers.AllBuffered || receivers == NetworkReceivers.OthersBuffered;

                    rpcNetworkingStream.SetProtocolType(OwningNetWorker is CrossPlatformUDP ? Networking.ProtocolType.UDP : Networking.ProtocolType.TCP);
                    rpcNetworkingStream.Prepare(OwningNetWorker, NetworkingStream.IdentifierType.RPC, this, getStreamBuffer, receivers, buffered);

                    return(rpc.Key);
                }
            }

            throw new NetworkException(14, "No method marked with [BRPC] was found by the name " + methodName);
        }
Пример #13
0
        private void ConnectionLoop(object server)
        {
            while (true)
            {
                try
                {
                    TcpClient client = ((TcpListener)server).AcceptTcpClient();

                    if (Connections >= MaxConnections)
                    {
                        lock (writeMutex)
                        {
                            writeBuffer.Clear();
                            ObjectMapper.MapBytes(writeBuffer, "Max Players Reached On Server");

                            staticWriteStream.SetProtocolType(Networking.ProtocolType.TCP);
                            WriteAndClose(client, staticWriteStream.Prepare(
                                              this, NetworkingStream.IdentifierType.Disconnect, 0, writeBuffer, noBehavior: true));
                        }

                        return;
                    }

                    // TODO:  Set the name
                    string name = string.Empty;

                    NetworkingPlayer player = new NetworkingPlayer(ServerPlayerCounter++, client.Client.RemoteEndPoint.ToString(), client, name);

                    lock (clientMutex)
                    {
                        Players.Add(player);
                    }
                }
                catch (Exception exception)
                {
#if !BARE_METAL
                    UnityEngine.Debug.LogException(exception);
#endif
                    Disconnect();
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Called when the Network as interpreted that a cache message has been sent from the client
        /// </summary>
        /// <param name="player">The player that requested data from the cache</param>
        /// <param name="stream">The data that was received</param>
        public static void NetworkReadServer(NetworkingPlayer player, NetworkingStream stream)
        {
            byte   type           = ObjectMapper.Map <byte>(stream);
            int    responseHookId = ObjectMapper.Map <int>(stream);
            string key            = ObjectMapper.Map <string>(stream);

            object obj = Get(key);

            // TODO:  Let the client know it is null
            if (obj == null)
            {
                return;
            }

            BMSByte data = new BMSByte();

            ObjectMapper.MapBytes(data, type, responseHookId, obj);

            Networking.WriteCustom(WriteCustomMapping.CACHE_READ_CLIENT, Socket, data, player, true);
        }
Пример #15
0
        private void PollPlayers()
        {
            playerPollData.Clear();

            if (!OwningNetWorker.IsServer)
            {
                return;
            }

            ObjectMapper.MapBytes(playerPollData, OwningNetWorker.Players.Count + 1);

            // Send the server first
            ObjectMapper.MapBytes(playerPollData, OwningNetWorker.Me.NetworkId, OwningNetWorker.Me.Name);

            foreach (NetworkingPlayer player in OwningNetWorker.Players)
            {
                ObjectMapper.MapBytes(playerPollData, player.NetworkId, player.Name);
            }

            Networking.WriteCustom(WriteCustomMapping.NETWORKING_MANAGER_POLL_PLAYERS, OwningNetWorker, playerPollData, OwningNetWorker.CurrentStreamOwner, true);
        }
Пример #16
0
        /// <summary>
        /// Get an object from cache
        /// </summary>
        /// <param name="key">The name variable used for storing the desired object</param>
        /// <returns>The string data at the desired key or null</returns>
        /// <remarks>
        /// Allows a client (or the server) to get a value from the Cache, the value is read directly from the server.
        /// A callback must be specified, this is because the code has to be executed after a moment when the response from the server
        /// is received. Request can be done like this:
        /// <code>
        /// void getServerDescription(){
        /// Cache.Request<string>("server_description", delegate (object response){
        ///     Debug.Log(((string) response));
        /// });
        /// }
        /// </code>
        /// The Cache only supports Forge's supported data Types, you can find a list of supported data Types in the NetSync documentation...
        /// </remarks>
        public static void Request <T>(string key, Action <object> callback)
        {
            CheckSetup();

            if (callback == null)
            {
                throw new NetworkException("A callback is needed when requesting data from the server");
            }

            if (Socket.IsServer)
            {
                callback(Get <T>(key));
                return;
            }

            responseHooks.Add(responseHookIncrementer, callback);

            BMSByte data       = new BMSByte();
            byte    targetType = byte.MaxValue;

            foreach (KeyValuePair <byte, Type> kv in typeMap)
            {
                if (typeof(T) == kv.Value)
                {
                    targetType = kv.Key;
                    break;
                }
            }

            if (targetType == byte.MaxValue)
            {
                throw new NetworkException("Invalid type specified");
            }

            ObjectMapper.MapBytes(data, targetType, responseHookIncrementer, key);

            Networking.WriteCustom(WriteCustomMapping.CACHE_READ_SERVER, Socket, data, true, NetworkReceivers.Server);
            responseHookIncrementer++;
        }
Пример #17
0
        private void ReadClients()
        {
            while (true)
            {
                try
                {
                    if (readThreadCancel)
                    {
                        return;
                    }

                    try
                    {
                        lock (clientMutex)
                        {
                            for (int i = 0; i < Players.Count; i++)
                            {
                                if (readThreadCancel)
                                {
                                    return;
                                }

                                TcpClient     playerClient = (TcpClient)Players[i].SocketEndpoint;
                                NetworkStream playerStream = playerClient.GetStream();

                                if (!playerClient.Connected)
                                {
                                    Disconnect(Players[i--]);
                                    continue;
                                }

                                if (!playerStream.DataAvailable)
                                {
                                    continue;
                                }

                                if (!Players[i].Connected)
                                {
                                    if (!Players[i].WebsocketHeaderPrepared)
                                    {
                                        byte[] bytes = new byte[playerClient.Available];
                                        playerStream.Read(bytes, 0, bytes.Length);

                                        string data = Encoding.UTF8.GetString(bytes);

                                        if (new Regex("^GET").IsMatch(data))
                                        {
                                            byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
                                                                                     + "Connection: Upgrade" + Environment.NewLine
                                                                                     + "Upgrade: websocket" + Environment.NewLine
                                                                                     + "Sec-WebSocket-Accept: " + Convert.ToBase64String((new SHA1CryptoServiceProvider()).ComputeHash(Encoding.UTF8.GetBytes(
                                                                                                                                                                                           new Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
                                                                                                                                                                                           ))) + Environment.NewLine + Environment.NewLine);

                                            playerStream.Write(response, 0, response.Length);
                                        }

                                        Players[i].WebsocketHeaderPrepared = true;
                                    }
                                    else
                                    {
                                        int    length = 0;
                                        byte[] bytes  = DecodeMessage(GetNextBytes(playerClient, playerStream, out length));

                                        lock (writeMutex)
                                        {
                                            writeBuffer.Clear();
                                            ObjectMapper.MapBytes(writeBuffer, Players[i].NetworkId);

                                            writeStream.SetProtocolType(Networking.ProtocolType.TCP);
                                            Write(Players[i], writeStream.Prepare(this,
                                                                                  NetworkingStream.IdentifierType.Player, 0, writeBuffer, noBehavior: true));

                                            OnPlayerConnected(Players[i]);
                                        }
                                    }
                                }
                                else
                                {
                                    int    length = 0;
                                    byte[] bytes  = DecodeMessage(GetNextBytes(playerClient, playerStream, out length));

                                    if (bytes[0] == 136)
                                    {
                                        Disconnect(Players[i--]);
                                        continue;
                                    }

                                    readBuffer.Clear();
                                    readBuffer.Clone(bytes);
                                    StreamReceived(Players[i], readBuffer);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
#if !BARE_METAL
                        UnityEngine.Debug.LogException(ex);
#endif
                    }

                    Thread.Sleep(ThreadSpeed);
                }
                catch (Exception ex)
                {
#if !BARE_METAL
                    UnityEngine.Debug.LogException(ex);
#endif
                }
            }
        }
        private void Listen(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (listenWorker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                TcpListener tcpListener = (TcpListener)e.Argument;

                try
                {
                    for (int i = 0; i < Players.Count; i++)
                    {
                        if (!((TcpClient)Players[i].SocketEndpoint).Connected)
                        {
                            Players.RemoveAt(i--);
                        }
                    }

                    // Create a TCP socket.
                    // If you ran this server on the desktop, you could use
                    // Socket socket = tcpListener.AcceptSocket()
                    // for greater flexibility.
                    TcpClient tcpClient = tcpListener.AcceptTcpClient();

                    if (Connections >= MaxConnections)
                    {
                        lock (writeMutex)
                        {
                            writeBuffer.Clear();
                            ObjectMapper.MapBytes(writeBuffer, "Max Players Reached On Server");

                            staticWriteStream.SetProtocolType(Networking.ProtocolType.TCP);
                            WriteAndClose(tcpClient, staticWriteStream.Prepare(
                                              this, NetworkingStream.IdentifierType.Disconnect, 0, writeBuffer, noBehavior: true));
                        }

                        return;
                    }

                    // TODO:  Set the name
                    string name = string.Empty;

                    NetworkingPlayer player = new NetworkingPlayer(ServerPlayerCounter++, tcpClient.Client.RemoteEndPoint.ToString(), tcpClient, name);

                    lock (Players)
                    {
                        Players.Add(player);
                    }

                    listenWorker.ReportProgress(0, player);
                }
                catch (NetworkException exception)
                {
#if !BARE_METAL
                    UnityEngine.Debug.LogException(exception);
#endif
                    Disconnect();
                }
            }
        }
Пример #19
0
        /// <summary>
        /// The final steps for preparing the NetworkingStream
        /// </summary>
        /// <param name="socket">The NetWorker socket to be used</param>
        /// <param name="identifierType">The type of Identifier it is going to prepare</param>
        /// <param name="behaviorNetworkId">NetworkedBehavior to use</param>
        /// <param name="extra">Extra parameters to prepare</param>
        /// <param name="receivers">Who shall be receiving this NetworkingStream</param>
        /// <param name="bufferedRPC">To know if this is a Buffered RPC</param>
        /// <param name="customidentifier">A custom Identifier to be passed through</param>
        /// <returns></returns>
        public NetworkingStream PrepareFinal(NetWorker socket, IdentifierType identifierType, ulong behaviorNetworkId, BMSByte extra = null, NetworkReceivers receivers = NetworkReceivers.All, bool bufferedRPC = false, uint customidentifier = 0, ulong senderId = 0)
        {
            lock (networkedObjectMutex)
            {
                if (senderId == 0)
                {
                    senderId = socket.Me != null ? socket.Me.NetworkId : 0;
                }

                NetworkedBehaviorId = behaviorNetworkId;
                RealSenderId        = senderId;
                Receivers           = receivers;
                Customidentifier    = customidentifier;
                BufferedRPC         = Receivers == NetworkReceivers.AllBuffered || Receivers == NetworkReceivers.OthersBuffered;

                Bytes.Clear();

                ObjectMapper.MapBytes(bytes, (int)ProtocolType);

                ObjectMapper.MapBytes(bytes, (int)receivers);
                ObjectMapper.MapBytes(bytes, socket.Uniqueidentifier);

                if (ProtocolType != Networking.ProtocolType.HTTP && ProtocolType != Networking.ProtocolType.QuickUDP && ProtocolType != Networking.ProtocolType.QuickTCP)
                {
                    this.identifierType = identifierType;

                    if (identifierType == IdentifierType.None)
                    {
                        Bytes.BlockCopy <byte>(((byte)identifier_NONE), 1);
                    }
                    else if (identifierType == IdentifierType.RPC)
                    {
                        Bytes.BlockCopy <byte>(((byte)identifier_RPC), 1);
                        Bytes.BlockCopy <byte>(((byte)(bufferedRPC ? 1 : 0)), 1);
                    }
                    else if (identifierType == IdentifierType.Player)
                    {
                        Bytes.BlockCopy <byte>(((byte)identifier_PLAYER), 1);
                    }
                    else if (identifierType == IdentifierType.NetworkedBehavior)
                    {
                        Bytes.BlockCopy <byte>(((byte)identifier_NETWORKED_BEHAVIOR), 1);
                    }
                    else if (identifierType == IdentifierType.Disconnect)
                    {
                        Bytes.BlockCopy <byte>(((byte)identifier_DISCONNECT), 1);
                    }
                    else if (identifierType == IdentifierType.Custom)
                    {
                        Bytes.BlockCopy <byte>(((byte)identifier_CUSTOM), 1);
                    }

                    ObjectMapper.MapBytes(bytes, behaviorNetworkId);
                }

                if (identifierType == IdentifierType.Custom)
                {
                    ObjectMapper.MapBytes(bytes, Customidentifier);
                }

                if (extra != null)
                {
                    Bytes.BlockCopy(extra.byteArr, extra.StartIndex(), extra.Size);
                }

                if (!ReferenceEquals(NetworkingManager.Instance, null))
                {
                    ObjectMapper.MapBytes(Bytes, NetworkingManager.Instance.CurrentFrame);
                }
                else
                {
                    ObjectMapper.MapBytes(Bytes, (byte)0);
                }

                if (ProtocolType == Networking.ProtocolType.TCP)
                {
                    List <byte> head = new List <byte>(BitConverter.GetBytes(Bytes.Size + 1));
                    head.Add(0);
                    Bytes.InsertRange(0, head.ToArray());
                }

                Ready = true;
                return(this);
            }
        }