Skip to content

plugin_push & plugin_pull

存储和获取全局数据,用于在插件内部或插件之间共享数据。

函数签名

javascript
plugin_push(key: string, value: any): void
plugin_pull(key: string): any

参数说明

plugin_push

参数类型必填说明
keystring数据键名
valueany要存储的数据值

plugin_pull

参数类型必填说明
keystring数据键名

返回值

  • plugin_push:无返回值
  • plugin_pull:返回存储的数据值,如果键不存在则返回 undefined

功能描述

plugin_pushplugin_pull 提供了一个简单的全局数据存储机制。插件可以使用这两个函数存储和读取数据,实现数据持久化、状态共享等功能。

数据存储在内存中,具有以下特点:

  • 全局共享:所有插件都可以访问同一数据存储
  • 运行时持久:数据在 MSL 运行期间一直存在
  • 重启清除:MSL 重启后数据会丢失(如需持久化,请使用文件或数据库)

使用示例

基本用法

javascript
// 存储数据
plugin_push("myKey", "Hello World");

// 读取数据
const value = plugin_pull("myKey");
plugin_log("INFO", `读取到的值: ${value}`);  // 输出: Hello World

存储对象

javascript
// 存储配置对象
plugin_push("config", {
    serverName: "My Server",
    maxPlayers: 20,
    features: {
        pvp: true,
        economy: true
    }
});

// 读取配置
const config = plugin_pull("config");
plugin_log("INFO", `服务器名称: ${config.serverName}`);

存储数组

javascript
// 存储玩家列表
plugin_push("onlinePlayers", ["Steve", "Alex", "Notch"]);

// 读取并操作
const players = plugin_pull("onlinePlayers") || [];
players.push("NewPlayer");
plugin_push("onlinePlayers", players);

玩家数据管理

javascript
// 记录玩家加入次数
plugin_onEvent("playerJoin", (time, player) => {
    const joinCount = plugin_pull("joinCount") || {};
    joinCount[player] = (joinCount[player] || 0) + 1;
    plugin_push("joinCount", joinCount);
    
    plugin_log("INFO", `${player} 第 ${joinCount[player]} 次加入`);
});

// 查询玩家加入次数
plugin_registerCommand("!joins", (player) => {
    const joinCount = plugin_pull("joinCount") || {};
    const count = joinCount[player] || 0;
    plugin_executeCommand(`tellraw ${player} {"text":"你已加入 ${count} 次","color":"yellow"}`);
});

经济系统

javascript
// 初始化玩家账户
plugin_onEvent("playerJoin", (time, player) => {
    const economy = plugin_pull("economy") || {};
    if (!economy[player]) {
        economy[player] = {
            balance: 1000,
            createdAt: new Date().toISOString()
        };
        plugin_push("economy", economy);
        plugin_log("INFO", `为 ${player} 创建账户`);
    }
});

// 查询余额
function getBalance(player) {
    const economy = plugin_pull("economy") || {};
    return economy[player]?.balance || 0;
}

// 修改余额
function setBalance(player, amount) {
    const economy = plugin_pull("economy") || {};
    if (economy[player]) {
        economy[player].balance = amount;
        plugin_push("economy", economy);
        return true;
    }
    return false;
}

// 转账
function transfer(from, to, amount) {
    const economy = plugin_pull("economy") || {};
    
    if (!economy[from] || !economy[to]) return false;
    if (economy[from].balance < amount) return false;
    
    economy[from].balance -= amount;
    economy[to].balance += amount;
    plugin_push("economy", economy);
    return true;
}

// 注册余额查询指令
plugin_registerCommand("!balance", (player) => {
    const balance = getBalance(player);
    plugin_executeCommand(`tellraw ${player} {"text":"你的余额: ${balance} 金币","color":"gold"}`);
});

聊天记录

