BedrockFetch/main.go
Matheus Sampaio Queiroga 27021fde73
All checks were successful
Find and Upload Minecraft Server versions / build (push) Successful in 14s
Fix upload
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2024-08-22 15:25:47 -03:00

186 lines
4.7 KiB
Go

package main
import (
"archive/tar"
"archive/zip"
"compress/gzip"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"sirherobrine23.org/go-bds/bedrockfetch/tea"
"sirherobrine23.org/go-bds/go-bds/bedrock/mojang"
"sirherobrine23.org/go-bds/go-bds/request"
)
func main() {
localVersionsFile, err := os.OpenFile("./versions.json", os.O_RDWR, 0)
if err != nil {
panic(err)
}
defer localVersionsFile.Close()
var versions mojang.Versions = make(mojang.Versions)
if err = json.NewDecoder(localVersionsFile).Decode(&versions); err != nil {
panic(err)
}
fmt.Println("Fetching minecraft bedrock versions in minecraft.net")
remoteUrls, err := mojang.FetchFromWebsite()
if err != nil {
panic(err)
}
for _, releaseFile := range remoteUrls.Versions {
var version mojang.Version
var ok bool
if version, ok = versions[releaseFile.Version]; !ok {
version = mojang.Version{
IsPreview: releaseFile.Preview,
DockerImage: make(map[string]string),
Platforms: make(map[string]mojang.VersionPlatform),
}
}
// Ignore if ared exists
if _, ok = version.Platforms[releaseFile.Platform]; ok {
fmt.Printf("Ignoring upload to %s %q, ared released in %s, skiping ...\n", releaseFile.Version, releaseFile.Platform, tea.RootURL)
continue
}
var file mojang.VersionPlatform
file.ZipFile = releaseFile.URL
zipFilePath, err := filepath.Abs(filepath.Join("./dists", releaseFile.Version, strings.ReplaceAll(releaseFile.Platform, "/", "_")+".zip"))
if err != nil {
panic(err)
}
tgzFilePath := strings.Replace(zipFilePath, ".zip", ".tgz", 1)
if err := os.MkdirAll(filepath.Dir(zipFilePath), 0777); err != nil && !os.IsNotExist(err) {
panic(err)
}
tgzFileBase := filepath.Base(tgzFilePath)
fmt.Printf("Downloading %q ...\n", releaseFile.URL)
if err := (&request.RequestOptions{Url: releaseFile.URL}).File(zipFilePath); err != nil {
panic(err)
} else if file.ZipSHA1, err = fileSha1(zipFilePath); err != nil {
panic(err)
}
fmt.Printf("Converting %q to %q\n", filepath.Base(zipFilePath), tgzFileBase)
file.ReleaseDate, err = ConvertZipToTgz(zipFilePath, tgzFilePath)
if err != nil {
panic(err)
} else if file.TarSHA1, err = fileSha1(tgzFilePath); err != nil {
panic(err)
}
// Get or create Release version
versionRelease, err := tea.Release(releaseFile.Preview, false, releaseFile.Version, "", "")
if err != nil {
panic(err)
}
fileAsset := versionRelease.GetFile(tgzFileBase)
if fileAsset == nil {
fmt.Printf("Uploading %s/%q ...\n", releaseFile.Version, tgzFileBase)
tgzFile, err := os.Open(tgzFilePath)
if err != nil {
panic(err)
}
defer tgzFile.Close()
if fileAsset, err = versionRelease.Upload(tgzFileBase, tgzFile); err != nil {
panic(err)
}
}
file.TarFile = fileAsset.FileUrl // Set latest Tar file
// re-add to versions map
version.Platforms[releaseFile.Platform] = file
versions[releaseFile.Version] = version
}
// Write versions to file
if _, err := localVersionsFile.Seek(0, 0); err != nil {
panic(err)
}
reencode := json.NewEncoder(localVersionsFile)
reencode.SetIndent("", " ")
if err := reencode.Encode(versions); err != nil {
panic(err)
}
}
func fileSha1(filepathStr string) (string, error) {
b, err := os.Open(filepathStr)
if err != nil {
return "", err
}
defer b.Close()
h := sha1.New()
if _, err := io.Copy(h, b); err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func ConvertZipToTgz(Src, Dst string) (time.Time, error) {
var bedrockRelease time.Time
zipFiles, err := zip.OpenReader(Src)
if err != nil {
return bedrockRelease, err
}
defer zipFiles.Close()
tgzFile, err := os.Create(Dst)
if err != nil {
return bedrockRelease, err
}
gz := gzip.NewWriter(tgzFile)
tz := tar.NewWriter(gz)
defer tz.Close()
defer gz.Close()
defer tgzFile.Close()
for _, file := range zipFiles.File {
info := file.FileInfo()
// Write tar header
if err = tz.WriteHeader(&tar.Header{Name: file.Name, Size: info.Size(), Typeflag: byte(info.Mode().Type()), Mode: int64(info.Mode()), ModTime: file.Modified, ChangeTime: file.Modified}); err != nil {
return bedrockRelease, err
}
if strings.HasPrefix(file.Name, "bedrock_server") {
bedrockRelease = file.Modified
}
// Ignore if is directory
if !info.IsDir() {
// Open file
read, err := file.Open()
if err != nil {
return bedrockRelease, err
}
// Copy data to tar file
_, err = io.Copy(tz, read)
read.Close()
if err != nil {
return bedrockRelease, err
}
}
}
// End convert zip to tar
tz.Close() // End tar file
gz.Close() // End gzip file
tgzFile.Close() // End file write
return bedrockRelease, nil
}