initial commit
This commit is contained in:
32
legacyver/proto/id.go
Normal file
32
legacyver/proto/id.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package proto
|
||||
|
||||
import "github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
|
||||
const (
|
||||
ID766 = 766
|
||||
ID748 = 748
|
||||
ID729 = 729
|
||||
ID712 = 712
|
||||
ID686 = 686
|
||||
ID685 = 685
|
||||
)
|
||||
|
||||
func IsProtoGTE(io protocol.IO, proto int32) bool {
|
||||
return io.(IO).ProtocolID() >= proto
|
||||
}
|
||||
|
||||
func IsProtoLTE(io protocol.IO, proto int32) bool {
|
||||
return io.(IO).ProtocolID() <= proto
|
||||
}
|
||||
|
||||
func IsProtoLT(io protocol.IO, proto int32) bool {
|
||||
return io.(IO).ProtocolID() < proto
|
||||
}
|
||||
|
||||
func IsProtoGT(io protocol.IO, proto int32) bool {
|
||||
return io.(IO).ProtocolID() > proto
|
||||
}
|
||||
|
||||
func FetchProtoID(io protocol.IO) int32 {
|
||||
return io.(IO).ProtocolID()
|
||||
}
|
||||
53
legacyver/proto/io.go
Normal file
53
legacyver/proto/io.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"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 }
|
||||
func (r *Reader) Reads() bool { return true }
|
||||
|
||||
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 (w *Writer) Reads() bool { return false }
|
||||
|
||||
func IsReader(r protocol.IO) bool {
|
||||
_, ok := r.(*Reader)
|
||||
return ok
|
||||
}
|
||||
|
||||
func IsWriter(w protocol.IO) bool {
|
||||
_, ok := w.(*Writer)
|
||||
return ok
|
||||
}
|
||||
652
legacyver/proto/item_stack.go
Normal file
652
legacyver/proto/item_stack.go
Normal file
@@ -0,0 +1,652 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
FilterCauseServerChatPublic = iota
|
||||
FilterCauseServerChatWhisper
|
||||
FilterCauseSignText
|
||||
FilterCauseAnvilText
|
||||
FilterCauseBookAndQuillText
|
||||
FilterCauseCommandBlockText
|
||||
FilterCauseBlockActorDataText
|
||||
FilterCauseJoinEventText
|
||||
FilterCauseLeaveEventText
|
||||
FilterCauseSlashCommandChat
|
||||
FilterCauseCartographyText
|
||||
FilterCauseKickCommand
|
||||
FilterCauseTitleCommand
|
||||
FilterCauseSummonCommand
|
||||
)
|
||||
|
||||
// ItemStackRequest represents a single request present in an ItemStackRequest packet sent by the client to
|
||||
// change an item in an inventory.
|
||||
// Item stack requests are either approved or rejected by the server using the ItemStackResponse packet.
|
||||
type ItemStackRequest struct {
|
||||
// RequestID is a unique ID for the request. This ID is used by the server to send a response for this
|
||||
// specific request in the ItemStackResponse packet.
|
||||
RequestID int32
|
||||
// Actions is a list of actions performed by the client. The actual type of the actions depends on which
|
||||
// ID was present, and is one of the concrete types below.
|
||||
Actions []protocol.StackRequestAction
|
||||
// FilterStrings is a list of filter strings involved in the request. This is typically filled with one string
|
||||
// when an anvil or cartography is used.
|
||||
FilterStrings []string
|
||||
// FilterCause represents the cause of any potential filtering. This is one of the constants above.
|
||||
FilterCause int32
|
||||
}
|
||||
|
||||
// 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.FilterStrings, r.String)
|
||||
r.Int32(&x.FilterCause)
|
||||
}
|
||||
|
||||
// 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 *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
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// lookupStackRequestAction looks up the StackRequestAction matching an ID.
|
||||
func lookupStackRequestAction(id uint8, x *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:
|
||||
*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{}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
ItemStackResponseStatusOK = iota
|
||||
ItemStackResponseStatusError
|
||||
ItemStackResponseStatusInvalidRequestActionType
|
||||
ItemStackResponseStatusActionRequestNotAllowed
|
||||
ItemStackResponseStatusScreenHandlerEndRequestFailed
|
||||
ItemStackResponseStatusItemRequestActionHandlerCommitFailed
|
||||
ItemStackResponseStatusInvalidRequestCraftActionType
|
||||
ItemStackResponseStatusInvalidCraftRequest
|
||||
ItemStackResponseStatusInvalidCraftRequestScreen
|
||||
ItemStackResponseStatusInvalidCraftResult
|
||||
ItemStackResponseStatusInvalidCraftResultIndex
|
||||
ItemStackResponseStatusInvalidCraftResultItem
|
||||
ItemStackResponseStatusInvalidItemNetId
|
||||
ItemStackResponseStatusMissingCreatedOutputContainer
|
||||
ItemStackResponseStatusFailedToSetCreatedItemOutputSlot
|
||||
ItemStackResponseStatusRequestAlreadyInProgress
|
||||
ItemStackResponseStatusFailedToInitSparseContainer
|
||||
ItemStackResponseStatusResultTransferFailed
|
||||
ItemStackResponseStatusExpectedItemSlotNotFullyConsumed
|
||||
ItemStackResponseStatusExpectedAnywhereItemNotFullyConsumed
|
||||
ItemStackResponseStatusItemAlreadyConsumedFromSlot
|
||||
ItemStackResponseStatusConsumedTooMuchFromSlot
|
||||
ItemStackResponseStatusMismatchSlotExpectedConsumedItem
|
||||
ItemStackResponseStatusMismatchSlotExpectedConsumedItemNetIdVariant
|
||||
ItemStackResponseStatusFailedToMatchExpectedSlotConsumedItem
|
||||
ItemStackResponseStatusFailedToMatchExpectedAllowedAnywhereConsumedItem
|
||||
ItemStackResponseStatusConsumedItemOutOfAllowedSlotRange
|
||||
ItemStackResponseStatusConsumedItemNotAllowed
|
||||
ItemStackResponseStatusPlayerNotInCreativeMode
|
||||
ItemStackResponseStatusInvalidExperimentalRecipeRequest
|
||||
ItemStackResponseStatusFailedToCraftCreative
|
||||
ItemStackResponseStatusFailedToGetLevelRecipe
|
||||
ItemStackResponseStatusFailedToFindRecipeByNetId
|
||||
ItemStackResponseStatusMismatchedCraftingSize
|
||||
ItemStackResponseStatusMissingInputSparseContainer
|
||||
ItemStackResponseStatusMismatchedRecipeForInputGridItems
|
||||
ItemStackResponseStatusEmptyCraftResults
|
||||
ItemStackResponseStatusFailedToEnchant
|
||||
ItemStackResponseStatusMissingInputItem
|
||||
ItemStackResponseStatusInsufficientPlayerLevelToEnchant
|
||||
ItemStackResponseStatusMissingMaterialItem
|
||||
ItemStackResponseStatusMissingActor
|
||||
ItemStackResponseStatusUnknownPrimaryEffect
|
||||
ItemStackResponseStatusPrimaryEffectOutOfRange
|
||||
ItemStackResponseStatusPrimaryEffectUnavailable
|
||||
ItemStackResponseStatusSecondaryEffectOutOfRange
|
||||
ItemStackResponseStatusSecondaryEffectUnavailable
|
||||
ItemStackResponseStatusDstContainerEqualToCreatedOutputContainer
|
||||
ItemStackResponseStatusDstContainerAndSlotEqualToSrcContainerAndSlot
|
||||
ItemStackResponseStatusFailedToValidateSrcSlot
|
||||
ItemStackResponseStatusFailedToValidateDstSlot
|
||||
ItemStackResponseStatusInvalidAdjustedAmount
|
||||
ItemStackResponseStatusInvalidItemSetType
|
||||
ItemStackResponseStatusInvalidTransferAmount
|
||||
ItemStackResponseStatusCannotSwapItem
|
||||
ItemStackResponseStatusCannotPlaceItem
|
||||
ItemStackResponseStatusUnhandledItemSetType
|
||||
ItemStackResponseStatusInvalidRemovedAmount
|
||||
ItemStackResponseStatusInvalidRegion
|
||||
ItemStackResponseStatusCannotDropItem
|
||||
ItemStackResponseStatusCannotDestroyItem
|
||||
ItemStackResponseStatusInvalidSourceContainer
|
||||
ItemStackResponseStatusItemNotConsumed
|
||||
ItemStackResponseStatusInvalidNumCrafts
|
||||
ItemStackResponseStatusInvalidCraftResultStackSize
|
||||
ItemStackResponseStatusCannotRemoveItem
|
||||
ItemStackResponseStatusCannotConsumeItem
|
||||
ItemStackResponseStatusScreenStackError
|
||||
)
|
||||
|
||||
// ItemStackResponse is a response to an individual ItemStackRequest.
|
||||
type ItemStackResponse struct {
|
||||
// Status specifies if the request with the RequestID below was successful. If this is the case, the
|
||||
// ContainerInfo below will have information on what slots ended up changing. If not, the container info
|
||||
// will be empty.
|
||||
// A non-0 status means an error occurred and will result in the action being reverted.
|
||||
Status uint8
|
||||
// RequestID is the unique ID of the request that this response is in reaction to. If rejected, the client
|
||||
// will undo the actions from the request with this ID.
|
||||
RequestID int32
|
||||
// ContainerInfo holds information on the containers that had their contents changed as a result of the
|
||||
// request.
|
||||
ContainerInfo []StackResponseContainerInfo
|
||||
}
|
||||
|
||||
func (x *ItemStackResponse) ToLatest() protocol.ItemStackResponse {
|
||||
ret := protocol.ItemStackResponse{
|
||||
Status: x.Status,
|
||||
RequestID: x.RequestID,
|
||||
ContainerInfo: make([]protocol.StackResponseContainerInfo, len(x.ContainerInfo)),
|
||||
}
|
||||
for i, v := range x.ContainerInfo {
|
||||
ret.ContainerInfo[i] = protocol.StackResponseContainerInfo{
|
||||
Container: v.Container,
|
||||
SlotInfo: make([]protocol.StackResponseSlotInfo, len(v.SlotInfo)),
|
||||
}
|
||||
for j, w := range v.SlotInfo {
|
||||
ret.ContainerInfo[i].SlotInfo[j] = protocol.StackResponseSlotInfo{
|
||||
Slot: w.Slot,
|
||||
HotbarSlot: w.HotbarSlot,
|
||||
Count: w.Count,
|
||||
StackNetworkID: w.StackNetworkID,
|
||||
CustomName: w.CustomName,
|
||||
FilteredCustomName: w.FilteredCustomName,
|
||||
DurabilityCorrection: w.DurabilityCorrection,
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Marshal encodes/decodes an ItemStackResponse.
|
||||
func (x *ItemStackResponse) Marshal(r protocol.IO) {
|
||||
r.Uint8(&x.Status)
|
||||
r.Varint32(&x.RequestID)
|
||||
if x.Status == ItemStackResponseStatusOK {
|
||||
protocol.Slice(r, &x.ContainerInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// StackResponseContainerInfo holds information on what slots in a container have what item stack in them.
|
||||
type StackResponseContainerInfo struct {
|
||||
// Container is the FullContainerName that describes the container that the slots that follow are in. For
|
||||
// the main inventory, the ContainerID seems to be 0x1b. Fur the cursor, this value seems to be 0x3a. For
|
||||
// the crafting grid, this value seems to be 0x0d.
|
||||
Container protocol.FullContainerName
|
||||
// SlotInfo holds information on what item stack should be present in specific slots in the container.
|
||||
SlotInfo []StackResponseSlotInfo
|
||||
}
|
||||
|
||||
// Marshal encodes/decodes a StackResponseContainerInfo.
|
||||
func (x *StackResponseContainerInfo) Marshal(r protocol.IO) {
|
||||
protocol.Single(r, &x.Container)
|
||||
protocol.Slice(r, &x.SlotInfo)
|
||||
}
|
||||
|
||||
// StackResponseSlotInfo holds information on what item stack should be present in a specific slot.
|
||||
type StackResponseSlotInfo struct {
|
||||
// Slot and HotbarSlot seem to be the same value every time: The slot that was actually changed. I'm not
|
||||
// sure if these slots ever differ.
|
||||
Slot, HotbarSlot byte
|
||||
// Count is the total count of the item stack. This count will be shown client-side after the response is
|
||||
// sent to the client.
|
||||
Count byte
|
||||
// StackNetworkID is the network ID of the new stack at a specific slot.
|
||||
StackNetworkID int32
|
||||
// CustomName is the custom name of the item stack. It is used in relation to text filtering.
|
||||
CustomName string
|
||||
// FilteredCustomName is a filtered version of CustomName with all the profanity removed. The client will
|
||||
// use this over CustomName if this field is not empty and they have the "Filter Profanity" setting enabled.
|
||||
FilteredCustomName string
|
||||
// DurabilityCorrection is the current durability of the item stack. This durability will be shown
|
||||
// client-side after the response is sent to the client.
|
||||
DurabilityCorrection int32
|
||||
}
|
||||
|
||||
// Marshal encodes/decodes a StackResponseSlotInfo.
|
||||
func (x *StackResponseSlotInfo) Marshal(r protocol.IO) {
|
||||
r.Uint8(&x.Slot)
|
||||
r.Uint8(&x.HotbarSlot)
|
||||
r.Uint8(&x.Count)
|
||||
r.Varint32(&x.StackNetworkID)
|
||||
if x.Slot != x.HotbarSlot {
|
||||
r.InvalidValue(x.HotbarSlot, "hotbar slot", "hot bar slot must be equal to normal slot")
|
||||
}
|
||||
r.String(&x.CustomName)
|
||||
if IsProtoGTE(r, ID766) {
|
||||
r.String(&x.FilteredCustomName)
|
||||
}
|
||||
r.Varint32(&x.DurabilityCorrection)
|
||||
}
|
||||
|
||||
// StackRequestAction represents a single action related to the inventory present in an ItemStackRequest.
|
||||
// The action is one of the concrete types below, each of which are indicative of a different action by the
|
||||
// client, such as moving an item around the inventory or placing a block. It is an alias of Marshaler.
|
||||
type StackRequestAction interface {
|
||||
protocol.Marshaler
|
||||
}
|
||||
|
||||
const (
|
||||
StackRequestActionTake = iota
|
||||
StackRequestActionPlace
|
||||
StackRequestActionSwap
|
||||
StackRequestActionDrop
|
||||
StackRequestActionDestroy
|
||||
StackRequestActionConsume
|
||||
StackRequestActionCreate
|
||||
StackRequestActionPlaceInContainer
|
||||
StackRequestActionTakeOutContainer
|
||||
StackRequestActionLabTableCombine
|
||||
StackRequestActionBeaconPayment
|
||||
StackRequestActionMineBlock
|
||||
StackRequestActionCraftRecipe
|
||||
StackRequestActionCraftRecipeAuto
|
||||
StackRequestActionCraftCreative
|
||||
StackRequestActionCraftRecipeOptional
|
||||
StackRequestActionCraftGrindstone
|
||||
StackRequestActionCraftLoom
|
||||
StackRequestActionCraftNonImplementedDeprecated
|
||||
StackRequestActionCraftResultsDeprecated
|
||||
)
|
||||
|
||||
// transferStackRequestAction is the structure shared by StackRequestActions that transfer items from one
|
||||
// slot into another.
|
||||
type transferStackRequestAction struct {
|
||||
// Count is the count of the item in the source slot that was taken towards the destination slot.
|
||||
Count byte
|
||||
// Source and Destination point to the source slot from which Count of the item stack were taken and the
|
||||
// destination slot to which this item was moved.
|
||||
Source, Destination StackRequestSlotInfo
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *transferStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Uint8(&a.Count)
|
||||
StackReqSlotInfo(r, &a.Source)
|
||||
StackReqSlotInfo(r, &a.Destination)
|
||||
}
|
||||
|
||||
// TakeStackRequestAction is sent by the client to the server to take x amount of items from one slot in a
|
||||
// container to the cursor.
|
||||
type TakeStackRequestAction struct {
|
||||
transferStackRequestAction
|
||||
}
|
||||
|
||||
// PlaceStackRequestAction is sent by the client to the server to place x amount of items from one slot into
|
||||
// another slot, such as when shift clicking an item in the inventory to move it around or when moving an item
|
||||
// in the cursor into a slot.
|
||||
type PlaceStackRequestAction struct {
|
||||
transferStackRequestAction
|
||||
}
|
||||
|
||||
// SwapStackRequestAction is sent by the client to swap the item in its cursor with an item present in another
|
||||
// container. The two item stacks swap places.
|
||||
type SwapStackRequestAction struct {
|
||||
// Source and Destination point to the source slot from which Count of the item stack were taken and the
|
||||
// destination slot to which this item was moved.
|
||||
Source, Destination StackRequestSlotInfo
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *SwapStackRequestAction) Marshal(r protocol.IO) {
|
||||
StackReqSlotInfo(r, &a.Source)
|
||||
StackReqSlotInfo(r, &a.Destination)
|
||||
}
|
||||
|
||||
// DropStackRequestAction is sent by the client when it drops an item out of the inventory when it has its
|
||||
// inventory opened. This action is not sent when a player drops an item out of the hotbar using the Q button
|
||||
// (or the equivalent on mobile). The InventoryTransaction packet is still used for that action, regardless of
|
||||
// whether the item stack network IDs are used or not.
|
||||
type DropStackRequestAction struct {
|
||||
// Count is the count of the item in the source slot that was taken towards the destination slot.
|
||||
Count byte
|
||||
// Source is the source slot from which items were dropped to the ground.
|
||||
Source StackRequestSlotInfo
|
||||
// Randomly seems to be set to false in most cases. I'm not entirely sure what this does, but this is what
|
||||
// vanilla calls this field.
|
||||
Randomly bool
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *DropStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Uint8(&a.Count)
|
||||
StackReqSlotInfo(r, &a.Source)
|
||||
r.Bool(&a.Randomly)
|
||||
}
|
||||
|
||||
// DestroyStackRequestAction is sent by the client when it destroys an item in creative mode by moving it
|
||||
// back into the creative inventory.
|
||||
type DestroyStackRequestAction struct {
|
||||
// Count is the count of the item in the source slot that was destroyed.
|
||||
Count byte
|
||||
// Source is the source slot from which items came that were destroyed by moving them into the creative
|
||||
// inventory.
|
||||
Source StackRequestSlotInfo
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *DestroyStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Uint8(&a.Count)
|
||||
StackReqSlotInfo(r, &a.Source)
|
||||
}
|
||||
|
||||
// ConsumeStackRequestAction is sent by the client when it uses an item to craft another item. The original
|
||||
// item is 'consumed'.
|
||||
type ConsumeStackRequestAction struct {
|
||||
DestroyStackRequestAction
|
||||
}
|
||||
|
||||
// CreateStackRequestAction is sent by the client when an item is created through being used as part of a
|
||||
// recipe. For example, when milk is used to craft a cake, the buckets are leftover. The buckets are moved to
|
||||
// the slot sent by the client here.
|
||||
// Note that before this is sent, an action for consuming all items in the crafting table/grid is sent. Items
|
||||
// that are not fully consumed when used for a recipe should not be destroyed there, but instead, should be
|
||||
// turned into their respective resulting items.
|
||||
type CreateStackRequestAction struct {
|
||||
// ResultsSlot is the slot in the inventory in which the results of the crafting ingredients are to be
|
||||
// placed.
|
||||
ResultsSlot byte
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *CreateStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Uint8(&a.ResultsSlot)
|
||||
}
|
||||
|
||||
// PlaceInContainerStackRequestAction currently has no known purpose.
|
||||
type PlaceInContainerStackRequestAction struct {
|
||||
transferStackRequestAction
|
||||
}
|
||||
|
||||
// TakeOutContainerStackRequestAction currently has no known purpose.
|
||||
type TakeOutContainerStackRequestAction struct {
|
||||
transferStackRequestAction
|
||||
}
|
||||
|
||||
// LabTableCombineStackRequestAction is sent by the client when it uses a lab table to combine item stacks.
|
||||
type LabTableCombineStackRequestAction struct{}
|
||||
|
||||
// Marshal ...
|
||||
func (a *LabTableCombineStackRequestAction) Marshal(protocol.IO) {}
|
||||
|
||||
// BeaconPaymentStackRequestAction is sent by the client when it submits an item to enable effects from a
|
||||
// beacon. These items will have been moved into the beacon item slot in advance.
|
||||
type BeaconPaymentStackRequestAction struct {
|
||||
// PrimaryEffect and SecondaryEffect are the effects that were selected from the beacon.
|
||||
PrimaryEffect, SecondaryEffect int32
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *BeaconPaymentStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varint32(&a.PrimaryEffect)
|
||||
r.Varint32(&a.SecondaryEffect)
|
||||
}
|
||||
|
||||
// MineBlockStackRequestAction is sent by the client when it breaks a block.
|
||||
type MineBlockStackRequestAction struct {
|
||||
// HotbarSlot is the slot held by the player while mining a block.
|
||||
HotbarSlot int32
|
||||
// PredictedDurability is the durability of the item that the client assumes to be present at the time.
|
||||
PredictedDurability int32
|
||||
// StackNetworkID is the unique stack ID that the client assumes to be present at the time. The server
|
||||
// must check if these IDs match. If they do not match, servers should reject the stack request that the
|
||||
// action holding this info was in.
|
||||
StackNetworkID int32
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *MineBlockStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varint32(&a.HotbarSlot)
|
||||
r.Varint32(&a.PredictedDurability)
|
||||
r.Varint32(&a.StackNetworkID)
|
||||
}
|
||||
|
||||
// CraftRecipeStackRequestAction is sent by the client the moment it begins crafting an item. This is the
|
||||
// first action sent, before the Consume and Create item stack request actions.
|
||||
// This action is also sent when an item is enchanted. Enchanting should be treated mostly the same way as
|
||||
// crafting, where the old item is consumed.
|
||||
type CraftRecipeStackRequestAction struct {
|
||||
// RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches
|
||||
// one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
|
||||
// of 1.16.
|
||||
RecipeNetworkID uint32
|
||||
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
|
||||
// has no effect.
|
||||
NumberOfCrafts byte
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *CraftRecipeStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varuint32(&a.RecipeNetworkID)
|
||||
r.Uint8(&a.NumberOfCrafts)
|
||||
}
|
||||
|
||||
// AutoCraftRecipeStackRequestAction is sent by the client similarly to the CraftRecipeStackRequestAction. The
|
||||
// only difference is that the recipe is automatically created and crafted by shift clicking the recipe book.
|
||||
type AutoCraftRecipeStackRequestAction struct {
|
||||
// RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches
|
||||
// one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
|
||||
// of 1.16.
|
||||
RecipeNetworkID uint32
|
||||
// NumberOfCrafts is how many times the recipe was crafted. This field is just a duplicate of TimesCrafted.
|
||||
NumberOfCrafts byte
|
||||
// TimesCrafted is how many times the recipe was crafted.
|
||||
TimesCrafted byte
|
||||
// Ingredients is a slice of ItemDescriptorCount that contains the ingredients that were used to craft the recipe.
|
||||
// It is not exactly clear what this is used for, but it is sent by the vanilla client.
|
||||
Ingredients []protocol.ItemDescriptorCount
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *AutoCraftRecipeStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varuint32(&a.RecipeNetworkID)
|
||||
r.Uint8(&a.NumberOfCrafts)
|
||||
r.Uint8(&a.TimesCrafted)
|
||||
protocol.FuncSlice(r, &a.Ingredients, r.ItemDescriptorCount)
|
||||
}
|
||||
|
||||
// CraftCreativeStackRequestAction is sent by the client when it takes an item out fo the creative inventory.
|
||||
// The item is thus not really crafted, but instantly created.
|
||||
type CraftCreativeStackRequestAction struct {
|
||||
// CreativeItemNetworkID is the network ID of the creative item that is being created. This is one of the
|
||||
// creative item network IDs sent in the CreativeContent packet.
|
||||
CreativeItemNetworkID uint32
|
||||
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
|
||||
// has no effect.
|
||||
NumberOfCrafts byte
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *CraftCreativeStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varuint32(&a.CreativeItemNetworkID)
|
||||
r.Uint8(&a.NumberOfCrafts)
|
||||
}
|
||||
|
||||
// CraftRecipeOptionalStackRequestAction is sent when using an anvil. When this action is sent, the
|
||||
// FilterStrings field in the respective stack request is non-empty and contains the name of the item created
|
||||
// using the anvil or cartography table.
|
||||
type CraftRecipeOptionalStackRequestAction struct {
|
||||
// RecipeNetworkID is the network ID of the multi-recipe that is about to be crafted. This network ID matches
|
||||
// one of the multi-recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
|
||||
// of 1.16.
|
||||
RecipeNetworkID uint32
|
||||
// FilterStringIndex is the index of a filter string sent in a ItemStackRequest.
|
||||
FilterStringIndex int32
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (c *CraftRecipeOptionalStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varuint32(&c.RecipeNetworkID)
|
||||
r.Int32(&c.FilterStringIndex)
|
||||
}
|
||||
|
||||
// CraftGrindstoneRecipeStackRequestAction is sent when a grindstone recipe is crafted. It contains the RecipeNetworkID
|
||||
// to identify the recipe crafted, and the cost for crafting the recipe.
|
||||
type CraftGrindstoneRecipeStackRequestAction struct {
|
||||
// RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches
|
||||
// one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as
|
||||
// of 1.16.
|
||||
RecipeNetworkID uint32
|
||||
// NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and
|
||||
// has no effect.
|
||||
NumberOfCrafts byte
|
||||
// Cost is the cost of the recipe that was crafted.
|
||||
Cost int32
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (c *CraftGrindstoneRecipeStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.Varuint32(&c.RecipeNetworkID)
|
||||
r.Uint8(&c.NumberOfCrafts)
|
||||
r.Varint32(&c.Cost)
|
||||
}
|
||||
|
||||
// CraftLoomRecipeStackRequestAction is sent when a loom recipe is crafted. It simply contains the
|
||||
// pattern identifier to figure out what pattern is meant to be applied to the item.
|
||||
type CraftLoomRecipeStackRequestAction struct {
|
||||
// Pattern is the pattern identifier for the loom recipe.
|
||||
Pattern string
|
||||
// TimesCrafted is how many times the recipe was crafted.
|
||||
TimesCrafted byte
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (c *CraftLoomRecipeStackRequestAction) Marshal(r protocol.IO) {
|
||||
r.String(&c.Pattern)
|
||||
r.Uint8(&c.TimesCrafted)
|
||||
}
|
||||
|
||||
// CraftNonImplementedStackRequestAction is an action sent for inventory actions that aren't yet implemented
|
||||
// in the new system. These include, for example, anvils.
|
||||
type CraftNonImplementedStackRequestAction struct{}
|
||||
|
||||
// Marshal ...
|
||||
func (*CraftNonImplementedStackRequestAction) Marshal(protocol.IO) {}
|
||||
|
||||
// CraftResultsDeprecatedStackRequestAction is an additional, deprecated packet sent by the client after
|
||||
// crafting. It holds the final results and the amount of times the recipe was crafted. It shouldn't be used.
|
||||
// This action is also sent when an item is enchanted. Enchanting should be treated mostly the same way as
|
||||
// crafting, where the old item is consumed.
|
||||
type CraftResultsDeprecatedStackRequestAction struct {
|
||||
ResultItems []protocol.ItemStack
|
||||
TimesCrafted byte
|
||||
}
|
||||
|
||||
// Marshal ...
|
||||
func (a *CraftResultsDeprecatedStackRequestAction) Marshal(r protocol.IO) {
|
||||
protocol.FuncSlice(r, &a.ResultItems, r.Item)
|
||||
r.Uint8(&a.TimesCrafted)
|
||||
}
|
||||
|
||||
// StackRequestSlotInfo holds information on a specific slot client-side.
|
||||
type StackRequestSlotInfo struct {
|
||||
// Container is the FullContainerName that describes the container that the slot is in.
|
||||
Container protocol.FullContainerName
|
||||
// Slot is the index of the slot within the container with the ContainerID above.
|
||||
Slot byte
|
||||
// StackNetworkID is the unique stack ID that the client assumes to be present in this slot. The server
|
||||
// must check if these IDs match. If they do not match, servers should reject the stack request that the
|
||||
// action holding this info was in.
|
||||
StackNetworkID int32
|
||||
}
|
||||
|
||||
// StackReqSlotInfo reads/writes a StackRequestSlotInfo x using IO r.
|
||||
func StackReqSlotInfo(r protocol.IO, x *StackRequestSlotInfo) {
|
||||
protocol.Single(r, &x.Container)
|
||||
r.Uint8(&x.Slot)
|
||||
r.Varint32(&x.StackNetworkID)
|
||||
}
|
||||
79
legacyver/proto/resource_pack.go
Normal file
79
legacyver/proto/resource_pack.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
)
|
||||
|
||||
// TexturePackInfo represents a texture pack's info sent over network. It holds information about the
|
||||
// texture pack such as its name, description and version.
|
||||
type TexturePackInfo struct {
|
||||
// UUID is the UUID of the texture pack. Each texture pack downloaded must have a different UUID in
|
||||
// order for the client to be able to handle them properly.
|
||||
UUID uuid.UUID
|
||||
// Version is the version of the texture pack. The client will cache texture packs sent by the server as
|
||||
// long as they carry the same version. Sending a texture pack with a different version than previously
|
||||
// will force the client to re-download it.
|
||||
Version string
|
||||
// Size is the total size in bytes that the texture pack occupies. This is the size of the compressed
|
||||
// archive (zip) of the texture pack.
|
||||
Size uint64
|
||||
// ContentKey is the key used to decrypt the behaviour pack if it is encrypted. This is generally the case
|
||||
// for marketplace texture packs.
|
||||
ContentKey string
|
||||
// SubPackName ...
|
||||
SubPackName string
|
||||
// ContentIdentity is another UUID for the resource pack, and is generally set for marketplace texture
|
||||
// packs. It is also required for client-side validations when the resource pack is encrypted.
|
||||
ContentIdentity string
|
||||
// HasScripts specifies if the texture packs has any scripts in it. A client will only download the
|
||||
// behaviour pack if it supports scripts, which, up to 1.11, only includes Windows 10.
|
||||
HasScripts bool
|
||||
// AddonPack specifies if the texture pack is from an addon.
|
||||
AddonPack bool
|
||||
// RTXEnabled specifies if the texture pack uses the raytracing technology introduced in 1.16.200.
|
||||
RTXEnabled bool
|
||||
// DownloadURL is a URL that the client can use to download the pack instead of the server sending it in
|
||||
// chunks, which it will continue to do if this field is left empty.
|
||||
DownloadURL string
|
||||
}
|
||||
|
||||
func (x *TexturePackInfo) ToLatest() protocol.TexturePackInfo {
|
||||
return protocol.TexturePackInfo{
|
||||
UUID: x.UUID,
|
||||
Version: x.Version,
|
||||
Size: x.Size,
|
||||
ContentKey: x.ContentKey,
|
||||
SubPackName: x.SubPackName,
|
||||
ContentIdentity: x.ContentIdentity,
|
||||
HasScripts: x.HasScripts,
|
||||
AddonPack: x.AddonPack,
|
||||
RTXEnabled: x.RTXEnabled,
|
||||
DownloadURL: x.DownloadURL,
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal encodes/decodes a TexturePackInfo.
|
||||
func (x *TexturePackInfo) Marshal(r protocol.IO) {
|
||||
if IsProtoGTE(r, ID766) {
|
||||
r.UUID(&x.UUID)
|
||||
} else {
|
||||
if IsReader(r) {
|
||||
uuidStr := ""
|
||||
r.String(&uuidStr)
|
||||
x.UUID = uuid.MustParse(uuidStr)
|
||||
} else {
|
||||
uuidStr := x.UUID.String()
|
||||
r.String(&uuidStr)
|
||||
}
|
||||
}
|
||||
r.String(&x.Version)
|
||||
r.Uint64(&x.Size)
|
||||
r.String(&x.ContentKey)
|
||||
r.String(&x.SubPackName)
|
||||
r.String(&x.ContentIdentity)
|
||||
r.Bool(&x.HasScripts)
|
||||
r.Bool(&x.AddonPack)
|
||||
r.Bool(&x.RTXEnabled)
|
||||
r.String(&x.DownloadURL)
|
||||
}
|
||||
5
legacyver/proto/type.go
Normal file
5
legacyver/proto/type.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package proto
|
||||
|
||||
type legacyType struct {
|
||||
ProtocolID int32
|
||||
}
|
||||
Reference in New Issue
Block a user