예제 #1
0
파일: lobby.go 프로젝트: TF2Stadium/Helen
func removePlayerFromLobby(lobbyId uint, steamId string) (*lobby.Lobby, *player.Player, error) {
	player, err := player.GetPlayerBySteamID(steamId)
	if err != nil {
		return nil, nil, err
	}

	lob, err := lobby.GetLobbyByID(lobbyId)
	if err != nil {
		return nil, nil, err
	}

	switch lob.State {
	case lobby.InProgress:
		lob.Substitute(player)
		return lob, player, lob.AddSpectator(player)
	case lobby.Ended:
		return lob, player, errors.New("Lobby has closed.")
	}

	_, err = lob.GetPlayerSlot(player)
	if err != nil {
		return lob, player, errors.New("Player not playing")
	}

	if err := lob.RemovePlayer(player); err != nil {
		return lob, player, err
	}

	return lob, player, lob.AddSpectator(player)
}
예제 #2
0
파일: player.go 프로젝트: TF2Stadium/Helen
func (Player) PlayerRecentLobbies(so *wsevent.Client, args struct {
	SteamID *string `json:"steamid"`
	Lobbies *int    `json:"lobbies"`
	LobbyID int     `json:"lobbyId"` // start from this lobbyID, 0 when not specified in json
}) interface{} {
	var p *player.Player

	if *args.SteamID != "" {
		var err error
		p, err = player.GetPlayerBySteamID(*args.SteamID)
		if err != nil {
			return err
		}

	} else {
		p = chelpers.GetPlayer(so.Token)
	}

	var lobbies []*lobby.Lobby

	db.DB.Model(&lobby.Lobby{}).Joins("INNER JOIN lobby_slots ON lobbies.ID = lobby_slots.lobby_id").
		Where("lobbies.match_ended = TRUE and lobby_slots.player_id = ? AND lobby_slots.needs_sub = FALSE AND lobbies.ID >= ?", p.ID, args.LobbyID).
		Order("lobbies.id desc").
		Limit(*args.Lobbies).
		Find(&lobbies)

	return newResponse(lobby.DecorateLobbyListData(lobbies, true))
}
예제 #3
0
파일: event.go 프로젝트: TF2Stadium/Helen
func playerConn(steamID string, lobbyID uint) {
	player, _ := playerpackage.GetPlayerBySteamID(steamID)
	lobby, _ := lobbypackage.GetLobbyByID(lobbyID)

	lobby.SetInGame(player)
	chat.SendNotification(fmt.Sprintf("%s has connected to the server.", player.Alias()), int(lobby.ID))
}
예제 #4
0
파일: lobby.go 프로젝트: TF2Stadium/Helen
func (lobby *Lobby) DiscordNotif(msg string) {
	if helpers.Discord != nil {
		mumble := ""
		if lobby.Mumble {
			mumble = helpers.DiscordEmoji("mumble")
		}

		region := lobby.RegionName
		if lobby.RegionCode == "eu" || lobby.RegionCode == "au" {
			region = fmt.Sprintf(":flag_%s:", lobby.RegionCode)
		} else if lobby.RegionCode == "na" {
			region = ":flag_us:"
		}

		byLine := ""
		player, playerErr := player.GetPlayerBySteamID(lobby.CreatedBySteamID)
		if playerErr != nil {
			logrus.Error(playerErr)
		} else {
			byLine = fmt.Sprintf(" by %s", player.Alias())
		}

		formatName := format.FriendlyNamesMap[lobby.Type]

		msg := fmt.Sprintf("%s: %s%s %s on %s%s: %s/lobby/%d", msg, region, mumble, formatName, lobby.MapName, byLine, config.Constants.LoginRedirectPath, lobby.ID)
		specificChannel := strings.ToLower(fmt.Sprintf("%s-%s", formatName, lobby.RegionCode))
		helpers.DiscordSendToChannel("lobby-notifications", msg)
		helpers.DiscordSendToChannel(specificChannel, fmt.Sprintf("@here %s", msg))
	}
}
예제 #5
0
파일: lobby.go 프로젝트: TF2Stadium/Helen
func (Lobby) LobbyChangeOwner(so *wsevent.Client, args struct {
	ID      *uint   `json:"id"`
	SteamID *string `json:"steamid"`
}) interface{} {
	lob, err := lobby.GetLobbyByID(*args.ID)
	if err != nil {
		return err
	}

	// current owner
	player1 := chelpers.GetPlayer(so.Token)
	if lob.CreatedBySteamID != player1.SteamID {
		return errors.New("You aren't authorized to change lobby owner.")
	}

	// to be owner
	player2, err := player.GetPlayerBySteamID(*args.SteamID)
	if err != nil {
		return err
	}

	lob.CreatedBySteamID = player2.SteamID
	lob.Save()
	lobby.BroadcastLobby(lob)
	lobby.BroadcastLobbyList()
	chat.NewBotMessage(fmt.Sprintf("Lobby leader changed to %s", player2.Alias()), int(*args.ID)).Send()

	return emptySuccess
}
예제 #6
0
func TwitchBadge(w http.ResponseWriter, r *http.Request) {
	if !reValidPath.MatchString(r.URL.Path) {
		http.NotFound(w, r)
		return
	}

	matches := reValidPath.FindStringSubmatch(r.URL.Path)
	steamid := matches[1]

	player, err := player.GetPlayerBySteamID(steamid)
	if err != nil { //player not found
		http.Error(w, "Player with given SteamID not found", http.StatusNotFound)
		return
	}

	id, err := player.GetLobbyID(false)
	if err != nil {
		//player not in lobby right now, just serve a page that refreshes every 5 seconds
		w.Write([]byte(emptyPage))
		return
	}

	lobby, _ := lobby.GetLobbyByID(id)
	err = twitchBadge.Execute(w, lobby)
}
예제 #7
0
파일: event.go 프로젝트: TF2Stadium/Helen
func playerChat(lobbyID uint, steamID string, message string) {
	lobby, _ := lobbypackage.GetLobbyByIDServer(lobbyID)
	player, _ := playerpackage.GetPlayerBySteamID(steamID)

	chatMessage := chat.NewInGameChatMessage(lobby.ID, player, message)
	chatMessage.Save()
	chatMessage.Send()
}
예제 #8
0
파일: unauth.go 프로젝트: TF2Stadium/Helen
func (Unauth) PlayerProfile(so *wsevent.Client, args struct {
	Steamid *string `json:"steamid"`
}) interface{} {

	player, err := player.GetPlayerBySteamID(*args.Steamid)
	if err != nil {
		return err
	}

	player.SetPlayerProfile()
	return newResponse(player)
}
예제 #9
0
파일: event.go 프로젝트: TF2Stadium/Helen
func playerDisc(steamID string, lobbyID uint) {
	player, _ := playerpackage.GetPlayerBySteamID(steamID)
	lobby, _ := lobbypackage.GetLobbyByID(lobbyID)

	lobby.SetNotInGame(player)

	chat.SendNotification(fmt.Sprintf("%s has disconected from the server.", player.Alias()), int(lobby.ID))

	lobby.AfterPlayerNotInGameFunc(player, 5*time.Minute, func() {
		lobby.Substitute(player)
		player.NewReport(playerpackage.Substitute, lobby.ID)
		chat.SendNotification(fmt.Sprintf("%s has been reported for not joining the game in 5 minutes", player.Alias()), int(lobby.ID))
	})
}
예제 #10
0
파일: lobby.go 프로젝트: TF2Stadium/Helen
func playerCanKick(lobbyId uint, steamId string) (bool, error) {
	lob, err := lobby.GetLobbyByID(lobbyId)
	if err != nil {
		return false, err
	}

	player, err := player.GetPlayerBySteamID(steamId)
	if err != nil {
		return false, err
	}
	if steamId != lob.CreatedBySteamID && player.Role != helpers.RoleAdmin {
		return false, errors.New("Not authorized to kick players")
	}
	return true, nil
}
예제 #11
0
파일: player.go 프로젝트: TF2Stadium/Helen
func (Player) PlayerProfile(so *wsevent.Client, args struct {
	Steamid *string `json:"steamid"`
}) interface{} {

	steamid := *args.Steamid
	if steamid == "" {
		steamid = so.Token.Claims.(*chelpers.TF2StadiumClaims).SteamID
	}

	player, err := player.GetPlayerBySteamID(steamid)
	if err != nil {
		return err
	}

	player.SetPlayerProfile()
	return newResponse(player)
}
예제 #12
0
파일: roles.go 프로젝트: TF2Stadium/Helen
func Remove(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	steamid := r.Form.Get("steamid")
	player, err := player.GetPlayerBySteamID(steamid)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	player.Role = authority.AuthRole(0)
	player.Save()
	fmt.Fprintf(w, "%s (%s) is no longer an admin/mod", player.Name, player.SteamID)
}
예제 #13
0
파일: event.go 프로젝트: TF2Stadium/Helen
func playerSub(steamID string, lobbyID uint, self bool) {
	player, _ := playerpackage.GetPlayerBySteamID(steamID)
	lobby, err := lobbypackage.GetLobbyByID(lobbyID)
	if err != nil {
		logrus.Error(err)
		return
	}

	lobby.Substitute(player)
	if self {
		player.NewReport(playerpackage.Substitute, lobby.ID)

	} else {
		// ban player from joining lobbies for 30 minutes
		player.NewReport(playerpackage.Vote, lobby.ID)
	}

	chat.SendNotification(fmt.Sprintf("%s has been reported.", player.Alias()), int(lobby.ID))
}
예제 #14
0
파일: roles.go 프로젝트: TF2Stadium/Helen
func ChangeRole(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	values := r.Form
	steamid := values.Get("steamid")
	remove := values.Get("remove")
	token := values.Get("xsrf-token")
	if !xsrftoken.Valid(token, config.Constants.CookieStoreSecret, "admin", "POST") {
		http.Error(w, "invalid xsrf token", http.StatusBadRequest)
		return
	}

	role, ok := map[string]authority.AuthRole{
		"admin": helpers.RoleAdmin,
		"mod":   helpers.RoleMod,
	}[values.Get("role")]
	if !ok {
		http.Error(w, "invalid role", http.StatusBadRequest)
		return
	}

	player, err := player.GetPlayerBySteamID(steamid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if remove == "true" {
		player.Role = 0
		player.Save()
		fmt.Fprintf(w, "Player %s (%s) has been removed as %s", player.Name, player.SteamID, helpers.RoleNames[role])
		return
	}

	player.Role = role
	player.Save()
	fmt.Fprintf(w, "Player %s (%s) has been made a %s", player.Name, player.SteamID, helpers.RoleNames[role])
	return
}
예제 #15
0
파일: event.go 프로젝트: TF2Stadium/Helen
func playersList(players []TF2RconWrapper.Player) {
	for _, player := range players {
		commid, _ := steamid.SteamIdToCommId(player.SteamID)
		player, err := playerpackage.GetPlayerBySteamID(commid)
		if err != nil {
			continue
		}

		id, _ := player.GetLobbyID(false)
		if id == 0 {
			continue
		}

		lobby, _ := lobbypackage.GetLobbyByID(id)
		if !lobby.IsPlayerInGame(player) {
			lobby.SetInGame(player)
		}
	}
}
예제 #16
0
파일: steam.go 프로젝트: TF2Stadium/Helen
func SteamMockLoginHandler(w http.ResponseWriter, r *http.Request) {
	if !config.Constants.MockupAuth {
		http.NotFound(w, r)
		return
	}

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

	p, err := player.GetPlayerBySteamID(steamid)
	if err != nil {
		p, err = player.NewPlayer(steamid)
		if err != nil {
			logrus.Error(err)
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
			return
		}

		database.DB.Create(p)
	}

	err = p.UpdatePlayerInfo()
	if err != nil {
		logrus.Error(err)
	}

	key := controllerhelpers.NewToken(p)
	cookie := &http.Cookie{
		Name:    "auth-jwt",
		Value:   key,
		Path:    "/",
		Domain:  config.Constants.CookieDomain,
		Expires: time.Now().Add(30 * 24 * time.Hour),
		//Secure: true,
	}

	http.SetCookie(w, cookie)

	http.Redirect(w, r, config.Constants.LoginRedirectPath, 303)
}
예제 #17
0
파일: ban.go 프로젝트: TF2Stadium/Helen
func GetBanLogs(w http.ResponseWriter, r *http.Request) {
	values := r.URL.Query()
	if !xsrftoken.Valid(values.Get("xsrf-token"), config.Constants.CookieStoreSecret, "admin", "POST") {
		http.Error(w, "invalid xsrf token", http.StatusBadRequest)
		return
	}

	var bans []*player.PlayerBan

	all := values.Get("all")

	steamid := values.Get("steamid")
	if steamid == "" {
		if all == "" {
			bans = player.GetAllActiveBans()
		} else {
			bans = player.GetAllBans()
		}

	} else {
		player, err := player.GetPlayerBySteamID(steamid)
		if err != nil {
			http.Error(w, err.Error(), http.StatusNotFound)
			return
		}

		if all == "" {
			bans, _ = player.GetActiveBans()
		} else {
			bans, _ = player.GetAllBans()
		}

	}

	err := banlogsTempl.Execute(w, bans)
	if err != nil {
		logrus.Error(err)
	}
}
예제 #18
0
//SocketInit initializes the websocket connection for the provided socket
func SocketInit(so *wsevent.Client) error {
	loggedIn := so.Token != nil

	if loggedIn {
		hooks.AfterConnect(socket.AuthServer, so)

		steamid := so.Token.Claims.(*chelpers.TF2StadiumClaims).SteamID

		player, err := player.GetPlayerBySteamID(steamid)
		if err != nil {
			return fmt.Errorf("Couldn't find player record for %s", steamid)
		}

		hooks.AfterConnectLoggedIn(so, player)
	} else {
		hooks.AfterConnect(socket.UnauthServer, so)
		so.EmitJSON(helpers.NewRequest("playerSettings", "{}"))
		so.EmitJSON(helpers.NewRequest("playerProfile", "{}"))
	}

	so.EmitJSON(helpers.NewRequest("socketInitialized", "{}"))

	return nil
}
예제 #19
0
파일: steam.go 프로젝트: TF2Stadium/Helen
func SteamLoginCallbackHandler(w http.ResponseWriter, r *http.Request) {
	refererURL := r.URL.Query().Get("referer")

	publicURL, _ := url.Parse(config.Constants.PublicAddress)
	// this wouldnt be used anymore, so modify it directly
	r.URL.Scheme = publicURL.Scheme
	r.URL.Host = publicURL.Host
	idURL, err := openid.Verify(r.URL.String(), discoveryCache, nonceStore)
	if err != nil {
		logrus.Error("Error verifying openid", err)
		http.Error(w, err.Error(), 500)
		return
	}

	parts := reSteamID.FindStringSubmatch(idURL)
	logrus.Info("Steam auth callback: ", idURL)
	if len(parts) != 2 {
		logrus.Errorf("Steam Authentication failed. Response: %s", idURL)
		http.Error(w, "Steam Authentication failed, please try again.", 500)
		return
	}

	steamid := parts[1]

	if config.Constants.SteamIDWhitelist != "" &&
		!controllerhelpers.IsSteamIDWhitelisted(steamid) {
		//Use a more user-friendly message later
		logrus.Errorf("User %s not in whitelist", steamid)
		http.Error(w, "Sorry, you're not in the closed alpha.", 403)
		return
	}

	p, err := player.GetPlayerBySteamID(steamid)
	if err != nil {
		p, err = player.NewPlayer(steamid)
		if err != nil {
			logrus.Error(err)
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
			return
		}

		database.DB.Create(p)
	}

	go func() {
		if time.Since(p.ProfileUpdatedAt) >= 1*time.Hour {
			err := p.UpdatePlayerInfo()
			if err != nil {
				logrus.Error(err)
			}
		}
	}()

	key := controllerhelpers.NewToken(p)
	cookie := &http.Cookie{
		Name:     "auth-jwt",
		Value:    key,
		Path:     "/",
		Domain:   config.Constants.CookieDomain,
		Expires:  time.Now().Add(30 * 24 * time.Hour),
		HttpOnly: true,
		Secure:   config.Constants.SecureCookies,
	}

	http.SetCookie(w, cookie)
	if refererURL != "" {
		http.Redirect(w, r, refererURL, 303)
		return
	}

	http.Redirect(w, r, config.Constants.LoginRedirectPath, 303)
}
예제 #20
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
}
예제 #21
0
파일: ban.go 프로젝트: TF2Stadium/Helen
func BanPlayer(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

	values := r.Form
	steamid := values.Get("steamid")
	reason := values.Get("reason")
	banType := values.Get("type")
	remove := values.Get("remove")
	token := values.Get("xsrf-token")
	if !xsrftoken.Valid(token, config.Constants.CookieStoreSecret, "admin", "POST") {
		http.Error(w, "invalid xsrf token", http.StatusBadRequest)
		return
	}

	ban, ok := map[string]player.BanType{
		"joinLobby":       player.BanJoin,
		"joinMumbleLobby": player.BanJoinMumble,
		"createLobby":     player.BanCreate,
		"chat":            player.BanChat,
		"full":            player.BanFull,
	}[banType]
	if !ok {
		http.Error(w, "Invalid ban type", http.StatusBadRequest)
		return
	}

	player, err := player.GetPlayerBySteamID(steamid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if remove == "true" {
		err := player.Unban(ban)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
		} else {
			fmt.Fprintf(w, "Player %s (%s) has been unbanned (%s)", player.Name, player.SteamID, ban.String())
		}
		return
	}

	until, err := time.Parse("2006-01-02 15:04", values.Get("date")+" "+values.Get("time"))
	if err != nil {
		http.Error(w, "invalid time format", http.StatusBadRequest)
		return
	} else if until.Sub(time.Now()) < 0 {
		http.Error(w, "invalid time", http.StatusBadRequest)
		return
	}

	jwt, _ := chelpers.GetToken(r)
	bannedByPlayer := chelpers.GetPlayer(jwt)

	err = player.BanUntil(until, ban, reason, bannedByPlayer.ID)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	fmt.Fprintf(w, "Player %s (%s) has been banned (%s) till %v", player.Name, player.SteamID, ban.String(), until)
}