import (
"github.com/HimbeerserverDE/srp"
- "github.com/Shopify/go-lua"
"github.com/anon55555/mt"
+ "github.com/dragonfireclient/hydra/tolua"
+ "github.com/yuin/gopher-lua"
"strings"
"time"
)
username string
password string
language string
+ version string
state authState
err string
srpBytesA, bytesA []byte
+ userdata *lua.LUserData
}
-func getAuth(l *lua.State) *Auth {
- return lua.CheckUserData(l, 1, "hydra.auth").(*Auth)
+var authFuncs = map[string]lua.LGFunction{
+ "username": l_auth_username,
+ "password": l_auth_password,
+ "language": l_auth_language,
+ "version": l_auth_version,
+ "state": l_auth_state,
}
-func (auth *Auth) create(client *Client) {
+func getAuth(l *lua.LState) *Auth {
+ return l.CheckUserData(1).Value.(*Auth)
+}
+
+func (auth *Auth) create(client *Client, l *lua.LState) {
+ if client.state != csNew {
+ panic("can't add auth component after connect")
+ }
+
auth.client = client
auth.language = "en_US"
+ auth.version = "hydra-dragonfire"
auth.state = asInit
+ auth.userdata = l.NewUserData()
+ auth.userdata.Value = auth
+ l.SetMetatable(auth.userdata, l.GetTypeMetatable("hydra.auth"))
}
-func (auth *Auth) push(l *lua.State) {
- l.PushUserData(auth)
-
- if lua.NewMetaTable(l, "hydra.auth") {
- lua.NewLibrary(l, []lua.RegistryFunction{
- {Name: "username", Function: l_auth_username},
- {Name: "password", Function: l_auth_password},
- {Name: "language", Function: l_auth_language},
- {Name: "state", Function: l_auth_state},
- })
- l.SetField(-2, "__index")
- }
- l.SetMetaTable(-2)
+func (auth *Auth) tolua() lua.LValue {
+ return auth.userdata
}
-func (auth *Auth) canConnect() (bool, string) {
+func (auth *Auth) connect() {
if auth.username == "" {
- return false, "missing username"
+ panic("missing username")
}
- return true, ""
-}
-
-func (auth *Auth) connect() {
go func() {
- for auth.state == asInit && auth.client.state == csConnected {
+ for auth.client.state == csConnected && auth.state == asInit {
auth.client.conn.SendCmd(&mt.ToSrvInit{
SerializeVer: 28,
MinProtoVer: 39,
}()
}
-func (auth *Auth) setError(err string) {
- auth.state = asError
+func (auth *Auth) fail(err string) {
auth.err = err
- auth.client.conn.Close()
+ auth.state = asError
+ auth.client.disconnect()
}
func (auth *Auth) checkState(state authState, pkt *mt.Pkt) bool {
return true
}
- auth.setError("received " + pktToString(pkt) + " in invalid state")
+ auth.fail("received " + string(tolua.PktType(pkt)) + " in invalid state")
return false
}
-func (auth *Auth) handle(pkt *mt.Pkt, l *lua.State, idx int) {
- if pkt == nil {
+func (auth *Auth) process(pkt *mt.Pkt) {
+ if auth.state == asError {
return
}
}
if cmd.SerializeVer != 28 {
- auth.setError("unsupported serialize_ver")
+ auth.fail("unsupported serialize version")
return
}
if cmd.AuthMethods == mt.FirstSRP {
salt, verifier, err := srp.NewClient([]byte(strings.ToLower(auth.username)), []byte(auth.password))
if err != nil {
- auth.setError(err.Error())
+ auth.fail(err.Error())
return
}
var err error
auth.srpBytesA, auth.bytesA, err = srp.InitiateHandshake()
if err != nil {
- auth.setError(err.Error())
+ auth.fail(err.Error())
return
}
})
auth.state = asRequested
} else {
- auth.setError("invalid auth methods")
- return
+ auth.fail("invalid auth methods")
+ return
}
case *mt.ToCltSRPBytesSaltB:
srpBytesK, err := srp.CompleteHandshake(auth.srpBytesA, auth.bytesA, []byte(strings.ToLower(auth.username)), []byte(auth.password), cmd.Salt, cmd.B)
if err != nil {
- auth.setError(err.Error())
+ auth.fail(err.Error())
return
}
auth.bytesA = []byte{}
if M == nil {
- auth.setError("srp safety check fail")
+ auth.fail("srp safety check fail")
return
}
Patch: 0,
Reserved: 0,
Formspec: 4,
- Version: "hydra-dragonfire",
+ Version: auth.version,
})
auth.state = asActive
}
}
-func l_auth_username(l *lua.State) int {
- auth := getAuth(l)
-
- if l.IsString(2) {
- if auth.client.state > csNew {
- panic("can't change username after connecting")
+func (auth *Auth) accessProperty(l *lua.LState, key string, ptr *string) int {
+ if str, ok := l.Get(2).(lua.LString); ok {
+ if auth.client.state != csNew {
+ panic("can't change " + key + " after connecting")
}
- auth.username = lua.CheckString(l, 2)
+ *ptr = string(str)
return 0
} else {
- l.PushString(auth.username)
+ l.Push(lua.LString(*ptr))
return 1
}
}
-func l_auth_password(l *lua.State) int {
+func l_auth_username(l *lua.LState) int {
auth := getAuth(l)
+ return auth.accessProperty(l, "username", &auth.username)
+}
- if l.IsString(2) {
- if auth.client.state > csNew {
- panic("can't change password after connecting")
- }
- auth.password = lua.CheckString(l, 2)
- return 0
- } else {
- l.PushString(auth.password)
- return 1
- }
+func l_auth_password(l *lua.LState) int {
+ auth := getAuth(l)
+ return auth.accessProperty(l, "password", &auth.password)
}
-func l_auth_language(l *lua.State) int {
+func l_auth_language(l *lua.LState) int {
auth := getAuth(l)
+ return auth.accessProperty(l, "language", &auth.language)
+}
- if l.IsString(2) {
- if auth.client.state > csNew {
- panic("can't change language after connecting")
- }
- auth.language = lua.CheckString(l, 2)
- return 0
- } else {
- l.PushString(auth.language)
- return 1
- }
+func l_auth_version(l *lua.LState) int {
+ auth := getAuth(l)
+ return auth.accessProperty(l, "version", &auth.version)
}
-func l_auth_state(l *lua.State) int {
+func l_auth_state(l *lua.LState) int {
auth := getAuth(l)
switch auth.state {
case asInit:
- l.PushString("init")
+ l.Push(lua.LString("init"))
case asRequested:
- l.PushString("requested")
+ l.Push(lua.LString("requested"))
case asVerified:
- l.PushString("verified")
+ l.Push(lua.LString("verified"))
case asActive:
- l.PushString("active")
+ l.Push(lua.LString("active"))
case asError:
- l.PushString("error")
- l.PushString(auth.err)
+ l.Push(lua.LString("error"))
+ l.Push(lua.LString(auth.err))
return 2
}
--[[ builtin/vector.lua ]]--
local function wrap(op, body_wrapper, ...)
- return load("return function(a, b) " .. body_wrapper(op, ...) .. "end")()
+ return loadstring("return function(a, b) " .. body_wrapper(op, ...) .. "end")()
end
local function arith_mt(...)
+++ /dev/null
-package main
-
-import (
- "github.com/Shopify/go-lua"
- "github.com/anon55555/mt"
-)
-
-type Callbacks struct {
- wildcard bool
- subscribed map[string]struct{}
-}
-
-func getCallbacks(l *lua.State) *Callbacks {
- return lua.CheckUserData(l, 1, "hydra.callbacks").(*Callbacks)
-}
-
-func (handler *Callbacks) create(client *Client) {
- handler.subscribed = map[string]struct{}{}
-}
-
-func (handler *Callbacks) push(l *lua.State) {
- l.PushUserData(handler)
-
- if lua.NewMetaTable(l, "hydra.callbacks") {
- lua.NewLibrary(l, []lua.RegistryFunction{
- {Name: "wildcard", Function: l_callbacks_wildcard},
- {Name: "subscribe", Function: l_callbacks_subscribe},
- {Name: "unsubscribe", Function: l_callbacks_unsubscribe},
- })
- l.SetField(-2, "__index")
- }
- l.SetMetaTable(-2)
-}
-
-func (handler *Callbacks) canConnect() (bool, string) {
- return true, ""
-}
-
-func (handler *Callbacks) connect() {
-}
-
-func (handler *Callbacks) handle(pkt *mt.Pkt, l *lua.State, idx int) {
- if !handler.wildcard && pkt != nil {
- if _, exists := handler.subscribed[pktToString(pkt)]; !exists {
- return
- }
- }
-
- if !l.IsFunction(2) {
- return
- }
-
- l.PushValue(2) // callback
- l.RawGetInt(1, idx) // arg 1: client
- pktToLua(l, pkt) // arg 2: pkt
- l.Call(2, 0)
-}
-
-func l_callbacks_wildcard(l *lua.State) int {
- handler := getCallbacks(l)
- handler.wildcard = l.ToBoolean(2)
- return 0
-}
-
-func l_callbacks_subscribe(l *lua.State) int {
- handler := getCallbacks(l)
-
- n := l.Top()
- for i := 2; i <= n; i++ {
- handler.subscribed[lua.CheckString(l, i)] = struct{}{}
- }
-
- return 0
-}
-
-func l_callbacks_unsubscribe(l *lua.State) int {
- handler := getCallbacks(l)
-
- n := l.Top()
- for i := 2; i <= n; i++ {
- delete(handler.subscribed, lua.CheckString(l, i))
- }
-
- return 0
-}
import (
"errors"
- "github.com/Shopify/go-lua"
"github.com/anon55555/mt"
+ "github.com/dragonfireclient/hydra/tolua"
+ "github.com/yuin/gopher-lua"
"net"
+ "sync"
)
type clientState uint8
csDisconnected
)
-type Handler interface {
- create(client *Client)
- push(l *lua.State)
- canConnect() (bool, string)
+type Component interface {
+ create(client *Client, l *lua.LState)
+ tolua() lua.LValue
connect()
- handle(pkt *mt.Pkt, l *lua.State, idx int)
+ process(pkt *mt.Pkt)
}
type Client struct {
- address string
- state clientState
- handlers map[string]Handler
- conn mt.Peer
- queue chan *mt.Pkt
+ mu sync.Mutex
+ address string
+ state clientState
+ conn mt.Peer
+ queue chan *mt.Pkt
+ wildcard bool
+ subscribed map[string]struct{}
+ components map[string]Component
+ userdata *lua.LUserData
}
-func getClient(l *lua.State) *Client {
- return lua.CheckUserData(l, 1, "hydra.client").(*Client)
+var clientFuncs = map[string]lua.LGFunction{
+ "address": l_client_address,
+ "state": l_client_state,
+ "connect": l_client_connect,
+ "poll": l_client_poll,
+ "disconnect": l_client_disconnect,
+ "enable": l_client_enable,
+ "subscribe": l_client_subscribe,
+ "unsubscribe": l_client_unsubscribe,
+ "wildcard": l_client_wildcard,
}
-func l_client(l *lua.State) int {
- client := &Client{
- address: lua.CheckString(l, 1),
- state: csNew,
- handlers: map[string]Handler{},
- }
+func getClient(l *lua.LState) *Client {
+ return l.CheckUserData(1).Value.(*Client)
+}
+
+func getClients(l *lua.LState) []*Client {
+ tbl := l.CheckTable(1)
+ n := tbl.MaxN()
- l.PushUserData(client)
-
- if lua.NewMetaTable(l, "hydra.client") {
- lua.NewLibrary(l, []lua.RegistryFunction{
- {Name: "address", Function: l_client_address},
- {Name: "state", Function: l_client_state},
- {Name: "handler", Function: l_client_handler},
- {Name: "connect", Function: l_client_connect},
- {Name: "disconnect", Function: l_client_disconnect},
- })
- l.SetField(-2, "__index")
+ clients := make([]*Client, 0, n)
+ for i := 1; i <= n; i++ {
+ clients = append(clients, l.RawGetInt(tbl, i).(*lua.LUserData).Value.(*Client))
}
- l.SetMetaTable(-2)
- return 1
+ return clients
}
-func l_client_address(l *lua.State) int {
- client := getClient(l)
- l.PushString(client.address)
- return 1
-}
+func getStrings(l *lua.LState) []string {
+ n := l.GetTop()
-func l_client_state(l *lua.State) int {
- client := getClient(l)
- switch client.state {
- case csNew:
- l.PushString("new")
- case csConnected:
- l.PushString("connected")
- case csDisconnected:
- l.PushString("disconnected")
+ strs := make([]string, 0, n-1)
+ for i := 2; i <= n; i++ {
+ strs = append(strs, l.CheckString(i))
}
- return 1
+
+ return strs
}
-func l_client_handler(l *lua.State) int {
- client := getClient(l)
- name := lua.CheckString(l, 2)
+func (client *Client) disconnect() {
+ client.mu.Lock()
+ defer client.mu.Unlock()
- handler, exists := client.handlers[name]
- if !exists {
- switch name {
- case "callbacks":
- handler = &Callbacks{}
+ if client.state == csConnected {
+ client.conn.Close()
+ }
+}
- case "auth":
- handler = &Auth{}
+func l_client(l *lua.LState) int {
+ client := &Client{}
- default:
- return 0
- }
+ client.address = l.CheckString(1)
+ client.state = csNew
+ client.wildcard = false
+ client.subscribed = map[string]struct{}{}
+ client.components = map[string]Component{}
+ client.userdata = l.NewUserData()
+ client.userdata.Value = client
+ l.SetMetatable(client.userdata, l.GetTypeMetatable("hydra.client"))
- client.handlers[name] = handler
- handler.create(client)
+ l.Push(client.userdata)
+ return 1
+}
+
+func l_client_index(l *lua.LState) int {
+ client := getClient(l)
+ key := l.CheckString(2)
+
+ if fun, exists := clientFuncs[key]; exists {
+ l.Push(l.NewFunction(fun))
+ } else if component, exists := client.components[key]; exists {
+ l.Push(component.tolua())
+ } else {
+ l.Push(lua.LNil)
}
- handler.push(l)
return 1
}
-func l_client_connect(l *lua.State) int {
+func l_client_address(l *lua.LState) int {
client := getClient(l)
+ l.Push(lua.LString(client.address))
+ return 1
+}
- if client.state != csNew {
- l.PushBoolean(false)
- l.PushString("invalid state")
- return 2
+func l_client_state(l *lua.LState) int {
+ client := getClient(l)
+ switch client.state {
+ case csNew:
+ l.Push(lua.LString("new"))
+ case csConnected:
+ l.Push(lua.LString("connected"))
+ case csDisconnected:
+ l.Push(lua.LString("disconnected"))
}
+ return 1
+}
- for _, handler := range client.handlers {
- ok, err := handler.canConnect()
+func l_client_connect(l *lua.LState) int {
+ client := getClient(l)
- if !ok {
- l.PushBoolean(false)
- l.PushString(err)
- return 2
- }
+ if client.state != csNew {
+ panic("can't reconnect")
}
addr, err := net.ResolveUDPAddr("udp", client.address)
if err != nil {
- l.PushBoolean(false)
- l.PushString(err.Error())
- return 2
+ panic(err)
}
conn, err := net.DialUDP("udp", nil, addr)
if err != nil {
- l.PushBoolean(false)
- l.PushString(err.Error())
- return 2
+ panic(err)
}
client.state = csConnected
client.conn = mt.Connect(conn)
client.queue = make(chan *mt.Pkt, 1024)
- for _, handler := range client.handlers {
- handler.connect()
- }
-
go func() {
for {
pkt, err := client.conn.Recv()
if err == nil {
- client.queue <- &pkt
+ client.mu.Lock()
+
+ for _, component := range client.components {
+ component.process(&pkt)
+ }
+
+ if _, exists := client.subscribed[string(tolua.PktType(&pkt))]; exists || client.wildcard {
+ client.queue <- &pkt
+ }
+
+ client.mu.Unlock()
} else if errors.Is(err, net.ErrClosed) {
close(client.queue)
return
}
}()
- l.PushBoolean(true)
- return 1
+ client.mu.Lock()
+ for _, component := range client.components {
+ component.connect()
+ }
+ client.mu.Unlock()
+
+ return 0
+}
+
+func l_client_poll(l *lua.LState) int {
+ client := getClient(l)
+ _, pkt, timeout := doPoll(l, []*Client{client})
+
+ l.Push(tolua.Pkt(l, pkt))
+ l.Push(lua.LBool(timeout))
+ return 2
+}
+
+func l_client_disconnect(l *lua.LState) int {
+ client := getClient(l)
+ client.disconnect()
+ return 0
+}
+
+func l_client_enable(l *lua.LState) int {
+ client := getClient(l)
+ client.mu.Lock()
+ defer client.mu.Unlock()
+
+ for _, compname := range getStrings(l) {
+ if component, exists := client.components[compname]; !exists {
+ switch compname {
+ case "auth":
+ component = &Auth{}
+ default:
+ panic("invalid component: " + compname)
+ }
+
+ client.components[compname] = component
+ component.create(client, l)
+ }
+ }
+
+ return 0
+}
+
+func l_client_subscribe(l *lua.LState) int {
+ client := getClient(l)
+ client.mu.Lock()
+ defer client.mu.Unlock()
+
+ for _, pkt := range getStrings(l) {
+ client.subscribed[pkt] = struct{}{}
+ }
+
+ return 0
}
-func l_client_disconnect(l *lua.State) int {
+func l_client_unsubscribe(l *lua.LState) int {
client := getClient(l)
+ client.mu.Lock()
+ defer client.mu.Unlock()
+
+ for _, pkt := range getStrings(l) {
+ delete(client.subscribed, pkt)
+ }
+
+ return 0
+}
+
+func l_client_wildcard(l *lua.LState) int {
+ client := getClient(l)
+ client.wildcard = l.ToBool(2)
+ return 0
+}
+
+/*
+
+func l_client_send(l *lua.LState) int {
+ client := getClient(l)
+ pkt := fromlua.Pkt(l.CheckTable(2))
+
+ client.mu.Lock()
+ defer client.mu.Unlock()
if client.state == csConnected {
- client.conn.Close()
+ client.conn.Send(pkt)
}
return 0
}
+
+*/
+++ /dev/null
-// generated by mkconvert.lua, DO NOT EDIT
-package main
-
-import (
- "github.com/Shopify/go-lua"
- "github.com/anon55555/mt"
-)
-
-func luaPushAnimType(l *lua.State, val mt.AnimType) {
- switch val {
- case mt.NoAnim:
- l.PushNil()
- case mt.VerticalFrameAnim:
- l.PushString("vertical_frame")
- case mt.SpriteSheetAnim:
- l.PushString("sprite_sheet")
- }
-}
-
-func luaPushChatMsgType(l *lua.State, val mt.ChatMsgType) {
- switch val {
- case mt.RawMsg:
- l.PushString("raw")
- case mt.NormalMsg:
- l.PushString("normal")
- case mt.AnnounceMsg:
- l.PushString("announce")
- case mt.SysMsg:
- l.PushString("sys")
- }
-}
-
-func luaPushHotbarParam(l *lua.State, val mt.HotbarParam) {
- switch val {
- case mt.HotbarSize:
- l.PushString("size")
- case mt.HotbarImg:
- l.PushString("img")
- case mt.HotbarSelImg:
- l.PushString("sel_img")
- }
-}
-
-func luaPushHUDField(l *lua.State, val mt.HUDField) {
- switch val {
- case mt.HUDPos:
- l.PushString("pos")
- case mt.HUDName:
- l.PushString("name")
- case mt.HUDScale:
- l.PushString("scale")
- case mt.HUDText:
- l.PushString("text")
- case mt.HUDNumber:
- l.PushString("number")
- case mt.HUDItem:
- l.PushString("item")
- case mt.HUDDir:
- l.PushString("dir")
- case mt.HUDAlign:
- l.PushString("align")
- case mt.HUDOffset:
- l.PushString("offset")
- case mt.HUDWorldPos:
- l.PushString("world_pos")
- case mt.HUDSize:
- l.PushString("size")
- case mt.HUDZIndex:
- l.PushString("z_index")
- case mt.HUDText2:
- l.PushString("text_2")
- }
-}
-
-func luaPushHUDType(l *lua.State, val mt.HUDType) {
- switch val {
- case mt.ImgHUD:
- l.PushString("img")
- case mt.TextHUD:
- l.PushString("text")
- case mt.StatbarHUD:
- l.PushString("statbar")
- case mt.InvHUD:
- l.PushString("inv")
- case mt.WaypointHUD:
- l.PushString("waypoint")
- case mt.ImgWaypointHUD:
- l.PushString("img_waypoint")
- }
-}
-
-func luaPushKickReason(l *lua.State, val mt.KickReason) {
- switch val {
- case mt.WrongPasswd:
- l.PushString("wrong_passwd")
- case mt.UnexpectedData:
- l.PushString("unexpected_data")
- case mt.SrvIsSingleplayer:
- l.PushString("srv_is_singleplayer")
- case mt.UnsupportedVer:
- l.PushString("unsupported_ver")
- case mt.BadNameChars:
- l.PushString("bad_name_chars")
- case mt.BadName:
- l.PushString("bad_name")
- case mt.TooManyClts:
- l.PushString("too_many_clts")
- case mt.EmptyPasswd:
- l.PushString("empty_passwd")
- case mt.AlreadyConnected:
- l.PushString("already_connected")
- case mt.SrvErr:
- l.PushString("srv_err")
- case mt.Custom:
- l.PushString("custom")
- case mt.Shutdown:
- l.PushString("shutdown")
- case mt.Crash:
- l.PushString("crash")
- }
-}
-
-func luaPushModChanSig(l *lua.State, val mt.ModChanSig) {
- switch val {
- case mt.JoinOK:
- l.PushString("join_ok")
- case mt.JoinFail:
- l.PushString("join_fail")
- case mt.LeaveOK:
- l.PushString("leave_ok")
- case mt.LeaveFail:
- l.PushString("leave_fail")
- case mt.NotRegistered:
- l.PushString("not_registered")
- case mt.SetState:
- l.PushString("set_state")
- }
-}
-
-func luaPushPlayerListUpdateType(l *lua.State, val mt.PlayerListUpdateType) {
- switch val {
- case mt.InitPlayers:
- l.PushString("init")
- case mt.AddPlayers:
- l.PushString("add")
- case mt.RemovePlayers:
- l.PushString("remove")
- }
-}
-
-func luaPushSoundSrcType(l *lua.State, val mt.SoundSrcType) {
- switch val {
- case mt.NoSrc:
- l.PushNil()
- case mt.PosSrc:
- l.PushString("pos")
- case mt.AOSrc:
- l.PushString("ao")
- }
-}
-
-func luaPushAuthMethods(l *lua.State, val mt.AuthMethods) {
- l.NewTable()
- if val&mt.LegacyPasswd != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "legacy_passwd")
- }
- if val&mt.SRP != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "srp")
- }
- if val&mt.FirstSRP != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "first_srp")
- }
-}
-
-func luaPushCSMRestrictionFlags(l *lua.State, val mt.CSMRestrictionFlags) {
- l.NewTable()
- if val&mt.NoCSMs != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "no_csms")
- }
- if val&mt.NoChatMsgs != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "no_chat_msgs")
- }
- if val&mt.NoNodeDefs != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "no_node_defs")
- }
- if val&mt.LimitMapRange != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "limit_map_range")
- }
- if val&mt.NoPlayerList != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "no_player_list")
- }
-}
-
-func luaPushHUDFlags(l *lua.State, val mt.HUDFlags) {
- l.NewTable()
- if val&mt.ShowHotbar != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "hotbar")
- }
- if val&mt.ShowHealthBar != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "health_bar")
- }
- if val&mt.ShowCrosshair != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "crosshair")
- }
- if val&mt.ShowWieldedItem != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "wielded_item")
- }
- if val&mt.ShowBreathBar != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "breath_bar")
- }
- if val&mt.ShowMinimap != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "minimap")
- }
- if val&mt.ShowRadarMinimap != 0 {
- l.PushBoolean(true)
- l.SetField(-2, "radar_minimap")
- }
-}
-
-func luaPushHUD(l *lua.State, val mt.HUD) {
- l.NewTable()
- luaPushVec2(l, [2]float64{float64(val.Align[0]), float64(val.Align[1])})
- l.SetField(-2, "align")
- l.PushInteger(int(val.Dir))
- l.SetField(-2, "dir")
- l.PushInteger(int(val.Item))
- l.SetField(-2, "item")
- l.PushString(string(val.Name))
- l.SetField(-2, "name")
- l.PushInteger(int(val.Number))
- l.SetField(-2, "number")
- luaPushVec2(l, [2]float64{float64(val.Offset[0]), float64(val.Offset[1])})
- l.SetField(-2, "offset")
- luaPushVec2(l, [2]float64{float64(val.Pos[0]), float64(val.Pos[1])})
- l.SetField(-2, "pos")
- luaPushVec2(l, [2]float64{float64(val.Scale[0]), float64(val.Scale[1])})
- l.SetField(-2, "scale")
- luaPushVec2(l, [2]float64{float64(val.Size[0]), float64(val.Size[1])})
- l.SetField(-2, "size")
- l.PushString(string(val.Text))
- l.SetField(-2, "text")
- l.PushString(string(val.Text2))
- l.SetField(-2, "text_2")
- luaPushHUDType(l, val.Type)
- l.SetField(-2, "type")
- luaPushVec3(l, [3]float64{float64(val.WorldPos[0]), float64(val.WorldPos[1]), float64(val.WorldPos[2])})
- l.SetField(-2, "world_pos")
- l.PushInteger(int(val.ZIndex))
- l.SetField(-2, "z_index")
-}
-
-func luaPushNode(l *lua.State, val mt.Node) {
- l.NewTable()
- l.PushInteger(int(val.Param0))
- l.SetField(-2, "param0")
- l.PushInteger(int(val.Param1))
- l.SetField(-2, "param1")
- l.PushInteger(int(val.Param2))
- l.SetField(-2, "param2")
-}
-
-func luaPushTileAnim(l *lua.State, val mt.TileAnim) {
- l.NewTable()
- luaPushVec2(l, [2]float64{float64(val.AspectRatio[0]), float64(val.AspectRatio[1])})
- l.SetField(-2, "aspect_ratio")
- l.PushNumber(float64(val.Duration))
- l.SetField(-2, "duration")
- luaPushVec2(l, [2]float64{float64(val.NFrames[0]), float64(val.NFrames[1])})
- l.SetField(-2, "n_frames")
- luaPushAnimType(l, val.Type)
- l.SetField(-2, "type")
-}
-
-func pktToString(pkt *mt.Pkt) string {
- switch pkt.Cmd.(type) {
- case *mt.ToCltAcceptAuth:
- return "accept_auth"
- case *mt.ToCltAcceptSudoMode:
- return "accept_sudo_mode"
- case *mt.ToCltAddHUD:
- return "add_hud"
- case *mt.ToCltAddNode:
- return "add_node"
- case *mt.ToCltAddParticleSpawner:
- return "add_particle_spawner"
- case *mt.ToCltAddPlayerVel:
- return "add_player_vel"
- case *mt.ToCltAnnounceMedia:
- return "announce_media"
- case *mt.ToCltAOMsgs:
- return "ao_msgs"
- case *mt.ToCltAORmAdd:
- return "ao_rm_add"
- case *mt.ToCltBlkData:
- return "blk_data"
- case *mt.ToCltBreath:
- return "breath"
- case *mt.ToCltChangeHUD:
- return "change_hud"
- case *mt.ToCltChatMsg:
- return "chat_msg"
- case *mt.ToCltCloudParams:
- return "cloud_params"
- case *mt.ToCltCSMRestrictionFlags:
- return "csm_restriction_flags"
- case *mt.ToCltDeathScreen:
- return "death_screen"
- case *mt.ToCltDelParticleSpawner:
- return "del_particle_spawner"
- case *mt.ToCltDenySudoMode:
- return "deny_sudo_mode"
- case *mt.ToCltDetachedInv:
- return "detached_inv"
- case *mt.ToCltDisco:
- return "disco"
- case *mt.ToCltEyeOffset:
- return "eye_offset"
- case *mt.ToCltFadeSound:
- return "fade_sound"
- case *mt.ToCltFormspecPrepend:
- return "formspec_prepend"
- case *mt.ToCltFOV:
- return "fov"
- case *mt.ToCltHello:
- return "hello"
- case *mt.ToCltHP:
- return "hp"
- case *mt.ToCltHUDFlags:
- return "hud_flags"
- case *mt.ToCltInv:
- return "inv"
- case *mt.ToCltInvFormspec:
- return "inv_formspec"
- case *mt.ToCltItemDefs:
- return "item_defs"
- case *mt.ToCltKick:
- return "kick"
- case *mt.ToCltLegacyKick:
- return "legacy_kick"
- case *mt.ToCltLocalPlayerAnim:
- return "local_player_anim"
- case *mt.ToCltMedia:
- return "media"
- case *mt.ToCltMediaPush:
- return "media_push"
- case *mt.ToCltMinimapModes:
- return "minimap_modes"
- case *mt.ToCltModChanMsg:
- return "mod_chan_msg"
- case *mt.ToCltModChanSig:
- return "mod_chan_sig"
- case *mt.ToCltMoonParams:
- return "moon_params"
- case *mt.ToCltMovePlayer:
- return "move_player"
- case *mt.ToCltMovement:
- return "movement"
- case *mt.ToCltNodeDefs:
- return "node_defs"
- case *mt.ToCltNodeMetasChanged:
- return "node_metas_changed"
- case *mt.ToCltOverrideDayNightRatio:
- return "override_day_night_ratio"
- case *mt.ToCltPlaySound:
- return "play_sound"
- case *mt.ToCltPrivs:
- return "privs"
- case *mt.ToCltRemoveNode:
- return "remove_node"
- case *mt.ToCltRmHUD:
- return "rm_hud"
- case *mt.ToCltSetHotbarParam:
- return "set_hotbar_param"
- case *mt.ToCltShowFormspec:
- return "show_formspec"
- case *mt.ToCltSkyParams:
- return "sky_params"
- case *mt.ToCltSpawnParticle:
- return "spawn_particle"
- case *mt.ToCltSRPBytesSaltB:
- return "srp_bytes_salt_b"
- case *mt.ToCltStarParams:
- return "star_params"
- case *mt.ToCltStopSound:
- return "stop_sound"
- case *mt.ToCltSunParams:
- return "sun_params"
- case *mt.ToCltTimeOfDay:
- return "time_of_day"
- case *mt.ToCltUpdatePlayerList:
- return "update_player_list"
- }
- panic("impossible")
- return ""
-}
-
-func pktToLua(l *lua.State, pkt *mt.Pkt) {
- if pkt == nil {
- l.PushNil()
- return
- }
- l.NewTable()
- l.PushString(pktToString(pkt))
- l.SetField(-2, "_type")
- switch val := pkt.Cmd.(type) {
- case *mt.ToCltAcceptAuth:
- l.PushNumber(float64(val.MapSeed))
- l.SetField(-2, "map_seed")
- luaPushVec3(l, [3]float64{float64(val.PlayerPos[0]), float64(val.PlayerPos[1]), float64(val.PlayerPos[2])})
- l.SetField(-2, "player_pos")
- l.PushNumber(float64(val.SendInterval))
- l.SetField(-2, "send_interval")
- luaPushAuthMethods(l, val.SudoAuthMethods)
- l.SetField(-2, "sudo_auth_methods")
- case *mt.ToCltAddHUD:
- luaPushHUD(l, val.HUD)
- l.SetField(-2, "hud")
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- case *mt.ToCltAddNode:
- l.PushBoolean(bool(val.KeepMeta))
- l.SetField(-2, "keep_meta")
- luaPushNode(l, val.Node)
- l.SetField(-2, "node")
- luaPushVec3(l, [3]float64{float64(val.Pos[0]), float64(val.Pos[1]), float64(val.Pos[2])})
- l.SetField(-2, "pos")
- case *mt.ToCltAddParticleSpawner:
- luaPushBox3(l, [2][3]float64{{float64(val.Acc[0][0]), float64(val.Acc[0][1]), float64(val.Acc[0][2])}, {float64(val.Acc[1][0]), float64(val.Acc[1][1]), float64(val.Acc[1][2])}})
- l.SetField(-2, "acc")
- l.PushInteger(int(val.Amount))
- l.SetField(-2, "amount")
- luaPushTileAnim(l, val.AnimParams)
- l.SetField(-2, "anim_params")
- l.PushBoolean(bool(val.AOCollision))
- l.SetField(-2, "ao_collision")
- l.PushBoolean(bool(val.Collide))
- l.SetField(-2, "collide")
- l.PushBoolean(bool(val.CollisionRm))
- l.SetField(-2, "collision_rm")
- l.PushNumber(float64(val.Duration))
- l.SetField(-2, "duration")
- luaPushBox1(l, [2]float64{float64(val.ExpirationTime[0]), float64(val.ExpirationTime[1])})
- l.SetField(-2, "expiration_time")
- l.PushInteger(int(val.Glow))
- l.SetField(-2, "glow")
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- l.PushInteger(int(val.NodeParam0))
- l.SetField(-2, "node_param0")
- l.PushInteger(int(val.NodeParam2))
- l.SetField(-2, "node_param2")
- l.PushInteger(int(val.NodeTile))
- l.SetField(-2, "node_tile")
- luaPushBox3(l, [2][3]float64{{float64(val.Pos[0][0]), float64(val.Pos[0][1]), float64(val.Pos[0][2])}, {float64(val.Pos[1][0]), float64(val.Pos[1][1]), float64(val.Pos[1][2])}})
- l.SetField(-2, "pos")
- luaPushBox1(l, [2]float64{float64(val.Size[0]), float64(val.Size[1])})
- l.SetField(-2, "size")
- l.PushString(string(val.Texture))
- l.SetField(-2, "texture")
- luaPushBox3(l, [2][3]float64{{float64(val.Vel[0][0]), float64(val.Vel[0][1]), float64(val.Vel[0][2])}, {float64(val.Vel[1][0]), float64(val.Vel[1][1]), float64(val.Vel[1][2])}})
- l.SetField(-2, "vel")
- l.PushBoolean(bool(val.Vertical))
- l.SetField(-2, "vertical")
- case *mt.ToCltAddPlayerVel:
- luaPushVec3(l, [3]float64{float64(val.Vel[0]), float64(val.Vel[1]), float64(val.Vel[2])})
- l.SetField(-2, "vel")
- case *mt.ToCltBlkData:
- luaPushVec3(l, [3]float64{float64(val.Blkpos[0]), float64(val.Blkpos[1]), float64(val.Blkpos[2])})
- l.SetField(-2, "blkpos")
- case *mt.ToCltBreath:
- l.PushInteger(int(val.Breath))
- l.SetField(-2, "breath")
- case *mt.ToCltChangeHUD:
- if val.Field == mt.HUDAlign {
- luaPushVec2(l, [2]float64{float64(val.Align[0]), float64(val.Align[1])})
- l.SetField(-2, "align")
- }
- if val.Field == mt.HUDDir {
- l.PushInteger(int(val.Dir))
- l.SetField(-2, "dir")
- }
- luaPushHUDField(l, val.Field)
- l.SetField(-2, "field")
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- if val.Field == mt.HUDItem {
- l.PushInteger(int(val.Item))
- l.SetField(-2, "item")
- }
- if val.Field == mt.HUDName {
- l.PushString(string(val.Name))
- l.SetField(-2, "name")
- }
- if val.Field == mt.HUDNumber {
- l.PushInteger(int(val.Number))
- l.SetField(-2, "number")
- }
- if val.Field == mt.HUDOffset {
- luaPushVec2(l, [2]float64{float64(val.Offset[0]), float64(val.Offset[1])})
- l.SetField(-2, "offset")
- }
- if val.Field == mt.HUDPos {
- luaPushVec2(l, [2]float64{float64(val.Pos[0]), float64(val.Pos[1])})
- l.SetField(-2, "pos")
- }
- if val.Field == mt.HUDSize {
- luaPushVec2(l, [2]float64{float64(val.Size[0]), float64(val.Size[1])})
- l.SetField(-2, "size")
- }
- if val.Field == mt.HUDText {
- l.PushString(string(val.Text))
- l.SetField(-2, "text")
- }
- if val.Field == mt.HUDText2 {
- l.PushString(string(val.Text2))
- l.SetField(-2, "text_2")
- }
- if val.Field == mt.HUDWorldPos {
- luaPushVec3(l, [3]float64{float64(val.WorldPos[0]), float64(val.WorldPos[1]), float64(val.WorldPos[2])})
- l.SetField(-2, "world_pos")
- }
- if val.Field == mt.HUDZIndex {
- l.PushInteger(int(val.ZIndex))
- l.SetField(-2, "z_index")
- }
- case *mt.ToCltChatMsg:
- l.PushString(string(val.Sender))
- l.SetField(-2, "sender")
- l.PushString(string(val.Text))
- l.SetField(-2, "text")
- l.PushNumber(float64(val.Timestamp))
- l.SetField(-2, "timestamp")
- luaPushChatMsgType(l, val.Type)
- l.SetField(-2, "type")
- case *mt.ToCltCloudParams:
- luaPushColor(l, val.AmbientColor)
- l.SetField(-2, "ambient_color")
- l.PushNumber(float64(val.Density))
- l.SetField(-2, "density")
- luaPushColor(l, val.DiffuseColor)
- l.SetField(-2, "diffuse_color")
- l.PushNumber(float64(val.Height))
- l.SetField(-2, "height")
- luaPushVec2(l, [2]float64{float64(val.Speed[0]), float64(val.Speed[1])})
- l.SetField(-2, "speed")
- l.PushNumber(float64(val.Thickness))
- l.SetField(-2, "thickness")
- case *mt.ToCltCSMRestrictionFlags:
- luaPushCSMRestrictionFlags(l, val.Flags)
- l.SetField(-2, "flags")
- l.PushInteger(int(val.MapRange))
- l.SetField(-2, "map_range")
- case *mt.ToCltDeathScreen:
- luaPushVec3(l, [3]float64{float64(val.PointAt[0]), float64(val.PointAt[1]), float64(val.PointAt[2])})
- l.SetField(-2, "point_at")
- l.PushBoolean(bool(val.PointCam))
- l.SetField(-2, "point_cam")
- case *mt.ToCltDelParticleSpawner:
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- case *mt.ToCltDetachedInv:
- l.PushString(string(val.Inv))
- l.SetField(-2, "inv")
- l.PushBoolean(bool(val.Keep))
- l.SetField(-2, "keep")
- l.PushInteger(int(val.Len))
- l.SetField(-2, "len")
- l.PushString(string(val.Name))
- l.SetField(-2, "name")
- case *mt.ToCltEyeOffset:
- luaPushVec3(l, [3]float64{float64(val.First[0]), float64(val.First[1]), float64(val.First[2])})
- l.SetField(-2, "first")
- luaPushVec3(l, [3]float64{float64(val.Third[0]), float64(val.Third[1]), float64(val.Third[2])})
- l.SetField(-2, "third")
- case *mt.ToCltFadeSound:
- l.PushNumber(float64(val.Gain))
- l.SetField(-2, "gain")
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- l.PushNumber(float64(val.Step))
- l.SetField(-2, "step")
- case *mt.ToCltFormspecPrepend:
- l.PushString(string(val.Prepend))
- l.SetField(-2, "prepend")
- case *mt.ToCltFOV:
- l.PushNumber(float64(val.FOV))
- l.SetField(-2, "fov")
- l.PushBoolean(bool(val.Multiplier))
- l.SetField(-2, "multiplier")
- l.PushNumber(float64(val.TransitionTime))
- l.SetField(-2, "transition_time")
- case *mt.ToCltHello:
- luaPushAuthMethods(l, val.AuthMethods)
- l.SetField(-2, "auth_methods")
- l.PushInteger(int(val.Compression))
- l.SetField(-2, "compression")
- l.PushInteger(int(val.ProtoVer))
- l.SetField(-2, "proto_ver")
- l.PushInteger(int(val.SerializeVer))
- l.SetField(-2, "serialize_ver")
- l.PushString(string(val.Username))
- l.SetField(-2, "username")
- case *mt.ToCltHP:
- l.PushInteger(int(val.HP))
- l.SetField(-2, "hp")
- case *mt.ToCltHUDFlags:
- luaPushHUDFlags(l, val.Flags)
- l.SetField(-2, "flags")
- luaPushHUDFlags(l, val.Mask)
- l.SetField(-2, "mask")
- case *mt.ToCltInv:
- l.PushString(string(val.Inv))
- l.SetField(-2, "inv")
- case *mt.ToCltInvFormspec:
- l.PushString(string(val.Formspec))
- l.SetField(-2, "formspec")
- case *mt.ToCltKick:
- if dr := val.Reason; dr == mt.Custom || dr == mt.Shutdown || dr == mt.Crash {
- l.PushString(string(val.Custom))
- l.SetField(-2, "custom")
- }
- luaPushKickReason(l, val.Reason)
- l.SetField(-2, "reason")
- if dr := val.Reason; dr == mt.Shutdown || dr == mt.Crash {
- l.PushBoolean(bool(val.Reconnect))
- l.SetField(-2, "reconnect")
- }
- case *mt.ToCltLegacyKick:
- l.PushString(string(val.Reason))
- l.SetField(-2, "reason")
- case *mt.ToCltLocalPlayerAnim:
- luaPushBox1(l, [2]float64{float64(val.Dig[0]), float64(val.Dig[1])})
- l.SetField(-2, "dig")
- luaPushBox1(l, [2]float64{float64(val.Idle[0]), float64(val.Idle[1])})
- l.SetField(-2, "idle")
- l.PushNumber(float64(val.Speed))
- l.SetField(-2, "speed")
- luaPushBox1(l, [2]float64{float64(val.Walk[0]), float64(val.Walk[1])})
- l.SetField(-2, "walk")
- luaPushBox1(l, [2]float64{float64(val.WalkDig[0]), float64(val.WalkDig[1])})
- l.SetField(-2, "walk_dig")
- case *mt.ToCltMediaPush:
- l.PushString(string(val.Data))
- l.SetField(-2, "data")
- l.PushString(string(val.Filename))
- l.SetField(-2, "filename")
- l.PushString(string(val.SHA1[:]))
- l.SetField(-2, "sha1")
- l.PushBoolean(bool(val.ShouldCache))
- l.SetField(-2, "should_cache")
- case *mt.ToCltModChanMsg:
- l.PushString(string(val.Channel))
- l.SetField(-2, "channel")
- l.PushString(string(val.Msg))
- l.SetField(-2, "msg")
- l.PushString(string(val.Sender))
- l.SetField(-2, "sender")
- case *mt.ToCltModChanSig:
- l.PushString(string(val.Channel))
- l.SetField(-2, "channel")
- luaPushModChanSig(l, val.Signal)
- l.SetField(-2, "signal")
- case *mt.ToCltMoonParams:
- l.PushNumber(float64(val.Size))
- l.SetField(-2, "size")
- l.PushString(string(val.Texture))
- l.SetField(-2, "texture")
- l.PushString(string(val.ToneMap))
- l.SetField(-2, "tone_map")
- l.PushBoolean(bool(val.Visible))
- l.SetField(-2, "visible")
- case *mt.ToCltMovePlayer:
- l.PushNumber(float64(val.Pitch))
- l.SetField(-2, "pitch")
- luaPushVec3(l, [3]float64{float64(val.Pos[0]), float64(val.Pos[1]), float64(val.Pos[2])})
- l.SetField(-2, "pos")
- l.PushNumber(float64(val.Yaw))
- l.SetField(-2, "yaw")
- case *mt.ToCltMovement:
- l.PushNumber(float64(val.AirAccel))
- l.SetField(-2, "air_accel")
- l.PushNumber(float64(val.ClimbSpeed))
- l.SetField(-2, "climb_speed")
- l.PushNumber(float64(val.CrouchSpeed))
- l.SetField(-2, "crouch_speed")
- l.PushNumber(float64(val.DefaultAccel))
- l.SetField(-2, "default_accel")
- l.PushNumber(float64(val.FastAccel))
- l.SetField(-2, "fast_accel")
- l.PushNumber(float64(val.FastSpeed))
- l.SetField(-2, "fast_speed")
- l.PushNumber(float64(val.Fluidity))
- l.SetField(-2, "fluidity")
- l.PushNumber(float64(val.Gravity))
- l.SetField(-2, "gravity")
- l.PushNumber(float64(val.JumpSpeed))
- l.SetField(-2, "jump_speed")
- l.PushNumber(float64(val.Sink))
- l.SetField(-2, "sink")
- l.PushNumber(float64(val.Smoothing))
- l.SetField(-2, "smoothing")
- l.PushNumber(float64(val.WalkSpeed))
- l.SetField(-2, "walk_speed")
- case *mt.ToCltOverrideDayNightRatio:
- l.PushBoolean(bool(val.Override))
- l.SetField(-2, "override")
- l.PushInteger(int(val.Ratio))
- l.SetField(-2, "ratio")
- case *mt.ToCltPlaySound:
- l.PushBoolean(bool(val.Ephemeral))
- l.SetField(-2, "ephemeral")
- l.PushNumber(float64(val.Fade))
- l.SetField(-2, "fade")
- l.PushNumber(float64(val.Gain))
- l.SetField(-2, "gain")
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- l.PushBoolean(bool(val.Loop))
- l.SetField(-2, "loop")
- l.PushString(string(val.Name))
- l.SetField(-2, "name")
- l.PushNumber(float64(val.Pitch))
- l.SetField(-2, "pitch")
- luaPushVec3(l, [3]float64{float64(val.Pos[0]), float64(val.Pos[1]), float64(val.Pos[2])})
- l.SetField(-2, "pos")
- l.PushInteger(int(val.SrcAOID))
- l.SetField(-2, "src_aoid")
- luaPushSoundSrcType(l, val.SrcType)
- l.SetField(-2, "src_type")
- case *mt.ToCltPrivs:
- luaPushStringSet(l, val.Privs)
- l.SetField(-2, "privs")
- case *mt.ToCltRemoveNode:
- luaPushVec3(l, [3]float64{float64(val.Pos[0]), float64(val.Pos[1]), float64(val.Pos[2])})
- l.SetField(-2, "pos")
- case *mt.ToCltRmHUD:
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- case *mt.ToCltSetHotbarParam:
- l.PushString(string(val.Img))
- l.SetField(-2, "img")
- luaPushHotbarParam(l, val.Param)
- l.SetField(-2, "param")
- l.PushInteger(int(val.Size))
- l.SetField(-2, "size")
- case *mt.ToCltShowFormspec:
- l.PushString(string(val.Formname))
- l.SetField(-2, "formname")
- l.PushString(string(val.Formspec))
- l.SetField(-2, "formspec")
- case *mt.ToCltSkyParams:
- luaPushColor(l, val.BgColor)
- l.SetField(-2, "bg_color")
- l.PushBoolean(bool(val.Clouds))
- l.SetField(-2, "clouds")
- if val.Type == "regular" {
- luaPushColor(l, val.DawnHorizon)
- l.SetField(-2, "dawn_horizon")
- }
- if val.Type == "regular" {
- luaPushColor(l, val.DawnSky)
- l.SetField(-2, "dawn_sky")
- }
- if val.Type == "regular" {
- luaPushColor(l, val.DayHorizon)
- l.SetField(-2, "day_horizon")
- }
- if val.Type == "regular" {
- luaPushColor(l, val.DaySky)
- l.SetField(-2, "day_sky")
- }
- l.PushString(string(val.FogTintType))
- l.SetField(-2, "fog_tint_type")
- if val.Type == "regular" {
- luaPushColor(l, val.Indoor)
- l.SetField(-2, "indoor")
- }
- luaPushColor(l, val.MoonFogTint)
- l.SetField(-2, "moon_fog_tint")
- if val.Type == "regular" {
- luaPushColor(l, val.NightHorizon)
- l.SetField(-2, "night_horizon")
- }
- if val.Type == "regular" {
- luaPushColor(l, val.NightSky)
- l.SetField(-2, "night_sky")
- }
- luaPushColor(l, val.SunFogTint)
- l.SetField(-2, "sun_fog_tint")
- if val.Type == "skybox" {
- luaPushTextureList(l, val.Textures)
- l.SetField(-2, "textures")
- }
- l.PushString(string(val.Type))
- l.SetField(-2, "type")
- case *mt.ToCltSpawnParticle:
- luaPushVec3(l, [3]float64{float64(val.Acc[0]), float64(val.Acc[1]), float64(val.Acc[2])})
- l.SetField(-2, "acc")
- luaPushTileAnim(l, val.AnimParams)
- l.SetField(-2, "anim_params")
- l.PushBoolean(bool(val.AOCollision))
- l.SetField(-2, "ao_collision")
- l.PushBoolean(bool(val.Collide))
- l.SetField(-2, "collide")
- l.PushBoolean(bool(val.CollisionRm))
- l.SetField(-2, "collision_rm")
- l.PushNumber(float64(val.ExpirationTime))
- l.SetField(-2, "expiration_time")
- l.PushInteger(int(val.Glow))
- l.SetField(-2, "glow")
- l.PushInteger(int(val.NodeParam0))
- l.SetField(-2, "node_param0")
- l.PushInteger(int(val.NodeParam2))
- l.SetField(-2, "node_param2")
- l.PushInteger(int(val.NodeTile))
- l.SetField(-2, "node_tile")
- luaPushVec3(l, [3]float64{float64(val.Pos[0]), float64(val.Pos[1]), float64(val.Pos[2])})
- l.SetField(-2, "pos")
- l.PushNumber(float64(val.Size))
- l.SetField(-2, "size")
- l.PushString(string(val.Texture))
- l.SetField(-2, "texture")
- luaPushVec3(l, [3]float64{float64(val.Vel[0]), float64(val.Vel[1]), float64(val.Vel[2])})
- l.SetField(-2, "vel")
- l.PushBoolean(bool(val.Vertical))
- l.SetField(-2, "vertical")
- case *mt.ToCltSRPBytesSaltB:
- l.PushString(string(val.B))
- l.SetField(-2, "b")
- l.PushString(string(val.Salt))
- l.SetField(-2, "salt")
- case *mt.ToCltStarParams:
- luaPushColor(l, val.Color)
- l.SetField(-2, "color")
- l.PushInteger(int(val.Count))
- l.SetField(-2, "count")
- l.PushNumber(float64(val.Size))
- l.SetField(-2, "size")
- l.PushBoolean(bool(val.Visible))
- l.SetField(-2, "visible")
- case *mt.ToCltStopSound:
- l.PushInteger(int(val.ID))
- l.SetField(-2, "id")
- case *mt.ToCltSunParams:
- l.PushString(string(val.Rise))
- l.SetField(-2, "rise")
- l.PushBoolean(bool(val.Rising))
- l.SetField(-2, "rising")
- l.PushNumber(float64(val.Size))
- l.SetField(-2, "size")
- l.PushString(string(val.Texture))
- l.SetField(-2, "texture")
- l.PushString(string(val.ToneMap))
- l.SetField(-2, "tone_map")
- l.PushBoolean(bool(val.Visible))
- l.SetField(-2, "visible")
- case *mt.ToCltTimeOfDay:
- l.PushNumber(float64(val.Speed))
- l.SetField(-2, "speed")
- l.PushInteger(int(val.Time))
- l.SetField(-2, "time")
- case *mt.ToCltUpdatePlayerList:
- luaPushStringList(l, val.Players)
- l.SetField(-2, "players")
- luaPushPlayerListUpdateType(l, val.Type)
- l.SetField(-2, "type")
- }
-}
--- /dev/null
+#!/usr/bin/env hydra
+local address, name, password = unpack(arg)
+local client = hydra.client(address)
+
+client:enable("auth")
+client.auth:username(name)
+client.auth:password(password or "")
+
+client:wildcard(true)
+client:connect()
+
+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
+ end
+ elseif not interrupt then
+ print("disconnected")
+ break
+ end
+end
+
+client:disconnect()
module github.com/dragonfireclient/hydra
-go 1.17
+go 1.18
require (
- github.com/HimbeerserverDE/srp v0.0.0 // indirect
- github.com/Shopify/go-lua v0.0.0-20220120202609-9ab779377807 // indirect
- github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f // indirect
- github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 // indirect
+ github.com/HimbeerserverDE/srp v0.0.0
+ github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f
+ github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64
)
github.com/HimbeerserverDE/srp v0.0.0 h1:Iy2GIF7DJphXXO9NjncLEBO6VsZd8Yhrlxl/qTr09eE=
github.com/HimbeerserverDE/srp v0.0.0/go.mod h1:pxNH8S2nh4n2DWE0ToX5GnnDr/uEAuaAhJsCpkDLIWw=
-github.com/Shopify/go-lua v0.0.0-20220120202609-9ab779377807 h1:b10jUZ94GuJk5GBl0iElM5aGIPPHi7FTRvqOKA7Ku+s=
-github.com/Shopify/go-lua v0.0.0-20220120202609-9ab779377807/go.mod h1:1cxA/QL5xgRGP7Crq6tXSOY4eo//me8GHGMyypHynM8=
github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f h1:tZU8VPYLyRrG3Lj9zBZvTVF5tUGciC/2aUIgTcU4WaM=
github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f/go.mod h1:jH4ER+ahjl7H6TczzK+q4V9sXY++U2Geh6/vt3r4Xvs=
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
import (
_ "embed"
- "github.com/Shopify/go-lua"
+ "github.com/dragonfireclient/hydra/tolua"
+ "github.com/yuin/gopher-lua"
"os"
"os/signal"
"syscall"
//go:embed builtin/vector.lua
var vectorLibrary string
-func l_dtime(l *lua.State) int {
- l.PushNumber(time.Since(lastTime).Seconds())
- lastTime = time.Now()
- return 1
-}
-
-func l_canceled(l *lua.State) int {
- l.PushBoolean(canceled)
- return 1
+var hydraFuncs = map[string]lua.LGFunction{
+ "client": l_client,
+ "dtime": l_dtime,
+ "canceled": l_canceled,
+ "poll": l_poll,
+ "disconnect": l_disconnect,
}
func signalChannel() chan os.Signal {
return sig
}
+func l_dtime(l *lua.LState) int {
+ l.Push(lua.LNumber(time.Since(lastTime).Seconds()))
+ return 1
+}
+
+func l_canceled(l *lua.LState) int {
+ l.Push(lua.LBool(canceled))
+ return 1
+}
+
+func l_poll(l *lua.LState) int {
+ client, pkt, timeout := doPoll(l, getClients(l))
+ if client == nil {
+ l.Push(lua.LNil)
+ } else {
+ l.Push(client.userdata)
+ }
+ l.Push(tolua.Pkt(l, pkt))
+ l.Push(lua.LBool(timeout))
+ return 3
+}
+
+func l_disconnect(l *lua.LState) int {
+ for _, client := range getClients(l) {
+ client.disconnect()
+ }
+
+ return 0
+}
+
func main() {
if len(os.Args) < 2 {
panic("missing filename")
canceled = true
}()
- l := lua.NewState()
- lua.OpenLibraries(l)
-
- lua.NewLibrary(l, []lua.RegistryFunction{
- {Name: "client", Function: l_client},
- {Name: "dtime", Function: l_dtime},
- {Name: "canceled", Function: l_canceled},
- {Name: "poll", Function: l_poll},
- })
+ l := lua.NewState(lua.Options{IncludeGoStackTrace: true})
+ defer l.Close()
- l.PushNumber(10.0)
- l.SetField(-2, "BS")
+ arg := l.NewTable()
+ for i, a := range os.Args {
+ l.RawSetInt(arg, i-1, lua.LString(a))
+ }
+ l.SetGlobal("arg", arg)
- l.SetGlobal("hydra")
+ hydra := l.SetFuncs(l.NewTable(), hydraFuncs)
+ l.SetField(hydra, "BS", lua.LNumber(10.0))
+ l.SetGlobal("hydra", hydra)
- l.NewTable()
- for i, arg := range os.Args {
- l.PushString(arg)
- l.RawSetInt(-2, i - 1)
- }
- l.SetGlobal("arg")
+ l.SetField(l.NewTypeMetatable("hydra.auth"), "__index", l.SetFuncs(l.NewTable(), authFuncs))
+ l.SetField(l.NewTypeMetatable("hydra.client"), "__index", l.NewFunction(l_client_index))
- if err := lua.DoString(l, vectorLibrary); err != nil {
+ if err := l.DoString(vectorLibrary); err != nil {
panic(err)
}
- if err := lua.DoFile(l, os.Args[1]); err != nil {
+ if err := l.DoFile(os.Args[1]); err != nil {
panic(err)
}
}
+++ /dev/null
-#!/usr/bin/env lua
-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
-
-local 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
-
-local 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")
-
-local 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
-
-local funcs = ""
-
-for name, fields in spairs(parse_spec("client/enum")) do
- local camel = camel_case(name)
- funcs = funcs .. "func luaPush" .. camel .. "(l *lua.State, val mt." .. camel .. ") {\n\tswitch val {\n"
-
- for _, var in ipairs(fields) do
- funcs = funcs .. "\tcase mt."
- .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "")
- .. ":\n\t\t" .. (var == "no" and "l.PushNil()" or "l.PushString(\"" .. var .. "\")") .. "\n"
- end
-
- funcs = funcs .. "\t}\n}\n\n"
-end
-
-for name, fields in spairs(parse_spec("client/flag")) do
- local camel = camel_case(name)
- funcs = funcs .. "func luaPush" .. camel .. "(l *lua.State, val mt." .. camel .. ") {\n\tl.NewTable()\n"
-
- for _, var in ipairs(fields) do
- funcs = funcs .. "\tif val&mt."
- .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "")
- .. " != 0 {\n\t\tl.PushBoolean(true)\n\t\tl.SetField(-2, \"" .. var .. "\")\n\t}\n"
- end
-
- funcs = funcs .. "}\n\n"
-end
-
-local push_type = {
- string = "l.PushString(string(VAL))",
- fixed_string = "l.PushString(string(VAL[:]))",
- boolean = "l.PushBoolean(bool(VAL))",
- integer = "l.PushInteger(int(VAL))",
- number = "l.PushNumber(float64(VAL))",
- vec2 = "luaPushVec2(l, [2]float64{float64(VAL[0]), float64(VAL[1])})",
- vec3 = "luaPushVec3(l, [3]float64{float64(VAL[0]), float64(VAL[1]), float64(VAL[2])})",
- box1 = "luaPushBox1(l, [2]float64{float64(VAL[0]), float64(VAL[1])})",
- box2 = "luaPushBox2(l, [2][2]float64{{float64(VAL[0][0]), float64(VAL[0][1])}, {float64(VAL[1][0]), float64(VAL[1][1])}})",
- box3 = "luaPushBox3(l, [2][3]float64{{float64(VAL[0][0]), float64(VAL[0][1]), float64(VAL[0][2])}, {float64(VAL[1][0]), float64(VAL[1][1]), float64(VAL[1][2])}})",
-}
-
-local function push_fields(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
-
- if push_type[type] then
- impl = impl .. idt .. push_type[type]:gsub("VAL", camel) .. "\n"
- else
- impl = impl .. idt .. "luaPush" .. camel_case(type) .. "(l, " .. camel .. ")\n"
- end
-
- impl = impl .. idt .. "l.SetField(-2, \"" .. name .. "\")\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 luaPush" .. camel .. "(l *lua.State, val mt." .. camel .. ") {\n\tl.NewTable()\n"
- .. push_fields(fields, "\t")
- .. "}\n\n"
-end
-
-local to_string_impl = ""
-local to_lua_impl = ""
-
-for name, fields in spairs(parse_spec("client/pkt", true)) do
- local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n"
-
- to_string_impl = to_string_impl
- .. case .. "\t\treturn \"" .. name .. "\"\n"
-
- if next(fields) then
- to_lua_impl = to_lua_impl .. case .. push_fields(fields, "\t\t")
- end
-end
-
-local f = io.open("convert.go", "w")
-f:write([[
-// generated by mkconvert.lua, DO NOT EDIT
-package main
-
-import (
- "github.com/Shopify/go-lua"
- "github.com/anon55555/mt"
-)
-
-]] .. funcs .. [[
-func pktToString(pkt *mt.Pkt) string {
- switch pkt.Cmd.(type) {
-]] .. to_string_impl .. [[
- }
- panic("impossible")
- return ""
-}
-
-func pktToLua(l *lua.State, pkt *mt.Pkt) {
- if pkt == nil {
- l.PushNil()
- return
- }
- l.NewTable()
- l.PushString(pktToString(pkt))
- l.SetField(-2, "_type")
- switch val := pkt.Cmd.(type) {
-]] .. to_lua_impl .. [[
- }
-}
-]])
-f:close()
--- /dev/null
+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
+
package main
import (
- "github.com/Shopify/go-lua"
"github.com/anon55555/mt"
+ "github.com/yuin/gopher-lua"
"reflect"
"time"
)
-func l_poll(l *lua.State) int {
- clients := make([]*Client, 0)
-
- lua.CheckType(l, 1, lua.TypeTable)
- i := 1
- for {
- l.RawGetInt(1, i)
- if l.IsNil(-1) {
- l.Pop(1)
- break
- }
-
- clients = append(clients, l.ToUserData(-1).(*Client))
- i++
- }
-
+func doPoll(l *lua.LState, clients []*Client) (*Client, *mt.Pkt, bool) {
var timeout time.Duration
hasTimeout := false
- if l.IsNumber(3) {
- timeout = time.Duration(lua.CheckNumber(l, 3) * float64(time.Second))
+ if l.GetTop() > 1 {
+ timeout = time.Duration(float64(l.ToNumber(2)) * float64(time.Second))
hasTimeout = true
}
- for {
- cases := make([]reflect.SelectCase, 0, len(clients)+2)
+ cases := make([]reflect.SelectCase, 0, len(clients)+2)
+ for _, client := range clients {
+ if client.state != csConnected {
+ continue
+ }
- for _, client := range clients {
- if client.state != csConnected {
- continue
- }
+ cases = append(cases, reflect.SelectCase{
+ Dir: reflect.SelectRecv,
+ Chan: reflect.ValueOf(client.queue),
+ })
+ }
- cases = append(cases, reflect.SelectCase{
- Dir: reflect.SelectRecv,
- Chan: reflect.ValueOf(client.queue),
- })
- }
+ offset := len(cases)
- offset := len(cases)
+ if offset < 1 {
+ return nil, nil, false
+ }
- if offset < 1 {
- l.PushBoolean(false)
- return 1
- }
+ cases = append(cases, reflect.SelectCase{
+ Dir: reflect.SelectRecv,
+ Chan: reflect.ValueOf(signalChannel()),
+ })
+ if hasTimeout {
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
- Chan: reflect.ValueOf(signalChannel()),
+ Chan: reflect.ValueOf(time.After(timeout)),
})
+ }
- if hasTimeout {
- cases = append(cases, reflect.SelectCase{
- Dir: reflect.SelectRecv,
- Chan: reflect.ValueOf(time.After(timeout)),
- })
- }
-
- idx, value, ok := reflect.Select(cases)
-
- if idx >= offset {
- l.PushBoolean(true)
- return 1
- }
+ idx, value, ok := reflect.Select(cases)
- client := clients[idx]
+ if idx >= offset {
+ return nil, nil, true
+ }
- var pkt *mt.Pkt = nil
- if ok {
- pkt = value.Interface().(*mt.Pkt)
- } else {
- client.state = csDisconnected
- }
+ client := clients[idx]
- for _, handler := range client.handlers {
- handler.handle(pkt, l, idx+1)
- }
+ var pkt *mt.Pkt = nil
+ if ok {
+ pkt = value.Interface().(*mt.Pkt)
+ } else {
+ client.state = csDisconnected
}
- panic("impossible")
- return 0
+ return client, pkt, false
}
hello
- integer serialize_ver
- integer compression
- integer proto_ver
+ number serialize_ver
+ number compression
+ number proto_ver
auth_methods auth_methods
string username
accept_auth
deny_sudo_mode
kick
kick_reason reason
- [custom] dr := val.Reason; dr == mt.Custom || dr == mt.Shutdown || dr == mt.Crash
+ [custom] val.Reason == mt.Custom || val.Reason == mt.Shutdown || val.Reason == mt.Crash
string custom
- [reconnect] dr := val.Reason; dr == mt.Shutdown || dr == mt.Crash
+ [reconnect] val.Reason == mt.Shutdown || val.Reason == mt.Crash
boolean reconnect
blk_data
vec3 blkpos
inv
string inv
time_of_day
- integer time
+ number time
number speed
csm_restriction_flags
csm_restriction_flags flags
- integer map_range
+ number map_range
add_player_vel
vec3 vel
media_push
ao_msgs
# TODO
hp
- integer hp
+ number hp
move_player
vec3 pos
number pitch
item_defs
# TODO
play_sound
- integer id
+ number id
string name
number gain
sound_src_type src_type
vec3 pos
- integer src_aoid
+ number src_aoid
boolean loop
number fade
number pitch
boolean ephemeral
stop_sound
- integer id
+ number id
privs
string_set privs
inv_formspec
detached_inv
string name
boolean keep
- integer len
+ number len
string inv
show_formspec
string formspec
boolean vertical
boolean collision_rm
tile_anim anim_params
- integer glow
+ number glow
boolean ao_collision
- integer node_param0
- integer node_param2
- integer node_tile
+ number node_param0
+ number node_param2
+ number node_tile
add_particle_spawner
- integer amount
+ number amount
number duration
box3 pos
box3 vel
box1 size
boolean collide
string texture
- integer id
+ number id
boolean vertical
boolean collision_rm
tile_anim anim_params
- integer glow
+ number glow
boolean ao_collision
- integer node_param0
- integer node_param2
- integer node_tile
+ number node_param0
+ number node_param2
+ number node_tile
add_hud
- integer id
+ number id
hud hud
rm_hud
- integer id
+ number id
change_hud
- integer id
+ number id
hud_field field
[pos] val.Field == mt.HUDPos
[name] val.Field == mt.HUDName
vec2 pos
string name
string text
- integer number
- integer item
- integer dir
+ number number
+ number item
+ number dir
vec2 align
vec2 offset
vec3 world_pos
vec2 size
- integer z_index
+ number z_index
string text_2
hud_flags
hud_flags flags
hud_flags mask
set_hotbar_param
hotbar_param param
- integer size
+ number size
string img
breath
- integer breath
+ number breath
sky_params
color bg_color
string type
color indoor
override_day_night_ratio
boolean override
- integer ratio
+ number ratio
local_player_anim
box1 idle
box1 walk
vec3 first
vec3 third
del_particle_spawner
- integer id
+ number id
cloud_params
number density
color diffuse_color
number thickness
vec2 speed
fade_sound
- integer id
+ number id
number step
number gain
update_player_list
number size
star_params
boolean visible
- integer count
+ number count
color color
number size
srp_bytes_salt_b
node
- integer param0
- integer param1
- integer param2
+ number param0
+ number param1
+ number param2
tile_anim
anim_type type
vec2 aspect_ratio
string name
vec2 scale
string text
- integer number
- integer item
- integer dir
+ number number
+ number item
+ number dir
vec2 align
vec2 offset
vec3 world_pos
vec2 size
- integer z_index
+ number z_index
string text_2
--- /dev/null
+#!/usr/bin/env lua
+dofile("../parse_spec.lua")
+
+local funcs = ""
+
+for name, fields in spairs(parse_spec("client/enum")) do
+ local camel = camel_case(name)
+ funcs = funcs .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\tswitch val {\n"
+
+ for _, var in ipairs(fields) do
+ funcs = funcs .. "\tcase mt."
+ .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "")
+ .. ":\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 " .. 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."
+ .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "")
+ .. " != 0 {\n\t\tl.SetField(tbl, \"" .. var .. "\", lua.LTrue)\n\t}\n"
+ end
+
+ funcs = funcs .. "\treturn tbl\n}\n\n"
+end
+
+local to_lua = {
+ string = "lua.LString(string(VAL))",
+ fixed_string = "lua.LString(string(VAL[:]))",
+ boolean = "lua.LBool(VAL)",
+ number = "lua.LNumber(VAL)",
+ vec2 = "Vec2(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
+ vec3 = "Vec3(l, [3]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1]), lua.LNumber(VAL[2])})",
+ box1 = "Box1(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
+ box2 = "Box2(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 = "Box3(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_to_lua(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 to_lua[type] then
+ impl = impl .. to_lua[type]:gsub("VAL", camel)
+ else
+ impl = impl .. 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 " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
+ .. fields_to_lua(fields, "\t")
+ .. "\treturn tbl\n}\n\n"
+end
+
+local to_string_impl = ""
+local to_lua_impl = ""
+
+for name, fields in spairs(parse_spec("client/pkt", true)) do
+ local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n"
+
+ to_string_impl = to_string_impl
+ .. case .. "\t\treturn lua.LString(\"" .. name .. "\")\n"
+
+ if next(fields) then
+ to_lua_impl = to_lua_impl .. case .. fields_to_lua(fields, "\t\t")
+ end
+end
+
+local f = io.open("generated.go", "w")
+f:write([[
+// generated by generate.lua, DO NOT EDIT
+package tolua
+
+import (
+ "github.com/anon55555/mt"
+ "github.com/yuin/gopher-lua"
+)
+
+]] .. funcs .. [[
+func PktType(pkt *mt.Pkt) lua.LString {
+ switch pkt.Cmd.(type) {
+]] .. to_string_impl .. [[
+ }
+ panic("impossible")
+ return ""
+}
+
+func Pkt(l *lua.LState, pkt *mt.Pkt) lua.LValue {
+ if pkt == nil {
+ return lua.LNil
+ }
+ tbl := l.NewTable()
+ l.SetField(tbl, "_type", PktType(pkt))
+ switch val := pkt.Cmd.(type) {
+]] .. to_lua_impl .. [[
+ }
+ return tbl
+}
+]])
+f:close()
--- /dev/null
+// generated by generate.lua, DO NOT EDIT
+package tolua
+
+import (
+ "github.com/anon55555/mt"
+ "github.com/yuin/gopher-lua"
+)
+
+func AnimType(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 ChatMsgType(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 HotbarParam(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 HUDField(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 HUDType(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 KickReason(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 ModChanSig(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 PlayerListUpdateType(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 SoundSrcType(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 AuthMethods(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 CSMRestrictionFlags(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 HUDFlags(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 HUD(l *lua.LState, val mt.HUD) lua.LValue {
+ tbl := l.NewTable()
+ l.SetField(tbl, "align", Vec2(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", Vec2(l, [2]lua.LNumber{lua.LNumber(val.Offset[0]), lua.LNumber(val.Offset[1])}))
+ l.SetField(tbl, "pos", Vec2(l, [2]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1])}))
+ l.SetField(tbl, "scale", Vec2(l, [2]lua.LNumber{lua.LNumber(val.Scale[0]), lua.LNumber(val.Scale[1])}))
+ l.SetField(tbl, "size", Vec2(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", HUDType(l, val.Type))
+ l.SetField(tbl, "world_pos", Vec3(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 Node(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 TileAnim(l *lua.LState, val mt.TileAnim) lua.LValue {
+ tbl := l.NewTable()
+ l.SetField(tbl, "aspect_ratio", Vec2(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", Vec2(l, [2]lua.LNumber{lua.LNumber(val.NFrames[0]), lua.LNumber(val.NFrames[1])}))
+ l.SetField(tbl, "type", AnimType(l, val.Type))
+ return tbl
+}
+
+func PktType(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 Pkt(l *lua.LState, pkt *mt.Pkt) lua.LValue {
+ if pkt == nil {
+ return lua.LNil
+ }
+ tbl := l.NewTable()
+ l.SetField(tbl, "_type", PktType(pkt))
+ switch val := pkt.Cmd.(type) {
+ case *mt.ToCltAcceptAuth:
+ l.SetField(tbl, "map_seed", lua.LNumber(val.MapSeed))
+ l.SetField(tbl, "player_pos", Vec3(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", AuthMethods(l, val.SudoAuthMethods))
+ case *mt.ToCltAddHUD:
+ l.SetField(tbl, "hud", HUD(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", Node(l, val.Node))
+ l.SetField(tbl, "pos", Vec3(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", Box3(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", TileAnim(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", Box1(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", Box3(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", Box1(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", Box3(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", Vec3(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", Vec3(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", Vec2(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", HUDField(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", Vec2(l, [2]lua.LNumber{lua.LNumber(val.Offset[0]), lua.LNumber(val.Offset[1])}))
+ }
+ if val.Field == mt.HUDPos {
+ l.SetField(tbl, "pos", Vec2(l, [2]lua.LNumber{lua.LNumber(val.Pos[0]), lua.LNumber(val.Pos[1])}))
+ }
+ if val.Field == mt.HUDSize {
+ l.SetField(tbl, "size", Vec2(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", Vec3(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", ChatMsgType(l, val.Type))
+ case *mt.ToCltCloudParams:
+ l.SetField(tbl, "ambient_color", Color(l, val.AmbientColor))
+ l.SetField(tbl, "density", lua.LNumber(val.Density))
+ l.SetField(tbl, "diffuse_color", Color(l, val.DiffuseColor))
+ l.SetField(tbl, "height", lua.LNumber(val.Height))
+ l.SetField(tbl, "speed", Vec2(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", CSMRestrictionFlags(l, val.Flags))
+ l.SetField(tbl, "map_range", lua.LNumber(val.MapRange))
+ case *mt.ToCltDeathScreen:
+ l.SetField(tbl, "point_at", Vec3(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", Vec3(l, [3]lua.LNumber{lua.LNumber(val.First[0]), lua.LNumber(val.First[1]), lua.LNumber(val.First[2])}))
+ l.SetField(tbl, "third", Vec3(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", AuthMethods(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", HUDFlags(l, val.Flags))
+ l.SetField(tbl, "mask", HUDFlags(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", KickReason(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", Box1(l, [2]lua.LNumber{lua.LNumber(val.Dig[0]), lua.LNumber(val.Dig[1])}))
+ l.SetField(tbl, "idle", Box1(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", Box1(l, [2]lua.LNumber{lua.LNumber(val.Walk[0]), lua.LNumber(val.Walk[1])}))
+ l.SetField(tbl, "walk_dig", Box1(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", ModChanSig(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", Vec3(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", Vec3(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", SoundSrcType(l, val.SrcType))
+ case *mt.ToCltPrivs:
+ l.SetField(tbl, "privs", StringSet(l, val.Privs))
+ case *mt.ToCltRemoveNode:
+ l.SetField(tbl, "pos", Vec3(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", HotbarParam(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", Color(l, val.BgColor))
+ l.SetField(tbl, "clouds", lua.LBool(val.Clouds))
+ if val.Type == "regular" {
+ l.SetField(tbl, "dawn_horizon", Color(l, val.DawnHorizon))
+ }
+ if val.Type == "regular" {
+ l.SetField(tbl, "dawn_sky", Color(l, val.DawnSky))
+ }
+ if val.Type == "regular" {
+ l.SetField(tbl, "day_horizon", Color(l, val.DayHorizon))
+ }
+ if val.Type == "regular" {
+ l.SetField(tbl, "day_sky", Color(l, val.DaySky))
+ }
+ l.SetField(tbl, "fog_tint_type", lua.LString(string(val.FogTintType)))
+ if val.Type == "regular" {
+ l.SetField(tbl, "indoor", Color(l, val.Indoor))
+ }
+ l.SetField(tbl, "moon_fog_tint", Color(l, val.MoonFogTint))
+ if val.Type == "regular" {
+ l.SetField(tbl, "night_horizon", Color(l, val.NightHorizon))
+ }
+ if val.Type == "regular" {
+ l.SetField(tbl, "night_sky", Color(l, val.NightSky))
+ }
+ l.SetField(tbl, "sun_fog_tint", Color(l, val.SunFogTint))
+ if val.Type == "skybox" {
+ l.SetField(tbl, "textures", TextureList(l, val.Textures))
+ }
+ l.SetField(tbl, "type", lua.LString(string(val.Type)))
+ case *mt.ToCltSpawnParticle:
+ l.SetField(tbl, "acc", Vec3(l, [3]lua.LNumber{lua.LNumber(val.Acc[0]), lua.LNumber(val.Acc[1]), lua.LNumber(val.Acc[2])}))
+ l.SetField(tbl, "anim_params", TileAnim(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", Vec3(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", Vec3(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", Color(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", StringList(l, val.Players))
+ l.SetField(tbl, "type", PlayerListUpdateType(l, val.Type))
+ }
+ return tbl
+}
--- /dev/null
+package tolua
+
+import (
+ "github.com/anon55555/mt"
+ "github.com/yuin/gopher-lua"
+ "image/color"
+)
+
+//go:generate ./generate.lua
+
+func pushVec2(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 pushVec3(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 Vec2(l *lua.LState, val [2]lua.LNumber) lua.LValue {
+ pushVec2(l, val)
+ return popValue(l)
+}
+
+func Vec3(l *lua.LState, val [3]lua.LNumber) lua.LValue {
+ pushVec3(l, val)
+ return popValue(l)
+}
+
+func Box1(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 Box2(l *lua.LState, val [2][2]lua.LNumber) lua.LValue {
+ l.Push(l.GetGlobal("box"))
+ pushVec2(l, val[0])
+ pushVec2(l, val[1])
+ l.Call(2, 1)
+ return popValue(l)
+}
+
+func Box3(l *lua.LState, val [2][3]lua.LNumber) lua.LValue {
+ l.Push(l.GetGlobal("box"))
+ pushVec3(l, val[0])
+ pushVec3(l, val[1])
+ l.Call(2, 1)
+ return popValue(l)
+}
+
+func Color(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 StringSet(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 StringList(l *lua.LState, val []string) lua.LValue {
+ return stringList[string](l, val)
+}
+
+func TextureList(l *lua.LState, val []mt.Texture) lua.LValue {
+ return stringList[mt.Texture](l, val)
+}
+++ /dev/null
-package main
-
-import (
- "github.com/Shopify/go-lua"
- "github.com/anon55555/mt"
- "image/color"
-)
-
-//go:generate ./mkconvert.lua
-
-func luaPushVec2(l *lua.State, val [2]float64) {
- l.Global("vec2")
- l.PushNumber(val[0])
- l.PushNumber(val[1])
- l.Call(2, 1)
-}
-
-func luaPushVec3(l *lua.State, val [3]float64) {
- l.Global("vec3")
- l.PushNumber(val[0])
- l.PushNumber(val[1])
- l.PushNumber(val[2])
- l.Call(3, 1)
-}
-
-func luaPushBox1(l *lua.State, val [2]float64) {
- l.Global("box")
- l.PushNumber(val[0])
- l.PushNumber(val[1])
- l.Call(2, 1)
-}
-
-func luaPushBox2(l *lua.State, val [2][2]float64) {
- l.Global("box")
- luaPushVec2(l, val[0])
- luaPushVec2(l, val[1])
- l.Call(2, 1)
-}
-
-func luaPushBox3(l *lua.State, val [2][3]float64) {
- l.Global("box")
- luaPushVec3(l, val[0])
- luaPushVec3(l, val[1])
- l.Call(2, 1)
-}
-
-func luaPushColor(l *lua.State, val color.NRGBA) {
- l.NewTable()
- l.PushInteger(int(val.R))
- l.SetField(-2, "r")
- l.PushInteger(int(val.G))
- l.SetField(-2, "g")
- l.PushInteger(int(val.B))
- l.SetField(-2, "b")
- l.PushInteger(int(val.A))
- l.SetField(-2, "a")
-}
-
-func luaPushStringSet(l *lua.State, val []string) {
- l.NewTable()
- for _, str := range val {
- l.PushBoolean(true)
- l.SetField(-2, str)
- }
-}
-
-func luaPushStringList(l *lua.State, val []string) {
- l.NewTable()
- for i, str := range val {
- l.PushString(str)
- l.RawSetInt(-2, i+1)
- }
-}
-
-// i hate go for making me do this instead of just using luaPushStringList
-// but i dont want to make an unsafe cast either
-func luaPushTextureList(l *lua.State, val []mt.Texture) {
- l.NewTable()
- for i, str := range val {
- l.PushString(string(str))
- l.RawSetInt(-2, i+1)
- }
-}