示例#1
0
        private void ReceiveCreateView(NetMessage message, NetConnection server)
        {
            if (!server.IsServer && !server.IsPeer)
            {
                return;
            }

            int    viewId     = (int)message.Parameters[0];
            int    group      = (int)message.Parameters[1];
            string prefabRoot = (string)message.Parameters[2];
            var    stream     = (NetStream)message.Parameters[3];

            NetView.Relation relation   = default(NetView.Relation);
            NetConnection    controller = null;

            switch (message.MessageId)
            {
            case (int)ViewCmd.CreateOwnerView:
                controller = Socket.Self;
                relation   = NetView.Relation.Owner;
                break;

            case (int)ViewCmd.CreatePeerView:
                relation = NetView.Relation.Peer;
                break;

            case (int)ViewCmd.CreateCreatorView:
                server   = Socket.Self;
                relation = NetView.Relation.Creator;
                break;

            case (int)ViewCmd.CreateProxyView:
                relation = NetView.Relation.Proxy;
                break;
            }

            if (relation == NetView.Relation.Creator || relation == NetView.Relation.Peer)
            {
                var ipendpoint = (IPEndPoint)message.Parameters[4];
                if (ipendpoint != null)
                {
                    if (Socket.EndpointConnected(ipendpoint))
                    {
                        controller = Socket.EndpointToConnection(ipendpoint);
                    }
                    else
                    {
                        NetLog.Error("Failed to create view, controller endpoint not connected: " + ipendpoint);
                    }
                }
            }

            var view = CreateView(controller, server, viewId, group, prefabRoot, relation);

            view.TriggerReadInstantiateData(stream);
            if (OnNetViewCreated != null)
            {
                OnNetViewCreated(view);
            }
        }
示例#2
0
        /// <summary> Processes a response to an RPC assignment request. The assigned id and method name are added to the LocalRpcs dictionary. </summary>
        internal void ReceiveAssignmentResponse(NetMessage netMessage, NetConnection connection)
        {
            if (!connection.IsServer && !connection.IsPeer)
            {
                return;
            }

            var id         = (ushort)netMessage.Parameters[0];
            var methodName = (string)netMessage.Parameters[1];

            if (RpcInfoCache.Exists(methodName) && !idToName.ContainsKey(id))
            {
                idToName.Add(id, methodName);
                if (!nameToId.ContainsKey(methodName))
                {
                    nameToId.Add(methodName, id);
                }
            }
            else
            {
                NetLog.Error("Cannot assign local RPC. ID: " + id + " MethodName: " + methodName);
            }

            if (idToName.Count == RpcInfoCache.Count)
            {
                Socket.SendRequirementsMet(connection);
            }
        }
示例#3
0
        /// <summary>
        /// Sets request result and removes request from queue.
        /// </summary>
        internal void SetResponse(NetMessage message, NetConnection connection)
        {
            if (message.Parameters.Length < 2 || !(message.Parameters[0] is ushort))
            {
                NetLog.Error("Received malformed request response. Discarding.");
                return;
            }

            ushort requestId = (ushort)message.Parameters[0];
            uint   key       = CreateKey(message.ViewId, requestId);

            if (!requests.ContainsKey(key))
            {
                //NetLog.Trace("Active request doesn't exist for response. Discarding.");
                return;
            }

            object requestObj = requests[key];

            requests.Remove(key);

            if ((bool)message.Parameters[1])
            {
                MethodInfo setResponse = requestObj.GetType().GetMethod("SetResponse");
                setResponse.Invoke(requestObj, message.Parameters);
            }
            else
            {
                MethodInfo failureResponse = requestObj.GetType().GetMethod("FailureResponse", BindingFlags.NonPublic);
                failureResponse.Invoke(requestObj, null);
            }
        }
示例#4
0
 /// <summary>
 /// When an RPC is received, the targeted NetView is identified and DispatchRPC is called for that
 /// particular NetView object. DispatchRPC then identifies the targeted method and invokes it with
 /// the supplied parameters.
 /// </summary>
 internal void DispatchRpc(string methodName, NetMessage message, NetConnection connection)
 {
     if (!CachedRpcObjects.ContainsKey(methodName))
     {
         NetLog.Error(string.Format("Can't find RPC method \"{0}\" for View {1}.", methodName, Id));
         return;
     }
     Socket.Rpc.Invoke(CachedRpcObjects[methodName], methodName, message, connection);
 }
