Poll will return early if the script is interrupted by a signal, one of the selected clients is disconnected or the configured timeout elapses.
Additionally, different native components can be enabled per-client to manage state.
-Currently only the `auth` component is available, but components like `map`, `objs`, `inv`, `pos`, `playerlist` etc. will be added in the future.
+Currently `auth` and `map` components are available, and components like `objs`, `inv`, `pos`, `player_list` etc. will be added in the future.
Components handle packets asynchronously, they will process them even if poll is not called.
# Further Documentation
--- /dev/null
+--[[ builtin/base64.lua ]]--
+
+-- Taken from: http://lua-users.org/wiki/BaseSixtyFour with minor modifications
+
+-- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss <alexthkloss@web.de>
+-- licensed under the terms of the LGPL2
+
+local base64 = {}
+package.loaded.base64 = base64
+
+-- character table string
+local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+
+-- encoding
+function base64.encode(data)
+ return ((data:gsub('.', function(x)
+ local r,b='',x:byte()
+ for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
+ return r;
+ end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
+ if (#x < 6) then return '' end
+ local c=0
+ for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
+ return b:sub(c+1,c+1)
+ end)..({ '', '==', '=' })[#data%3+1])
+end
+
+-- decoding
+function base64.decode(data)
+ data = string.gsub(data, '[^'..b..'=]', '')
+ return (data:gsub('.', function(x)
+ if (x == '=') then return '' end
+ local r,f='',(b:find(x)-1)
+ for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
+ return r;
+ end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
+ if (#x ~= 8) then return '' end
+ local c=0
+ for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
+ return string.char(c)
+ end))
+end
+
-- code taken from minetest/builtin/common/misc_helpers.lua with modifications
local escapes = {}
-package.loaded["escapes"] = escapes
+package.loaded.escapes = escapes
escapes.ESCAPE_CHAR = string.char(0x1b)
assert(type(self.x) == "number")
assert(type(self.y) == "number")
return self
- end
+ end,
+ round = function(self)
+ return vec2(math.round(self.x), math.round(self.y))
+ end,
}
function vec2(a, b)
assert(type(self.y) == "number")
assert(type(self.z) == "number")
return self
- end
+ end,
+ round = function(self)
+ return vec3(math.floor(self.x), math.floor(self.y), math.floor(self.z))
+ end,
}
function vec3(a, b, c)
switch compname {
case "auth":
component = &Auth{}
+ case "map":
+ component = &Map{}
default:
panic("invalid component: " + compname)
}
"github.com/yuin/gopher-lua"
)
-func pushAnimType(l *lua.LState, val mt.AnimType) lua.LValue {
+func PushAnimType(l *lua.LState, val mt.AnimType) lua.LValue {
switch val {
case mt.NoAnim:
return lua.LNil
return lua.LNil
}
-func pushChatMsgType(l *lua.LState, val mt.ChatMsgType) lua.LValue {
+func PushChatMsgType(l *lua.LState, val mt.ChatMsgType) lua.LValue {
switch val {
case mt.RawMsg:
return lua.LString("raw")
return lua.LNil
}
-func pushHotbarParam(l *lua.LState, val mt.HotbarParam) lua.LValue {
+func PushHotbarParam(l *lua.LState, val mt.HotbarParam) lua.LValue {
switch val {
case mt.HotbarSize:
return lua.LString("size")
return lua.LNil
}
-func pushHUDField(l *lua.LState, val mt.HUDField) lua.LValue {
+func PushHUDField(l *lua.LState, val mt.HUDField) lua.LValue {
switch val {
case mt.HUDPos:
return lua.LString("pos")
return lua.LNil
}
-func pushHUDType(l *lua.LState, val mt.HUDType) lua.LValue {
+func PushHUDType(l *lua.LState, val mt.HUDType) lua.LValue {
switch val {
case mt.ImgHUD:
return lua.LString("img")
return lua.LNil
}
-func pushKickReason(l *lua.LState, val mt.KickReason) lua.LValue {
+func PushKickReason(l *lua.LState, val mt.KickReason) lua.LValue {
switch val {
case mt.WrongPasswd:
return lua.LString("wrong_passwd")
return lua.LNil
}
-func pushModChanSig(l *lua.LState, val mt.ModChanSig) lua.LValue {
+func PushModChanSig(l *lua.LState, val mt.ModChanSig) lua.LValue {
switch val {
case mt.JoinOK:
return lua.LString("join_ok")
return lua.LNil
}
-func pushPlayerListUpdateType(l *lua.LState, val mt.PlayerListUpdateType) lua.LValue {
+func PushPlayerListUpdateType(l *lua.LState, val mt.PlayerListUpdateType) lua.LValue {
switch val {
case mt.InitPlayers:
return lua.LString("init")
return lua.LNil
}
-func pushSoundSrcType(l *lua.LState, val mt.SoundSrcType) lua.LValue {
+func PushSoundSrcType(l *lua.LState, val mt.SoundSrcType) lua.LValue {
switch val {
case mt.NoSrc:
return lua.LNil
return lua.LNil
}
-func pushAuthMethods(l *lua.LState, val mt.AuthMethods) lua.LValue {
+func PushAuthMethods(l *lua.LState, val mt.AuthMethods) lua.LValue {
tbl := l.NewTable()
- if val&mt.LegacyPasswd != 0 {
- l.SetField(tbl, "legacy_passwd", lua.LTrue)
- }
- if val&mt.SRP != 0 {
- l.SetField(tbl, "srp", lua.LTrue)
- }
- if val&mt.FirstSRP != 0 {
- l.SetField(tbl, "first_srp", lua.LTrue)
- }
+ l.SetField(tbl, "legacy_passwd", lua.LBool(val&mt.LegacyPasswd != 0))
+ l.SetField(tbl, "srp", lua.LBool(val&mt.SRP != 0))
+ l.SetField(tbl, "first_srp", lua.LBool(val&mt.FirstSRP != 0))
return tbl
}
-func pushCSMRestrictionFlags(l *lua.LState, val mt.CSMRestrictionFlags) lua.LValue {
+func PushCSMRestrictionFlags(l *lua.LState, val mt.CSMRestrictionFlags) lua.LValue {
tbl := l.NewTable()
- if val&mt.NoCSMs != 0 {
- l.SetField(tbl, "no_csms", lua.LTrue)
- }
- if val&mt.NoChatMsgs != 0 {
- l.SetField(tbl, "no_chat_msgs", lua.LTrue)
- }
- if val&mt.NoNodeDefs != 0 {
- l.SetField(tbl, "no_node_defs", lua.LTrue)
- }
- if val&mt.LimitMapRange != 0 {
- l.SetField(tbl, "limit_map_range", lua.LTrue)
- }
- if val&mt.NoPlayerList != 0 {
- l.SetField(tbl, "no_player_list", lua.LTrue)
- }
+ l.SetField(tbl, "no_csms", lua.LBool(val&mt.NoCSMs != 0))
+ l.SetField(tbl, "no_chat_msgs", lua.LBool(val&mt.NoChatMsgs != 0))
+ l.SetField(tbl, "no_node_defs", lua.LBool(val&mt.NoNodeDefs != 0))
+ l.SetField(tbl, "limit_map_range", lua.LBool(val&mt.LimitMapRange != 0))
+ l.SetField(tbl, "no_player_list", lua.LBool(val&mt.NoPlayerList != 0))
return tbl
}
-func pushHUDFlags(l *lua.LState, val mt.HUDFlags) lua.LValue {
+func PushHUDFlags(l *lua.LState, val mt.HUDFlags) lua.LValue {
tbl := l.NewTable()
- if val&mt.ShowHotbar != 0 {
- l.SetField(tbl, "hotbar", lua.LTrue)
- }
- if val&mt.ShowHealthBar != 0 {
- l.SetField(tbl, "health_bar", lua.LTrue)
- }
- if val&mt.ShowCrosshair != 0 {
- l.SetField(tbl, "crosshair", lua.LTrue)
- }
- if val&mt.ShowWieldedItem != 0 {
- l.SetField(tbl, "wielded_item", lua.LTrue)
- }
- if val&mt.ShowBreathBar != 0 {
- l.SetField(tbl, "breath_bar", lua.LTrue)
- }
- if val&mt.ShowMinimap != 0 {
- l.SetField(tbl, "minimap", lua.LTrue)
- }
- if val&mt.ShowRadarMinimap != 0 {
- l.SetField(tbl, "radar_minimap", lua.LTrue)
- }
+ l.SetField(tbl, "hotbar", lua.LBool(val&mt.ShowHotbar != 0))
+ l.SetField(tbl, "health_bar", lua.LBool(val&mt.ShowHealthBar != 0))
+ l.SetField(tbl, "crosshair", lua.LBool(val&mt.ShowCrosshair != 0))
+ l.SetField(tbl, "wielded_item", lua.LBool(val&mt.ShowWieldedItem != 0))
+ l.SetField(tbl, "breath_bar", lua.LBool(val&mt.ShowBreathBar != 0))
+ l.SetField(tbl, "minimap", lua.LBool(val&mt.ShowMinimap != 0))
+ l.SetField(tbl, "radar_minimap", lua.LBool(val&mt.ShowRadarMinimap != 0))
+ return tbl
+}
+
+func PushMapBlkFlags(l *lua.LState, val mt.MapBlkFlags) lua.LValue {
+ tbl := l.NewTable()
+ l.SetField(tbl, "is_underground", lua.LBool(val&mt.BlkIsUnderground != 0))
+ l.SetField(tbl, "day_night_diff", lua.LBool(val&mt.BlkDayNightDiff != 0))
+ l.SetField(tbl, "light_expired", lua.LBool(val&mt.BlkLightExpired != 0))
+ l.SetField(tbl, "not_generated", lua.LBool(val&mt.BlkNotGenerated != 0))
return tbl
}
-func pushHUD(l *lua.LState, val mt.HUD) lua.LValue {
+func PushHUD(l *lua.LState, val mt.HUD) lua.LValue {
tbl := l.NewTable()
- l.SetField(tbl, "align", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Align[0]), lua.LNumber(val.Align[1])}))
+ l.SetField(tbl, "align", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Align[0]), lua.LNumber(val.Align[1])}))
l.SetField(tbl, "dir", lua.LNumber(val.Dir))
l.SetField(tbl, "item", lua.LNumber(val.Item))
l.SetField(tbl, "name", lua.LString(string(val.Name)))
l.SetField(tbl, "number", lua.LNumber(val.Number))
- l.SetField(tbl, "offset", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Offset[0]), lua.LNumber(val.Offset[1])}))
- l.SetField(tbl, "pos", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1])}))
- l.SetField(tbl, "scale", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Scale[0]), lua.LNumber(val.Scale[1])}))
- l.SetField(tbl, "size", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Size[0]), lua.LNumber(val.Size[1])}))
+ l.SetField(tbl, "offset", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Offset[0]), lua.LNumber(val.Offset[1])}))
+ l.SetField(tbl, "pos", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1])}))
+ l.SetField(tbl, "scale", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Scale[0]), lua.LNumber(val.Scale[1])}))
+ l.SetField(tbl, "size", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Size[0]), lua.LNumber(val.Size[1])}))
l.SetField(tbl, "text", lua.LString(string(val.Text)))
l.SetField(tbl, "text_2", lua.LString(string(val.Text2)))
- l.SetField(tbl, "type", pushHUDType(l, val.Type))
- l.SetField(tbl, "world_pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.WorldPos[0]), lua.LNumber(val.WorldPos[1]), lua.LNumber(val.WorldPos[2])}))
+ l.SetField(tbl, "type", PushHUDType(l, val.Type))
+ l.SetField(tbl, "world_pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.WorldPos[0]), lua.LNumber(val.WorldPos[1]), lua.LNumber(val.WorldPos[2])}))
l.SetField(tbl, "z_index", lua.LNumber(val.ZIndex))
return tbl
}
-func pushNode(l *lua.LState, val mt.Node) lua.LValue {
+func PushMapBlk(l *lua.LState, val mt.MapBlk) lua.LValue {
+ tbl := l.NewTable()
+ l.SetField(tbl, "flags", PushMapBlkFlags(l, val.Flags))
+ l.SetField(tbl, "lit_from", lua.LNumber(val.LitFrom))
+ l.SetField(tbl, "node_metas", PushNodeMetas(l, val.NodeMetas))
+ l.SetField(tbl, "param0", Push4096[mt.Content](l, val.Param0))
+ l.SetField(tbl, "param1", Push4096[uint8](l, val.Param1))
+ l.SetField(tbl, "param2", Push4096[uint8](l, val.Param2))
+ return tbl
+}
+
+func PushNode(l *lua.LState, val mt.Node) lua.LValue {
tbl := l.NewTable()
l.SetField(tbl, "param0", lua.LNumber(val.Param0))
l.SetField(tbl, "param1", lua.LNumber(val.Param1))
return tbl
}
-func pushTileAnim(l *lua.LState, val mt.TileAnim) lua.LValue {
+func PushNodeMeta(l *lua.LState, val mt.NodeMeta) lua.LValue {
+ tbl := l.NewTable()
+ l.SetField(tbl, "fields", PushNodeMetaFields(l, val.Fields))
+ l.SetField(tbl, "inv", PushInv(l, val.Inv))
+ return tbl
+}
+
+func PushTileAnim(l *lua.LState, val mt.TileAnim) lua.LValue {
tbl := l.NewTable()
- l.SetField(tbl, "aspect_ratio", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.AspectRatio[0]), lua.LNumber(val.AspectRatio[1])}))
+ l.SetField(tbl, "aspect_ratio", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.AspectRatio[0]), lua.LNumber(val.AspectRatio[1])}))
l.SetField(tbl, "duration", lua.LNumber(val.Duration))
- l.SetField(tbl, "n_frames", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.NFrames[0]), lua.LNumber(val.NFrames[1])}))
- l.SetField(tbl, "type", pushAnimType(l, val.Type))
+ l.SetField(tbl, "n_frames", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.NFrames[0]), lua.LNumber(val.NFrames[1])}))
+ l.SetField(tbl, "type", PushAnimType(l, val.Type))
+ return tbl
+}
+
+func PushToolCaps(l *lua.LState, val mt.ToolCaps) lua.LValue {
+ tbl := l.NewTable()
+ l.SetField(tbl, "attack_cooldown", lua.LNumber(val.AttackCooldown))
+ l.SetField(tbl, "dmg_groups", PushGroups(l, val.DmgGroups))
+ l.SetField(tbl, "group_caps", PushGroupCaps(l, val.GroupCaps))
+ l.SetField(tbl, "max_drop_lvl", lua.LNumber(val.MaxDropLvl))
+ l.SetField(tbl, "punch_uses", lua.LNumber(val.PunchUses))
return tbl
}
switch val := pkt.Cmd.(type) {
case *mt.ToCltAcceptAuth:
l.SetField(tbl, "map_seed", lua.LNumber(val.MapSeed))
- l.SetField(tbl, "player_pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.PlayerPos[0]), lua.LNumber(val.PlayerPos[1]), lua.LNumber(val.PlayerPos[2])}))
+ l.SetField(tbl, "player_pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.PlayerPos[0]), lua.LNumber(val.PlayerPos[1]), lua.LNumber(val.PlayerPos[2])}))
l.SetField(tbl, "send_interval", lua.LNumber(val.SendInterval))
- l.SetField(tbl, "sudo_auth_methods", pushAuthMethods(l, val.SudoAuthMethods))
+ l.SetField(tbl, "sudo_auth_methods", PushAuthMethods(l, val.SudoAuthMethods))
case *mt.ToCltAddHUD:
- l.SetField(tbl, "hud", pushHUD(l, val.HUD))
+ l.SetField(tbl, "hud", PushHUD(l, val.HUD))
l.SetField(tbl, "id", lua.LNumber(val.ID))
case *mt.ToCltAddNode:
l.SetField(tbl, "keep_meta", lua.LBool(val.KeepMeta))
- l.SetField(tbl, "node", pushNode(l, val.Node))
- l.SetField(tbl, "pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
+ l.SetField(tbl, "node", PushNode(l, val.Node))
+ l.SetField(tbl, "pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
case *mt.ToCltAddParticleSpawner:
- l.SetField(tbl, "acc", pushBox3(l, [2][3]lua.LNumber{{lua.LNumber(val.Acc[0][0]), lua.LNumber(val.Acc[0][1]), lua.LNumber(val.Acc[0][2])}, {lua.LNumber(val.Acc[1][0]), lua.LNumber(val.Acc[1][1]), lua.LNumber(val.Acc[1][2])}}))
+ l.SetField(tbl, "acc", PushBox3(l, [2][3]lua.LNumber{{lua.LNumber(val.Acc[0][0]), lua.LNumber(val.Acc[0][1]), lua.LNumber(val.Acc[0][2])}, {lua.LNumber(val.Acc[1][0]), lua.LNumber(val.Acc[1][1]), lua.LNumber(val.Acc[1][2])}}))
l.SetField(tbl, "amount", lua.LNumber(val.Amount))
- l.SetField(tbl, "anim_params", pushTileAnim(l, val.AnimParams))
+ l.SetField(tbl, "anim_params", PushTileAnim(l, val.AnimParams))
l.SetField(tbl, "ao_collision", lua.LBool(val.AOCollision))
l.SetField(tbl, "collide", lua.LBool(val.Collide))
l.SetField(tbl, "collision_rm", lua.LBool(val.CollisionRm))
l.SetField(tbl, "duration", lua.LNumber(val.Duration))
- l.SetField(tbl, "expiration_time", pushBox1(l, [2]lua.LNumber{lua.LNumber(val.ExpirationTime[0]), lua.LNumber(val.ExpirationTime[1])}))
+ l.SetField(tbl, "expiration_time", PushBox1(l, [2]lua.LNumber{lua.LNumber(val.ExpirationTime[0]), lua.LNumber(val.ExpirationTime[1])}))
l.SetField(tbl, "glow", lua.LNumber(val.Glow))
l.SetField(tbl, "id", lua.LNumber(val.ID))
l.SetField(tbl, "node_param0", lua.LNumber(val.NodeParam0))
l.SetField(tbl, "node_param2", lua.LNumber(val.NodeParam2))
l.SetField(tbl, "node_tile", lua.LNumber(val.NodeTile))
- l.SetField(tbl, "pos", pushBox3(l, [2][3]lua.LNumber{{lua.LNumber(val.Pos[0][0]), lua.LNumber(val.Pos[0][1]), lua.LNumber(val.Pos[0][2])}, {lua.LNumber(val.Pos[1][0]), lua.LNumber(val.Pos[1][1]), lua.LNumber(val.Pos[1][2])}}))
- l.SetField(tbl, "size", pushBox1(l, [2]lua.LNumber{lua.LNumber(val.Size[0]), lua.LNumber(val.Size[1])}))
+ l.SetField(tbl, "pos", PushBox3(l, [2][3]lua.LNumber{{lua.LNumber(val.Pos[0][0]), lua.LNumber(val.Pos[0][1]), lua.LNumber(val.Pos[0][2])}, {lua.LNumber(val.Pos[1][0]), lua.LNumber(val.Pos[1][1]), lua.LNumber(val.Pos[1][2])}}))
+ l.SetField(tbl, "size", PushBox1(l, [2]lua.LNumber{lua.LNumber(val.Size[0]), lua.LNumber(val.Size[1])}))
l.SetField(tbl, "texture", lua.LString(string(val.Texture)))
- l.SetField(tbl, "vel", pushBox3(l, [2][3]lua.LNumber{{lua.LNumber(val.Vel[0][0]), lua.LNumber(val.Vel[0][1]), lua.LNumber(val.Vel[0][2])}, {lua.LNumber(val.Vel[1][0]), lua.LNumber(val.Vel[1][1]), lua.LNumber(val.Vel[1][2])}}))
+ l.SetField(tbl, "vel", PushBox3(l, [2][3]lua.LNumber{{lua.LNumber(val.Vel[0][0]), lua.LNumber(val.Vel[0][1]), lua.LNumber(val.Vel[0][2])}, {lua.LNumber(val.Vel[1][0]), lua.LNumber(val.Vel[1][1]), lua.LNumber(val.Vel[1][2])}}))
l.SetField(tbl, "vertical", lua.LBool(val.Vertical))
case *mt.ToCltAddPlayerVel:
- l.SetField(tbl, "vel", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Vel[0]), lua.LNumber(val.Vel[1]), lua.LNumber(val.Vel[2])}))
+ l.SetField(tbl, "vel", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Vel[0]), lua.LNumber(val.Vel[1]), lua.LNumber(val.Vel[2])}))
case *mt.ToCltBlkData:
- l.SetField(tbl, "blkpos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Blkpos[0]), lua.LNumber(val.Blkpos[1]), lua.LNumber(val.Blkpos[2])}))
+ l.SetField(tbl, "blk", PushMapBlk(l, val.Blk))
+ l.SetField(tbl, "blkpos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Blkpos[0]), lua.LNumber(val.Blkpos[1]), lua.LNumber(val.Blkpos[2])}))
case *mt.ToCltBreath:
l.SetField(tbl, "breath", lua.LNumber(val.Breath))
case *mt.ToCltChangeHUD:
if val.Field == mt.HUDAlign {
- l.SetField(tbl, "align", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Align[0]), lua.LNumber(val.Align[1])}))
+ l.SetField(tbl, "align", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Align[0]), lua.LNumber(val.Align[1])}))
}
if val.Field == mt.HUDDir {
l.SetField(tbl, "dir", lua.LNumber(val.Dir))
}
- l.SetField(tbl, "field", pushHUDField(l, val.Field))
+ l.SetField(tbl, "field", PushHUDField(l, val.Field))
l.SetField(tbl, "id", lua.LNumber(val.ID))
if val.Field == mt.HUDItem {
l.SetField(tbl, "item", lua.LNumber(val.Item))
l.SetField(tbl, "number", lua.LNumber(val.Number))
}
if val.Field == mt.HUDOffset {
- l.SetField(tbl, "offset", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Offset[0]), lua.LNumber(val.Offset[1])}))
+ l.SetField(tbl, "offset", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Offset[0]), lua.LNumber(val.Offset[1])}))
}
if val.Field == mt.HUDPos {
- l.SetField(tbl, "pos", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1])}))
+ l.SetField(tbl, "pos", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1])}))
}
if val.Field == mt.HUDSize {
- l.SetField(tbl, "size", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Size[0]), lua.LNumber(val.Size[1])}))
+ l.SetField(tbl, "size", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Size[0]), lua.LNumber(val.Size[1])}))
}
if val.Field == mt.HUDText {
l.SetField(tbl, "text", lua.LString(string(val.Text)))
l.SetField(tbl, "text_2", lua.LString(string(val.Text2)))
}
if val.Field == mt.HUDWorldPos {
- l.SetField(tbl, "world_pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.WorldPos[0]), lua.LNumber(val.WorldPos[1]), lua.LNumber(val.WorldPos[2])}))
+ l.SetField(tbl, "world_pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.WorldPos[0]), lua.LNumber(val.WorldPos[1]), lua.LNumber(val.WorldPos[2])}))
}
if val.Field == mt.HUDZIndex {
l.SetField(tbl, "z_index", lua.LNumber(val.ZIndex))
l.SetField(tbl, "sender", lua.LString(string(val.Sender)))
l.SetField(tbl, "text", lua.LString(string(val.Text)))
l.SetField(tbl, "timestamp", lua.LNumber(val.Timestamp))
- l.SetField(tbl, "type", pushChatMsgType(l, val.Type))
+ l.SetField(tbl, "type", PushChatMsgType(l, val.Type))
case *mt.ToCltCloudParams:
- l.SetField(tbl, "ambient_color", pushColor(l, val.AmbientColor))
+ l.SetField(tbl, "ambient_color", PushColor(l, val.AmbientColor))
l.SetField(tbl, "density", lua.LNumber(val.Density))
- l.SetField(tbl, "diffuse_color", pushColor(l, val.DiffuseColor))
+ l.SetField(tbl, "diffuse_color", PushColor(l, val.DiffuseColor))
l.SetField(tbl, "height", lua.LNumber(val.Height))
- l.SetField(tbl, "speed", pushVec2(l, [2]lua.LNumber{lua.LNumber(val.Speed[0]), lua.LNumber(val.Speed[1])}))
+ l.SetField(tbl, "speed", PushVec2(l, [2]lua.LNumber{lua.LNumber(val.Speed[0]), lua.LNumber(val.Speed[1])}))
l.SetField(tbl, "thickness", lua.LNumber(val.Thickness))
case *mt.ToCltCSMRestrictionFlags:
- l.SetField(tbl, "flags", pushCSMRestrictionFlags(l, val.Flags))
+ l.SetField(tbl, "flags", PushCSMRestrictionFlags(l, val.Flags))
l.SetField(tbl, "map_range", lua.LNumber(val.MapRange))
case *mt.ToCltDeathScreen:
- l.SetField(tbl, "point_at", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.PointAt[0]), lua.LNumber(val.PointAt[1]), lua.LNumber(val.PointAt[2])}))
+ l.SetField(tbl, "point_at", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.PointAt[0]), lua.LNumber(val.PointAt[1]), lua.LNumber(val.PointAt[2])}))
l.SetField(tbl, "point_cam", lua.LBool(val.PointCam))
case *mt.ToCltDelParticleSpawner:
l.SetField(tbl, "id", lua.LNumber(val.ID))
l.SetField(tbl, "len", lua.LNumber(val.Len))
l.SetField(tbl, "name", lua.LString(string(val.Name)))
case *mt.ToCltEyeOffset:
- l.SetField(tbl, "first", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.First[0]), lua.LNumber(val.First[1]), lua.LNumber(val.First[2])}))
- l.SetField(tbl, "third", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Third[0]), lua.LNumber(val.Third[1]), lua.LNumber(val.Third[2])}))
+ l.SetField(tbl, "first", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.First[0]), lua.LNumber(val.First[1]), lua.LNumber(val.First[2])}))
+ l.SetField(tbl, "third", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Third[0]), lua.LNumber(val.Third[1]), lua.LNumber(val.Third[2])}))
case *mt.ToCltFadeSound:
l.SetField(tbl, "gain", lua.LNumber(val.Gain))
l.SetField(tbl, "id", lua.LNumber(val.ID))
l.SetField(tbl, "multiplier", lua.LBool(val.Multiplier))
l.SetField(tbl, "transition_time", lua.LNumber(val.TransitionTime))
case *mt.ToCltHello:
- l.SetField(tbl, "auth_methods", pushAuthMethods(l, val.AuthMethods))
+ l.SetField(tbl, "auth_methods", PushAuthMethods(l, val.AuthMethods))
l.SetField(tbl, "compression", lua.LNumber(val.Compression))
l.SetField(tbl, "proto_ver", lua.LNumber(val.ProtoVer))
l.SetField(tbl, "serialize_ver", lua.LNumber(val.SerializeVer))
case *mt.ToCltHP:
l.SetField(tbl, "hp", lua.LNumber(val.HP))
case *mt.ToCltHUDFlags:
- l.SetField(tbl, "flags", pushHUDFlags(l, val.Flags))
- l.SetField(tbl, "mask", pushHUDFlags(l, val.Mask))
+ l.SetField(tbl, "flags", PushHUDFlags(l, val.Flags))
+ l.SetField(tbl, "mask", PushHUDFlags(l, val.Mask))
case *mt.ToCltInv:
l.SetField(tbl, "inv", lua.LString(string(val.Inv)))
case *mt.ToCltInvFormspec:
if val.Reason == mt.Custom || val.Reason == mt.Shutdown || val.Reason == mt.Crash {
l.SetField(tbl, "custom", lua.LString(string(val.Custom)))
}
- l.SetField(tbl, "reason", pushKickReason(l, val.Reason))
+ l.SetField(tbl, "reason", PushKickReason(l, val.Reason))
if val.Reason == mt.Shutdown || val.Reason == mt.Crash {
l.SetField(tbl, "reconnect", lua.LBool(val.Reconnect))
}
case *mt.ToCltLegacyKick:
l.SetField(tbl, "reason", lua.LString(string(val.Reason)))
case *mt.ToCltLocalPlayerAnim:
- l.SetField(tbl, "dig", pushBox1(l, [2]lua.LNumber{lua.LNumber(val.Dig[0]), lua.LNumber(val.Dig[1])}))
- l.SetField(tbl, "idle", pushBox1(l, [2]lua.LNumber{lua.LNumber(val.Idle[0]), lua.LNumber(val.Idle[1])}))
+ l.SetField(tbl, "dig", PushBox1(l, [2]lua.LNumber{lua.LNumber(val.Dig[0]), lua.LNumber(val.Dig[1])}))
+ l.SetField(tbl, "idle", PushBox1(l, [2]lua.LNumber{lua.LNumber(val.Idle[0]), lua.LNumber(val.Idle[1])}))
l.SetField(tbl, "speed", lua.LNumber(val.Speed))
- l.SetField(tbl, "walk", pushBox1(l, [2]lua.LNumber{lua.LNumber(val.Walk[0]), lua.LNumber(val.Walk[1])}))
- l.SetField(tbl, "walk_dig", pushBox1(l, [2]lua.LNumber{lua.LNumber(val.WalkDig[0]), lua.LNumber(val.WalkDig[1])}))
+ l.SetField(tbl, "walk", PushBox1(l, [2]lua.LNumber{lua.LNumber(val.Walk[0]), lua.LNumber(val.Walk[1])}))
+ l.SetField(tbl, "walk_dig", PushBox1(l, [2]lua.LNumber{lua.LNumber(val.WalkDig[0]), lua.LNumber(val.WalkDig[1])}))
case *mt.ToCltMediaPush:
l.SetField(tbl, "data", lua.LString(string(val.Data)))
l.SetField(tbl, "filename", lua.LString(string(val.Filename)))
l.SetField(tbl, "sender", lua.LString(string(val.Sender)))
case *mt.ToCltModChanSig:
l.SetField(tbl, "channel", lua.LString(string(val.Channel)))
- l.SetField(tbl, "signal", pushModChanSig(l, val.Signal))
+ l.SetField(tbl, "signal", PushModChanSig(l, val.Signal))
case *mt.ToCltMoonParams:
l.SetField(tbl, "size", lua.LNumber(val.Size))
l.SetField(tbl, "texture", lua.LString(string(val.Texture)))
l.SetField(tbl, "visible", lua.LBool(val.Visible))
case *mt.ToCltMovePlayer:
l.SetField(tbl, "pitch", lua.LNumber(val.Pitch))
- l.SetField(tbl, "pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
+ l.SetField(tbl, "pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
l.SetField(tbl, "yaw", lua.LNumber(val.Yaw))
case *mt.ToCltMovement:
l.SetField(tbl, "air_accel", lua.LNumber(val.AirAccel))
l.SetField(tbl, "sink", lua.LNumber(val.Sink))
l.SetField(tbl, "smoothing", lua.LNumber(val.Smoothing))
l.SetField(tbl, "walk_speed", lua.LNumber(val.WalkSpeed))
+ case *mt.ToCltNodeMetasChanged:
+ l.SetField(tbl, "changed", PushChangedNodeMetas(l, val.Changed))
case *mt.ToCltOverrideDayNightRatio:
l.SetField(tbl, "override", lua.LBool(val.Override))
l.SetField(tbl, "ratio", lua.LNumber(val.Ratio))
l.SetField(tbl, "loop", lua.LBool(val.Loop))
l.SetField(tbl, "name", lua.LString(string(val.Name)))
l.SetField(tbl, "pitch", lua.LNumber(val.Pitch))
- l.SetField(tbl, "pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
+ l.SetField(tbl, "pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
l.SetField(tbl, "src_aoid", lua.LNumber(val.SrcAOID))
- l.SetField(tbl, "src_type", pushSoundSrcType(l, val.SrcType))
+ l.SetField(tbl, "src_type", PushSoundSrcType(l, val.SrcType))
case *mt.ToCltPrivs:
- l.SetField(tbl, "privs", pushStringSet(l, val.Privs))
+ l.SetField(tbl, "privs", PushStringSet(l, val.Privs))
case *mt.ToCltRemoveNode:
- l.SetField(tbl, "pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
+ l.SetField(tbl, "pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
case *mt.ToCltRmHUD:
l.SetField(tbl, "id", lua.LNumber(val.ID))
case *mt.ToCltSetHotbarParam:
l.SetField(tbl, "img", lua.LString(string(val.Img)))
- l.SetField(tbl, "param", pushHotbarParam(l, val.Param))
+ l.SetField(tbl, "param", PushHotbarParam(l, val.Param))
l.SetField(tbl, "size", lua.LNumber(val.Size))
case *mt.ToCltShowFormspec:
l.SetField(tbl, "formname", lua.LString(string(val.Formname)))
l.SetField(tbl, "formspec", lua.LString(string(val.Formspec)))
case *mt.ToCltSkyParams:
- l.SetField(tbl, "bg_color", pushColor(l, val.BgColor))
+ l.SetField(tbl, "bg_color", PushColor(l, val.BgColor))
l.SetField(tbl, "clouds", lua.LBool(val.Clouds))
if val.Type == "regular" {
- l.SetField(tbl, "dawn_horizon", pushColor(l, val.DawnHorizon))
+ l.SetField(tbl, "dawn_horizon", PushColor(l, val.DawnHorizon))
}
if val.Type == "regular" {
- l.SetField(tbl, "dawn_sky", pushColor(l, val.DawnSky))
+ l.SetField(tbl, "dawn_sky", PushColor(l, val.DawnSky))
}
if val.Type == "regular" {
- l.SetField(tbl, "day_horizon", pushColor(l, val.DayHorizon))
+ l.SetField(tbl, "day_horizon", PushColor(l, val.DayHorizon))
}
if val.Type == "regular" {
- l.SetField(tbl, "day_sky", pushColor(l, val.DaySky))
+ l.SetField(tbl, "day_sky", PushColor(l, val.DaySky))
}
l.SetField(tbl, "fog_tint_type", lua.LString(string(val.FogTintType)))
if val.Type == "regular" {
- l.SetField(tbl, "indoor", pushColor(l, val.Indoor))
+ l.SetField(tbl, "indoor", PushColor(l, val.Indoor))
}
- l.SetField(tbl, "moon_fog_tint", pushColor(l, val.MoonFogTint))
+ l.SetField(tbl, "moon_fog_tint", PushColor(l, val.MoonFogTint))
if val.Type == "regular" {
- l.SetField(tbl, "night_horizon", pushColor(l, val.NightHorizon))
+ l.SetField(tbl, "night_horizon", PushColor(l, val.NightHorizon))
}
if val.Type == "regular" {
- l.SetField(tbl, "night_sky", pushColor(l, val.NightSky))
+ l.SetField(tbl, "night_sky", PushColor(l, val.NightSky))
}
- l.SetField(tbl, "sun_fog_tint", pushColor(l, val.SunFogTint))
+ l.SetField(tbl, "sun_fog_tint", PushColor(l, val.SunFogTint))
if val.Type == "skybox" {
- l.SetField(tbl, "textures", pushTextureList(l, val.Textures))
+ l.SetField(tbl, "textures", PushStringList[mt.Texture](l, val.Textures))
}
l.SetField(tbl, "type", lua.LString(string(val.Type)))
case *mt.ToCltSpawnParticle:
- l.SetField(tbl, "acc", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Acc[0]), lua.LNumber(val.Acc[1]), lua.LNumber(val.Acc[2])}))
- l.SetField(tbl, "anim_params", pushTileAnim(l, val.AnimParams))
+ l.SetField(tbl, "acc", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Acc[0]), lua.LNumber(val.Acc[1]), lua.LNumber(val.Acc[2])}))
+ l.SetField(tbl, "anim_params", PushTileAnim(l, val.AnimParams))
l.SetField(tbl, "ao_collision", lua.LBool(val.AOCollision))
l.SetField(tbl, "collide", lua.LBool(val.Collide))
l.SetField(tbl, "collision_rm", lua.LBool(val.CollisionRm))
l.SetField(tbl, "node_param0", lua.LNumber(val.NodeParam0))
l.SetField(tbl, "node_param2", lua.LNumber(val.NodeParam2))
l.SetField(tbl, "node_tile", lua.LNumber(val.NodeTile))
- l.SetField(tbl, "pos", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
+ l.SetField(tbl, "pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1]), lua.LNumber(val.Pos[2])}))
l.SetField(tbl, "size", lua.LNumber(val.Size))
l.SetField(tbl, "texture", lua.LString(string(val.Texture)))
- l.SetField(tbl, "vel", pushVec3(l, [3]lua.LNumber{lua.LNumber(val.Vel[0]), lua.LNumber(val.Vel[1]), lua.LNumber(val.Vel[2])}))
+ l.SetField(tbl, "vel", PushVec3(l, [3]lua.LNumber{lua.LNumber(val.Vel[0]), lua.LNumber(val.Vel[1]), lua.LNumber(val.Vel[2])}))
l.SetField(tbl, "vertical", lua.LBool(val.Vertical))
case *mt.ToCltSRPBytesSaltB:
l.SetField(tbl, "b", lua.LString(string(val.B)))
l.SetField(tbl, "salt", lua.LString(string(val.Salt)))
case *mt.ToCltStarParams:
- l.SetField(tbl, "color", pushColor(l, val.Color))
+ l.SetField(tbl, "color", PushColor(l, val.Color))
l.SetField(tbl, "count", lua.LNumber(val.Count))
l.SetField(tbl, "size", lua.LNumber(val.Size))
l.SetField(tbl, "visible", lua.LBool(val.Visible))
l.SetField(tbl, "speed", lua.LNumber(val.Speed))
l.SetField(tbl, "time", lua.LNumber(val.Time))
case *mt.ToCltUpdatePlayerList:
- l.SetField(tbl, "players", pushStringList(l, val.Players))
- l.SetField(tbl, "type", pushPlayerListUpdateType(l, val.Type))
+ l.SetField(tbl, "players", PushStringList[string](l, val.Players))
+ l.SetField(tbl, "type", PushPlayerListUpdateType(l, val.Type))
}
return tbl
}
for name, fields in spairs(parse_spec("client/enum")) do
local camel = camel_case(name)
- funcs = funcs .. "func push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\tswitch val {\n"
+ funcs = funcs .. "func Push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\tswitch val {\n"
for _, var in ipairs(fields) do
funcs = funcs .. "\tcase mt." .. apply_prefix(fields, var) .. ":\n\t\t" ..
for name, fields in spairs(parse_spec("client/flag")) do
local camel = camel_case(name)
- funcs = funcs .. "func push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
+ funcs = funcs .. "func Push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
for _, var in ipairs(fields) do
- funcs = funcs .. "\tif val&mt." .. apply_prefix(fields, var)
- .. " != 0 {\n\t\tl.SetField(tbl, \"" .. var .. "\", lua.LTrue)\n\t}\n"
+ funcs = funcs .. "\tl.SetField(tbl, \"" .. var .. "\", lua.LBool(val&mt." .. apply_prefix(fields, var) .. " != 0))\n"
end
funcs = funcs .. "\treturn tbl\n}\n\n"
fixed_string = "lua.LString(string(VAL[:]))",
boolean = "lua.LBool(VAL)",
number = "lua.LNumber(VAL)",
- vec2 = "pushVec2(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
- vec3 = "pushVec3(l, [3]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1]), lua.LNumber(VAL[2])})",
- box1 = "pushBox1(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
- box2 = "pushBox2(l, [2][2]lua.LNumber{{lua.LNumber(VAL[0][0]), lua.LNumber(VAL[0][1])}, {lua.LNumber(VAL[1][0]), lua.LNumber(VAL[1][1])}})",
- box3 = "pushBox3(l, [2][3]lua.LNumber{{lua.LNumber(VAL[0][0]), lua.LNumber(VAL[0][1]), lua.LNumber(VAL[0][2])}, {lua.LNumber(VAL[1][0]), lua.LNumber(VAL[1][1]), lua.LNumber(VAL[1][2])}})",
+ vec2 = "PushVec2(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
+ vec3 = "PushVec3(l, [3]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1]), lua.LNumber(VAL[2])})",
+ box1 = "PushBox1(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
+ box2 = "PushBox2(l, [2][2]lua.LNumber{{lua.LNumber(VAL[0][0]), lua.LNumber(VAL[0][1])}, {lua.LNumber(VAL[1][0]), lua.LNumber(VAL[1][1])}})",
+ box3 = "PushBox3(l, [2][3]lua.LNumber{{lua.LNumber(VAL[0][0]), lua.LNumber(VAL[0][1]), lua.LNumber(VAL[0][2])}, {lua.LNumber(VAL[1][0]), lua.LNumber(VAL[1][1]), lua.LNumber(VAL[1][2])}})",
}
local function fields_tolua(fields, indent)
local impl = ""
for name, type in spairs(fields) do
- if name:sub(1, 1) ~= "{" then
+ local c = name:sub(1, 1)
+ if c ~= "{" and c ~= "%" then
local camel = "val." .. camel_case(name)
local idt = indent
local condition = fields["{" .. name .. "}"]
+ local typeparam = fields["%" .. name .. "%"]
if condition then
impl = impl .. indent .. "if " .. condition .. " {\n"
if tolua[type] then
impl = impl .. tolua[type]:gsub("VAL", camel)
else
- impl = impl .. "push" .. camel_case(type) .. "(l, " .. camel .. ")"
+ impl = impl .. "Push" .. camel_case(type)
+ .. (typeparam and "[" .. typeparam .. "]" or "")
+ .. "(l, " .. camel .. ")"
end
impl = impl .. ")\n"
for name, fields in spairs(parse_spec("client/struct", true)) do
local camel = camel_case(name)
funcs = funcs
- .. "func push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
+ .. "func Push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
.. fields_tolua(fields, "\t")
.. "\treturn tbl\n}\n\n"
end
//go:generate ./push_mkauto.lua
-func vec2(l *lua.LState, val [2]lua.LNumber) {
+func CreateVec2(l *lua.LState, val [2]lua.LNumber) {
l.Push(l.GetGlobal("vec2"))
l.Push(val[0])
l.Push(val[1])
l.Call(2, 1)
}
-func vec3(l *lua.LState, val [3]lua.LNumber) {
+func CreateVec3(l *lua.LState, val [3]lua.LNumber) {
l.Push(l.GetGlobal("vec3"))
l.Push(val[0])
l.Push(val[1])
return ret
}
-func pushVec2(l *lua.LState, val [2]lua.LNumber) lua.LValue {
- vec2(l, val)
+func PushVec2(l *lua.LState, val [2]lua.LNumber) lua.LValue {
+ CreateVec2(l, val)
return popValue(l)
}
-func pushVec3(l *lua.LState, val [3]lua.LNumber) lua.LValue {
- vec3(l, val)
+func PushVec3(l *lua.LState, val [3]lua.LNumber) lua.LValue {
+ CreateVec3(l, val)
return popValue(l)
}
-func pushBox1(l *lua.LState, val [2]lua.LNumber) lua.LValue {
+func PushBox1(l *lua.LState, val [2]lua.LNumber) lua.LValue {
l.Push(l.GetGlobal("box"))
l.Push(val[0])
l.Push(val[1])
return popValue(l)
}
-func pushBox2(l *lua.LState, val [2][2]lua.LNumber) lua.LValue {
+func PushBox2(l *lua.LState, val [2][2]lua.LNumber) lua.LValue {
l.Push(l.GetGlobal("box"))
- vec2(l, val[0])
- vec2(l, val[1])
+ CreateVec2(l, val[0])
+ CreateVec2(l, val[1])
l.Call(2, 1)
return popValue(l)
}
-func pushBox3(l *lua.LState, val [2][3]lua.LNumber) lua.LValue {
+func PushBox3(l *lua.LState, val [2][3]lua.LNumber) lua.LValue {
l.Push(l.GetGlobal("box"))
- vec3(l, val[0])
- vec3(l, val[1])
+ CreateVec3(l, val[0])
+ CreateVec3(l, val[1])
l.Call(2, 1)
return popValue(l)
}
-func pushColor(l *lua.LState, val color.NRGBA) lua.LValue {
+func PushColor(l *lua.LState, val color.NRGBA) lua.LValue {
tbl := l.NewTable()
l.SetField(tbl, "r", lua.LNumber(val.R))
l.SetField(tbl, "g", lua.LNumber(val.G))
return tbl
}
-func pushStringSet(l *lua.LState, val []string) lua.LValue {
+func PushStringSet(l *lua.LState, val []string) lua.LValue {
tbl := l.NewTable()
for _, str := range val {
l.SetField(tbl, str, lua.LTrue)
return tbl
}
-func stringList[T ~string](l *lua.LState, val []T) lua.LValue {
+func PushStringList[T ~string](l *lua.LState, val []T) lua.LValue {
tbl := l.NewTable()
for _, s := range val {
tbl.Append(lua.LString(s))
return tbl
}
-func pushStringList(l *lua.LState, val []string) lua.LValue {
- return stringList[string](l, val)
+func Push4096[T uint8 | mt.Content](l *lua.LState, val [4096]T) lua.LValue {
+ tbl := l.NewTable()
+ for i, v := range val {
+ l.RawSetInt(tbl, i, lua.LNumber(v))
+ }
+ return tbl
+}
+
+func PushFields(l *lua.LState, val []mt.Field) lua.LValue {
+ tbl := l.NewTable()
+ for _, pair := range val {
+ l.SetField(tbl, pair.Name, lua.LString(pair.Value))
+ }
+ return tbl
+}
+
+func PushNodeMetaFields(l *lua.LState, val []mt.NodeMetaField) lua.LValue {
+ tbl := l.NewTable()
+ for _, pair := range val {
+ l.SetField(tbl, pair.Name, lua.LString(pair.Value))
+ }
+ return tbl
+}
+
+func PushInv(l *lua.LState, val mt.Inv) lua.LValue {
+ linv := l.NewTable()
+ for _, list := range val {
+ llist := l.NewTable()
+ l.SetField(llist, "width", lua.LNumber(list.Width))
+ for _, stack := range list.Stacks {
+ lmeta := l.NewTable()
+ l.SetField(lmeta, "fields", PushFields(l, stack.Fields()))
+ if toolcaps, ok := stack.ToolCaps(); ok {
+ l.SetField(lmeta, "tool_caps", PushToolCaps(l, toolcaps))
+ }
+
+ lstack := l.NewTable()
+ l.SetField(lstack, "name", lua.LString(stack.Name))
+ l.SetField(lstack, "count", lua.LNumber(stack.Count))
+ l.SetField(lstack, "wear", lua.LNumber(stack.Wear))
+ l.SetField(lstack, "meta", lmeta)
+
+ llist.Append(lstack)
+ }
+ l.SetField(linv, list.Name, llist)
+ }
+ return linv
+}
+
+func PushNodeMetas(l *lua.LState, val map[uint16]*mt.NodeMeta) lua.LValue {
+ tbl := l.NewTable()
+ for i, meta := range val {
+ l.RawSetInt(tbl, int(i), PushNodeMeta(l, *meta))
+ }
+ return tbl
+}
+
+func PushChangedNodeMetas(l *lua.LState, val map[[3]int16]*mt.NodeMeta) lua.LValue {
+ lmetas := l.NewTable()
+ for pos, meta := range val {
+ lmeta := l.NewTable()
+ l.SetField(lmeta, "pos", PushVec3(l, [3]lua.LNumber{lua.LNumber(pos[0]), lua.LNumber(pos[1]), lua.LNumber(pos[2])}))
+ l.SetField(lmeta, "meta", PushNodeMeta(l, *meta))
+ lmetas.Append(lmeta)
+ }
+ return lmetas
}
-func pushTextureList(l *lua.LState, val []mt.Texture) lua.LValue {
- return stringList[mt.Texture](l, val)
+func PushGroups(l *lua.LState, val []mt.Group) lua.LValue {
+ tbl := l.NewTable()
+ for _, group := range val {
+ l.SetField(tbl, group.Name, lua.LNumber(group.Rating))
+ }
+ return tbl
+}
+
+func PushGroupCaps(l *lua.LState, val []mt.ToolGroupCap) lua.LValue {
+ lcaps := l.NewTable()
+ for _, groupcap := range val {
+ ltimes := l.NewTable()
+ for _, digtime := range groupcap.Times {
+ l.RawSetInt(ltimes, int(digtime.Rating), lua.LNumber(digtime.Time))
+ }
+
+ lcap := l.NewTable()
+ l.SetField(lcap, "uses", lua.LNumber(groupcap.Uses))
+ l.SetField(lcap, "max_lvl", lua.LNumber(groupcap.MaxLvl))
+ l.SetField(lcap, "times", ltimes)
+
+ l.SetField(lcaps, groupcap.Name, lcap)
+ }
+ return lcaps
}
import (
"github.com/anon55555/mt"
"github.com/yuin/gopher-lua"
+ "math"
)
-func readAOID(l *lua.LState, val lua.LValue, ptr *mt.AOID) {
+func ReadAOID(l *lua.LState, val lua.LValue, ptr *mt.AOID) {
if val.Type() != lua.LTNumber {
panic("invalid value for AOID: must be a number")
}
- *ptr = mt.AOID(val.(lua.LNumber))
+ *ptr = mt.AOID(math.Round(float64(val.(lua.LNumber))))
}
-func readCompressionModes(l *lua.LState, val lua.LValue, ptr *mt.CompressionModes) {
+func ReadCompressionModes(l *lua.LState, val lua.LValue, ptr *mt.CompressionModes) {
if val.Type() != lua.LTNumber {
panic("invalid value for CompressionModes: must be a number")
}
- *ptr = mt.CompressionModes(val.(lua.LNumber))
+ *ptr = mt.CompressionModes(math.Round(float64(val.(lua.LNumber))))
}
-func readInt16(l *lua.LState, val lua.LValue, ptr *int16) {
+func ReadInt16(l *lua.LState, val lua.LValue, ptr *int16) {
if val.Type() != lua.LTNumber {
panic("invalid value for int16: must be a number")
}
- *ptr = int16(val.(lua.LNumber))
+ *ptr = int16(math.Round(float64(val.(lua.LNumber))))
}
-func readInt32(l *lua.LState, val lua.LValue, ptr *int32) {
+func ReadInt32(l *lua.LState, val lua.LValue, ptr *int32) {
if val.Type() != lua.LTNumber {
panic("invalid value for int32: must be a number")
}
- *ptr = int32(val.(lua.LNumber))
+ *ptr = int32(math.Round(float64(val.(lua.LNumber))))
}
-func readInteraction(l *lua.LState, val lua.LValue, ptr *mt.Interaction) {
+func ReadInteraction(l *lua.LState, val lua.LValue, ptr *mt.Interaction) {
if val.Type() != lua.LTString {
panic("invalid value for Interaction: must be a string")
}
}
}
-func readKeys(l *lua.LState, val lua.LValue, ptr *mt.Keys) {
+func ReadKeys(l *lua.LState, val lua.LValue, ptr *mt.Keys) {
if val.Type() != lua.LTTable {
panic("invalid value for Keys: must be a table")
}
}
}
-func readPlayerPos(l *lua.LState, val lua.LValue, ptr *mt.PlayerPos) {
+func ReadPlayerPos(l *lua.LState, val lua.LValue, ptr *mt.PlayerPos) {
if val.Type() != lua.LTTable {
panic("invalid value for PlayerPos: must be a table")
}
- readUint8(l, l.GetField(val, "fov80"), &ptr.FOV80)
- readKeys(l, l.GetField(val, "keys"), &ptr.Keys)
- readInt32(l, l.GetField(val, "pitch100"), &ptr.Pitch100)
- readVec3Int32(l, l.GetField(val, "pos100"), &ptr.Pos100)
- readVec3Int32(l, l.GetField(val, "vel100"), &ptr.Vel100)
- readUint8(l, l.GetField(val, "wanted_range"), &ptr.WantedRange)
- readInt32(l, l.GetField(val, "yaw100"), &ptr.Yaw100)
+ ReadUint8(l, l.GetField(val, "fov80"), &ptr.FOV80)
+ ReadKeys(l, l.GetField(val, "keys"), &ptr.Keys)
+ ReadInt32(l, l.GetField(val, "pitch100"), &ptr.Pitch100)
+ ReadVec3Int32(l, l.GetField(val, "pos100"), &ptr.Pos100)
+ ReadVec3Int32(l, l.GetField(val, "vel100"), &ptr.Vel100)
+ ReadUint8(l, l.GetField(val, "wanted_range"), &ptr.WantedRange)
+ ReadInt32(l, l.GetField(val, "yaw100"), &ptr.Yaw100)
}
-func readSliceSoundID(l *lua.LState, val lua.LValue, ptr *[]mt.SoundID) {
+func ReadSliceSoundID(l *lua.LState, val lua.LValue, ptr *[]mt.SoundID) {
if val.Type() != lua.LTTable {
panic("invalid value for []SoundID: must be a table")
}
n := tbl.MaxN()
*ptr = make([]mt.SoundID, n)
for i := range *ptr {
- readSoundID(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
+ ReadSoundID(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
}
}
-func readSliceString(l *lua.LState, val lua.LValue, ptr *[]string) {
+func ReadSliceString(l *lua.LState, val lua.LValue, ptr *[]string) {
if val.Type() != lua.LTTable {
panic("invalid value for []string: must be a table")
}
n := tbl.MaxN()
*ptr = make([]string, n)
for i := range *ptr {
- readString(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
+ ReadString(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
}
}
-func readSliceVec3Int16(l *lua.LState, val lua.LValue, ptr *[][3]int16) {
+func ReadSliceVec3Int16(l *lua.LState, val lua.LValue, ptr *[][3]int16) {
if val.Type() != lua.LTTable {
panic("invalid value for [][3]int16: must be a table")
}
n := tbl.MaxN()
*ptr = make([][3]int16, n)
for i := range *ptr {
- readVec3Int16(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
+ ReadVec3Int16(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
}
}
-func readSoundID(l *lua.LState, val lua.LValue, ptr *mt.SoundID) {
+func ReadSoundID(l *lua.LState, val lua.LValue, ptr *mt.SoundID) {
if val.Type() != lua.LTNumber {
panic("invalid value for SoundID: must be a number")
}
- *ptr = mt.SoundID(val.(lua.LNumber))
+ *ptr = mt.SoundID(math.Round(float64(val.(lua.LNumber))))
}
-func readUint16(l *lua.LState, val lua.LValue, ptr *uint16) {
+func ReadUint16(l *lua.LState, val lua.LValue, ptr *uint16) {
if val.Type() != lua.LTNumber {
panic("invalid value for uint16: must be a number")
}
- *ptr = uint16(val.(lua.LNumber))
+ *ptr = uint16(math.Round(float64(val.(lua.LNumber))))
}
-func readUint8(l *lua.LState, val lua.LValue, ptr *uint8) {
+func ReadUint8(l *lua.LState, val lua.LValue, ptr *uint8) {
if val.Type() != lua.LTNumber {
panic("invalid value for uint8: must be a number")
}
- *ptr = uint8(val.(lua.LNumber))
+ *ptr = uint8(math.Round(float64(val.(lua.LNumber))))
}
-func readVec3Int16(l *lua.LState, val lua.LValue, ptr *[3]int16) {
+func ReadVec3Int16(l *lua.LState, val lua.LValue, ptr *[3]int16) {
if val.Type() != lua.LTTable {
panic("invalid value for [3]int16: must be a table")
}
- readInt16(l, l.GetField(val, "x"), &(*ptr)[0])
- readInt16(l, l.GetField(val, "y"), &(*ptr)[1])
- readInt16(l, l.GetField(val, "z"), &(*ptr)[2])
+ ReadInt16(l, l.GetField(val, "x"), &(*ptr)[0])
+ ReadInt16(l, l.GetField(val, "y"), &(*ptr)[1])
+ ReadInt16(l, l.GetField(val, "z"), &(*ptr)[2])
}
-func readVec3Int32(l *lua.LState, val lua.LValue, ptr *[3]int32) {
+func ReadVec3Int32(l *lua.LState, val lua.LValue, ptr *[3]int32) {
if val.Type() != lua.LTTable {
panic("invalid value for [3]int32: must be a table")
}
- readInt32(l, l.GetField(val, "x"), &(*ptr)[0])
- readInt32(l, l.GetField(val, "y"), &(*ptr)[1])
- readInt32(l, l.GetField(val, "z"), &(*ptr)[2])
+ ReadInt32(l, l.GetField(val, "x"), &(*ptr)[0])
+ ReadInt32(l, l.GetField(val, "y"), &(*ptr)[1])
+ ReadInt32(l, l.GetField(val, "z"), &(*ptr)[2])
}
func ReadCmd(l *lua.LState) mt.Cmd {
case "chat_msg":
ptr := &mt.ToSrvChatMsg{}
val := l.CheckTable(3)
- readString(l, l.GetField(val, "msg"), &ptr.Msg)
+ ReadString(l, l.GetField(val, "msg"), &ptr.Msg)
return ptr
case "clt_ready":
ptr := &mt.ToSrvCltReady{}
val := l.CheckTable(3)
- readUint16(l, l.GetField(val, "formspec"), &ptr.Formspec)
- readUint8(l, l.GetField(val, "major"), &ptr.Major)
- readUint8(l, l.GetField(val, "minor"), &ptr.Minor)
- readUint8(l, l.GetField(val, "patch"), &ptr.Patch)
- readString(l, l.GetField(val, "version"), &ptr.Version)
+ ReadUint16(l, l.GetField(val, "formspec"), &ptr.Formspec)
+ ReadUint8(l, l.GetField(val, "major"), &ptr.Major)
+ ReadUint8(l, l.GetField(val, "minor"), &ptr.Minor)
+ ReadUint8(l, l.GetField(val, "patch"), &ptr.Patch)
+ ReadString(l, l.GetField(val, "version"), &ptr.Version)
return ptr
case "deleted_blks":
ptr := &mt.ToSrvDeletedBlks{}
val := l.CheckTable(3)
- readSliceVec3Int16(l, l.GetField(val, "blks"), &ptr.Blks)
+ ReadSliceVec3Int16(l, l.GetField(val, "blks"), &ptr.Blks)
return ptr
case "fall_dmg":
ptr := &mt.ToSrvFallDmg{}
val := l.CheckTable(3)
- readUint16(l, l.GetField(val, "amount"), &ptr.Amount)
+ ReadUint16(l, l.GetField(val, "amount"), &ptr.Amount)
return ptr
case "first_srp":
ptr := &mt.ToSrvFirstSRP{}
val := l.CheckTable(3)
- readBool(l, l.GetField(val, "empty_passwd"), &ptr.EmptyPasswd)
- readSliceByte(l, l.GetField(val, "salt"), &ptr.Salt)
- readSliceByte(l, l.GetField(val, "verifier"), &ptr.Verifier)
+ ReadBool(l, l.GetField(val, "empty_passwd"), &ptr.EmptyPasswd)
+ ReadSliceByte(l, l.GetField(val, "salt"), &ptr.Salt)
+ ReadSliceByte(l, l.GetField(val, "verifier"), &ptr.Verifier)
return ptr
case "got_blks":
ptr := &mt.ToSrvGotBlks{}
val := l.CheckTable(3)
- readSliceVec3Int16(l, l.GetField(val, "blks"), &ptr.Blks)
+ ReadSliceVec3Int16(l, l.GetField(val, "blks"), &ptr.Blks)
return ptr
case "init":
ptr := &mt.ToSrvInit{}
val := l.CheckTable(3)
- readUint16(l, l.GetField(val, "max_proto_ver"), &ptr.MaxProtoVer)
- readUint16(l, l.GetField(val, "min_proto_ver"), &ptr.MinProtoVer)
- readString(l, l.GetField(val, "player_name"), &ptr.PlayerName)
- readBool(l, l.GetField(val, "send_full_item_meta"), &ptr.SendFullItemMeta)
- readUint8(l, l.GetField(val, "serialize_ver"), &ptr.SerializeVer)
- readCompressionModes(l, l.GetField(val, "supported_compression"), &ptr.SupportedCompression)
+ ReadUint16(l, l.GetField(val, "max_proto_ver"), &ptr.MaxProtoVer)
+ ReadUint16(l, l.GetField(val, "min_proto_ver"), &ptr.MinProtoVer)
+ ReadString(l, l.GetField(val, "player_name"), &ptr.PlayerName)
+ ReadBool(l, l.GetField(val, "send_full_item_meta"), &ptr.SendFullItemMeta)
+ ReadUint8(l, l.GetField(val, "serialize_ver"), &ptr.SerializeVer)
+ ReadCompressionModes(l, l.GetField(val, "supported_compression"), &ptr.SupportedCompression)
return ptr
case "init2":
ptr := &mt.ToSrvInit2{}
val := l.CheckTable(3)
- readString(l, l.GetField(val, "lang"), &ptr.Lang)
+ ReadString(l, l.GetField(val, "lang"), &ptr.Lang)
return ptr
case "interact":
ptr := &mt.ToSrvInteract{}
val := l.CheckTable(3)
- readInteraction(l, l.GetField(val, "action"), &ptr.Action)
- readUint16(l, l.GetField(val, "item_slot"), &ptr.ItemSlot)
- readPointedThing(l, l.GetField(val, "pointed"), &ptr.Pointed)
- readPlayerPos(l, l.GetField(val, "pos"), &ptr.Pos)
+ ReadInteraction(l, l.GetField(val, "action"), &ptr.Action)
+ ReadUint16(l, l.GetField(val, "item_slot"), &ptr.ItemSlot)
+ ReadPointedThing(l, l.GetField(val, "pointed"), &ptr.Pointed)
+ ReadPlayerPos(l, l.GetField(val, "pos"), &ptr.Pos)
return ptr
case "inv_action":
ptr := &mt.ToSrvInvAction{}
val := l.CheckTable(3)
- readString(l, l.GetField(val, "action"), &ptr.Action)
+ ReadString(l, l.GetField(val, "action"), &ptr.Action)
return ptr
case "inv_fields":
ptr := &mt.ToSrvInvFields{}
val := l.CheckTable(3)
- readSliceField(l, l.GetField(val, "fields"), &ptr.Fields)
- readString(l, l.GetField(val, "formname"), &ptr.Formname)
+ ReadSliceField(l, l.GetField(val, "fields"), &ptr.Fields)
+ ReadString(l, l.GetField(val, "formname"), &ptr.Formname)
return ptr
case "join_mod_chan":
ptr := &mt.ToSrvJoinModChan{}
val := l.CheckTable(3)
- readString(l, l.GetField(val, "channel"), &ptr.Channel)
+ ReadString(l, l.GetField(val, "channel"), &ptr.Channel)
return ptr
case "leave_mod_chan":
ptr := &mt.ToSrvLeaveModChan{}
val := l.CheckTable(3)
- readString(l, l.GetField(val, "channel"), &ptr.Channel)
+ ReadString(l, l.GetField(val, "channel"), &ptr.Channel)
return ptr
case "msg_mod_chan":
ptr := &mt.ToSrvMsgModChan{}
val := l.CheckTable(3)
- readString(l, l.GetField(val, "channel"), &ptr.Channel)
- readString(l, l.GetField(val, "msg"), &ptr.Msg)
+ ReadString(l, l.GetField(val, "channel"), &ptr.Channel)
+ ReadString(l, l.GetField(val, "msg"), &ptr.Msg)
return ptr
case "nil":
ptr := &mt.ToSrvNil{}
case "node_meta_fields":
ptr := &mt.ToSrvNodeMetaFields{}
val := l.CheckTable(3)
- readSliceField(l, l.GetField(val, "fields"), &ptr.Fields)
- readString(l, l.GetField(val, "formname"), &ptr.Formname)
- readVec3Int16(l, l.GetField(val, "pos"), &ptr.Pos)
+ ReadSliceField(l, l.GetField(val, "fields"), &ptr.Fields)
+ ReadString(l, l.GetField(val, "formname"), &ptr.Formname)
+ ReadVec3Int16(l, l.GetField(val, "pos"), &ptr.Pos)
return ptr
case "player_pos":
ptr := &mt.ToSrvPlayerPos{}
val := l.CheckTable(3)
- readPlayerPos(l, l.GetField(val, "pos"), &ptr.Pos)
+ ReadPlayerPos(l, l.GetField(val, "pos"), &ptr.Pos)
return ptr
case "removed_sounds":
ptr := &mt.ToSrvRemovedSounds{}
val := l.CheckTable(3)
- readSliceSoundID(l, l.GetField(val, "ids"), &ptr.IDs)
+ ReadSliceSoundID(l, l.GetField(val, "ids"), &ptr.IDs)
return ptr
case "req_media":
ptr := &mt.ToSrvReqMedia{}
val := l.CheckTable(3)
- readSliceString(l, l.GetField(val, "filenames"), &ptr.Filenames)
+ ReadSliceString(l, l.GetField(val, "filenames"), &ptr.Filenames)
return ptr
case "respawn":
ptr := &mt.ToSrvRespawn{}
case "select_item":
ptr := &mt.ToSrvSelectItem{}
val := l.CheckTable(3)
- readUint16(l, l.GetField(val, "slot"), &ptr.Slot)
+ ReadUint16(l, l.GetField(val, "slot"), &ptr.Slot)
return ptr
case "srp_bytes_a":
ptr := &mt.ToSrvSRPBytesA{}
val := l.CheckTable(3)
- readSliceByte(l, l.GetField(val, "a"), &ptr.A)
- readBool(l, l.GetField(val, "no_sha1"), &ptr.NoSHA1)
+ ReadSliceByte(l, l.GetField(val, "a"), &ptr.A)
+ ReadBool(l, l.GetField(val, "no_sha1"), &ptr.NoSHA1)
return ptr
case "srp_bytes_m":
ptr := &mt.ToSrvSRPBytesM{}
val := l.CheckTable(3)
- readSliceByte(l, l.GetField(val, "m"), &ptr.M)
+ ReadSliceByte(l, l.GetField(val, "m"), &ptr.M)
return ptr
}
PointedThing = true,
}
-local static_uses = {
+local external = {
"[3]int16",
"AOID"
}
end
if not readers[fnname] then
- local fun = "func read" .. fnname .. "(l *lua.LState, val lua.LValue, ptr *" .. type .. ") {\n"
+ local fun = "func Read" .. fnname .. "(l *lua.LState, val lua.LValue, ptr *" .. type .. ") {\n"
if child then
fun = fun .. "\tif val.Type() != lua.LTTable {\n\t\tpanic(\"invalid value for "
n := tbl.MaxN()
*ptr = make(]] .. type .. [[, n)
for i := range *ptr {
- read]] .. childfn .. [[(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
+ Read]] .. childfn .. [[(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
}
]]
else
end
fun = fun
- .. "\tread" .. childfn
+ .. "\tRead" .. childfn
.. "(l, l.GetField(val, \"" .. v .. "\"), &(*ptr)[" .. (i - 1) .. "])\n"
end
end
else
+ local is_float = type == "float32" or type == "float64"
+
fun = fun .. "\tif val.Type() != lua.LTNumber {\n\t\tpanic(\"invalid value for "
.. name .. ": must be a number\")\n\t}\n"
- .. "\t*ptr = " .. type .. "(val.(lua.LNumber))\n"
+ .. "\t*ptr = " .. type .. "("
+ .. (is_float and "" or "math.Round(float64(")
+ .. "val.(lua.LNumber)"
+ .. (is_float and "" or "))")
+ .. ")\n"
end
fun = fun .. "}\n\n"
return fnname, type
end
-for _, use in ipairs(static_uses) do
+for _, use in ipairs(external) do
generate(use)
end
local function signature(name, prefix, type)
local camel = camel_case(name)
- return "func read" .. camel .. "(l *lua.LState, val lua.LValue, ptr *" .. prefix .. camel .. ") {\n"
+ return "func Read" .. camel .. "(l *lua.LState, val lua.LValue, ptr *" .. prefix .. camel .. ") {\n"
end
for name, fields in spairs(parse_spec("server/enum")) do
local impl = ""
for name, type in spairs(fields) do
- impl = impl .. indent .. "read" .. generate(type) .. "(l, l.GetField(val, \"" .. name .. "\"), &ptr."
+ impl = impl .. indent .. "Read" .. generate(type) .. "(l, l.GetField(val, \"" .. name .. "\"), &ptr."
.. camel_case(name) .. ")\n"
end
import (
"github.com/anon55555/mt"
"github.com/yuin/gopher-lua"
+ "math"
)
]] .. funcs .. [[
//go:generate ./read_mkauto.lua
-func readBool(l *lua.LState, val lua.LValue, ptr *bool) {
+func ReadBool(l *lua.LState, val lua.LValue, ptr *bool) {
if val.Type() != lua.LTBool {
panic("invalid value for bool: must be a boolean")
}
*ptr = bool(val.(lua.LBool))
}
-func readString(l *lua.LState, val lua.LValue, ptr *string) {
+func ReadString(l *lua.LState, val lua.LValue, ptr *string) {
if val.Type() != lua.LTString {
panic("invalid value for string: must be a string")
}
*ptr = string(val.(lua.LString))
}
-func readSliceByte(l *lua.LState, val lua.LValue, ptr *[]byte) {
+func ReadSliceByte(l *lua.LState, val lua.LValue, ptr *[]byte) {
if val.Type() != lua.LTString {
panic("invalid value for []byte: must be a string")
}
*ptr = []byte(val.(lua.LString))
}
-func readSliceField(l *lua.LState, val lua.LValue, ptr *[]mt.Field) {
+func ReadSliceField(l *lua.LState, val lua.LValue, ptr *[]mt.Field) {
if val.Type() != lua.LTTable {
panic("invalid value for []Field: must be a table")
}
})
}
-func readPointedThing(l *lua.LState, val lua.LValue, ptr *mt.PointedThing) {
+func ReadPointedThing(l *lua.LState, val lua.LValue, ptr *mt.PointedThing) {
if val.Type() != lua.LTTable {
panic("invalid value for PointedThing: must be a table")
}
if id != lua.LNil {
pt := &mt.PointedAO{}
- readAOID(l, id, &(*pt).ID)
+ ReadAOID(l, id, &(*pt).ID)
*ptr = pt
} else {
pt := &mt.PointedNode{}
- readVec3Int16(l, l.GetField(val, "under"), &(*pt).Under)
- readVec3Int16(l, l.GetField(val, "above"), &(*pt).Above)
+ ReadVec3Int16(l, l.GetField(val, "under"), &(*pt).Under)
+ ReadVec3Int16(l, l.GetField(val, "above"), &(*pt).Above)
*ptr = pt
}
}
if idx then
local first, second = pair:sub(1, idx - 1), pair:sub(idx + 1)
+ local c = first:sub(1, 1)
- if value_first and first:sub(1, 1) ~= "{" then
+ if value_first and c ~= "{" and c ~= "%" then
return second, first
else
return first, second
end
function parse_spec(name, value_first)
- local f = io.open("../spec/" .. name, "r")
+ local f = io.open("spec/" .. name, "r")
local spec = {}
local top
--- /dev/null
+id ID
+ao AO
+hud HUD
+hp HP
+fov FOV
+srp SRP
+sha1 SHA1
+ao_rm_add AORmAdd
+ao_msgs AOMsgs
+src_aoid SrcAOID
+ao_collision AOCollision
+add_hud AddHUD
+rm_hud RmHUD
+change_hud ChangeHUD
+hud_flags HUDFlags
+hud_type HUDType
+hud_field HUDField
+first_srp FirstSRP
+csm_restriction_flags CSMRestrictionFlags
+srp_bytes_salt_b SRPBytesSaltB
+srp_bytes_a SRPBytesA
+srp_bytes_m SRPBytesM
+no_csms NoCSMs
+join_ok JoinOK
+leave_ok LeaveOK
+no_sha1 NoSHA1
+fov80 FOV80
+ids IDs
--- /dev/null
+kick_reason
+ wrong_passwd
+ unexpected_data
+ srv_is_singleplayer
+ unsupported_ver
+ bad_name_chars
+ bad_name
+ too_many_clts
+ empty_passwd
+ already_connected
+ srv_err
+ custom
+ shutdown
+ crash
+chat_msg_type
+ postfix Msg
+ raw
+ normal
+ announce
+ sys
+sound_src_type
+ postfix Src
+ no
+ pos
+ ao
+anim_type
+ postfix Anim
+ no
+ vertical_frame
+ sprite_sheet
+hud_type
+ postfix HUD
+ img
+ text
+ statbar
+ inv
+ waypoint
+ img_waypoint
+hud_field
+ prefix HUD
+ pos
+ name
+ scale
+ text
+ number
+ item
+ dir
+ align
+ offset
+ world_pos
+ size
+ z_index
+ text_2
+hotbar_param
+ prefix Hotbar
+ size
+ img
+ sel_img
+mod_chan_sig
+ join_ok
+ join_fail
+ leave_ok
+ leave_fail
+ not_registered
+ set_state
+player_list_update_type
+ postfix Players
+ init
+ add
+ remove
--- /dev/null
+auth_methods
+ legacy_passwd
+ srp
+ first_srp
+csm_restriction_flags
+ no_csms
+ no_chat_msgs
+ no_node_defs
+ limit_map_range
+ no_player_list
+hud_flags
+ prefix Show
+ hotbar
+ health_bar
+ crosshair
+ wielded_item
+ breath_bar
+ minimap
+ radar_minimap
+map_blk_flags
+ prefix Blk
+ is_underground
+ day_night_diff
+ light_expired
+ not_generated
--- /dev/null
+hello
+ number serialize_ver
+ number compression
+ number proto_ver
+ auth_methods auth_methods
+ string username
+accept_auth
+ vec3 player_pos
+ number map_seed
+ number send_interval
+ auth_methods sudo_auth_methods
+accept_sudo_mode
+deny_sudo_mode
+kick
+ kick_reason reason
+ {custom} val.Reason == mt.Custom || val.Reason == mt.Shutdown || val.Reason == mt.Crash
+ string custom
+ {reconnect} val.Reason == mt.Shutdown || val.Reason == mt.Crash
+ boolean reconnect
+blk_data
+ vec3 blkpos
+ map_blk blk
+add_node
+ vec3 pos
+ node node
+ boolean keep_meta
+remove_node
+ vec3 pos
+inv
+ string inv
+time_of_day
+ number time
+ number speed
+csm_restriction_flags
+ csm_restriction_flags flags
+ number map_range
+add_player_vel
+ vec3 vel
+media_push
+ fixed_string sha1
+ string filename
+ boolean should_cache
+ string data
+chat_msg
+ chat_msg_type type
+ string sender
+ string text
+ number timestamp
+ao_rm_add
+ # TODO
+ao_msgs
+ # TODO
+hp
+ number hp
+move_player
+ vec3 pos
+ number pitch
+ number yaw
+legacy_kick
+ string reason
+fov
+ number fov
+ boolean multiplier
+ number transition_time
+death_screen
+ boolean point_cam
+ vec3 point_at
+media
+ # TODO
+node_defs
+ # TODO
+announce_media
+ # TODO
+item_defs
+ # TODO
+play_sound
+ number id
+ string name
+ number gain
+ sound_src_type src_type
+ vec3 pos
+ number src_aoid
+ boolean loop
+ number fade
+ number pitch
+ boolean ephemeral
+stop_sound
+ number id
+privs
+ string_set privs
+inv_formspec
+ string formspec
+detached_inv
+ string name
+ boolean keep
+ number len
+ string inv
+show_formspec
+ string formspec
+ string formname
+movement
+ number default_accel
+ number air_accel
+ number fast_accel
+ number walk_speed
+ number crouch_speed
+ number fast_speed
+ number climb_speed
+ number jump_speed
+ number fluidity
+ number smoothing
+ number sink
+ number gravity
+spawn_particle
+ vec3 pos
+ vec3 vel
+ vec3 acc
+ number expiration_time
+ number size
+ boolean collide
+ string texture
+ boolean vertical
+ boolean collision_rm
+ tile_anim anim_params
+ number glow
+ boolean ao_collision
+ number node_param0
+ number node_param2
+ number node_tile
+add_particle_spawner
+ number amount
+ number duration
+ box3 pos
+ box3 vel
+ box3 acc
+ box1 expiration_time
+ box1 size
+ boolean collide
+ string texture
+ number id
+ boolean vertical
+ boolean collision_rm
+ tile_anim anim_params
+ number glow
+ boolean ao_collision
+ number node_param0
+ number node_param2
+ number node_tile
+add_hud
+ number id
+ hud hud
+rm_hud
+ number id
+change_hud
+ number id
+ hud_field field
+ {pos} val.Field == mt.HUDPos
+ {name} val.Field == mt.HUDName
+ {text} val.Field == mt.HUDText
+ {number} val.Field == mt.HUDNumber
+ {item} val.Field == mt.HUDItem
+ {dir} val.Field == mt.HUDDir
+ {align} val.Field == mt.HUDAlign
+ {offset} val.Field == mt.HUDOffset
+ {world_pos} val.Field == mt.HUDWorldPos
+ {size} val.Field == mt.HUDSize
+ {z_index} val.Field == mt.HUDZIndex
+ {text_2} val.Field == mt.HUDText2
+ vec2 pos
+ string name
+ string text
+ number number
+ number item
+ number dir
+ vec2 align
+ vec2 offset
+ vec3 world_pos
+ vec2 size
+ number z_index
+ string text_2
+hud_flags
+ hud_flags flags
+ hud_flags mask
+set_hotbar_param
+ hotbar_param param
+ number size
+ string img
+breath
+ number breath
+sky_params
+ color bg_color
+ string type
+ boolean clouds
+ color sun_fog_tint
+ color moon_fog_tint
+ string fog_tint_type
+ {textures} val.Type == "skybox"
+ %textures% mt.Texture
+ string_list textures
+ {day_sky} val.Type == "regular"
+ {day_horizon} val.Type == "regular"
+ {dawn_sky} val.Type == "regular"
+ {dawn_horizon} val.Type == "regular"
+ {night_sky} val.Type == "regular"
+ {night_horizon} val.Type == "regular"
+ {indoor} val.Type == "regular"
+ color day_sky
+ color day_horizon
+ color dawn_sky
+ color dawn_horizon
+ color night_sky
+ color night_horizon
+ color indoor
+override_day_night_ratio
+ boolean override
+ number ratio
+local_player_anim
+ box1 idle
+ box1 walk
+ box1 dig
+ box1 walk_dig
+ number speed
+eye_offset
+ vec3 first
+ vec3 third
+del_particle_spawner
+ number id
+cloud_params
+ number density
+ color diffuse_color
+ color ambient_color
+ number height
+ number thickness
+ vec2 speed
+fade_sound
+ number id
+ number step
+ number gain
+update_player_list
+ player_list_update_type type
+ %players% string
+ string_list players
+mod_chan_msg
+ string channel
+ string sender
+ string msg
+mod_chan_sig
+ mod_chan_sig signal
+ string channel
+node_metas_changed
+ changed_node_metas changed
+sun_params
+ boolean visible
+ string texture
+ string tone_map
+ string rise
+ boolean rising
+ number size
+moon_params
+ boolean visible
+ string texture
+ string tone_map
+ number size
+star_params
+ boolean visible
+ number count
+ color color
+ number size
+srp_bytes_salt_b
+ string salt
+ string b
+formspec_prepend
+ string prepend
+minimap_modes
+ # TODO
+disco
--- /dev/null
+node
+ number param0
+ number param1
+ number param2
+tile_anim
+ anim_type type
+ vec2 aspect_ratio
+ vec2 n_frames
+ number duration
+hud
+ hud_type type
+ vec2 pos
+ string name
+ vec2 scale
+ string text
+ number number
+ number item
+ number dir
+ vec2 align
+ vec2 offset
+ vec3 world_pos
+ vec2 size
+ number z_index
+ string text_2
+map_blk
+ map_blk_flags flags
+ number lit_from
+ %param0% mt.Content
+ 4096 param0
+ %param1% uint8
+ 4096 param1
+ %param2% uint8
+ 4096 param2
+ node_metas node_metas
+node_meta
+ node_meta_fields fields
+ inv inv
+tool_caps
+ number attack_cooldown
+ number max_drop_lvl
+ group_caps group_caps
+ groups dmg_groups
+ number punch_uses
--- /dev/null
+interaction
+ dig
+ stop_digging
+ dug
+ place
+ use
+ activate
--- /dev/null
+keys
+ postfix Key
+ forward
+ backward
+ left
+ right
+ jump
+ special
+ sneak
+ dig
+ place
+ zoom
--- /dev/null
+nil
+init
+ uint8 serialize_ver
+ CompressionModes supported_compression
+ uint16 min_proto_ver
+ uint16 max_proto_ver
+ string player_name
+ bool send_full_item_meta
+init2
+ string lang
+join_mod_chan
+ string channel
+leave_mod_chan
+ string channel
+msg_mod_chan
+ string channel
+ string msg
+player_pos
+ PlayerPos pos
+got_blks
+ [][3]int16 blks
+deleted_blks
+ [][3]int16 blks
+inv_action
+ string action
+chat_msg
+ string msg
+fall_dmg
+ uint16 amount
+select_item
+ uint16 slot
+respawn
+interact
+ Interaction action
+ uint16 item_slot
+ PointedThing pointed
+ PlayerPos pos
+removed_sounds
+ []SoundID ids
+node_meta_fields
+ [3]int16 pos
+ string formname
+ []Field fields
+inv_fields
+ string formname
+ []Field fields
+req_media
+ []string filenames
+clt_ready
+ uint8 major
+ uint8 minor
+ uint8 patch
+ string version
+ uint16 formspec
+first_srp
+ []byte salt
+ []byte verifier
+ bool empty_passwd
+srp_bytes_a
+ []byte a
+ bool no_sha1
+srp_bytes_m
+ []byte m
--- /dev/null
+player_pos
+ [3]int32 pos100
+ [3]int32 vel100
+ int32 pitch100
+ int32 yaw100
+ Keys keys
+ uint8 fov80
+ uint8 wanted_range
- `escapes`: contains utility functions to deal with minetest escape sequences, see [escapes.md](escapes.md)
- `client`: a function to create a client from command line arguments in the form `<server> <username> <password>`. This is trivial but so commonly used that this function was added to avoid repetition in scripts.
+- `base64`: contains the `base64.encode(data)` function to base64 encode a string as well as `base64.decode(data)` to decode
## Standard library additions
Enabled components can be accessed by using `self.<component name>`.
- `self.auth`: Handles authentication. Recommended for the vast majority of scripts. See [auth.md](auth.md).
+- `self.map`: Stores MapBlocks received from server. See [map.md](map.md).
# Client Packets
TODO: automatically generate documentation from spec.
-For now, have a look at [spec/client](../spec/client)
+For now, have a look at [spec/client](../convert/spec/client)
--- /dev/null
+# Map Component
+Source code: [map.go](../map.go)
+
+Map handles the `blk_data` and `node_metas_changed` packets.
+Map may send `got_blks`, `deleted_blks` packets.
+
+## Functions
+
+`self:clear()`: Forget all blocks.
+
+`self:block(blkpos)`: Return the `map_blk` at `blkpos` as found in the `blk_data` packet (See [client_pkts.md](client_pkts.md)). `nil` if block is not present.
+
+`self:node(pos)`: Return a node in the form `{ param0 = 126, param1 = 0, param2 = 0, meta = { ... } }`. The meta field is a `node_meta` as found in the `blk_data` packet. `nil` if node is not present.
# Server Packets
TODO: automatically generate documentation from spec.
-For now, have a look at [spec/server](../spec/server)
+For now, have a look at [spec/server](../convert/spec/server)
#!/usr/bin/env hydra-dragonfire
+local escapes = require("escapes")
+local base64 = require("base64")
local client = require("client")()
client:wildcard(true)
client:connect()
+local function dump(val, indent)
+ local t = type(val)
+ local mt = getmetatable(val)
+
+ if t ~= "table" or mt and mt.__tostring then
+ if t == "string" then
+ val = val:gsub("\n", "\\n")
+ end
+ print(val)
+ else
+ print(val._type or "")
+
+ local idt = (indent or "") .. " "
+ for k, v in pairs(val) do
+ if k ~= "_type" then
+ io.write(idt .. k .. " ")
+ dump(v, idt)
+ end
+ end
+ end
+end
+
while not hydra.canceled() do
local pkt, interrupt = client:poll()
if pkt then
- print(pkt._type)
- for k, v in pairs(pkt) do
- if k ~= "_type" then
- print("", k, v)
- end
+ if pkt._type == "srp_bytes_salt_b" then
+ pkt.b = base64.encode(pkt.b)
+ pkt.salt = base64.encode(pkt.salt)
+ end
+
+ if pkt._type == "chat_msg" then
+ pkt.text = escapes.strip_all(pkt.text)
+ end
+
+ if pkt._type == "blk_data" then
+ pkt.blk.param0 = {}
+ pkt.blk.param1 = {}
+ pkt.blk.param2 = {}
end
+
+ dump(pkt)
elseif not interrupt then
print("disconnected")
break
--- /dev/null
+#!/usr/bin/env hydra-dragonfire
+local client = require("client")()
+client:enable("map")
+
+client:subscribe("move_player")
+client:connect()
+
+local pos
+
+while not hydra.canceled() do
+ local pkt, interrupted = client:poll(1)
+
+ if pkt then
+ pos = (pkt.pos / hydra.BS + vec3(0, -1, 0)):round()
+ elseif not interrupted then
+ break
+ elseif pos then
+ local node = client.map:node(pos)
+ print(pos, node and node.param0)
+ end
+end
+
+client:close()
//go:embed builtin/client.lua
var builtinClient string
+//go:embed builtin/base64.lua
+var builtinBase64 string
+
var builtinFiles = []string{
builtinLuaX,
builtinVector,
builtinEscapes,
builtinClient,
+ builtinBase64,
}
var hydraFuncs = map[string]lua.LGFunction{
l.SetField(l.NewTypeMetatable("hydra.auth"), "__index", l.SetFuncs(l.NewTable(), authFuncs))
l.SetField(l.NewTypeMetatable("hydra.client"), "__index", l.NewFunction(l_client_index))
+ l.SetField(l.NewTypeMetatable("hydra.map"), "__index", l.SetFuncs(l.NewTable(), mapFuncs))
for _, str := range builtinFiles {
if err := l.DoString(str); err != nil {
--- /dev/null
+package main
+
+import (
+ "github.com/anon55555/mt"
+ "github.com/dragonfireclient/hydra-dragonfire/convert"
+ "github.com/yuin/gopher-lua"
+ "sync"
+)
+
+type Map struct {
+ client *Client
+ mu sync.Mutex
+ blocks map[[3]int16]*mt.MapBlk
+ userdata *lua.LUserData
+}
+
+var mapFuncs = map[string]lua.LGFunction{
+ "clear": l_map_clear,
+ "block": l_map_block,
+ "node": l_map_node,
+}
+
+func getMap(l *lua.LState) *Map {
+ return l.CheckUserData(1).Value.(*Map)
+}
+
+func (mtmap *Map) create(client *Client, l *lua.LState) {
+ mtmap.client = client
+ mtmap.blocks = map[[3]int16]*mt.MapBlk{}
+ mtmap.userdata = l.NewUserData()
+ mtmap.userdata.Value = mtmap
+ l.SetMetatable(mtmap.userdata, l.GetTypeMetatable("hydra.map"))
+}
+
+func (mtmap *Map) push() lua.LValue {
+ return mtmap.userdata
+}
+
+func (mtmap *Map) connect() {
+}
+
+func (mtmap *Map) process(pkt *mt.Pkt) {
+ switch cmd := pkt.Cmd.(type) {
+ case *mt.ToCltBlkData:
+ mtmap.mu.Lock()
+ mtmap.blocks[cmd.Blkpos] = &cmd.Blk
+ mtmap.client.conn.SendCmd(&mt.ToSrvGotBlks{Blks: [][3]int16{cmd.Blkpos}})
+ mtmap.mu.Unlock()
+ }
+}
+
+func l_map_clear(l *lua.LState) int {
+ mtmap := getMap(l)
+
+ mtmap.mu.Lock()
+ defer mtmap.mu.Unlock()
+
+ var cmd mt.ToSrvDeletedBlks
+ for pos := range mtmap.blocks {
+ cmd.Blks = append(cmd.Blks, pos)
+ }
+
+ mtmap.blocks = map[[3]int16]*mt.MapBlk{}
+
+ mtmap.client.conn.SendCmd(&cmd)
+
+ return 0
+}
+
+func l_map_block(l *lua.LState) int {
+ mtmap := getMap(l)
+ var blkpos [3]int16
+ convert.ReadVec3Int16(l, l.Get(2), &blkpos)
+
+ mtmap.mu.Lock()
+ defer mtmap.mu.Unlock()
+
+ block, ok := mtmap.blocks[blkpos]
+ if ok {
+ l.Push(convert.PushMapBlk(l, *block))
+ } else {
+ l.Push(lua.LNil)
+ }
+
+ return 1
+}
+
+func l_map_node(l *lua.LState) int {
+ mtmap := getMap(l)
+
+ var pos [3]int16
+ convert.ReadVec3Int16(l, l.Get(2), &pos)
+ blkpos, i := mt.Pos2Blkpos(pos)
+
+ mtmap.mu.Lock()
+ defer mtmap.mu.Unlock()
+
+ block, block_exists := mtmap.blocks[blkpos]
+ if block_exists {
+ meta, meta_exists := block.NodeMetas[i]
+ if !meta_exists {
+ meta = &mt.NodeMeta{}
+ }
+
+ lnode := l.NewTable()
+ l.SetField(lnode, "param0", lua.LNumber(block.Param0[i]))
+ l.SetField(lnode, "param1", lua.LNumber(block.Param1[i]))
+ l.SetField(lnode, "param2", lua.LNumber(block.Param2[i]))
+ l.SetField(lnode, "meta", convert.PushNodeMeta(l, *meta))
+ l.Push(lnode)
+ } else {
+ l.Push(lua.LNil)
+ }
+
+ return 1
+}
+++ /dev/null
-id ID
-ao AO
-hud HUD
-hp HP
-fov FOV
-srp SRP
-sha1 SHA1
-ao_rm_add AORmAdd
-ao_msgs AOMsgs
-src_aoid SrcAOID
-ao_collision AOCollision
-add_hud AddHUD
-rm_hud RmHUD
-change_hud ChangeHUD
-hud_flags HUDFlags
-hud_type HUDType
-hud_field HUDField
-first_srp FirstSRP
-csm_restriction_flags CSMRestrictionFlags
-srp_bytes_salt_b SRPBytesSaltB
-srp_bytes_a SRPBytesA
-srp_bytes_m SRPBytesM
-no_csms NoCSMs
-join_ok JoinOK
-leave_ok LeaveOK
-no_sha1 NoSHA1
-fov80 FOV80
-ids IDs
+++ /dev/null
-kick_reason
- wrong_passwd
- unexpected_data
- srv_is_singleplayer
- unsupported_ver
- bad_name_chars
- bad_name
- too_many_clts
- empty_passwd
- already_connected
- srv_err
- custom
- shutdown
- crash
-chat_msg_type
- postfix Msg
- raw
- normal
- announce
- sys
-sound_src_type
- postfix Src
- no
- pos
- ao
-anim_type
- postfix Anim
- no
- vertical_frame
- sprite_sheet
-hud_type
- postfix HUD
- img
- text
- statbar
- inv
- waypoint
- img_waypoint
-hud_field
- prefix HUD
- pos
- name
- scale
- text
- number
- item
- dir
- align
- offset
- world_pos
- size
- z_index
- text_2
-hotbar_param
- prefix Hotbar
- size
- img
- sel_img
-mod_chan_sig
- join_ok
- join_fail
- leave_ok
- leave_fail
- not_registered
- set_state
-player_list_update_type
- postfix Players
- init
- add
- remove
+++ /dev/null
-auth_methods
- legacy_passwd
- srp
- first_srp
-csm_restriction_flags
- no_csms
- no_chat_msgs
- no_node_defs
- limit_map_range
- no_player_list
-hud_flags
- prefix Show
- hotbar
- health_bar
- crosshair
- wielded_item
- breath_bar
- minimap
- radar_minimap
+++ /dev/null
-hello
- number serialize_ver
- number compression
- number proto_ver
- auth_methods auth_methods
- string username
-accept_auth
- vec3 player_pos
- number map_seed
- number send_interval
- auth_methods sudo_auth_methods
-accept_sudo_mode
-deny_sudo_mode
-kick
- kick_reason reason
- {custom} val.Reason == mt.Custom || val.Reason == mt.Shutdown || val.Reason == mt.Crash
- string custom
- {reconnect} val.Reason == mt.Shutdown || val.Reason == mt.Crash
- boolean reconnect
-blk_data
- vec3 blkpos
- # TODO
-add_node
- vec3 pos
- node node
- boolean keep_meta
-remove_node
- vec3 pos
-inv
- string inv
-time_of_day
- number time
- number speed
-csm_restriction_flags
- csm_restriction_flags flags
- number map_range
-add_player_vel
- vec3 vel
-media_push
- fixed_string sha1
- string filename
- boolean should_cache
- string data
-chat_msg
- chat_msg_type type
- string sender
- string text
- number timestamp
-ao_rm_add
- # TODO
-ao_msgs
- # TODO
-hp
- number hp
-move_player
- vec3 pos
- number pitch
- number yaw
-legacy_kick
- string reason
-fov
- number fov
- boolean multiplier
- number transition_time
-death_screen
- boolean point_cam
- vec3 point_at
-media
- # TODO
-node_defs
- # TODO
-announce_media
- # TODO
-item_defs
- # TODO
-play_sound
- number id
- string name
- number gain
- sound_src_type src_type
- vec3 pos
- number src_aoid
- boolean loop
- number fade
- number pitch
- boolean ephemeral
-stop_sound
- number id
-privs
- string_set privs
-inv_formspec
- string formspec
-detached_inv
- string name
- boolean keep
- number len
- string inv
-show_formspec
- string formspec
- string formname
-movement
- number default_accel
- number air_accel
- number fast_accel
- number walk_speed
- number crouch_speed
- number fast_speed
- number climb_speed
- number jump_speed
- number fluidity
- number smoothing
- number sink
- number gravity
-spawn_particle
- vec3 pos
- vec3 vel
- vec3 acc
- number expiration_time
- number size
- boolean collide
- string texture
- boolean vertical
- boolean collision_rm
- tile_anim anim_params
- number glow
- boolean ao_collision
- number node_param0
- number node_param2
- number node_tile
-add_particle_spawner
- number amount
- number duration
- box3 pos
- box3 vel
- box3 acc
- box1 expiration_time
- box1 size
- boolean collide
- string texture
- number id
- boolean vertical
- boolean collision_rm
- tile_anim anim_params
- number glow
- boolean ao_collision
- number node_param0
- number node_param2
- number node_tile
-add_hud
- number id
- hud hud
-rm_hud
- number id
-change_hud
- number id
- hud_field field
- {pos} val.Field == mt.HUDPos
- {name} val.Field == mt.HUDName
- {text} val.Field == mt.HUDText
- {number} val.Field == mt.HUDNumber
- {item} val.Field == mt.HUDItem
- {dir} val.Field == mt.HUDDir
- {align} val.Field == mt.HUDAlign
- {offset} val.Field == mt.HUDOffset
- {world_pos} val.Field == mt.HUDWorldPos
- {size} val.Field == mt.HUDSize
- {z_index} val.Field == mt.HUDZIndex
- {text_2} val.Field == mt.HUDText2
- vec2 pos
- string name
- string text
- number number
- number item
- number dir
- vec2 align
- vec2 offset
- vec3 world_pos
- vec2 size
- number z_index
- string text_2
-hud_flags
- hud_flags flags
- hud_flags mask
-set_hotbar_param
- hotbar_param param
- number size
- string img
-breath
- number breath
-sky_params
- color bg_color
- string type
- boolean clouds
- color sun_fog_tint
- color moon_fog_tint
- string fog_tint_type
- {textures} val.Type == "skybox"
- texture_list textures
- {day_sky} val.Type == "regular"
- {day_horizon} val.Type == "regular"
- {dawn_sky} val.Type == "regular"
- {dawn_horizon} val.Type == "regular"
- {night_sky} val.Type == "regular"
- {night_horizon} val.Type == "regular"
- {indoor} val.Type == "regular"
- color day_sky
- color day_horizon
- color dawn_sky
- color dawn_horizon
- color night_sky
- color night_horizon
- color indoor
-override_day_night_ratio
- boolean override
- number ratio
-local_player_anim
- box1 idle
- box1 walk
- box1 dig
- box1 walk_dig
- number speed
-eye_offset
- vec3 first
- vec3 third
-del_particle_spawner
- number id
-cloud_params
- number density
- color diffuse_color
- color ambient_color
- number height
- number thickness
- vec2 speed
-fade_sound
- number id
- number step
- number gain
-update_player_list
- player_list_update_type type
- string_list players
-mod_chan_msg
- string channel
- string sender
- string msg
-mod_chan_sig
- mod_chan_sig signal
- string channel
-node_metas_changed
- # TODO
-sun_params
- boolean visible
- string texture
- string tone_map
- string rise
- boolean rising
- number size
-moon_params
- boolean visible
- string texture
- string tone_map
- number size
-star_params
- boolean visible
- number count
- color color
- number size
-srp_bytes_salt_b
- string salt
- string b
-formspec_prepend
- string prepend
-minimap_modes
- # TODO
-disco
+++ /dev/null
-node
- number param0
- number param1
- number param2
-tile_anim
- anim_type type
- vec2 aspect_ratio
- vec2 n_frames
- number duration
-hud
- hud_type type
- vec2 pos
- string name
- vec2 scale
- string text
- number number
- number item
- number dir
- vec2 align
- vec2 offset
- vec3 world_pos
- vec2 size
- number z_index
- string text_2
+++ /dev/null
-interaction
- dig
- stop_digging
- dug
- place
- use
- activate
+++ /dev/null
-keys
- postfix Key
- forward
- backward
- left
- right
- jump
- special
- sneak
- dig
- place
- zoom
+++ /dev/null
-nil
-init
- uint8 serialize_ver
- CompressionModes supported_compression
- uint16 min_proto_ver
- uint16 max_proto_ver
- string player_name
- bool send_full_item_meta
-init2
- string lang
-join_mod_chan
- string channel
-leave_mod_chan
- string channel
-msg_mod_chan
- string channel
- string msg
-player_pos
- PlayerPos pos
-got_blks
- [][3]int16 blks
-deleted_blks
- [][3]int16 blks
-inv_action
- string action
-chat_msg
- string msg
-fall_dmg
- uint16 amount
-select_item
- uint16 slot
-respawn
-interact
- Interaction action
- uint16 item_slot
- PointedThing pointed
- PlayerPos pos
-removed_sounds
- []SoundID ids
-node_meta_fields
- [3]int16 pos
- string formname
- []Field fields
-inv_fields
- string formname
- []Field fields
-req_media
- []string filenames
-clt_ready
- uint8 major
- uint8 minor
- uint8 patch
- string version
- uint16 formspec
-first_srp
- []byte salt
- []byte verifier
- bool empty_passwd
-srp_bytes_a
- []byte a
- bool no_sha1
-srp_bytes_m
- []byte m
+++ /dev/null
-player_pos
- [3]int32 pos100
- [3]int32 vel100
- int32 pitch100
- int32 yaw100
- Keys keys
- uint8 fov80
- uint8 wanted_range