예제 #1
0
        public ParameterReader(RPCMethod method, RuntimeTypeHandle messageInfoHandle)
        {
            _appendStream      = false;
            _appendMessageInfo = false;

            var infos = method.info.GetParameters();

            _count = infos.Length;
            var handles = new RuntimeTypeHandle[_count];

            for (int i = 0; i < infos.Length; i++)
            {
                handles[i] = infos[i].ParameterType.TypeHandle;
            }

            int last = _count - 1;

            if (last >= 0)
            {
                var parameterHandle = handles[last];
                if (typeof(BitStream).TypeHandle.Equals(parameterHandle))
                {
                    _appendStream = true;
                    last--;
                }
                else if (messageInfoHandle.Equals(parameterHandle))
                {
                    _appendMessageInfo = true;
                    last--;

                    if (last >= 0 && typeof(BitStream).TypeHandle.Equals(handles[last]))
                    {
                        _appendStream = true;
                        last--;
                    }
                }
            }

            _codecs = new BitStreamCodec[last + 1];

            for (int i = 0; i <= last; i++)
            {
                var handle = handles[i];
                var codec  = BitStreamCodec.Find(handle);

                if (!(codec.deserializer != null))
                {
                    Utility.Exception("Missing Deserializer for parameter ", i, ", ", handle, ", in ", method);
                }

                _codecs[i] = codec;
            }
        }
예제 #2
0
        public object[] ReadParameters(BitStream stream, object messageInfo, RPCMethod method)
        {
            var parameters = new object[_count];
            int i          = 0;

            // TODO: use a uLink specific exception instead.
            try
            {
                for (; i < _codecs.Length; i++)
                {
                    parameters[i] = stream._ReadObject(_codecs[i]);
                }
            }
            catch (Exception e)
            {
                if (e.Message != NetBuffer.c_readOverflowError)
                {
                    throw;
                }

                Log.Warning(NetworkLogFlags.RPC, "Trying to read past the buffer size when calling RPC ", method, " - likely caused by mismatching send parameters, different size or order.");
                return(null);
            }

            if (_appendStream)
            {
                parameters[i++] = stream;
            }
            if (_appendMessageInfo)
            {
                parameters[i] = messageInfo;
            }

            int bytesRemaining = stream.bytesRemaining;

            if (!_appendStream && bytesRemaining > 0)
            {
                // TODO: does this happen all the time?
#if PIKKO_BUILD
                Log.Warning("All RPC parameters ({0} remaining bytes) were not read by the {1} declaration", bytesRemaining, method);
#else
                Log.Warning(NetworkLogFlags.RPC, "All RPC parameters (", bytesRemaining, " remaining bytes) were not read by the ", method, " declaration");
#endif
            }

            return(parameters);
        }
예제 #3
0
        private void _Initialize(Component source, UnityEngine.MonoBehaviour[] components, string rpcName, RuntimeTypeHandle messageInfoHandle)
        {
            string type = "";

            int typeIndex = rpcName.IndexOf(':');

            if (typeIndex != -1)
            {
                type    = rpcName.Substring(0, typeIndex);
                rpcName = rpcName.Substring(typeIndex + 1);
            }

            foreach (var component in components)
            {
                if (!String.IsNullOrEmpty(type) && component.GetType().Name != type)
                {
                    continue;
                }

                var candidate = new RPCMethod(component.GetType(), rpcName, true);
                if (candidate.isExecutable)
                {
                    if (instance.IsNotNull())
                    {
                        NetworkLog.Error(NetworkLogFlags.RPC, "Found two or more RPCs named '", rpcName, "' inside the receivers at ", source);

                        instance = null;
                        return;
                    }

                    instance = component;
                    method   = candidate;
                }
            }

            if (instance.IsNotNull())
            {
                reader = new ParameterReader(method, messageInfoHandle);
            }
            else
            {
                Log.Error(NetworkLogFlags.RPC, "No receiver found for RPC '", rpcName, "' at ", source);
            }
        }