NetworkMatchChecker.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Mirror
  5. {
  6. /// <summary>
  7. /// Component that controls visibility of networked objects based on match id.
  8. /// <para>Any object with this component on it will only be visible to other objects in the same match.</para>
  9. /// <para>This would be used to isolate players to their respective matches within a single game server instance. </para>
  10. /// </summary>
  11. // Deprecated 2021-02-17
  12. [Obsolete(NetworkVisibilityObsoleteMessage.Message)]
  13. [DisallowMultipleComponent]
  14. [AddComponentMenu("Network/NetworkMatchChecker")]
  15. [RequireComponent(typeof(NetworkIdentity))]
  16. [RequireComponent(typeof(NetworkMatch))]
  17. [HelpURL("https://mirror-networking.gitbook.io/docs/components/network-match-checker")]
  18. public class NetworkMatchChecker : NetworkVisibility
  19. {
  20. // internal for tests
  21. internal static readonly Dictionary<Guid, HashSet<NetworkIdentity>> matchPlayers =
  22. new Dictionary<Guid, HashSet<NetworkIdentity>>();
  23. // internal for tests
  24. internal Guid currentMatch
  25. {
  26. get => GetComponent<NetworkMatch>().matchId;
  27. set => GetComponent<NetworkMatch>().matchId = value;
  28. }
  29. internal Guid lastMatch;
  30. public override void OnStartServer()
  31. {
  32. if (currentMatch == Guid.Empty) return;
  33. if (!matchPlayers.ContainsKey(currentMatch))
  34. matchPlayers.Add(currentMatch, new HashSet<NetworkIdentity>());
  35. matchPlayers[currentMatch].Add(netIdentity);
  36. // No need to rebuild anything here.
  37. // identity.RebuildObservers is called right after this from NetworkServer.SpawnObject
  38. }
  39. public override void OnStopServer()
  40. {
  41. if (currentMatch == Guid.Empty) return;
  42. if (matchPlayers.ContainsKey(currentMatch) && matchPlayers[currentMatch].Remove(netIdentity))
  43. RebuildMatchObservers(currentMatch);
  44. }
  45. void RebuildMatchObservers(Guid specificMatch)
  46. {
  47. foreach (NetworkIdentity networkIdentity in matchPlayers[specificMatch])
  48. networkIdentity?.RebuildObservers(false);
  49. }
  50. #region Observers
  51. /// <summary>
  52. /// Callback used by the visibility system to determine if an observer (player) can see this object.
  53. /// <para>If this function returns true, the network connection will be added as an observer.</para>
  54. /// </summary>
  55. /// <param name="conn">Network connection of a player.</param>
  56. /// <returns>True if the player can see this object.</returns>
  57. public override bool OnCheckObserver(NetworkConnection conn)
  58. {
  59. // Not Visible if not in a match
  60. if (currentMatch == Guid.Empty)
  61. return false;
  62. NetworkMatchChecker networkMatchChecker = conn.identity.GetComponent<NetworkMatchChecker>();
  63. if (networkMatchChecker == null)
  64. return false;
  65. return networkMatchChecker.currentMatch == currentMatch;
  66. }
  67. /// <summary>
  68. /// Callback used by the visibility system to (re)construct the set of observers that can see this object.
  69. /// <para>Implementations of this callback should add network connections of players that can see this object to the observers set.</para>
  70. /// </summary>
  71. /// <param name="observers">The new set of observers for this object.</param>
  72. /// <param name="initialize">True if the set of observers is being built for the first time.</param>
  73. public override void OnRebuildObservers(HashSet<NetworkConnection> observers, bool initialize)
  74. {
  75. if (currentMatch == Guid.Empty) return;
  76. foreach (NetworkIdentity networkIdentity in matchPlayers[currentMatch])
  77. if (networkIdentity != null && networkIdentity.connectionToClient != null)
  78. observers.Add(networkIdentity.connectionToClient);
  79. }
  80. #endregion
  81. [ServerCallback]
  82. void Update()
  83. {
  84. // only if changed
  85. if (currentMatch == lastMatch)
  86. return;
  87. // This object is in a new match so observers in the prior match
  88. // and the new match need to rebuild their respective observers lists.
  89. // Remove this object from the hashset of the match it just left
  90. if (lastMatch != Guid.Empty)
  91. {
  92. matchPlayers[lastMatch].Remove(netIdentity);
  93. // RebuildObservers of all NetworkIdentity's in the match this
  94. // object just left
  95. RebuildMatchObservers(lastMatch);
  96. }
  97. if (currentMatch != Guid.Empty)
  98. {
  99. // Make sure this new match is in the dictionary
  100. if (!matchPlayers.ContainsKey(currentMatch))
  101. matchPlayers.Add(currentMatch, new HashSet<NetworkIdentity>());
  102. // Add this object to the hashset of the new match
  103. matchPlayers[currentMatch].Add(netIdentity);
  104. // RebuildObservers of all NetworkIdentity's in the match this object just entered
  105. RebuildMatchObservers(currentMatch);
  106. }
  107. else
  108. {
  109. // Not in any match now...RebuildObservers will clear and add self
  110. netIdentity.RebuildObservers(false);
  111. }
  112. // save last rebuild's match
  113. lastMatch = currentMatch;
  114. }
  115. }
  116. }