Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69e230a79c | ||
|
|
1a5f4f4f8e | ||
|
|
d0844dd6b5 | ||
|
|
d8e36aa6fa | ||
|
|
6781e4c16d | ||
|
|
fccba0248a |
+3
-3
@@ -125,7 +125,7 @@ func (s *LoginClient) OnStart() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoginRaw(c *proto.Conn, account *api.Account, addr string) (err error) {
|
func LoginRaw(c *proto.Conn, account *api.Account) (err error) {
|
||||||
lc := &LoginClient{
|
lc := &LoginClient{
|
||||||
Conn: c,
|
Conn: c,
|
||||||
Account: account,
|
Account: account,
|
||||||
@@ -161,7 +161,7 @@ func LoginNoSrv(connectTo string, account *api.Account) (c *proto.Conn, err erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = LoginRaw(c, account, connectTo)
|
err = LoginRaw(c, account)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +174,6 @@ func Login(connectTo string, account *api.Account) (c *proto.Conn, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = LoginRaw(c, account, connectTo)
|
err = LoginRaw(c, account)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-1
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"debug/buildinfo"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -18,12 +19,26 @@ import (
|
|||||||
var ExpectedASubcommandErr = errors.New("expected a subcommand")
|
var ExpectedASubcommandErr = errors.New("expected a subcommand")
|
||||||
var UnknownSubcommandErr = errors.New("unknown subcommand try 'strom help' for a list of subcommands")
|
var UnknownSubcommandErr = errors.New("unknown subcommand try 'strom help' for a list of subcommands")
|
||||||
|
|
||||||
|
func Version(args []string) (err error) {
|
||||||
|
selfPath, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, err := buildinfo.ReadFile(selfPath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("strom cli ", info.Main.Version, " (", info.Main.Sum, ")")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var subcommands = map[string]func(args []string) error{
|
var subcommands = map[string]func(args []string) error{
|
||||||
"offline-uuid": offline_uuid.Run,
|
"offline-uuid": offline_uuid.Run,
|
||||||
"print-nbt": print_nbt.Run,
|
"print-nbt": print_nbt.Run,
|
||||||
"status": status.Run,
|
"status": status.Run,
|
||||||
"packet-spy": packet_inspector.Run,
|
"packet-spy": packet_inspector.Run,
|
||||||
"api": api.Run,
|
"api": api.Run,
|
||||||
|
"version": Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Help(args []string) (err error) {
|
func Help(args []string) (err error) {
|
||||||
@@ -39,7 +54,7 @@ func mainE() (err error) {
|
|||||||
|
|
||||||
// Debug stuff
|
// Debug stuff
|
||||||
slog.SetLogLoggerLevel(slog.LevelDebug)
|
slog.SetLogLoggerLevel(slog.LevelDebug)
|
||||||
//args = []string{"TEST", "api", "-name", "Admin_Else"}
|
//args = []string{"TEST", "version"}
|
||||||
|
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
err = ExpectedASubcommandErr
|
err = ExpectedASubcommandErr
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ func Run(args []string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.DebugPrintPackets = []string{""}
|
c.DebugPrintPackets = []string{""}
|
||||||
err = client.LoginRaw(c, acc, *TargetAddr)
|
err = client.LoginRaw(c, acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -99,7 +99,12 @@ func StateIdFromBlocKAndStateMap(version string, name string, stateMap map[strin
|
|||||||
err = BlockNotFoundErr
|
err = BlockNotFoundErr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stateId, err = b.IdFromStateMap(stateMap)
|
if stateMap == nil {
|
||||||
|
stateId = b.DefaultState
|
||||||
|
} else {
|
||||||
|
stateId, err = b.IdFromStateMap(stateMap)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+59
-3
@@ -1,5 +1,14 @@
|
|||||||
package anvil
|
package anvil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/admin-else/strom/data"
|
||||||
|
"github.com/admin-else/strom/level"
|
||||||
|
"github.com/admin-else/strom/util"
|
||||||
|
)
|
||||||
|
|
||||||
type Chunk struct {
|
type Chunk struct {
|
||||||
DataVersion int32
|
DataVersion int32
|
||||||
Heightmaps map[string][]int64
|
Heightmaps map[string][]int64
|
||||||
@@ -8,17 +17,64 @@ type Chunk struct {
|
|||||||
Sections []Section
|
Sections []Section
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const McPrefix = "minecraft:"
|
||||||
|
|
||||||
|
func (c Chunk) ToStorage(version string) (toChunk *level.Chunk, err error) {
|
||||||
|
f := level.MakeBlockFormat(version)
|
||||||
|
toChunk = new(level.Chunk)
|
||||||
|
|
||||||
|
toChunk.Sections = make([]level.Section, len(c.Sections))
|
||||||
|
for i, s := range c.Sections {
|
||||||
|
pallete := make([]int32, len(s.BlockStates.Palette))
|
||||||
|
for j, p := range s.BlockStates.Palette {
|
||||||
|
pallete[j], err = data.StateIdFromBlocKAndStateMap(version, strings.TrimPrefix(p.Name, McPrefix), p.Properties)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this is probably fine
|
||||||
|
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.BlockStates.Data))), len(s.BlockStates.Data))
|
||||||
|
|
||||||
|
toChunk.Sections[i].Blocks, err = f.Import(uintSlice, util.BpeByNum(float64(len(s.BlockStates.Palette))), pallete)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
toChunk.Sections[i].BlockCount = int16(level.CountStorage(toChunk.Sections[i].Blocks, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, s := range c.Sections {
|
||||||
|
pallete := make([]int32, len(s.Biomes.Palette))
|
||||||
|
for j, p := range s.Biomes.Palette {
|
||||||
|
var b *data.Biome
|
||||||
|
b, ok := data.LookupBiomeByName(version, strings.TrimPrefix(p, McPrefix))
|
||||||
|
if !ok {
|
||||||
|
err = data.UnknownBiomeNameErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pallete[j] = b.Id
|
||||||
|
}
|
||||||
|
// this is probably fine
|
||||||
|
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.Biomes.Data))), len(s.Biomes.Data))
|
||||||
|
|
||||||
|
toChunk.Sections[i].Biomes, err = f.Import(uintSlice, util.BpeByNum(float64(len(pallete))), pallete)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type Section struct {
|
type Section struct {
|
||||||
Y int8
|
Y int8
|
||||||
BlockStates struct {
|
BlockStates struct {
|
||||||
Data []int64
|
Data []int64 `nbt:"data,omitempty"`
|
||||||
Palette []struct {
|
Palette []struct {
|
||||||
Name string
|
Name string
|
||||||
Properties map[string]string `nbt:"properties,omitempty"`
|
Properties map[string]string `nbt:"properties,omitempty"`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Biomes []struct {
|
Biomes struct {
|
||||||
Data []int64
|
Data []int64 `nbt:"data,omitempty"`
|
||||||
Palette []string
|
Palette []string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-4
@@ -29,13 +29,30 @@ func (r StorageFormat) Import(data []uint64, bpe uint8, palette []int32) (s *Sto
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !slices.Contains(r.AvailableBpes, bpe) {
|
|
||||||
err = BpeNotAvailableErr
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s = new(Storage)
|
s = new(Storage)
|
||||||
s.format = r
|
s.format = r
|
||||||
s.resize(bpe)
|
s.resize(bpe)
|
||||||
|
|
||||||
|
if !slices.Contains(r.AvailableBpes, bpe) {
|
||||||
|
var newBpe uint8
|
||||||
|
for _, newBpe = range r.AvailableBpes {
|
||||||
|
if bpe < newBpe {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tmps *Storage
|
||||||
|
tmps, err = StorageFormat{
|
||||||
|
AvailableBpes: []uint8{bpe},
|
||||||
|
BiggestDirect: false,
|
||||||
|
Len: r.Len,
|
||||||
|
}.ImportDataDirect(data)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tmps.resize(newBpe)
|
||||||
|
data = tmps.data
|
||||||
|
bpe = newBpe
|
||||||
|
}
|
||||||
if bpe == 0 && len(palette) != 1 {
|
if bpe == 0 && len(palette) != 1 {
|
||||||
err = Bpe0PalletMustBeLenOneErr
|
err = Bpe0PalletMustBeLenOneErr
|
||||||
return
|
return
|
||||||
@@ -238,3 +255,12 @@ func CompareStorage(a, b *Storage) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CountStorage(s *Storage, v int32) (a int) {
|
||||||
|
for i := range s.format.Len {
|
||||||
|
if w, _ := s.Get(i); w == v {
|
||||||
|
a++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
+11
-5
@@ -163,15 +163,18 @@ func (l *LoginServer) OnEncryptionResponse(packet *v1_21_8.LoginToServerPacketEn
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
serverId := crypto.AuthDigest([]byte(l.ServerId), sharedSecret, l.PublicKeyBytes)
|
|
||||||
_, err = api.HasJoined(l.Requested.Name, serverId, "")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = l.SetSecret(sharedSecret)
|
err = l.SetSecret(sharedSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverId := crypto.AuthDigest([]byte(l.ServerId), sharedSecret, l.PublicKeyBytes)
|
||||||
|
if l.OnlineMode {
|
||||||
|
_, err = api.HasJoined(l.Requested.Name, serverId, "")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
err = l.FinishLogin()
|
err = l.FinishLogin()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -234,12 +237,15 @@ func WithCompatibleVersions(versions ...int32) LoginServerSetting {
|
|||||||
|
|
||||||
func ServeLogin(c *proto.Conn, settings ...LoginServerSetting) (ret *LoginServer, err error) {
|
func ServeLogin(c *proto.Conn, settings ...LoginServerSetting) (ret *LoginServer, err error) {
|
||||||
ret = &LoginServer{Conn: c}
|
ret = &LoginServer{Conn: c}
|
||||||
|
ret.OnlineMode = true
|
||||||
|
|
||||||
ret.RegisterCritical(ret.OnDefault)
|
ret.RegisterCritical(ret.OnDefault)
|
||||||
ret.RegisterCriticalUntilLatest(ret.OnHandshake)
|
ret.RegisterCriticalUntilLatest(ret.OnHandshake)
|
||||||
ret.RegisterCriticalUntilLatest(ret.OnLoginStart)
|
ret.RegisterCriticalUntilLatest(ret.OnLoginStart)
|
||||||
ret.RegisterCriticalUntilLatest(ret.OnLoginAcknowledged)
|
ret.RegisterCriticalUntilLatest(ret.OnLoginAcknowledged)
|
||||||
ret.RegisterCriticalUntilLatest(ret.OnStatusRequest)
|
ret.RegisterCriticalUntilLatest(ret.OnStatusRequest)
|
||||||
ret.RegisterCriticalUntilLatest(ret.OnStatusPing)
|
ret.RegisterCriticalUntilLatest(ret.OnStatusPing)
|
||||||
|
ret.RegisterCriticalUntilLatest(ret.OnEncryptionResponse)
|
||||||
for _, s := range settings {
|
for _, s := range settings {
|
||||||
s(ret)
|
s(ret)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ func StartServerWithOnConn(listenAddr string, onConn func(c *proto.Conn) (err er
|
|||||||
if errors.Is(connErr, ShutDownServerErr) {
|
if errors.Is(connErr, ShutDownServerErr) {
|
||||||
running = false
|
running = false
|
||||||
}
|
}
|
||||||
|
c.Log.Error("closing connection", "err", connErr)
|
||||||
if connErr != nil {
|
if connErr != nil {
|
||||||
connErr = Kick(c, text.Pretty(connErr.Error()), "")
|
connErr = Kick(c, text.Pretty(connErr.Error()), "")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ func wontFail[T any](v T, err error) T {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// THIS IS REDUNDANT USE LOGIN PACKET IN MINECRAFT DATA
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Edit these two
|
// Edit these two
|
||||||
Version = "1.21.11"
|
Version = "1.21.11"
|
||||||
|
|||||||
Reference in New Issue
Block a user