Example #1
0
//RemovePlayer removes a given player from the lobby
func (lobby *Lobby) RemovePlayer(player *player.Player) error {
	lobby.Lock()
	err := db.DB.Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).Delete(&LobbySlot{}).Error
	lobby.Unlock()

	if err != nil {
		return err
	}

	rpc.DisallowPlayer(lobby.ID, player.SteamID, player.ID)
	lobby.OnChange(true)
	return nil
}
Example #2
0
//BanPlayer bans a given player from the lobby
func (lobby *Lobby) BanPlayer(player *player.Player) {
	rpc.DisallowPlayer(lobby.ID, player.SteamID, player.ID)
	db.DB.Model(lobby).Association("BannedPlayers").Append(player)
}
Example #3
0
//AddPlayer adds the given player to lobby, If the player occupies a slot in the lobby already, switch slots.
//If the player is in another lobby, removes them from that lobby before adding them.
func (lobby *Lobby) AddPlayer(p *player.Player, slot int, password string) error {
	/* Possible errors while joining
	 * Slot has been filled
	 * Player has already joined a lobby
	 * anything else?
	 */

	//Check if player is banned
	if lobby.IsPlayerBanned(p) {
		return ErrLobbyBan
	}

	if slot >= 2*format.NumberOfClassesMap[lobby.Type] || slot < 0 {
		return ErrBadSlot
	}

	isSubstitution := lobby.SlotNeedsSubstitute(slot)

	//Check whether the slot is occupied
	if !isSubstitution && lobby.IsSlotOccupied(slot) {
		return ErrFilled
	}

	if lobby.HasSlotRequirement(slot) {
		//check if player fits the requirements for the slot
		if ok, err := lobby.FitsRequirements(p, slot); !ok {
			return err
		}

		req, _ := lobby.GetSlotRequirement(slot)
		if password != req.Password {
			return ErrInvalidPassword
		}
	}

	var slotChange bool
	//Check if the player is currently in another lobby
	if currLobbyID, err := p.GetLobbyID(false); err == nil {
		if currLobbyID != lobby.ID {
			//if the player is in a different lobby, remove them from that lobby
			//plus substitute them
			curLobby, _ := GetLobbyByID(currLobbyID)

			if curLobby.State == InProgress {
				curLobby.Substitute(p)
			} else {
				curLobby.Lock()
				db.DB.Where("player_id = ? AND lobby_id = ?", p.ID, curLobby.ID).Delete(&LobbySlot{})
				curLobby.Unlock()

			}

		} else { //player is in the same lobby, they're changing their slots
			//assign the player to a new slot
			if isSubstitution {
				//the slot needs a substitute (which happens when the lobby is in progress),
				//so players already in the lobby cannot fill it.
				return ErrNeedsSub
			}
			lobby.Lock()
			db.DB.Where("player_id = ? AND lobby_id = ?", p.ID, lobby.ID).Delete(&LobbySlot{})
			lobby.Unlock()

			slotChange = true
		}
	}

	if !slotChange {
		//check if the player is in the steam group whitelist
		url := fmt.Sprintf(`http://steamcommunity.com/groups/%s/memberslistxml/?xml=1`,
			lobby.PlayerWhitelist)

		if lobby.PlayerWhitelist != "" && !helpers.IsWhitelisted(p.SteamID, url) {
			return ErrNotWhitelisted
		}

		//check if player has been subbed to the twitch channel (if any)
		//allow channel owners
		if lobby.TwitchChannel != "" && p.TwitchName != lobby.TwitchChannel {
			//check if player has connected their twitch account
			if p.TwitchAccessToken == "" {
				return errors.New("You need to connect your Twitch Account first to join the lobby.")
			}
			if lobby.TwitchRestriction == TwitchSubscribers && !p.IsSubscribed(lobby.TwitchChannel) {
				return fmt.Errorf("You aren't subscribed to %s", lobby.TwitchChannel)
			}
			if lobby.TwitchRestriction == TwitchFollowers && !p.IsFollowing(lobby.TwitchChannel) {
				return fmt.Errorf("You aren't following %s", lobby.TwitchChannel)
			}
		}
	}

	// Check if player is a substitute (the slot needs a subtitute)
	if isSubstitution {
		//get previous slot, to kick them from game
		prevPlayerID, _ := lobby.GetPlayerIDBySlot(slot)
		prevPlayer, _ := player.GetPlayerByID(prevPlayerID)

		lobby.Lock()
		db.DB.Where("lobby_id = ? AND slot = ?", lobby.ID, slot).Delete(&LobbySlot{})
		lobby.Unlock()

		go func() {
			//kicks previous slot occupant if they're in-game, resets their !rep count, removes them from the lobby
			rpc.DisallowPlayer(lobby.ID, prevPlayer.SteamID, prevPlayer.ID)
			BroadcastSubList() //since the sub slot has been deleted, broadcast the updated substitute list
			//notify players in game server of subtitute
			class, team, _ := format.GetSlotTeamClass(lobby.Type, slot)
			rpc.Say(lobby.ID, fmt.Sprintf("Substitute found for %s %s: %s (%s)", team, class, p.Name, p.SteamID))
		}()
		//allow player in mumble
	}

	//try to remove them from spectators
	lobby.RemoveSpectator(p, true)

	newSlotObj := &LobbySlot{
		PlayerID: p.ID,
		LobbyID:  lobby.ID,
		Slot:     slot,
	}

	lobby.Lock()
	db.DB.Create(newSlotObj)
	lobby.Unlock()
	if !slotChange {
		if p.TwitchName != "" {
			rpc.TwitchBotAnnouce(p.TwitchName, lobby.ID)
		}
	}

	lobby.OnChange(true)
	p.SetMumbleUsername(lobby.Type, slot)

	return nil
}