look at the code if you want to know what i did
This commit is contained in:
@@ -3,6 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/admin-else/strom/event"
|
||||||
"github.com/admin-else/strom/proto"
|
"github.com/admin-else/strom/proto"
|
||||||
"github.com/admin-else/strom/proto_base"
|
"github.com/admin-else/strom/proto_base"
|
||||||
)
|
)
|
||||||
@@ -30,6 +31,7 @@ func ConnectVersionLess(addr string) (ret *proto.Conn, err error) {
|
|||||||
ret.SetState(proto_base.Handshaking)
|
ret.SetState(proto_base.Handshaking)
|
||||||
ret.SetCompressionThreshold(-1)
|
ret.SetCompressionThreshold(-1)
|
||||||
ret.Actor = proto_base.Client
|
ret.Actor = proto_base.Client
|
||||||
|
ret.Loop = event.NewLoop()
|
||||||
ret.Conn, err = net.Dial("tcp", addr)
|
ret.Conn, err = net.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ func (c *ConfigIgnorer) OnStart() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigIgnorer) Default(event event.Anything) (err error) {
|
func (c *ConfigIgnorer) Default(e event.Anything) (err error) {
|
||||||
slog.Debug("Config ignorer", "packet", fmt.Sprintf("%#v", event))
|
if e.Val == (event.Tick{}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
slog.Debug("Config ignorer", "packet", fmt.Sprintf("%#v", e))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +59,7 @@ func IgnoreConfig(c *proto.Conn) (err error) {
|
|||||||
ci.RegisterUntilLatest(ci.OnPing)
|
ci.RegisterUntilLatest(ci.OnPing)
|
||||||
ci.RegisterUntilLatest(ci.OnKeepAlive)
|
ci.RegisterUntilLatest(ci.OnKeepAlive)
|
||||||
|
|
||||||
err = ci.Start()
|
err = ci.StartConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Join(err, errors.New("failed to ignore config"))
|
err = errors.Join(err, errors.New("failed to ignore config"))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -106,7 +106,7 @@ func DoDnsSimple(in string) (out string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
out = in
|
out = host + ":" + strconv.Itoa(int(portN))
|
||||||
if portN != 25565 {
|
if portN != 25565 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -152,7 +152,7 @@ func Login(c *proto.Conn, account *api.Account) (err error) {
|
|||||||
lc.SetState(proto_base.Login)
|
lc.SetState(proto_base.Login)
|
||||||
err = lc.Send(&v1_21_8.LoginToServerPacketLoginStart{Username: lc.Account.Name, PlayerUUID: lc.Account.Uuid})
|
err = lc.Send(&v1_21_8.LoginToServerPacketLoginStart{Username: lc.Account.Name, PlayerUUID: lc.Account.Uuid})
|
||||||
|
|
||||||
err = lc.Start()
|
err = lc.StartConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Join(FailedToLoginErr, err)
|
err = errors.Join(FailedToLoginErr, err)
|
||||||
}
|
}
|
||||||
@@ -165,8 +165,5 @@ func ConnectAndLogin(connectTo string, account *api.Account) (c *proto.Conn, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = Login(c, account)
|
err = Login(c, account)
|
||||||
if err != nil {
|
|
||||||
err = errors.Join(FailedToLoginErr, err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -19,10 +19,6 @@ type StatusClient struct {
|
|||||||
DoPingRoundTripTime bool
|
DoPingRoundTripTime bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StatusClient) OnStart() (err error) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StatusClient) OnStatus(p *v1_21_8.StatusToClientPacketServerInfo) (err error) {
|
func (s *StatusClient) OnStatus(p *v1_21_8.StatusToClientPacketServerInfo) (err error) {
|
||||||
s.Status = p.Response
|
s.Status = p.Response
|
||||||
s.PingSendTime = time.Now()
|
s.PingSendTime = time.Now()
|
||||||
@@ -55,9 +51,8 @@ func StatusRaw(addr string) (s *StatusClient, err error) {
|
|||||||
s = &StatusClient{
|
s = &StatusClient{
|
||||||
Conn: c,
|
Conn: c,
|
||||||
}
|
}
|
||||||
s.Loop = event.NewLoop()
|
s.RegisterCriticalUntilLatest(s.OnStatus)
|
||||||
s.RegisterUntilLatest(s.OnStatus)
|
s.RegisterCriticalUntilLatest(s.OnPong)
|
||||||
s.RegisterUntilLatest(s.OnPong)
|
|
||||||
|
|
||||||
p, err := MakeHandshakePacketAddr(s.Conn, proto_base.Status, addr)
|
p, err := MakeHandshakePacketAddr(s.Conn, proto_base.Status, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+32
-26
@@ -2,6 +2,7 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -75,9 +76,9 @@ func LookupBlockByStateId(version string, stateId int32) (block *Block, ok bool)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func LookupBlockByName(version string, stateId int32) (block *Block, ok bool) {
|
func LookupBlockByName(version string, name string) (block *Block, ok bool) {
|
||||||
for _, b := range BlocksForVersion(version) {
|
for _, b := range BlocksForVersion(version) {
|
||||||
if b.MinStateId <= stateId && stateId <= b.MaxStateId {
|
if b.Name == name {
|
||||||
block = b
|
block = b
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -85,6 +86,16 @@ func LookupBlockByName(version string, stateId int32) (block *Block, ok bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StateIdFromBlocKAndStateMap(version string, name string, stateMap map[string]string) (stateId int32, err error) {
|
||||||
|
b, ok := LookupBlockByName(version, name)
|
||||||
|
if !ok {
|
||||||
|
err = BlockNotFoundErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stateId, err = b.IdFromStateMap(stateMap)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var BlockStateOutOfRangeErr = errors.New("stateId out of range")
|
var BlockStateOutOfRangeErr = errors.New("stateId out of range")
|
||||||
var BlockNotFoundErr = errors.New("block not found")
|
var BlockNotFoundErr = errors.New("block not found")
|
||||||
var InvalidBoolValueErr = errors.New("invalid bool value")
|
var InvalidBoolValueErr = errors.New("invalid bool value")
|
||||||
@@ -92,7 +103,7 @@ var BadBlockStateTypeErr = errors.New("bad block state type")
|
|||||||
var BadEnumErr = errors.New("bad enum")
|
var BadEnumErr = errors.New("bad enum")
|
||||||
var SupplyAllStatesErr = errors.New("supply all states")
|
var SupplyAllStatesErr = errors.New("supply all states")
|
||||||
|
|
||||||
func FromBlockState(version string, stateId int32) (b *Block, stateData map[string]any, err error) {
|
func FromBlockState(version string, stateId int32) (b *Block, stateData map[string]string, err error) {
|
||||||
b, ok := LookupBlockByStateId(version, stateId)
|
b, ok := LookupBlockByStateId(version, stateId)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = BlockNotFoundErr
|
err = BlockNotFoundErr
|
||||||
@@ -101,19 +112,17 @@ func FromBlockState(version string, stateId int32) (b *Block, stateData map[stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: mc stores these as strings so we will do the same
|
func mcDataBlockStateTypeParse(n int32, s *BlockState) (v string, err error) {
|
||||||
|
|
||||||
func mcDataBlockStateTypeParse(n int32, s *BlockState) (v any, err error) {
|
|
||||||
switch s.Type {
|
switch s.Type {
|
||||||
case "int":
|
case "int":
|
||||||
v = n
|
v = strconv.Itoa(int(n))
|
||||||
case "enum":
|
case "enum":
|
||||||
v = s.Values[n]
|
v = s.Values[n]
|
||||||
case "bool":
|
case "bool":
|
||||||
if n == 0 { // MOJANK: 0 is true, 1 is false
|
if n == 0 { // MOJANK: 0 is true, 1 is false
|
||||||
v = true
|
v = "true"
|
||||||
} else if n == 1 {
|
} else if n == 1 {
|
||||||
v = false
|
v = "false"
|
||||||
} else {
|
} else {
|
||||||
err = InvalidBoolValueErr
|
err = InvalidBoolValueErr
|
||||||
}
|
}
|
||||||
@@ -123,35 +132,32 @@ func mcDataBlockStateTypeParse(n int32, s *BlockState) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func mcDataBlockStateTypeSerialize(v any, s *BlockState) (n int32, err error) {
|
func mcDataBlockStateTypeSerialize(v string, s *BlockState) (n int32, err error) {
|
||||||
switch t := v.(type) {
|
if v == "true" {
|
||||||
case int32:
|
return 0, nil
|
||||||
n = t
|
}
|
||||||
case bool:
|
if v == "false" {
|
||||||
if t {
|
return 1, nil
|
||||||
n = 0
|
}
|
||||||
} else {
|
n1, errMabye := strconv.Atoi(v)
|
||||||
n = 1
|
if errMabye == nil {
|
||||||
|
return int32(n1), nil
|
||||||
}
|
}
|
||||||
case string:
|
|
||||||
for i, enumValue := range s.Values {
|
for i, enumValue := range s.Values {
|
||||||
if enumValue == t {
|
if enumValue == v {
|
||||||
return int32(i), nil
|
return int32(i), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = BadEnumErr
|
err = BadEnumErr
|
||||||
default:
|
|
||||||
err = BadBlockStateTypeErr
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) StateMapFromId(stateId int32) (ret map[string]any, err error) {
|
func (b *Block) StateMapFromId(stateId int32) (ret map[string]string, err error) {
|
||||||
if stateId < b.MinStateId || stateId > b.MaxStateId {
|
if stateId < b.MinStateId || stateId > b.MaxStateId {
|
||||||
err = BlockStateOutOfRangeErr
|
err = BlockStateOutOfRangeErr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret = make(map[string]any)
|
ret = make(map[string]string)
|
||||||
stateId -= b.MinStateId
|
stateId -= b.MinStateId
|
||||||
|
|
||||||
a := int32(1)
|
a := int32(1)
|
||||||
@@ -166,7 +172,7 @@ func (b *Block) StateMapFromId(stateId int32) (ret map[string]any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) IdFromStateMap(m map[string]any) (ret int32, err error) {
|
func (b *Block) IdFromStateMap(m map[string]string) (ret int32, err error) {
|
||||||
a := int32(1)
|
a := int32(1)
|
||||||
for i := range len(b.States) {
|
for i := range len(b.States) {
|
||||||
s := b.States[len(b.States)-1-i]
|
s := b.States[len(b.States)-1-i]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ package data
|
|||||||
type VersionInfo struct {
|
type VersionInfo struct {
|
||||||
MinecraftVersion string
|
MinecraftVersion string
|
||||||
Version int32
|
Version int32
|
||||||
DataVersion int
|
DataVersion int32
|
||||||
UsesNetty bool
|
UsesNetty bool
|
||||||
MajorVersion string
|
MajorVersion string
|
||||||
ReleaseType string
|
ReleaseType string
|
||||||
@@ -42,6 +42,16 @@ func LookUpVersionByProtocolVersion(version int32) (ret VersionInfo, err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LookUpVersionByDataVersion(version int32) (ret VersionInfo, err error) {
|
||||||
|
for _, v := range ProtocolVersions {
|
||||||
|
if v.DataVersion == version {
|
||||||
|
ret = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = UnknownMinecraftVersionError
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
must(LoadJson("minecraft-data/data/pc/common/protocolVersions.json", &ProtocolVersions))
|
must(LoadJson("minecraft-data/data/pc/common/protocolVersions.json", &ProtocolVersions))
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-5
@@ -53,10 +53,13 @@ func (e HandlerDoneErr) Unwrap() error {
|
|||||||
return e.Return
|
return e.Return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrDontForward will stop the event from being forwarded to other handlers, including anything handlers.
|
// DontForwardErr will stop the event from being forwarded to other handlers, including anything handlers.
|
||||||
var ErrDontForward = errors.New("dont forward")
|
var DontForwardErr = errors.New("dont forward")
|
||||||
var WhileClosingErr = errors.New("error while closing")
|
var WhileClosingErr = errors.New("error while closing")
|
||||||
|
|
||||||
|
// CloseNonCriticalErr will close even when the event is non-critical
|
||||||
|
var CloseNonCriticalErr = errors.New("close non-critical")
|
||||||
|
|
||||||
func ValidateHandler(h any) (eventType reflect.Type, hv reflect.Value) {
|
func ValidateHandler(h any) (eventType reflect.Type, hv reflect.Value) {
|
||||||
hv = reflect.ValueOf(h)
|
hv = reflect.ValueOf(h)
|
||||||
if hv.Kind() != reflect.Func {
|
if hv.Kind() != reflect.Func {
|
||||||
@@ -86,7 +89,11 @@ func (l *Loop) RegisterCustomType(eventType reflect.Type, hv reflect.Value) {
|
|||||||
handleFunc := func(packet any) error {
|
handleFunc := func(packet any) error {
|
||||||
v := hv.Call([]reflect.Value{reflect.ValueOf(packet)})[0]
|
v := hv.Call([]reflect.Value{reflect.ValueOf(packet)})[0]
|
||||||
if !v.IsNil() {
|
if !v.IsNil() {
|
||||||
slog.Error("handler failed", "err", v.Interface().(error))
|
err := v.Interface().(error)
|
||||||
|
if errors.Is(err, CloseNonCriticalErr) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
slog.Error("handler failed", "err", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -124,7 +131,7 @@ func (l *Loop) FireFound(event any) (found bool, err error) {
|
|||||||
func (l *Loop) Fire(event any) (err error) {
|
func (l *Loop) Fire(event any) (err error) {
|
||||||
found, err := l.FireFound(event)
|
found, err := l.FireFound(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, ErrDontForward) {
|
if errors.Is(err, DontForwardErr) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -159,7 +166,7 @@ func (l *Loop) startLoop() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Loop) Start() (err error) {
|
func (l *Loop) StartLoop() (err error) {
|
||||||
go func() {
|
go func() {
|
||||||
l.ErrChan <- l.startLoop()
|
l.ErrChan <- l.startLoop()
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/admin-else/strom/data"
|
||||||
|
"github.com/go-viper/mapstructure/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Position struct {
|
||||||
|
X, Y, Z int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type MetaData struct {
|
||||||
|
Author string
|
||||||
|
Description string
|
||||||
|
Name string
|
||||||
|
TimeCreated int64
|
||||||
|
TimeModified int64
|
||||||
|
TotalBlocks int32
|
||||||
|
TotalVolume int32
|
||||||
|
RegionCount int32
|
||||||
|
EnclosingSize Position
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockState struct {
|
||||||
|
Name string
|
||||||
|
Properties map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Region struct {
|
||||||
|
Position Position
|
||||||
|
Size Position
|
||||||
|
BlockStatePalette []BlockState
|
||||||
|
BlockStates []int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
Version int32
|
||||||
|
SubVersion int32
|
||||||
|
MinecraftDataVersion int32
|
||||||
|
Metadata MetaData
|
||||||
|
Regions map[string]Region
|
||||||
|
}
|
||||||
|
|
||||||
|
type Structure struct {
|
||||||
|
File
|
||||||
|
BlockStatePalletRealized map[string][]int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load(v any) (s *Structure, err error) {
|
||||||
|
s = &Structure{}
|
||||||
|
err = mapstructure.Decode(v, &s.File)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret, err := data.LookUpVersionByDataVersion(s.MinecraftDataVersion)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for k, r := range s.Regions {
|
||||||
|
s.BlockStatePalletRealized[k] = make([]int32, len(r.BlockStatePalette))
|
||||||
|
for i, b := range r.BlockStatePalette {
|
||||||
|
var stateId int32
|
||||||
|
stateId, err = data.StateIdFromBlocKAndStateMap(ret.MinecraftVersion, b.Name, b.Properties)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.BlockStatePalletRealized[k][i] = stateId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package level
|
package structure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/admin-else/strom/nbt"
|
"github.com/admin-else/strom/nbt"
|
||||||
"github.com/go-viper/mapstructure/v2"
|
"github.com/go-viper/mapstructure/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadStructure(fileName string) (s *Structure, err error) {
|
func Load(fileName string) (s *Structure, err error) {
|
||||||
n, err := nbt.ReadFilePath(fileName)
|
n, err := nbt.ReadFilePath(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
+3
-1
@@ -291,6 +291,8 @@ func readPayload(id int8, r io.Reader) (ret any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var UnknownTagTypeErr = errors.New("unknown nbt type")
|
||||||
|
|
||||||
func writePayload(v any, w io.Writer) (err error) {
|
func writePayload(v any, w io.Writer) (err error) {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case struct{}:
|
case struct{}:
|
||||||
@@ -361,7 +363,7 @@ func writePayload(v any, w io.Writer) (err error) {
|
|||||||
}
|
}
|
||||||
err = binary.Write(w, Order, End)
|
err = binary.Write(w, Order, End)
|
||||||
default:
|
default:
|
||||||
err = errors.New("unknown nbt type")
|
err = UnknownTagTypeErr
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
package nbt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrintSNBTAny documented at https://minecraft.wiki/w/NBT_format#SNBT_format
|
||||||
|
func PrintSNBTAny(t any, w io.Writer) (err error) {
|
||||||
|
switch t := t.(type) {
|
||||||
|
case int8:
|
||||||
|
_, err = fmt.Fprintf(w, "%vB", t)
|
||||||
|
case bool:
|
||||||
|
_, err = fmt.Fprintf(w, "%v", t)
|
||||||
|
case int16:
|
||||||
|
_, err = fmt.Fprintf(w, "%vS", t)
|
||||||
|
case int32:
|
||||||
|
_, err = fmt.Fprintf(w, "%vI", t)
|
||||||
|
case int64:
|
||||||
|
_, err = fmt.Fprintf(w, "%vL", t)
|
||||||
|
case float32:
|
||||||
|
_, err = fmt.Fprintf(w, "%vF", t)
|
||||||
|
case float64:
|
||||||
|
_, err = fmt.Fprintf(w, "%vD", t)
|
||||||
|
case string:
|
||||||
|
_, err = fmt.Fprintf(w, "%q", t)
|
||||||
|
case []any:
|
||||||
|
_, err = fmt.Fprintf(w, "[")
|
||||||
|
for _, v := range t {
|
||||||
|
err = PrintSNBTAny(v, w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, ",")
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, "]")
|
||||||
|
case map[string]any:
|
||||||
|
_, err = fmt.Fprintf(w, "{")
|
||||||
|
for k, v := range t {
|
||||||
|
_, err = fmt.Fprintf(w, "%q:,", k)
|
||||||
|
err = PrintSNBTAny(v, w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, ",")
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, "}")
|
||||||
|
case []int8:
|
||||||
|
_, err = fmt.Fprintf(w, "[B;")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range t {
|
||||||
|
err = PrintSNBTAny(v, w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, ",")
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, "]")
|
||||||
|
case []int32:
|
||||||
|
_, err = fmt.Fprintf(w, "[I;")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range t {
|
||||||
|
err = PrintSNBTAny(v, w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, ",")
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, "]")
|
||||||
|
case []int64:
|
||||||
|
_, err = fmt.Fprintf(w, "[L;")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range t {
|
||||||
|
err = PrintSNBTAny(v, w)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, ",")
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(w, "]")
|
||||||
|
default:
|
||||||
|
err = UnknownTagTypeErr
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package nbt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
_ "embed"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed testdata/top_0_20.nbt
|
||||||
|
var topSNBT []byte
|
||||||
|
|
||||||
|
func TestPrintSNBTAny(t *testing.T) {
|
||||||
|
n, err := ReadFile(bytes.NewReader(topSNBT))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
bb := bytes.NewBuffer(nil)
|
||||||
|
err = PrintSNBTAny(n.Value, bb)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
t.Log(bb.String())
|
||||||
|
}
|
||||||
Vendored
BIN
Binary file not shown.
+8
-9
@@ -60,13 +60,19 @@ type Conn struct {
|
|||||||
|
|
||||||
func (c *Conn) StartConn() (err error) {
|
func (c *Conn) StartConn() (err error) {
|
||||||
c.RegisterCritical(c.OnTick)
|
c.RegisterCritical(c.OnTick)
|
||||||
return c.Loop.Start()
|
if c.state == proto_base.Play {
|
||||||
|
c.ActivateReceiveRoutine()
|
||||||
|
}
|
||||||
|
err = c.Loop.StartLoop()
|
||||||
|
c.Loop = event.NewLoop()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) ReceiveJob() {
|
func (c *Conn) ReceiveJob() {
|
||||||
|
ctx := c.Ctx
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-c.Ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
packet, err := c.Receive()
|
packet, err := c.Receive()
|
||||||
@@ -233,10 +239,3 @@ func (c *Conn) OnTick(_ event.Tick) (err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) Start() (err error) {
|
|
||||||
if c.Loop == nil {
|
|
||||||
c.Loop = &event.Loop{}
|
|
||||||
}
|
|
||||||
return c.Loop.Start()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func ServeConfig(c *proto.Conn) (err error) {
|
|||||||
}
|
}
|
||||||
err = c.Send(&v1_21_8.ConfigurationToClientPacketFinishConfiguration{})
|
err = c.Send(&v1_21_8.ConfigurationToClientPacketFinishConfiguration{})
|
||||||
cs := &ConfigServer{c}
|
cs := &ConfigServer{c}
|
||||||
return cs.Start()
|
return cs.StartLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigServer) OnFinishConfiguration(_ *v1_21_8.ConfigurationToServerPacketFinishConfiguration) (err error) {
|
func (c *ConfigServer) OnFinishConfiguration(_ *v1_21_8.ConfigurationToServerPacketFinishConfiguration) (err error) {
|
||||||
|
|||||||
@@ -168,6 +168,6 @@ func ServeLogin(c *proto.Conn, settings ...LoginServerSetting) (ret *LoginServer
|
|||||||
s(ret)
|
s(ret)
|
||||||
}
|
}
|
||||||
ret.CompressionThreshold = 256
|
ret.CompressionThreshold = 256
|
||||||
err = ret.Start()
|
err = ret.StartLoop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -67,6 +67,6 @@ func ServeStatus(c *proto.Conn, s StatusResponse) (err error) {
|
|||||||
}
|
}
|
||||||
server.RegisterUntilLatest(server.OnStatusRequest)
|
server.RegisterUntilLatest(server.OnStatusRequest)
|
||||||
server.RegisterUntilLatest(server.OnStatusPing)
|
server.RegisterUntilLatest(server.OnStatusPing)
|
||||||
err = server.Start()
|
err = server.StartLoop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package print_nbt
|
package print_nbt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"os"
|
"os"
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
cmd = flag.NewFlagSet("print-nbt", flag.ContinueOnError)
|
cmd = flag.NewFlagSet("print-nbt", flag.ContinueOnError)
|
||||||
FileFlag = cmd.String("file", "", "The NBT file to print")
|
FileFlag = cmd.String("file", "", "The NBT file to print")
|
||||||
|
HashFormatFlag = cmd.Bool("snbt", false, "will print with go %#v")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run(args []string) (err error) {
|
func Run(args []string) (err error) {
|
||||||
@@ -27,7 +29,18 @@ func Run(args []string) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b, err := json.MarshalIndent(n, "", " ")
|
var b []byte
|
||||||
|
if *HashFormatFlag {
|
||||||
|
bb := bytes.NewBuffer(nil)
|
||||||
|
err = nbt.PrintSNBTAny(n.Value, bb)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b = bb.Bytes()
|
||||||
|
//b = []byte(strings.ReplaceAll(string(b), ",", ",\n"))
|
||||||
|
} else {
|
||||||
|
b, err = json.MarshalIndent(n, "", " ")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,10 +116,7 @@ func handleClient(c *proto.Conn) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer sockPuppet.Close()
|
defer sockPuppet.Close()
|
||||||
err = sockPuppet.Start(&client.LoginClient{
|
err = sockPuppet.StartLoop()
|
||||||
Conn: sockPuppet,
|
|
||||||
Account: acc,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -127,10 +124,10 @@ func handleClient(c *proto.Conn) (err error) {
|
|||||||
p := &Proxy{Client: sockPuppet, Servee: c}
|
p := &Proxy{Client: sockPuppet, Servee: c}
|
||||||
p.Data.Value = map[string]any{"Registries": []any{}}
|
p.Data.Value = map[string]any{"Registries": []any{}}
|
||||||
go func() {
|
go func() {
|
||||||
errChan <- p.Client.Start(p)
|
errChan <- p.Client.StartLoop()
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
errChan <- p.Servee.Start(p)
|
errChan <- p.Servee.StartLoop()
|
||||||
}()
|
}()
|
||||||
err = <-errChan
|
err = <-errChan
|
||||||
f, err := os.Create("data/registry/" + SaveAs + ".nbt")
|
f, err := os.Create("data/registry/" + SaveAs + ".nbt")
|
||||||
|
|||||||
@@ -154,10 +154,10 @@ func main() {
|
|||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
defer pc.Close()
|
defer pc.Close()
|
||||||
go func() {
|
go func() {
|
||||||
errChan <- pc.Start(pc)
|
errChan <- pc.StartConn()
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
errChan <- p.Start(p)
|
errChan <- p.StartConn()
|
||||||
}()
|
}()
|
||||||
err = <-errChan
|
err = <-errChan
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user