BedrockFetch/main.go
Matheus Sampaio Queiroga 5368ef3f25
All checks were successful
Find and Upload Minecraft Server versions / build (push) Successful in 2m26s
MIgration from minecraft.azureedge.net to minecraft.net
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2025-01-20 17:01:56 -03:00

193 lines
4.4 KiB
Go

package main
import (
"archive/tar"
"archive/zip"
"compress/gzip"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"sync"
"sirherobrine23.com.br/go-bds/go-bds/bedrock"
"sirherobrine23.com.br/go-bds/go-bds/request/v2"
"sirherobrine23.com.br/go-bds/go-bds/semver"
"sirherobrine23.com.br/go-bds/bedrockfetch/tea"
)
type ConvertToTar bedrock.VersionPlatform
func (version *ConvertToTar) Convert(platformTarget string, client *tea.GiteaRelease) error {
fmt.Printf("Downloading %q\n", version.ZipFile)
localFile, _, err := request.SaveTmp(version.ZipFile, &request.Options{Header: bedrock.MojangHeaders})
if err != nil {
return err
}
defer func() {
fmt.Printf("Deleting %q\n", version.ZipFile)
localFile.Close() // Close file to delete
os.Remove(localFile.Name()) // Delete file
}()
tarGzFile, err := os.CreateTemp(os.TempDir(), "bedrock*fetch.tgz")
if err != nil {
return err
}
defer func() {
tarGzFile.Close()
os.Remove(tarGzFile.Name())
}()
stat, _ := localFile.Stat()
zipFile, err := zip.NewReader(localFile, stat.Size())
if err != nil {
return err
}
tarSha1 := sha1.New()
gz := gzip.NewWriter(io.MultiWriter(tarSha1, tarGzFile))
defer gz.Close()
tarball := tar.NewWriter(gz)
defer tarball.Close()
for _, file := range zipFile.File {
node := file.FileInfo()
head, err := tar.FileInfoHeader(node, "")
if err != nil {
return err
} else if err := tarball.WriteHeader(head); err != nil {
return err
} else if node.IsDir() {
continue
}
// Open file
fileRead, err := file.Open()
if err != nil {
return err
}
// Copy data
_, err = io.Copy(tarball, io.LimitReader(fileRead, node.Size()))
fileRead.Close()
if err != nil {
return err
}
}
if err := tarball.Close(); err != nil {
return err
} else if err = gz.Close(); err != nil {
return err
} else if _, err = tarGzFile.Seek(0, 0); err != nil {
return err
}
version.TarSHA1 = hex.EncodeToString(tarSha1.Sum(nil))
filename := fmt.Sprintf("%s.tgz", strings.ToLower(strings.ReplaceAll(platformTarget, "/", "_")))
if client.ExistsFile(filename) {
fmt.Printf("%q exist in %s\n", filename, client.TagName)
version.TarFile = client.GetFile(filename).FileUrl
} else {
fmt.Printf("Uploading %q to %s\n", filename, client.TagName)
asset, err := client.Upload(filename, tarGzFile)
if err != nil {
return err
}
version.TarFile = asset.FileUrl
}
return nil
}
func processMain() error {
fmt.Println("Fetching versions from minecraft site...")
fromMojang, err := bedrock.FetchFromWebsite()
if err != nil {
return err
}
convertedFromMojang, err := fromMojang.ConvertToVersions()
if err != nil {
return err
}
fmt.Println("loadding versions json...")
oldVersionFile, err := os.OpenFile("./versions.json", os.O_RDWR, 0)
if err != nil {
return err
}
defer oldVersionFile.Close()
var versions bedrock.Versions
if err = json.NewDecoder(oldVersionFile).Decode(&versions); err != nil {
return err
}
for _, remoteVersion := range convertedFromMojang {
fmt.Printf("Checking %s...", remoteVersion.ServerVersion)
if versions.Has(remoteVersion.ServerVersion) {
fmt.Println(" ignoring, ared released!")
continue
}
fmt.Println(" Creating Release")
release, err := tea.Release(remoteVersion.IsPreview, false, remoteVersion.ServerVersion, "", "")
if err != nil {
fmt.Println("cannot create release!")
return err
}
fmt.Printf("Converting %s\n", remoteVersion.ServerVersion)
var locker sync.Mutex
var waiter sync.WaitGroup
waiter.Add(len(remoteVersion.Platforms))
for platformIndex := range remoteVersion.Platforms {
go func() {
data := ConvertToTar(remoteVersion.Platforms[platformIndex])
if err2 := data.Convert(platformIndex, release); err == nil && err2 != nil {
err = err2
}
locker.Lock()
defer locker.Unlock()
remoteVersion.Platforms[platformIndex] = bedrock.VersionPlatform(data)
waiter.Done()
}()
}
// Wait convertions
waiter.Wait()
if err != nil {
release.DeleteRelease()
return err
}
versions = append(versions, remoteVersion)
}
// Sort versions slice
semver.SortStruct(versions)
if _, err = oldVersionFile.Seek(0, 0); err != nil {
return err
} else if err = oldVersionFile.Truncate(0); err != nil {
return err
}
enc := json.NewEncoder(oldVersionFile)
enc.SetIndent("", " ")
return enc.Encode(versions)
}
func main() {
if err := processMain(); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}