Skip to content

Commit

Permalink
Support for 1.19.80 (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
TwistedAsylumMC committed Apr 29, 2023
1 parent 272313d commit f10711f
Show file tree
Hide file tree
Showing 22 changed files with 348 additions and 21 deletions.
4 changes: 4 additions & 0 deletions minecraft/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,8 @@ func (conn *Conn) startGame() {
Dimension: data.Dimension,
WorldSpawn: data.WorldSpawn,
EditorWorld: data.EditorWorld,
CreatedInEditor: data.CreatedInEditor,
ExportedFromEditor: data.ExportedFromEditor,
PersonaDisabled: data.PersonaDisabled,
CustomSkinsDisabled: data.CustomSkinsDisabled,
GameRules: data.GameRules,
Expand Down Expand Up @@ -1205,6 +1207,8 @@ func (conn *Conn) handleStartGame(pk *packet.StartGame) error {
Dimension: pk.Dimension,
WorldSpawn: pk.WorldSpawn,
EditorWorld: pk.EditorWorld,
CreatedInEditor: pk.CreatedInEditor,
ExportedFromEditor: pk.ExportedFromEditor,
PersonaDisabled: pk.PersonaDisabled,
CustomSkinsDisabled: pk.CustomSkinsDisabled,
GameRules: pk.GameRules,
Expand Down
6 changes: 6 additions & 0 deletions minecraft/game_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ type GameData struct {
// 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
// CreatedInEditor is a value to dictate if the world was created as a project in the editor mode. The functionality
// of this field is currently unknown.
CreatedInEditor bool
// ExportedFromEditor is a value to dictate if the world was exported from editor mode. The functionality of this
// field is currently unknown.
ExportedFromEditor 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
18 changes: 9 additions & 9 deletions minecraft/protocol/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ const (
CommandArgTypeWildcardTarget = 10
CommandArgTypeFilepath = 17
CommandArgTypeIntegerRange = 23
CommandArgTypeEquipmentSlots = 38
CommandArgTypeString = 39
CommandArgTypeBlockPosition = 47
CommandArgTypePosition = 48
CommandArgTypeMessage = 51
CommandArgTypeRawText = 53
CommandArgTypeJSON = 57
CommandArgTypeBlockStates = 67
CommandArgTypeCommand = 70
CommandArgTypeEquipmentSlots = 43
CommandArgTypeString = 44
CommandArgTypeBlockPosition = 52
CommandArgTypePosition = 53
CommandArgTypeMessage = 55
CommandArgTypeRawText = 58
CommandArgTypeJSON = 62
CommandArgTypeBlockStates = 71
CommandArgTypeCommand = 74
)

const (
Expand Down
1 change: 1 addition & 0 deletions minecraft/protocol/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const (
ContainerBarrel
ContainerCursor
ContainerCreatedOutput
ContainerSmithingTableTemplate
)

const (
Expand Down
4 changes: 2 additions & 2 deletions minecraft/protocol/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package protocol

const (
// CurrentProtocol is the current protocol version for the version below.
CurrentProtocol = 575
CurrentProtocol = 582
// CurrentVersion is the current version of Minecraft as supported by the `packet` package.
CurrentVersion = "1.19.70"
CurrentVersion = "1.19.80"
)
1 change: 1 addition & 0 deletions minecraft/protocol/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type IO interface {
PlayerInventoryAction(x *UseItemTransactionData)
GameRule(x *GameRule)
AbilityValue(x *any)
CompressedBiomeDefinitions(x *map[string]any)
Commands(commands *[]Command, constraints *[]CommandEnumConstraint)

ShieldID() int32
Expand Down
3 changes: 3 additions & 0 deletions minecraft/protocol/login/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ type ClientData struct {
TrustedSkin bool
// OverrideSkin is a boolean that does not make sense to be here. The current usage of this field is unknown.
OverrideSkin bool
// CompatibleWithClientSideChunkGen is a boolean indicating if the client's hardware is capable of using the client
// side chunk generation system.
CompatibleWithClientSideChunkGen bool
}

// PersonaPiece represents a piece of a persona skin. All pieces are sent separately.
Expand Down
22 changes: 22 additions & 0 deletions minecraft/protocol/packet/compressed_biome_definition_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package packet

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

// CompressedBiomeDefinitionList is sent by the server to send a list of biomes to the client. The contents of this packet
// are very large, even after being compressed. This packet is only required when using client-side chunk generation.
type CompressedBiomeDefinitionList struct {
// Biomes is a map of biomes with their identifier as key, and the biome data as value. The biome data contains many
// different fields such as climate, surface materials and generation rules etc.
Biomes map[string]any
}

// ID ...
func (*CompressedBiomeDefinitionList) ID() uint32 {
return IDCompressedBiomeDefinitionList
}

func (pk *CompressedBiomeDefinitionList) Marshal(io protocol.IO) {
io.CompressedBiomeDefinitions(&pk.Biomes)
}
3 changes: 3 additions & 0 deletions minecraft/protocol/packet/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,7 @@ const (
IDCameraPresets
IDUnlockedRecipes
IDCameraInstruction = iota + 101
IDCompressedBiomeDefinitionList
IDTrimData
IDOpenSign
)
7 changes: 7 additions & 0 deletions minecraft/protocol/packet/level_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
LevelEventSoundPointedDripstoneLand = 1064
LevelEventSoundDyeUsed = 1065
LevelEventSoundInkSacUsed = 1066
LevelEventSoundAmethystResonate = 1067
LevelEventQueueCustomMusic = 1900
LevelEventPlayCustomMusic = 1901
LevelEventStopCustomMusic = 1902
Expand Down Expand Up @@ -111,6 +112,12 @@ const (
LevelEventStartBlockCracking = 3600
LevelEventStopBlockCracking = 3601
LevelEventUpdateBlockCracking = 3602
LevelEventParticlesCrackBlockDown = 3603
LevelEventParticlesCrackBlockUp = 3604
LevelEventParticlesCrackBlockNorth = 3605
LevelEventParticlesCrackBlockSouth = 3606
LevelEventParticlesCrackBlockWest = 3607
LevelEventParticlesCrackBlockEast = 3608
LevelEventAllPlayersSleeping = 9800
LevelEventSleepingPlayers = 9801
LevelEventJumpPrevented = 9810
Expand Down
26 changes: 26 additions & 0 deletions minecraft/protocol/packet/open_sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package packet

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

// OpenSign is sent by the server to open a sign for editing. As of 1.19.80, the player can interact with a sign to edit
// the text on both sides instead of just the front.
type OpenSign struct {
// Position is the position of the sign to edit. The client uses this position to get the data of the sign, including
// the existing text and formatting etc.
Position protocol.BlockPos
// FrontSide dictates whether the front side of the sign should be opened for editing. If false, the back side is
// assumed to be edited.
FrontSide bool
}

// ID ...
func (*OpenSign) ID() uint32 {
return IDOpenSign
}

func (pk *OpenSign) Marshal(io protocol.IO) {
io.UBlockPos(&pk.Position)
io.Bool(&pk.FrontSide)
}
2 changes: 1 addition & 1 deletion minecraft/protocol/packet/photo_info_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"github.com/sandertv/gophertunnel/minecraft/protocol"
)

// PhotoInfoRequest is sent by the client to request photo information from the server.
// PhotoInfoRequest is sent by the client to request photo information from the server. This packet was deprecated in 1.19.80.
type PhotoInfoRequest struct {
// PhotoID is the ID of the photo.
PhotoID int64
Expand Down
5 changes: 4 additions & 1 deletion minecraft/protocol/packet/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@ func init() {
IDCameraPresets: func() Packet { return &CameraPresets{} },
IDUnlockedRecipes: func() Packet { return &UnlockedRecipes{} },
// ---
IDCameraInstruction: func() Packet { return &CameraInstruction{} },
IDCameraInstruction: func() Packet { return &CameraInstruction{} },
IDCompressedBiomeDefinitionList: func() Packet { return &CompressedBiomeDefinitionList{} },
IDTrimData: func() Packet { return &TrimData{} },
IDOpenSign: func() Packet { return &OpenSign{} },
}
for id, pk := range packets {
Register(id, pk)
Expand Down
4 changes: 4 additions & 0 deletions minecraft/protocol/packet/request_chunk_radius.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ type RequestChunkRadius struct {
// ChunkRadius is the requested chunk radius. This value is always the value set in the settings of the
// player.
ChunkRadius int32
// MaxChunkRadius is the maximum chunk radius that the player wants to receive. The reason for the client sending this
// is currently unknown.
MaxChunkRadius int32
}

// ID ...
Expand All @@ -20,4 +23,5 @@ func (*RequestChunkRadius) ID() uint32 {

func (pk *RequestChunkRadius) Marshal(io protocol.IO) {
io.Varint32(&pk.ChunkRadius)
io.Varint32(&pk.MaxChunkRadius)
}
10 changes: 10 additions & 0 deletions minecraft/protocol/packet/start_game.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ type StartGame struct {
// 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
// CreatedInEditor is a value to dictate if the world was created as a project in the editor mode. The functionality
// of this field is currently unknown.
CreatedInEditor bool
// ExportedFromEditor is a value to dictate if the world was exported from editor mode. The functionality of this
// field is currently unknown.
ExportedFromEditor bool
// DayCycleLockTime is the time at which the day cycle was locked if the day cycle is disabled using the
// respective game rule. The client will maintain this time as long as the day cycle is disabled.
DayCycleLockTime int32
Expand Down Expand Up @@ -227,6 +233,7 @@ type StartGame struct {
ChatRestrictionLevel uint8
// DisablePlayerInteractions is true if the client should ignore other players when interacting with the world.
DisablePlayerInteractions bool
UseBlockNetworkIDHashes bool
}

// ID ...
Expand All @@ -251,6 +258,8 @@ func (pk *StartGame) Marshal(io protocol.IO) {
io.UBlockPos(&pk.WorldSpawn)
io.Bool(&pk.AchievementsDisabled)
io.Bool(&pk.EditorWorld)
io.Bool(&pk.CreatedInEditor)
io.Bool(&pk.ExportedFromEditor)
io.Varint32(&pk.DayCycleLockTime)
io.Varint32(&pk.EducationEditionOffer)
io.Bool(&pk.EducationFeaturesEnabled)
Expand Down Expand Up @@ -305,4 +314,5 @@ func (pk *StartGame) Marshal(io protocol.IO) {
io.Uint64(&pk.ServerBlockStateChecksum)
io.UUID(&pk.WorldTemplateID)
io.Bool(&pk.ClientSideGeneration)
io.Bool(&pk.UseBlockNetworkIDHashes)
}
26 changes: 26 additions & 0 deletions minecraft/protocol/packet/trim_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package packet

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

// TrimData is sent by the server to the client when they first join the server. It contains a list of all the patterns
// and materials that can be applied via armour trims.
type TrimData struct {
// Patterns is a list of patterns that can be applied to armour. Each pattern has its own style and texture that is
// defined through resource packs.
Patterns []protocol.TrimPattern
// Materials is a list of materials that can be applied to armour. These are mostly different ores that have different
// colours for more customization.
Materials []protocol.TrimMaterial
}

// ID ...
func (*TrimData) ID() uint32 {
return IDTrimData
}

func (pk *TrimData) Marshal(io protocol.IO) {
protocol.Slice(io, &pk.Patterns)
protocol.Slice(io, &pk.Materials)
}
53 changes: 53 additions & 0 deletions minecraft/protocol/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,59 @@ func (r *Reader) AbilityValue(x *any) {
}
}

// CompressedBiomeDefinitions reads a list of compressed biome definitions from the reader. Minecraft decided to make their
// own type of compression for this, so we have to implement it ourselves. It uses a dictionary of repeated byte sequences
// to reduce the size of the data. The compressed data is read byte-by-byte, and if the byte is 0xff then it is assumed
// that the next two bytes are an int16 for the dictionary index. Otherwise, the byte is copied to the output. The dictionary
// index is then used to look up the byte sequence to be appended to the output.
func (r *Reader) CompressedBiomeDefinitions(x *map[string]any) {
var length uint32
header := make([]byte, 10)
r.Varuint32(&length)
if _, err := r.r.Read(header); err != nil {
r.panic(err)
}
if !bytes.Equal(header, []byte("COMPRESSED")) {
r.InvalidValue(header, "compression header", fmt.Sprintf("must be COMPRESSED (%v)", []byte("COMPRESSED")))
return
}

var dictLength uint16
var entryLength uint8
r.Uint16(&dictLength)
dictionary := make([][]byte, dictLength)
for i := 0; i < int(dictLength); i++ {
r.Uint8(&entryLength)
dictionary[i] = make([]byte, int(entryLength))
if _, err := r.r.Read(dictionary[i]); err != nil {
r.panic(err)
}
}

var decompressed []byte
var dictIndex int16
for {
key, err := r.r.ReadByte()
if err != nil {
break
}
if key != 0xff {
decompressed = append(decompressed, key)
continue
}

r.Int16(&dictIndex)
if dictIndex >= 0 && int(dictIndex) < len(dictionary) {
decompressed = append(decompressed, dictionary[dictIndex]...)
continue
}
decompressed = append(decompressed, key)
}
if err := nbt.Unmarshal(decompressed, x); err != nil {
r.panic(err)
}
}

// Commands reads a Command slice and its constraints from a reader.
func (r *Reader) Commands(commands *[]Command, constraints *[]CommandEnumConstraint) {
var ctx AvailableCommandsContext
Expand Down

0 comments on commit f10711f

Please sign in to comment.