Compare commits

...
19 Commits
Author SHA1 Message Date
Ben Woo ccfcae9dd0 Merge pull request #3247 from Multiverse/fix/vanila-selector
Hotfix for vanilla selector params getting cut off by comma separation
2025-06-03 22:09:53 +08:00
Ben Woo f50849422b Merge pull request #3248 from Multiverse/chore/issue-template-update
Update issue template new dumps command, and fix typos
2025-06-02 22:43:47 +08:00
Ben Woo 8786a09b8f Update issue template new dumps command, and fix typos 2025-06-02 22:25:55 +08:00
Ben Woo 07b750f11c Hotfix for vanilla selector params getting cut off by comma separation 2025-06-02 21:45:29 +08:00
Ben Woo 38bbe8103c Merge pull request #3241 from Multiverse/fix/entry-fee-message
Fix vault economy not showing payment message
2025-06-02 10:55:13 +08:00
Ben Woo d2af009d9f Fix entry check messages 2025-06-02 10:51:43 +08:00
Ben Woo fd72d6a9b8 Add locale keys for economy recipt messages 2025-06-01 20:40:15 +08:00
Ben Woo d73e90e46e Fix negative deposit issue 2025-06-01 20:39:48 +08:00
Ben Woo 913f131b3b Cleanup double to int conversion for item economy 2025-06-01 20:32:11 +08:00
Ben Woo 795aeab7a3 Fix vault economy not showing payment message 2025-06-01 16:22:36 +08:00
Ben Woo 2ee01adb6b Fix negative entry fee display in /mv info command 2025-06-01 15:37:15 +08:00
Ben Woo b4e246ffb3 Merge pull request #3240 from Multiverse/fix/chat-prefix-colour
Fix chat prefix colour codes not applying
2025-06-01 10:09:21 +08:00
Ben Woo 64995a0bfd Fix chat prefix colour codes not applying 2025-06-01 09:58:37 +08:00
Ben Woo 3173b5fc18 Merge pull request #3236 from Multiverse/fix/locale-key
Fix content display wrong locale key
2025-05-31 16:22:48 +08:00
Ben Woo e1dadc045f Fix content display wrong locale key 2025-05-31 13:53:46 +08:00
Ben Woo 15812081e0 Merge pull request #3230 from xiaohuang2004/patch-1
Update multiverse-core_zh.properties
2025-05-31 09:58:02 +08:00
Ben Woo 5365ebd939 Fix Localization test 2025-05-31 09:56:14 +08:00
Ben Woo e06770a55f Fix zh property file location 2025-05-31 09:56:04 +08:00
Huang Jinjie f0992dae25 Update multiverse-core_zh.properties
I read Multiverse Core Changelog and found it support message outputs with localisation support. However, my client still display English which has been set to Chinese. I searched the code and don't found a Chinese simplified translation file. So I translate it base on the multiverse-core_en.property. I don't know exactly how to operate it, so I commit the file directly and hope the plugin can support Chinese in next version. If it can be accepted, I will continue to translate other add-one Multiverse plugins. Thanks!
2025-05-14 14:02:17 +08:00
13 changed files with 418 additions and 39 deletions

No files matched your search

