Example #1
0
func IsAllowed(userid uint32, lobbyid uint, channelname string) (bool, string) {
	var lobbyType, slot int
	db.QueryRow("SELECT type FROM lobbies WHERE id = $1", lobbyid).Scan(&lobbyType)
	err := db.QueryRow("SELECT slot FROM lobby_slots WHERE player_id = $1 AND lobby_id = $2", userid, lobbyid).Scan(&slot)
	if err == sql.ErrNoRows {
		return false, "You're not in this lobby"
	} else if err != nil {
		log.Println(err)
		return false, "Internal fumble error"
	}

	if channelname[0] == 'L' { // channel name is "Lobby..."
		return true, ""
	}

	//channel name is either "RED" or "BLU"
	team, _, err := format.GetSlotTeamClass(format.Format(lobbyType), slot)
	if err != nil {
		log.Println(err)
	}

	if team != strings.ToLower(channelname) {
		return false, "You're in team " + strings.ToUpper(team) + ", not " + channelname
	}

	return true, ""
}
Example #2
0
func (player *Player) SetMumbleUsername(lobbyType format.Format, slot int) {
	_, class, _ := format.GetSlotTeamClass(lobbyType, slot)
	username := strings.ToUpper(class) + "_"
	alias := player.GetSetting("siteAlias")

	switch {
	case isClean(alias):
		username += strings.Replace(alias, " ", "_", -1)
	case isClean(player.Name):
		username += strings.Replace(player.Name, " ", "_", -1)
	case reSteamProfileID.MatchString(player.Profileurl):
		m := reSteamProfileID.FindStringSubmatch(player.Profileurl)
		username += m[1]
	default:
		username += player.SteamID
	}

	var count int
	db.DB.Model(&Player{}).Where("mumble_username = ? AND id <> ?", username, player.ID).Count(&count)
	for count != 0 {
		username += "_"
		db.DB.Model(&Player{}).Where("mumble_username = ? AND id <> ?", username, player.ID).Count(&count)
	}

	db.DB.Model(&Player{}).Where("id = ?", player.ID).UpdateColumn("mumble_username", username)
}
Example #3
0
func GetTeam(lobbyID uint, lobbyType format.Format, commID string) (team string) {
	var slot int
	err := db.QueryRow("SELECT lobby_slots.slot FROM lobby_slots INNER JOIN players ON lobby_slots.player_id = players.id WHERE lobby_slots.lobby_id = $1 AND players.steam_id = $2", lobbyID, commID).Scan(&slot)
	if err != nil {
		helpers.Logger.Error(err.Error())
	}
	team, _, _ = format.GetSlotTeamClass(lobbyType, slot)
	return
}
Example #4
0
func GetCurrentLobby(userid uint32) (uint, string) {
	var lobbyID uint
	var slot int
	var lobbyFormat format.Format

	err := db.QueryRow("SELECT lobby_slots.lobby_id, lobby_slots.slot, lobbies.type FROM lobbies INNER JOIN lobby_slots ON lobbies.id = lobby_slots.lobby_id WHERE lobby_slots.player_id = $1 AND lobbies.state <> $2 AND lobbies.state <> $3", userid, lobby.Ended, lobby.Initializing).Scan(&lobbyID, &slot, &lobbyFormat)
	if err != nil && err != sql.ErrNoRows { // if err == ErrNoRows, player isn't in any active lobby
		log.Println(err)
	}

	team, _, _ := format.GetSlotTeamClass(lobbyFormat, slot)

	return lobbyID, team
}
Example #5
0
func DecorateLobbyConnect(lob *Lobby, player *player.Player, slot int) LobbyConnectData {
	l := LobbyConnectData{}
	l.ID = lob.ID
	l.Time = lob.CreatedAt.Unix()
	l.Pass = lob.ServerInfo.ServerPassword
	l.Game.Host = lob.ServerInfo.Host

	l.Mumble.Address = config.Constants.MumbleAddr
	l.Mumble.Password = player.MumbleAuthkey
	team, _, _ := format.GetSlotTeamClass(lob.Type, slot)
	l.Mumble.Channel = fmt.Sprintf("Lobby #%d/%s", lob.ID, strings.ToUpper(team))

	if lob.Discord {
		if team == "red" {
			l.DiscordChannel = lob.DiscordRedChannel
		} else {
			l.DiscordChannel = lob.DiscordBluChannel
		}
	}

	return l
}
Example #6
0
func DecorateSubstitute(slot *LobbySlot) SubstituteData {
	lobby, _ := GetLobbyByID(slot.LobbyID)

	substitute := SubstituteData{
		LobbyID:       lobby.ID,
		Format:        format.FriendlyNamesMap[lobby.Type],
		MapName:       lobby.MapName,
		Mumble:        lobby.Mumble,
		TwitchChannel: lobby.TwitchChannel,
		SteamGroup:    lobby.PlayerWhitelist,
		RegionLock:    lobby.RegionLock,
	}

	req, _ := lobby.GetSlotRequirement(slot.Slot)
	if req != nil {
		substitute.Password = req.Password != ""
	}

	substitute.Region.Name = lobby.RegionName
	substitute.Region.Code = lobby.RegionCode
	substitute.Team, substitute.Class, _ = format.GetSlotTeamClass(lobby.Type, slot.Slot)

	return substitute
}
Example #7
0
func (ps *PlayerStats) IncreaseClassCount(f format.Format, slot int) {
	_, class, _ := format.GetSlotTeamClass(f, slot)
	switch class {
	case "scout", "scout1", "scout2":
		ps.Scout++
	case "roamer", "pocket", "soldier", "soldier1", "soldier2":
		ps.Soldier++
	case "pyro":
		ps.Pyro++
	case "engineer":
		ps.Engineer++
	case "heavy":
		ps.Heavy++
	case "demoman":
		ps.Demoman++
	case "sniper":
		ps.Sniper++
	case "medic":
		ps.Medic++
	case "spy":
		ps.Spy++
	}
	database.DB.Save(ps)
}
Example #8
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
}