Esempio n. 1
0
        internal void Invoke(IEnumerable <Player> players, RPCResult result, string name, params object[] args)
        {
            Network.ByteOutStream stream = new Network.ByteOutStream(256);

            stream.WriteByte(HeaderBytes.RemoteProcedureCall);
            stream.WriteBool(true);
            stream.WriteString(name);

            if (result != null)
            {
                stream.WriteInt(result.ReturnIndex);
                results.Add(result.ReturnIndex, result);
                result.Name = name;
            }

            foreach (object arg in args)
            {
                Writer writer;

                if (!writers.TryGetValue(arg.GetType(), out writer))
                {
                    log.Error("No RPC argument writer for type '{0}', can't send RPC '{1}'", arg.GetTypeName(), name);
                    return;
                }

                writer(stream, arg.GetType(), arg);
            }

            log.Info("Sending {0}", name);

            foreach (Player player in players)
            {
                player.Connection.Queue(stream, true);
            }
        }
Esempio n. 2
0
        bool onCall(Network.ByteInStream stream)
        {
            string name = stream.ReadString();

            Receiver receiver;

            if (!receivers.TryGetValue(name, out receiver))
            {
                log.Error("No receiver for '{0}' found", name);
                return(false);
            }

            int returnIndex = 0;
            int length      = receiver.Parameters.Length;

            if (receiver.ReturnsValue)
            {
                returnIndex = stream.ReadInt();
            }

            if (receiver.RequiresInfoArgument)
            {
                length += 1;
            }

            object[] args = new object[length];

            for (var i = 0; i < receiver.Parameters.Length; ++i)
            {
                Type   t = receiver.Parameters[i];
                Reader reader;

                if (!readers.TryGetTypeValue(t, out reader))
                {
                    return(false);
                }

                args[i] = reader(stream, t);

                if (args[i] is Player)
                {
                    if (!ReferenceEquals(args[i], stream.Player))
                    {
                        log.Error("RPC from {0} tried to use object for {1}", stream.Player, args[i]);
                        return(false);
                    }
                }
            }

            if (receiver.RequiresInfoArgument)
            {
                RPCInfo info = new RPCInfo();

                info.Caller         = stream.Player;
                info.Context        = Context;
                info.RemoteGameTime = stream.RemoteGameTime;

                args[args.Length - 1] = info;
            }

            log.Info("Received {0}", receiver.Name);

            if (receiver.ReturnsValue)
            {
                object result = receiver.Method.Invoke(receiver.Instance, args);
                Network.ByteOutStream resultStream = new Network.ByteOutStream(128);

                resultStream.WriteByte(HeaderBytes.RemoteProcedureCall);
                resultStream.WriteBool(false);
                resultStream.WriteInt(returnIndex);

                if (result == null)
                {
                    resultStream.WriteBool(false);
                }
                else
                {
                    Writer writer;
                    Type   t = result.GetType();

                    resultStream.WriteBool(true);

                    if (writers.TryGetTypeValue(t, out writer))
                    {
                        writer(resultStream, t, result);
                    }
                }

                stream.Player.Connection.Queue(resultStream, true);
            }
            else
            {
                receiver.Method.Invoke(receiver.Instance, args);
            }

            return(true);
        }