diff options
| author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-30 00:09:33 +0200 |
|---|---|---|
| committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-30 00:09:33 +0200 |
| commit | ff8def17c85dc6d8f362e2f325037d909850e46b (patch) | |
| tree | 640c0ef81f0fbd43287facb31347d5d09985e03f /convert | |
| parent | c7b0b4e955d625c9d4d08370b683e62d2838651d (diff) | |
| download | hydra-dragonfire-ff8def17c85dc6d8f362e2f325037d909850e46b.tar.xz | |
Move conversion code into convert package
Diffstat (limited to 'convert')
| -rw-r--r-- | convert/push_auto.go | 684 | ||||
| -rwxr-xr-x | convert/push_mkauto.lua | 127 | ||||
| -rw-r--r-- | convert/push_static.go | 97 | ||||
| -rw-r--r-- | convert/read_auto.go | 320 | ||||
| -rwxr-xr-x | convert/read_mkauto.lua | 198 | ||||
| -rw-r--r-- | convert/read_static.go | 59 | ||||
| -rw-r--r-- | convert/spec.lua | 108 |
7 files changed, 1593 insertions, 0 deletions
diff --git a/convert/push_auto.go b/convert/push_auto.go new file mode 100644 index 0000000..282a5f5 --- /dev/null +++ b/convert/push_auto.go @@ -0,0 +1,684 @@ +// generated by push_mkauto.lua, DO NOT EDIT +package convert + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" +) + +func pushAnimType(l *lua.LState, val mt.AnimType) lua.LValue { + switch val { + case mt.NoAnim: + return lua.LNil + case mt.VerticalFrameAnim: + return lua.LString("vertical_frame") + case mt.SpriteSheetAnim: + return lua.LString("sprite_sheet") + } + panic("impossible") + return lua.LNil +} + +func pushChatMsgType(l *lua.LState, val mt.ChatMsgType) lua.LValue { + switch val { + case mt.RawMsg: + return lua.LString("raw") + case mt.NormalMsg: + return lua.LString("normal") + case mt.AnnounceMsg: + return lua.LString("announce") + case mt.SysMsg: + return lua.LString("sys") + } + panic("impossible") + return lua.LNil +} + +func pushHotbarParam(l *lua.LState, val mt.HotbarParam) lua.LValue { + switch val { + case mt.HotbarSize: + return lua.LString("size") + case mt.HotbarImg: + return lua.LString("img") + case mt.HotbarSelImg: + return lua.LString("sel_img") + } + panic("impossible") + return lua.LNil +} + +func pushHUDField(l *lua.LState, val mt.HUDField) lua.LValue { + switch val { + case mt.HUDPos: + return lua.LString("pos") + case mt.HUDName: + return lua.LString("name") + case mt.HUDScale: + return lua.LString("scale") + case mt.HUDText: + return lua.LString("text") + case mt.HUDNumber: + return lua.LString("number") + case mt.HUDItem: + return lua.LString("item") + case mt.HUDDir: + return lua.LString("dir") + case mt.HUDAlign: + return lua.LString("align") + case mt.HUDOffset: + return lua.LString("offset") + case mt.HUDWorldPos: + return lua.LString("world_pos") + case mt.HUDSize: + return lua.LString("size") + case mt.HUDZIndex: + return lua.LString("z_index") + case mt.HUDText2: + return lua.LString("text_2") + } + panic("impossible") + return lua.LNil +} + +func pushHUDType(l *lua.LState, val mt.HUDType) lua.LValue { + switch val { + case mt.ImgHUD: + return lua.LString("img") + case mt.TextHUD: + return lua.LString("text") + case mt.StatbarHUD: + return lua.LString("statbar") + case mt.InvHUD: + return lua.LString("inv") + case mt.WaypointHUD: + return lua.LString("waypoint") + case mt.ImgWaypointHUD: + return lua.LString("img_waypoint") + } + panic("impossible") + return lua.LNil +} + +func pushKickReason(l *lua.LState, val mt.KickReason) lua.LValue { + switch val { + case mt.WrongPasswd: + return lua.LString("wrong_passwd") + case mt.UnexpectedData: + return lua.LString("unexpected_data") + case mt.SrvIsSingleplayer: + return lua.LString("srv_is_singleplayer") + case mt.UnsupportedVer: + return lua.LString("unsupported_ver") + case mt.BadNameChars: + return lua.LString("bad_name_chars") + case mt.BadName: + return lua.LString("bad_name") + case mt.TooManyClts: + return lua.LString("too_many_clts") + case mt.EmptyPasswd: + return lua.LString("empty_passwd") + case mt.AlreadyConnected: + return lua.LString("already_connected") + case mt.SrvErr: + return lua.LString("srv_err") + case mt.Custom: + return lua.LString("custom") + case mt.Shutdown: + return lua.LString("shutdown") + case mt.Crash: + return lua.LString("crash") + } + panic("impossible") + return lua.LNil +} + +func pushModChanSig(l *lua.LState, val mt.ModChanSig) lua.LValue { + switch val { + case mt.JoinOK: + return lua.LString("join_ok") + case mt.JoinFail: + return lua.LString("join_fail") + case mt.LeaveOK: + return lua.LString("leave_ok") + case mt.LeaveFail: + return lua.LString("leave_fail") + case mt.NotRegistered: + return lua.LString("not_registered") + case mt.SetState: + return lua.LString("set_state") + } + panic("impossible") + return lua.LNil +} + +func pushPlayerListUpdateType(l *lua.LState, val mt.PlayerListUpdateType) lua.LValue { + switch val { + case mt.InitPlayers: + return lua.LString("init") + case mt.AddPlayers: + return lua.LString("add") + case mt.RemovePlayers: + return lua.LString("remove") + } + panic("impossible") + return lua.LNil +} + +func pushSoundSrcType(l *lua.LState, val mt.SoundSrcType) lua.LValue { + switch val { + case mt.NoSrc: + return lua.LNil + case mt.PosSrc: + return lua.LString("pos") + case mt.AOSrc: + return lua.LString("ao") + } + panic("impossible") + return lua.LNil +} + +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) + } + return tbl +} + +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) + } + return tbl +} + +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) + } + return tbl +} + +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, "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, "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, "z_index", lua.LNumber(val.ZIndex)) + 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)) + l.SetField(tbl, "param2", lua.LNumber(val.Param2)) + 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, "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)) + return tbl +} + +func PushPktType(pkt *mt.Pkt) lua.LString { + switch pkt.Cmd.(type) { + case *mt.ToCltAcceptAuth: + return lua.LString("accept_auth") + case *mt.ToCltAcceptSudoMode: + return lua.LString("accept_sudo_mode") + case *mt.ToCltAddHUD: + return lua.LString("add_hud") + case *mt.ToCltAddNode: + return lua.LString("add_node") + case *mt.ToCltAddParticleSpawner: + return lua.LString("add_particle_spawner") + case *mt.ToCltAddPlayerVel: + return lua.LString("add_player_vel") + case *mt.ToCltAnnounceMedia: + return lua.LString("announce_media") + case *mt.ToCltAOMsgs: + return lua.LString("ao_msgs") + case *mt.ToCltAORmAdd: + return lua.LString("ao_rm_add") + case *mt.ToCltBlkData: + return lua.LString("blk_data") + case *mt.ToCltBreath: + return lua.LString("breath") + case *mt.ToCltChangeHUD: + return lua.LString("change_hud") + case *mt.ToCltChatMsg: + return lua.LString("chat_msg") + case *mt.ToCltCloudParams: + return lua.LString("cloud_params") + case *mt.ToCltCSMRestrictionFlags: + return lua.LString("csm_restriction_flags") + case *mt.ToCltDeathScreen: + return lua.LString("death_screen") + case *mt.ToCltDelParticleSpawner: + return lua.LString("del_particle_spawner") + case *mt.ToCltDenySudoMode: + return lua.LString("deny_sudo_mode") + case *mt.ToCltDetachedInv: + return lua.LString("detached_inv") + case *mt.ToCltDisco: + return lua.LString("disco") + case *mt.ToCltEyeOffset: + return lua.LString("eye_offset") + case *mt.ToCltFadeSound: + return lua.LString("fade_sound") + case *mt.ToCltFormspecPrepend: + return lua.LString("formspec_prepend") + case *mt.ToCltFOV: + return lua.LString("fov") + case *mt.ToCltHello: + return lua.LString("hello") + case *mt.ToCltHP: + return lua.LString("hp") + case *mt.ToCltHUDFlags: + return lua.LString("hud_flags") + case *mt.ToCltInv: + return lua.LString("inv") + case *mt.ToCltInvFormspec: + return lua.LString("inv_formspec") + case *mt.ToCltItemDefs: + return lua.LString("item_defs") + case *mt.ToCltKick: + return lua.LString("kick") + case *mt.ToCltLegacyKick: + return lua.LString("legacy_kick") + case *mt.ToCltLocalPlayerAnim: + return lua.LString("local_player_anim") + case *mt.ToCltMedia: + return lua.LString("media") + case *mt.ToCltMediaPush: + return lua.LString("media_push") + case *mt.ToCltMinimapModes: + return lua.LString("minimap_modes") + case *mt.ToCltModChanMsg: + return lua.LString("mod_chan_msg") + case *mt.ToCltModChanSig: + return lua.LString("mod_chan_sig") + case *mt.ToCltMoonParams: + return lua.LString("moon_params") + case *mt.ToCltMovePlayer: + return lua.LString("move_player") + case *mt.ToCltMovement: + return lua.LString("movement") + case *mt.ToCltNodeDefs: + return lua.LString("node_defs") + case *mt.ToCltNodeMetasChanged: + return lua.LString("node_metas_changed") + case *mt.ToCltOverrideDayNightRatio: + return lua.LString("override_day_night_ratio") + case *mt.ToCltPlaySound: + return lua.LString("play_sound") + case *mt.ToCltPrivs: + return lua.LString("privs") + case *mt.ToCltRemoveNode: + return lua.LString("remove_node") + case *mt.ToCltRmHUD: + return lua.LString("rm_hud") + case *mt.ToCltSetHotbarParam: + return lua.LString("set_hotbar_param") + case *mt.ToCltShowFormspec: + return lua.LString("show_formspec") + case *mt.ToCltSkyParams: + return lua.LString("sky_params") + case *mt.ToCltSpawnParticle: + return lua.LString("spawn_particle") + case *mt.ToCltSRPBytesSaltB: + return lua.LString("srp_bytes_salt_b") + case *mt.ToCltStarParams: + return lua.LString("star_params") + case *mt.ToCltStopSound: + return lua.LString("stop_sound") + case *mt.ToCltSunParams: + return lua.LString("sun_params") + case *mt.ToCltTimeOfDay: + return lua.LString("time_of_day") + case *mt.ToCltUpdatePlayerList: + return lua.LString("update_player_list") + } + panic("impossible") + return "" +} + +func PushPkt(l *lua.LState, pkt *mt.Pkt) lua.LValue { + if pkt == nil { + return lua.LNil + } + tbl := l.NewTable() + l.SetField(tbl, "_type", PushPktType(pkt)) + 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, "send_interval", lua.LNumber(val.SendInterval)) + l.SetField(tbl, "sudo_auth_methods", pushAuthMethods(l, val.SudoAuthMethods)) + case *mt.ToCltAddHUD: + 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])})) + 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, "amount", lua.LNumber(val.Amount)) + 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, "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, "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, "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])})) + 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])})) + 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])})) + } + if val.Field == mt.HUDDir { + l.SetField(tbl, "dir", lua.LNumber(val.Dir)) + } + 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)) + } + if val.Field == mt.HUDName { + l.SetField(tbl, "name", lua.LString(string(val.Name))) + } + if val.Field == mt.HUDNumber { + 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])})) + } + if val.Field == mt.HUDPos { + 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])})) + } + if val.Field == mt.HUDText { + l.SetField(tbl, "text", lua.LString(string(val.Text))) + } + if val.Field == mt.HUDText2 { + 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])})) + } + if val.Field == mt.HUDZIndex { + l.SetField(tbl, "z_index", lua.LNumber(val.ZIndex)) + } + case *mt.ToCltChatMsg: + 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)) + case *mt.ToCltCloudParams: + 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, "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, "thickness", lua.LNumber(val.Thickness)) + case *mt.ToCltCSMRestrictionFlags: + 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_cam", lua.LBool(val.PointCam)) + case *mt.ToCltDelParticleSpawner: + l.SetField(tbl, "id", lua.LNumber(val.ID)) + case *mt.ToCltDetachedInv: + l.SetField(tbl, "inv", lua.LString(string(val.Inv))) + l.SetField(tbl, "keep", lua.LBool(val.Keep)) + 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])})) + case *mt.ToCltFadeSound: + l.SetField(tbl, "gain", lua.LNumber(val.Gain)) + l.SetField(tbl, "id", lua.LNumber(val.ID)) + l.SetField(tbl, "step", lua.LNumber(val.Step)) + case *mt.ToCltFormspecPrepend: + l.SetField(tbl, "prepend", lua.LString(string(val.Prepend))) + case *mt.ToCltFOV: + l.SetField(tbl, "fov", lua.LNumber(val.FOV)) + 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, "compression", lua.LNumber(val.Compression)) + l.SetField(tbl, "proto_ver", lua.LNumber(val.ProtoVer)) + l.SetField(tbl, "serialize_ver", lua.LNumber(val.SerializeVer)) + l.SetField(tbl, "username", lua.LString(string(val.Username))) + 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)) + case *mt.ToCltInv: + l.SetField(tbl, "inv", lua.LString(string(val.Inv))) + case *mt.ToCltInvFormspec: + l.SetField(tbl, "formspec", lua.LString(string(val.Formspec))) + case *mt.ToCltKick: + 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)) + 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, "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])})) + case *mt.ToCltMediaPush: + l.SetField(tbl, "data", lua.LString(string(val.Data))) + l.SetField(tbl, "filename", lua.LString(string(val.Filename))) + l.SetField(tbl, "sha1", lua.LString(string(val.SHA1[:]))) + l.SetField(tbl, "should_cache", lua.LBool(val.ShouldCache)) + case *mt.ToCltModChanMsg: + l.SetField(tbl, "channel", lua.LString(string(val.Channel))) + l.SetField(tbl, "msg", lua.LString(string(val.Msg))) + 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)) + case *mt.ToCltMoonParams: + l.SetField(tbl, "size", lua.LNumber(val.Size)) + l.SetField(tbl, "texture", lua.LString(string(val.Texture))) + l.SetField(tbl, "tone_map", lua.LString(string(val.ToneMap))) + 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, "yaw", lua.LNumber(val.Yaw)) + case *mt.ToCltMovement: + l.SetField(tbl, "air_accel", lua.LNumber(val.AirAccel)) + l.SetField(tbl, "climb_speed", lua.LNumber(val.ClimbSpeed)) + l.SetField(tbl, "crouch_speed", lua.LNumber(val.CrouchSpeed)) + l.SetField(tbl, "default_accel", lua.LNumber(val.DefaultAccel)) + l.SetField(tbl, "fast_accel", lua.LNumber(val.FastAccel)) + l.SetField(tbl, "fast_speed", lua.LNumber(val.FastSpeed)) + l.SetField(tbl, "fluidity", lua.LNumber(val.Fluidity)) + l.SetField(tbl, "gravity", lua.LNumber(val.Gravity)) + l.SetField(tbl, "jump_speed", lua.LNumber(val.JumpSpeed)) + 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.ToCltOverrideDayNightRatio: + l.SetField(tbl, "override", lua.LBool(val.Override)) + l.SetField(tbl, "ratio", lua.LNumber(val.Ratio)) + case *mt.ToCltPlaySound: + l.SetField(tbl, "ephemeral", lua.LBool(val.Ephemeral)) + l.SetField(tbl, "fade", lua.LNumber(val.Fade)) + l.SetField(tbl, "gain", lua.LNumber(val.Gain)) + l.SetField(tbl, "id", lua.LNumber(val.ID)) + 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, "src_aoid", lua.LNumber(val.SrcAOID)) + l.SetField(tbl, "src_type", pushSoundSrcType(l, val.SrcType)) + case *mt.ToCltPrivs: + 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])})) + 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, "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, "clouds", lua.LBool(val.Clouds)) + if val.Type == "regular" { + l.SetField(tbl, "dawn_horizon", pushColor(l, val.DawnHorizon)) + } + if val.Type == "regular" { + l.SetField(tbl, "dawn_sky", pushColor(l, val.DawnSky)) + } + if val.Type == "regular" { + 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, "fog_tint_type", lua.LString(string(val.FogTintType))) + if val.Type == "regular" { + l.SetField(tbl, "indoor", pushColor(l, val.Indoor)) + } + l.SetField(tbl, "moon_fog_tint", pushColor(l, val.MoonFogTint)) + if val.Type == "regular" { + 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, "sun_fog_tint", pushColor(l, val.SunFogTint)) + if val.Type == "skybox" { + l.SetField(tbl, "textures", pushTextureList(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, "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, "expiration_time", lua.LNumber(val.ExpirationTime)) + l.SetField(tbl, "glow", lua.LNumber(val.Glow)) + 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, "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, "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, "count", lua.LNumber(val.Count)) + l.SetField(tbl, "size", lua.LNumber(val.Size)) + l.SetField(tbl, "visible", lua.LBool(val.Visible)) + case *mt.ToCltStopSound: + l.SetField(tbl, "id", lua.LNumber(val.ID)) + case *mt.ToCltSunParams: + l.SetField(tbl, "rise", lua.LString(string(val.Rise))) + l.SetField(tbl, "rising", lua.LBool(val.Rising)) + l.SetField(tbl, "size", lua.LNumber(val.Size)) + l.SetField(tbl, "texture", lua.LString(string(val.Texture))) + l.SetField(tbl, "tone_map", lua.LString(string(val.ToneMap))) + l.SetField(tbl, "visible", lua.LBool(val.Visible)) + case *mt.ToCltTimeOfDay: + 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)) + } + return tbl +} diff --git a/convert/push_mkauto.lua b/convert/push_mkauto.lua new file mode 100755 index 0000000..3e02932 --- /dev/null +++ b/convert/push_mkauto.lua @@ -0,0 +1,127 @@ +#!/usr/bin/env lua +require("spec") + +local funcs = "" + +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" + + for _, var in ipairs(fields) do + funcs = funcs .. "\tcase mt." .. apply_prefix(fields, var) .. ":\n\t\t" .. + (var == "no" and "return lua.LNil" or "return lua.LString(\"" .. var .. "\")") .. "\n" + end + + funcs = funcs .. "\t}\n\tpanic(\"impossible\")\n\treturn lua.LNil\n}\n\n" +end + +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" + + 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" + end + + funcs = funcs .. "\treturn tbl\n}\n\n" +end + +local tolua = { + string = "lua.LString(string(VAL))", + 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])}})", +} + +local function fields_tolua(fields, indent) + local impl = "" + + for name, type in spairs(fields) do + if name:sub(1, 1) ~= "{" then + local camel = "val." .. camel_case(name) + + local idt = indent + local condition = fields["{" .. name .. "}"] + + if condition then + impl = impl .. indent .. "if " .. condition .. " {\n" + idt = idt .. "\t" + end + + impl = impl .. idt .. "l.SetField(tbl, \"" .. name .. "\", " + if tolua[type] then + impl = impl .. tolua[type]:gsub("VAL", camel) + else + impl = impl .. "push" .. camel_case(type) .. "(l, " .. camel .. ")" + end + impl = impl .. ")\n" + + if condition then + impl = impl .. indent .. "}\n" + end + end + end + + return impl +end + +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" + .. fields_tolua(fields, "\t") + .. "\treturn tbl\n}\n\n" +end + +local pkt_type_impl = "" +local pkt_impl = "" + +for name, fields in spairs(parse_spec("client/pkt", true)) do + local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n" + + pkt_type_impl = pkt_type_impl + .. case .. "\t\treturn lua.LString(\"" .. name .. "\")\n" + + if next(fields) then + pkt_impl = pkt_impl .. case .. fields_tolua(fields, "\t\t") + end +end + +local f = io.open("push_auto.go", "w") +f:write([[ +// generated by push_mkauto.lua, DO NOT EDIT +package convert + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" +) + +]] .. funcs .. [[ +func PushPktType(pkt *mt.Pkt) lua.LString { + switch pkt.Cmd.(type) { +]] .. pkt_type_impl .. [[ + } + panic("impossible") + return "" +} + +func PushPkt(l *lua.LState, pkt *mt.Pkt) lua.LValue { + if pkt == nil { + return lua.LNil + } + tbl := l.NewTable() + l.SetField(tbl, "_type", PushPktType(pkt)) + switch val := pkt.Cmd.(type) { +]] .. pkt_impl .. [[ + } + return tbl +} +]]) +f:close() diff --git a/convert/push_static.go b/convert/push_static.go new file mode 100644 index 0000000..4eb7cb0 --- /dev/null +++ b/convert/push_static.go @@ -0,0 +1,97 @@ +package convert + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" + "image/color" +) + +//go:generate ./push_mkauto.lua + +func vec2(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) { + l.Push(l.GetGlobal("vec3")) + l.Push(val[0]) + l.Push(val[1]) + l.Push(val[2]) + l.Call(3, 1) +} + +func popValue(l *lua.LState) lua.LValue { + ret := l.Get(-1) + l.Pop(1) + return ret +} + +func pushVec2(l *lua.LState, val [2]lua.LNumber) lua.LValue { + vec2(l, val) + return popValue(l) +} + +func pushVec3(l *lua.LState, val [3]lua.LNumber) lua.LValue { + vec3(l, val) + return popValue(l) +} + +func pushBox1(l *lua.LState, val [2]lua.LNumber) lua.LValue { + l.Push(l.GetGlobal("box")) + l.Push(val[0]) + l.Push(val[1]) + l.Call(2, 1) + return popValue(l) +} + +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]) + l.Call(2, 1) + return popValue(l) +} + +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]) + l.Call(2, 1) + return popValue(l) +} + +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)) + l.SetField(tbl, "b", lua.LNumber(val.B)) + l.SetField(tbl, "a", lua.LNumber(val.A)) + return tbl +} + +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 { + 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 pushTextureList(l *lua.LState, val []mt.Texture) lua.LValue { + return stringList[mt.Texture](l, val) +} diff --git a/convert/read_auto.go b/convert/read_auto.go new file mode 100644 index 0000000..c5a39be --- /dev/null +++ b/convert/read_auto.go @@ -0,0 +1,320 @@ +// generated by read_mkauto.lua, DO NOT EDIT +package convert + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" +) + +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)) +} + +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)) +} + +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)) +} + +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)) +} + +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") + } + str := string(val.(lua.LString)) + switch str { + case "dig": + *ptr = mt.Dig + case "stop_digging": + *ptr = mt.StopDigging + case "dug": + *ptr = mt.Dug + case "place": + *ptr = mt.Place + case "use": + *ptr = mt.Use + case "activate": + *ptr = mt.Activate + default: + panic("invalid value for interaction: " + str) + } +} + +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") + } + if l.GetField(val, "forward") == lua.LTrue { + *ptr = *ptr | mt.ForwardKey + } + if l.GetField(val, "backward") == lua.LTrue { + *ptr = *ptr | mt.BackwardKey + } + if l.GetField(val, "left") == lua.LTrue { + *ptr = *ptr | mt.LeftKey + } + if l.GetField(val, "right") == lua.LTrue { + *ptr = *ptr | mt.RightKey + } + if l.GetField(val, "jump") == lua.LTrue { + *ptr = *ptr | mt.JumpKey + } + if l.GetField(val, "special") == lua.LTrue { + *ptr = *ptr | mt.SpecialKey + } + if l.GetField(val, "sneak") == lua.LTrue { + *ptr = *ptr | mt.SneakKey + } + if l.GetField(val, "dig") == lua.LTrue { + *ptr = *ptr | mt.DigKey + } + if l.GetField(val, "place") == lua.LTrue { + *ptr = *ptr | mt.PlaceKey + } + if l.GetField(val, "zoom") == lua.LTrue { + *ptr = *ptr | mt.ZoomKey + } +} + +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) +} + +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") + } + tbl := val.(*lua.LTable) + n := tbl.MaxN() + *ptr = make([]mt.SoundID, n) + for i := range *ptr { + readSoundID(l, l.RawGetInt(tbl, i+1), &(*ptr)[i]) + } +} + +func readSliceString(l *lua.LState, val lua.LValue, ptr *[]string) { + if val.Type() != lua.LTTable { + panic("invalid value for []string: must be a table") + } + tbl := val.(*lua.LTable) + n := tbl.MaxN() + *ptr = make([]string, n) + for i := range *ptr { + readString(l, l.RawGetInt(tbl, i+1), &(*ptr)[i]) + } +} + +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") + } + tbl := val.(*lua.LTable) + n := tbl.MaxN() + *ptr = make([][3]int16, n) + for i := range *ptr { + readVec3Int16(l, l.RawGetInt(tbl, i+1), &(*ptr)[i]) + } +} + +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)) +} + +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)) +} + +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)) +} + +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]) +} + +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]) +} + +func ReadCmd(l *lua.LState) mt.Cmd { + str := l.CheckString(2) + switch str { + case "chat_msg": + ptr := &mt.ToSrvChatMsg{} + val := l.CheckTable(3) + 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) + return ptr + case "deleted_blks": + ptr := &mt.ToSrvDeletedBlks{} + val := l.CheckTable(3) + 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) + 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) + return ptr + case "got_blks": + ptr := &mt.ToSrvGotBlks{} + val := l.CheckTable(3) + 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) + return ptr + case "init2": + ptr := &mt.ToSrvInit2{} + val := l.CheckTable(3) + 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) + return ptr + case "inv_action": + ptr := &mt.ToSrvInvAction{} + val := l.CheckTable(3) + 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) + return ptr + case "join_mod_chan": + ptr := &mt.ToSrvJoinModChan{} + val := l.CheckTable(3) + 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) + 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) + return ptr + case "nil": + ptr := &mt.ToSrvNil{} + return ptr + 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) + return ptr + case "player_pos": + ptr := &mt.ToSrvPlayerPos{} + val := l.CheckTable(3) + 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) + return ptr + case "req_media": + ptr := &mt.ToSrvReqMedia{} + val := l.CheckTable(3) + readSliceString(l, l.GetField(val, "filenames"), &ptr.Filenames) + return ptr + case "respawn": + ptr := &mt.ToSrvRespawn{} + return ptr + case "select_item": + ptr := &mt.ToSrvSelectItem{} + val := l.CheckTable(3) + 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) + return ptr + case "srp_bytes_m": + ptr := &mt.ToSrvSRPBytesM{} + val := l.CheckTable(3) + readSliceByte(l, l.GetField(val, "m"), &ptr.M) + return ptr + } + + panic("invalid packet type: " + str) +} diff --git a/convert/read_mkauto.lua b/convert/read_mkauto.lua new file mode 100755 index 0000000..f749f99 --- /dev/null +++ b/convert/read_mkauto.lua @@ -0,0 +1,198 @@ +#!/usr/bin/env lua +require("spec") + +local readers = { + SliceByte = true, + Byte = true, + String = true, + SliceField = true, + Field = true, + Bool = true, + PointedThing = true, +} + +local static_uses = { + "[3]int16", + "AOID" +} + +local function generate(name) + local fnname, index, child, childfn, childtype + local type = name + + local open = name:find("%[") + local clos = name:find("%]") + + if open == 1 then + index = name:sub(open + 1, clos - 1) + child = name:sub(clos + 1) + childfn, childtype = generate(child) + fnname = (index == "" and "Slice" or "Vec" .. index) .. childfn + + type = "[" .. index .. "]" .. childtype + else + fnname = camel_case(name) + + local c = name:sub(1, 1) + if c == c:upper() then + type = "mt." .. name + end + end + + if not readers[fnname] then + 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 " + .. name .. ": must be a table\")\n\t}\n" + + if index == "" then + fun = fun .. +[[ + tbl := val.(*lua.LTable) + n := tbl.MaxN() + *ptr = make(]] .. type .. [[, n) + for i := range *ptr { + read]] .. childfn .. [[(l, l.RawGetInt(tbl, i+1), &(*ptr)[i]) + } +]] + else + local n = tonumber(index) + for i, v in ipairs({"x", "y", "z"}) do + if i > n then + break + end + + fun = fun + .. "\tread" .. childfn + .. "(l, l.GetField(val, \"" .. v .. "\"), &(*ptr)[" .. (i - 1) .. "])\n" + end + end + else + 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" + end + + fun = fun .. "}\n\n" + + readers[fnname] = fun + end + + return fnname, type +end + +for _, use in ipairs(static_uses) 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" +end + +for name, fields in spairs(parse_spec("server/enum")) do + local camel = camel_case(name) + local fun = signature(name, "mt.") + + local impl = "" + for _, var in ipairs(fields) do + local equals = "*ptr = mt." .. apply_prefix(fields, var) .. "\n" + + if var == "no" then + fun = fun .. "\tif val.Type() == lua.LTNil {\n\t\t" .. equals .. "\t\treturn\n\t}\n" + else + impl = impl .. "\tcase \"" .. var .. "\":\n\t\t" .. equals + end + end + + fun = fun + .. "\tif val.Type() != lua.LTString {\n\t\tpanic(\"invalid value for " + .. camel .. ": must be a string\")\n\t}\n" + .. "\tstr := string(val.(lua.LString))\n" + .. "\tswitch str {\n" .. impl + .. "\tdefault:\n\t\tpanic(\"invalid value for " .. name .. ": \" + str)\n\t}\n}\n\n" + + readers[camel] = fun +end + +for name, fields in spairs(parse_spec("server/flag")) do + local camel = camel_case(name) + local fun = signature(name, "mt.") + .. "\tif val.Type() != lua.LTTable {\n\t\tpanic(\"invalid value for " + .. camel .. ": must be a table\")\n\t}\n" + + for _, var in ipairs(fields) do + fun = fun .. "\tif l.GetField(val, \"" .. var .. "\") == lua.LTrue {\n" + .. "\t\t*ptr = *ptr | mt." .. apply_prefix(fields, var) .. "\n\t}\n" + end + + fun = fun .. "}\n\n" + readers[camel] = fun +end + +local function fields_fromlua(fields, indent) + local impl = "" + + for name, type in spairs(fields) do + impl = impl .. indent .. "read" .. generate(type) .. "(l, l.GetField(val, \"" .. name .. "\"), &ptr." + .. camel_case(name) .. ")\n" + end + + return impl +end + +for name, fields in spairs(parse_spec("server/struct", true)) do + local camel = camel_case(name) + readers[camel] = signature(name, "mt.") + .. "\tif val.Type() != lua.LTTable {\n" + .. "\t\tpanic(\"invalid value for " .. camel .. ": must be a table\")\n\t}\n" + .. fields_fromlua(fields, "\t") + .. "}\n\n" +end + +local pkt_impl = "" + +for name, fields in spairs(parse_spec("server/pkt", true)) do + pkt_impl = pkt_impl + .. "\tcase \"" .. name .. "\"" .. "" .. ":\n" + .. "\t\tptr := &mt.ToSrv" .. camel_case(name) .. "{}\n" + + if next(fields) then + pkt_impl = pkt_impl + .. "\t\tval := l.CheckTable(3)\n" + .. fields_fromlua(fields, "\t\t") + end + + pkt_impl = pkt_impl + .. "\t\treturn ptr\n" +end + +local funcs = "" +for _, fn in spairs(readers) do + if type(fn) == "string" then + funcs = funcs .. fn + end +end + +local f = io.open("read_auto.go", "w") +f:write([[ +// generated by read_mkauto.lua, DO NOT EDIT +package convert + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" +) + +]] .. funcs .. [[ +func ReadCmd(l *lua.LState) mt.Cmd { + str := l.CheckString(2) + switch str { +]] .. pkt_impl .. [[ + } + + panic("invalid packet type: " + str) +} +]]) +f:close() diff --git a/convert/read_static.go b/convert/read_static.go new file mode 100644 index 0000000..2f62473 --- /dev/null +++ b/convert/read_static.go @@ -0,0 +1,59 @@ +package convert + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" +) + +//go:generate ./read_mkauto.lua + +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) { + 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) { + 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) { + if val.Type() != lua.LTTable { + panic("invalid value for []Field: must be a table") + } + val.(*lua.LTable).ForEach(func(k, v lua.LValue) { + if k.Type() != lua.LTString || v.Type() != lua.LTString { + panic("invalid value for Field: key and value must be strings") + } + *ptr = append(*ptr, mt.Field{Name: string(k.(lua.LString)), Value: string(v.(lua.LString))}) + }) +} + +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") + } + id := l.GetField(val, "id") + + if id == lua.LNil { + pt := &mt.PointedAO{} + 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) + *ptr = pt + } +} diff --git a/convert/spec.lua b/convert/spec.lua new file mode 100644 index 0000000..588f4d7 --- /dev/null +++ b/convert/spec.lua @@ -0,0 +1,108 @@ +local function snext(t, state) + local key + + if state == nil then + t.__sorted = {} + for k in pairs(t) do + if k ~= "__sorted" then + table.insert(t.__sorted, k) + end + end + table.sort(t.__sorted) + + key = t.__sorted[1] + else + for i, v in ipairs(t.__sorted) do + if v == state then + key = t.__sorted[i + 1] + break + end + end + end + + if key then + return key, t[key] + end + + t.__sorted = nil +end + +function spairs(t) + return snext, t, nil +end + +local function parse_pair(pair, value_first) + if pair:sub(1, 1) == "#" then + return + end + + local idx = pair:find(" ") + + if idx then + local first, second = pair:sub(1, idx - 1), pair:sub(idx + 1) + + if value_first and first:sub(1, 1) ~= "{" then + return second, first + else + return first, second + end + else + return pair + end +end + +function parse_spec(name, value_first) + local f = io.open("../spec/" .. name, "r") + local spec = {} + local top + + for l in f:lines() do + if l:sub(1, 1) == "\t" then + local key, val = parse_pair(l:sub(2), value_first) + + if val then + top[key] = val + elseif key then + table.insert(top, key) + end + else + local key, val = parse_pair(l, value_first) + + if val then + spec[key] = val + elseif key then + top = {} + spec[key] = top + end + end + end + + f:close() + return spec +end + +local casemap = parse_spec("casemap") + +function camel_case(snake) + if casemap[snake] then + return casemap[snake] + end + + local camel = "" + + while #snake > 0 do + local idx = snake:find("_") or #snake + 1 + + camel = camel + .. snake:sub(1, 1):upper() + .. snake:sub(2, idx - 1) + + snake = snake:sub(idx + 1) + end + + return camel +end + +function apply_prefix(fields, str) + return (fields.prefix or "") .. camel_case(str) .. (fields.postfix or "") +end |