javascript
// 记录聊天消息
plugin_onEvent("playerSendMessage", (time, player, message) => {
    const chatLog = plugin_pull("chatLog") || [];
    chatLog.push({
        time: time,
        player: player,
        message: message,
        timestamp: Date.now()
    });
    
    // 只保留最近 100 条
    if (chatLog.length > 100) {
        chatLog.shift();
    }
    
    plugin_push("chatLog", chatLog);
});

// 查询聊天记录
plugin_registerCommand("!history", (player) => {
    const chatLog = plugin_pull("chatLog") || [];
    const recent = chatLog.slice(-5);
    
    recent.forEach(log => {
        plugin_executeCommand(`tellraw ${player} {"text":"[${log.time}] ${log.player}: ${log.message}","color":"gray"}`);
    });
});

统计数据

javascript
// 统计服务器数据
const stats = {
    playerJoins: 0,
    playerQuits: 0,
    messages: 0,
    commands: 0
};

plugin_onEvent("playerJoin", () => {
    const s = plugin_pull("stats") || { ...stats };
    s.playerJoins++;
    plugin_push("stats", s);
});

plugin_onEvent("playerQuit", () => {
    const s = plugin_pull("stats") || { ...stats };
    s.playerQuits++;
    plugin_push("stats", s);
});

plugin_onEvent("playerSendMessage", () => {
    const s = plugin_pull("stats") || { ...stats };
    s.messages++;
    plugin_push("stats", s);
});

plugin_onEvent("playerSendCommand", () => {
    const s = plugin_pull("stats") || { ...stats };
    s.commands++;
    plugin_push("stats", s);
});

// 查询统计
plugin_registerCommand("!stats", (player) => {
    const s = plugin_pull("stats") || stats;
    plugin_executeCommand(`tellraw ${player} {"text":"服务器统计:","color":"gold"}`);
    plugin_executeCommand(`tellraw ${player} {"text":"加入: ${s.playerJoins} | 退出: ${s.playerQuits}","color":"white"}`);
    plugin_executeCommand(`tellraw ${player} {"text":"消息: ${s.messages} | 指令: ${s.commands}","color":"white"}`);
});

插件间数据共享

javascript
// 插件 A 存储数据
plugin_push("myPlugin:config", {
    enabled: true,
    version: "1.0.0"
});

// 插件 B 读取数据
const config = plugin_pull("myPlugin:config");
if (config && config.enabled) {
    plugin_log("INFO", "检测到 myPlugin 已启用");
}

数据键命名规范

建议使用以下命名规范以避免键名冲突:

javascript
// 推荐:使用插件名作为前缀
plugin_push("myPlugin:config", configData);
plugin_push("myPlugin:playerData", playerData);
plugin_push("myPlugin:cache", cacheData);

// 不推荐:通用名称可能冲突
plugin_push("config", configData);  // 可能与其他插件冲突

注意事项

  1. 内存存储:数据存储在内存中,MSL 重启后会丢失
  2. 键名冲突:不同插件使用相同的键名会覆盖数据
  3. 数据大小:避免存储过大的数据,以免占用过多内存
  4. 异步安全:数据操作是同步的,不存在竞态条件

持久化方案

如果需要数据持久化,可以结合文件系统:

javascript
const fs = plugin_require("fs");
const path = plugin_require("path");

// 保存数据到文件
function saveData() {
    const data = {
        economy: plugin_pull("economy"),
        stats: plugin_pull("stats")
    };
    fs.writeFileSync(
        path.join(__dirname, "..", "..", "data", "plugin-data.json"),
        JSON.stringify(data, null, 2)
    );
}

// 加载数据
function loadData() {
    try {
        const filePath = path.join(__dirname, "..", "..", "data", "plugin-data.json");
        if (fs.existsSync(filePath)) {
            const data = JSON.parse(fs.readFileSync(filePath, "utf-8"));
            if (data.economy) plugin_push("economy", data.economy);
            if (data.stats) plugin_push("stats", data.stats);
        }
    } catch (e) {
        plugin_log("ERROR", `加载数据失败: ${e.message}`);
    }
}

// 定期保存
setInterval(saveData, 60000);  // 每分钟保存一次

相关 API

相关指南