Skip to content

Instantly share code, notes, and snippets.

@pyt0xic
Last active August 3, 2025 13:15
Show Gist options
  • Save pyt0xic/95c6a511755e6652f05eea868f600d31 to your computer and use it in GitHub Desktop.
Save pyt0xic/95c6a511755e6652f05eea868f600d31 to your computer and use it in GitHub Desktop.
Start Refrag Retakes Server
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"time"
"github.com/joho/godotenv"
)
const (
refragAPIEndpoint = "https://api.refrag.gg/auth/sign_in"
refragStartServerEndpoint = "https://api.refrag.gg/cs_servers/start_new_server"
refragRunningServersEndpoint = "https://api.refrag.gg/cs_servers/running"
refragOrigin = "https://play.refrag.gg"
outputFilename = "refrag_login_data.json"
)
// LoginRequest represents the login request payload
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
Remember bool `json:"remember"`
}
// LoginResponse represents the API response data
type LoginResponse struct {
Data struct {
Email string `json:"email"`
Provider string `json:"provider"`
UID string `json:"uid"`
MatchAuthToken string `json:"match_auth_token"`
ID int `json:"id"`
AllowPasswordChange bool `json:"allow_password_change"`
Name any `json:"name"`
Nickname any `json:"nickname"`
Image any `json:"image"`
TeamID any `json:"team_id"`
SteamID string `json:"steam_id"`
IsBetaTester any `json:"is_beta_tester"`
HasScrimAccess bool `json:"has_scrim_access"`
AdminAccess bool `json:"admin_access"`
CustomProAccess bool `json:"custom_pro_access"`
WarmupKillCount int `json:"warmup_kill_count"`
EmailSignUp bool `json:"email_sign_up"`
ServerSettings []ServerSettings `json:"server_settings"`
CustomCompetitor any `json:"custom_competitor"`
CustomPlayer any `json:"custom_player"`
CustomTeam any `json:"custom_team"`
FaceitNickname string `json:"faceit_nickname"`
UUID string `json:"uuid"`
Username any `json:"username"`
DiscordID any `json:"discord_id"`
DiscordTag any `json:"discord_tag"`
ReceiveEmailForNotifications bool `json:"receive_email_for_notifications"`
ReceiveEmailForAccessCodes bool `json:"receive_email_for_access_codes"`
OnboardedStepsCompleted int `json:"onboarded_steps_completed"`
SashID int `json:"sash_id"`
Level int `json:"level"`
FaceitPlayerID any `json:"faceit_player_id"`
CommunityMod bool `json:"community_mod"`
SteamProfileJSON SteamProfile `json:"steam_profile_json"`
// Other fields omitted for brevity
} `json:"data"`
}
type ServerSettings struct {
Modules []Module `json:"modules"`
ModName string `json:"mod_name"`
}
type Module struct {
Module string `json:"module"`
Settings string `json:"settings"`
}
type SteamProfile struct {
Avatar string `json:"avatar"`
GameID string `json:"gameid"`
SteamID string `json:"steamid"`
Realname string `json:"realname"`
Avatarfull string `json:"avatarfull"`
Avatarhash string `json:"avatarhash"`
Profileurl string `json:"profileurl"`
Personaname string `json:"personaname"`
Timecreated int `json:"timecreated"`
Avatarmedium string `json:"avatarmedium"`
Lobbysteamid string `json:"lobbysteamid"`
Personastate int `json:"personastate"`
Profilestate int `json:"profilestate"`
Gameextrainfo string `json:"gameextrainfo"`
Primaryclanid string `json:"primaryclanid"`
Loccountrycode string `json:"loccountrycode"`
Commentpermission int `json:"commentpermission"`
Personastateflags int `json:"personastateflags"`
Communityvisibilitystate int `json:"communityvisibilitystate"`
}
// AuthHeaders holds the authentication headers received from the API
type AuthHeaders struct {
AccessToken string `json:"access_token"`
Authorization string `json:"authorization"`
Client string `json:"client"`
Expiry string `json:"expiry"`
UID string `json:"uid"`
}
// SavedData represents the complete data structure to save to file
type SavedData struct {
Response LoginResponse `json:"response"`
Headers AuthHeaders `json:"headers"`
}
// StartServerRequest represents the payload for starting a new server
type StartServerRequest struct {
ServerLocationID int `json:"server_location_id"`
Game string `json:"game"`
BetaServer bool `json:"betaServer"`
SecureServer bool `json:"secureServer"`
IsAssessment bool `json:"is_assessment"`
LaunchSettings LaunchSettings `json:"launch_settings"`
}
type LaunchSettings struct {
Mod string `json:"mod"`
Map string `json:"map"`
}
// ServerResponse represents a server in the API responses
type ServerResponse struct {
ID int `json:"id"`
IP string `json:"ip"`
Port int `json:"port"`
Status string `json:"status"`
Password string `json:"password"`
VACSecure bool `json:"vac_secure"`
ActiveMap string `json:"active_map"`
ActiveMod string `json:"active_mod"`
ConnectedPlayers any `json:"connected_players"`
IsAssessment bool `json:"is_assessment"`
Game string `json:"game"`
RawIP string `json:"raw_ip"`
IsScrim bool `json:"is_scrim"`
ServerLocation string `json:"server_location"`
StartedBy User `json:"started_by"`
Team Team `json:"team"`
}
type User struct {
ID int `json:"id"`
SteamProfile SteamProfile `json:"steam_profile"`
}
type Team struct {
Name string `json:"name"`
ID int `json:"id"`
}
func main() {
fmt.Println("Logging in to refrag.gg...")
// Load credentials from env vars or .env file
email, password, err := loadCredentials()
if err != nil {
log.Fatal(err)
}
// Log in to the API
response, headers, err := loginToRefrag(email, password)
if err != nil {
log.Fatal("Login failed: ", err)
}
// Save the data to file
if err := saveLoginResponseData(response, headers); err != nil {
log.Fatal("Failed to save response data: ", err)
}
// Print success message with auth headers
printLoginSuccess(headers)
// Load server parameters from environment variables
mapName, mod, locationID, err := loadServerParameters()
if err != nil {
log.Fatal(err)
}
// Start a new server
server, err := StartServer(headers, locationID, "cs2", mod, mapName)
if err != nil {
log.Fatal("Failed to start server: ", err)
}
fmt.Printf("Server started! Connect: %s:%d (Password: %s)\n", server.IP, server.Port, server.Password)
// Loop until password is available
maxAttempts := 30 // Avoid infinite loops
time.Sleep(3 * time.Second)
for i := 0; i < maxAttempts; i++ {
// Sleep for 3 seconds at the start of each iteration
fmt.Printf("Waiting for 3 seconds (attempt %d/%d)...\n", i+1, maxAttempts)
time.Sleep(3 * time.Second)
// Get running servers
servers, err := GetRunningServers(headers)
if err != nil {
log.Printf("Failed to get running servers: %v. Retrying...", err)
continue
}
fmt.Printf("Running Servers (%d):\n", len(servers))
// Look for our server
var foundServer bool
for _, srv := range servers {
fmt.Printf(" %s:%d - %s on %s (Status: %s, Password: %s)\n",
srv.IP, srv.Port, srv.ActiveMod, srv.ActiveMap, srv.Status, srv.Password)
// If this is our server and password is available
if srv.ID == server.ID && srv.Password != "" && srv.Status == "online" {
fmt.Printf("\nServer is ready! Connect: %s:%d (Password: %s)\n", srv.IP, srv.Port, srv.Password)
fmt.Printf("\nconnect %s:%d; password %s\n", srv.IP, srv.Port, srv.Password)
return
}
}
if !foundServer {
fmt.Println("Our server is not in the list. It might be still starting up...")
} else {
fmt.Println("Server found but password not yet available.")
}
}
fmt.Println("Maximum attempts reached. Please check server status manually.")
}
// loadCredentials loads REFRAG_EMAIL and REFRAG_PASSWORD from environment or .env file
func loadCredentials() (email, password string, err error) {
// Load .env file if it exists
if err := godotenv.Load(); err != nil {
fmt.Println("No .env file found, using environment variables directly")
}
// Get credentials from environment variables
email = os.Getenv("REFRAG_EMAIL")
password = os.Getenv("REFRAG_PASSWORD")
if email == "" || password == "" {
return "", "", fmt.Errorf("REFRAG_EMAIL and REFRAG_PASSWORD environment variables must be set")
}
return email, password, nil
}
// loadServerParameters loads REFRAG_MAP, REFRAG_MOD, and REFRAG_LOCATION_ID from environment variables
func loadServerParameters() (mapName, mod string, locationID int, err error) {
mapName = os.Getenv("REFRAG_MAP")
mod = os.Getenv("REFRAG_MOD")
locationIDStr := os.Getenv("REFRAG_LOCATION_ID")
if mapName == "" {
mapName = "de_ancient" // Default map
}
if mod == "" {
mod = "retakes" // Default mod
}
if locationIDStr == "" {
locationID = 16 // Default location ID (change as needed)
} else {
locationID, err = strconv.Atoi(locationIDStr)
if err != nil {
return "", "", 0, fmt.Errorf("invalid REFRAG_LOCATION_ID: %w", err)
}
}
return mapName, mod, locationID, nil
}
// loginToRefrag attempts to login to the Refrag API and returns the response and auth headers
func loginToRefrag(email, password string) (*LoginResponse, *AuthHeaders, error) {
// Create login request payload
loginData := LoginRequest{
Email: email,
Password: password,
Remember: false,
}
// Convert to JSON
jsonData, err := json.Marshal(loginData)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal JSON: %w", err)
}
// Create and configure the HTTP request
req, err := http.NewRequest(http.MethodPost, refragAPIEndpoint, bytes.NewBuffer(jsonData))
if err != nil {
return nil, nil, fmt.Errorf("failed to create request: %w", err)
}
// Set headers
setLoginRequestHeaders(req)
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, nil, fmt.Errorf("failed to read response: %w", err)
}
// Parse the JSON response
var loginResponse LoginResponse
err = json.Unmarshal(body, &loginResponse)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse JSON response: %w", err)
}
// Extract authentication headers
headers := &AuthHeaders{
AccessToken: resp.Header.Get("access-token"),
Authorization: resp.Header.Get("authorization"),
Client: resp.Header.Get("client"),
Expiry: resp.Header.Get("expiry"),
UID: resp.Header.Get("uid"),
}
return &loginResponse, headers, nil
}
// setLoginRequestHeaders adds all required headers to the HTTP request
func setLoginRequestHeaders(req *http.Request) {
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0")
req.Header.Set("Accept", "application/json, text/plain, */*")
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Origin", refragOrigin)
req.Header.Set("DNT", "1")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Referer", refragOrigin+"/")
req.Header.Set("Sec-Fetch-Dest", "empty")
req.Header.Set("Sec-Fetch-Mode", "cors")
req.Header.Set("Sec-Fetch-Site", "same-site")
req.Header.Set("Priority", "u=0")
req.Header.Set("TE", "trailers")
}
// saveLoginResponseData saves the login response and headers to a JSON file
func saveLoginResponseData(response *LoginResponse, headers *AuthHeaders) error {
savedData := SavedData{
Response: *response,
Headers: *headers,
}
// Convert to JSON for storage
outputJSON, err := json.MarshalIndent(savedData, "", " ")
if err != nil {
return fmt.Errorf("failed to create output JSON: %w", err)
}
// Save to file
err = os.WriteFile(outputFilename, outputJSON, 0644)
if err != nil {
return fmt.Errorf("failed to write to file: %w", err)
}
return nil
}
// printLoginSuccess prints the successful login information
func printLoginSuccess(headers *AuthHeaders) {
fmt.Println("Login successful!")
fmt.Println("Access Token:", headers.AccessToken)
fmt.Println("Authorization:", headers.Authorization)
fmt.Println("Client:", headers.Client)
fmt.Println("Expiry:", headers.Expiry)
fmt.Println("UID:", headers.UID)
fmt.Println("Response data saved to", outputFilename)
}
// StartServer starts a new server with the given parameters
func StartServer(auth *AuthHeaders, locationID int, game string, mod string, mapName string) (*ServerResponse, error) {
fmt.Println("Starting a new server...")
// Create server request payload
requestData := StartServerRequest{
ServerLocationID: locationID,
Game: game,
BetaServer: false,
SecureServer: false,
IsAssessment: false,
LaunchSettings: LaunchSettings{
Mod: mod,
Map: mapName,
},
}
// Convert to JSON
jsonData, err := json.Marshal(requestData)
if err != nil {
return nil, fmt.Errorf("failed to marshal JSON: %w", err)
}
// Create and configure the HTTP request
req, err := http.NewRequest(http.MethodPost, refragStartServerEndpoint, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
// Set headers
setRefragRequestHeaders(req, auth)
req.Header.Set("X-GAME", game)
req.Header.Set("X-TEAM-ID", "272803") // This could be made dynamic if needed
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
// Parse the JSON response
var serverResponse ServerResponse
err = json.Unmarshal(body, &serverResponse)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %w", err)
}
return &serverResponse, nil
}
// GetRunningServers retrieves all currently running servers
func GetRunningServers(auth *AuthHeaders) ([]ServerResponse, error) {
fmt.Println("Getting running servers...")
// Create and configure the HTTP request
req, err := http.NewRequest(http.MethodGet, refragRunningServersEndpoint, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
// Set headers
setRefragRequestHeaders(req, auth)
req.Header.Set("X-GAME", "cs2")
req.Header.Set("X-TEAM-ID", "272803") // This could be made dynamic if needed
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
// Parse the JSON response
var servers []ServerResponse
err = json.Unmarshal(body, &servers)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %w", err)
}
return servers, nil
}
// setRefragRequestHeaders sets the necessary authentication headers for Refrag API requests
func setRefragRequestHeaders(req *http.Request, auth *AuthHeaders) {
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0")
req.Header.Set("Accept", "application/json, text/plain, */*")
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Origin", refragOrigin)
req.Header.Set("DNT", "1")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Referer", refragOrigin+"/")
req.Header.Set("Sec-Fetch-Dest", "empty")
req.Header.Set("Sec-Fetch-Mode", "cors")
req.Header.Set("Sec-Fetch-Site", "same-site")
req.Header.Set("Priority", "u=0")
req.Header.Set("TE", "trailers")
// Authentication headers
req.Header.Set("Token-Type", "Bearer")
req.Header.Set("Access-Token", auth.AccessToken)
req.Header.Set("Client", auth.Client)
req.Header.Set("Uid", auth.UID)
req.Header.Set("Expiry", auth.Expiry)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment