Skip to content

Commit 371dc58

Browse files
committed
feat: Add Minecraft handshake intent rewriting & transfer rule support
1 parent 16c152f commit 371dc58

File tree

7 files changed

+55
-16
lines changed

7 files changed

+55
-16
lines changed

common/mcprotocol/enum.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
package mcprotocol
22

33
const (
4-
NextStateStatus = iota + 1
5-
NextStateLogin
6-
NextStateTransfer // added in 1.20.5 (24w03a)
4+
IntentStatus = iota + 1
5+
IntentLogin
6+
IntentTransfer // added in 1.20.5 (24w03a)
7+
)
8+
9+
// Deprecated: Next State has been renamed to Intent.
10+
const (
11+
NextStateStatus = IntentStatus
12+
NextStateLogin = IntentLogin
13+
NextStateTransfer = IntentTransfer
714
)

config/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type RuleRewrite struct {
2626
type ruleRewriteMinecraft struct {
2727
Hostname string `json:",omitempty"`
2828
Port uint16 `json:",omitempty"`
29+
Intent int8 `json:",omitempty"`
2930
}
3031

3132
type RuleDomain struct {

protocol/minecraft/outbound.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func (o *Outbound) InjectConnection(ctx context.Context, conn *bufio.CachedConn,
238238
conn.Rewind(metadata.Minecraft.SniffPosition)
239239
}
240240
switch metadata.Minecraft.NextState {
241-
case mcprotocol.NextStateStatus:
241+
case mcprotocol.IntentStatus:
242242
// skip Status Request packet
243243
_, err := conn.Peek(2)
244244
if err != nil {
@@ -282,7 +282,7 @@ func (o *Outbound) InjectConnection(ctx context.Context, conn *bufio.CachedConn,
282282
mcprotocol.VarInt(metadata.Minecraft.ProtocolVersion).WriteToBuffer(buffer)
283283
mcprotocol.WriteString(buffer, hostname)
284284
binary.BigEndian.PutUint16(buffer.Extend(2), port)
285-
buffer.WriteByte(mcprotocol.NextStateStatus)
285+
buffer.WriteByte(mcprotocol.IntentStatus)
286286
mcprotocol.AppendPacketLength(buffer, buffer.Len())
287287
// construct status packet
288288
buffer.WriteByte(1)
@@ -337,7 +337,7 @@ func (o *Outbound) InjectConnection(ctx context.Context, conn *bufio.CachedConn,
337337
return nil
338338
}
339339

340-
case mcprotocol.NextStateLogin:
340+
case mcprotocol.IntentLogin:
341341
buffer := buf.New()
342342
buffer.Reset(mcprotocol.MaxVarIntLen)
343343
if o.config.Minecraft.NameAccess.Mode != access.DefaultMode {
@@ -412,7 +412,7 @@ func (o *Outbound) InjectConnection(ctx context.Context, conn *bufio.CachedConn,
412412
mcprotocol.VarInt(metadata.Minecraft.ProtocolVersion).WriteToBuffer(buffer)
413413
mcprotocol.WriteString(buffer, hostname)
414414
binary.BigEndian.PutUint16(buffer.Extend(2), port)
415-
buffer.WriteByte(mcprotocol.NextStateLogin)
415+
buffer.WriteByte(mcprotocol.IntentLogin)
416416
mcprotocol.AppendPacketLength(buffer, buffer.Len())
417417
// write handshake and login packet
418418
cache := conn.Cache()
@@ -431,7 +431,7 @@ func (o *Outbound) InjectConnection(ctx context.Context, conn *bufio.CachedConn,
431431
o.onlineCount.Add(-1)
432432
return err
433433

434-
case mcprotocol.NextStateTransfer:
434+
case mcprotocol.IntentTransfer:
435435
// TODO: Minecraft transfer support
436436
conn.Conn.(*net.TCPConn).SetLinger(0)
437437
return conn.Close()

protocol/minecraft/sniff.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,21 @@ func SniffClientHandshake(conn bufio.PeekConn, metadata *adapter.Metadata) error
7171
return ErrBadPacket
7272
}
7373

74-
nextState, err := buffer.ReadByte()
74+
intent, err := buffer.ReadByte()
7575
if err != nil {
7676
return common.Cause("read next state: ", err)
7777
}
78-
switch nextState {
79-
case mcprotocol.NextStateLogin,
80-
mcprotocol.NextStateStatus,
81-
mcprotocol.NextStateTransfer:
78+
switch intent {
79+
case mcprotocol.IntentLogin,
80+
mcprotocol.IntentStatus,
81+
mcprotocol.IntentTransfer:
8282
default:
8383
return ErrBadPacket
8484
}
85-
metadata.Minecraft.NextState = int8(nextState)
85+
metadata.Minecraft.NextState = int8(intent)
8686

8787
metadata.Minecraft.SniffPosition = conn.CurrentPosition()
88-
if nextState == mcprotocol.NextStateStatus {
88+
if intent == mcprotocol.IntentStatus {
8989
// status packet
9090
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
9191
_, err = conn.Peek(2)

route/router.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ func (r *Router) HandleConnection(conn net.Conn, metadata *adapter.Metadata) {
106106
if ruleConfig.Rewrite.Minecraft.Port > 0 {
107107
metadata.Minecraft.RewrittenPort = ruleConfig.Rewrite.Minecraft.Port
108108
}
109+
if ruleConfig.Rewrite.Minecraft.Intent > 0 {
110+
metadata.Minecraft.NextState = ruleConfig.Rewrite.Minecraft.Intent
111+
}
109112
}
110113
}
111114
// handle outbound

route/rule.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ func NewRule(logger *log.Logger, config *config.Rule, listMap map[string]set.Str
4747
return NewMinecraftPlayerNameRule(config, listMap)
4848
case "MinecraftStatus":
4949
return NewMinecraftStatusRule(config)
50+
case "MinecraftTransfer":
51+
return NewMinecraftTransferRule(config)
5052
}
5153
if len(ruleRegistry) > 0 && strings.HasPrefix(config.Type, typeCustomPrefix) {
5254
typeName := strings.TrimPrefix(config.Type, typeCustomPrefix)

route/rule_minecraft.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,33 @@ func (r *RuleMinecraftStatus) Config() *config.Rule {
8888

8989
func (r *RuleMinecraftStatus) Match(metadata *adapter.Metadata) (match bool) {
9090
if metadata.Minecraft != nil {
91-
match = metadata.Minecraft.NextState == mcprotocol.NextStateStatus
91+
match = metadata.Minecraft.NextState == mcprotocol.IntentStatus
92+
}
93+
if r.config.Invert {
94+
match = !match
95+
}
96+
return
97+
}
98+
99+
type RuleMinecraftTransfer struct {
100+
config *config.Rule
101+
}
102+
103+
var _ Rule = (*RuleMinecraftTransfer)(nil)
104+
105+
func NewMinecraftTransferRule(newConfig *config.Rule) (Rule, error) {
106+
return &RuleMinecraftTransfer{
107+
config: newConfig,
108+
}, nil
109+
}
110+
111+
func (r *RuleMinecraftTransfer) Config() *config.Rule {
112+
return r.config
113+
}
114+
115+
func (r *RuleMinecraftTransfer) Match(metadata *adapter.Metadata) (match bool) {
116+
if metadata.Minecraft != nil {
117+
match = metadata.Minecraft.NextState == mcprotocol.IntentTransfer
92118
}
93119
if r.config.Invert {
94120
match = !match

0 commit comments

Comments
 (0)