Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for v1.19.10 #136

Merged
merged 6 commits into from Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.mod
Expand Up @@ -6,6 +6,7 @@ require (
github.com/go-gl/mathgl v1.0.0
github.com/google/uuid v1.3.0
github.com/klauspost/compress v1.15.1
github.com/kr/pretty v0.1.0
github.com/muhammadmuzzammil1998/jsonc v1.0.0
github.com/pelletier/go-toml v1.9.4
github.com/sandertv/go-raknet v1.10.9
Expand All @@ -19,6 +20,7 @@ require (
require (
github.com/df-mc/atomic v1.10.0 // indirect
github.com/golang/protobuf v1.4.2 // indirect
github.com/kr/text v0.1.0 // indirect
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect
google.golang.org/appengine v1.6.6 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -110,8 +110,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/muhammadmuzzammil1998/jsonc v1.0.0 h1:8o5gBQn4ZA3NBA9DlTujCj2a4w0tqWrPVjDwhzkgTIs=
github.com/muhammadmuzzammil1998/jsonc v1.0.0/go.mod h1:saF2fIVw4banK0H4+/EuqfFLpRnoy5S+ECwTOCcRcSU=
Expand Down
8 changes: 8 additions & 0 deletions minecraft/conn.go
Expand Up @@ -944,6 +944,7 @@ func (conn *Conn) startGame() {
Yaw: data.Yaw,
Dimension: data.Dimension,
WorldSpawn: data.WorldSpawn,
EditorWorld: data.EditorWorld,
GameRules: data.GameRules,
Time: data.Time,
Blocks: data.CustomBlocks,
Expand Down Expand Up @@ -1132,6 +1133,7 @@ func (conn *Conn) handleStartGame(pk *packet.StartGame) error {
Yaw: pk.Yaw,
Dimension: pk.Dimension,
WorldSpawn: pk.WorldSpawn,
EditorWorld: pk.EditorWorld,
GameRules: pk.GameRules,
Time: pk.Time,
ServerBlockStateChecksum: pk.ServerBlockStateChecksum,
Expand Down Expand Up @@ -1243,6 +1245,12 @@ func (conn *Conn) handlePlayStatus(pk *packet.PlayStatus) error {
case packet.PlayStatusLoginFailedServerFull:
_ = conn.Close()
return fmt.Errorf("server full")
case packet.PlayStatusLoginFailedEditorVanilla:
_ = conn.Close()
return fmt.Errorf("cannot join a vanilla game on editor")
case packet.PlayStatusLoginFailedVanillaEditor:
_ = conn.Close()
return fmt.Errorf("cannot join an editor game on vanilla")
default:
return fmt.Errorf("unknown play status in PlayStatus packet %v", pk.Status)
}
Expand Down
3 changes: 3 additions & 0 deletions minecraft/game_data.go
Expand Up @@ -46,6 +46,9 @@ type GameData struct {
// WorldSpawn is the block on which the world spawn of the world. This coordinate has no effect on the
// place that the client spawns, but it does have an effect on the direction that a compass points.
WorldSpawn protocol.BlockPos
// EditorWorld is a value to dictate if the world is in editor mode, a special mode recently introduced adding
// "powerful tools for editing worlds, intended for experienced creators."
EditorWorld bool
// WorldGameMode is the game mode that a player gets when it first spawns in the world. It is shown in the
// settings and is used if the PlayerGameMode is set to 5.
WorldGameMode int32
Expand Down
60 changes: 60 additions & 0 deletions minecraft/protocol/ability.go
@@ -0,0 +1,60 @@
package protocol

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

const (
AbilityLayerTypeCustomCache = iota
AbilityLayerTypeBase
AbilityLayerTypeSpectator
AbilityLayerTypeCommands
)

const (
AbilityBaseFlySpeed = 0.05
AbilityBaseWalkSpeed = 0.1
)

// AbilityLayer represents the abilities of a specific layer, such as the base layer or the spectator layer.
type AbilityLayer struct {
// Type represents the type of the layer. This is one of the AbilityLayerType constants defined above.
Type uint16
// Abilities is a set of abilities that are enabled for the layer. This is one of the Ability constants defined
// above.
Abilities uint32
// Values is a set of values that are associated with the enabled abilities, representing the values of the
// abilities.
Values uint32
// FlySpeed is the default fly speed of the layer.
FlySpeed float32
// WalkSpeed is the default walk speed of the layer.
WalkSpeed float32
}

// SerializedLayer reads/writes a AbilityLayer x using IO r.
func SerializedLayer(r IO, x *AbilityLayer) {
r.Uint16(&x.Type)
r.Uint32(&x.Abilities)
r.Uint32(&x.Values)
r.Float32(&x.FlySpeed)
r.Float32(&x.WalkSpeed)
}
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 = 527
CurrentProtocol = 534
// CurrentVersion is the current version of Minecraft as supported by the `packet` package.
CurrentVersion = "1.19.0"
CurrentVersion = "1.19.10"
)
1 change: 1 addition & 0 deletions minecraft/protocol/packet/actor_event.go
Expand Up @@ -68,6 +68,7 @@ const (
ActorEventLandedOnGround
ActorEventActorGrowUp
ActorEventVibrationDetected
ActorEventDrinkMilk
)

// ActorEvent is sent by the server when a particular event happens that has to do with an entity. Some of
Expand Down
10 changes: 8 additions & 2 deletions minecraft/protocol/packet/add_actor.go
Expand Up @@ -29,9 +29,13 @@ type AddActor struct {
Pitch float32
// Yaw is the horizontal rotation of the entity. Yaw is also measured in degrees.
Yaw float32
// HeadYaw is the same as Yaw, except that it applies specifically to the head of the entity. A different
// value for HeadYaw than Yaw means that the entity will have its head turned.
// HeadYaw is the same as Yaw, except that it applies specifically to the head of the entity. A different value for
// HeadYaw than Yaw means that the entity will have its head turned.
HeadYaw float32
// BodyYaw is the same as Yaw, except that it applies specifically to the body of the entity. A different value for
// BodyYaw than HeadYaw means that the entity will have its body turned, although it is unclear what the difference
// between BodyYaw and Yaw is.
BodyYaw float32
// Attributes is a slice of attributes that the entity has. It includes attributes such as its health,
// movement speed, etc.
Attributes []protocol.Attribute
Expand Down Expand Up @@ -60,6 +64,7 @@ func (pk *AddActor) Marshal(w *protocol.Writer) {
w.Float32(&pk.Pitch)
w.Float32(&pk.Yaw)
w.Float32(&pk.HeadYaw)
w.Float32(&pk.BodyYaw)
protocol.WriteInitialAttributes(w, &pk.Attributes)
w.EntityMetadata(&pk.EntityMetadata)
protocol.WriteEntityLinks(w, &pk.EntityLinks)
Expand All @@ -75,6 +80,7 @@ func (pk *AddActor) Unmarshal(r *protocol.Reader) {
r.Float32(&pk.Pitch)
r.Float32(&pk.Yaw)
r.Float32(&pk.HeadYaw)
r.Float32(&pk.BodyYaw)
protocol.InitialAttributes(r, &pk.Attributes)
r.EntityMetadata(&pk.EntityMetadata)
protocol.EntityLinks(r, &pk.EntityLinks)
Expand Down
60 changes: 27 additions & 33 deletions minecraft/protocol/packet/add_player.go
Expand Up @@ -16,10 +16,6 @@ type AddPlayer struct {
// Username is the name of the player. This username is the username that will be set as the initial
// name tag of the player.
Username string
// EntityUniqueID is the unique ID of the player. The unique ID is a value that remains consistent across
// different sessions of the same world, but most servers simply fill the runtime ID of the player out for
// this field.
EntityUniqueID int64
// EntityRuntimeID is the runtime ID of the player. The runtime ID is unique for each world session, and
// entities are generally identified in packets using this runtime ID.
EntityRuntimeID uint64
Expand Down Expand Up @@ -51,22 +47,17 @@ type AddPlayer struct {
// particular the way the player looks. Flags include ones such as 'on fire' and 'sprinting'.
// The metadata values are indexed by their property key.
EntityMetadata map[uint32]any
// Flags is a set of flags that specify certain properties of the player, such as whether it can
// fly and/or move through blocks.
Flags uint32
// CommandPermissionLevel is a set of permissions that specify what commands a player is allowed to execute.
CommandPermissionLevel uint32
// ActionPermissions is, much like Flags, a set of flags that specify actions that the player is allowed
// to undertake, such as whether it is allowed to edit blocks, open doors etc.
ActionPermissions uint32
// PermissionLevel is the permission level of the player as it shows up in the player list built up using
// the PlayerList packet.
PermissionLevel uint32
// CustomStoredPermissions ...
CustomStoredPermissions uint32
// PlayerUniqueID is a unique identifier of the player. It appears it is not required to fill this field
// EntityUniqueID is a unique identifier of the player. It appears it is not required to fill this field
// out with a correct value. Simply writing 0 seems to work.
PlayerUniqueID int64
EntityUniqueID int64
// PlayerPermissions is the permission level of the player as it shows up in the player list built up using
// the PlayerList packet.
PlayerPermissions byte
// CommandPermissions is a set of permissions that specify what commands a player is allowed to execute.
CommandPermissions byte
// Layers contains all ability layers and their potential values. This should at least have one entry, being the
// base layer.
Layers []protocol.AbilityLayer
// EntityLinks is a list of entity links that are currently active on the player. These links alter the
// way the player shows up when first spawned in terms of it shown as riding an entity. Setting these
// links is important for new viewers to see the player is riding another entity.
Expand All @@ -88,7 +79,6 @@ func (*AddPlayer) ID() uint32 {
func (pk *AddPlayer) Marshal(w *protocol.Writer) {
w.UUID(&pk.UUID)
w.String(&pk.Username)
w.Varint64(&pk.EntityUniqueID)
w.Varuint64(&pk.EntityRuntimeID)
w.String(&pk.PlatformChatID)
w.Vec3(&pk.Position)
Expand All @@ -99,12 +89,14 @@ func (pk *AddPlayer) Marshal(w *protocol.Writer) {
w.ItemInstance(&pk.HeldItem)
w.Varint32(&pk.GameType)
w.EntityMetadata(&pk.EntityMetadata)
w.Varuint32(&pk.Flags)
w.Varuint32(&pk.CommandPermissionLevel)
w.Varuint32(&pk.ActionPermissions)
w.Varuint32(&pk.PermissionLevel)
w.Varuint32(&pk.CustomStoredPermissions)
w.Int64(&pk.PlayerUniqueID)
w.Int64(&pk.EntityUniqueID)
w.Uint8(&pk.PlayerPermissions)
w.Uint8(&pk.CommandPermissions)
layersLen := uint8(len(pk.Layers))
w.Uint8(&layersLen)
for _, layer := range pk.Layers {
protocol.SerializedLayer(w, &layer)
}
protocol.WriteEntityLinks(w, &pk.EntityLinks)
w.String(&pk.DeviceID)
w.Int32(&pk.BuildPlatform)
Expand All @@ -114,7 +106,6 @@ func (pk *AddPlayer) Marshal(w *protocol.Writer) {
func (pk *AddPlayer) Unmarshal(r *protocol.Reader) {
r.UUID(&pk.UUID)
r.String(&pk.Username)
r.Varint64(&pk.EntityUniqueID)
r.Varuint64(&pk.EntityRuntimeID)
r.String(&pk.PlatformChatID)
r.Vec3(&pk.Position)
Expand All @@ -125,12 +116,15 @@ func (pk *AddPlayer) Unmarshal(r *protocol.Reader) {
r.ItemInstance(&pk.HeldItem)
r.Varint32(&pk.GameType)
r.EntityMetadata(&pk.EntityMetadata)
r.Varuint32(&pk.Flags)
r.Varuint32(&pk.CommandPermissionLevel)
r.Varuint32(&pk.ActionPermissions)
r.Varuint32(&pk.PermissionLevel)
r.Varuint32(&pk.CustomStoredPermissions)
r.Int64(&pk.PlayerUniqueID)
r.Int64(&pk.EntityUniqueID)
r.Uint8(&pk.PlayerPermissions)
r.Uint8(&pk.CommandPermissions)
var layersLen uint8
r.Uint8(&layersLen)
pk.Layers = make([]protocol.AbilityLayer, layersLen)
for i := uint8(0); i < layersLen; i++ {
protocol.SerializedLayer(r, &pk.Layers[i])
}
protocol.EntityLinks(r, &pk.EntityLinks)
r.String(&pk.DeviceID)
r.Int32(&pk.BuildPlatform)
Expand Down
40 changes: 40 additions & 0 deletions minecraft/protocol/packet/death_info.go
@@ -0,0 +1,40 @@
package packet

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

// DeathInfo is a packet sent from the server to the client expected to be sent when a player dies. It contains messages
// related to the player's death, which are shown on the death screen as of v1.19.10.
type DeathInfo struct {
// Cause is the cause of the player's death, such as "suffocation" or "suicide".
Cause string
// Messages is a list of death messages to be shown on the death screen.
Messages []string
}

// ID ...
func (*DeathInfo) ID() uint32 {
return IDDeathInfo
}

// Marshal ...
func (pk *DeathInfo) Marshal(w *protocol.Writer) {
w.String(&pk.Cause)
messageLen := uint32(len(pk.Messages))
w.Varuint32(&messageLen)
for _, message := range pk.Messages {
w.String(&message)
}
}

// Unmarshal ...
func (pk *DeathInfo) Unmarshal(r *protocol.Reader) {
r.String(&pk.Cause)
var messageLen uint32
r.Varuint32(&messageLen)
pk.Messages = make([]string, messageLen)
for i := uint32(0); i < messageLen; i++ {
r.String(&pk.Messages[i])
}
}
28 changes: 28 additions & 0 deletions minecraft/protocol/packet/editor_network.go
@@ -0,0 +1,28 @@
package packet

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

// EditorNetwork is a packet sent from the server to the client and vise-versa to communicate editor-mode related
// information. It carries a single compound tag containing the relevant information.
type EditorNetwork struct {
// Payload is a network little endian compound tag holding data relevant to the editor.
Payload map[string]any
}

// ID ...
func (*EditorNetwork) ID() uint32 {
return IDEditorNetwork
}

// Marshal ...
func (pk *EditorNetwork) Marshal(w *protocol.Writer) {
w.NBT(&pk.Payload, nbt.NetworkLittleEndian)
}

// Unmarshal ...
func (pk *EditorNetwork) Unmarshal(r *protocol.Reader) {
r.NBT(&pk.Payload, nbt.NetworkLittleEndian)
}
4 changes: 4 additions & 0 deletions minecraft/protocol/packet/id.go
Expand Up @@ -187,4 +187,8 @@ const (
IDRequestAbility
IDRequestPermissions
IDToastRequest
IDUpdateAbilities
IDUpdateAdventureSettings
IDDeathInfo
IDEditorNetwork
)