Files
ngzz-mc/cmd/client/multiplayer_gl.go

60 lines
1.6 KiB
Go
Raw Normal View History

//go:build gl
// 客户端联机:netclient 接入(多人同步.md §2 权威链路客户端侧)。
package main
import (
"mc/internal/block"
"mc/internal/netclient"
"mc/internal/netproto"
"mc/internal/save"
)
// mpHandler 联机回调:区块安装与方块变更应用(多人同步.md §4–§5)。
type mpHandler struct {
app *clientApp
}
// OnLogin 登录结果。
func (h *mpHandler) OnLogin(code uint8) {
if code != 0 {
h.app.logf("服务器拒绝登录(码 %d)", code)
h.app.net.Close()
h.app.net = nil
h.app.screen = 0
}
}
// OnChunk 收到区块:反序列化并安装到世界(多人同步.md §4)。
func (h *mpHandler) OnChunk(data []byte) {
c, err := save.DecodeChunk(data)
if err != nil {
h.app.logf("区块解码失败: %v", err)
return
}
h.app.sess.World.InstallChunk(c)
}
// OnBlockChange 方块变更(服务器权威广播,多人同步.md §5)。
func (h *mpHandler) OnBlockChange(m netproto.BlockChange) {
h.app.sess.World.SetBlock(m.X, m.Y, m.Z, block.NewState(m.BlockID, m.Meta))
}
// OnEntityMove 其他玩家移动(多人同步.md §3:客户端存储位置,渲染插值后置)。
func (h *mpHandler) OnEntityMove(m netproto.EntityMove) {
h.app.remoteMu.Lock()
h.app.remotePlayers[m.EntityID] = [3]float64{float64(m.X), float64(m.Y), float64(m.Z)}
h.app.remoteMu.Unlock()
}
// dialServer 连接服务器(多人游戏按钮,多人同步.md §2)。
func dialServer(a *clientApp, addr string, name string) error {
h := &mpHandler{app: a}
nc, err := netclient.Dial(addr, netproto.Handshake{ProtocolVersion: 1, ClientID: name}, h)
if err != nil {
return err
}
a.net = nc
return nil
}