Skip to content

Commit acf5e59

Browse files
committed
Commands
1 parent f9fe92a commit acf5e59

File tree

16 files changed

+361
-76
lines changed

16 files changed

+361
-76
lines changed

commands/debug.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package commands
22

33
import (
4+
"github.com/zeppelinmc/zeppelin/server/player"
45
"math"
56

67
"github.com/zeppelinmc/zeppelin/protocol/text"
7-
"github.com/zeppelinmc/zeppelin/server"
88
"github.com/zeppelinmc/zeppelin/server/command"
9-
"github.com/zeppelinmc/zeppelin/server/player/state"
109

1110
//"github.com/zeppelinmc/zeppelin/server/session"
1211
"github.com/zeppelinmc/zeppelin/util"
@@ -17,30 +16,22 @@ var debug = command.Command{
1716
Aliases: []string{"f3"},
1817
Namespace: "zeppelin",
1918
Callback: func(ccc command.CommandCallContext) {
20-
s, ok := ccc.Executor.(interface{ Player() *state.PlayerEntity })
19+
player, ok := ccc.Executor.(*player.Player)
2120
if !ok {
2221
ccc.Executor.SystemMessage(text.TextComponent{
2322
Text: "This command should be used by a player.",
2423
Color: "red",
2524
})
2625
return
2726
}
28-
player := s.Player()
29-
if player == nil {
30-
ccc.Executor.SystemMessage(text.TextComponent{
31-
Text: "This command should be used by a player.",
32-
Color: "red",
33-
})
34-
return
35-
}
3627
x, y, z := player.Position()
3728
chunkX, chunkY, chunkZ := int32(x)>>4, int32(y)>>4, int32(z)>>4
3829
xb, yb, zb := int32(math.Floor(x)), int32(math.Floor(y)), int32(math.Floor(z))
3930
rx, rz := chunkX>>5, chunkZ>>5
4031

4132
yaw, pitch := player.Rotation()
4233

43-
dimension := ccc.Server.(*server.Server).World.Dimension(player.Dimension())
34+
dimension := player.Dimension()
4435

4536
c, err := dimension.GetChunk(chunkX, chunkZ)
4637
if err != nil {

properties/properties.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ type ServerProperties struct {
6464
ServerIp string `properties:"server-ip"`
6565
ServerPort uint16 `properties:"server-port"`
6666

67-
SimulationDistance int `properties:"simulation-distance"`
67+
SimulationDistance int32 `properties:"simulation-distance"`
6868

6969
SpawnMonsters bool `properties:"spawn-monsters"`
7070
SpawnProtection int `properties:"spawn-protection"`

server/entity/entity.go

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func NewLiving(e *Entity) LivingEntity {
3232
return LivingEntity{Entity: *e}
3333
}
3434

35-
// base state
35+
// Entity is the base state for entities
3636
type Entity struct {
3737
uuid uuid.UUID
3838
typ int32
@@ -48,7 +48,7 @@ type Entity struct {
4848
attr_mu sync.RWMutex
4949
attributes []Attribute
5050

51-
dimension a.AtomicValue[string]
51+
dimensionName a.AtomicValue[string]
5252
}
5353

5454
func (p *Entity) Attribute(id string) *Attribute {
@@ -71,7 +71,7 @@ func (p *Entity) Attribute(id string) *Attribute {
7171
return attr
7272
}
7373

74-
// returns a clone of the attributes of this state
74+
// Attributes returns a clone of the attributes of this state
7575
func (p *Entity) Attributes() []Attribute {
7676
p.attr_mu.RLock()
7777
defer p.attr_mu.RUnlock()
@@ -88,11 +88,11 @@ func (p *Entity) SetAttribute(id string, base float64) {
8888
p.attributes[i].Base = base
8989
}
9090

91-
// returns a clone of the metadata of this state
92-
func (e *Entity) Metadata() metadata.Metadata {
93-
e.md_mu.RLock()
94-
defer e.md_mu.RUnlock()
95-
return maps.Clone(e.metadata)
91+
// Metadata returns a clone of the metadata of this state
92+
func (p *Entity) Metadata() metadata.Metadata {
93+
p.md_mu.RLock()
94+
defer p.md_mu.RUnlock()
95+
return maps.Clone(p.metadata)
9696
}
9797

9898
func (p *Entity) SetMetadata(md metadata.Metadata) {
@@ -121,57 +121,57 @@ func (p *Entity) SetMetadataIndexes(md metadata.Metadata) {
121121
}
122122
}
123123

124-
func (e *Entity) Dimension() string {
125-
return e.dimension.Get()
124+
func (p *Entity) DimensionName() string {
125+
return p.dimensionName.Get()
126126
}
127127

128-
func (e *Entity) SetDimension(v string) {
129-
e.dimension.Set(v)
128+
func (p *Entity) SetDimensionName(v string) {
129+
p.dimensionName.Set(v)
130130
}
131131

132-
func (e *Entity) SetMotion(x, y, z float64) {
133-
e.vx.Store(math.Float64bits(x))
134-
e.vy.Store(math.Float64bits(y))
135-
e.vz.Store(math.Float64bits(z))
132+
func (p *Entity) SetMotion(x, y, z float64) {
133+
p.vx.Store(math.Float64bits(x))
134+
p.vy.Store(math.Float64bits(y))
135+
p.vz.Store(math.Float64bits(z))
136136
}
137137

138-
func (e *Entity) SetPosition(x, y, z float64) {
139-
e.x.Store(math.Float64bits(x))
140-
e.y.Store(math.Float64bits(y))
141-
e.z.Store(math.Float64bits(z))
138+
func (p *Entity) SetPosition(x, y, z float64) {
139+
p.x.Store(math.Float64bits(x))
140+
p.y.Store(math.Float64bits(y))
141+
p.z.Store(math.Float64bits(z))
142142
}
143143

144-
func (e *Entity) SetRotation(yaw, pitch float32) {
145-
e.yaw.Store(math.Float32bits(yaw))
146-
e.pitch.Store(math.Float32bits(pitch))
144+
func (p *Entity) SetRotation(yaw, pitch float32) {
145+
p.yaw.Store(math.Float32bits(yaw))
146+
p.pitch.Store(math.Float32bits(pitch))
147147
}
148148

149-
func (e *Entity) SetOnGround(v bool) {
150-
e.onGround.Store(v)
149+
func (p *Entity) SetOnGround(v bool) {
150+
p.onGround.Store(v)
151151
}
152152

153-
func (e *Entity) Position() (x, y, z float64) {
154-
return math.Float64frombits(e.x.Load()), math.Float64frombits(e.y.Load()), math.Float64frombits(e.z.Load())
153+
func (p *Entity) Position() (x, y, z float64) {
154+
return math.Float64frombits(p.x.Load()), math.Float64frombits(p.y.Load()), math.Float64frombits(p.z.Load())
155155
}
156156

157-
func (e *Entity) Motion() (vx, vy, vz float64) {
158-
return math.Float64frombits(e.vx.Load()), math.Float64frombits(e.vy.Load()), math.Float64frombits(e.vz.Load())
157+
func (p *Entity) Motion() (vx, vy, vz float64) {
158+
return math.Float64frombits(p.vx.Load()), math.Float64frombits(p.vy.Load()), math.Float64frombits(p.vz.Load())
159159
}
160160

161-
func (e *Entity) Rotation() (yaw, pitch float32) {
162-
return math.Float32frombits(e.yaw.Load()), math.Float32frombits(e.pitch.Load())
161+
func (p *Entity) Rotation() (yaw, pitch float32) {
162+
return math.Float32frombits(p.yaw.Load()), math.Float32frombits(p.pitch.Load())
163163
}
164164

165-
func (e *Entity) OnGround() bool {
166-
return e.onGround.Load()
165+
func (p *Entity) OnGround() bool {
166+
return p.onGround.Load()
167167
}
168168

169-
func (e *Entity) UUID() uuid.UUID {
170-
return e.uuid
169+
func (p *Entity) UUID() uuid.UUID {
170+
return p.uuid
171171
}
172172

173-
func (e *Entity) Type() int32 {
174-
return e.typ
173+
func (p *Entity) Type() int32 {
174+
return p.typ
175175
}
176176

177177
type LivingEntity struct {

server/player/chunks.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import (
99

1010
// Dimension returns the dimension struct this player is in
1111
func (p *Player) Dimension() *dimension.Dimension {
12-
return p.dimensionManager.Dimension(p.state.Dimension())
12+
return p.dimensionManager.Dimension(p.DimensionName())
1313
}
1414

1515
func (p *Player) sendSpawnChunks() error {
1616
viewDistance := p.ViewDistance()
1717

18-
x, _, z := p.state.Position()
18+
x, _, z := p.Position()
1919
chunkX, chunkZ := int32(x)>>4, int32(z)>>4
2020

2121
if err := p.WritePacket(&play.SetCenterChunk{ChunkX: chunkX, ChunkZ: chunkZ}); err != nil {

server/player/conn.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ import (
99
"unsafe"
1010
)
1111

12-
// RegisteredHandlers maps all handler functions by their state[0] and id[1]
13-
var RegisteredHandlers = make(map[[2]int32]func(packet packet.Decodeable) error)
12+
// registeredHandlers maps all handler functions by their state[0] and id[1]
13+
var registeredHandlers = make(map[[2]int32]func(*Player, packet.Decodeable) error)
14+
15+
func RegisterHandler(state, id int32, handler func(*Player, packet.Decodeable) error) struct{} {
16+
registeredHandlers[[2]int32{state, id}] = handler
17+
18+
return struct{}{}
19+
}
1420

1521
// awaitPacket waits for the packet with the id to be received
1622
func (p *Player) awaitPacket(id int32) (packet.Decodeable, error) {
@@ -84,7 +90,7 @@ func (p *Player) listenPackets() {
8490
p.packetAwaited.Store(-1)
8591
}
8692

87-
handler, ok := RegisteredHandlers[[2]int32{state, id}]
93+
handler, ok := registeredHandlers[[2]int32{state, id}]
8894
if !ok {
8995
switch pk := pk.(type) {
9096
case *configuration.ClientInformation, *play.ClientInformation:
@@ -93,7 +99,7 @@ func (p *Player) listenPackets() {
9399
continue
94100
}
95101

96-
if err := handler(pk); err != nil {
102+
if err := handler(p, pk); err != nil {
97103
p.killConnection(false, "packet handling error: "+err.Error())
98104
return
99105
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package player
2+
3+
import (
4+
"github.com/zeppelinmc/zeppelin/protocol/net"
5+
"github.com/zeppelinmc/zeppelin/protocol/net/packet"
6+
"github.com/zeppelinmc/zeppelin/protocol/net/packet/play"
7+
"github.com/zeppelinmc/zeppelin/util/log"
8+
)
9+
10+
var _ = RegisterHandler(net.PlayState, play.PacketIdChatCommand, func(p *Player, packet packet.Decodeable) error {
11+
pk := packet.(*play.ChatCommand)
12+
13+
log.Infolnf("%sPlayer %s (%s) issued server command: /%s", log.FormatAddr(p.serverProperties.LogIPs, p.RemoteAddr()), p.Username(), p.UUID(), pk.Command)
14+
p.commandManager.Call(pk.Command, p)
15+
16+
return nil
17+
})

server/player/player.go

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package player
22

33
import (
4+
"github.com/zeppelinmc/zeppelin/properties"
45
"github.com/zeppelinmc/zeppelin/protocol/net"
56
"github.com/zeppelinmc/zeppelin/protocol/net/io/encoding"
67
"github.com/zeppelinmc/zeppelin/protocol/net/packet"
78
"github.com/zeppelinmc/zeppelin/protocol/net/packet/configuration"
89
"github.com/zeppelinmc/zeppelin/protocol/net/packet/play"
910
"github.com/zeppelinmc/zeppelin/protocol/net/tags"
11+
"github.com/zeppelinmc/zeppelin/protocol/text"
12+
"github.com/zeppelinmc/zeppelin/server/command"
1013
"github.com/zeppelinmc/zeppelin/server/entity"
1114
"github.com/zeppelinmc/zeppelin/server/player/state"
1215
"github.com/zeppelinmc/zeppelin/server/world/dimension"
@@ -18,18 +21,22 @@ import (
1821

1922
type Player struct {
2023
*net.Conn
24+
*state.PlayerEntity
2125

2226
playerList *PlayerList
23-
// the player entity
24-
state *state.PlayerEntity
2527
// the entity id for this player
2628
entityId int32
2729

30+
Unlisted bool
31+
2832
ClientInformation atomic.Pointer[configuration.ClientInformation]
2933

3034
dimensionManager *dimension.DimensionManager
3135
worldLevel *level.Level
3236

37+
serverProperties *properties.ServerProperties
38+
commandManager *command.Manager
39+
3340
// the time in milliseconds that the keep alive packet was sent to the server from the client
3441
sbLastKeepalive atomic.Int64
3542
// the time in milliseconds that the keep alive packet was sent to the client from the server
@@ -47,14 +54,17 @@ func int32toAtomic(i int32) atomic.Int32 {
4754
return *(*atomic.Int32)(unsafe.Pointer(&i))
4855
}
4956

50-
func (list *PlayerList) New(conn *net.Conn, en *state.PlayerEntity, dimensionManager *dimension.DimensionManager, worldLevel *level.Level) *Player {
57+
func (list *PlayerList) New(conn *net.Conn, en *state.PlayerEntity, dimensionManager *dimension.DimensionManager, worldLevel *level.Level, serverProperties *properties.ServerProperties, commandManager *command.Manager) *Player {
5158
p := &Player{
52-
entityId: entity.NewEntityId(),
53-
state: en,
59+
entityId: entity.NewEntityId(),
60+
PlayerEntity: en,
5461

5562
dimensionManager: dimensionManager,
5663
worldLevel: worldLevel,
5764

65+
serverProperties: serverProperties,
66+
commandManager: commandManager,
67+
5868
registryIndexes: make(map[string][]string),
5969

6070
packetAwaited: int32toAtomic(-1),
@@ -122,11 +132,19 @@ func (p *Player) finishConfiguration() error {
122132

123133
// startGame finishes the initialization for the player and logs it into the world
124134
func (p *Player) startGame() error {
135+
if err := p.sendCommandGraph(); err != nil {
136+
return err
137+
}
138+
125139
if err := p.WritePacket(&play.Login{
126-
EntityID: p.entityId,
127-
DimensionName: p.state.Dimension(),
128-
GameMode: 1,
129-
DimensionType: int32(slices.Index(p.registryIndexes["minecraft:dimension_type"], p.state.Dimension())),
140+
EntityID: p.entityId,
141+
DimensionName: p.DimensionName(),
142+
GameMode: byte(p.GameMode()),
143+
DimensionType: int32(slices.Index(p.registryIndexes["minecraft:dimension_type"], p.DimensionName())),
144+
ViewDistance: p.serverProperties.ViewDistance,
145+
SimulationDistance: p.serverProperties.SimulationDistance,
146+
HashedSeed: p.worldLevel.Data.WorldGenSettings.Seed.Hash(),
147+
EnforcesSecureChat: p.serverProperties.EnforceSecureProfile,
130148
}); err != nil {
131149
return err
132150
}
@@ -141,8 +159,8 @@ func (p *Player) startGame() error {
141159
return err
142160
}
143161

144-
x, y, z := p.state.Position()
145-
yaw, pitch := p.state.Rotation()
162+
x, y, z := p.Position()
163+
yaw, pitch := p.Rotation()
146164

147165
if err := p.SynchronizePosition(x, y, z, yaw, pitch); err != nil {
148166
return err
@@ -166,8 +184,8 @@ func (p *Player) startGame() error {
166184

167185
// SynchronizePosition teleports the player to the specified coordinates
168186
func (p *Player) SynchronizePosition(x, y, z float64, yaw, pitch float32) error {
169-
p.state.SetPosition(x, y, z)
170-
p.state.SetRotation(yaw, pitch)
187+
p.SetPosition(x, y, z)
188+
p.SetRotation(yaw, pitch)
171189

172190
if err := p.WritePacket(&play.SynchronizePlayerPosition{X: x, Y: y, Z: z, Yaw: yaw, Pitch: pitch}); err != nil {
173191
return err
@@ -184,3 +202,13 @@ func (p *Player) Login() error {
184202
}
185203
return p.startGame()
186204
}
205+
206+
// SystemMessage sends a system message (unsigned) to the player
207+
func (p *Player) SystemMessage(msg text.TextComponent) error {
208+
return p.WritePacket(&play.SystemChatMessage{Content: msg})
209+
}
210+
211+
// sendCommandGraph sends the command graph to the player
212+
func (p *Player) sendCommandGraph() error {
213+
return p.WritePacket(p.commandManager.Encode())
214+
}

server/player/playerlist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (list *PlayerList) AddPlayer(player *Player) {
4949

5050
update.Players[player.UUID()] = play.PlayerAction{
5151
Name: player.Username(),
52-
Listed: true,
52+
Listed: !player.Unlisted,
5353
Properties: player.Properties(),
5454
}
5555
}

0 commit comments

Comments
 (0)