Files
2025-08-13 21:37:46 +07:00

135 lines
3.0 KiB
Go

package proto
import (
"fmt"
"github.com/sandertv/gophertunnel/minecraft/protocol"
)
type IO interface {
protocol.IO
SetProtocolID(protocolID int32)
ProtocolID() int32
}
type Reader struct {
*protocol.Reader
protocolID int32
}
func NewReader(r *protocol.Reader, protocolID int32) *Reader {
return &Reader{
Reader: r,
protocolID: protocolID,
}
}
func (r *Reader) SetProtocolID(protocolID int32) { r.protocolID = protocolID }
func (r *Reader) ProtocolID() int32 { return r.protocolID }
type Writer struct {
*protocol.Writer
protocolID int32
}
func NewWriter(w *protocol.Writer, protocolID int32) *Writer {
return &Writer{w, protocolID}
}
func (w *Writer) SetProtocolID(protocolID int32) { w.protocolID = protocolID }
func (w *Writer) ProtocolID() int32 { return w.protocolID }
func IsReader(r protocol.IO) bool {
_, ok := r.(*Reader)
return ok
}
func IsWriter(w protocol.IO) bool {
_, ok := w.(*Writer)
return ok
}
func EmptySlice[T any](io protocol.IO, slice *[]T) {
if IsReader(io) {
*slice = make([]T, 0)
}
}
func TransactionDataType(io protocol.IO, x *InventoryTransactionData) {
if IsReader(io) {
var transactionType uint32
io.Varuint32(&transactionType)
if !lookupTransactionData(transactionType, x) {
io.UnknownEnumOption(transactionType, "inventory transaction data type")
}
} else {
var id uint32
if !lookupTransactionDataType(*x, &id) {
io.UnknownEnumOption(fmt.Sprintf("%T", x), "inventory transaction data type")
}
io.Varuint32(&id)
}
}
func PlayerInventoryAction(io protocol.IO, x *protocol.UseItemTransactionData) {
io.Varint32(&x.LegacyRequestID)
if x.LegacyRequestID < -1 && (x.LegacyRequestID&1) == 0 {
protocol.Slice(io, &x.LegacySetItemSlots)
}
protocol.Slice(io, &x.Actions)
io.Varuint32(&x.ActionType)
if IsProtoGTE(io, ID712) {
io.Varuint32(&x.TriggerType)
}
io.BlockPos(&x.BlockPosition)
io.Varint32(&x.BlockFace)
io.Varint32(&x.HotBarSlot)
io.ItemInstance(&x.HeldItem)
io.Vec3(&x.Position)
io.Vec3(&x.ClickedPosition)
io.Varuint32(&x.BlockRuntimeID)
if IsProtoGTE(io, ID712) {
io.Varuint32(&x.ClientPrediction)
}
}
func IOStackRequestAction(io protocol.IO, x *protocol.StackRequestAction) {
if IsReader(io) {
var id uint8
io.Uint8(&id)
if !lookupStackRequestAction(id, x) {
io.UnknownEnumOption(id, "stack request action type")
return
}
} else {
var id byte
if !lookupStackRequestActionType(*x, &id) {
io.UnknownEnumOption(fmt.Sprintf("%T", *x), "stack request action type")
}
io.Uint8(&id)
}
(*x).Marshal(io)
}
func IORecipe(io protocol.IO, recipe *Recipe) {
if IsReader(io) {
var recipeType int32
io.Varint32(&recipeType)
if !lookupRecipe(recipeType, recipe) {
io.UnknownEnumOption(recipeType, "crafting data recipe type")
return
}
(*recipe).Unmarshal(io.(*Reader))
} else {
var recipeType int32
if !lookupRecipeType(*recipe, &recipeType) {
io.UnknownEnumOption(fmt.Sprintf("%T", *recipe), "crafting recipe type")
}
io.Varint32(&recipeType)
(*recipe).Marshal(io.(*Writer))
}
}