From f2931a76033915b625674d7bdf5d9f4853857d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorben=20G=C3=BCnther?= Date: Tue, 15 Aug 2023 14:19:46 +0200 Subject: [PATCH] Forward account list with context between handlers --- faceit.go | 81 ++++++++++++++++--------------------------------------- steam.go | 32 ++++++++++++++++------ 2 files changed, 47 insertions(+), 66 deletions(-) diff --git a/faceit.go b/faceit.go index 0f711fb..2c82322 100644 --- a/faceit.go +++ b/faceit.go @@ -107,6 +107,8 @@ type faceitChecker struct { templates *template.Template } +type accountsContextKey struct{} + func main() { var configPath string flag.StringVar(&configPath, "config", "/etc/faceit_checker/config.scfg", "config file path") @@ -148,7 +150,6 @@ func main() { r := http.NewServeMux() r.HandleFunc("/", fc.faceitHandler) - r.HandleFunc("/search", fc.requestHandler) r.HandleFunc("/api/elo/", fc.getElo) fs := http.FileServer(http.FS(css)) r.Handle("/css/", fs) @@ -395,10 +396,11 @@ func (fc *faceitChecker) faceitHandler(w http.ResponseWriter, r *http.Request) { logger.Debug("Received input", slog.Any("input", input)) status := r.FormValue("status") - var steamAccountList []string + var steamAccountList []steamAccount if status == "status" { - steamMap, err := parseStatus(input) + var err error + steamAccountList, err = fc.parseStatus(input) if err != nil { logger.Debug("Failed to parse status") if err := fc.templates.ExecuteTemplate(w, "error.html", err); err != nil { @@ -408,17 +410,6 @@ func (fc *faceitChecker) faceitHandler(w http.ResponseWriter, r *http.Request) { } return } - - for steamID, nickname := range steamMap { - id64, err := parseSteamID(steamID) - if err != nil { - logger.Error("Failed to parse SteamID", - slog.String("ID", steamID), - slog.String("error", err.Error())) - continue - } - steamAccountList = append(steamAccountList, fmt.Sprintf("%s_%s", id64, nickname)) - } } else { steamLinks := strings.Fields(input) for _, steamLink := range steamLinks { @@ -431,48 +422,30 @@ func (fc *faceitChecker) faceitHandler(w http.ResponseWriter, r *http.Request) { } return } - steamAccountList = append(steamAccountList, fmt.Sprintf("%s_%s", steamProfile.ID64, sanitizeName(steamProfile.Name))) + + steamAccountList = append(steamAccountList, steamAccount{ + id: steamProfile.ID64, + name: steamProfile.Name, + }) } } - redirect(w, r, strings.Join(steamAccountList, "+")) + r = r.WithContext(context.WithValue(r.Context(), accountsContextKey{}, steamAccountList)) + fc.requestHandler(w, r) } func (fc *faceitChecker) requestHandler(w http.ResponseWriter, r *http.Request) { logger := fc.logger.With(slog.String("handler", "/search")) - - if err := r.ParseForm(); err != nil { - logger.Error("Failed to parse form", - slog.String("error", err.Error())) - if err := fc.templates.ExecuteTemplate(w, "error.html", "Internal error with parsing form"); err != nil { - logger.Error("Failed to execute template", - slog.String("error", err.Error())) - http.Error(w, internalError, http.StatusInternalServerError) - } - return - } - accounts := r.FormValue("accounts") - if accounts == "" { - if err := fc.templates.ExecuteTemplate(w, "error.html", "Wrong input"); err != nil { - logger.Error("Failed to execute template", - slog.String("error", err.Error())) - http.Error(w, internalError, http.StatusInternalServerError) - } - return - } - - if strings.Contains(accounts, "error") { - if err := fc.templates.ExecuteTemplate(w, "error.html", "Internal error"); err != nil { - logger.Error("Failed to execute template", - slog.String("error", err.Error())) - http.Error(w, internalError, http.StatusInternalServerError) - } + accountsFromContext := r.Context().Value(accountsContextKey{}) + if accountsFromContext == nil { + logger.Error("Could not retrieve account list from context") + http.Error(w, internalError, http.StatusInternalServerError) return } - var playerList []*FaceitPlayer - accountList := strings.Split(accounts, " ") + accountList := accountsFromContext.([]steamAccount) length := len(accountList) + var playerList []*FaceitPlayer for _, account := range accountList { select { @@ -484,25 +457,17 @@ func (fc *faceitChecker) requestHandler(w http.ResponseWriter, r *http.Request) player := &FaceitPlayer{} playerList = append(playerList, player) - // parsed[0] is ID64 , parsed[1] is nickname - parsed := strings.Split(account, "_") - if len(parsed) != 2 { - logger.Error("Failed to parse account", - slog.String("account", account)) - continue - } - // Information is only needed if multiple accounts are displayed if length > 1 { - player.SteamLink = "https://steamcommunity.com/profiles/" + parsed[0] - player.SteamName = parsed[1] + player.SteamLink = "https://steamcommunity.com/profiles/" + account.id + player.SteamName = account.name } - playerLogger := logger.With(slog.String("ID", parsed[0]), - slog.String("name", parsed[1])) + playerLogger := logger.With(slog.String("ID", account.id), + slog.String("name", account.name)) playerLogger.Debug("Checking player") - data, err := fc.getFaceitPlayer(r.Context(), parsed[0]) + data, err := fc.getFaceitPlayer(r.Context(), account.id) if err != nil { playerLogger.Error("Failed to get Faceit player", slog.String("error", err.Error())) diff --git a/steam.go b/steam.go index 51ee6be..88d5168 100644 --- a/steam.go +++ b/steam.go @@ -3,6 +3,7 @@ package main import ( "errors" "fmt" + "log/slog" "regexp" "strconv" "strings" @@ -10,6 +11,11 @@ import ( const baseID64 int64 = 76561197960265728 +type steamAccount struct { + name string + id string +} + // https://developer.valvesoftware.com/wiki/SteamID func parseSteamID(steamID string) (string, error) { trimmed := strings.TrimPrefix(steamID, "STEAM_") @@ -33,7 +39,7 @@ func parseSteamID(steamID string) (string, error) { return strconv.FormatInt(id64, 10), nil } -func parseStatus(status string) (map[string]string, error) { +func (fc *faceitChecker) parseStatus(status string) ([]steamAccount, error) { lineRegex, err := regexp.Compile(`^#.*"(.*)" (STEAM_[0-9:]*).*$`) if err != nil { return nil, err @@ -49,18 +55,28 @@ func parseStatus(status string) (map[string]string, error) { // Remove first and last line playerSlice = playerSlice[1 : len(playerSlice)-1] - players := make(map[string]string) + // This list could potentially contain less accounts than the playerSlice. + // It happens for example for bots, which do not have a valid Steam ID. + var steamAccountList []steamAccount for _, player := range playerSlice { match := lineRegex.FindStringSubmatch(player) if len(match) != 3 { continue } - players[match[2]] = sanitizeName(match[1]) - } - return players, nil -} + id, err := parseSteamID(match[2]) + if err != nil { + fc.logger.Error("Failed to parse SteamID", + slog.String("ID", match[2]), + slog.String("error", err.Error())) + continue + } + + steamAccountList = append(steamAccountList, steamAccount{ + name: match[1], + id: id, + }) + } -func sanitizeName(name string) string { - return strings.ReplaceAll(name, " ", "") + return steamAccountList, nil } -- 2.44.0