LINLANG · JLING

琳琅让开发,
专注于创造。

把重复的代码交给琳琅吧!文件、命令路由、消息投递、容器界面与审计,这些共同构成服务于业务插件的琳琅。

开发者文档
版本动态

持续完善,持续创造。

查看琳琅的近期改进、问题修复与升级说明。

查看完整更新日志
把时间留给业务

为什么选择琳琅?

您不必在每个插件里,都重新编写一套相似的基础代码。使用琳琅,让繁琐沉淀,让自己的想法继续向前。

了解运行时设计
  1. 少写重复的基础代码

    文件、命令路由、消息投递与界面管理都有现成入口,把开发精力留给插件自身的玩法与逻辑。

  2. 共享实现,又划清界限

    同一个运行时为每个插件提供独立的服务门面,配置目录、语言设置和审计上下文按插件管理。

  3. 从启用到关闭,有始有终

    通过统一入口初始化服务,明确资源归属,并在插件停用时集中释放,让生命周期更容易梳理。

  4. 表达与逻辑,各司其职

    语言文件承载文本,界面资源描述布局,Java 代码处理数据与交互。修改表达时,不必把所有逻辑混在一起。

围绕插件开发的日常

常用能力,一处组织。

从配置文件到玩家看到的消息,让通用服务有清晰的入口,也有明确的生命周期。

01 / LINFILE

让文件成为代码的一部分。

统一组织配置与语言文件,通过结构映射连接文件内容和代码中的对象,使代码先行,文件即刻出现。

  • 配置映射
  • 语言文件
  • 文件重载
了解文件服务
声明一个配置文件JAVA
@ConfigFile(name = "config")
public class MainConfig {
    public String language = "zh_CN";
    public Database database = new Database();

    public static class Database {
        public String host = "127.0.0.1";
        public int port = 3306;
    }
}

类声明字段、层级与默认值。

生成的配置文件YAML
language: zh_CN
database:
  host: 127.0.0.1
  port: 3306

文件中的嵌套结构与对象字段一一对应。

02 / LINCOMMAND

把命令交给服务。

围绕命令描述、参数类型和命令组组织入口,将命令注册与路由集中管理,把处理函数留给实际业务。琳琅还提供补全与帮助。

  • 命令注册
  • 参数解析
  • 命令组
了解命令服务
注册重载命令。JAVA
LinCommand commands = lin.linCommand();

commands.register(
    "rs reload",
    ctx -> reloadPlugin(),
    LinCommand.Permission.perms("rainbowedit.reload"),
    LinCommand.ExecTarget.ALL,
    LinCommand.I18n.create()
        .desc(lang.command.reload.description)
);

调用片段:reloadPlugin 与 lang 由业务插件提供。

命令帮助效果
命令注册后的帮助消息
03 / MESSENGER

从文本来源,到消息送达。

将文本解析、命名变量、前缀和语言引用串联起来,再转换为 Bukkit 文本组件并投递,让消息表达和传输各司其职。

  • 命名变量
  • 多语言
  • 消息前缀
了解消息服务
为消息绑定命名变量JAVA
LinMessenger messenger = lin.linMessenger();

messenger.send(
    player,
    lang.command.preview.cancel,
    "player", player.getName(),
    "item", itemName
);

调用片段:接收者、语言字段和物品名称由业务插件提供。

消息投递效果
消息投递效果
04 / LINVIEW

让容器界面有章可循。

用静态区、动态区和占位符组织界面内容,让界面布局与交互行为有各自的位置,并按插件管理相应资源。

  • 静态与动态区域
  • 占位符
  • 界面变体
了解界面服务
注册交互并打开界面JAVA
LinView view = lin.linView();

view.hook("领地 {name} 权限管理面板", ctx -> {
    Player player = (Player) ctx.viewer();
    player.sendMessage("§aHello!");
});

GuiSession session = view.open(player, "demo.hello");

配合文档中的 demo.hello.yml 使用;布局留在资源文件,交互留在代码。

容器界面效果
容器界面效果
05 / LINAUDIT

让运行中的问题有迹可循。

通过统一审计入口记录运行信息与异常,结合异常代码定位问题,并以租户方式区分不同插件的审计上下文。

  • 统一记录
  • 异常代码
  • 插件上下文
了解审计服务
记录运行信息JAVA
LinLogger logger = lin.linAudit().logger();

logger.info("Loaded {} entries", count);
logger.warn(
    "Failed to load {file}",
    exception,
    "file", file
);

调用片段:传入实际的数量、异常与文件上下文。

保留操作上下文JAVA
lin.linAudit().record(
    "config.reload",
    "actor", sender.getName(),
    "file", "config.yml"
);

以稳定事件名称,记录谁对哪个文件执行了操作。

琳琅

从一个插件开始。

开发时引入 API,服务器安装 Runtime,随后琳琅就绪。

  1. 01

    准备运行环境

    确认开发环境与平台要求,在服务器安装与 API 兼容的琳琅运行时。

    运行时说明
  2. 02

    引入开发接口

    将 linlang-api 设为编译期依赖,并在 plugin.yml 中声明运行时前置。

    依赖引入
  3. 03

    初始化与释放

    在插件启用时创建并保存 Linlang 实例,在停用时关闭,管理完整生命周期。

    初始化指南