Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F627026
loader.lua
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None
loader.lua
View Options
--[[
mattata v2.0 - Plugin Loader
Discovers, validates, and manages plugins from category directories.
Supports hot-reload and per-chat enable/disable.
]]
local
loader
=
{}
local
logger
=
require
(
'src.core.logger'
)
local
config
=
require
(
'src.core.config'
)
local
plugins
=
{}
-- ordered list of all loaded plugins
local
by_command
=
{}
-- command -> plugin lookup
local
by_name
=
{}
-- name -> plugin lookup
local
categories
=
{}
-- category -> list of plugin names
local
api
,
db
,
redis
local
PERMANENT_PLUGINS
=
{
'help'
,
'about'
,
'plugins'
}
local
CATEGORIES
=
{
'admin'
,
'utility'
,
'fun'
,
'media'
,
'ai'
}
function
loader
.
init
(
api_ref
,
db_ref
,
redis_ref
)
api
=
api_ref
db
=
db_ref
redis
=
redis_ref
plugins
=
{}
by_command
=
{}
by_name
=
{}
categories
=
{}
for
_
,
category
in
ipairs
(
CATEGORIES
)
do
categories
[
category
]
=
{}
local
manifest_path
=
'src.plugins.'
..
category
..
'.init'
local
ok
,
manifest
=
pcall
(
require
,
manifest_path
)
if
ok
and
type
(
manifest
)
==
'table'
and
manifest
.
plugins
then
for
_
,
plugin_name
in
ipairs
(
manifest
.
plugins
)
do
local
plugin_path
=
'src.plugins.'
..
category
..
'.'
..
plugin_name
local
load_ok
,
plugin
=
pcall
(
require
,
plugin_path
)
if
load_ok
and
type
(
plugin
)
==
'table'
then
plugin
.
name
=
plugin
.
name
or
plugin_name
plugin
.
category
=
plugin
.
category
or
category
plugin
.
commands
=
plugin
.
commands
or
{}
plugin
.
help
=
plugin
.
help
or
''
plugin
.
description
=
plugin
.
description
or
''
table.insert
(
plugins
,
plugin
)
by_name
[
plugin
.
name
]
=
plugin
table.insert
(
categories
[
category
],
plugin
.
name
)
-- Index commands for fast lookup
for
_
,
cmd
in
ipairs
(
plugin
.
commands
)
do
by_command
[
cmd
:
lower
()]
=
plugin
end
logger
.
debug
(
'Loaded plugin: %s/%s (%d commands)'
,
category
,
plugin
.
name
,
#
plugin
.
commands
)
else
logger
.
warn
(
'Failed to load plugin %s/%s: %s'
,
category
,
plugin_name
,
tostring
(
plugin
))
end
end
else
logger
.
debug
(
'No manifest for category: %s (%s)'
,
category
,
tostring
(
manifest
))
end
end
logger
.
info
(
'Loaded %d plugins across %d categories'
,
#
plugins
,
#
CATEGORIES
)
end
-- Get all loaded plugins (ordered)
function
loader
.
get_plugins
()
return
plugins
end
-- Look up a plugin by command name
function
loader
.
get_by_command
(
command
)
return
by_command
[
command
:
lower
()]
end
-- Look up a plugin by name
function
loader
.
get_by_name
(
name
)
return
by_name
[
name
]
end
-- Get all plugins in a category
function
loader
.
get_category
(
category
)
local
result
=
{}
for
_
,
name
in
ipairs
(
categories
[
category
]
or
{})
do
table.insert
(
result
,
by_name
[
name
])
end
return
result
end
-- Count loaded plugins
function
loader
.
count
()
return
#
plugins
end
-- Check if a plugin is permanent (cannot be disabled)
function
loader
.
is_permanent
(
name
)
for
_
,
pname
in
ipairs
(
PERMANENT_PLUGINS
)
do
if
pname
==
name
then
return
true
end
end
return
false
end
-- Hot-reload a plugin by name
function
loader
.
reload
(
name
)
local
plugin
=
by_name
[
name
]
if
not
plugin
then
return
false
,
'Plugin not found: '
..
name
end
local
path
=
'src.plugins.'
..
plugin
.
category
..
'.'
..
name
package.loaded
[
path
]
=
nil
local
ok
,
new_plugin
=
pcall
(
require
,
path
)
if
not
ok
then
return
false
,
'Reload failed: '
..
tostring
(
new_plugin
)
end
-- Preserve metadata
new_plugin
.
name
=
name
new_plugin
.
category
=
plugin
.
category
new_plugin
.
commands
=
new_plugin
.
commands
or
{}
-- Replace in ordered list
for
i
,
p
in
ipairs
(
plugins
)
do
if
p
.
name
==
name
then
plugins
[
i
]
=
new_plugin
break
end
end
-- Re-index commands (remove old, add new)
for
cmd
,
p
in
pairs
(
by_command
)
do
if
p
.
name
==
name
then
by_command
[
cmd
]
=
nil
end
end
for
_
,
cmd
in
ipairs
(
new_plugin
.
commands
)
do
by_command
[
cmd
:
lower
()]
=
new_plugin
end
by_name
[
name
]
=
new_plugin
logger
.
info
(
'Hot-reloaded plugin: %s'
,
name
)
return
true
end
-- Get help text for all plugins or a specific category
function
loader
.
get_help
(
category
,
chat_id
)
local
help
=
{}
local
source
=
category
and
loader
.
get_category
(
category
)
or
plugins
for
_
,
plugin
in
ipairs
(
source
)
do
if
plugin
.
help
and
plugin
.
help
~=
''
then
table.insert
(
help
,
{
name
=
plugin
.
name
,
category
=
plugin
.
category
,
commands
=
plugin
.
commands
,
help
=
plugin
.
help
,
description
=
plugin
.
description
})
end
end
return
help
end
-- Get list of categories
function
loader
.
get_categories
()
return
CATEGORIES
end
return
loader
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 15, 1:29 AM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
136116
Default Alt Text
loader.lua (5 KB)
Attached To
Mode
R69 mattata
Attached
Detach File
Event Timeline