plugin_push & plugin_pull
存储和获取全局数据,用于在插件内部或插件之间共享数据。
函数签名
javascript
plugin_push(key: string, value: any): void
plugin_pull(key: string): any参数说明
plugin_push
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
key | string | 是 | 数据键名 |
value | any | 是 | 要存储的数据值 |
plugin_pull
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
key | string | 是 | 数据键名 |
返回值
- plugin_push:无返回值
- plugin_pull:返回存储的数据值,如果键不存在则返回
undefined
功能描述
plugin_push 和 plugin_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); // 可能与其他插件冲突注意事项
- 内存存储:数据存储在内存中,MSL 重启后会丢失
- 键名冲突:不同插件使用相同的键名会覆盖数据
- 数据大小:避免存储过大的数据,以免占用过多内存
- 异步安全:数据操作是同步的,不存在竞态条件
持久化方案
如果需要数据持久化,可以结合文件系统:
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
- plugin_require - 引入 Node.js 模块(用于文件操作)
- plugin_generateOfflineUUID - 生成玩家 UUID
相关指南
- Node.js 开发 - 使用文件系统持久化数据