/// <summary>
    /// Joins a room by name and sets this player's properties.
    /// </summary>
    /// <param name="roomName"></param>
    /// <param name="playerProperties"></param>
    /// <param name="createIfNotExists"></param>
    /// <returns>If the operation could be sent (has to be connected).</returns>
    public virtual bool OpJoinRoom(string roomName, Hashtable playerProperties, bool createIfNotExists)
    {
        if (this.DebugOut >= DebugLevel.INFO)
        {
            this.Listener.DebugReturn(DebugLevel.INFO, "OpJoinRoom()");
        }

        if (string.IsNullOrEmpty(roomName))
        {
            this.Listener.DebugReturn(DebugLevel.ERROR, "OpJoinRoom() failed. Please specify a roomname.");
            return(false);
        }

        Dictionary <byte, object> op = new Dictionary <byte, object>();

        op[ParameterCode.RoomName]  = roomName;
        op[ParameterCode.Broadcast] = true;

        if (createIfNotExists)
        {
            op[ParameterCode.CreateIfNotExists] = createIfNotExists;
        }
        if (playerProperties != null)
        {
            op[ParameterCode.PlayerProperties] = playerProperties;
        }
        if (m_LogicObj != null)
        {
            m_LogicObj.SendJoinRoom(roomName);
        }
        if (PhotonHandler.IsShowLog())
        {
            PhotonHandler.ShowLog("OpJoinRoom()");
        }
        return(this.OpCustom(OperationCode.JoinGame, op, true));
    }