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