Seven is the number.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
11 KiB

4 years ago
  1. // ----------------------------------------------------------------------------
  2. // <copyright file="RoomInfo.cs" company="Exit Games GmbH">
  3. // Loadbalancing Framework for Photon - Copyright (C) 2018 Exit Games GmbH
  4. // </copyright>
  5. // <summary>
  6. // This class resembles info about available rooms, as sent by the Master
  7. // server's lobby. Consider all values as readonly.
  8. // </summary>
  9. // <author>developer@photonengine.com</author>
  10. // ----------------------------------------------------------------------------
  11. #if UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER
  12. #define SUPPORTED_UNITY
  13. #endif
  14. namespace Photon.Realtime
  15. {
  16. using System.Collections;
  17. using ExitGames.Client.Photon;
  18. #if SUPPORTED_UNITY || NETFX_CORE
  19. using Hashtable = ExitGames.Client.Photon.Hashtable;
  20. using SupportClass = ExitGames.Client.Photon.SupportClass;
  21. #endif
  22. /// <summary>
  23. /// A simplified room with just the info required to list and join, used for the room listing in the lobby.
  24. /// The properties are not settable (IsOpen, MaxPlayers, etc).
  25. /// </summary>
  26. /// <remarks>
  27. /// This class resembles info about available rooms, as sent by the Master server's lobby.
  28. /// Consider all values as readonly. None are synced (only updated by events by server).
  29. /// </remarks>
  30. public class RoomInfo
  31. {
  32. /// <summary>Used in lobby, to mark rooms that are no longer listed (for being full, closed or hidden).</summary>
  33. public bool RemovedFromList;
  34. /// <summary>Backing field for property.</summary>
  35. private Hashtable customProperties = new Hashtable();
  36. /// <summary>Backing field for property.</summary>
  37. protected byte maxPlayers = 0;
  38. /// <summary>Backing field for property.</summary>
  39. protected int emptyRoomTtl = 0;
  40. /// <summary>Backing field for property.</summary>
  41. protected int playerTtl = 0;
  42. /// <summary>Backing field for property.</summary>
  43. protected string[] expectedUsers;
  44. /// <summary>Backing field for property.</summary>
  45. protected bool isOpen = true;
  46. /// <summary>Backing field for property.</summary>
  47. protected bool isVisible = true;
  48. /// <summary>Backing field for property. False unless the GameProperty is set to true (else it's not sent).</summary>
  49. protected bool autoCleanUp = true;
  50. /// <summary>Backing field for property.</summary>
  51. protected string name;
  52. /// <summary>Backing field for master client id (actorNumber). defined by server in room props and ev leave.</summary>
  53. public int masterClientId;
  54. /// <summary>Backing field for property.</summary>
  55. protected string[] propertiesListedInLobby;
  56. /// <summary>Read-only "cache" of custom properties of a room. Set via Room.SetCustomProperties (not available for RoomInfo class!).</summary>
  57. /// <remarks>All keys are string-typed and the values depend on the game/application.</remarks>
  58. /// <see cref="Room.SetCustomProperties"/>
  59. public Hashtable CustomProperties
  60. {
  61. get
  62. {
  63. return this.customProperties;
  64. }
  65. }
  66. /// <summary>The name of a room. Unique identifier for a room/match (per AppId + game-Version).</summary>
  67. public string Name
  68. {
  69. get
  70. {
  71. return this.name;
  72. }
  73. }
  74. /// <summary>
  75. /// Count of players currently in room. This property is overwritten by the Room class (used when you're in a Room).
  76. /// </summary>
  77. public int PlayerCount { get; private set; }
  78. /// <summary>
  79. /// The limit of players for this room. This property is shown in lobby, too.
  80. /// If the room is full (players count == maxplayers), joining this room will fail.
  81. /// </summary>
  82. /// <remarks>
  83. /// As part of RoomInfo this can't be set.
  84. /// As part of a Room (which the player joined), the setter will update the server and all clients.
  85. /// </remarks>
  86. public byte MaxPlayers
  87. {
  88. get
  89. {
  90. return this.maxPlayers;
  91. }
  92. }
  93. /// <summary>
  94. /// Defines if the room can be joined.
  95. /// This does not affect listing in a lobby but joining the room will fail if not open.
  96. /// If not open, the room is excluded from random matchmaking.
  97. /// Due to racing conditions, found matches might become closed even while you join them.
  98. /// Simply re-connect to master and find another.
  99. /// Use property "IsVisible" to not list the room.
  100. /// </summary>
  101. /// <remarks>
  102. /// As part of RoomInfo this can't be set.
  103. /// As part of a Room (which the player joined), the setter will update the server and all clients.
  104. /// </remarks>
  105. public bool IsOpen
  106. {
  107. get
  108. {
  109. return this.isOpen;
  110. }
  111. }
  112. /// <summary>
  113. /// Defines if the room is listed in its lobby.
  114. /// Rooms can be created invisible, or changed to invisible.
  115. /// To change if a room can be joined, use property: open.
  116. /// </summary>
  117. /// <remarks>
  118. /// As part of RoomInfo this can't be set.
  119. /// As part of a Room (which the player joined), the setter will update the server and all clients.
  120. /// </remarks>
  121. public bool IsVisible
  122. {
  123. get
  124. {
  125. return this.isVisible;
  126. }
  127. }
  128. /// <summary>
  129. /// Constructs a RoomInfo to be used in room listings in lobby.
  130. /// </summary>
  131. /// <param name="roomName">Name of the room and unique ID at the same time.</param>
  132. /// <param name="roomProperties">Properties for this room.</param>
  133. protected internal RoomInfo(string roomName, Hashtable roomProperties)
  134. {
  135. this.InternalCacheProperties(roomProperties);
  136. this.name = roomName;
  137. }
  138. /// <summary>
  139. /// Makes RoomInfo comparable (by name).
  140. /// </summary>
  141. public override bool Equals(object other)
  142. {
  143. RoomInfo otherRoomInfo = other as RoomInfo;
  144. return (otherRoomInfo != null && this.Name.Equals(otherRoomInfo.name));
  145. }
  146. /// <summary>
  147. /// Accompanies Equals, using the name's HashCode as return.
  148. /// </summary>
  149. /// <returns></returns>
  150. public override int GetHashCode()
  151. {
  152. return this.name.GetHashCode();
  153. }
  154. /// <summary>Returns most interesting room values as string.</summary>
  155. /// <returns>Summary of this RoomInfo instance.</returns>
  156. public override string ToString()
  157. {
  158. return string.Format("Room: '{0}' {1},{2} {4}/{3} players.", this.name, this.isVisible ? "visible" : "hidden", this.isOpen ? "open" : "closed", this.maxPlayers, this.PlayerCount);
  159. }
  160. /// <summary>Returns most interesting room values as string, including custom properties.</summary>
  161. /// <returns>Summary of this RoomInfo instance.</returns>
  162. public string ToStringFull()
  163. {
  164. return string.Format("Room: '{0}' {1},{2} {4}/{3} players.\ncustomProps: {5}", this.name, this.isVisible ? "visible" : "hidden", this.isOpen ? "open" : "closed", this.maxPlayers, this.PlayerCount, this.customProperties.ToStringFull());
  165. }
  166. /// <summary>Copies "well known" properties to fields (IsVisible, etc) and caches the custom properties (string-keys only) in a local hashtable.</summary>
  167. /// <param name="propertiesToCache">New or updated properties to store in this RoomInfo.</param>
  168. protected internal virtual void InternalCacheProperties(Hashtable propertiesToCache)
  169. {
  170. if (propertiesToCache == null || propertiesToCache.Count == 0 || this.customProperties.Equals(propertiesToCache))
  171. {
  172. return;
  173. }
  174. // check of this game was removed from the list. in that case, we don't
  175. // need to read any further properties
  176. // list updates will remove this game from the game listing
  177. if (propertiesToCache.ContainsKey(GamePropertyKey.Removed))
  178. {
  179. this.RemovedFromList = (bool)propertiesToCache[GamePropertyKey.Removed];
  180. if (this.RemovedFromList)
  181. {
  182. return;
  183. }
  184. }
  185. // fetch the "well known" properties of the room, if available
  186. if (propertiesToCache.ContainsKey(GamePropertyKey.MaxPlayers))
  187. {
  188. this.maxPlayers = (byte)propertiesToCache[GamePropertyKey.MaxPlayers];
  189. }
  190. if (propertiesToCache.ContainsKey(GamePropertyKey.IsOpen))
  191. {
  192. this.isOpen = (bool)propertiesToCache[GamePropertyKey.IsOpen];
  193. }
  194. if (propertiesToCache.ContainsKey(GamePropertyKey.IsVisible))
  195. {
  196. this.isVisible = (bool)propertiesToCache[GamePropertyKey.IsVisible];
  197. }
  198. if (propertiesToCache.ContainsKey(GamePropertyKey.PlayerCount))
  199. {
  200. this.PlayerCount = (int)((byte)propertiesToCache[GamePropertyKey.PlayerCount]);
  201. }
  202. if (propertiesToCache.ContainsKey(GamePropertyKey.CleanupCacheOnLeave))
  203. {
  204. this.autoCleanUp = (bool)propertiesToCache[GamePropertyKey.CleanupCacheOnLeave];
  205. }
  206. if (propertiesToCache.ContainsKey(GamePropertyKey.MasterClientId))
  207. {
  208. this.masterClientId = (int)propertiesToCache[GamePropertyKey.MasterClientId];
  209. }
  210. if (propertiesToCache.ContainsKey(GamePropertyKey.PropsListedInLobby))
  211. {
  212. this.propertiesListedInLobby = propertiesToCache[GamePropertyKey.PropsListedInLobby] as string[];
  213. }
  214. if (propertiesToCache.ContainsKey((byte)GamePropertyKey.ExpectedUsers))
  215. {
  216. this.expectedUsers = (string[])propertiesToCache[GamePropertyKey.ExpectedUsers];
  217. }
  218. if (propertiesToCache.ContainsKey((byte)GamePropertyKey.EmptyRoomTtl))
  219. {
  220. this.emptyRoomTtl = (int)propertiesToCache[GamePropertyKey.EmptyRoomTtl];
  221. }
  222. if (propertiesToCache.ContainsKey((byte)GamePropertyKey.PlayerTtl))
  223. {
  224. this.playerTtl = (int)propertiesToCache[GamePropertyKey.PlayerTtl];
  225. }
  226. // merge the custom properties (from your application) to the cache (only string-typed keys will be kept)
  227. this.customProperties.MergeStringKeys(propertiesToCache);
  228. this.customProperties.StripKeysWithNullValues();
  229. }
  230. }
  231. }