bedrocktool/utils/utils.go

196 lines
4.1 KiB
Go
Raw Permalink Normal View History

2023-01-29 21:20:13 +00:00
// Package utils ...
2022-09-04 14:26:32 +00:00
package utils
import (
"bytes"
2022-09-04 14:26:32 +00:00
"context"
"crypto/aes"
"crypto/sha256"
2022-09-04 14:26:32 +00:00
"encoding/json"
"errors"
2023-04-27 19:45:04 +00:00
"fmt"
2023-02-08 18:08:26 +00:00
"os"
2023-04-27 19:45:04 +00:00
"os/exec"
2022-09-04 14:26:32 +00:00
"path"
2023-04-27 19:45:04 +00:00
"path/filepath"
2022-09-04 14:26:32 +00:00
"regexp"
2023-04-27 19:45:04 +00:00
"runtime"
2022-09-04 14:26:32 +00:00
"strings"
"sync"
2022-09-04 14:26:32 +00:00
"github.com/bedrock-tool/bedrocktool/locale"
2022-10-20 23:46:18 +00:00
"github.com/google/uuid"
2022-09-04 14:26:32 +00:00
"github.com/sandertv/gophertunnel/minecraft"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2"
2022-09-04 14:26:32 +00:00
//"github.com/sandertv/gophertunnel/minecraft/gatherings"
"github.com/sandertv/gophertunnel/minecraft/protocol/login"
2023-02-08 18:08:26 +00:00
"github.com/sandertv/gophertunnel/minecraft/resource"
2022-09-04 14:26:32 +00:00
)
2023-03-05 21:50:58 +00:00
var Options struct {
2023-03-06 01:03:31 +00:00
Debug bool
Preload bool
IsInteractive bool
ExtraDebug bool
2023-04-20 22:55:52 +00:00
Capture bool
2023-03-06 01:03:31 +00:00
PathCustomUserData string
2023-03-05 21:50:58 +00:00
}
2022-09-04 14:26:32 +00:00
2023-01-29 21:20:13 +00:00
var nameRegexp = regexp.MustCompile(`\||(?:§.?)`)
2022-09-04 14:26:32 +00:00
2023-01-29 21:20:13 +00:00
// CleanupName cleans name so it can be used as a filename
2022-09-04 14:26:32 +00:00
func CleanupName(name string) string {
name = strings.Split(name, "\n")[0]
var _tmp struct {
K string `json:"k"`
}
err := json.Unmarshal([]byte(name), &_tmp)
if err == nil {
name = _tmp.K
}
2023-01-29 21:20:13 +00:00
name = string(nameRegexp.ReplaceAll([]byte(name), []byte("")))
2022-09-04 14:26:32 +00:00
name = strings.TrimSpace(name)
return name
}
// connections
func connectServer(ctx context.Context, address string, ClientData *login.ClientData, wantPacks bool, packetFunc PacketFunc, tokenSource oauth2.TokenSource) (serverConn *minecraft.Conn, err error) {
2022-09-04 14:26:32 +00:00
cd := login.ClientData{}
if ClientData != nil {
cd = *ClientData
}
logrus.Info(locale.Loc("connecting", locale.Strmap{"Address": address}))
2022-09-04 14:26:32 +00:00
serverConn, err = minecraft.Dialer{
TokenSource: tokenSource,
2022-10-20 23:46:18 +00:00
ClientData: cd,
2023-04-04 01:51:13 +00:00
PacketFunc: packetFunc,
2023-02-18 20:49:44 +00:00
DownloadResourcePack: func(id uuid.UUID, version string, current int, total int) bool {
2023-01-29 21:20:13 +00:00
return wantPacks
2022-10-20 23:46:18 +00:00
},
2022-09-04 14:26:32 +00:00
}.DialContext(ctx, "raknet", address)
if err != nil {
2023-02-22 15:48:24 +00:00
return serverConn, err
2022-09-04 14:26:32 +00:00
}
2022-09-07 12:07:33 +00:00
logrus.Debug(locale.Loc("connected", nil))
2022-09-04 14:26:32 +00:00
return serverConn, nil
}
func spawnConn(ctx context.Context, clientConn minecraft.IConn, serverConn minecraft.IConn, gd minecraft.GameData) error {
wg := sync.WaitGroup{}
2022-09-04 14:26:32 +00:00
errs := make(chan error, 2)
if clientConn != nil {
wg.Add(1)
go func() {
defer wg.Done()
2023-03-25 21:19:14 +00:00
errs <- clientConn.StartGame(gd)
}()
}
wg.Add(1)
2022-09-04 14:26:32 +00:00
go func() {
defer wg.Done()
2022-09-04 14:26:32 +00:00
errs <- serverConn.DoSpawn()
}()
wg.Wait()
2022-09-04 14:26:32 +00:00
for i := 0; i < 2; i++ {
select {
case err := <-errs:
if err != nil {
return errors.New(locale.Loc("failed_start_game", locale.Strmap{"Err": err}))
2022-09-04 14:26:32 +00:00
}
case <-ctx.Done():
return errors.New(locale.Loc("connection_cancelled", nil))
default:
2022-09-04 14:26:32 +00:00
}
}
return nil
}
// SplitExt splits path to filename and extension
func SplitExt(filename string) (name, ext string) {
name, ext = path.Base(filename), path.Ext(filename)
if ext != "" {
name = strings.TrimSuffix(name, ext)
}
return
}
func Clamp(a, b int) int {
if a > b {
return b
}
if a < 0 {
return 0
}
return a
}
2023-01-29 21:20:13 +00:00
func RandSeededUUID(str string) string {
h := sha256.Sum256([]byte(str))
id, _ := uuid.NewRandomFromReader(bytes.NewBuffer(h[:]))
return id.String()
}
2023-02-08 18:08:26 +00:00
func WriteManifest(manifest *resource.Manifest, fpath string) error {
w, err := os.Create(path.Join(fpath, "manifest.json"))
if err != nil {
return err
}
2023-06-24 09:02:58 +00:00
defer w.Close()
2023-02-08 18:08:26 +00:00
e := json.NewEncoder(w)
e.SetIndent("", "\t")
if err = e.Encode(manifest); err != nil {
return err
}
return nil
}
2023-03-14 01:07:39 +00:00
func CfbDecrypt(data []byte, key []byte) []byte {
cipher, _ := aes.NewCipher([]byte(key))
shiftRegister := append(key[:16], data...)
iv := make([]byte, 16)
off := 0
for ; off < len(data); off += 1 {
cipher.Encrypt(iv, shiftRegister)
data[off] ^= iv[0]
shiftRegister = shiftRegister[1:]
}
2023-03-14 01:07:39 +00:00
return data
}
2023-04-27 19:45:04 +00:00
func abs(n float32) float32 {
if n < 0 {
n = -n
}
return n
}
func SizeofFmt(num float32) string {
for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} {
if abs(num) < 1024.0 {
return fmt.Sprintf("%3.1f%sB", num, unit)
}
num /= 1024.0
}
return fmt.Sprintf("%.1fYiB", num)
}
func ShowFile(path string) {
path, _ = filepath.Abs(path)
if runtime.GOOS == "windows" {
2023-04-29 16:17:24 +00:00
cmd := exec.Command(`explorer`, "/select,", path)
cmd.Start()
2023-04-27 19:45:04 +00:00
return
}
if runtime.GOOS == "linux" {
println(path)
2023-04-27 19:45:04 +00:00
}
}