Files
wehub-resource-sync ead81af521
CI / go (push) Waiting to run
CI / build (darwin, macos-14) (push) Waiting to run
CI / build (windows, windows-2025) (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Failing after 0s
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

127 lines
3.0 KiB
Go

package luaplugin
import lua "github.com/yuin/gopher-lua"
// registerControlAPI adds cliamp.player control methods (next, prev, play_pause,
// stop, set_volume, set_speed, seek, toggle_mono, set_eq_band) to the cliamp table.
// These are only functional if the plugin declared permissions = {"control"}.
func registerControlAPI(L *lua.LState, cliamp *lua.LTable, ctrl *ControlProvider, p *Plugin, logger *pluginLogger) {
playerTbl := L.GetField(cliamp, "player")
tbl, ok := playerTbl.(*lua.LTable)
if !ok {
return
}
warned := false
guard := func(name string) bool {
if !p.perms[PermControl] {
if !warned {
logger.log(p.Name, "warn", "%s requires permissions = {\"control\"} — further warnings suppressed", name)
warned = true
}
return false
}
return true
}
L.SetField(tbl, "next", L.NewFunction(func(L *lua.LState) int {
if guard("next") {
ctrl.Next()
}
return 0
}))
L.SetField(tbl, "prev", L.NewFunction(func(L *lua.LState) int {
if guard("prev") {
ctrl.Prev()
}
return 0
}))
L.SetField(tbl, "play_pause", L.NewFunction(func(L *lua.LState) int {
if guard("play_pause") {
ctrl.TogglePause()
}
return 0
}))
L.SetField(tbl, "stop", L.NewFunction(func(L *lua.LState) int {
if guard("stop") {
ctrl.Stop()
}
return 0
}))
L.SetField(tbl, "set_volume", L.NewFunction(func(L *lua.LState) int {
if !guard("set_volume") {
return 0
}
db := float64(L.CheckNumber(1))
ctrl.SetVolume(max(min(db, 6), -30))
return 0
}))
L.SetField(tbl, "set_speed", L.NewFunction(func(L *lua.LState) int {
if !guard("set_speed") {
return 0
}
ratio := float64(L.CheckNumber(1))
ctrl.SetSpeed(max(min(ratio, 2.0), 0.25))
return 0
}))
L.SetField(tbl, "seek", L.NewFunction(func(L *lua.LState) int {
if !guard("seek") {
return 0
}
ctrl.Seek(float64(L.CheckNumber(1)))
return 0
}))
L.SetField(tbl, "toggle_mono", L.NewFunction(func(L *lua.LState) int {
if guard("toggle_mono") {
ctrl.ToggleMono()
}
return 0
}))
// set_eq_preset("name") or set_eq_preset("name", {band1, band2, ..., band10})
L.SetField(tbl, "set_eq_preset", L.NewFunction(func(L *lua.LState) int {
if !guard("set_eq_preset") {
return 0
}
name := L.CheckString(1)
var bands *[10]float64
if tbl := L.OptTable(2, nil); tbl != nil {
b := [10]float64{}
for i := range 10 {
v := tbl.RawGetInt(i + 1)
if v == lua.LNil {
// A partial table would silently zero the unset bands;
// require all 10 so the caller's intent is explicit.
L.ArgError(2, "eq bands table must contain all 10 values")
return 0
}
b[i] = max(min(float64(lua.LVAsNumber(v)), 12), -12)
}
bands = &b
}
ctrl.SetEQPreset(name, bands)
return 0
}))
L.SetField(tbl, "set_eq_band", L.NewFunction(func(L *lua.LState) int {
if !guard("set_eq_band") {
return 0
}
band := L.CheckInt(1) - 1 // Lua 1-indexed → Go 0-indexed
if band < 0 || band > 9 {
L.ArgError(1, "band must be 1-10")
return 0
}
db := float64(L.CheckNumber(2))
ctrl.SetEQBand(band, max(min(db, 12), -12))
return 0
}))
}