From 93c4825ff7286b6417644f97ec8d5af00ea797f3 Mon Sep 17 00:00:00 2001 From: Raum0x2A Date: Thu, 21 May 2026 10:10:18 -0600 Subject: [PATCH] Added internet check and warning when offline --- launchserver.go | 3 ++ mods.go | 136 +++++++++++++++++++++++++----------------------- serv-install.go | 60 +++++++++++---------- utils.go | 12 +++++ 4 files changed, 117 insertions(+), 94 deletions(-) diff --git a/launchserver.go b/launchserver.go index 9acc2ef..b266f95 100644 --- a/launchserver.go +++ b/launchserver.go @@ -8,6 +8,9 @@ import ( ) func startStopServer(cmd string, con UsrConfig) { + if hasInternet() != true { + fmt.Printf("WARNING!\n\tNot connected to internet, LAN access only\n") + } switch cmd { case "start": x := fmt.Sprintf("%s --port %d --server-settings %s --start-server %s", con.Server.ServExec, con.Server.ServPort, con.Server.ServCfg, con.Server.WorldFile) diff --git a/mods.go b/mods.go index 641dd25..c9aeac5 100644 --- a/mods.go +++ b/mods.go @@ -9,76 +9,80 @@ import ( ) func downloadMods(c UsrConfig) { - //var c = readCfg("config.yml") - modlist := string(c.Server.ServDir) + "/mods/mod-list.json" + if hasInternet() == true { - fmt.Printf("Updating mods from %s\n", modlist) + //var c = readCfg("config.yml") + modlist := string(c.Server.ServDir) + "/mods/mod-list.json" - //read from modlist - file, err := os.Open(modlist) - if err != nil { - log.Fatalf("Error reading modlist: %v", err) - } - defer file.Close() + fmt.Printf("Updating mods from %s\n", modlist) - // create temp directory - tempDir, err := os.MkdirTemp("", "factoryman-*") - if err != nil { - log.Fatalln("Failed to create temporary directory") - } - defer os.RemoveAll(tempDir) - - //decode json response from api - var modList ModList - decoder := json.NewDecoder(file) - if err := decoder.Decode(&modList); err != nil { - log.Fatalf("Error reading JSON: %v", err) - } - // Iterate over modlist.json - for _, mod := range modList.Mods { - switch mod.Name { - case "base": - fmt.Println("Skipping base...") - case "elevated-rails": - fmt.Println("Skipping elevated-rails...") - case "quality": - fmt.Println("Skipping quality...") - case "space-age": - fmt.Println("Skipping space-age...") - default: - // query mod on modportal api - modportalurl := fmt.Sprintf("https://mods.factorio.com/api/mods/%s", mod.Name) - resp, err := http.Get(modportalurl) - if err != nil { - log.Fatalf("Error reading JSON: %v", err) - } - defer resp.Body.Close() - - // decode json response - var moddata ModPortal - if err := json.NewDecoder(resp.Body).Decode(&moddata); err != nil { - log.Fatalf("Error reading JSON: %v", err) - } - - // query download url for mod - accessToken := fmt.Sprintf("?username=%s&token=%s", c.Factoryman.UserName, c.Factoryman.ApiToken) - modDownloadUrl := fmt.Sprintf("https://mods.factorio.com%s%s", moddata.Releases[len(moddata.Releases)-1].DownloadUrl, accessToken) - fileName := string(tempDir + "/" + moddata.Releases[len(moddata.Releases)-1].Filename) - //download mod archive - downloadErr := download(fileName, modDownloadUrl) - if downloadErr != nil { - log.Fatalf("Error downloading: %v", downloadErr) - } - fmt.Printf("Downloaded: %s\n", fileName) - fmt.Printf("extracting files to %s\n", c.Server.ServDir+"/mods/") - // extract archive to mods folder - //exec.Command("unzip", fileName, "-d", c.Server.ServDir+"/mods/") - _, extracterr := unzip(fileName, c.Server.ServDir+"/mods/") - if extracterr != nil { - log.Fatalf("Error extracting archive: %v", extracterr) - } + //read from modlist + file, err := os.Open(modlist) + if err != nil { + log.Fatalf("Error reading modlist: %v", err) } + defer file.Close() + // create temp directory + tempDir, err := os.MkdirTemp("", "factoryman-*") + if err != nil { + log.Fatalln("Failed to create temporary directory") + } + defer os.RemoveAll(tempDir) + + //decode json response from api + var modList ModList + decoder := json.NewDecoder(file) + if err := decoder.Decode(&modList); err != nil { + log.Fatalf("Error reading JSON: %v", err) + } + // Iterate over modlist.json + for _, mod := range modList.Mods { + switch mod.Name { + case "base": + fmt.Println("Skipping base...") + case "elevated-rails": + fmt.Println("Skipping elevated-rails...") + case "quality": + fmt.Println("Skipping quality...") + case "space-age": + fmt.Println("Skipping space-age...") + default: + // query mod on modportal api + modportalurl := fmt.Sprintf("https://mods.factorio.com/api/mods/%s", mod.Name) + resp, err := http.Get(modportalurl) + if err != nil { + log.Fatalf("Error reading JSON: %v", err) + } + defer resp.Body.Close() + + // decode json response + var moddata ModPortal + if err := json.NewDecoder(resp.Body).Decode(&moddata); err != nil { + log.Fatalf("Error reading JSON: %v", err) + } + + // query download url for mod + accessToken := fmt.Sprintf("?username=%s&token=%s", c.Factoryman.UserName, c.Factoryman.ApiToken) + modDownloadUrl := fmt.Sprintf("https://mods.factorio.com%s%s", moddata.Releases[len(moddata.Releases)-1].DownloadUrl, accessToken) + fileName := string(tempDir + "/" + moddata.Releases[len(moddata.Releases)-1].Filename) + //download mod archive + downloadErr := download(fileName, modDownloadUrl) + if downloadErr != nil { + log.Fatalf("Error downloading: %v", downloadErr) + } + fmt.Printf("Downloaded: %s\n", fileName) + fmt.Printf("extracting files to %s\n", c.Server.ServDir+"/mods/") + // extract archive to mods folder + //exec.Command("unzip", fileName, "-d", c.Server.ServDir+"/mods/") + _, extracterr := unzip(fileName, c.Server.ServDir+"/mods/") + if extracterr != nil { + log.Fatalf("Error extracting archive: %v", extracterr) + } + } + + } + } else { + fmt.Println("Unable to access internet, please check connection.") } - } diff --git a/serv-install.go b/serv-install.go index ef1f745..9a4fdb4 100644 --- a/serv-install.go +++ b/serv-install.go @@ -2,6 +2,7 @@ package main import ( "archive/tar" + "fmt" "io" "log" "net/http" @@ -13,37 +14,40 @@ import ( ) func downloadHeadless(c UsrConfig) { - //var c = readCfg("config.yml") - headlessQuery := "https://www.factorio.com/get-download/latest/headless/linux64" + if hasInternet() == true { + headlessQuery := "https://www.factorio.com/get-download/latest/headless/linux64" - url := headlessQuery - resp, err := http.Get(url) - if err != nil || resp.StatusCode != http.StatusOK { - log.Fatal("Download failed") - } - defer resp.Body.Close() - - // Wrap stream in XZ and Tar readers - xzReader, _ := xz.NewReader(resp.Body, 0) - tr := tar.NewReader(xzReader) - - for { - header, err := tr.Next() - if err == io.EOF { - break + url := headlessQuery + resp, err := http.Get(url) + if err != nil || resp.StatusCode != http.StatusOK { + log.Fatal("Download failed") } + defer resp.Body.Close() - target := filepath.Join(".", header.Name) - switch header.Typeflag { - case tar.TypeDir: - os.MkdirAll(target, 0755) - case tar.TypeReg: - os.MkdirAll(filepath.Dir(target), 0755) - outFile, _ := os.Create(target) - io.Copy(outFile, tr) - outFile.Close() + // Wrap stream in XZ and Tar readers + xzReader, _ := xz.NewReader(resp.Body, 0) + tr := tar.NewReader(xzReader) + + for { + header, err := tr.Next() + if err == io.EOF { + break + } + + target := filepath.Join(".", header.Name) + switch header.Typeflag { + case tar.TypeDir: + os.MkdirAll(target, 0755) + case tar.TypeReg: + os.MkdirAll(filepath.Dir(target), 0755) + outFile, _ := os.Create(target) + io.Copy(outFile, tr) + outFile.Close() + } } + // zip does not preserve permissions correctly so i have to do this + exec.Command("chmod", "+x", c.Server.ServExec) + } else { + fmt.Println("Unable to access internet, please check connection.") } - // zip does not preserve permissions correctly so i have to do this - exec.Command("chmod", "+x", c.Server.ServExec) } diff --git a/utils.go b/utils.go index 3207273..a247a18 100644 --- a/utils.go +++ b/utils.go @@ -4,10 +4,12 @@ import ( "archive/zip" "fmt" "io" + "net" "net/http" "os" "path/filepath" "strings" + "time" ) //Utilities @@ -91,3 +93,13 @@ func unzip(src, dest string) ([]string, error) { return filenames, nil } + +func hasInternet() bool { + timeout := 2 * time.Second + conn, err := net.DialTimeout("tcp", "8.8.8.8:53", timeout) + if err != nil { + return false + } + conn.Close() + return true +}