Translate ItemStackRequest

This commit is contained in:
AkmalFairuz
2025-01-01 14:22:41 +07:00
parent e2c9fe43cc
commit d469d7573d
4 changed files with 177 additions and 76 deletions

View File

@@ -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)
}

View File

@@ -96,3 +96,21 @@ func PlayerInventoryAction(io protocol.IO, x *protocol.UseItemTransactionData) {
io.Varuint32(&x.ClientPrediction) 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)
}

View File

@@ -38,10 +38,40 @@ type ItemStackRequest struct {
FilterCause int32 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. // Marshal encodes/decodes an ItemStackRequest.
func (x *ItemStackRequest) Marshal(r protocol.IO) { func (x *ItemStackRequest) Marshal(r protocol.IO) {
r.Varint32(&x.RequestID) 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) protocol.FuncSlice(r, &x.FilterStrings, r.String)
r.Int32(&x.FilterCause) r.Int32(&x.FilterCause)
} }
@@ -49,42 +79,42 @@ func (x *ItemStackRequest) Marshal(r protocol.IO) {
// lookupStackRequestActionType looks up the ID of a StackRequestAction. // lookupStackRequestActionType looks up the ID of a StackRequestAction.
func lookupStackRequestActionType(x StackRequestAction, id *uint8) bool { func lookupStackRequestActionType(x StackRequestAction, id *uint8) bool {
switch x.(type) { switch x.(type) {
case *TakeStackRequestAction: case *protocol.TakeStackRequestAction:
*id = StackRequestActionTake *id = protocol.StackRequestActionTake
case *PlaceStackRequestAction: case *protocol.PlaceStackRequestAction:
*id = StackRequestActionPlace *id = protocol.StackRequestActionPlace
case *SwapStackRequestAction: case *protocol.SwapStackRequestAction:
*id = StackRequestActionSwap *id = protocol.StackRequestActionSwap
case *DropStackRequestAction: case *protocol.DropStackRequestAction:
*id = StackRequestActionDrop *id = protocol.StackRequestActionDrop
case *DestroyStackRequestAction: case *protocol.DestroyStackRequestAction:
*id = StackRequestActionDestroy *id = protocol.StackRequestActionDestroy
case *ConsumeStackRequestAction: case *protocol.ConsumeStackRequestAction:
*id = StackRequestActionConsume *id = protocol.StackRequestActionConsume
case *CreateStackRequestAction: case *protocol.CreateStackRequestAction:
*id = StackRequestActionCreate *id = protocol.StackRequestActionCreate
case *LabTableCombineStackRequestAction: case *protocol.LabTableCombineStackRequestAction:
*id = StackRequestActionLabTableCombine *id = protocol.StackRequestActionLabTableCombine
case *BeaconPaymentStackRequestAction: case *protocol.BeaconPaymentStackRequestAction:
*id = StackRequestActionBeaconPayment *id = protocol.StackRequestActionBeaconPayment
case *MineBlockStackRequestAction: case *protocol.MineBlockStackRequestAction:
*id = StackRequestActionMineBlock *id = protocol.StackRequestActionMineBlock
case *CraftRecipeStackRequestAction: case *CraftRecipeStackRequestAction:
*id = StackRequestActionCraftRecipe *id = protocol.StackRequestActionCraftRecipe
case *AutoCraftRecipeStackRequestAction: case *protocol.AutoCraftRecipeStackRequestAction:
*id = StackRequestActionCraftRecipeAuto *id = protocol.StackRequestActionCraftRecipeAuto
case *CraftCreativeStackRequestAction: case *protocol.CraftCreativeStackRequestAction:
*id = StackRequestActionCraftCreative *id = protocol.StackRequestActionCraftCreative
case *CraftRecipeOptionalStackRequestAction: case *protocol.CraftRecipeOptionalStackRequestAction:
*id = StackRequestActionCraftRecipeOptional *id = protocol.StackRequestActionCraftRecipeOptional
case *CraftGrindstoneRecipeStackRequestAction: case *protocol.CraftGrindstoneRecipeStackRequestAction:
*id = StackRequestActionCraftGrindstone *id = protocol.StackRequestActionCraftGrindstone
case *CraftLoomRecipeStackRequestAction: case *protocol.CraftLoomRecipeStackRequestAction:
*id = StackRequestActionCraftLoom *id = protocol.StackRequestActionCraftLoom
case *CraftNonImplementedStackRequestAction: case *protocol.CraftNonImplementedStackRequestAction:
*id = StackRequestActionCraftNonImplementedDeprecated *id = protocol.StackRequestActionCraftNonImplementedDeprecated
case *CraftResultsDeprecatedStackRequestAction: case *protocol.CraftResultsDeprecatedStackRequestAction:
*id = StackRequestActionCraftResultsDeprecated *id = protocol.StackRequestActionCraftResultsDeprecated
default: default:
return false return false
} }
@@ -92,48 +122,48 @@ func lookupStackRequestActionType(x StackRequestAction, id *uint8) bool {
} }
// lookupStackRequestAction looks up the StackRequestAction matching an ID. // 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 { switch id {
case StackRequestActionTake: case protocol.StackRequestActionTake:
*x = &TakeStackRequestAction{} *x = &protocol.TakeStackRequestAction{}
case StackRequestActionPlace: case protocol.StackRequestActionPlace:
*x = &PlaceStackRequestAction{} *x = &protocol.PlaceStackRequestAction{}
case StackRequestActionSwap: case protocol.StackRequestActionSwap:
*x = &SwapStackRequestAction{} *x = &protocol.SwapStackRequestAction{}
case StackRequestActionDrop: case protocol.StackRequestActionDrop:
*x = &DropStackRequestAction{} *x = &protocol.DropStackRequestAction{}
case StackRequestActionDestroy: case protocol.StackRequestActionDestroy:
*x = &DestroyStackRequestAction{} *x = &protocol.DestroyStackRequestAction{}
case StackRequestActionConsume: case protocol.StackRequestActionConsume:
*x = &ConsumeStackRequestAction{} *x = &protocol.ConsumeStackRequestAction{}
case StackRequestActionCreate: case protocol.StackRequestActionCreate:
*x = &CreateStackRequestAction{} *x = &protocol.CreateStackRequestAction{}
case StackRequestActionPlaceInContainer: case protocol.StackRequestActionPlaceInContainer:
*x = &PlaceInContainerStackRequestAction{} *x = &protocol.PlaceInContainerStackRequestAction{}
case StackRequestActionTakeOutContainer: case protocol.StackRequestActionTakeOutContainer:
*x = &TakeOutContainerStackRequestAction{} *x = &protocol.TakeOutContainerStackRequestAction{}
case StackRequestActionLabTableCombine: case protocol.StackRequestActionLabTableCombine:
*x = &LabTableCombineStackRequestAction{} *x = &protocol.LabTableCombineStackRequestAction{}
case StackRequestActionBeaconPayment: case protocol.StackRequestActionBeaconPayment:
*x = &BeaconPaymentStackRequestAction{} *x = &protocol.BeaconPaymentStackRequestAction{}
case StackRequestActionMineBlock: case protocol.StackRequestActionMineBlock:
*x = &MineBlockStackRequestAction{} *x = &protocol.MineBlockStackRequestAction{}
case StackRequestActionCraftRecipe: case protocol.StackRequestActionCraftRecipe:
*x = &CraftRecipeStackRequestAction{} *x = &CraftRecipeStackRequestAction{}
case StackRequestActionCraftRecipeAuto: case protocol.StackRequestActionCraftRecipeAuto:
*x = &AutoCraftRecipeStackRequestAction{} *x = &protocol.AutoCraftRecipeStackRequestAction{}
case StackRequestActionCraftCreative: case protocol.StackRequestActionCraftCreative:
*x = &CraftCreativeStackRequestAction{} *x = &protocol.CraftCreativeStackRequestAction{}
case StackRequestActionCraftRecipeOptional: case protocol.StackRequestActionCraftRecipeOptional:
*x = &CraftRecipeOptionalStackRequestAction{} *x = &protocol.CraftRecipeOptionalStackRequestAction{}
case StackRequestActionCraftGrindstone: case protocol.StackRequestActionCraftGrindstone:
*x = &CraftGrindstoneRecipeStackRequestAction{} *x = &protocol.CraftGrindstoneRecipeStackRequestAction{}
case StackRequestActionCraftLoom: case protocol.StackRequestActionCraftLoom:
*x = &CraftLoomRecipeStackRequestAction{} *x = &protocol.CraftLoomRecipeStackRequestAction{}
case StackRequestActionCraftNonImplementedDeprecated: case protocol.StackRequestActionCraftNonImplementedDeprecated:
*x = &CraftNonImplementedStackRequestAction{} *x = &protocol.CraftNonImplementedStackRequestAction{}
case StackRequestActionCraftResultsDeprecated: case protocol.StackRequestActionCraftResultsDeprecated:
*x = &CraftResultsDeprecatedStackRequestAction{} *x = &protocol.CraftResultsDeprecatedStackRequestAction{}
default: default:
return false return false
} }
@@ -535,6 +565,19 @@ type CraftRecipeStackRequestAction struct {
NumberOfCrafts byte 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 ... // Marshal ...
func (a *CraftRecipeStackRequestAction) Marshal(r protocol.IO) { func (a *CraftRecipeStackRequestAction) Marshal(r protocol.IO) {
r.Varuint32(&a.RecipeNetworkID) r.Varuint32(&a.RecipeNetworkID)

View File

@@ -74,6 +74,8 @@ func convertPacketFunc(pid uint32, cur func() packet.Packet) func() packet.Packe
return func() packet.Packet { return &legacypacket.StopSound{} } return func() packet.Packet { return &legacypacket.StopSound{} }
case packet.IDInventoryTransaction: case packet.IDInventoryTransaction:
return func() packet.Packet { return &legacypacket.InventoryTransaction{} } return func() packet.Packet { return &legacypacket.InventoryTransaction{} }
case packet.IDItemStackRequest:
return func() packet.Packet { return &legacypacket.ItemStackRequest{} }
default: default:
return cur return cur
} }
@@ -390,6 +392,12 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [
Actions: pk.Actions, Actions: pk.Actions,
TransactionData: trData, 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, Actions: pk.Actions,
TransactionData: trData, 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 return pks