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); } }
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); }