PyNK v2.0 - Python para Nukkit via Jython
Plugin para Nukkit que permite criar plugins/scripts em Python usando Jython,
com suporte completo a eventos, comandos, scheduler, módulos, permissões
e configuração em múltiplos formatos.
Novidades na v2.0
Múltiplas Pastas de Scripts
Os scripts agora podem ser organizados em subpastas:
plugins/PyNK/scripts/
example_plugin.py
examples/
subfolder_example.py
module_consumer.py
O scanner recursivo carrega automaticamente todos os arquivos .py.
A pasta modules/ é reservada e ignorada pelo scanner.
Comandos:
- /pynk load examples/subfolder_example - carrega script em subpasta
- /pynk scan - lista todos os scripts encontrados com status
Sistema de Permissões
Cada script pode declarar permissões via metadados:
SCRIPT_PERMISSIONS = [
"meuplugin.use",
"meuplugin.admin",
"meuplugin.action"
]
As permissões são registradas automaticamente. Uso no script:
def meu_comando(sender, label, args):
if not api.check_permission(sender, "meuplugin.admin"):
return True
# ...
Comandos:
- /pynk perms - lista todas as permissões
- /pynk perms <script> - permissões de um script específico
Sistema de Módulos
Módulos são scripts Python reutilizáveis localizados em scripts/modules/.
plugins/PyNK/scripts/
modules/
utils.py
core/
database.py
meu_plugin.py
Uso:
utils = api.require_module("utils")
result = utils.format_player_name("steve")
# Subpasta:
db = api.require_module("core.database")
Dependências automáticas:
SCRIPT_DEPENDENCIES = ["utils", "core.database"]
Comandos:
- /pynk modules - lista módulos carregados e disponíveis
Comandos Dinâmicos com Subcomandos
api.register_command("guild", "Sistema de guildas", "/guild <sub>", None, "guild.use", cmd_guild)
api.add_sub_command("guild", "create", "Criar guilda", cmd_create, "guild.create")
api.add_sub_command("guild", "info", "Informações da guilda", cmd_info, "guild.use")
api.add_sub_command("guild", "delete", "Deletar guilda", cmd_delete, "guild.admin")
# Tab-complete customizado:
api.set_tab_completer("guild", tab_guild)
Exportação/Importação entre Scripts
# No script A:
api.export("minha_funcao", minha_funcao)
# No script B:
func = api.import_from("script_a", "minha_funcao")
func()
Configuração JSON/YAML/Properties
JSON (recomendado):
api.load_config("settings", "json", {
"database": {
"host": "localhost",
"port": 3306
},
"max_players": 100
})
api.get_config_string("settings", "database.host") # "localhost"
api.get_config_int("settings", "database.port") # 3306
api.get_config_bool("settings", "features.pvp", True) # True
api.get_config_list("settings", "blocked_items") # [...]
api.set_config_value("settings", "max_players", 200)
api.save_config_file("settings")
api.reload_config("settings")
YAML e Properties também são suportados:
api.load_config("messages", "yaml", {...})
api.load_config("server", "properties", {...})
Config legado (compatibilidade com v1.0):
api.get_config("chave", "default")
api.set_config("chave", valor)
api.save_config()
API Completa
Mensagens & Players
- api.broadcast(message) - envia mensagem para todos
- api.broadcast(message, permission) - mensagem filtrada por permissão
- api.get_player(name) / api.get_player_exact(name)
- api.get_online_players() - lista de jogadores online
- api.send_message(sender, message)
- api.colorize(message) - converte & em cores
- api.dispatch_command(cmd) - executa comando como console
Eventos
- api.register_event("PlayerJoinEvent", callback)
- api.unregister_event("PlayerJoinEvent", callback)
- api.list_events() - lista todos os eventos indexados
- api.count_event_handlers("EventName")
Comandos
- api.register_command(name, desc, usage, aliases, perm, callback)
- api.add_sub_command(parent, name, desc, callback, perm)
- api.set_tab_completer(name, completer)
Scheduler
- api.schedule_task(callback, delay_ticks)
- api.schedule_repeating_task(callback, period_ticks)
- api.cancel_task(task_id)
Config
- api.load_config(name, format, defaults) - carrega config
- api.get_config_value(name, key) / get_config_string/int/double/bool/list/section
- api.set_config_value(name, key, value)
- api.remove_config_key(name, key)
- api.config_contains(name, key)
- api.save_config_file(name) / api.reload_config(name)
- api.save_all_configs() / api.list_configs()
Permissões
- api.has_permission(sender, perm) - verifica
- api.check_permission(sender, perm) - verifica e notifica
- api.register_permission(perm, default, desc)
- api.get_script_permissions()
Módulos
- api.require_module(name) - carrega módulo
- api.reload_module(name) - recarrega módulo
- api.is_module_loaded(name) - verifica se está carregado
- api.list_available_modules() / api.list_loaded_modules()
Exportação/Importação
- api.export(name, value) - exporta função/variável
- api.import_from(script_name, name) - importa de outro script
Comandos do /pynk
| Comando | Descrição | Permissão |
|---|
| /pynk list | Lista scripts carregados | pynk.script.list |
| /pynk load <path> | Carrega script (suporta subpastas) | pynk.script.load |
| /pynk unload <name> | Descarrega um script | pynk.script.unload |
| /pynk reload <name> | Recarrega um script | pynk.script.reload |
| /pynk reloadall | Recarrega todos os scripts | pynk.script.reload |
| /pynk events [filter] | Lista eventos indexados | (nenhuma) |
| /pynk info <name> | Informações detalhadas | pynk.script.info |
| /pynk modules | Lista módulos | (nenhuma) |
| /pynk perms [script] | Lista permissões | (nenhuma) |
| /pynk scan | Escaneia pastas e mostra status | pynk.admin |
Metadados de Scripts
PLUGIN_NAME = "MeuPlugin"
PLUGIN_VERSION = "1.0.0"
PLUGIN_AUTHOR = "Autor"
PLUGIN_DESCRIPTION = "Descrição"
SCRIPT_PERMISSIONS = ["meuplugin.use", "meuplugin.admin"]
SCRIPT_DEPENDENCIES = ["utils"]
Variáveis Globais Injetadas
| Variável | Tipo | Descrição |
|---|
| api | PyAPI | API de conveniência |
| server | Server | Instância do servidor Nukkit |
| plugin | PyNKPlugin | Instância do plugin PyNK |
| logger | Logger | Logger do plugin |
| SCRIPT_NAME | str | Nome do script |
| SCRIPT_FILE | str | Caminho absoluto do arquivo .py |
| SCRIPT_FOLDER | str | Subpasta relativa (vazio se raiz) |
| DATA_FOLDER | str | Pasta de dados do script |
| MODULE_NAME | str | Nome do módulo (apenas módulos) |
| MODULE_PATH | str | Caminho do módulo (apenas módulos) |
Build
mvn clean package
O arquivo final .jar com Jython embutido será gerado em target/PyNK.jar.
Licença
MIT
PyNK v2.0 - Python for Nukkit via Jython
A plugin for Nukkit that allows creating plugins/scripts in Python using Jython,
with full support for events, commands, scheduler, modules, permissions,
and multi-format configuration.
What's New in v2.0
Multiple Script Folders
Scripts can now be organized into subfolders:
plugins/PyNK/scripts/
example_plugin.py
examples/
subfolder_example.py
module_consumer.py
The recursive scanner automatically loads all .py files.
The modules/ folder is reserved and ignored by the scanner.
Commands:
- /pynk load examples/subfolder_example - loads a script from a subfolder
- /pynk scan - lists all detected scripts with status
Permission System
Each script can declare permissions via metadata:
SCRIPT_PERMISSIONS = [
"myplugin.use",
"myplugin.admin",
"myplugin.action"
]
Permissions are registered automatically. Usage in script:
def my_command(sender, label, args):
if not api.check_permission(sender, "myplugin.admin"):
return True
# ...
Commands:
- /pynk perms - lists all permissions
- /pynk perms <script> - permissions of a specific script
Module System
Modules are reusable Python scripts located in scripts/modules/.
plugins/PyNK/scripts/
modules/
utils.py
core/
database.py
my_plugin.py
Usage:
utils = api.require_module("utils")
result = utils.format_player_name("steve")
# Subfolder:
db = api.require_module("core.database")
Automatic dependencies:
SCRIPT_DEPENDENCIES = ["utils", "core.database"]
Commands:
- /pynk modules - lists loaded and available modules
Dynamic Commands with Subcommands
api.register_command("guild", "Guild system", "/guild <sub>", None, "guild.use", cmd_guild)
api.add_sub_command("guild", "create", "Create guild", cmd_create, "guild.create")
api.add_sub_command("guild", "info", "Guild info", cmd_info, "guild.use")
api.add_sub_command("guild", "delete", "Delete guild", cmd_delete, "guild.admin")
# Custom tab-complete:
api.set_tab_completer("guild", tab_guild)
Export/Import Between Scripts
# In script A:
api.export("my_function", my_function)
# In script B:
func = api.import_from("script_a", "my_function")
func()
Config JSON/YAML/Properties
JSON (recommended):
api.load_config("settings", "json", {
"database": {
"host": "localhost",
"port": 3306
},
"max_players": 100
})
api.get_config_string("settings", "database.host") # "localhost"
api.get_config_int("settings", "database.port") # 3306
api.get_config_bool("settings", "features.pvp", True) # True
api.get_config_list("settings", "blocked_items") # [...]
api.set_config_value("settings", "max_players", 200)
api.save_config_file("settings")
api.reload_config("settings")
YAML and Properties are also supported:
api.load_config("messages", "yaml", {...})
api.load_config("server", "properties", {...})
Legacy config (v1.0 compatibility):
api.get_config("key", "default")
api.set_config("key", value)
api.save_config()
Full API
Messages & Players
- api.broadcast(message) - message to all
- api.broadcast(message, permission) - permission-filtered message
- api.get_player(name) / api.get_player_exact(name)
- api.get_online_players() - list of Player
- api.send_message(sender, message)
- api.colorize(message) - converts & to colors
- api.dispatch_command(cmd) - executes command as console
Events
- api.register_event("PlayerJoinEvent", callback)
- api.unregister_event("PlayerJoinEvent", callback)
- api.list_events() - lists all indexed events
- api.count_event_handlers("EventName")
Commands
- api.register_command(name, desc, usage, aliases, perm, callback)
- api.add_sub_command(parent, name, desc, callback, perm)
- api.set_tab_completer(name, completer)
Scheduler
- api.schedule_task(callback, delay_ticks)
- api.schedule_repeating_task(callback, period_ticks)
- api.cancel_task(task_id)
Config
- api.load_config(name, format, defaults) - loads config
- api.get_config_value(name, key) / get_config_string/int/double/bool/list/section
- api.set_config_value(name, key, value)
- api.remove_config_key(name, key)
- api.config_contains(name, key)
- api.save_config_file(name) / api.reload_config(name)
- api.save_all_configs() / api.list_configs()
Permissions
- api.has_permission(sender, perm) - checks
- api.check_permission(sender, perm) - checks and notifies
- api.register_permission(perm, default, desc)
- api.get_script_permissions()
Modules
- api.require_module(name) - loads module
- api.reload_module(name) - reloads module
- api.is_module_loaded(name) - checks if loaded
- api.list_available_modules() / api.list_loaded_modules()
Export/Import
- api.export(name, value) - exports function/variable
- api.import_from(script_name, name) - imports from another script
/pynk Commands
| Command | Description | Permission |
|---|
| /pynk list | Lists loaded scripts | pynk.script.list |
| /pynk load <path> | Loads script (supports subfolder) | pynk.script.load |
| /pynk unload <name> | Unloads a script | pynk.script.unload |
| /pynk reload <name> | Reloads a script | pynk.script.reload |
| /pynk reloadall | Reloads all scripts | pynk.script.reload |
| /pynk events [filter] | Lists indexed events | (none) |
| /pynk info <name> | Detailed script info | pynk.script.info |
| /pynk modules | Lists modules | (none) |
| /pynk perms [script] | Lists permissions | (none) |
| /pynk scan | Scans folders and lists status | pynk.admin |
Script Metadata
PLUGIN_NAME = "MyPlugin"
PLUGIN_VERSION = "1.0.0"
PLUGIN_AUTHOR = "Author"
PLUGIN_DESCRIPTION = "Description"
SCRIPT_PERMISSIONS = ["myplugin.use", "myplugin.admin"]
SCRIPT_DEPENDENCIES = ["utils"]
Injected Global Variables
| Variable | Type | Description |
|---|
| api | PyAPI | Convenience API |
| server | Server | Nukkit server instance |
| plugin | PyNKPlugin | PyNK plugin instance |
| logger | Logger | Plugin logger |
| SCRIPT_NAME | str | Script name |
| SCRIPT_FILE | str | Absolute path of the .py file |
| SCRIPT_FOLDER | str | Relative subfolder (empty if root) |
| DATA_FOLDER | str | Script data folder |
| MODULE_NAME | str | Module name (modules only) |
| MODULE_PATH | str | Module path (modules only) |
Build
mvn clean package
The final jar with embedded Jython will be generated at target/PyNK.jar.
License
MIT