Example #1
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);
        }
Example #2
0
 public override void Unpack(SlimNet.Network.ByteInStream stream)
 {
     Message = stream.ReadString();
 }