150 lines
5.1 KiB
Go
150 lines
5.1 KiB
Go
package basic
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"github.com/Tnze/go-mc/data/packetid"
|
|
"github.com/Tnze/go-mc/nbt"
|
|
pk "github.com/Tnze/go-mc/net/packet"
|
|
)
|
|
|
|
// WorldInfo content player info in server.
|
|
type WorldInfo struct {
|
|
DimensionCodec DimensionCodec
|
|
DimensionType string
|
|
DimensionNames []string // Identifiers for all worlds on the server.
|
|
DimensionName string // Name of the world being spawned into.
|
|
HashedSeed int64 // First 8 bytes of the SHA-256 hash of the world's seed. Used client side for biome noise
|
|
MaxPlayers int32 // Was once used by the client to draw the player list, but now is ignored.
|
|
ViewDistance int32 // Render distance (2-32).
|
|
SimulationDistance int32 // The distance that the client will process specific things, such as entities.
|
|
ReducedDebugInfo bool // If true, a Notchian client shows reduced information on the debug screen. For servers in development, this should almost always be false.
|
|
EnableRespawnScreen bool // Set to false when the doImmediateRespawn gamerule is true.
|
|
IsDebug bool // True if the world is a debug mode world; debug mode worlds cannot be modified and have predefined blocks.
|
|
IsFlat bool // True if the world is a superflat world; flat worlds have different void fog and a horizon at y=0 instead of y=63.
|
|
}
|
|
|
|
type Dimension struct {
|
|
FixedTime int64 `nbt:"fixed_time,omitempty"`
|
|
HasSkylight bool `nbt:"has_skylight"`
|
|
HasCeiling bool `nbt:"has_ceiling"`
|
|
Ultrawarm bool `nbt:"ultrawarm"`
|
|
Natural bool `nbt:"natural"`
|
|
CoordinateScale float64 `nbt:"coordinate_scale"`
|
|
BedWorks bool `nbt:"bed_works"`
|
|
RespawnAnchorWorks byte `nbt:"respawn_anchor_works"`
|
|
MinY int32 `nbt:"min_y"`
|
|
Height int32 `nbt:"height"`
|
|
LogicalHeight int32 `nbt:"logical_height"`
|
|
InfiniteBurn string `nbt:"infiniburn"`
|
|
Effects string `nbt:"effects"`
|
|
AmbientLight float64 `nbt:"ambient_light"`
|
|
|
|
PiglinSafe byte `nbt:"piglin_safe"`
|
|
HasRaids byte `nbt:"has_raids"`
|
|
MonsterSpawnLightLevel nbt.RawMessage `nbt:"monster_spawn_light_level"` // Tag_Int or {type:"minecraft:uniform", value:{min_inclusive: Tag_Int, max_inclusive: Tag_Int}}
|
|
MonsterSpawnBlockLightLimit int32 `nbt:"monster_spawn_block_light_limit"`
|
|
}
|
|
|
|
type DimensionCodec struct {
|
|
// What is Below? (wiki.vg)
|
|
ChatType Registry[nbt.RawMessage] `nbt:"minecraft:chat_type"`
|
|
DimensionType Registry[Dimension] `nbt:"minecraft:dimension_type"`
|
|
WorldGenBiome Registry[nbt.RawMessage] `nbt:"minecraft:worldgen/biome"`
|
|
}
|
|
|
|
type Registry[E any] struct {
|
|
Type string `nbt:"type"`
|
|
Value []struct {
|
|
Name string `nbt:"name"`
|
|
ID int32 `nbt:"id"`
|
|
Element E `nbt:"element"`
|
|
} `nbt:"value"`
|
|
}
|
|
|
|
func (r *Registry[E]) Find(name string) *E {
|
|
for i := range r.Value {
|
|
if r.Value[i].Name == name {
|
|
return &r.Value[i].Element
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type PlayerInfo struct {
|
|
EID int32 // The player's Entity ID (EID).
|
|
Hardcore bool // Is hardcore
|
|
Gamemode byte // Gamemode. 0: Survival, 1: Creative, 2: Adventure, 3: Spectator.
|
|
PrevGamemode int8 // Previous Gamemode
|
|
}
|
|
|
|
// ServInfo contains information about the server implementation.
|
|
type ServInfo struct {
|
|
Brand string
|
|
}
|
|
|
|
func (p *Player) handleLoginPacket(packet pk.Packet) error {
|
|
err := packet.Scan(
|
|
(*pk.Int)(&p.EID),
|
|
(*pk.Boolean)(&p.Hardcore),
|
|
(*pk.UnsignedByte)(&p.Gamemode),
|
|
(*pk.Byte)(&p.PrevGamemode),
|
|
pk.Array((*[]pk.Identifier)(unsafe.Pointer(&p.DimensionNames))),
|
|
pk.NBT(&p.WorldInfo.DimensionCodec),
|
|
(*pk.Identifier)(&p.WorldInfo.DimensionType),
|
|
(*pk.Identifier)(&p.DimensionName),
|
|
(*pk.Long)(&p.HashedSeed),
|
|
(*pk.VarInt)(&p.MaxPlayers),
|
|
(*pk.VarInt)(&p.ViewDistance),
|
|
(*pk.VarInt)(&p.SimulationDistance),
|
|
(*pk.Boolean)(&p.ReducedDebugInfo),
|
|
(*pk.Boolean)(&p.EnableRespawnScreen),
|
|
(*pk.Boolean)(&p.IsDebug),
|
|
(*pk.Boolean)(&p.IsFlat),
|
|
)
|
|
if err != nil {
|
|
return Error{err}
|
|
}
|
|
err = p.c.Conn.WritePacket(pk.Marshal( //PluginMessage packet
|
|
packetid.ServerboundCustomPayload,
|
|
pk.Identifier("minecraft:brand"),
|
|
pk.String(p.Settings.Brand),
|
|
))
|
|
if err != nil {
|
|
return Error{err}
|
|
}
|
|
|
|
err = p.c.Conn.WritePacket(pk.Marshal(
|
|
packetid.ServerboundClientInformation, // Client settings
|
|
pk.String(p.Settings.Locale),
|
|
pk.Byte(p.Settings.ViewDistance),
|
|
pk.VarInt(p.Settings.ChatMode),
|
|
pk.Boolean(p.Settings.ChatColors),
|
|
pk.UnsignedByte(p.Settings.DisplayedSkinParts),
|
|
pk.VarInt(p.Settings.MainHand),
|
|
pk.Boolean(p.Settings.EnableTextFiltering),
|
|
pk.Boolean(p.Settings.AllowListing),
|
|
))
|
|
if err != nil {
|
|
return Error{err}
|
|
}
|
|
return nil
|
|
}
|
|
func (p *Player) handleRespawnPacket(packet pk.Packet) error {
|
|
var copyMeta bool
|
|
err := packet.Scan(
|
|
(*pk.String)(&p.DimensionType),
|
|
(*pk.Identifier)(&p.DimensionName),
|
|
(*pk.Long)(&p.HashedSeed),
|
|
(*pk.UnsignedByte)(&p.Gamemode),
|
|
(*pk.Byte)(&p.PrevGamemode),
|
|
(*pk.Boolean)(&p.IsDebug),
|
|
(*pk.Boolean)(&p.IsFlat),
|
|
(*pk.Boolean)(©Meta),
|
|
)
|
|
if err != nil {
|
|
return Error{err}
|
|
}
|
|
return nil
|
|
}
|