示例#5
0
 internal void Register(ushort commandId, Action <NetStream, NetConnection> target)
 {
     if (paramTypes.ContainsKey(commandId))
     {
         NetLog.Error("Command Id already in use. Cannot add command.");
         return;
     }
     streamTargets.Add(commandId, target);
     paramTypes.Add(commandId, streamTypes);
 }
示例#6
0
 internal void Register(ushort commandId, Action <NetMessage, NetConnection> target, List <Type> types)
 {
     if (paramTypes.ContainsKey(commandId))
     {
         NetLog.Error("Command Id already in use. Cannot add command.");
         return;
     }
     paramTypes.Add(commandId, types);
     targets.Add(commandId, target);
 }
示例#7
0
        /// <summary> Send overload that creates the NetMessage for the RPC. </summary>
        internal void Send(int viewId, bool reliable, string methodName, NetConnection target, params object[] parameters)
        {
            if (!Socket.Rpc.HasId(methodName))
            {
                NetLog.Error("Send failed: RPC method name has not been assigned an ID.");
                return;
            }
            var netMessage = NetMessage.Create(Socket.Rpc.NameToId(methodName), (uint)viewId, parameters, reliable);

            target.Send(netMessage);
        }
示例#8
0
        /// <summary> Sends a reliable RPC that does not target a specific view. </summary>
        public void Send(string methodName, NetConnection target, params object[] parameters)
        {
            if (!Rpc.HasId(methodName))
            {
                NetLog.Error("Remote RPC does not have an assigned ID: " + methodName);
                return;
            }
            var message = NetMessage.Create(Rpc.NameToId(methodName), 0, parameters, true);

            target.Send(message);
        }
示例#9
0
        /// <summary>
        /// Passes parameters from an incoming network message to the method associated with the RPC.
        /// </summary>
        internal void DispatchRpc(NetMessage message, NetConnection connection)
        {
            string methodName = Rpc.IdToName(message.MessageId);

            if (!rpcObjectInstances.ContainsKey(methodName))
            {
                NetLog.Error(string.Format("Can't find method \"{0}\" for Viewless RPC.", methodName));
                return;
            }

            Rpc.Invoke(rpcObjectInstances[methodName], methodName, message, connection);
        }
示例#10
0
 internal void RegisterParams(ushort commandId, List <Type> paramTypes)
 {
     if (this.paramTypes.ContainsKey(commandId))
     {
         NetLog.Error("Command Id already in use. Cannot add command types.");
         return;
     }
     if (commandId < 1800 || commandId > 2047)
     {
         throw new Exception("Cannot register Command - Range: 1800-2047 - Provided: " + commandId);
     }
     this.paramTypes.Add(commandId, paramTypes);
 }
示例#11
0
        /// <summary>
        ///  Returns the connection that matches the supplied target.
        ///  Returns the server for Server or the first controller for Controllers.
        /// </summary>
        internal NetConnection GetTarget(RpcTarget target, NetView view)
        {
            switch (target)
            {
            case RpcTarget.Server:
                return(view.Server);

            case RpcTarget.Controllers:
                return(view.Controllers[0]);
            }

            NetLog.Error("Invalid RpcTarget for GetTarget. Only RpcTarget.Server or RpcTarget.Controllers can be used.");
            return(null);
        }
示例#12
0
        internal static NetMessage ReadNetMessage(NetStream stream)
        {
            List <Type> paramTypes;
            ushort      messageId = stream.ReadUShort(11);
            uint        viewId    = 0;

            if (stream.ReadBool())
            {
                viewId = stream.ReadUInt(20);
            }

            if (messageId == (int)Cmd.RequestResponse)
            {
                return(CreateResponseMessage(stream, messageId, viewId));
            }

            if (messageId > 1800)
            {
                if (!stream.Socket.Command.Exists(messageId))
                {
                    NetLog.Error("Cannot deserialize message, Command ID not found: " + messageId);
                    return(null);
                }
                paramTypes = stream.Socket.Command.ParamTypes(messageId);
            }
            else
            {
                if (!stream.Socket.Rpc.Exists(messageId))
                {
                    NetLog.Error("Cannot deserialize message, RPC ID not found: " + messageId);
                    return(null);
                }
                paramTypes = stream.Socket.Rpc.ParamTypes(messageId);
            }

            NetMessage netMessage = NetMessage.Create(messageId, viewId, paramTypes.Count, false);

            if (stream.Socket.Rpc.TakesRequests(messageId))
            {
                return(CreateRequestMessage(stream, netMessage, paramTypes));
            }

            for (int i = 0; i < paramTypes.Count; i++)
            {
                netMessage.Parameters[i] = ReadParam(stream, paramTypes[i]);
            }

            return(netMessage);
        }
