
自定义玩家数据
对Minecraft服务器有用的模组或模组开发者的框架。
自定义玩家数据
Fabric 框架 1.20.6,用于管理持久化且同步的玩家数据。
此模组允许你定义附加到每个玩家的自定义变量,这些变量保存在 Minecraft 原生的 player.dat 文件中,并在服务器与客户端之间自动同步。
功能
- JSON Schema:在自动生成于地图文件夹中的
player_data_schema.json文件里定义你的变量。 - 原生持久化:数据通过 Mixin 直接存储在
player.dat中——零数据丢失,即使崩溃后也不会丢失。 - 自动同步:所有变量在连接时以及每次变更时发送到客户端(非常适合 HUD)。
- 开发者 API:可被其他模组作为依赖项使用,以编程方式注入和操作变量。
- 自定义类型:创建你自己的复杂数据类型(例如
Power、Skill、Quest……)。 - 管理员命令:
/playerdata get和/playerdata set,供管理员使用。 - 校验:
int的最小/最大值、空值检查、运行时类型验证。
面向服务器管理员
安装
- 将
.jar文件放入你的 Fabric 1.20.6 服务器的mods/文件夹中。 - 首次启动服务器——
player_data_schema.json文件将在你的世界文件夹中生成(与level.dat相邻)。 - 根据需要修改 JSON,然后重启。
JSON Schema 格式
{
"note": {
"type": "int",
"defaultValue": 0,
"maxValue": 5,
"minValue": 0,
"null": false
},
"hudColor": {
"type": "string",
"defaultValue": "light_blue",
"null": false
},
"powers": {
"type": "Power",
"array": true,
"defaultValue": null,
"null": true
}
}
| 参数 | 描述 | 必需 |
|---|---|---|
type |
int、string、boolean 或已注册的自定义类型 |
是 |
defaultValue |
新玩家的默认值 | 否 |
maxValue |
最大值(仅 int 类型) |
否 |
minValue |
最小值(仅 int 类型) |
否 |
null |
允许 null(默认为 false) |
否 |
array |
该变量为数组(默认为 false) |
否 |
重要:如果某个变量设置为
"null": false且没有defaultValue,启动时将记录错误。
命令
| 命令 | 描述 | 权限 |
|---|---|---|
/playerdata get <variable> <joueur> |
显示当前值 | OP 等级 2+ |
/playerdata set <variable> <joueur> <valeur> |
修改值(仅限原始类型) | OP 等级 2+ |
示例:
/playerdata get note Steve
/playerdata set hudColor Steve red
/playerdata set note Steve 3
开发者指南——将自定义玩家数据用作 API
1. 添加依赖项
在你的 build.gradle 文件中,将该 JAR 添加为本地依赖项(或者如果已发布,则通过 Maven 仓库):
dependencies {
// 添加这一项
modImplementation files("libs/custom-player-data-1.0.0.jar")
}
在你的 fabric.mod.json 文件中,添加以下依赖项:
{
"depends": {
"custom-player-data": ">=1.0.0"
}
}
2. 创建自定义类型(可选)
如果你需要存储复杂数据,请实现 ICustomDataType:
package com.myMod.data;
import fr.hdi.api.ICustomDataType;
import net.minecraft.nbt.NbtCompound;
public class Skill implements ICustomDataType {
private String name = "";
private int xp = 0;
private boolean unlocked = false;
public Skill() {}
public Skill(String name, int xp, boolean unlocked) {
this.name = name;
this.xp = xp;
this.unlocked = unlocked;
}
@Override
public void writeNbt(NbtCompound nbt) {
nbt.putString("name", name);
nbt.putInt("xp", xp);
nbt.putBoolean("unlocked", unlocked);
}
@Override
public void readNbt(NbtCompound nbt) {
this.name = nbt.getString("name");
this.xp = nbt.getInt("xp");
this.unlocked = nbt.getBoolean("unlocked");
}
public String getName() { return name; }
public int getXp() { return xp; }
public boolean isUnlocked() { return unlocked; }
public void setXp(int xp) { this.xp = xp; }
public void setUnlocked(boolean unlocked) { this.unlocked = unlocked; }
@Override
public String toString() {
return "Skill{" + name + ", xp=" + xp + ", unlocked=" + unlocked + "}";
}
}
3. 注册你的类型和变量
在你的模组的 onInitialize() 方法中:
package com.myMod;
import com.myMod.data.Skill;
import fr.hdi.api.TypeRegistry;
import fr.hdi.schema.SchemaManager;
import fr.hdi.schema.VariableDefinition;
import net.fabricmc.api.ModInitializer;
public class myMod implements ModInitializer {
@Override
public void onInitialize() {
// 1. 注册自定义类型
TypeRegistry.register("Skill", Skill::new);
// 2. 注册所有可能的变量 schema
SchemaManager.registerVariable(
VariableDefinition.builder("level", "int")
.defaultValue(1)
.minValue(1)
.maxValue(100)
.build()
);
SchemaManager.registerVariable(
VariableDefinition.builder("clan", "string")
.defaultValue("none")
.build()
);
SchemaManager.registerVariable(
VariableDefinition.builder("hasCompletedTutorial", "boolean")
.defaultValue(false)
.build()
);
SchemaManager.registerVariable(
VariableDefinition.builder("skills", "Skill")
.array(true)
.nullable(true)
.defaultNull()
.build()
);
}
}
4. 读取和写入玩家数据
使用 PlayerDataStore 从服务器代码中的任何位置访问数据:
import fr.hdi.api.PlayerDataStore;
import net.minecraft.server.network.ServerPlayerEntity;
// 读取经典类型
int level = PlayerDataStore.getInt(player, "level");
String clan = PlayerDataStore.getString(player, "clan");
boolean done = PlayerDataStore.getBoolean(player, "hasCompletedTutorial");
// 使用默认值读取
String color = PlayerDataStore.getString(player, "color", "red");
// 读取自定义类型
Skill skill = PlayerDataStore.getCustom(player, "mainSkill", Skill.class);
// 列表读取
List<Skill> skills = PlayerDataStore.getList(player, "skills", Skill.class);
// 泛型读取
Object raw = PlayerDataStore.getData(player, "level");
// 设置基础变量
PlayerDataStore.setData(player, "level", 42);
PlayerDataStore.setData(player, "clan", "Dragons");
PlayerDataStore.setData(player, "hasCompletedTutorial", true);
// 写入自定义类型数组
Skill newSkill = new Skill("Archery", 150, true);
List<Skill> skillList = new ArrayList<>();
skillList.add(newSkill);
PlayerDataStore.setData(player, "skills", skillList);
5. 在客户端读取数据
数据会自动同步到客户端。使用 CustomPlayerDataClient:
import fr.hdi.CustomPlayerDataClient;
int level = CustomPlayerDataClient.getClientInt("level");
String color = CustomPlayerDataClient.getClientString("hudColor");
boolean done = CustomPlayerDataClient.getClientBoolean("hasCompletedTutorial");
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。