package main import ( "bufio" "bytes" _ "embed" "fmt" "io" "net/http" "os" "path/filepath" "strings" "sync" ) //go:embed files.txt var fileData []byte func main() { baseURL := "https://cdn.rage.mp/updater/prerelease_server/server-files/" var wg sync.WaitGroup // WaitGroup for synchronization scanner := bufio.NewScanner(bytes.NewReader(fileData)) for scanner.Scan() { filePath := scanner.Text() filePath = strings.ReplaceAll(filePath, "\\", "/") // 1. Determine Download URL var downloadURL string = baseURL + filePath fmt.Println("download path", downloadURL) wg.Add(1) // Increment WaitGroup counter go func(filePath, downloadURL string) { // Use goroutine for concurrent download defer wg.Done() // Decrement WaitGroup counter when done // 2. Download and Save the File response, err := http.Get(downloadURL) if err != nil { fmt.Println("Error downloading file:", err, filePath) return } defer response.Body.Close() // --- CREATE SUBDIRECTORIES IF NECESSARY --- fullSavePath := filePath // Maintain the original file path with subdirectories if !strings.Contains(filePath, ".") { // If it's a directory, append a separator fullSavePath += "/" } dir := filepath.Dir(fullSavePath) // Get the directory part if _, err := os.Stat(dir); os.IsNotExist(err) { os.MkdirAll(dir, 0755) // Create all missing directories } outFile, err := os.OpenFile(fullSavePath, os.O_CREATE|os.O_RDWR, 0644) if err != nil { fmt.Println("Error creating file:", err, filePath) return } defer outFile.Close() _, err = io.Copy(outFile, response.Body) if err != nil { fmt.Println("Error copying file:", err, filePath) return } outFile.Sync() fmt.Println("Downloaded:", filePath) }(filePath, downloadURL) // Pass arguments to the goroutine } wg.Wait() // Wait for all downloads to complete if err := scanner.Err(); err != nil { fmt.Println("Error reading file:", err) } }