Example #1
0
func TwitchLogoutHandler(w http.ResponseWriter, r *http.Request) {
	token, err := controllerhelpers.GetToken(r)
	if err == http.ErrNoCookie {
		http.Error(w, "You are not logged in.", http.StatusUnauthorized)
		return
	} else if err != nil {
		http.Error(w, "Invalid jwt", http.StatusBadRequest)
		return
	}

	id := token.Claims.(*controllerhelpers.TF2StadiumClaims).PlayerID

	player, _ := player.GetPlayerByID(id)
	player.TwitchName = ""
	player.TwitchAccessToken = ""
	player.Save()

	referer, ok := r.Header["Referer"]
	if ok {
		http.Redirect(w, r, referer[0], 303)
		return
	}

	http.Redirect(w, r, config.Constants.LoginRedirectPath, http.StatusTemporaryRedirect)
}
Example #2
0
//RemoveUnreadyPlayers removes players who haven't removed. If spec == true, move them to spectators
func (lobby *Lobby) RemoveUnreadyPlayers(spec bool) error {
	playerids := []uint{}

	if spec {
		//get list of player ids which are not ready
		err := db.DB.Model(&LobbySlot{}).Where("lobby_id = ? AND ready = ?", lobby.ID, false).Pluck("player_id", &playerids).Error
		if err != nil {
			return err
		}
	}

	//remove players which aren't ready
	lobby.Lock()
	err := db.DB.Where("lobby_id = ? AND ready = ?", lobby.ID, false).Delete(&LobbySlot{}).Error
	lobby.Unlock()

	if spec {
		for _, id := range playerids {
			p, _ := player.GetPlayerByID(id)
			lobby.AddSpectator(p)
		}
	}
	lobby.OnChange(true)
	return err
}
Example #3
0
func TwitchLoginHandler(w http.ResponseWriter, r *http.Request) {
	token, err := controllerhelpers.GetToken(r)
	if err == http.ErrNoCookie {
		http.Error(w, "You are not logged in.", http.StatusUnauthorized)
		return
	} else if err != nil {
		http.Error(w, "Invalid jwt", http.StatusBadRequest)
		return
	}

	id := token.Claims.(*controllerhelpers.TF2StadiumClaims).PlayerID
	player, _ := player.GetPlayerByID(id)
	loginURL := url.URL{
		Scheme: "https",
		Host:   "api.twitch.tv",
		Path:   "kraken/oauth2/authorize",
	}

	//twitchRedirectURL := config.Constants.PublicAddress + "/" + "twitchAuth"
	twitchRedirectURL, _ := url.Parse(config.Constants.PublicAddress)
	twitchRedirectURL.Path = "twitchAuth"

	values := loginURL.Query()
	values.Set("response_type", "code")
	values.Set("client_id", config.Constants.TwitchClientID)
	values.Set("redirect_uri", twitchRedirectURL.String())
	values.Set("scope", "channel_check_subscription user_subscriptions channel_subscriptions user_read")
	values.Set("state", xsrftoken.Generate(config.Constants.CookieStoreSecret, player.SteamID, "GET"))
	loginURL.RawQuery = values.Encode()

	http.Redirect(w, r, loginURL.String(), http.StatusTemporaryRedirect)
}
Example #4
0
func decorateSlotDetails(lobby *Lobby, slot int, playerInfo bool) SlotDetails {
	playerId, err := lobby.GetPlayerIDBySlot(slot)
	needsSub := lobby.SlotNeedsSubstitute(slot)

	slotDetails := SlotDetails{Slot: slot, Filled: err == nil && !needsSub}

	if err == nil && playerInfo && !needsSub {
		p, _ := player.GetPlayerByID(playerId)
		p.SetPlayerSummary()

		slotDetails.Player = p

		ready, _ := lobby.IsPlayerReady(p)
		slotDetails.Ready = &ready

		ingame := lobby.IsPlayerInGame(p)
		slotDetails.InGame = &ingame

		inmumble := lobby.IsPlayerInMumble(p)
		slotDetails.InMumble = &inmumble
	}

	if lobby.HasSlotRequirement(slot) {
		req, _ := lobby.GetSlotRequirement(slot)
		if req != nil {
			slotDetails.Requirements = req
			slotDetails.Password = req.Password != ""
		}
	}

	return slotDetails
}
Example #5
0
// shitlord
func CheckPrivilege(so *wsevent.Client, action authority.AuthAction) error {
	//Checks if the client has the neccesary authority to perform action
	player, _ := player.GetPlayerByID(so.Token.Claims.(*TF2StadiumClaims).PlayerID)
	if !player.Role.Can(action) {
		return errors.New("You are not authorized to perform this action")
	}
	return nil
}
Example #6
0
//Not really broadcast, since it sends each client a different LobbyStart JSON
func BroadcastLobbyStart(lob *lobby.Lobby) {
	for _, slot := range lob.GetAllSlots() {
		player, _ := player.GetPlayerByID(slot.PlayerID)

		connectInfo := lobby.DecorateLobbyConnect(lob, player, slot.Slot)
		broadcaster.SendMessage(player.SteamID, "lobbyStart", connectInfo)
	}
}
Example #7
0
func mumbleLeft(playerID uint) {
	player, _ := playerpackage.GetPlayerByID(playerID)
	id, _ := player.GetLobbyID(false)
	if id == 0 { // player joined mumble lobby for closed channel
		return
	}

	lobby, _ := lobbypackage.GetLobbyByID(id)
	lobby.SetNotInMumble(player)
}
Example #8
0
//UpdateStats updates the PlayerStats records for all players in the lobby
//(increments the relevent lobby type field by one). Used when the lobby successfully ends.
func (lobby *Lobby) UpdateStats() {
	db.DB.Preload("Slots").First(lobby, lobby.ID)

	for _, slot := range lobby.Slots {
		p, _ := player.GetPlayerByID(slot.PlayerID)

		db.DB.Preload("Stats").First(p, slot.PlayerID)
		p.Stats.PlayedCountIncrease(lobby.Type)
		p.Stats.IncreaseClassCount(lobby.Type, slot.Slot)
		p.Save()
	}
	lobby.OnChange(false)
}
Example #9
0
// move player_settings values to player.Settings hstore
func setPlayerSettings() {
	rows, err := db.DB.DB().Query("SELECT player_id, key, value FROM player_settings")
	if err != nil {
		logrus.Fatal(err)
	}
	for rows.Next() {
		var playerID uint
		var key, value string

		rows.Scan(&playerID, &key, &value)
		p, _ := player.GetPlayerByID(playerID)
		p.SetSetting(key, value)
	}

	db.DB.Exec("DROP TABLE player_settings")
}
Example #10
0
func moveReportsServers() {
	type oldReport struct {
		PlayerID uint
		LobbyID  uint
	}

	reportTypes := []struct {
		table string
		rtype player.ReportType
	}{
		{"ragequits_player_lobbies", player.RageQuit},
		{"reports_player_lobbies", player.Vote},
		{"substitutes_player_lobbies", player.Substitute},
	}

	for _, rtype := range reportTypes {
		rows, _ := db.DB.DB().Query("SELECT * FROM " + rtype.table)

		logrus.Info("Creating entries for ", rtype.table)
		for rows.Next() {
			var report oldReport

			rows.Scan(&report.PlayerID, &report.LobbyID)
			p, _ := player.GetPlayerByID(report.PlayerID)
			newReport := &player.Report{
				PlayerID: p.ID,
				LobbyID:  report.LobbyID,
				Type:     rtype.rtype,
			}
			db.DB.Create(newReport)
		}
	}

	db.DB.Exec("DROP TABLE ragequits_player_lobbies")
	db.DB.Exec("DROP TABLE reports_player_lobbies")
	db.DB.Exec("DROP TABLE substitutes_player_lobbies")
}
Example #11
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
}
Example #12
0
func TwitchAuthHandler(w http.ResponseWriter, r *http.Request) {
	token, err := controllerhelpers.GetToken(r)
	if err == http.ErrNoCookie {
		http.Error(w, "You are not logged in.", http.StatusUnauthorized)
		return
	} else if err != nil {
		http.Error(w, "Invalid jwt", http.StatusBadRequest)
		return
	}

	id := token.Claims.(*controllerhelpers.TF2StadiumClaims).PlayerID
	player, _ := player.GetPlayerByID(id)

	values := r.URL.Query()
	code := values.Get("code")
	if code == "" {
		http.Error(w, "No code given", http.StatusBadRequest)
		return
	}

	state := values.Get("state")
	if state == "" || !xsrftoken.Valid(state, config.Constants.CookieStoreSecret, player.SteamID, "GET") {
		http.Error(w, "Missing or Invalid XSRF token", http.StatusBadRequest)
		return
	}

	twitchRedirectURL, _ := url.Parse(config.Constants.PublicAddress)
	twitchRedirectURL.Path = "twitchAuth"

	// successful login, try getting access token now
	tokenURL := url.URL{
		Scheme: "https",
		Host:   "api.twitch.tv",
		Path:   "kraken/oauth2/token",
	}
	values = tokenURL.Query()
	values.Set("client_id", config.Constants.TwitchClientID)
	values.Set("client_secret", config.Constants.TwitchClientSecret)
	values.Set("grant_type", "authorization_code")
	values.Set("redirect_uri", twitchRedirectURL.String())
	values.Set("code", code)
	values.Set("state", state)

	req, err := http.NewRequest("POST", tokenURL.String(), strings.NewReader(values.Encode()))
	if err != nil {
		logrus.Error(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	resp, err := helpers.HTTPClient.Do(req)
	if err != nil {
		logrus.Error(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	reply := reply{}

	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&reply)
	if err != nil {
		logrus.Error(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	info, err := getUserInfo(reply.AccessToken)
	if err != nil {
		logrus.Error(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	player.TwitchName = info.Name
	player.TwitchAccessToken = reply.AccessToken
	player.Save()

	http.Redirect(w, r, config.Constants.LoginRedirectPath, http.StatusTemporaryRedirect)
}
Example #13
0
func DecorateLobbyData(lobby *Lobby, playerInfo bool) LobbyData {
	lobbyData := LobbyData{
		ID:                lobby.ID,
		Mode:              lobby.Mode,
		Type:              format.FriendlyNamesMap[lobby.Type],
		Players:           lobby.GetPlayerNumber(),
		Map:               lobby.MapName,
		League:            lobby.League,
		Mumble:            lobby.Mumble,
		Discord:           lobby.Discord,
		TwitchChannel:     lobby.TwitchChannel,
		TwitchRestriction: lobby.TwitchRestriction.String(),
		RegionLock:        lobby.RegionLock,
		RedTeamName:       lobby.RedTeamName,
		BluTeamName:       lobby.BluTeamName,

		SteamGroup: lobby.PlayerWhitelist,
	}

	lobbyData.Region.Name = lobby.RegionName
	lobbyData.Region.Code = lobby.RegionCode

	classList := format.GetClasses(lobby.Type)

	classes := make([]ClassDetails, len(classList))
	lobbyData.MaxPlayers = format.NumberOfClassesMap[lobby.Type] * 2

	for slot, className := range classList {
		class := ClassDetails{
			Red:   decorateSlotDetails(lobby, slot, playerInfo),
			Blu:   decorateSlotDetails(lobby, slot+format.NumberOfClassesMap[lobby.Type], playerInfo),
			Class: className,
		}

		classes[slot] = class
	}

	lobbyData.Classes = classes
	lobbyData.WhitelistID = lobby.Whitelist

	if !playerInfo {
		return lobbyData
	}

	if lobby.CreatedBySteamID != "" { // == "" during tests
		leader, _ := player.GetPlayerBySteamID(lobby.CreatedBySteamID)
		leader.SetPlayerSummary()
		lobbyData.Leader = *leader
	}

	lobbyData.CreatedAt = lobby.CreatedAt.Unix()
	lobbyData.State = int(lobby.State)

	var specIDs []uint
	db.DB.Table("spectators_players_lobbies").Where("lobby_id = ?", lobby.ID).Pluck("player_id", &specIDs)

	spectators := make([]SpecDetails, len(specIDs))

	for i, spectatorID := range specIDs {
		specPlayer, _ := player.GetPlayerByID(spectatorID)

		specJs := SpecDetails{
			Name:    specPlayer.Alias(),
			SteamID: specPlayer.SteamID,
		}

		spectators[i] = specJs
	}

	lobbyData.Spectators = spectators

	return lobbyData
}
Example #14
0
func GetPlayer(token *jwt.Token) *player.Player {
	player, _ := player.GetPlayerByID(token.Claims.(*TF2StadiumClaims).PlayerID)
	return player
}