+5 -5
View File
@@ -18,10 +18,10 @@ body:
When completing the report, please ensure all fields are filled with the correct details requested. Failure to do so will result in your issue being closed.
- type: input
id: mutliverse-version-info
id: multiverse-version-info
attributes:
label: '`/mv version -p` output'
description: Run `/mv version -p` in the console, then copy and paste the link from the output of the command into this box.
label: '`/mv dumps` output'
description: Run `/mv dumps` in the console, then copy and paste the link from the output of the command into this box. If `/mv dumps` command is not available, update multiverse to v5.
validations:
required: true
- type: input
@@ -29,7 +29,7 @@ body:
attributes:
label: Server logs
description: >
Include full startup log and console error (if any). upload all relevant logs to either https://paste.gg
Include full startup log and console error (if any). upload all relevant logs to either https://pastes.dev
or https://gist.github.com, save and the paste the link in this box.
validations:
required: true
@@ -54,7 +54,7 @@ body:
id: reproduce-steps
attributes:
label: Steps to reproduce
description: Provide detailed intructions to trigger the bug.
description: Provide detailed instructions to trigger the bug.
placeholder: |
Example:
1. Start a server with only multiverse installed.
@@ -129,9 +129,9 @@ class InfoCommand extends CoreCommand {
if (price == 0) {
outMap.put("Entry Fee", "FREE!");
} else if (price > 0) {
outMap.put("Entry Fee", economist.formatPrice(-price, world.getCurrency()));
outMap.put("Entry Fee", economist.formatPrice(price, world.getCurrency()));
} else if (price < 0) {
outMap.put("Entry Reward", economist.formatPrice(price, world.getCurrency()));
outMap.put("Entry Reward", economist.formatPrice(-price, world.getCurrency()));
}
}
@@ -3,20 +3,26 @@ package org.mvplugins.multiverse.core.economy;
import java.util.HashMap;
import jakarta.inject.Inject;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.command.MVCommandManager;
import org.mvplugins.multiverse.core.locale.MVCorei18n;
import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace;
@Service
final class ItemEconomy {
private static final String ECONOMY_NAME = "Simple Item Economy";
@NotNull
private final MVCommandManager commandManager;
@Inject
private ItemEconomy() {
// Can't instantiate
private ItemEconomy(@NotNull MVCommandManager commandManager) {
this.commandManager = commandManager;
}
String getFormattedPrice(double amount, Material currency) {
@@ -33,7 +39,7 @@ final class ItemEconomy {
boolean hasEnough(Player player, double amount, Material currency) {
if (currency != null) {
return player.getInventory().contains(currency, (int) amount);
return player.getInventory().contains(currency, augmentAmount(amount));
} else {
return true;
}
@@ -41,30 +47,30 @@ final class ItemEconomy {
void deposit(Player player, double amount, Material currency) {
if (MVEconomist.isItemCurrency(currency)) {
giveItem(player, amount, currency);
giveItem(player, augmentAmount(amount), currency);
}
}
void withdraw(Player player, double amount, Material currency) {
if (MVEconomist.isItemCurrency(currency)) {
takeItem(player, amount, currency);
takeItem(player, augmentAmount(amount), currency);
}
}
void giveItem(Player player, double amount, Material type) {
ItemStack item = new ItemStack(type, (int) amount);
void giveItem(Player player, int amount, Material type) {
ItemStack item = new ItemStack(type, amount);
player.getInventory().addItem(item);
showReceipt(player, (amount * -1), type);
showReceipt(player, amount, type);
}
void takeItem(Player player, double amount, Material type) {
void takeItem(Player player, int amount, Material type) {
int removed = 0;
HashMap<Integer, ItemStack> items = (HashMap<Integer, ItemStack>) player.getInventory().all(type);
for (int i : items.keySet()) {
if (removed >= amount) {
break;
}
int diff = (int) (amount - removed);
int diff = amount - removed;
int amt = player.getInventory().getItem(i).getAmount();
if (amt - diff > 0) {
player.getInventory().getItem(i).setAmount(amt - diff);
@@ -77,14 +83,17 @@ final class ItemEconomy {
showReceipt(player, amount, type);
}
void showReceipt(Player player, double price, Material item) {
void showReceipt(Player player, int price, Material item) {
if (price > 0D) {
player.sendMessage(String.format("%s%s%s %s",
ChatColor.WHITE, "You have been charged", ChatColor.GREEN, getFormattedPrice(price, item)));
commandManager.getCommandIssuer(player).sendInfo(MVCorei18n.ECONOMY_ITEM_WITHDRAW,
replace("{price}").with(getFormattedPrice(price, item)));
} else if (price < 0D) {
player.sendMessage(String.format("%s%s%s %s",
ChatColor.DARK_GREEN, getFormattedPrice((price * -1), item),
ChatColor.WHITE, "has been added to your inventory."));
commandManager.getCommandIssuer(player).sendInfo(MVCorei18n.ECONOMY_ITEM_DEPOSIT,
replace("{price}").with(getFormattedPrice(price, item)));
}
}
private int augmentAmount(@NotNull Double amount) {
return amount.intValue();
}
}
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.MultiverseCore;
import org.mvplugins.multiverse.core.command.MVCommandManager;
import org.mvplugins.multiverse.core.world.MultiverseWorld;
/**
@@ -22,8 +23,8 @@ public final class MVEconomist {
private final ItemEconomy itemEconomy;
@Inject
MVEconomist(MultiverseCore plugin, ItemEconomy itemEconomy) {
vaultHandler = new VaultHandler(plugin);
MVEconomist(MultiverseCore plugin, ItemEconomy itemEconomy, MVCommandManager commandManager) {
vaultHandler = new VaultHandler(plugin, commandManager);
this.itemEconomy = itemEconomy;
}
@@ -137,6 +138,7 @@ public final class MVEconomist {
public void deposit(Player player, double amount, @Nullable Material currency) {
if (isUsingVault(currency)) {
getVaultHandler().getEconomy().depositPlayer(player, amount);
getVaultHandler().showReceipt(player, amount);
} else {
itemEconomy.deposit(player, amount, currency);
}
@@ -153,6 +155,7 @@ public final class MVEconomist {
public void withdraw(Player player, double amount, @Nullable Material currency) {
if (isUsingVault(currency)) {
getVaultHandler().getEconomy().withdrawPlayer(player, amount);
getVaultHandler().showReceipt(player, amount);
} else {
itemEconomy.withdraw(player, amount, currency);
}
@@ -3,12 +3,18 @@ package org.mvplugins.multiverse.core.economy;
import com.dumptruckman.minecraft.util.Logging;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.jetbrains.annotations.NotNull;
import org.mvplugins.multiverse.core.command.MVCommandManager;
import org.mvplugins.multiverse.core.locale.MVCorei18n;
import static org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace;
/**
* A class we use to interface with Vault when it is present.
@@ -16,8 +22,10 @@ import org.bukkit.plugin.RegisteredServiceProvider;
final class VaultHandler implements Listener {
private Economy economy;
private final MVCommandManager commandManager;
VaultHandler(final Plugin plugin) {
VaultHandler(final Plugin plugin, @NotNull MVCommandManager commandManager) {
this.commandManager = commandManager;
Bukkit.getPluginManager().registerEvents(new VaultListener(), plugin);
setupVaultEconomy();
}
@@ -60,6 +68,16 @@ final class VaultHandler implements Listener {
return economy;
}
void showReceipt(Player player, double price) {
if (price > 0D) {
commandManager.getCommandIssuer(player).sendInfo(MVCorei18n.ECONOMY_VAULT_WITHDRAW,
replace("{price}").with(economy.format(price)));
} else if (price < 0D) {
commandManager.getCommandIssuer(player).sendInfo(MVCorei18n.ECONOMY_VAULT_DEPOSIT,
replace("{price}").with(economy.format(price)));
}
}
/**
* Listens for Vault plugin events.
*/
@@ -56,7 +56,8 @@ final class MVChatListener implements CoreListener {
.deserialize(config.getPrefixChatFormat())
.replaceText(TextReplacementConfig.builder()
.matchLiteral("%world%")
.replacement(MVChatListener.this.getWorldName(source))
.replacement(LegacyComponentSerializer.legacyAmpersand()
.deserialize(getWorldName(source)))
.build())
.replaceText(TextReplacementConfig.builder()
.matchLiteral("%chat%")
@@ -318,7 +318,6 @@ final class MVPlayerListener implements CoreListener {
.onSuccessReason(EntryFeeResult.Success.class, reason -> {
if (reason == EntryFeeResult.Success.ENOUGH_MONEY) {
economist.payEntryFee((Player) finalTeleporter, toWorld);
// Send payment receipt
}
})
.onFailure(results -> {
@@ -254,6 +254,12 @@ public enum MVCorei18n implements MessageKeyProvider {
ENTRYCHECK_EXCEEDPLAYERLIMIT,
ENTRYCHECK_NOWORLDACCESS,
// economy
ECONOMY_ITEM_DEPOSIT,
ECONOMY_ITEM_WITHDRAW,
ECONOMY_VAULT_DEPOSIT,
ECONOMY_VAULT_WITHDRAW,
// multiverse parse destination failure reason
DESTINATION_ANCHOR_FAILUREREASON_ANCHORNOTFOUND,
DESTINATION_BED_FAILUREREASON_PLAYERNOTFOUND,
@@ -19,6 +19,8 @@ import org.jetbrains.annotations.Nullable;
*/
public final class PlayerFinder {
private static final List<String> VANILLA_SELECTORS = List.of("@a", "@e", "@r", "@p", "@s");
/**
* Get a {@link Player} based on an identifier of name UUID or selector.
*
@@ -80,6 +82,16 @@ public final class PlayerFinder {
return playerResults;
}
// TODO: Currently just assume entire string is a selector. Add support for comma seperated mixture of names, uuids and selectors
if (isSelector(playerIdentifiers)) {
Logging.finer("Using selector: %s", playerIdentifiers);
List<Player> targetPlayers = getMultiBySelector(playerIdentifiers, sender);
if (targetPlayers != null) {
playerResults.addAll(targetPlayers);
}
return playerResults;
}
String[] playerIdentifierArray = REPatterns.COMMA.split(playerIdentifiers);
for (String playerIdentifier : playerIdentifierArray) {
Player targetPlayer = getByName(playerIdentifier);
@@ -100,6 +112,10 @@ public final class PlayerFinder {
return playerResults;
}
private static boolean isSelector(@NotNull String playerIdentifier) {
return VANILLA_SELECTORS.stream().anyMatch(playerIdentifier::startsWith);
}
/**
* Get a {@link Player} based on player name.
*
@@ -231,11 +231,17 @@ mv-core.commands.error.playersonly=&cThis command can only be used by players
mv-core.commands.error.multiverseworldonly=&cThis can only be used in multiverse worlds
# entry check
mv-core.entrycheck.blacklisted='{world}' is blacklisted.
mv-core.entrycheck.notenoughmoney=you do not have enough money to pay entry fee. You are required to pay {amount}.
mv-core.entrycheck.cannotpayentryfee=you do not have the ability to pay entry fee.
mv-core.entrycheck.exceedplayerlimit=the world has reached its player limit.
mv-core.entrycheck.noworldaccess=you do not have permissions to access the world.
mv-core.entrycheck.blacklisted=The world '{world}' is blacklisted.
mv-core.entrycheck.notenoughmoney=You do not have enough money to pay entry fee. You are required to pay {amount}.
mv-core.entrycheck.cannotpayentryfee=You do not have the ability to pay entry fee.
mv-core.entrycheck.exceedplayerlimit=The world has reached its player limit.
mv-core.entrycheck.noworldaccess=You do not have permissions to access the world.
# economy
mv-core.economy.item.deposit=&fYou have been charged &a{price}.
mv-core.economy.item.withdraw=&a{price}&f has been deposited into your inventory.
mv-core.economy.vault.deposit=&fYou have been charged &2{price}.
mv-core.economy.vault.withdraw=&2{price}&f has been deposited into your account.
# multiverse parse destination failure reason
mv-core.destination.anchor.failurereason.anchornotfound=&cAnchor '&6{anchor}&c' does not exist!
@@ -305,8 +311,8 @@ mv-core.contentdisplay.nocontent=&cThere is no content to display.
mv-core.contentdisplay.filter=&7[Filter '{filter}']
mv-core.contentdisplay.page=&7[Page {current} of {total}]
mv-core.contentdisplay.invalidpage=&cInvalid page number. Please enter a page number between &31&c and &3{total}&c.
mv-core.contentdisplay.null=&7&oempty
mv-core.contentdisplay.empty=&7&onull
mv-core.contentdisplay.empty=&7&oempty
mv-core.contentdisplay.null=&7&onull
# multiverse world exception
mv-core.exception.multiverseworld.createnull=World created returned null!
@@ -0,0 +1,322 @@
# configuration
mv-core.config.save.failed=保存 Multiverse-Core 的 config.yml 文件失败,所有操作都将是临时的!
mv-core.config.node.notfound=在配置文件中无法找到节点: {node}
# /mv check
mv-core.check.description=检查某位玩家是否可以将自己传送至某个地方。
mv-core.check.player.description=要检查的玩家。
mv-core.check.destination.description=目标的地址,例如某个世界的名字。
mv-core.check.haspermission=&a{player} 可以传送至 {destination}
mv-core.check.nopermission=&c{player} 不能传送至 {destination}
mv-core.check.location=目标的地址是: &f{location}
# /mv clone
mv-core.clone.description=复制一个世界。
mv-core.clone.world.description=需要复制的原世界。
mv-core.clone.newWorld.description=新世界的名称。
mv-core.clone.cloning=正在复制 '{world}' 到 '{newworld}'……
mv-core.clone.success=&a已将世界复制到 '{world}'!
# /mv config
mv-core.config.description=查看或设置某个配置的值。
mv-core.config.name.description=需要查看或设置的配置。
mv-core.config.value.description=需要设置的值。如果没有指定,将显示当前配置的值。
mv-core.config.show.success=&a配置 '&6{name}&a' 已被设置为 '&6{value}&a'。
mv-core.config.show.error=&c获取配置 '&6{name}&c' 的值失败。\n&c{error}
mv-core.config.set.success=&a成功将配置 '&6{name}&a' 设置为 '&6{value}&a'。
mv-core.config.set.error=&c将配置 '&6{name}&c' 设置为 '&6{value}&c' 失败。\n&c{error}
# /mv confirm
mv-core.confirm.description=在执行危险的指令前再一次进行确认。
# /mv coordinates
mv-core.coordinates.description=发送你的坐标信息
mv-core.coordinates.info.title=&b--- 位置信息 ---
mv-core.coordinates.info.world=&b世界: &f{world}
mv-core.coordinates.info.alias=&b别名: &f{alias}
mv-core.coordinates.info.worldScale=&b世界尺度: &f{scale}
mv-core.coordinates.info.coordinates=&b坐标: &f{coordinates}
mv-core.coordinates.info.direction=&b方向: &f{direction}
# /mv create
mv-core.create.description=创建一个新的世界并且加载。
mv-core.create.name.description=新世界的名称。
mv-core.create.environment.description=世界的环境。详见:/mv environments
mv-core.create.flags.description=附加的世界设置。在 https://gg.gg/nn8bl 上查看所有可能的标志。
mv-core.create.properties=使用以下属性创建世界 {worldName} :
mv-core.create.properties.environment=- 环境: &f{environment}
mv-core.create.properties.seed=- 种子: &f{seed}
mv-core.create.properties.worldtype=- 世界类型: &f{worldType}
mv-core.create.properties.adjustspawn=- 调节出生点: &f{adjustSpawn}
mv-core.create.properties.biome=- 生物群系: &f{biome}
mv-core.create.properties.generator=- 生成器: &f{generator}
mv-core.create.properties.generatorsettings=- 生成器设置: &f{generatorSettings}
mv-core.create.properties.structures=- 结构: &f{structures}
mv-core.create.loading=创建世界中……
mv-core.create.success=&a世界 '{world}' 已经创建!
# /mv debug
mv-core.debug.info.description=显示当前的调试等级。
mv-core.debug.info.off=&fMultiverse 调试模式是 &cOFF&f.
mv-core.debug.info.on=&fMultiverse 调试模式处于 &a等级{level}&f.
mv-core.debug.change.description=改变调试等级。
mv-core.debug.change.syntax=等级
mv-core.debug.change.level.description=需要设置的调试等级。
# /mv delete
mv-core.delete.description=在服务器上永久删除某个世界。
mv-core.delete.deleting=正在删除世界 '{world}'……
mv-core.delete.prompt=你确定想要删除世界 '{world}' 吗?
mv-core.delete.success=&a世界 '{world}' 已经删除!
# /mv dumps
mv-core.dumps.description=导出版本信息到控制台或者粘贴服务。
mv-core.dumps.url.list={service}:{link}
# /mv gamerule set
mv-core.gamerule.set.description=修改某个世界或某些世界的游戏规则。
mv-core.gamerule.set.gamerule.description=需要设置的游戏规则。
mv-core.gamerule.set.value.description=需要设置的游戏规则的值。
mv-core.gamerule.set.world.description=需要应用游戏规则的世界,默认为当前玩家所在的世界。
mv-core.gamerule.set.failed=在 {world} 中设置游戏规则 {gamerule} 为 {value} 失败。 &f它应该是 {type} 类型。
mv-core.gamerule.set.success.single=&a成功在 {world} 中将游戏规则 {gamerule} 设置为 {value}。
mv-core.gamerule.set.success.multiple=&a成功在 {count} 个世界中将游戏规则 {gamerule} 设置为 {value}。
# /mv gamerule reset
mv-core.gamerule.reset.description=重置某个世界或某些世界的游戏规则为默认值。
mv-core.gamerule.reset.gamerule.description=需要重置的游戏规则。
mv-core.gamerule.reset.world.description=需要重置游戏规则的世界,默认为当前玩家所在的世界。
mv-core.gamerule.reset.failed=在 {world} 中重置游戏规则 {gamerule} 失败。
mv-core.gamerule.reset.success.single=&a在 {world} 中重置游戏规则 {gamerule} 成功。
mv-core.gamerule.reset.success.multiple=&a成功在 {count} 个世界中重置游戏规则 {gamerule}。
# /mv gamerule list
mv-core.gamerule.list.description=列出某个特定世界的游戏规则。
mv-core.gamerule.list.description.page=查看的页码。
mv-core.gamerule.list.description.world=需要列出游戏规则的世界。
mv-core.gamerule.list.title= --- {world} 的游戏规则 ---
# /mv generators
mv-core.generators.description=列出 Multiverse 已知的生成器。
mv-core.generators.description.flags=筛选 - 仅显示匹配的条目。页码 - 查看的页面序号。
mv-core.generators.empty=&c未找到生成器插件。
# /mv import
mv-core.import.description=导入一个已经存在的世界文件夹。
mv-core.import.name.description=世界文件夹的名称。
mv-core.import.env.description=世界的环境。详见:/mv env
mv-core.import.other.description=其他世界设置。详见:https://gg.gg/nn8c2
mv-core.import.importing=开始导入世界 '{world}'……
mv-core.import.success=&a已导入世界 '{world}'!
# /mv info
mv-core.info.description=显示某个世界所有已配置的属性。
mv-core.info.description.world=需要显示信息的世界。
mv-core.info.header=&a&l---- 世界信息: &f&l{world}&a&l ----
mv-core.info.nocontent=&c没有找到这样的世界属性!
# /mv list
mv-core.list.description=显示所有可进入世界的列表。
mv-core.list.header=&6====[ 多世界列表 ]====
mv-core.list.nocontent=&c未找到任何世界,或者你没有权限进入它们!
# /mv load
mv-core.load.description=加载某个世界,世界必须已经在 worlds.yml,或者请使用 /mv import 导入。
mv-core.load.world.description=想要加载的世界名称。
mv-core.load.loading=加载世界 '{world}' 中……
mv-core.load.success=&a已加载世界 '{world}'!
# /mv modify
mv-core.modify.description=修改某个给定世界的属性。
mv-core.modify.world.description=需要修改的世界的名称。
mv-core.modify.property.description=需要修改的属性。
mv-core.modify.value.description=需要修改属性的值。
mv-core.modify.cannothavevalue=你不能指定一个值来 {action} '{property}'。
mv-core.modify.specifyvalue=你必须指定一个值来 {action} '{property}'。
mv-core.modify.success=&a成功在世界 &9{world}&a 中 {action} '&9{property}&a' 为 '&9{value}&a' 。
mv-core.modify.failure=&c在世界 &9{world}&c 中 {action} '&9{property}&c' 为 '&9{value}&c' 失败。\n&c{error}
mv-core.modify.failure.novalue=&c在世界 &9{world}&c 中 {action} '&9{property}&c' 失败。\n&c{error}
# /mv regen
mv-core.regen.description=在你的服务器上重新生成一个世界。之前的状态将会被永久丢弃。
mv-core.regen.world.description=你想要重新生成的世界。
mv-core.regen.other.description=其他的世界设置。详见:http://gg.gg/nn8lk
mv-core.regen.regenerating=重新生成世界 '{world}'……
mv-core.regen.prompt=你确定想要重新生成世界 '{world}' 吗?
mv-core.regen.success=&a已重新生成 世界 '{world}'!
# /mv reload
mv-core.reload.description=重新加载所有 Multiverse 模块的配置文件。
mv-core.reload.reloading=&6正在重新加载所有 Multiverse 插件的配置文件……
mv-core.reload.success=&a重新加载完成!
# /mv remove
mv-core.remove.description=从 Multiverse 中卸载某个世界并从 worlds.yml 中移除。这不会删除世界的文件夹。
mv-core.remove.world.description=你想要从MV认知中移除的世界。
mv-core.remove.success=&a已移除世界 '{world}'!
# /mv
mv-core.root.title=&a{name} 版本 {version}
mv-core.root.help=&a查看 &f/mv help&a 了解可以执行的指令。
# /mv setspawn
mv-core.setspawn.description=为某个特定的世界设置出生点。
mv-core.setspawn.location.description=新出生点的位置。
mv-core.setspawn.world.description=需要设置出生点的目标世界(默认为玩家的当前世界)
# /mv spawn
mv-core.spawn.description=传送某个特定的玩家到他们所在世界的出生点。
mv-core.spawn.player.description=玩家
mv-core.spawn.success=已传送 {player} 到 '{world}' 的出生点!
mv-core.spawn.failed=传送 {player} 到 '{world}' 的出生点失败。{reason}
# /mv tp
mv-core.teleport.description=允许你传送到服务器上的某个位置!
mv-core.teleport.player.description=传送的玩家。
mv-core.teleport.destination.description=位置,可以是一个世界的名字。
mv-core.teleport.toomanyplayers=&c你一次不能传送超过 {count} 个玩家。
mv-core.teleport.success=已传送 {player} 到 {destination}。
mv-core.teleport.failed=传送 {player} 到 {destination}失败。{reason}
# /mv unload
mv-core.unload.description=从 Multiverse 中卸载某个世界。这不会移除世界的文件夹。这不会将它从配置文件中移除。
mv-core.unload.world.description=你想要卸载的世界名称。
mv-core.unload.unloading=正在卸载世界 '{world}'……
mv-core.unload.success=&a已卸载 '{world}'!
# /mv usage
mv-core.usage.description=显示 Multiverse-Core 指令的用法。
# /mv version
mv-core.version.description=显示版本和作者。
mv-core.version.mv=Multiverse Core 版本 &fv{version}
mv-core.version.authors=Multiverse Core 作者 &f{authors}
mv-core.version.secretcode=特征码: &fFRN002
# /mv who
# /mv whoall
mv-core.who.description=列出在某个世界的玩家
mv-core.who.all.description=列出所有世界的玩家
mv-core.who.world.description=需要列出玩家的世界名称
mv-core.who.flags.description=筛选 - 仅显示匹配的条目。页码 - 查看的页面序号。
mv-core.who.empty=&7&o空
mv-core.who.header=&b====[ 多世界玩家列表 ]====
# /mv worldborder
mv-core.worldborder.center.nothingchanged=&c无变化。世界边界的中心在世界 '&6{world}&c' 中已经有相同的设置。
mv-core.worldborder.center.success=&r已设置世界 '&6{world}&r' 边界的中心为 &6{x}&r, &6{z}&r 。
mv-core.worldborder.damageamount.nothingchanged=&c无变化。世界边界的伤害在世界 '&6{world}&c' 中已经有相同的设置。
mv-core.worldborder.damageamount.success=&r已设置世界 '&6{world}&r' 的边界伤害为每秒每格 {amount} 点伤害。
mv-core.worldborder.damagebuffer.nothingchanged=&c无变化。世界边界伤害的缓冲在世界 '&6{world}&c' 中已经有相同的设置。
mv-core.worldborder.damagebuffer.success=&r已设置世界 '&6{world}&r' 边界伤害的缓冲为 {distance} 格。
mv-core.worldborder.get.size=&r世界 '&6{world}&r' 的边界宽度目前为 {size} 格。
mv-core.worldborder.set.nothingchanged=&c无变化。世界边界的大小在世界 '&6{world}&c' 中已经有相同的设置。
mv-core.worldborder.set.immediate=&r已设置世界 '&6{world}&r' 的边界大小为 {size} 格宽。
mv-core.worldborder.set.shrinking=&r将在 {time} 秒内收缩世界 '&6{world}&r' 的边界大小至 {size} 格宽。
mv-core.worldborder.set.growing=&r将在 {time} 秒内扩张世界 '&6{world}&r' 的边界大小至 {size} 格宽。
mv-core.worldborder.warningdistance.nothingchanged=&c无变化。世界边界的警告距离在世界 '&6{world}&c' 中已经有相同的设置。
mv-core.worldborder.warningdistance.success=&r已设置世界 '&6{world}&r' 的边界警告距离为 {distance} 格。
mv-core.worldborder.warningtime.nothingchanged=&c无变化。世界边界的警告时间在世界 '&6{world}&c' 中已经有相同的设置。
mv-core.worldborder.warningtime.success=&r已设置世界 '&6{world}&r' 的边界警告时间为 {time} 秒。
# commands error
mv-core.commands.error.playersonly=&c该指令仅玩家可以使用。
mv-core.commands.error.multiverseworldonly=&c该指令仅可以在多世界中使用。
# entry check
mv-core.entrycheck.blacklisted='{world}' 在黑名单中。
mv-core.entrycheck.notenoughmoney=你没有足够的金钱来支付入场费。你需要支付 {amount}。
mv-core.entrycheck.cannotpayentryfee=你没有能力支付入场费。
mv-core.entrycheck.exceedplayerlimit=该世界已经达到最大玩家数量限制。
mv-core.entrycheck.noworldaccess=你没有权限进入该世界。
# multiverse parse destination failure reason
mv-core.destination.anchor.failurereason.anchornotfound=&c锚点 '&6{anchor}&c' 不存在!
mv-core.destination.bed.failurereason.playernotfound=&玩家 '&6{player}&c' 不存在或不在线!如果想传送到自己的床,使用 'playerbed'。
mv-core.destination.cannon.failurereason.invalidformat=&c大炮目标格式是:&6ca:worldname:x,y,z:pitch:yaw:speed
mv-core.destination.exact.failurereason.invalidformat=&c精确目标格式是:&6e:worldname:x,y,z:pitch:yaw
mv-core.destination.player.failurereason.playernotfound=&c玩家 '&6{player}&c' 不存在或不在线!
mv-core.destination.shared.failurereason.invalidcoordinatesformat=你必须指定一个具有以下格式有效的坐标:&6{x},{y},{z}
mv-core.destination.shared.failurereason.invalidnumberformat=给定的值不是一个有效的数字。{error}.
mv-core.destination.shared.failurereason.worldnotfound=&c世界 '&6{world}&c' 不存在或着未被加载!
mv-core.destination.parse.failurereason.invaliddestinationid=无效的目标ID:{id}。有效的目标ID有:{ids}
# teleport failure reason
mv-core.teleportfailurereason.null.destination=目标无效!
mv-core.teleportfailurereason.null.location=位置无效!
mv-core.teleportfailurereason.null.world=&c位置所在的世界无效!
mv-core.teleportfailurereason.unsafe.location=位置是不安全的!使用 `--unsafe` 忽视该问题。
mv-core.teleportfailurereason.teleport.failed=出于某些拒绝了该传送。
mv-core.teleportfailurereason.teleport.failed.exception=在传送过程中出现了一个错误。查看控制台获取更多信息。
mv-core.teleportfailurereason.event.cancelled=传送被另一个插件取消了。
# world manager result
mv-core.cloneworld.invalidworldname=世界 '{world}' 包含无效的字符!
mv-core.cloneworld.worldexistfolder=世界 '{world}' 已经存在于服务器的文件中!在复制前你需要先删除它。
mv-core.cloneworld.worldexistunloaded=世界 '{world}' 已经存在并且未被加载!在复制前你需要先删除它。
mv-core.cloneworld.worldexistloaded=世界 '{world}' 已经存在!在复制前你需要先删除它。
mv-core.cloneworld.copyfailed=复制世界到 '{world}' 失败:{error}\n&f查看控制台获取更多信息。
mv-core.createworld.invalidworldname=世界 '{world}' 包含无效的字符!
mv-core.createworld.worldexistfolder=世界 '{world}' 已经存在于服务器的文件中!&f 如果你想要导入它,输入 '&a/mv import {world} <environment>&f'。
mv-core.createworld.worldexistunloaded=世界 '{world}' 已经存在, 但是未被加载!&f 如果你想要加载它,输入 '&a/mv load {world}&f'。
mv-core.createworld.worldexistloaded=世界 '{world}' 已经存在!
mv-core.deleteworld.worldnonexistent=世界 '{world}' 不存在!
mv-core.deleteworld.loadfailed=不能加载世界 '{world}',请确认世界文件夹是否存在。&f 你可以执行 '&a/mv remove {world}&f' 将它从 Multiverse 中移除,或者使用 '&a/mv load {world}&f' 尝试重新加载。
mv-core.deleteworld.worldfoldernotfound=世界 '{world}' folder not found!
mv-core.deleteworld.failedtodeletefolder=删除世界 '{world}' 的文件夹失败:{error}\n&f查看控制台获取更多信息。
mv-core.importworld.invalidworldname=世界 '{world}' 包含无效的字符!
mv-core.importworld.worldexistunloaded=世界 '{world}' 已经存在, 但是未被加载!&f 如果你想要加载它,输入 '&a/mv load {world}&f'。
mv-core.importworld.worldexistloaded=世界 '{world}' 已经存在!
mv-core.importworld.worldfolderinvalid=世界 '{world}' 文件夹的内容看上去不像是一个有效的世界!
mv-core.loadworld.worldalreadyloading=世界 '{world}' 已经正在加载!请稍后……
mv-core.loadworld.worldnonexistent=世界 '{world}' 不存在!使用 '&a/mv create {world} <environment>&f' 来创建。
mv-core.loadworld.worldexistfolder=世界 '{world}' 已经存在于服务器的文件中, 但是未被 Multiverse 识别!&f 如果你想要导入它,输入 '&a/mv import {world} <environment>&f'。
mv-core.loadworld.worldexistloaded=世界 '{world}' 已经存在!
mv-core.removeworld.worldnonexistent=世界 '{world}' 不存在!
mv-core.unloadworld.worldalreadyunloading=世界 '{world}' 已经在卸载! 请稍后……
mv-core.unloadworld.worldnonexistent=世界 '{world}' 不存在!
mv-core.unloadworld.worldunloaded=世界 '{world}' 已经卸载!
mv-core.unloadworld.bukkitunloadfailed=Bukkit 卸载世界 '{world}' 失败:{error}
mv-core.worldcreator.invalidbiomeprovider=&c无效的生物群系 '&6{biome}&c'!{error}\n&c查看控制台获取更多信息。
mv-core.worldcreator.invalidchunkgenerator=&c无效的区块生成器 '&6{generator}&c'! {error}\n&c这更像是生成器插件的问题,而不是 Multiverse。查看控制台获取更多信息。
mv-core.worldcreator.bukkitcreationfailed=&cBukkit 创建世界 '{world}' 失败:{error}\n&c查看控制台获取更多信息。
# queue command result
mv-core.queuecommand.nocommandinqueue=&c你没有任何指令在列队中。
mv-core.queuecommand.invalidotp=&c无效的 OTP 数字 '&6{otp}&c'。请重试……
mv-core.queuecommand.commandexecutionerror=&c在处理列队中命令时发生了错误:{error}\n&f查看控制台获取更多信息。
# content display messages
mv-core.contentdisplay.nocontent=&c没有可显示的内容
mv-core.contentdisplay.filter=&7[筛选 '{filter}']
mv-core.contentdisplay.page=&7[第 {current} 页,共 {total} 页]
mv-core.contentdisplay.invalidpage=&c无效的页码。请输入一个在 &31&c 到 &3{total}&c 之间的页码。
mv-core.contentdisplay.empty=&7&o空
mv-core.contentdisplay.null=&7&o错误
# multiverse world exception
mv-core.exception.multiverseworld.createnull=创建的世界返回为null!
mv-core.exception.multiverseworld.unloaddefaultworld=&c你不能卸载默认的世界!世界 &6{world}&c 是定义在 server.properties '&6level-name&c' 中的默认世界。
mv-core.exception.multiverseworld.unloadplayersinworld=&c目前仍然有 &6{count}&c 位玩家在世界中!在命令中使用 '&6--remove-players&c' 标签将所有的玩家从世界中移除。
mv-core.exception.multiverseworld.unloaderror=&c在卸载世界 &6{world}&c 过程中出现了一个位置的错误。\n&c查看控制台获取更多信息。
# generic
mv-core.generic.success=成功!
mv-core.generic.failure=失败!
mv-core.generic.error=错误!
mv-core.generic.null=无效!
mv-core.generic.you=你
@@ -330,7 +330,7 @@ class LocalizationTest : TestWithMockBukkit() {
fun `Change default locale to chinese without per player locale should get chinese message`() {
config.perPlayerLocale = false
config.defaultLocale = Locale.CHINESE
assertEquals("ab!", Message.of(
assertEquals("成功!", Message.of(
MVCorei18n.GENERIC_SUCCESS, "").formatted(locales, issuer))
}
@@ -346,7 +346,7 @@ class LocalizationTest : TestWithMockBukkit() {
fun `PerPlayerLocale enabled - Player with chinese locale should get chinese message`() {
config.perPlayerLocale = true
player.setLocale(Locale.CHINESE)
assertEquals("ab!", Message.of(
assertEquals("成功!", Message.of(
MVCorei18n.GENERIC_SUCCESS, "").formatted(locales, issuer))
}
@@ -1 +0,0 @@
mv-core.generic.success=ab!