From d469d7573d51b9452c60f44f5a0c84806b30f143 Mon Sep 17 00:00:00 2001 From: AkmalFairuz Date: Wed, 1 Jan 2025 14:22:41 +0700 Subject: [PATCH] Translate ItemStackRequest --- legacyver/legacypacket/item_stack_request.go | 26 +++ legacyver/proto/io.go | 18 ++ legacyver/proto/item_stack.go | 195 +++++++++++-------- legacyver/protocol.go | 14 ++ 4 files changed, 177 insertions(+), 76 deletions(-) create mode 100644 legacyver/legacypacket/item_stack_request.go diff --git a/legacyver/legacypacket/item_stack_request.go b/legacyver/legacypacket/item_stack_request.go new file mode 100644 index 0000000..592515f --- /dev/null +++ b/legacyver/legacypacket/item_stack_request.go @@ -0,0 +1,26 @@ +package legacypacket + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +// ItemStackRequest is sent by the client to change item stacks in an inventory. It is essentially a +// replacement of the InventoryTransaction packet added in 1.16 for inventory specific actions, such as moving +// items around or crafting. The InventoryTransaction packet is still used for actions such as placing blocks +// and interacting with entities. +type ItemStackRequest struct { + // Requests holds a list of item stack requests. These requests are all separate, but the client buffers + // the requests, so you might find multiple unrelated requests in this packet. + Requests []proto.ItemStackRequest +} + +// ID ... +func (*ItemStackRequest) ID() uint32 { + return packet.IDItemStackRequest +} + +func (pk *ItemStackRequest) Marshal(io protocol.IO) { + protocol.Slice(io, &pk.Requests) +} diff --git a/legacyver/proto/io.go b/legacyver/proto/io.go index ca37321..c5f1bd4 100644 --- a/legacyver/proto/io.go +++ b/legacyver/proto/io.go @@ -96,3 +96,21 @@ func PlayerInventoryAction(io protocol.IO, x *protocol.UseItemTransactionData) { 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) +} diff --git a/legacyver/proto/item_stack.go b/legacyver/proto/item_stack.go index e179f92..14212b3 100644 --- a/legacyver/proto/item_stack.go +++ b/legacyver/proto/item_stack.go @@ -38,10 +38,40 @@ type ItemStackRequest struct { FilterCause int32 } +func (x *ItemStackRequest) FromLatest(y protocol.ItemStackRequest) ItemStackRequest { + x.RequestID = y.RequestID + x.Actions = make([]protocol.StackRequestAction, len(y.Actions)) + for i, v := range y.Actions { + if z, ok := v.(*protocol.CraftRecipeStackRequestAction); ok { + x.Actions[i] = (&CraftRecipeStackRequestAction{}).FromLatest(z) + } + } + x.FilterStrings = y.FilterStrings + x.FilterCause = y.FilterCause + return *x +} + +func (x *ItemStackRequest) ToLatest() protocol.ItemStackRequest { + ret := protocol.ItemStackRequest{ + RequestID: x.RequestID, + Actions: make([]protocol.StackRequestAction, len(x.Actions)), + FilterStrings: x.FilterStrings, + FilterCause: x.FilterCause, + } + for i, v := range x.Actions { + if z, ok := v.(*CraftRecipeStackRequestAction); ok { + ret.Actions[i] = z.ToLatest() + } + } + return ret +} + // Marshal encodes/decodes an ItemStackRequest. func (x *ItemStackRequest) Marshal(r protocol.IO) { r.Varint32(&x.RequestID) - protocol.FuncSlice(r, &x.Actions, r.StackRequestAction) + protocol.FuncSlice(r, &x.Actions, func(p *protocol.StackRequestAction) { + IOStackRequestAction(r, p) + }) protocol.FuncSlice(r, &x.FilterStrings, r.String) r.Int32(&x.FilterCause) } @@ -49,42 +79,42 @@ func (x *ItemStackRequest) Marshal(r protocol.IO) { // lookupStackRequestActionType looks up the ID of a StackRequestAction. func lookupStackRequestActionType(x StackRequestAction, id *uint8) bool { switch x.(type) { - case *TakeStackRequestAction: - *id = StackRequestActionTake - case *PlaceStackRequestAction: - *id = StackRequestActionPlace - case *SwapStackRequestAction: - *id = StackRequestActionSwap - case *DropStackRequestAction: - *id = StackRequestActionDrop - case *DestroyStackRequestAction: - *id = StackRequestActionDestroy - case *ConsumeStackRequestAction: - *id = StackRequestActionConsume - case *CreateStackRequestAction: - *id = StackRequestActionCreate - case *LabTableCombineStackRequestAction: - *id = StackRequestActionLabTableCombine - case *BeaconPaymentStackRequestAction: - *id = StackRequestActionBeaconPayment - case *MineBlockStackRequestAction: - *id = StackRequestActionMineBlock + case *protocol.TakeStackRequestAction: + *id = protocol.StackRequestActionTake + case *protocol.PlaceStackRequestAction: + *id = protocol.StackRequestActionPlace + case *protocol.SwapStackRequestAction: + *id = protocol.StackRequestActionSwap + case *protocol.DropStackRequestAction: + *id = protocol.StackRequestActionDrop + case *protocol.DestroyStackRequestAction: + *id = protocol.StackRequestActionDestroy + case *protocol.ConsumeStackRequestAction: + *id = protocol.StackRequestActionConsume + case *protocol.CreateStackRequestAction: + *id = protocol.StackRequestActionCreate + case *protocol.LabTableCombineStackRequestAction: + *id = protocol.StackRequestActionLabTableCombine + case *protocol.BeaconPaymentStackRequestAction: + *id = protocol.StackRequestActionBeaconPayment + case *protocol.MineBlockStackRequestAction: + *id = protocol.StackRequestActionMineBlock case *CraftRecipeStackRequestAction: - *id = StackRequestActionCraftRecipe - case *AutoCraftRecipeStackRequestAction: - *id = StackRequestActionCraftRecipeAuto - case *CraftCreativeStackRequestAction: - *id = StackRequestActionCraftCreative - case *CraftRecipeOptionalStackRequestAction: - *id = StackRequestActionCraftRecipeOptional - case *CraftGrindstoneRecipeStackRequestAction: - *id = StackRequestActionCraftGrindstone - case *CraftLoomRecipeStackRequestAction: - *id = StackRequestActionCraftLoom - case *CraftNonImplementedStackRequestAction: - *id = StackRequestActionCraftNonImplementedDeprecated - case *CraftResultsDeprecatedStackRequestAction: - *id = StackRequestActionCraftResultsDeprecated + *id = protocol.StackRequestActionCraftRecipe + case *protocol.AutoCraftRecipeStackRequestAction: + *id = protocol.StackRequestActionCraftRecipeAuto + case *protocol.CraftCreativeStackRequestAction: + *id = protocol.StackRequestActionCraftCreative + case *protocol.CraftRecipeOptionalStackRequestAction: + *id = protocol.StackRequestActionCraftRecipeOptional + case *protocol.CraftGrindstoneRecipeStackRequestAction: + *id = protocol.StackRequestActionCraftGrindstone + case *protocol.CraftLoomRecipeStackRequestAction: + *id = protocol.StackRequestActionCraftLoom + case *protocol.CraftNonImplementedStackRequestAction: + *id = protocol.StackRequestActionCraftNonImplementedDeprecated + case *protocol.CraftResultsDeprecatedStackRequestAction: + *id = protocol.StackRequestActionCraftResultsDeprecated default: return false } @@ -92,48 +122,48 @@ func lookupStackRequestActionType(x StackRequestAction, id *uint8) bool { } // lookupStackRequestAction looks up the StackRequestAction matching an ID. -func lookupStackRequestAction(id uint8, x *StackRequestAction) bool { +func lookupStackRequestAction(id uint8, x *protocol.StackRequestAction) bool { switch id { - case StackRequestActionTake: - *x = &TakeStackRequestAction{} - case StackRequestActionPlace: - *x = &PlaceStackRequestAction{} - case StackRequestActionSwap: - *x = &SwapStackRequestAction{} - case StackRequestActionDrop: - *x = &DropStackRequestAction{} - case StackRequestActionDestroy: - *x = &DestroyStackRequestAction{} - case StackRequestActionConsume: - *x = &ConsumeStackRequestAction{} - case StackRequestActionCreate: - *x = &CreateStackRequestAction{} - case StackRequestActionPlaceInContainer: - *x = &PlaceInContainerStackRequestAction{} - case StackRequestActionTakeOutContainer: - *x = &TakeOutContainerStackRequestAction{} - case StackRequestActionLabTableCombine: - *x = &LabTableCombineStackRequestAction{} - case StackRequestActionBeaconPayment: - *x = &BeaconPaymentStackRequestAction{} - case StackRequestActionMineBlock: - *x = &MineBlockStackRequestAction{} - case StackRequestActionCraftRecipe: + case protocol.StackRequestActionTake: + *x = &protocol.TakeStackRequestAction{} + case protocol.StackRequestActionPlace: + *x = &protocol.PlaceStackRequestAction{} + case protocol.StackRequestActionSwap: + *x = &protocol.SwapStackRequestAction{} + case protocol.StackRequestActionDrop: + *x = &protocol.DropStackRequestAction{} + case protocol.StackRequestActionDestroy: + *x = &protocol.DestroyStackRequestAction{} + case protocol.StackRequestActionConsume: + *x = &protocol.ConsumeStackRequestAction{} + case protocol.StackRequestActionCreate: + *x = &protocol.CreateStackRequestAction{} + case protocol.StackRequestActionPlaceInContainer: + *x = &protocol.PlaceInContainerStackRequestAction{} + case protocol.StackRequestActionTakeOutContainer: + *x = &protocol.TakeOutContainerStackRequestAction{} + case protocol.StackRequestActionLabTableCombine: + *x = &protocol.LabTableCombineStackRequestAction{} + case protocol.StackRequestActionBeaconPayment: + *x = &protocol.BeaconPaymentStackRequestAction{} + case protocol.StackRequestActionMineBlock: + *x = &protocol.MineBlockStackRequestAction{} + case protocol.StackRequestActionCraftRecipe: *x = &CraftRecipeStackRequestAction{} - case StackRequestActionCraftRecipeAuto: - *x = &AutoCraftRecipeStackRequestAction{} - case StackRequestActionCraftCreative: - *x = &CraftCreativeStackRequestAction{} - case StackRequestActionCraftRecipeOptional: - *x = &CraftRecipeOptionalStackRequestAction{} - case StackRequestActionCraftGrindstone: - *x = &CraftGrindstoneRecipeStackRequestAction{} - case StackRequestActionCraftLoom: - *x = &CraftLoomRecipeStackRequestAction{} - case StackRequestActionCraftNonImplementedDeprecated: - *x = &CraftNonImplementedStackRequestAction{} - case StackRequestActionCraftResultsDeprecated: - *x = &CraftResultsDeprecatedStackRequestAction{} + case protocol.StackRequestActionCraftRecipeAuto: + *x = &protocol.AutoCraftRecipeStackRequestAction{} + case protocol.StackRequestActionCraftCreative: + *x = &protocol.CraftCreativeStackRequestAction{} + case protocol.StackRequestActionCraftRecipeOptional: + *x = &protocol.CraftRecipeOptionalStackRequestAction{} + case protocol.StackRequestActionCraftGrindstone: + *x = &protocol.CraftGrindstoneRecipeStackRequestAction{} + case protocol.StackRequestActionCraftLoom: + *x = &protocol.CraftLoomRecipeStackRequestAction{} + case protocol.StackRequestActionCraftNonImplementedDeprecated: + *x = &protocol.CraftNonImplementedStackRequestAction{} + case protocol.StackRequestActionCraftResultsDeprecated: + *x = &protocol.CraftResultsDeprecatedStackRequestAction{} default: return false } @@ -535,6 +565,19 @@ type CraftRecipeStackRequestAction struct { NumberOfCrafts byte } +func (a *CraftRecipeStackRequestAction) FromLatest(y *protocol.CraftRecipeStackRequestAction) *CraftRecipeStackRequestAction { + a.RecipeNetworkID = y.RecipeNetworkID + a.NumberOfCrafts = y.NumberOfCrafts + return a +} + +func (a *CraftRecipeStackRequestAction) ToLatest() *protocol.CraftRecipeStackRequestAction { + return &protocol.CraftRecipeStackRequestAction{ + RecipeNetworkID: a.RecipeNetworkID, + NumberOfCrafts: a.NumberOfCrafts, + } +} + // Marshal ... func (a *CraftRecipeStackRequestAction) Marshal(r protocol.IO) { r.Varuint32(&a.RecipeNetworkID) diff --git a/legacyver/protocol.go b/legacyver/protocol.go index a40919b..105d6de 100644 --- a/legacyver/protocol.go +++ b/legacyver/protocol.go @@ -74,6 +74,8 @@ func convertPacketFunc(pid uint32, cur func() packet.Packet) func() packet.Packe return func() packet.Packet { return &legacypacket.StopSound{} } case packet.IDInventoryTransaction: return func() packet.Packet { return &legacypacket.InventoryTransaction{} } + case packet.IDItemStackRequest: + return func() packet.Packet { return &legacypacket.ItemStackRequest{} } default: return cur } @@ -390,6 +392,12 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [ Actions: pk.Actions, TransactionData: trData, } + case *packet.ItemStackRequest: + requests := make([]proto.ItemStackRequest, len(pk.Requests)) + for i, r := range pk.Requests { + requests[i] = (&proto.ItemStackRequest{}).FromLatest(r) + } + pks[pkIndex] = &legacypacket.ItemStackRequest{Requests: requests} } } @@ -660,6 +668,12 @@ func (p *Protocol) upgradePackets(pks []packet.Packet, conn *minecraft.Conn) []p Actions: pk.Actions, TransactionData: trData, } + case *legacypacket.ItemStackRequest: + requests := make([]protocol.ItemStackRequest, len(pk.Requests)) + for i, r := range pk.Requests { + requests[i] = r.ToLatest() + } + pks[pkIndex] = &packet.ItemStackRequest{Requests: requests} } } return pks