Add login and status clients with modular compression handling
This commit is contained in:
+55
-7
@@ -2,6 +2,7 @@ package strom
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/zlib"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@@ -42,7 +43,7 @@ func (a Actor) ReceiveDirection() queser.Direction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Connection struct {
|
type Connection struct {
|
||||||
io.ReadWriteCloser
|
net.Conn
|
||||||
CompressionThreshold int32
|
CompressionThreshold int32
|
||||||
State queser.State
|
State queser.State
|
||||||
Actor Actor
|
Actor Actor
|
||||||
@@ -62,7 +63,26 @@ func (c *Connection) Send(packet any) (err error) {
|
|||||||
}
|
}
|
||||||
var packetBytes []byte
|
var packetBytes []byte
|
||||||
if c.CompressionThreshold > 0 {
|
if c.CompressionThreshold > 0 {
|
||||||
panic("todo")
|
packetBuffer := bytes.NewBuffer(nil)
|
||||||
|
if int32(len(packetBytes)) >= c.CompressionThreshold {
|
||||||
|
err = queser.VarInt(len(packetBytes)).Encode(packetBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = zlib.NewWriter(packetBuffer).Write(packetBytes)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = queser.VarInt(0).Encode(packetBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = packetBuffer.Write(packetBytes)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
packetBytes = rawPacketBuffer.Bytes()
|
packetBytes = rawPacketBuffer.Bytes()
|
||||||
}
|
}
|
||||||
@@ -75,18 +95,37 @@ func (c *Connection) Send(packet any) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Connection) Receive() (packet any, err error) {
|
func (c *Connection) Receive() (packet any, err error) {
|
||||||
var packetLen queser.VarInt
|
var rawPacketLen queser.VarInt
|
||||||
packetLen, err = packetLen.Decode(c)
|
rawPacketLen, err = rawPacketLen.Decode(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rawPacketBytes, err := io.ReadAll(io.LimitReader(c, int64(packetLen)))
|
rawPacketBytes, err := io.ReadAll(io.LimitReader(c, int64(rawPacketLen)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
rawPacketBuffer := bytes.NewBuffer(rawPacketBytes)
|
||||||
var packetBytes []byte
|
var packetBytes []byte
|
||||||
if c.CompressionThreshold > 0 {
|
if c.CompressionThreshold > 0 {
|
||||||
panic("todo")
|
var packetLen queser.VarInt
|
||||||
|
packetLen, err = packetLen.Decode(rawPacketBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if packetLen == 0 {
|
||||||
|
packetBytes, err = io.ReadAll(rawPacketBuffer)
|
||||||
|
} else {
|
||||||
|
var zReader io.ReadCloser
|
||||||
|
zReader, err = zlib.NewReader(rawPacketBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer zReader.Close()
|
||||||
|
packetBytes, err = io.ReadAll(zReader)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
packetBytes = rawPacketBytes
|
packetBytes = rawPacketBytes
|
||||||
}
|
}
|
||||||
@@ -100,9 +139,18 @@ func ClientConnect(addr string) (ret *Connection, err error) {
|
|||||||
ret.State = queser.Handshaking
|
ret.State = queser.Handshaking
|
||||||
ret.CompressionThreshold = -1
|
ret.CompressionThreshold = -1
|
||||||
ret.Actor = Client
|
ret.Actor = Client
|
||||||
ret.ReadWriteCloser, err = net.Dial("tcp", addr)
|
ret.Conn, err = net.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConnectAndStart(addr string, inst HandlerInst) (ret *Connection, err error) {
|
||||||
|
ret, err = ClientConnect(addr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ret.Start(inst)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
+10
-34
@@ -1,43 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strom"
|
"strom"
|
||||||
|
"strom/modules"
|
||||||
|
|
||||||
"github.com/admin-else/queser"
|
"github.com/google/uuid"
|
||||||
"github.com/admin-else/queser/generated/v1_21_8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type StatusClient struct {
|
|
||||||
*strom.Connection
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StatusClient) Default(event any) (err error) {
|
|
||||||
err = fmt.Errorf("unexpected event: %v", event)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StatusClient) OnStart(_ strom.OnStart) (err error) {
|
|
||||||
err = s.Send(v1_21_8.HandshakingToServerPacketSetProtocol{
|
|
||||||
ProtocolVersion: 772,
|
|
||||||
ServerHost: "127.0.0.1",
|
|
||||||
ServerPort: 25566,
|
|
||||||
NextState: queser.VarInt(queser.Status),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.State = queser.Status
|
|
||||||
err = s.Send(v1_21_8.StatusToServerPacketPingStart{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StatusClient) OnStatus(p v1_21_8.StatusToClientPacketServerInfo) (err error) {
|
|
||||||
fmt.Println(p)
|
|
||||||
err = strom.HandlerDone
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func must(err error) {
|
func must(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -47,6 +16,13 @@ func must(err error) {
|
|||||||
func main() {
|
func main() {
|
||||||
c, err := strom.ClientConnect("127.0.0.1:25566")
|
c, err := strom.ClientConnect("127.0.0.1:25566")
|
||||||
must(err)
|
must(err)
|
||||||
err = c.Start(&StatusClient{c})
|
err = c.Start(&modules.LoginClient{
|
||||||
|
Account: modules.Account{
|
||||||
|
Username: "Admin_rizz",
|
||||||
|
UUID: uuid.UUID{},
|
||||||
|
Token: "",
|
||||||
|
},
|
||||||
|
Connection: c,
|
||||||
|
})
|
||||||
must(err)
|
must(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"strom"
|
||||||
|
|
||||||
|
"github.com/admin-else/queser"
|
||||||
|
"github.com/admin-else/queser/data"
|
||||||
|
"github.com/admin-else/queser/generated/v1_21_8"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
Username string
|
||||||
|
UUID uuid.UUID
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
type LoginClient struct {
|
||||||
|
*strom.Connection
|
||||||
|
Account Account
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoginClient) Default(event any) (err error) {
|
||||||
|
err = fmt.Errorf("unexpected event: %T%v", event, event)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoginClient) OnStart(_ strom.OnStart) (err error) {
|
||||||
|
parts := strings.Split(s.RemoteAddr().String(), ":")
|
||||||
|
versionData, err := data.LookUpProtocolVersionByName(s.Version)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
port, err := strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = s.Send(v1_21_8.HandshakingToServerPacketSetProtocol{
|
||||||
|
ProtocolVersion: queser.VarInt(versionData.Version),
|
||||||
|
ServerHost: parts[0],
|
||||||
|
ServerPort: uint16(port),
|
||||||
|
NextState: queser.VarInt(queser.Login),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.State = queser.Login
|
||||||
|
err = s.Send(v1_21_8.LoginToServerPacketLoginStart{Username: s.Account.Username, PlayerUUID: s.Account.UUID})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoginClient) OnCompress(compress v1_21_8.LoginToClientPacketCompress) (err error) {
|
||||||
|
s.CompressionThreshold = int32(compress.Threshold)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LoginClient) OnSuccess(success v1_21_8.LoginToClientPacketSuccess) (err error) {
|
||||||
|
err = s.Send(v1_21_8.LoginToServerPacketLoginAcknowledged{})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.State = queser.Configuration
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package modules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"strom"
|
||||||
|
|
||||||
|
"github.com/admin-else/queser"
|
||||||
|
"github.com/admin-else/queser/data"
|
||||||
|
"github.com/admin-else/queser/generated/v1_21_8"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusClient struct {
|
||||||
|
*strom.Connection
|
||||||
|
Status string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StatusClient) Default(event any) (err error) {
|
||||||
|
err = fmt.Errorf("unexpected event: %v", event)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StatusClient) OnStart(_ strom.OnStart) (err error) {
|
||||||
|
parts := strings.Split(s.RemoteAddr().String(), ":")
|
||||||
|
versionData, err := data.LookUpProtocolVersionByName(s.Version)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
port, err := strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = s.Send(v1_21_8.HandshakingToServerPacketSetProtocol{
|
||||||
|
ProtocolVersion: queser.VarInt(versionData.Version),
|
||||||
|
ServerHost: parts[0],
|
||||||
|
ServerPort: uint16(port),
|
||||||
|
NextState: queser.VarInt(queser.Status),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.State = queser.Status
|
||||||
|
err = s.Send(v1_21_8.StatusToServerPacketPingStart{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StatusClient) OnStatus(p v1_21_8.StatusToClientPacketServerInfo) (err error) {
|
||||||
|
s.Status = p.Response
|
||||||
|
err = strom.HandlerDone
|
||||||
|
return
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user