internal static NetMessage GetMessage(int size, ReliabilityMode rel, BroadcastMode broad, MsgType mType, SubMsgType sub = SubMsgType.Out) { var msg = GetMessage(size + 1); msg.Write(RpcUtils.GetHeader(rel, broad, mType, sub)); return(msg); }
internal void CallRpc(NetMessage msg, NetMessageInfo info, SubMsgType sub) { if (msg.RemainingBits < 32) { Debug.LogWarning("Attempted to call an rpc on a network view, but there weren't enough bits remaining to do it."); return; } var id = msg.ReadUInt16(); var comp = msg.ReadByte(); var rpc = msg.ReadByte(); NetworkView view; var supposedToHave = _networkViews.TryGetValue(id, out view); if (supposedToHave && view != null) { view.IncomingRpc(comp, rpc, msg, info, sub); } else { Debug.LogWarning($"Could not find view {id} to call {comp} rpc {rpc}"); } //todo: filter if rpc mode is all/others/owner, and then send to appropriate people. if (info.ContinueForwarding && view != null) { if (info.Mode == BroadcastMode.Others) { view.SendExcept(msg, info.Sender, info.Reliability); } else if (info.Mode == BroadcastMode.All) { view.SendMessage(msg, RpcUtils.RpcMode(info.Reliability, info.Mode)); } else if (info.Mode == BroadcastMode.Owner && info.Sender != view.Owner && view.Owner.IsValid) { view.Owner.SendMessage(msg, info.Reliability); } } }
internal void IncomingRpc(byte componentId, byte rpc, NetMessage msg, NetMessageInfo info, SubMsgType sub) { var id = (componentId << 8) | rpc; if (sub != SubMsgType.Out) { var cont = Dequeue(info.Sender.Id, componentId, rpc); if (cont == null) { return; } if (sub == SubMsgType.Reply) { cont.RunSuccess(msg, info); } else if (sub == SubMsgType.Error) { cont.RunError(msg, info); } return; } RpcProcessor processor; if (!_rpcProcessors.TryGetValue(id, out processor)) { Debug.LogWarning($"Networkview on {componentId}: unhandled RPC {rpc}"); info.ContinueForwarding = false; } else { info.ContinueForwarding = processor.DefaultContinueForwarding; if (processor.Action != null) { try { processor.Action(msg, info); } catch (Exception e) { info.ContinueForwarding = false; Debug.LogException(e); } } else if (processor.Func != null) { object ret; try { ret = processor.Func(msg, info); } catch (Exception e) { Debug.LogException(e); ret = e; } //need to serialize and send back to the player. ReturnFuncRpc(componentId, rpc, info.Sender, ret); } else { //Debug.LogWarning("RPC processor for {0} was null. Automatically cleaning up. Please be sure to clean up after yourself in the future.", rpcID); _rpcProcessors.Remove(id); } } }
public static void ReadHeader(byte value, out ReliabilityMode rel, out BroadcastMode broad, out MsgType msg, out SubMsgType sub) { rel = (ReliabilityMode)(value & ReliabilityMask); broad = (BroadcastMode)(value & BroadcastMask); msg = (MsgType)(value & MsgTypeMask); sub = (SubMsgType)(value & SubTypeMask); }
public static byte GetHeader(ReliabilityMode rel, BroadcastMode broad, MsgType msg, SubMsgType sub = SubMsgType.Out) { //OR can be used because the values should not encroach in the other bit areas. byte ret = (byte)rel; ret |= (byte)broad; ret |= (byte)msg; ret |= (byte)sub; return(ret); //todo: which is more efficient? //return (byte)((byte)rel | (byte)broad | (byte)msg | (byte)sub); }