Adding client-side and server-side interactions. Also adds purpur/paper support
This commit is contained in:
+27
-1
@@ -15,6 +15,7 @@ type Context struct {
|
||||
snapshot *SnapshotSubscription
|
||||
}
|
||||
|
||||
// Broadcast queues a message to be sent to all players.
|
||||
func (context *Context) Broadcast(message string) {
|
||||
context.actions = append(context.actions, ActionRequest{
|
||||
Type: "minecraft:chat.broadcast",
|
||||
@@ -24,6 +25,7 @@ func (context *Context) Broadcast(message string) {
|
||||
})
|
||||
}
|
||||
|
||||
// SendMessage queues a message to be sent to a player.
|
||||
func (context *Context) SendMessage(playerUUID, message string) {
|
||||
context.actions = append(context.actions, ActionRequest{
|
||||
Type: "minecraft:chat.player",
|
||||
@@ -34,7 +36,29 @@ func (context *Context) SendMessage(playerUUID, message string) {
|
||||
})
|
||||
}
|
||||
|
||||
func (context *Context) SystemCall(name string, payload any) string {
|
||||
// DisplayClientMessage appends a local-only message to the Minecraft client
|
||||
// chat. Client runtimes reject server action types such as SendMessage.
|
||||
func (context *Context) DisplayClientMessage(message string) {
|
||||
context.actions = append(context.actions, ActionRequest{
|
||||
Type: "minecraft:client.chat.display",
|
||||
Payload: map[string]any{
|
||||
"message": message,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// SystemCall queues one of the system calls built into the bridge.
|
||||
func (context *Context) SystemCall(callType SystemCallType, payload any) string {
|
||||
return context.queueSystemCall(string(callType), payload)
|
||||
}
|
||||
|
||||
// CustomSystemCall queues a system call registered by another mod.
|
||||
func (context *Context) CustomSystemCall(name string, payload any) string {
|
||||
return context.queueSystemCall(name, payload)
|
||||
}
|
||||
|
||||
// queueSystemCall queues a system call to be executed by the bridge.
|
||||
func (context *Context) queueSystemCall(name string, payload any) string {
|
||||
id := fmt.Sprintf("call-%d", callSequence.Add(1))
|
||||
context.systemCalls = append(context.systemCalls, SystemCallRequest{
|
||||
ID: id,
|
||||
@@ -44,6 +68,7 @@ func (context *Context) SystemCall(name string, payload any) string {
|
||||
return id
|
||||
}
|
||||
|
||||
// SubscribeSnapshot queues a snapshot subscription to be executed by the bridge.
|
||||
func (context *Context) SubscribeSnapshot(entities bool, blocks ...BlockReference) {
|
||||
context.snapshot = &SnapshotSubscription{
|
||||
Entities: entities,
|
||||
@@ -51,6 +76,7 @@ func (context *Context) SubscribeSnapshot(entities bool, blocks ...BlockReferenc
|
||||
}
|
||||
}
|
||||
|
||||
// Log queues a log message to be sent to the server.
|
||||
func (context *Context) Log(level, message string) {
|
||||
context.logs = append(context.logs, LogEntry{
|
||||
Stream: "sdk",
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package sdk
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSystemCallUsesBuiltInType(t *testing.T) {
|
||||
context := &Context{}
|
||||
runtimeID := 42
|
||||
id := context.SystemCall(SystemCallGetEntity, GetEntityRequest{RuntimeID: &runtimeID})
|
||||
|
||||
if id == "" {
|
||||
t.Fatal("SystemCall returned an empty id")
|
||||
}
|
||||
if len(context.systemCalls) != 1 {
|
||||
t.Fatalf("got %d queued calls, want 1", len(context.systemCalls))
|
||||
}
|
||||
if got := context.systemCalls[0].Name; got != "minecraft:get_entity" {
|
||||
t.Fatalf("queued call name = %q, want %q", got, "minecraft:get_entity")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomSystemCallKeepsExtensionPoint(t *testing.T) {
|
||||
context := &Context{}
|
||||
context.CustomSystemCall("example:claim.owner", nil)
|
||||
|
||||
if len(context.systemCalls) != 1 {
|
||||
t.Fatalf("got %d queued calls, want 1", len(context.systemCalls))
|
||||
}
|
||||
if got := context.systemCalls[0].Name; got != "example:claim.owner" {
|
||||
t.Fatalf("queued call name = %q, want %q", got, "example:claim.owner")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
flat "github.com/yawaflua/GoMinecraftBridge/sdk/internal/fbs/gmb"
|
||||
)
|
||||
|
||||
func decodeTickSnapshot(input []byte) (snapshot ServerSnapshot, err error) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
err = fmt.Errorf("sdk: invalid FlatBuffers tick snapshot: %v", recovered)
|
||||
}
|
||||
}()
|
||||
|
||||
if len(input) < 8 || !flat.ServerSnapshotBufferHasIdentifier(input) {
|
||||
return snapshot, fmt.Errorf("sdk: tick snapshot is not a GMBS FlatBuffer")
|
||||
}
|
||||
|
||||
root := flat.GetRootAsServerSnapshot(input, 0)
|
||||
snapshot.Tick = root.Tick()
|
||||
snapshot.TimestampUnixMilli = root.TimestampUnixMilli()
|
||||
|
||||
snapshot.Levels = make([]LevelSnapshot, root.LevelsLength())
|
||||
var level flat.LevelSnapshot
|
||||
for index := range snapshot.Levels {
|
||||
if !root.Levels(&level, index) {
|
||||
return ServerSnapshot{}, fmt.Errorf("sdk: missing level %d", index)
|
||||
}
|
||||
snapshot.Levels[index] = LevelSnapshot{
|
||||
Dimension: string(level.Dimension()),
|
||||
GameTime: level.GameTime(),
|
||||
DayTime: level.DayTime(),
|
||||
Raining: level.Raining(),
|
||||
Thundering: level.Thundering(),
|
||||
}
|
||||
}
|
||||
|
||||
snapshot.Entities = make([]EntitySnapshot, root.EntitiesLength())
|
||||
var entity flat.EntitySnapshot
|
||||
for index := range snapshot.Entities {
|
||||
if !root.Entities(&entity, index) {
|
||||
return ServerSnapshot{}, fmt.Errorf("sdk: missing entity %d", index)
|
||||
}
|
||||
converted := EntitySnapshot{
|
||||
RuntimeID: int(entity.RuntimeId()),
|
||||
UUID: string(entity.Uuid()),
|
||||
Type: string(entity.Type()),
|
||||
Name: string(entity.Name()),
|
||||
Dimension: string(entity.Dimension()),
|
||||
X: entity.X(),
|
||||
Y: entity.Y(),
|
||||
Z: entity.Z(),
|
||||
Yaw: entity.Yaw(),
|
||||
Pitch: entity.Pitch(),
|
||||
VelocityX: entity.VelocityX(),
|
||||
VelocityY: entity.VelocityY(),
|
||||
VelocityZ: entity.VelocityZ(),
|
||||
Alive: entity.Alive(),
|
||||
Player: entity.Player(),
|
||||
}
|
||||
if entity.HasHealth() {
|
||||
health := entity.Health()
|
||||
maxHealth := entity.MaxHealth()
|
||||
converted.Health = &health
|
||||
converted.MaxHealth = &maxHealth
|
||||
}
|
||||
snapshot.Entities[index] = converted
|
||||
}
|
||||
|
||||
snapshot.Blocks = make([]BlockSnapshot, root.BlocksLength())
|
||||
var block flat.BlockSnapshot
|
||||
var property flat.BlockProperty
|
||||
for index := range snapshot.Blocks {
|
||||
if !root.Blocks(&block, index) {
|
||||
return ServerSnapshot{}, fmt.Errorf("sdk: missing block %d", index)
|
||||
}
|
||||
properties := make(map[string]string, block.PropertiesLength())
|
||||
for propertyIndex := 0; propertyIndex < block.PropertiesLength(); propertyIndex++ {
|
||||
if block.Properties(&property, propertyIndex) {
|
||||
properties[string(property.Key())] = string(property.Value())
|
||||
}
|
||||
}
|
||||
snapshot.Blocks[index] = BlockSnapshot{
|
||||
Dimension: string(block.Dimension()),
|
||||
X: int(block.X()),
|
||||
Y: int(block.Y()),
|
||||
Z: int(block.Z()),
|
||||
Block: string(block.Block()),
|
||||
Properties: properties,
|
||||
}
|
||||
}
|
||||
|
||||
return snapshot, nil
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
flat "github.com/yawaflua/GoMinecraftBridge/sdk/internal/fbs/gmb"
|
||||
)
|
||||
|
||||
func TestDecodeTickSnapshot(t *testing.T) {
|
||||
want := benchmarkSnapshot(3)
|
||||
encoded := encodeBenchmarkFlatBuffer(want)
|
||||
got, err := decodeTickSnapshot(encoded)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Tick != want.Tick || len(got.Entities) != 3 || got.Entities[2].UUID != want.Entities[2].UUID {
|
||||
t.Fatalf("unexpected decoded snapshot: %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFlatBuffersSnapshot1000Entities(b *testing.B) {
|
||||
encoded := encodeBenchmarkFlatBuffer(benchmarkSnapshot(1000))
|
||||
b.ReportAllocs()
|
||||
for b.Loop() {
|
||||
if _, err := decodeTickSnapshot(encoded); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
b.ReportMetric(float64(len(encoded)), "bytes/snapshot")
|
||||
}
|
||||
|
||||
func encodeBenchmarkFlatBuffer(snapshot ServerSnapshot) []byte {
|
||||
builder := flatbuffers.NewBuilder(16 * 1024)
|
||||
levels := make([]flatbuffers.UOffsetT, len(snapshot.Levels))
|
||||
for index, level := range snapshot.Levels {
|
||||
dimension := builder.CreateString(level.Dimension)
|
||||
flat.LevelSnapshotStart(builder)
|
||||
flat.LevelSnapshotAddDimension(builder, dimension)
|
||||
flat.LevelSnapshotAddGameTime(builder, level.GameTime)
|
||||
flat.LevelSnapshotAddDayTime(builder, level.DayTime)
|
||||
flat.LevelSnapshotAddRaining(builder, level.Raining)
|
||||
flat.LevelSnapshotAddThundering(builder, level.Thundering)
|
||||
levels[index] = flat.LevelSnapshotEnd(builder)
|
||||
}
|
||||
|
||||
entities := make([]flatbuffers.UOffsetT, len(snapshot.Entities))
|
||||
for index, entity := range snapshot.Entities {
|
||||
uuid := builder.CreateString(entity.UUID)
|
||||
entityType := builder.CreateString(entity.Type)
|
||||
name := builder.CreateString(entity.Name)
|
||||
dimension := builder.CreateString(entity.Dimension)
|
||||
hasHealth := entity.Health != nil && entity.MaxHealth != nil
|
||||
var health, maxHealth float32
|
||||
if hasHealth {
|
||||
health = *entity.Health
|
||||
maxHealth = *entity.MaxHealth
|
||||
}
|
||||
flat.EntitySnapshotStart(builder)
|
||||
flat.EntitySnapshotAddRuntimeId(builder, int32(entity.RuntimeID))
|
||||
flat.EntitySnapshotAddUuid(builder, uuid)
|
||||
flat.EntitySnapshotAddType(builder, entityType)
|
||||
flat.EntitySnapshotAddName(builder, name)
|
||||
flat.EntitySnapshotAddDimension(builder, dimension)
|
||||
flat.EntitySnapshotAddX(builder, entity.X)
|
||||
flat.EntitySnapshotAddY(builder, entity.Y)
|
||||
flat.EntitySnapshotAddZ(builder, entity.Z)
|
||||
flat.EntitySnapshotAddYaw(builder, entity.Yaw)
|
||||
flat.EntitySnapshotAddPitch(builder, entity.Pitch)
|
||||
flat.EntitySnapshotAddVelocityX(builder, entity.VelocityX)
|
||||
flat.EntitySnapshotAddVelocityY(builder, entity.VelocityY)
|
||||
flat.EntitySnapshotAddVelocityZ(builder, entity.VelocityZ)
|
||||
flat.EntitySnapshotAddAlive(builder, entity.Alive)
|
||||
flat.EntitySnapshotAddPlayer(builder, entity.Player)
|
||||
flat.EntitySnapshotAddHasHealth(builder, hasHealth)
|
||||
flat.EntitySnapshotAddHealth(builder, health)
|
||||
flat.EntitySnapshotAddMaxHealth(builder, maxHealth)
|
||||
entities[index] = flat.EntitySnapshotEnd(builder)
|
||||
}
|
||||
|
||||
flat.ServerSnapshotStartLevelsVector(builder, len(levels))
|
||||
for index := len(levels) - 1; index >= 0; index-- {
|
||||
builder.PrependUOffsetT(levels[index])
|
||||
}
|
||||
levelVector := builder.EndVector(len(levels))
|
||||
flat.ServerSnapshotStartEntitiesVector(builder, len(entities))
|
||||
for index := len(entities) - 1; index >= 0; index-- {
|
||||
builder.PrependUOffsetT(entities[index])
|
||||
}
|
||||
entityVector := builder.EndVector(len(entities))
|
||||
flat.ServerSnapshotStartBlocksVector(builder, 0)
|
||||
blockVector := builder.EndVector(0)
|
||||
|
||||
flat.ServerSnapshotStart(builder)
|
||||
flat.ServerSnapshotAddTick(builder, snapshot.Tick)
|
||||
flat.ServerSnapshotAddTimestampUnixMilli(builder, snapshot.TimestampUnixMilli)
|
||||
flat.ServerSnapshotAddLevels(builder, levelVector)
|
||||
flat.ServerSnapshotAddEntities(builder, entityVector)
|
||||
flat.ServerSnapshotAddBlocks(builder, blockVector)
|
||||
root := flat.ServerSnapshotEnd(builder)
|
||||
flat.FinishServerSnapshotBuffer(builder, root)
|
||||
return builder.FinishedBytes()
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
module github.com/yawaflua/GoMinecraftBridge/sdk
|
||||
|
||||
go 1.24.0
|
||||
|
||||
require github.com/google/flatbuffers v25.2.10+incompatible
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package gmb
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type BlockProperty struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsBlockProperty(buf []byte, offset flatbuffers.UOffsetT) *BlockProperty {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &BlockProperty{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishBlockPropertyBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.Finish(offset)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsBlockProperty(buf []byte, offset flatbuffers.UOffsetT) *BlockProperty {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &BlockProperty{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedBlockPropertyBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.FinishSizePrefixed(offset)
|
||||
}
|
||||
|
||||
func (rcv *BlockProperty) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *BlockProperty) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *BlockProperty) Key() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *BlockProperty) Value() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func BlockPropertyStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(2)
|
||||
}
|
||||
func BlockPropertyAddKey(builder *flatbuffers.Builder, key flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(key), 0)
|
||||
}
|
||||
func BlockPropertyAddValue(builder *flatbuffers.Builder, value flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(value), 0)
|
||||
}
|
||||
func BlockPropertyEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package gmb
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type BlockSnapshot struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsBlockSnapshot(buf []byte, offset flatbuffers.UOffsetT) *BlockSnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &BlockSnapshot{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishBlockSnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.Finish(offset)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsBlockSnapshot(buf []byte, offset flatbuffers.UOffsetT) *BlockSnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &BlockSnapshot{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedBlockSnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.FinishSizePrefixed(offset)
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Dimension() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) X() int32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) MutateX(n int32) bool {
|
||||
return rcv._tab.MutateInt32Slot(6, n)
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Y() int32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) MutateY(n int32) bool {
|
||||
return rcv._tab.MutateInt32Slot(8, n)
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Z() int32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) MutateZ(n int32) bool {
|
||||
return rcv._tab.MutateInt32Slot(10, n)
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Block() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) Properties(obj *BlockProperty, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *BlockSnapshot) PropertiesLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func BlockSnapshotStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(6)
|
||||
}
|
||||
func BlockSnapshotAddDimension(builder *flatbuffers.Builder, dimension flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(dimension), 0)
|
||||
}
|
||||
func BlockSnapshotAddX(builder *flatbuffers.Builder, x int32) {
|
||||
builder.PrependInt32Slot(1, x, 0)
|
||||
}
|
||||
func BlockSnapshotAddY(builder *flatbuffers.Builder, y int32) {
|
||||
builder.PrependInt32Slot(2, y, 0)
|
||||
}
|
||||
func BlockSnapshotAddZ(builder *flatbuffers.Builder, z int32) {
|
||||
builder.PrependInt32Slot(3, z, 0)
|
||||
}
|
||||
func BlockSnapshotAddBlock(builder *flatbuffers.Builder, block flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(4, flatbuffers.UOffsetT(block), 0)
|
||||
}
|
||||
func BlockSnapshotAddProperties(builder *flatbuffers.Builder, properties flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(properties), 0)
|
||||
}
|
||||
func BlockSnapshotStartPropertiesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
}
|
||||
func BlockSnapshotEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package gmb
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type EntitySnapshot struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsEntitySnapshot(buf []byte, offset flatbuffers.UOffsetT) *EntitySnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &EntitySnapshot{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishEntitySnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.Finish(offset)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsEntitySnapshot(buf []byte, offset flatbuffers.UOffsetT) *EntitySnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &EntitySnapshot{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedEntitySnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.FinishSizePrefixed(offset)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) RuntimeId() int32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateRuntimeId(n int32) bool {
|
||||
return rcv._tab.MutateInt32Slot(4, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Uuid() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Type() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Name() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Dimension() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) X() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateX(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(14, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Y() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateY(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(16, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Z() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateZ(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(18, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Yaw() float32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateYaw(n float32) bool {
|
||||
return rcv._tab.MutateFloat32Slot(20, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Pitch() float32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutatePitch(n float32) bool {
|
||||
return rcv._tab.MutateFloat32Slot(22, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) VelocityX() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateVelocityX(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(24, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) VelocityY() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateVelocityY(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(26, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) VelocityZ() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(28))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateVelocityZ(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(28, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Alive() bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(30))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetBool(o + rcv._tab.Pos)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateAlive(n bool) bool {
|
||||
return rcv._tab.MutateBoolSlot(30, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Player() bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(32))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetBool(o + rcv._tab.Pos)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutatePlayer(n bool) bool {
|
||||
return rcv._tab.MutateBoolSlot(32, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) HasHealth() bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(34))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetBool(o + rcv._tab.Pos)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateHasHealth(n bool) bool {
|
||||
return rcv._tab.MutateBoolSlot(34, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) Health() float32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(36))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateHealth(n float32) bool {
|
||||
return rcv._tab.MutateFloat32Slot(36, n)
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MaxHealth() float32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(38))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat32(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *EntitySnapshot) MutateMaxHealth(n float32) bool {
|
||||
return rcv._tab.MutateFloat32Slot(38, n)
|
||||
}
|
||||
|
||||
func EntitySnapshotStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(18)
|
||||
}
|
||||
func EntitySnapshotAddRuntimeId(builder *flatbuffers.Builder, runtimeId int32) {
|
||||
builder.PrependInt32Slot(0, runtimeId, 0)
|
||||
}
|
||||
func EntitySnapshotAddUuid(builder *flatbuffers.Builder, uuid flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(uuid), 0)
|
||||
}
|
||||
func EntitySnapshotAddType(builder *flatbuffers.Builder, type_ flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(type_), 0)
|
||||
}
|
||||
func EntitySnapshotAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(name), 0)
|
||||
}
|
||||
func EntitySnapshotAddDimension(builder *flatbuffers.Builder, dimension flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(4, flatbuffers.UOffsetT(dimension), 0)
|
||||
}
|
||||
func EntitySnapshotAddX(builder *flatbuffers.Builder, x float64) {
|
||||
builder.PrependFloat64Slot(5, x, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddY(builder *flatbuffers.Builder, y float64) {
|
||||
builder.PrependFloat64Slot(6, y, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddZ(builder *flatbuffers.Builder, z float64) {
|
||||
builder.PrependFloat64Slot(7, z, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddYaw(builder *flatbuffers.Builder, yaw float32) {
|
||||
builder.PrependFloat32Slot(8, yaw, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddPitch(builder *flatbuffers.Builder, pitch float32) {
|
||||
builder.PrependFloat32Slot(9, pitch, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddVelocityX(builder *flatbuffers.Builder, velocityX float64) {
|
||||
builder.PrependFloat64Slot(10, velocityX, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddVelocityY(builder *flatbuffers.Builder, velocityY float64) {
|
||||
builder.PrependFloat64Slot(11, velocityY, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddVelocityZ(builder *flatbuffers.Builder, velocityZ float64) {
|
||||
builder.PrependFloat64Slot(12, velocityZ, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddAlive(builder *flatbuffers.Builder, alive bool) {
|
||||
builder.PrependBoolSlot(13, alive, false)
|
||||
}
|
||||
func EntitySnapshotAddPlayer(builder *flatbuffers.Builder, player bool) {
|
||||
builder.PrependBoolSlot(14, player, false)
|
||||
}
|
||||
func EntitySnapshotAddHasHealth(builder *flatbuffers.Builder, hasHealth bool) {
|
||||
builder.PrependBoolSlot(15, hasHealth, false)
|
||||
}
|
||||
func EntitySnapshotAddHealth(builder *flatbuffers.Builder, health float32) {
|
||||
builder.PrependFloat32Slot(16, health, 0.0)
|
||||
}
|
||||
func EntitySnapshotAddMaxHealth(builder *flatbuffers.Builder, maxHealth float32) {
|
||||
builder.PrependFloat32Slot(17, maxHealth, 0.0)
|
||||
}
|
||||
func EntitySnapshotEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package gmb
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type LevelSnapshot struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsLevelSnapshot(buf []byte, offset flatbuffers.UOffsetT) *LevelSnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &LevelSnapshot{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishLevelSnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.Finish(offset)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsLevelSnapshot(buf []byte, offset flatbuffers.UOffsetT) *LevelSnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &LevelSnapshot{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedLevelSnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.FinishSizePrefixed(offset)
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) Dimension() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) GameTime() int64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) MutateGameTime(n int64) bool {
|
||||
return rcv._tab.MutateInt64Slot(6, n)
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) DayTime() int64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) MutateDayTime(n int64) bool {
|
||||
return rcv._tab.MutateInt64Slot(8, n)
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) Raining() bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetBool(o + rcv._tab.Pos)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) MutateRaining(n bool) bool {
|
||||
return rcv._tab.MutateBoolSlot(10, n)
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) Thundering() bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetBool(o + rcv._tab.Pos)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *LevelSnapshot) MutateThundering(n bool) bool {
|
||||
return rcv._tab.MutateBoolSlot(12, n)
|
||||
}
|
||||
|
||||
func LevelSnapshotStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(5)
|
||||
}
|
||||
func LevelSnapshotAddDimension(builder *flatbuffers.Builder, dimension flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(dimension), 0)
|
||||
}
|
||||
func LevelSnapshotAddGameTime(builder *flatbuffers.Builder, gameTime int64) {
|
||||
builder.PrependInt64Slot(1, gameTime, 0)
|
||||
}
|
||||
func LevelSnapshotAddDayTime(builder *flatbuffers.Builder, dayTime int64) {
|
||||
builder.PrependInt64Slot(2, dayTime, 0)
|
||||
}
|
||||
func LevelSnapshotAddRaining(builder *flatbuffers.Builder, raining bool) {
|
||||
builder.PrependBoolSlot(3, raining, false)
|
||||
}
|
||||
func LevelSnapshotAddThundering(builder *flatbuffers.Builder, thundering bool) {
|
||||
builder.PrependBoolSlot(4, thundering, false)
|
||||
}
|
||||
func LevelSnapshotEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package gmb
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type ServerSnapshot struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
const ServerSnapshotIdentifier = "GMBS"
|
||||
|
||||
func GetRootAsServerSnapshot(buf []byte, offset flatbuffers.UOffsetT) *ServerSnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &ServerSnapshot{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishServerSnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
identifierBytes := []byte(ServerSnapshotIdentifier)
|
||||
builder.FinishWithFileIdentifier(offset, identifierBytes)
|
||||
}
|
||||
|
||||
func ServerSnapshotBufferHasIdentifier(buf []byte) bool {
|
||||
return flatbuffers.BufferHasIdentifier(buf, ServerSnapshotIdentifier)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsServerSnapshot(buf []byte, offset flatbuffers.UOffsetT) *ServerSnapshot {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &ServerSnapshot{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedServerSnapshotBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
identifierBytes := []byte(ServerSnapshotIdentifier)
|
||||
builder.FinishSizePrefixedWithFileIdentifier(offset, identifierBytes)
|
||||
}
|
||||
|
||||
func SizePrefixedServerSnapshotBufferHasIdentifier(buf []byte) bool {
|
||||
return flatbuffers.SizePrefixedBufferHasIdentifier(buf, ServerSnapshotIdentifier)
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) Tick() int64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) MutateTick(n int64) bool {
|
||||
return rcv._tab.MutateInt64Slot(4, n)
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) TimestampUnixMilli() int64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) MutateTimestampUnixMilli(n int64) bool {
|
||||
return rcv._tab.MutateInt64Slot(6, n)
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) Levels(obj *LevelSnapshot, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) LevelsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) Entities(obj *EntitySnapshot, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) EntitiesLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) Blocks(obj *BlockSnapshot, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *ServerSnapshot) BlocksLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func ServerSnapshotStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(5)
|
||||
}
|
||||
func ServerSnapshotAddTick(builder *flatbuffers.Builder, tick int64) {
|
||||
builder.PrependInt64Slot(0, tick, 0)
|
||||
}
|
||||
func ServerSnapshotAddTimestampUnixMilli(builder *flatbuffers.Builder, timestampUnixMilli int64) {
|
||||
builder.PrependInt64Slot(1, timestampUnixMilli, 0)
|
||||
}
|
||||
func ServerSnapshotAddLevels(builder *flatbuffers.Builder, levels flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(levels), 0)
|
||||
}
|
||||
func ServerSnapshotStartLevelsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
}
|
||||
func ServerSnapshotAddEntities(builder *flatbuffers.Builder, entities flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(entities), 0)
|
||||
}
|
||||
func ServerSnapshotStartEntitiesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
}
|
||||
func ServerSnapshotAddBlocks(builder *flatbuffers.Builder, blocks flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(4, flatbuffers.UOffsetT(blocks), 0)
|
||||
}
|
||||
func ServerSnapshotStartBlocksVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
}
|
||||
func ServerSnapshotEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
@@ -12,6 +12,12 @@ type TickHandler interface {
|
||||
Tick(context *Context, snapshot ServerSnapshot) error
|
||||
}
|
||||
|
||||
// ClientTickHandler is invoked only by a client native runtime. A plugin with
|
||||
// environment "both" may implement TickHandler, ClientTickHandler, or both.
|
||||
type ClientTickHandler interface {
|
||||
ClientTick(context *Context, event ClientTickEvent) error
|
||||
}
|
||||
|
||||
type ChatHandler interface {
|
||||
Chat(context *Context, event ChatEvent) error
|
||||
}
|
||||
|
||||
+14
-1
@@ -13,6 +13,7 @@ var (
|
||||
registeredPlugin Plugin
|
||||
)
|
||||
|
||||
// Register registers a plugin with the server.
|
||||
func Register(plugin Plugin) {
|
||||
if plugin == nil {
|
||||
panic("sdk: cannot register a nil plugin")
|
||||
@@ -27,6 +28,7 @@ func Register(plugin Plugin) {
|
||||
enableOutputCapture()
|
||||
}
|
||||
|
||||
// Dispatch dispatches a plugin operation to the registered plugin.
|
||||
func Dispatch(operation int, input []byte) (output []byte) {
|
||||
context := &Context{}
|
||||
result := response{Status: "ok"}
|
||||
@@ -61,6 +63,9 @@ func Dispatch(operation int, input []byte) (output []byte) {
|
||||
if metadata.APIVersion == 0 {
|
||||
metadata.APIVersion = ABIVersion
|
||||
}
|
||||
if metadata.Environment == "" {
|
||||
metadata.Environment = PluginEnvironmentServer
|
||||
}
|
||||
result.Data = metadata
|
||||
case OperationInit:
|
||||
var event InitEvent
|
||||
@@ -72,7 +77,7 @@ func Dispatch(operation int, input []byte) (output []byte) {
|
||||
}
|
||||
case OperationTick:
|
||||
var snapshot ServerSnapshot
|
||||
err = decode(input, &snapshot)
|
||||
snapshot, err = decodeTickSnapshot(input)
|
||||
if err == nil {
|
||||
if handler, ok := plugin.(TickHandler); ok {
|
||||
err = handler.Tick(context, snapshot)
|
||||
@@ -110,6 +115,14 @@ func Dispatch(operation int, input []byte) (output []byte) {
|
||||
err = handler.Deinit(context, event)
|
||||
}
|
||||
}
|
||||
case OperationClientTick:
|
||||
var event ClientTickEvent
|
||||
err = decode(input, &event)
|
||||
if err == nil {
|
||||
if handler, ok := plugin.(ClientTickHandler); ok {
|
||||
err = handler.ClientTick(context, event)
|
||||
}
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("sdk: unknown operation %d", operation)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,13 @@ func (testPlugin) Chat(context *Context, event ChatEvent) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (testPlugin) ClientTick(context *Context, event ClientTickEvent) error {
|
||||
if event.Connected {
|
||||
context.DisplayClientMessage(event.PlayerName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDispatch(t *testing.T) {
|
||||
pluginMu.Lock()
|
||||
registeredPlugin = testPlugin{}
|
||||
@@ -38,6 +45,40 @@ func TestDispatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataDefaultsToServerEnvironment(t *testing.T) {
|
||||
pluginMu.Lock()
|
||||
registeredPlugin = testPlugin{}
|
||||
pluginMu.Unlock()
|
||||
|
||||
var got struct {
|
||||
Data Metadata `json:"data"`
|
||||
}
|
||||
if err := json.Unmarshal(Dispatch(OperationMetadata, nil), &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Data.Environment != PluginEnvironmentServer {
|
||||
t.Fatalf("environment = %q, want %q", got.Data.Environment, PluginEnvironmentServer)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDispatchClientTick(t *testing.T) {
|
||||
pluginMu.Lock()
|
||||
registeredPlugin = testPlugin{}
|
||||
pluginMu.Unlock()
|
||||
|
||||
input, _ := json.Marshal(ClientTickEvent{Connected: true, PlayerName: "Client player"})
|
||||
var got response
|
||||
if err := json.Unmarshal(Dispatch(OperationClientTick, input), &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Status != "ok" || len(got.Actions) != 1 {
|
||||
t.Fatalf("unexpected client tick response: %#v", got)
|
||||
}
|
||||
if got.Actions[0].Type != "minecraft:client.chat.display" {
|
||||
t.Fatalf("action type = %q", got.Actions[0].Type)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDispatchRecoversPanic(t *testing.T) {
|
||||
pluginMu.Lock()
|
||||
registeredPlugin = testPlugin{}
|
||||
|
||||
+54
-12
@@ -2,7 +2,7 @@ package sdk
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
const ABIVersion = 1
|
||||
const ABIVersion = 2
|
||||
|
||||
const (
|
||||
OperationMetadata = 1
|
||||
@@ -12,23 +12,47 @@ const (
|
||||
OperationDeath = 5
|
||||
OperationSystemCallResult = 6
|
||||
OperationDeinit = 7
|
||||
OperationClientTick = 8
|
||||
)
|
||||
|
||||
// PluginEnvironment declares which Minecraft process may execute a plugin.
|
||||
type PluginEnvironment string
|
||||
|
||||
const (
|
||||
PluginEnvironmentServer PluginEnvironment = "server"
|
||||
PluginEnvironmentClient PluginEnvironment = "client"
|
||||
PluginEnvironmentBoth PluginEnvironment = "both"
|
||||
)
|
||||
|
||||
type Metadata struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Authors []string `json:"authors,omitempty"`
|
||||
Website string `json:"website,omitempty"`
|
||||
APIVersion int `json:"apiVersion"`
|
||||
ConfigSchema map[string]any `json:"configSchema,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Authors []string `json:"authors,omitempty"`
|
||||
Website string `json:"website,omitempty"`
|
||||
APIVersion int `json:"apiVersion"`
|
||||
ConfigSchema map[string]any `json:"configSchema,omitempty"`
|
||||
Environment PluginEnvironment `json:"environment"`
|
||||
}
|
||||
|
||||
type InitEvent struct {
|
||||
MinecraftVersion string `json:"minecraftVersion"`
|
||||
Dedicated bool `json:"dedicated"`
|
||||
DataDirectory string `json:"dataDirectory"`
|
||||
MinecraftVersion string `json:"minecraftVersion"`
|
||||
Dedicated bool `json:"dedicated"`
|
||||
DataDirectory string `json:"dataDirectory"`
|
||||
RuntimeEnvironment PluginEnvironment `json:"runtimeEnvironment"`
|
||||
}
|
||||
|
||||
// ClientTickEvent contains client-local state. Pointer-like values are empty
|
||||
// when the client is at the title screen or is not connected to a world.
|
||||
type ClientTickEvent struct {
|
||||
Tick int64 `json:"tick"`
|
||||
TimestampUnixMilli int64 `json:"timestampUnixMilli"`
|
||||
Connected bool `json:"connected"`
|
||||
ServerAddress string `json:"serverAddress,omitempty"`
|
||||
PlayerUUID string `json:"playerUuid,omitempty"`
|
||||
PlayerName string `json:"playerName,omitempty"`
|
||||
Dimension string `json:"dimension,omitempty"`
|
||||
}
|
||||
|
||||
type ServerSnapshot struct {
|
||||
@@ -105,6 +129,24 @@ type SystemCallResult struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// SystemCallType identifies a system call provided by the bridge itself.
|
||||
// Use Context.CustomSystemCall for calls registered by another mod.
|
||||
type SystemCallType string
|
||||
|
||||
const (
|
||||
SystemCallServerInfo SystemCallType = "minecraft:server.info"
|
||||
SystemCallPlayerGet SystemCallType = "minecraft:player.get"
|
||||
SystemCallBlockGet SystemCallType = "minecraft:block.get"
|
||||
SystemCallGetEntity SystemCallType = "minecraft:get_entity"
|
||||
)
|
||||
|
||||
// GetEntityRequest selects an entity by UUID or by its runtime ID.
|
||||
// Exactly one field must be set.
|
||||
type GetEntityRequest struct {
|
||||
UUID string `json:"uuid,omitempty"`
|
||||
RuntimeID *int `json:"runtimeId,omitempty"`
|
||||
}
|
||||
|
||||
type DeinitEvent struct {
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user