示例#13
0
        /// <summary> Send overload that creates the NetMessage for the RPC. </summary>
        internal void Send(int viewId, bool reliable, string methodName, List <NetConnection> targets, params object[] parameters)
        {
            if (!Socket.Rpc.HasId(methodName))
            {
                NetLog.Error("Send failed: RPC method name has not been assigned an ID.");
                return;
            }

            var message = NetMessage.Create(Socket.Rpc.NameToId(methodName), (uint)viewId, parameters, reliable);

            for (int i = 0; i < targets.Count; i++)
            {
                targets[i].Send(message);
            }
        }
示例#14
0
        /// <summary> Send overload that creates the NetMessage for the RPC. </summary>
        internal void Send(int viewId, bool reliable, string methodName, RpcTarget target, params object[] parameters)
        {
            if (!Socket.Rpc.HasId(methodName))
            {
                NetLog.Error("Send failed: RPC method name has not been assigned an ID.");
                return;
            }
            if (!ViewLookup.ContainsKey(viewId))
            {
                return;
            }
            NetView view       = ViewLookup[viewId];
            var     netMessage = NetMessage.Create(Socket.Rpc.NameToId(methodName), (uint)viewId, parameters, reliable);

            Send(view, netMessage, target);
        }
示例#15
0
        /// <summary>
        /// Starts the socket using the supplied endpoint.
        /// If the port is taken, the given port will be incremented to a free port.
        /// </summary>
        public void StartSocket(IPEndPoint endpoint)
        {
            Self   = new NetConnection(false, false, this, endpoint);
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            try {
                const uint IOC_IN            = 0x80000000;
                const uint IOC_VENDOR        = 0x18000000;
                uint       SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
                socket.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null);
            } catch {
                NetLog.Warning("Failed to set control code for ignoring ICMP port unreachable.");
            }

            socket.ReceiveBufferSize = 4194304;
            if (socket.ReceiveBufferSize != 4194304)
            {
                NetLog.Warning("ReceiveBufferSize restricted by OS.");
            }
            socket.SendBufferSize = 1048576;
            socket.Blocking       = false;

            try {
                socket.Bind(endpoint);
            } catch (SocketException e) {
                if (e.ErrorCode == 10048)
                {
                    var newEp = new IPEndPoint(endpoint.Address, endpoint.Port + 1);
                    NetLog.Warning("Port in use. Incrementing and retrying...");
                    StartSocket(newEp);
                }
                else
                {
                    NetLog.Error(e.Message);
                }
                return;
            }

            NetLog.Info(NetTime.StartDateTime() + " | Socket Started. Bound to: " + endpoint);
            NetTime.Milliseconds();

            if (ProtocolAuthority)
            {
                Rpc.AssignLocalRpcs();
            }
            Events.SocketStart();
        }
示例#16
0
 /// <summary> Deserializes incoming reliable stream into NetMessages, forwards them to the NetSocket, releases the stream,
 /// increments the remote sequence, and retries the out-of-order buffer when needed. </summary>
 private void DeliverStream(NetStream strm)
 {
     // Deserialize stream into individual messages and pass them to the socket:
     while (NetSerializer.CanReadMessage(strm))
     {
         var message = NetSerializer.ReadNetMessage(strm);
         if (message == null)
         {
             NetLog.Error("Failed to parse reliable message from: " + Connection.Endpoint + " Pos: " + strm.Pos + " Size: " + strm.Size);
             break;
         }
         Connection.Socket.ReceiveMessage(message, Connection);
     }
     // Return stream to pool and update receive buffer distances:
     strm.Release();
     LastAcceptedRemoteSequence++;
     if (recvBuffer.Count > 0)
     {
         DecrementReceiveBuffer();
     }
 }
