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) }
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)) }
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)) }
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)) } }
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 }
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) }
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() }
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) }
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)) }) }
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 }
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) }
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) }
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)) }
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 }
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) } } }
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) }
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) } }
//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 }
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) }
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 }
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) }