/// <summary>Creates a Room (representation) with given name and properties and the "listing options" as provided by parameters.</summary> /// <param name="roomName">Name of the room (can be null until it's actually created on server).</param> /// <param name="options">Room options.</param> protected internal Room(string roomName, RoomOptions options) : base(roomName, options.CustomRoomProperties) { // base sets name and (custom)properties. here we set "well known" properties this.isVisible = options.IsVisible; this.isOpen = options.IsOpen; this.maxPlayers = options.MaxPlayers; this.PropsListedInLobby = options.CustomRoomPropertiesForLobby; this.PlayerTTL = options.PlayerTtl; this.RoomTTL = options.EmptyRoomTtl; }
/// <summary>Internal "factory" method to create a room-instance.</summary> protected internal virtual Room CreateRoom(string roomName, RoomOptions opt) { if (opt == null) { opt = new RoomOptions(); } Room r = new Room(roomName, opt); return r; }
/// <summary> /// Joins a room by roomName. If this client returns to the room, set the previously used Player.ID as actorNumber. /// </summary> /// <remarks> /// This method is useful when you are using a lobby to list rooms and know their names. /// A room's name has to be unique (per region and game version), so it does not matter which lobby it's in. /// /// If this client returns to the room, set the previously used Player.ID as actorNumber. /// When you are using Custom Authentication with unique user IDs, the server will use the userID /// to find the previously assigned actorNumber in the room. /// /// For turnbased games, this is especially useful as rooms can be continued after hours or days. /// To return to a room, set the actorNumber to anything but 0. It's best practice to use -1 with /// Custom Authentication and unique user accounts. /// /// If the room is full, closed or not existing, this will fail. Override this class and implement /// OnOperationResponse(OperationResponse operationResponse) to get the errors. /// /// OpJoinRoom can only be called while the client is connected to a Master Server. /// You should check LoadBalancingClient.Server and LoadBalancingClient.IsConnectedAndReady before calling this method. /// Alternatively, check the returned bool value. /// /// While the server is joining the game, the State will be ClientState.Joining. /// It's set immediately when this method sends the Operation. /// /// If successful, the LoadBalancingClient will get a Game Server Address and use it automatically /// to switch servers and join the room. When you're in the room, this client's State will become /// ClientState.Joined (both, for joining or creating it). /// Set a OnStateChangeAction method to check for states. /// /// When joining a room, this client's Player Custom Properties will be sent to the room. /// Use LocalPlayer.SetCustomProperties to set them, even while not yet in the room. /// Note that the player properties will be cached locally and sent to any next room you would join, too. /// /// It's usually better to use OpJoinOrCreateRoom for invitations. /// Then it does not matter if the room is already setup. /// </remarks> /// <param name="roomName">The name of the room to join. Must be existing already, open and non-full or can't be joined.</param> /// <param name="actorNumber">When returning to a room, use a non-0 value. For Turnbased games, set the previously assigned Player.ID or -1 when using Custom Authentication.</param> /// <returns>If the operation could be sent currently (requires connection to Master Server).</returns> public bool OpJoinRoom(string roomName, int actorNumber) { this.State = ClientState.Joining; this.lastJoinType = JoinType.JoinRoom; this.lastJoinActorNumber = actorNumber; this.createRoomOptions = new RoomOptions(); this.CurrentRoom = CreateRoom(roomName, this.createRoomOptions); Hashtable playerPropsToSend = null; if (this.Server == ServerConnection.GameServer) { playerPropsToSend = this.LocalPlayer.AllProperties; } bool onGameServer = this.Server == ServerConnection.GameServer; return this.loadBalancingPeer.OpJoinRoom(roomName, playerPropsToSend, actorNumber, this.createRoomOptions, null, false, onGameServer); }
/// <summary> /// Joins a specific room by name. If the room does not exist (yet), it will be created implicitly. /// </summary> /// <remarks> /// Unlike OpJoinRoom, this operation does not fail if the room does not exist. /// This can be useful when you send invitations to a room before actually creating it: /// Any invited player (whoever is first) can call this and on demand, the room gets created implicitly. /// /// If you set room properties in RoomOptions, they get ignored when the room is existing already. /// This avoids changing the room properties by late joining players. Only when the room gets created, /// the RoomOptions are set in this case. /// /// If this client returns to the room, set the previously used Player.ID as actorNumber. /// When you are using Custom Authentication with unique user IDs, the server will use the userID /// to find the previously assigned actorNumber in the room. /// /// For turnbased games, this is especially useful as rooms can be continued after hours or days. /// To return to a room, set the actorNumber to anything but 0. It's best practice to use -1 with /// Custom Authentication and unique user accounts. /// /// If the room is full or closed, this will fail. Override this class and implement /// OnOperationResponse(OperationResponse operationResponse) to get the errors. /// /// This method can only be called while the client is connected to a Master Server. /// You should check LoadBalancingClient.Server and LoadBalancingClient.IsConnectedAndReady before calling this method. /// Alternatively, check the returned bool value. /// /// While the server is joining the game, the State will be ClientState.Joining. /// It's set immediately when this method sends the Operation. /// /// If successful, the LoadBalancingClient will get a Game Server Address and use it automatically /// to switch servers and join the room. When you're in the room, this client's State will become /// ClientState.Joined (both, for joining or creating it). /// Set a OnStateChangeAction method to check for states. /// /// When entering the room, this client's Player Custom Properties will be sent to the room. /// Use LocalPlayer.SetCustomProperties to set them, even while not yet in the room. /// Note that the player properties will be cached locally and sent to any next room you would join, too. /// </remarks> /// <param name="roomName">The name of the room to join (might be created implicitly).</param> /// <param name="actorNumber">When returning to a room, use a non-0 value. For Turnbased games, set the previously assigned Player.ID or -1 when using Custom Authentication.</param> /// <param name="roomOptions">Contains the parameters and properties of the new room. See RoomOptions class for a description of each.</param> /// <param name="lobby">Typed lobby to be used if the roomname is not in use (and room gets created). If != null, it will also set CurrentLobby.</param> /// <returns>If the operation could be sent currently (requires connection to Master Server).</returns> public bool OpJoinOrCreateRoom(string roomName, int actorNumber, RoomOptions roomOptions, TypedLobby lobby) { if (roomOptions == null) { roomOptions = new RoomOptions(); } this.State = ClientState.Joining; this.lastJoinType = JoinType.JoinOrCreateRoom; this.lastJoinActorNumber = actorNumber; this.createRoomOptions = roomOptions; this.CurrentRoom = CreateRoom(roomName, roomOptions); Hashtable playerPropsToSend = null; if (this.Server == ServerConnection.GameServer) { playerPropsToSend = this.LocalPlayer.AllProperties; } if (lobby != null) this.CurrentLobby = lobby; bool onGameServer = this.Server == ServerConnection.GameServer; return this.loadBalancingPeer.OpJoinRoom(roomName, playerPropsToSend, actorNumber, roomOptions, lobby, true, onGameServer); }
public bool OpJoinOrCreateRoom(string roomName, int actorNumber, RoomOptions roomOptions) { return OpJoinOrCreateRoom(roomName, actorNumber, roomOptions, null); }
/// <summary> /// Creates a new room on the server (or fails if the name is already in use). /// </summary> /// <remarks> /// If you don't want to create a unique room-name, pass null or "" as name and the server will assign a /// roomName (a GUID as string). Room names are unique. /// /// A room will be attached to the specified lobby. Use null as lobby to attach the /// room to the lobby you are now in. If you are in no lobby, the default lobby is used. /// /// Multiple lobbies can help separate players by map or skill or game type. Each room can only be found /// in one lobby (no matter if defined by name and type or as default). /// /// This method can only be called while the client is connected to a Master Server. /// You should check LoadBalancingClient.Server and LoadBalancingClient.IsConnectedAndReady before calling this method. /// Alternatively, check the returned bool value. /// /// Even when sent, the Operation will fail (on the server) if the roomName is in use. /// Override this class and implement OnOperationResponse(OperationResponse operationResponse) to get the errors. /// /// /// While the server is creating the game, the State will be ClientState.Joining. /// The state Joining is used because the client is on the way to enter a room (no matter if joining or creating). /// It's set immediately when this method sends the Operation. /// /// If successful, the LoadBalancingClient will get a Game Server Address and use it automatically /// to switch servers and enter the room. When you're in the room, this client's State will become /// ClientState.Joined (both, for joining or creating it). /// Set a OnStateChangeAction method to check for states. /// /// When entering the room, this client's Player Custom Properties will be sent to the room. /// Use LocalPlayer.SetCustomProperties to set them, even while not yet in the room. /// Note that the player properties will be cached locally and sent to any next room you would join, too. /// </remarks> /// <param name="roomName">The name to create a room with. Must be unique and not in use or can't be created. If null, the server will assign a GUID as name.</param> /// <param name="roomOptions">Contains the parameters and properties of the new room. See RoomOptions class for a description of each.</param> /// <param name="lobby">The lobby (name and type) in which to create the room. Null uses the current lobby or the default lobby (if not in a lobby).</param> /// <returns>If the operation could be sent currently (requires connection to Master Server).</returns> public bool OpCreateRoom(string roomName, RoomOptions roomOptions, TypedLobby lobby) { this.State = ClientState.Joining; this.lastJoinType = JoinType.CreateRoom; this.lastJoinActorNumber = 0; this.createRoomOptions = roomOptions; this.CurrentRoom = this.CreateRoom(roomName, roomOptions); Hashtable playerPropsToSend = null; if (this.Server == ServerConnection.GameServer) { playerPropsToSend = this.LocalPlayer.AllProperties; } this.CurrentLobby = lobby; bool onGameServer = this.Server == ServerConnection.GameServer; return this.loadBalancingPeer.OpCreateRoom(roomName, roomOptions, lobby, playerPropsToSend, onGameServer); }
public bool OpCreateRoom(string roomName, bool isVisible, bool isOpen, byte maxPlayers, Hashtable customGameProperties, string[] propsListedInLobby, string lobbyName, LobbyType lobbyType, int playerTtl, int roomTtl) { this.State = ClientState.Joining; this.lastJoinType = JoinType.CreateRoom; this.lastJoinActorNumber = 0; this.createRoomOptions = new RoomOptions() { IsVisible = isVisible, IsOpen = isOpen, MaxPlayers = maxPlayers, PlayerTtl = playerTtl, EmptyRoomTtl = roomTtl, CleanupCacheOnLeave = true, CustomRoomProperties = customGameProperties, CustomRoomPropertiesForLobby = propsListedInLobby }; this.CurrentRoom = this.CreateRoom(roomName, this.createRoomOptions); Hashtable playerPropsToSend = null; if (this.Server == ServerConnection.GameServer) { playerPropsToSend = this.LocalPlayer.AllProperties; } this.CurrentLobby = new TypedLobby(lobbyName, lobbyType); bool onGameServer = this.Server == ServerConnection.GameServer; return this.loadBalancingPeer.OpCreateRoom(roomName, this.createRoomOptions, new TypedLobby(lobbyName, lobbyType), playerPropsToSend, onGameServer); }
/// <summary> /// Joins a room by name or creates new room if room with given name not exists. /// The OperationResponse depends on the server the peer is connected to: /// Master will return a Game Server to connect to. /// Game Server will return the joined Room's data. /// This is an async request which triggers a OnOperationResponse() call. /// </summary> /// <remarks> /// If the room is not existing (anymore), the OperationResponse will have a returnCode of ErrorCode.GameDoesNotExist. /// Other possible ErrorCodes are: GameClosed, GameFull. /// </remarks> /// <param name="roomName">The name of an existing room.</param> /// <param name="playerProperties">This player's custom properties.</param> /// <param name="actorId">To allow players to return to a game, they have to specify their actorId.</param> /// <param name="createRoomOptions">Options used for new room creation (only sent if createIfNotExists is true).</param> /// <param name="lobby">Typed lobby to be used if the roomname is not in use (and room gets created). It's never used when createIfNotExists is false.</param> /// <param name="createIfNotExists">Tells the server to create the room if it doesn't exist (if true).</param> /// <param name="onGameServer">Master- and Game-Server require different parameters. This allows us to optimize the requests based on the server type (unknown in peer).</param> /// <returns>If the operation could be sent (requires connection).</returns> public virtual bool OpJoinRoom(string roomName, Hashtable playerProperties, int actorId, RoomOptions createRoomOptions, TypedLobby lobby, bool createIfNotExists, bool onGameServer) { if (this.DebugOut >= DebugLevel.INFO) { this.Listener.DebugReturn(DebugLevel.INFO, "OpJoinOrCreateRoom()"); } if (string.IsNullOrEmpty(roomName)) { this.Listener.DebugReturn(DebugLevel.ERROR, "OpJoinOrCreateRoom() failed. Please specify a roomname."); return false; } Dictionary<byte, object> op = new Dictionary<byte, object>(); op[ParameterCode.RoomName] = roomName; if (createIfNotExists) { op[ParameterCode.JoinMode] = (byte)JoinMode.CreateIfNotExists; if (lobby != null) { op[ParameterCode.LobbyName] = lobby.Name; op[ParameterCode.LobbyType] = (byte)lobby.Type; } } if (actorId != 0) { op[ParameterCode.JoinMode] = (byte)JoinMode.Rejoin; op[ParameterCode.ActorNr] = actorId; } if (onGameServer) { if (playerProperties != null) { op[ParameterCode.PlayerProperties] = playerProperties; op[ParameterCode.Broadcast] = true; } if (createIfNotExists) { this.RoomOptionsToOpParameters(op, createRoomOptions); } } return this.OpCustom(OperationCode.JoinGame, op, true); }
/// <summary> /// Creates a room (on either Master or Game Server). /// The OperationResponse depends on the server the peer is connected to: /// Master will return a Game Server to connect to. /// Game Server will return the joined Room's data. /// This is an async request which triggers a OnOperationResponse() call. /// </summary> /// <remarks> /// If the room is already existing, the OperationResponse will have a returnCode of ErrorCode.GameAlreadyExists. /// </remarks> /// <param name="roomName">The name of this room. Must be unique. Pass null to make the server assign a name.</param> /// <param name="roomOptions">Room creation options. Pass null for defaults.</param> /// <param name="lobby">Lobby this room gets added to. If null, current lobby (or default lobby) is used.</param> /// <param name="playerProperties">This player's custom properties. Use string keys!</param> /// <param name="onGameServer">This operation sends more parameters to the GameServer than to the MasterServer to optimize traffic.</param> /// <returns>If the operation could be sent (requires connection).</returns> public virtual bool OpCreateRoom(string roomName, RoomOptions roomOptions, TypedLobby lobby, Hashtable playerProperties, bool onGameServer) { if (this.DebugOut >= DebugLevel.INFO) { this.Listener.DebugReturn(DebugLevel.INFO, "OpCreateRoom()"); } Dictionary<byte, object> op = new Dictionary<byte, object>(); if (!string.IsNullOrEmpty(roomName)) { op[ParameterCode.RoomName] = roomName; } if (lobby != null && !string.IsNullOrEmpty(lobby.Name)) { op[ParameterCode.LobbyName] = lobby.Name; op[ParameterCode.LobbyType] = lobby.Type; } // room- and player-props are only needed by the GameServer if (onGameServer) { if (playerProperties != null) { op[ParameterCode.PlayerProperties] = playerProperties; op[ParameterCode.Broadcast] = true; } this.RoomOptionsToOpParameters(op, roomOptions); } return this.OpCustom(OperationCode.CreateGame, op, true); }
private void RoomOptionsToOpParameters(Dictionary<byte, object> op, RoomOptions roomOptions) { if (roomOptions == null) { roomOptions = new RoomOptions(); } Hashtable gameProperties = new Hashtable(); gameProperties[GamePropertyKey.IsOpen] = roomOptions.IsOpen; gameProperties[GamePropertyKey.IsVisible] = roomOptions.IsVisible; gameProperties[GamePropertyKey.PropsListedInLobby] = (roomOptions.CustomRoomPropertiesForLobby == null) ? new string[0] : roomOptions.CustomRoomPropertiesForLobby; gameProperties.MergeStringKeys(roomOptions.CustomRoomProperties); if (roomOptions.MaxPlayers > 0) { gameProperties[GamePropertyKey.MaxPlayers] = roomOptions.MaxPlayers; } op[ParameterCode.GameProperties] = gameProperties; op[ParameterCode.CleanupCacheOnLeave] = roomOptions.CleanupCacheOnLeave; if (roomOptions.CheckUserOnJoin) { op[ParameterCode.CheckUserOnJoin] = true; //TURNBASED } if (roomOptions.PlayerTtl > 0 || roomOptions.PlayerTtl == -1) { op[ParameterCode.PlayerTTL] = roomOptions.PlayerTtl; //TURNBASED } if (roomOptions.EmptyRoomTtl > 0) { op[ParameterCode.EmptyRoomTTL] = roomOptions.EmptyRoomTtl; //TURNBASED } if (roomOptions.SuppressRoomEvents) { op[ParameterCode.SuppressRoomEvents] = true; } if (roomOptions.Plugins != null) { op[ParameterCode.Plugins] = roomOptions.Plugins; } }
/// <summary> /// Demo method that makes up a roomname and sets up the room in general. /// </summary> public void CreateTurnbasedRoom(string roomPwd) { string newRoomName = this.PlayerName + "-" + Random.Range(0, 1000).ToString("D4"); // for int, Random.Range is max-exclusive! Debug.Log("CreateTurnbasedRoom() will create: " + newRoomName); var customRoomProperties = new Hashtable() { { "pwd", roomPwd } }; RoomOptions roomOptions = new RoomOptions() { MaxPlayers = kPlayersNum, CustomRoomProperties = customRoomProperties, CustomRoomPropertiesForLobby = kRoomPropsInLobby, EmptyRoomTtl = kEmptyRoomTtl, PlayerTtl = kPlayerTtl }; this.OpCreateRoom(newRoomName, roomOptions, TypedLobby.Default); }
/// <summary> /// Override of the factory method used by the LoadBalancing framework (which we extend here) to create a Room instance. /// </summary> /// <remarks> /// While CreateParticleDemoRoom will make the server create the room, this method creates a local object to represent that room. /// /// This method is used by a LoadBalancingClient automatically whenever this client joins or creates a room. /// We override it to produce a ParticleRoom which has more features like Map and GridSize. /// </remarks> protected internal override Room CreateRoom(string roomName, RoomOptions opt) { return new ParticleRoom(roomName, opt); }
/// <summary> /// Joins a specific room by name. If the room does not exist (yet), it will be created implicitly. /// </summary> /// <remarks> /// Unlike OpJoinRoom, this operation does not fail if the room does not exist. /// This can be useful when you send invitations to a room before actually creating it: /// Any invited player (whoever is first) can call this and on demand, the room gets created implicitly. /// /// If you set room properties in RoomOptions, they get ignored when the room is existing already. /// This avoids changing the room properties by late joining players. Only when the room gets created, /// the RoomOptions are set in this case. /// /// If this client returns to the room, set the previously used Player.ID as actorNumber. /// When you are using Custom Authentication with unique user IDs, the server will use the userID /// to find the previously assigned actorNumber in the room. /// /// For turnbased games, this is especially useful as rooms can be continued after hours or days. /// To return to a room, set the actorNumber to anything but 0. It's best practice to use -1 with /// Custom Authentication and unique user accounts. /// /// If the room is full or closed, this will fail. Override this class and implement /// OnOperationResponse(OperationResponse operationResponse) to get the errors. /// /// This method can only be called while the client is connected to a Master Server. /// You should check LoadBalancingClient.Server and LoadBalancingClient.IsConnectedAndReady before calling this method. /// Alternatively, check the returned bool value. /// /// While the server is joining the game, the State will be ClientState.Joining. /// It's set immediately when this method sends the Operation. /// /// If successful, the LoadBalancingClient will get a Game Server Address and use it automatically /// to switch servers and join the room. When you're in the room, this client's State will become /// ClientState.Joined (both, for joining or creating it). /// Set a OnStateChangeAction method to check for states. /// /// When entering the room, this client's Player Custom Properties will be sent to the room. /// Use LocalPlayer.SetCustomProperties to set them, even while not yet in the room. /// Note that the player properties will be cached locally and sent to any next room you would join, too. /// </remarks> /// <param name="roomName">The name of the room to join (might be created implicitly).</param> /// <param name="actorNumber">When returning to a room, use a non-0 value. For Turnbased games, set the previously assigned Player.ID or -1 when using Custom Authentication.</param> /// <param name="roomOptions">Contains the parameters and properties of the new room. See RoomOptions class for a description of each.</param> /// <param name="lobby">Typed lobby to be used if the roomname is not in use (and room gets created). If != null, it will also set CurrentLobby.</param> /// <returns>If the operation could be sent currently (requires connection to Master Server).</returns> public bool OpJoinOrCreateRoom(string roomName, int actorNumber, RoomOptions roomOptions, TypedLobby lobby) { this.State = ClientState.Joining; this.lastJoinType = JoinType.JoinOrCreateRoom; this.CurrentLobby = lobby; bool onGameServer = this.Server == ServerConnection.GameServer; LoadBalancingPeer.EnterRoomParams opParams = new LoadBalancingPeer.EnterRoomParams(); this.enterRoomParamsCache = opParams; opParams.RoomName = roomName; opParams.ActorNumber = actorNumber; opParams.RoomOptions = roomOptions; opParams.Lobby = lobby; opParams.CreateIfNotExists = true; opParams.OnGameServer = onGameServer; return this.loadBalancingPeer.OpJoinRoom(opParams); //return this.loadBalancingPeer.OpJoinRoom(roomName, playerPropsToSend, actorNumber, roomOptions, lobby, true, onGameServer); }
/// <summary> /// Uses the base constructor to initialize this ParticleRoom. /// </summary> protected internal ParticleRoom(string roomName, RoomOptions opt) : base(roomName, opt) { }