示例#17
0
        internal static void WriteParam(NetStream stream, object param)
        {
            if (param == null)
            {
                // TODO: Explicit nullable params should be properly supported.
                stream.WriteBool(false);
                return;
            }

            // Get the object type so we can compare it:
            Type type = param.GetType();

            // Built-in types:
            if (type == typeof(bool))
            {
                stream.WriteBool((bool)param);
            }
            else if (type == typeof(byte))
            {
                stream.WriteByte((byte)param);
            }
            else if (type == typeof(short))
            {
                stream.WriteShort((short)param);
            }
            else if (type == typeof(ushort))
            {
                stream.WriteUShort((ushort)param);
            }
            else if (type == typeof(int))
            {
                stream.WriteInt((int)param);
            }
            else if (type == typeof(uint))
            {
                stream.WriteUInt((uint)param);
            }
            else if (type == typeof(float))
            {
                stream.WriteFloat((float)param);
            }
            else if (type == typeof(long))
            {
                stream.WriteLong((long)param);
            }
            else if (type == typeof(ulong))
            {
                stream.WriteULong((ulong)param);
            }
            else if (type == typeof(double))
            {
                stream.WriteDouble((double)param);
            }
            else if (type == typeof(string))
            {
                stream.WriteString((string)param);
            }
            else if (type == typeof(Vector2))
            {
                stream.WriteVector2((Vector2)param);
            }
            else if (type == typeof(Vector3))
            {
                stream.WriteVector3((Vector3)param);
            }
            else if (type == typeof(Quaternion))
            {
                stream.WriteQuaternion((Quaternion)param);
            }

            else if (type == typeof(bool[]))
            {
                bool[] arr = (bool[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteBool(arr[i]);
                }
            }
            else if (type == typeof(byte[]))
            {
                byte[] arr = (byte[])param;
                stream.WriteUShort((ushort)arr.Length);
                stream.WriteByteArray(arr, arr.Length);
            }
            else if (type == typeof(short[]))
            {
                short[] arr = (short[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteShort(arr[i]);
                }
            }
            else if (type == typeof(ushort[]))
            {
                ushort[] arr = (ushort[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteUShort(arr[i]);
                }
            }
            else if (type == typeof(int[]))
            {
                int[] arr = (int[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteInt(arr[i]);
                }
            }
            else if (type == typeof(uint[]))
            {
                uint[] arr = (uint[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteUInt(arr[i]);
                }
            }
            else if (type == typeof(float[]))
            {
                float[] arr = (float[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteFloat(arr[i]);
                }
            }
            else if (type == typeof(string[]))
            {
                string[] arr = (string[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteString(arr[i]);
                }
            }
            else if (type == typeof(char[]))
            {
                char[] arr = (char[])param;
                stream.WriteUShort((ushort)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    stream.WriteChar(arr[i]);
                }
            }
            else if (type == typeof(NetMessage))
            {
                WriteNetMessage(stream, (NetMessage)param);
            }
            else if (type == typeof(NetMessage[]))
            {
                NetMessage[] arr = (NetMessage[])param;
                stream.WriteByte((byte)arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    WriteNetMessage(stream, arr[i]);
                }
            }
            else if (type == typeof(IPAddress))
            {
                IPAddress address = (IPAddress)param;
                stream.WriteByteArray(address.GetAddressBytes());
            }
            else if (type == typeof(IPEndPoint))
            {
                IPEndPoint ep = (IPEndPoint)param;
                stream.WriteBool(true); // non-null
                WriteParam(stream, ep.Address);
                stream.WriteUShort((ushort)ep.Port);
            }
            else if (type == typeof(NetZone))
            {
                var zone = (NetZone)param;
                stream.WriteUInt(zone.Id);
                bool serializeEndpoint = zone.ServerEndpoint != null;
                stream.WriteBool(serializeEndpoint);
                if (serializeEndpoint)
                {
                    WriteParam(stream, zone.ServerEndpoint);
                }
                stream.WriteVector3(zone.Position);
                stream.WriteInt(zone.ViewIdMin);
                stream.WriteInt(zone.ViewIdMax);
            }
            else if (type == typeof(NetStream))
            {
                NetStream netStream = (NetStream)param;
                netStream.CopyTo(stream);
            }
            else if (HasType(type))
            {
                Write(stream, type, param);
            }
            else
            {
                NetLog.Error("Failed to serialize, no serializer found: " + type);
                throw new Exception(
                          "Serializer not implemented for type! You must add your own type check and serialization logic to serialize this type: " +
                          type);
            }
        }