using FishNet.Broadcast; using FishNet.Broadcast.Helping; using FishNet.Managing.Utility; using FishNet.Serializing; using FishNet.Serializing.Helping; using FishNet.Transporting; using GameKit.Dependencies.Utilities; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using UnityEngine; namespace FishNet.Managing.Client { public sealed partial class ClientManager : MonoBehaviour { #region Private. /// /// Handler for registered broadcasts. /// private readonly Dictionary _broadcastHandlers = new(); #endregion /// /// Registers a method to call when a Broadcast arrives. /// /// Type of broadcast being registered. /// Method to call. public void RegisterBroadcast(Action handler) where T : struct, IBroadcast { if (handler == null) { NetworkManager.LogError($"Broadcast cannot be registered because handler is null. This may occur when trying to register to objects which require initialization, such as events."); return; } ushort key = BroadcastExtensions.GetKey(); //Create new IBroadcastHandler if needed. BroadcastHandlerBase bhs; if (!_broadcastHandlers.TryGetValueIL2CPP(key, out bhs)) { bhs = new ServerBroadcastHandler(); _broadcastHandlers.Add(key, bhs); } //Register handler to IBroadcastHandler. bhs.RegisterHandler(handler); } /// /// Unregisters a method call from a Broadcast type. /// /// Type of broadcast being unregistered. /// Method to unregister. public void UnregisterBroadcast(Action handler) where T : struct, IBroadcast { ushort key = BroadcastExtensions.GetKey(); if (_broadcastHandlers.TryGetValueIL2CPP(key, out BroadcastHandlerBase bhs)) bhs.UnregisterHandler(handler); } /// /// Parses a received broadcast. /// private void ParseBroadcast(PooledReader reader, Channel channel) { ushort key = reader.ReadUInt16(); int dataLength = Packets.GetPacketLength((ushort)PacketId.Broadcast, reader, channel); // try to invoke the handler for that message if (_broadcastHandlers.TryGetValueIL2CPP(key, out BroadcastHandlerBase bhs)) bhs.InvokeHandlers(reader, channel); else reader.Skip(dataLength); } /// /// Sends a Broadcast to the server. /// /// Type of broadcast to send. /// Broadcast data being sent; for example: an instance of your broadcast type. /// Channel to send on. public void Broadcast(T message, Channel channel = Channel.Reliable) where T : struct, IBroadcast { //Check local connection state. if (!Started) { NetworkManager.LogWarning($"Cannot send broadcast to server because client is not active."); return; } PooledWriter writer = WriterPool.Retrieve(); BroadcastsSerializers.WriteBroadcast(NetworkManager, writer, message, ref channel); ArraySegment segment = writer.GetArraySegment(); NetworkManager.TransportManager.SendToServer((byte)channel, segment); writer.Store(); } } }