├── .gitignore ├── LICENSE ├── README.md ├── compiler.bat ├── go.mod ├── go.sum ├── media ├── We are no longer serving any files through our network. swd_io.png ├── demo.gif └── demo1.1.gif └── swd.go /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/go 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=go 4 | 5 | ### Go ### 6 | # If you prefer the allow list template instead of the deny list, see community template: 7 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 8 | # 9 | # Binaries for programs and plugins 10 | *.exe 11 | *.exe~ 12 | *.dll 13 | *.so 14 | *.dylib 15 | 16 | # Test binary, built with `go test -c` 17 | *.test 18 | 19 | # Output of the go coverage tool, specifically when used with LiteIDE 20 | *.out 21 | 22 | # Dependency directories (remove the comment below to include it) 23 | # vendor/ 24 | 25 | # Go workspace file 26 | go.work 27 | 28 | ### Go Patch ### 29 | /vendor/ 30 | /Godeps/ 31 | 32 | # End of https://www.toptal.com/developers/gitignore/api/go 33 | 34 | # Downloaded files by swd.go 35 | *.zip 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### ⚠️ 28/05/2022 - doesn't work anymore. **This repo is no longer maintained**, [API has been shutdown.](https://www.reddit.com/r/swd_io/comments/uy55qg/we_are_no_longer_serving_any_files_through_our/) 2 | 3 |
4 | We are no longer serving any files through our network 5 | 6 |
7 | 8 | 9 | # swd 10 | 11 | 12 | Easy to use, simply wrapper for [steamworkshopdownloader.io](https://steamworkshopdownloader.io/) API. 13 | 14 | ## Usage & info 15 | 16 | swd downloads the files compressed in a zip file with the steam workshop article id. 17 | 18 | ```shell 19 | id_steamworkshop.zip 20 | ``` 21 | 22 | run from source code (Golang installation required). 23 | 24 | ```shell 25 | git clone https://github.com/SegoCode/swd 26 | cd swd 27 | go get -d ./... 28 | go run swd.go https://steamcommunity.com/sharedfiles/filedetails/?id=1111111111 29 | ``` 30 | Or better [donwload a binary](https://github.com/SegoCode/swd/releases). 31 | 32 | ## Parameters 33 | 34 | It's simple, there is only one parameter, the url of the steam workshop article you want to download. 35 | ```shell 36 | swd https://steamcommunity.com/sharedfiles/filedetails/?id=1111111111 37 | ``` 38 | 39 | But... steamworkshopdownloader.io has an optional parameter for download, if you know any you can specify 40 | ```shell 41 | swd https://steamcommunity.com/sharedfiles/filedetails/?id=1111111111 --downloadFormat gmaextract 42 | ``` 43 | 44 | ## Downloads 45 | 46 | https://github.com/SegoCode/swd/releases/ 47 | -------------------------------------------------------------------------------- /compiler.bat: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | 3 | :: -------------------------------------------------------------------------------- 4 | :: 5 | :: Author: SegoCode 6 | :: 7 | :: Script function: 8 | :: Create release binary for golang script on different OS 9 | :: 10 | :: Note: 11 | :: You need golang.org/x/sys/unix dependence in your system if 12 | :: you want to compile for linux, run 'go get golang.org/x/sys/unix' 13 | :: 14 | :: For compiling without go.mod file set GO111MODULE to off, this 15 | :: isnt recommended, if you dont have go.mod run 'go mod init main' 16 | :: and 'go mod tidy' for create the go.mod file 17 | :: 18 | :: Be sure there is no binary from any previous build in the root directory 19 | :: 20 | :: -------------------------------------------------------------------------------- 21 | 22 | :: -------------------------------------------------------------------------------- 23 | :: Change the values ​​shown below they must match the name of the file to compile 24 | SET gofile=swd.go 25 | SET gofilename=swd 26 | :: -------------------------------------------------------------------------------- 27 | 28 | CD %~dp0 29 | 30 | ECHO Compiling for: linux-amd64. . . 31 | SET GOOS=linux 32 | SET GOARCH=amd64 33 | 34 | go build -o "%gofilename%-%GOOS%-%GOARCH%" %gofile% 35 | 36 | ECHO Compiling for: linux-386. . . 37 | SET GOOS=linux 38 | SET GOARCH=386 39 | 40 | go build -o "%gofilename%-%GOOS%-%GOARCH%" %gofile% 41 | 42 | ECHO Compiling for: linux-arm. . . 43 | SET GOOS=linux 44 | SET GOARCH=arm 45 | 46 | go build -o "%gofilename%-%GOOS%-%GOARCH%" %gofile% 47 | 48 | ECHO Compiling for: windows-386. . . 49 | SET GOOS=windows 50 | SET GOARCH=386 51 | 52 | go build -o "%gofilename%-%GOOS%-%GOARCH%.exe" %gofile% 53 | 54 | ECHO Compiling for: windows-amd64. . . 55 | SET GOOS=windows 56 | SET GOARCH=amd64 57 | 58 | go build -o "%gofilename%-%GOOS%-%GOARCH%.exe" %gofile% 59 | 60 | ECHO DONE! 61 | pause > nul 62 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module swd 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/briandowns/spinner v1.13.0 7 | github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 // indirect 8 | github.com/fatih/color v1.13.0 9 | github.com/google/go-github v17.0.0+incompatible // indirect 10 | github.com/google/go-querystring v1.1.0 // indirect 11 | github.com/hashicorp/go-version v1.3.0 // indirect 12 | github.com/parnurzeal/gorequest v0.2.16 13 | github.com/pkg/errors v0.9.1 // indirect 14 | github.com/smartystreets/goconvey v1.7.2 // indirect 15 | github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e 16 | github.com/tidwall/gjson v1.10.2 17 | golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect 18 | moul.io/http2curl v1.0.0 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/briandowns/spinner v1.13.0 h1:q/Y9LtpwtvL0CRzXrAMj0keVXqNhBYUFg6tBOUiY8ek= 2 | github.com/briandowns/spinner v1.13.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= 3 | github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 h1:lS3P5Nw3oPO05Lk2gFiYUOL3QPaH+fRoI1wFOc4G1UY= 4 | github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= 5 | github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= 6 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 7 | github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= 8 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 9 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 10 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 11 | github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= 12 | github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= 13 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 14 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 15 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 16 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 17 | github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= 18 | github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 19 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 20 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 21 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 22 | github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= 23 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 24 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 25 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 26 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 27 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 28 | github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ= 29 | github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= 30 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 31 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 32 | github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= 33 | github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= 34 | github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= 35 | github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= 36 | github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= 37 | github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= 38 | github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= 39 | github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= 40 | github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= 41 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= 42 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= 43 | github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= 44 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 45 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 46 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 47 | golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI= 48 | golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 49 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 50 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 51 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 52 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 53 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 54 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 55 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= 56 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 57 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 58 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 59 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 60 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 61 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 62 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 63 | moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= 64 | moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= 65 | -------------------------------------------------------------------------------- /media/We are no longer serving any files through our network. swd_io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegoCode/swd/986c5138dd3766ccc5683fc7c629eb80cc18f428/media/We are no longer serving any files through our network. swd_io.png -------------------------------------------------------------------------------- /media/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegoCode/swd/986c5138dd3766ccc5683fc7c629eb80cc18f428/media/demo.gif -------------------------------------------------------------------------------- /media/demo1.1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SegoCode/swd/986c5138dd3766ccc5683fc7c629eb80cc18f428/media/demo1.1.gif -------------------------------------------------------------------------------- /swd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "net/url" 8 | "os" 9 | "strconv" 10 | "strings" 11 | "time" 12 | 13 | "github.com/briandowns/spinner" 14 | "github.com/fatih/color" 15 | "github.com/parnurzeal/gorequest" 16 | "github.com/tcnksm/go-latest" 17 | "github.com/tidwall/gjson" 18 | ) 19 | 20 | const APP_VERSION = "1.7.0" 21 | 22 | const INFO = 1 23 | const WARNING = 2 24 | const ERR = 3 25 | 26 | // START_NODE and END_NODE get from (steamworkshopdownloader.io) thanks to @Cod3dDOT 27 | const START_NODE = 4 28 | const DEFAULT_NODE = 8 29 | const END_NODE = 8 30 | 31 | func logger(text string, errorlevel int) { 32 | 33 | if errorlevel == INFO { 34 | fmt.Println("[" + color.CyanString("INFO") + "] " + text) 35 | } 36 | 37 | if errorlevel == WARNING { 38 | fmt.Println("[" + color.YellowString("WARN") + "] " + text) 39 | } 40 | 41 | if errorlevel == ERR { 42 | fmt.Println("[" + color.RedString("ERR") + "] " + text) 43 | os.Exit(1) 44 | } 45 | } 46 | 47 | func GetEndpoint(node int) string { 48 | endpoint := "https://node0" + strconv.Itoa(node) + ".steamworkshopdownloader.io/prod//api/" 49 | return endpoint 50 | } 51 | 52 | func DownloadFile(url string, filepath string) error { 53 | 54 | loadSp := spinner.New(spinner.CharSets[14], 100*time.Millisecond) 55 | loadSp.Prefix = "[" + color.CyanString("INFO") + "] " + "RECEIVING DATA: " 56 | loadSp.FinalMSG = "\033[F" 57 | 58 | loadSp.Start() 59 | 60 | out, err := os.Create(filepath) // Create the file 61 | if err != nil { 62 | return err 63 | } 64 | defer out.Close() 65 | 66 | resp, err := http.Get(url) // Get the data 67 | if err != nil { 68 | return err 69 | } 70 | defer resp.Body.Close() 71 | 72 | _, err = io.Copy(out, resp.Body) // Write the body to file 73 | if err != nil { 74 | return err 75 | } 76 | 77 | loadSp.Stop() 78 | 79 | return nil 80 | } 81 | 82 | func getUUID(api string, publishedFileId string, downloadFormat string) string { 83 | request := gorequest.New() 84 | resp, body, errs := request.Post(api). 85 | Set("Content-Type", "application/json"). 86 | Send(`{"publishedFileId":` + publishedFileId + `, "collectionId":null, "hidden":false, "downloadFormat":"` + downloadFormat + `", "autodownload":true}`). 87 | End() 88 | 89 | if errs != nil { 90 | logger("CAN'T CONNECT TO THE SERVER", WARNING) 91 | return "0" 92 | } 93 | 94 | if resp.StatusCode != 200 { 95 | logger("GAME NOT AVAILABLE OR SERVER IS DOWN, CODE RESPONSE: "+strconv.Itoa(resp.StatusCode), WARNING) 96 | return "0" 97 | } else { 98 | logger("GAME IS AVAILABLE FOR STEAM WORKSHOP DOWNLOADS", INFO) 99 | return body 100 | } 101 | 102 | } 103 | 104 | func main() { 105 | 106 | // Args validation // 107 | if len(os.Args) <= 1 { 108 | logger("USAGE: swd https://steamcommunity.com/sharedfiles/filedetails/?id=1111111111", ERR) 109 | } 110 | 111 | url, err := url.ParseRequestURI(os.Args[1]) 112 | if err != nil { 113 | logger("URL NOT VALID (Example: swd https://steamcommunity.com/sharedfiles/filedetails/?id=1111111111)", ERR) 114 | } 115 | 116 | fileId := url.Query().Get("id") 117 | if fileId == "" { 118 | logger("URL NOT VALID (Example: swd \"https://steamcommunity.com/sharedfiles/filedetails/?id=1111111111\")", ERR) 119 | } 120 | 121 | var downloadFormat = "raw" 122 | if len(os.Args) >= 3 && (os.Args[2] == "--downloadFormat") { 123 | downloadFormat = os.Args[3] 124 | } 125 | 126 | // End Args validation // 127 | 128 | githubTag := &latest.GithubTag{ 129 | Owner: "SegoCode", 130 | Repository: "swd", 131 | } 132 | 133 | res, err := latest.Check(githubTag, APP_VERSION) 134 | if err == nil { 135 | if res.Outdated { 136 | logger("NEW VERSION IS AVAILABLE, CHECK https://github.com/SegoCode/swd/releases", WARNING) 137 | } 138 | } else { 139 | logger("CAN'T CHECK THE LATEST VERSION IN GITHUB, CHECK https://github.com/SegoCode/swd/releases", WARNING) 140 | } 141 | 142 | // Get initial request // 143 | var initResponse string 144 | var endpoint string 145 | 146 | logger("CHEKING IF THE GAME IS AVAILABLE FOR STEAM WORKSHOP DOWNLOADS . . .", INFO) 147 | for i := DEFAULT_NODE; i >= START_NODE; i-- { // Check node range 148 | endpoint = GetEndpoint(i) 149 | logger("REQUESTING DOWNLOAD FROM SERVER NUMBER "+strconv.Itoa(i), INFO) 150 | initResponse = getUUID(endpoint+"download/request", fileId, downloadFormat) 151 | if initResponse != "0" { 152 | break 153 | } 154 | } 155 | if initResponse == "0" { 156 | logger("CAN'T FOUND AVAILABLE SERVER", ERR) 157 | } 158 | 159 | // Download request // 160 | uid := gjson.Get(initResponse, "uuid").String() 161 | var readyFile = false 162 | var storageNode = "" 163 | var storagepath = "" 164 | request := gorequest.New() 165 | for i := 0; i < 10; i++ { // Try 10 times for 2 seconds of waiting, total 20 seconds of preparation maximum 166 | _, body, _ := request.Post(endpoint+"download/status"). 167 | Set("Content-Type", "application/json"). 168 | Send(`{"uuids": ["` + uid + `"]}`). 169 | End() 170 | 171 | logger("WAITING FOR THE SERVER. . . DOWNLOAD STATUS: "+strings.ToUpper(gjson.Get(body, uid+".status").String()), INFO) 172 | 173 | if strings.Contains(body, "prepared") { 174 | readyFile = true 175 | storageNode = gjson.Get(body, uid+".storageNode").String() 176 | storagepath = gjson.Get(body, uid+".storagePath").String() 177 | logger("INITIATING DOWNLOADING. . . ", INFO) 178 | break 179 | } 180 | time.Sleep(2 * time.Second) 181 | } 182 | 183 | // File ready, start download // 184 | if readyFile { 185 | dir, _ := os.Getwd() 186 | err := DownloadFile("https://"+storageNode+"/prod//storage/"+storagepath+"?uuid="+uid, dir+string(os.PathSeparator)+fileId+".zip") 187 | 188 | if err != nil { 189 | panic(err) 190 | } else { 191 | logger("✔️ DOWNLOAD FINISHED IN "+(dir+string(os.PathSeparator)+fileId+".zip"), INFO) 192 | } 193 | 194 | } else { 195 | logger("THE SERVER IS BUSY", ERR) 196 | } 197 | 198 | } 199 | --------------------------------------------------------------------------------