bedrocktool/utils/utils.go

155 lines
3.3 KiB
Go
Raw Normal View History

2022-09-04 14:26:32 +00:00
package utils
import (
"context"
"encoding/json"
"errors"
2022-09-04 14:26:32 +00:00
"net"
"path"
"regexp"
"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"
//"github.com/sandertv/gophertunnel/minecraft/gatherings"
"github.com/sandertv/gophertunnel/minecraft/protocol/login"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)
var (
2023-01-27 12:07:53 +00:00
G_debug bool // log packet names to console
G_preload_packs bool // connect to server to get packs before proxy
G_interactive bool // interactive cli input
2022-09-04 14:26:32 +00:00
)
var name_regexp = regexp.MustCompile(`\||(?:§.?)`)
// cleans name so it can be used as a filename
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
}
name = string(name_regexp.ReplaceAll([]byte(name), []byte("")))
name = strings.TrimSpace(name)
return name
}
// connections
func connectServer(ctx context.Context, address string, ClientData *login.ClientData, want_packs bool, packetFunc PacketFunc) (serverConn *minecraft.Conn, err error) {
2022-09-04 14:26:32 +00:00
packet_func := func(header packet.Header, payload []byte, src, dst net.Addr) {
if G_debug {
PacketLogger(header, payload, src, dst)
2022-10-01 02:47:38 +00:00
}
if packetFunc != nil {
packetFunc(header, payload, src, dst)
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{
2022-10-20 23:46:18 +00:00
TokenSource: GetTokenSource(),
ClientData: cd,
PacketFunc: packet_func,
DownloadResourcePack: func(id uuid.UUID, version string) bool {
return want_packs
},
2022-09-04 14:26:32 +00:00
}.DialContext(ctx, "raknet", address)
if err != nil {
return nil, err
}
2022-09-07 12:07:33 +00:00
logrus.Debug(locale.Loc("connected", nil))
2022-09-07 12:07:33 +00:00
Client_addr = serverConn.LocalAddr()
2022-09-04 14:26:32 +00:00
return serverConn, nil
}
func spawn_conn(ctx context.Context, clientConn *minecraft.Conn, serverConn *minecraft.Conn) 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()
errs <- clientConn.StartGame(serverConn.GameData())
}()
}
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
}
// get longest line length
func max_len(lines []string) int {
o := 0
for _, line := range lines {
if o < len(line) {
o = len(line)
}
}
return o
}
// make text centered
func MarginLines(lines []string) string {
ret := ""
max := max_len(lines)
for _, line := range lines {
if len(line) != max {
ret += strings.Repeat(" ", max/2-len(line)/4)
}
ret += line + "\n"
}
return ret
}
// 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
}