zh_cn:tutorial:persistent_states
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
zh_cn:tutorial:persistent_states [2023/12/21 07:51] – translating player specified persistent states dreamuniverse | zh_cn:tutorial:persistent_states [2024/07/10 03:31] (current) – several corrections to the title and specified words dreamuniverse | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== 持久状态 |
===== 引言 ===== | ===== 引言 ===== | ||
Line 130: | Line 130: | ||
</ | </ | ||
- | 注:在继承 '' | + | 注:在继承 '' |
* '' | * '' | ||
Line 283: | Line 283: | ||
如果您现在运行游戏,您会发现计数器正常递增,但现在即使您关闭游戏并重新启动,计数器也会从退出时的位置继续递增。 | 如果您现在运行游戏,您会发现计数器正常递增,但现在即使您关闭游戏并重新启动,计数器也会从退出时的位置继续递增。 | ||
- | 有一点您有可能会忽略,'' | + | 有一点您有可能会忽略,'' |
- | 这对我们模组中的特定类型数据是很好的,表明它们能正常工作。但更多时候,我们期望数据是玩家限定(因人而异)的。 | + | 这对我们模组中的特定类型数据是很好的,表明它们能正常工作。但更多时候,我们期望数据是因玩家而异的。 |
正如我们开篇所提,如果我们想要保留**任意玩家**的**特定方块**的挖掘数据,这时我们要怎么做? | 正如我们开篇所提,如果我们想要保留**任意玩家**的**特定方块**的挖掘数据,这时我们要怎么做? | ||
===== 因玩家而异的持久化状态 ===== | ===== 因玩家而异的持久化状态 ===== | ||
- | 我们可以将我们所写的代码延伸一下,这样就可以存储每个玩家的特定数据了。 | + | 我们可以将我们所写的代码再改进一下,这样就可以存储每个玩家的特定数据了。 |
首先,新建一个名为 '' | 首先,新建一个名为 '' | ||
- | * 特别提示: | + | * 特别提示: |
如果您期望在客户端侧获知部分或全部的 '' | 如果您期望在客户端侧获知部分或全部的 '' | ||
Line 322: | Line 322: | ||
</ | </ | ||
- | 注:我们创建了一个关于 '' | + | 注:我们创建了一个关于 '' |
Hashmap 即哈希表,简单而言,在本例中,您向表中给出一个特定的“键值”(key),表从 '' | Hashmap 即哈希表,简单而言,在本例中,您向表中给出一个特定的“键值”(key),表从 '' | ||
我们使用 '' | 我们使用 '' | ||
Line 396: | Line 396: | ||
</ | </ | ||
- | 您同时需要将实现了 '' | + | 您同时需要将实现了 '' |
<code java> | <code java> | ||
Line 563: | Line 563: | ||
===== 内联同步 ===== | ===== 内联同步 ===== | ||
- | What if it's important for our mod that as soon as a player joins they receive some or all the PlayerData | + | 那么,当玩家加入服务器时,他们应当收到与他们相关的部分或全部玩家数据(''**PlayerData**'' |
+ | 对于这一点,当玩家加入世界时,我们会向玩家发送一个用于内联同步('' | ||
- | Modify your class which '' | + | 现在,我们将实现了'' |
<code java> | <code java> | ||
Line 581: | Line 582: | ||
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
- | public static final String MOD_ID = "your_unique_mod_id_change_me_please"; | + | public static final String MOD_ID = "您的MOD_ID"; |
public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, | public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, | ||
Line 601: | Line 602: | ||
if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) { | if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) { | ||
StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer()); | StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer()); | ||
- | // Increment the amount of dirt blocks that have been broken | + | // 当泥土方块被挖掘时增加计数 |
serverState.totalDirtBlocksBroken += 1; | serverState.totalDirtBlocksBroken += 1; | ||
Line 607: | Line 608: | ||
playerState.dirtBlocksBroken += 1; | playerState.dirtBlocksBroken += 1; | ||
- | // Send a packet to the client | + | // 向客户端发送数据包 |
MinecraftServer server = world.getServer(); | MinecraftServer server = world.getServer(); | ||
Line 624: | Line 625: | ||
</ | </ | ||
- | Then modify your class which '' | + | 随后,再将实现了 |
<code java> | <code java> | ||
Line 642: | Line 643: | ||
client.execute(() -> { | client.execute(() -> { | ||
- | client.player.sendMessage(Text.literal(" | + | client.player.sendMessage(Text.literal(" |
- | client.player.sendMessage(Text.literal(" | + | client.player.sendMessage(Text.literal(" |
}); | }); | ||
}); | }); | ||
Line 651: | Line 652: | ||
client.execute(() -> { | client.execute(() -> { | ||
- | client.player.sendMessage(Text.literal(" | + | client.player.sendMessage(Text.literal(" |
}); | }); | ||
}); | }); | ||
Line 658: | Line 659: | ||
</ | </ | ||
- | As soon as you join the world/ | + | 这样一来,当您进入本地世界或服务器时,您就会看到有一条消息提示您已经挖掘了多少泥土方块。 |
- | * Note: The '' | + | * 注①:我们在客户端侧所创建的 |
- | * Note: each time you restart the minecraft client with fabric, you're assigned a new UUID, so it may seem like it's not working, but that's just because of the developer environment. | + | * 注②:每次您使用 Fabric 调试启动客户端时,您所分配到的 |
===== 更复杂的玩家数据 ===== | ===== 更复杂的玩家数据 ===== | ||
- | And just for good measure, let's see an example of how our '' | + | 现在我们已经不能满足单一方块的统计需求了,我们来看另一个例子:如果我们的 |
- | Let's say this is our '' | + | 假设我们的 |
<code java> | <code java> | ||
Line 684: | Line 685: | ||
</ | </ | ||
- | This would be our '' | + | 我们的 |
<code java> | <code java> | ||
Line 755: | Line 756: | ||
private static Type< | private static Type< | ||
- | StateSaverAndLoader:: | + | StateSaverAndLoader:: |
- | StateSaverAndLoader:: | + | StateSaverAndLoader:: |
- | null // Supposed to be an ' | + | null // 此处理论上应为 |
); | ); | ||
+ | |||
public static StateSaverAndLoader getServerState(MinecraftServer server) { | public static StateSaverAndLoader getServerState(MinecraftServer server) { | ||
- | // (Note: arbitrary choice to use ' | + | // (注:如需在任意维度生效,请使用 |
PersistentStateManager persistentStateManager = server.getWorld(World.OVERWORLD).getPersistentStateManager(); | PersistentStateManager persistentStateManager = server.getWorld(World.OVERWORLD).getPersistentStateManager(); | ||
- | + | ||
- | // The first time the following | + | // 当第一次调用了方法 |
- | // stores it inside the ' | + | // ' |
- | // ' | + | |
StateSaverAndLoader state = persistentStateManager.getOrCreate(type, | StateSaverAndLoader state = persistentStateManager.getOrCreate(type, | ||
- | + | ||
- | // If state is not marked | + | // 若状态未标记为脏(dirty),当 |
- | // Technically it's ' | + | // 从技术上讲,只有在事实上发生数据变更时才应当将状态标记为脏(dirty)。 |
- | // of mod writers are just going to be confused when their data isn't being saved, and so it's best just to ' | + | // 但大多数开发者和模组作者会对他们的数据未能保存而感到困惑,所以不妨直接使用 |
- | // Besides, it's literally just setting a bool to true, and the only time there' | + | // 另外,这只将对应的布尔值设定为 TRUE,代价是文件写入磁盘时模组的状态不会有任何改变。(这种情况非常少见) |
- | // there were no actual change to any of the mods state (INCREDIBLY RARE). | + | |
state.markDirty(); | state.markDirty(); | ||
+ | |||
return state; | return state; | ||
} | } | ||
Line 782: | Line 781: | ||
StateSaverAndLoader serverState = getServerState(player.getWorld().getServer()); | StateSaverAndLoader serverState = getServerState(player.getWorld().getServer()); | ||
- | // Either get the player by the uuid, or we don't have data for him yet, make a new player state | + | // 根据 UUID 获取对应玩家的状态,如果没有该玩家的数据,就创建一个新的玩家状态。 |
PlayerData playerState = serverState.players.computeIfAbsent(player.getUuid(), | PlayerData playerState = serverState.players.computeIfAbsent(player.getUuid(), | ||
Line 790: | Line 789: | ||
</ | </ | ||
- | Our classes which implement | + | 对已经实现了 |
<code java> | <code java> | ||
Line 808: | Line 807: | ||
client.execute(() -> { | client.execute(() -> { | ||
- | client.player.sendMessage(Text.literal(" | + | client.player.sendMessage(Text.literal(" |
- | client.player.sendMessage(Text.literal(" | + | client.player.sendMessage(Text.literal(" |
}); | }); | ||
}); | }); | ||
Line 817: | Line 816: | ||
client.execute(() -> { | client.execute(() -> { | ||
- | client.player.sendMessage(Text.literal(" | + | client.player.sendMessage(Text.literal(" |
}); | }); | ||
}); | }); | ||
Line 839: | Line 838: | ||
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
- | public static final String MOD_ID = "your_unique_mod_id_change_me_please"; | + | public static final String MOD_ID = "您的MOD_ID"; |
public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, | public static final Identifier DIRT_BROKEN = new Identifier(MOD_ID, | ||
Line 859: | Line 858: | ||
if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) { | if (state.getBlock() == Blocks.GRASS_BLOCK || state.getBlock() == Blocks.DIRT) { | ||
StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer()); | StateSaverAndLoader serverState = StateSaverAndLoader.getServerState(world.getServer()); | ||
- | // Increment the amount of dirt blocks that have been broken | + | // 当泥土方块被挖掘时增加计数 |
serverState.totalDirtBlocksBroken += 1; | serverState.totalDirtBlocksBroken += 1; | ||
Line 865: | Line 864: | ||
playerState.dirtBlocksBroken += 1; | playerState.dirtBlocksBroken += 1; | ||
- | // Send a packet to the client | + | // 向客户端发送数据包 |
MinecraftServer server = world.getServer(); | MinecraftServer server = world.getServer(); | ||
zh_cn/tutorial/persistent_states.1703145092.txt.gz · Last modified: 2023/12/21 07:51 by dreamuniverse