Skip to content

Commit

Permalink
Implement 1.19 support (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustTalDevelops committed Jun 7, 2022
1 parent 8a310b2 commit 56ec96a
Show file tree
Hide file tree
Showing 16 changed files with 258 additions and 15 deletions.
20 changes: 10 additions & 10 deletions minecraft/protocol/command.go
Expand Up @@ -47,16 +47,16 @@ const (
CommandArgTypeValue = 4
CommandArgTypeWildcardInt = 5
CommandArgTypeOperator = 6
CommandArgTypeTarget = 7
CommandArgTypeWildcardTarget = 9
CommandArgTypeFilepath = 16
CommandArgTypeString = 38
CommandArgTypeBlockPosition = 46
CommandArgTypePosition = 47
CommandArgTypeMessage = 50
CommandArgTypeRawText = 52
CommandArgTypeJSON = 56
CommandArgTypeCommand = 69
CommandArgTypeTarget = 8
CommandArgTypeWildcardTarget = 10
CommandArgTypeFilepath = 17
CommandArgTypeString = 39
CommandArgTypeBlockPosition = 47
CommandArgTypePosition = 48
CommandArgTypeMessage = 51
CommandArgTypeRawText = 53
CommandArgTypeJSON = 57
CommandArgTypeCommand = 70
)
const (
// ParamOptionCollapseEnum specifies if the enum (only if the Type is actually an enum type. If not,
Expand Down
4 changes: 2 additions & 2 deletions minecraft/protocol/events.go
Expand Up @@ -228,7 +228,7 @@ func (a *AgentCommandEventData) Unmarshal(r *Reader) {
r.String(&a.Output)
}

// PatternRemovedEventData is the event data sent when a pattern is removed.
// PatternRemovedEventData is the event data sent when a pattern is removed. This is now deprecated.
type PatternRemovedEventData struct {
// ItemID ...
ItemID int32
Expand Down Expand Up @@ -346,7 +346,7 @@ func (m *MobBornEventData) Unmarshal(r *Reader) {
r.Uint8(&m.Colour)
}

// PetDiedEventData is the event data sent when a pet dies.
// PetDiedEventData is the event data sent when a pet dies. This is now deprecated.
type PetDiedEventData struct {
// KilledByOwner ...
KilledByOwner bool
Expand Down
4 changes: 2 additions & 2 deletions minecraft/protocol/info.go
Expand Up @@ -2,7 +2,7 @@ package protocol

const (
// CurrentProtocol is the current protocol version for the version below.
CurrentProtocol = 503
CurrentProtocol = 527
// CurrentVersion is the current version of Minecraft as supported by the `packet` package.
CurrentVersion = "1.18.30"
CurrentVersion = "1.19.0"
)
1 change: 1 addition & 0 deletions minecraft/protocol/os.go
Expand Up @@ -19,4 +19,5 @@ const (
DeviceNX
DeviceXBOX
DeviceWP
DeviceLinux
)
4 changes: 4 additions & 0 deletions minecraft/protocol/packet/id.go
Expand Up @@ -183,4 +183,8 @@ const (
IDDimensionData
IDAgentAction
IDChangeMobProperty
IDLessonProgress
IDRequestAbility
IDRequestPermissions
IDToastRequest
)
41 changes: 41 additions & 0 deletions minecraft/protocol/packet/lesson_progress.go
@@ -0,0 +1,41 @@
package packet

import (
"github.com/sandertv/gophertunnel/minecraft/protocol"
)

const (
LessonActionStart = iota
LessonActionComplete
LessonActionRestart
)

// LessonProgress is a packet sent by the server to the client to inform the client of updated progress on a lesson.
// This packet only functions on the Minecraft: Education Edition version of the game.
type LessonProgress struct {
// Identifier is the identifier of the lesson that is being progressed.
Identifier string
// Action is the action the client should perform to show progress. This is one of the constants defined above.
Action uint8
// Score is the score the client should use when displaying the progress.
Score int32
}

// ID ...
func (*LessonProgress) ID() uint32 {
return IDLessonProgress
}

// Marshal ...
func (pk *LessonProgress) Marshal(w *protocol.Writer) {
w.Uint8(&pk.Action)
w.Varint32(&pk.Score)
w.String(&pk.Identifier)
}

// Unmarshal ...
func (pk *LessonProgress) Unmarshal(r *protocol.Reader) {
r.Uint8(&pk.Action)
r.Varint32(&pk.Score)
r.String(&pk.Identifier)
}
1 change: 1 addition & 0 deletions minecraft/protocol/packet/level_event.go
Expand Up @@ -85,6 +85,7 @@ const (
LevelEventSculkCatalystBloom = 2036
LevelEventSculkCharge = 2037
LevelEventSculkChargePop = 2038
LevelEventSonicExplosion = 2039
LevelEventStartRaining = 3001
LevelEventStartThunderstorm = 3002
LevelEventStopRaining = 3003
Expand Down
20 changes: 19 additions & 1 deletion minecraft/protocol/packet/level_sound_event.go
Expand Up @@ -385,7 +385,7 @@ const (
SoundEventListening
SoundEventHeartbeat
SoundEventHornBreak
SoundEventSculkPlace
_
SoundEventSculkSpread
SoundEventSculkCharge
SoundEventSculkSensorPlace
Expand Down Expand Up @@ -430,6 +430,24 @@ const (
SoundEventGoatBass7
SoundEventGoatBass8
SoundEventGoatBass9
_
_
_
SoundEventImitateWarden
SoundEventListeningAngry
SoundEventItemGiven
SoundEventItemTaken
SoundEventDisappeared
SoundEventReappeared
_
SoundEventFrogspawnHatched
SoundEventLaySpawn
SoundEventFrogspawnBreak
SoundEventSonicBoom
SoundEventSonicCharge
SoundeventItemThrown
SoundEventRecord5
SoundEventConvertToFrog
SoundEventUndefined
)

Expand Down
5 changes: 5 additions & 0 deletions minecraft/protocol/packet/player_action.go
Expand Up @@ -16,6 +16,9 @@ type PlayerAction struct {
// BlockPosition is the position of the target block, if the action with the ActionType set concerned a
// block. If that is not the case, the block position will be zero.
BlockPosition protocol.BlockPos
// ResultPosition is the position of the action's result. When a UseItemOn action is sent, this is the position of
// the block clicked, but when a block is placed, this is the position at which the block will be placed.
ResultPosition protocol.BlockPos
// BlockFace is the face of the target block that was touched. If the action with the ActionType set
// concerned a block. If not, the face is always 0.
BlockFace int32
Expand All @@ -31,6 +34,7 @@ func (pk *PlayerAction) Marshal(w *protocol.Writer) {
w.Varuint64(&pk.EntityRuntimeID)
w.Varint32(&pk.ActionType)
w.UBlockPos(&pk.BlockPosition)
w.UBlockPos(&pk.ResultPosition)
w.Varint32(&pk.BlockFace)
}

Expand All @@ -39,5 +43,6 @@ func (pk *PlayerAction) Unmarshal(r *protocol.Reader) {
r.Varuint64(&pk.EntityRuntimeID)
r.Varint32(&pk.ActionType)
r.UBlockPos(&pk.BlockPosition)
r.UBlockPos(&pk.ResultPosition)
r.Varint32(&pk.BlockFace)
}
11 changes: 11 additions & 0 deletions minecraft/protocol/packet/player_auth_input.go
Expand Up @@ -65,6 +65,12 @@ const (
PlayModeNumModes
)

const (
InteractionModelTouch = iota
InteractionModelCrosshair
InteractionModelClassic
)

// PlayerAuthInput is sent by the client to allow for server authoritative movement. It is used to synchronise
// the player input with the position server-side.
// The client sends this packet when the ServerAuthoritativeMovementMode field in the StartGame packet is set
Expand All @@ -88,6 +94,9 @@ type PlayerAuthInput struct {
// PlayMode specifies the way that the player is playing. The values it holds, which are rather random,
// may be found above.
PlayMode uint32
// InteractionModel is a constant representing the interaction model the player is using. It is one of the
// constants that may be found above.
InteractionModel int32
// GazeDirection is the direction in which the player is gazing, when the PlayMode is PlayModeReality: In
// other words, when the player is playing in virtual reality.
GazeDirection mgl32.Vec3
Expand Down Expand Up @@ -120,6 +129,7 @@ func (pk *PlayerAuthInput) Marshal(w *protocol.Writer) {
w.Varuint64(&pk.InputData)
w.Varuint32(&pk.InputMode)
w.Varuint32(&pk.PlayMode)
w.Varint32(&pk.InteractionModel)
if pk.PlayMode == PlayModeReality {
w.Vec3(&pk.GazeDirection)
}
Expand Down Expand Up @@ -153,6 +163,7 @@ func (pk *PlayerAuthInput) Unmarshal(r *protocol.Reader) {
r.Varuint64(&pk.InputData)
r.Varuint32(&pk.InputMode)
r.Varuint32(&pk.PlayMode)
r.Varint32(&pk.InteractionModel)
if pk.PlayMode == PlayModeReality {
r.Vec3(&pk.GazeDirection)
}
Expand Down
4 changes: 4 additions & 0 deletions minecraft/protocol/packet/pool.go
Expand Up @@ -206,6 +206,10 @@ func init() {
IDDimensionData: func() Packet { return &DimensionData{} },
IDAgentAction: func() Packet { return &AgentAction{} },
IDChangeMobProperty: func() Packet { return &ChangeMobProperty{} },
IDLessonProgress: func() Packet { return &LessonProgress{} },
IDRequestAbility: func() Packet { return &RequestAbility{} },
IDRequestPermissions: func() Packet { return &RequestPermissions{} },
IDToastRequest: func() Packet { return &ToastRequest{} },
}
for id, pk := range packets {
Register(id, pk)
Expand Down
78 changes: 78 additions & 0 deletions minecraft/protocol/packet/request_ability.go
@@ -0,0 +1,78 @@
package packet

import (
"github.com/sandertv/gophertunnel/minecraft/protocol"
)

const (
AbilityBuild = iota
AbilityMine
AbilityDoorsAndSwitches
AbilityOpenContainers
AbilityAttackPlayers
AbilityAttackMobs
AbilityOperatorCommands
AbilityTeleport
AbilityInvulnerable
AbilityFlying
AbilityMayFly
AbilityInstantBuild
AbilityLightning
AbilityFlySpeed
AbilityWalkSpeed
AbilityMuted
AbilityWorldBuilder
AbilityNoClip
AbilityAbilityCount
)

// RequestAbility is a packet sent by the client to the server to request permission for a specific ability from the
// server. These abilities are defined above.
type RequestAbility struct {
// Ability is the ability that the client is requesting. This is one of the constants defined above.
Ability int32
// Value represents the value of the ability. This can either be a boolean or a float32, otherwise the writer/reader
// will panic.
Value any
}

// ID ...
func (*RequestAbility) ID() uint32 {
return IDRequestAbility
}

// Marshal ...
func (pk *RequestAbility) Marshal(w *protocol.Writer) {
w.Varint32(&pk.Ability)
switch val := pk.Value.(type) {
case bool:
valType, defaultVal := uint8(1), float32(0)
w.Uint8(&valType)
w.Bool(&val)
w.Float32(&defaultVal)
case float32:
valType, defaultVal := uint8(2), false
w.Uint8(&valType)
w.Bool(&defaultVal)
w.Float32(&val)
default:
w.InvalidValue(pk.Value, "ability value type", "must be bool or float32")
}
}

// Unmarshal ...
func (pk *RequestAbility) Unmarshal(r *protocol.Reader) {
valType, boolVal, floatVal := uint8(0), false, float32(0)
r.Varint32(&pk.Ability)
r.Uint8(&valType)
r.Bool(&boolVal)
r.Float32(&floatVal)
switch valType {
case 1:
pk.Value = boolVal
case 2:
pk.Value = floatVal
default:
r.InvalidValue(valType, "ability value type", "must be bool or float32")
}
}
37 changes: 37 additions & 0 deletions minecraft/protocol/packet/request_permissions.go
@@ -0,0 +1,37 @@
package packet

import (
"github.com/sandertv/gophertunnel/minecraft/protocol"
)

// RequestPermissions is a packet sent from the client to the server to request permissions that the client does not
// currently have. It can only be sent by operators and host in vanilla Minecraft.
type RequestPermissions struct {
// EntityUniqueID is the unique ID of the player. The unique ID is unique for the entire world and is
// often used in packets. Most servers send an EntityUniqueID equal to the EntityRuntimeID.
EntityUniqueID int64
// PermissionLevel is the current permission level of the player. This is one of the constants that may be found
// in the AdventureSettings packet.
PermissionLevel uint8
// RequestedPermissions contains the requested permission flags.
RequestedPermissions uint16
}

// ID ...
func (*RequestPermissions) ID() uint32 {
return IDRequestPermissions
}

// Marshal ...
func (pk *RequestPermissions) Marshal(w *protocol.Writer) {
w.Int64(&pk.EntityUniqueID)
w.Uint8(&pk.PermissionLevel)
w.Uint16(&pk.RequestedPermissions)
}

// Unmarshal ...
func (pk *RequestPermissions) Unmarshal(r *protocol.Reader) {
r.Int64(&pk.EntityUniqueID)
r.Uint8(&pk.PermissionLevel)
r.Uint16(&pk.RequestedPermissions)
}
12 changes: 12 additions & 0 deletions minecraft/protocol/packet/start_game.go
Expand Up @@ -2,6 +2,8 @@ package packet

import (
"github.com/go-gl/mathgl/mgl32"
"github.com/google/uuid"
"github.com/sandertv/gophertunnel/minecraft/nbt"
"github.com/sandertv/gophertunnel/minecraft/protocol"
)

Expand Down Expand Up @@ -194,9 +196,15 @@ type StartGame struct {
ServerAuthoritativeInventory bool
// GameVersion is the version of the game the server is running. The exact function of this field isn't clear.
GameVersion string
// PropertyData contains properties that should be applied on the player. These properties are the same as the
// ones that are sent in the SyncActorProperty packet.
PropertyData map[string]any
// ServerBlockStateChecksum is a checksum to ensure block states between the server and client match.
// This can simply be left empty, and the client will avoid trying to verify it.
ServerBlockStateChecksum uint64
// WorldTemplateID is a UUID that identifies the template that was used to generate the world. Servers that do not
// use a world based off of a template can set this to an empty UUID.
WorldTemplateID uuid.UUID
}

// ID ...
Expand Down Expand Up @@ -285,7 +293,9 @@ func (pk *StartGame) Marshal(w *protocol.Writer) {
w.String(&pk.MultiPlayerCorrelationID)
w.Bool(&pk.ServerAuthoritativeInventory)
w.String(&pk.GameVersion)
w.NBT(&pk.PropertyData, nbt.NetworkLittleEndian)
w.Uint64(&pk.ServerBlockStateChecksum)
w.UUID(&pk.WorldTemplateID)
}

// Unmarshal ...
Expand Down Expand Up @@ -371,5 +381,7 @@ func (pk *StartGame) Unmarshal(r *protocol.Reader) {
r.String(&pk.MultiPlayerCorrelationID)
r.Bool(&pk.ServerAuthoritativeInventory)
r.String(&pk.GameVersion)
r.NBT(&pk.PropertyData, nbt.NetworkLittleEndian)
r.Uint64(&pk.ServerBlockStateChecksum)
r.UUID(&pk.WorldTemplateID)
}

0 comments on commit 56ec96a

Please sign in to comment.