Rebase translation work for easier rebasing

This commit is contained in:
Matthew Miller 2019-10-13 21:47:26 +10:00
parent 77ef0ae417
commit 96e56bdd0c
80 changed files with 1155 additions and 359 deletions

View File

@ -53,4 +53,5 @@ dependencies {
implementation("net.minecraftforge.gradle:ForgeGradle:3.0.143")
implementation("net.fabricmc:fabric-loom:$loomVersion")
implementation("net.fabricmc:sponge-mixin:$mixinVersion")
implementation("gradle.plugin.com.mendhak.gradlecrowdin:plugin:0.1.0")
}

View File

@ -32,9 +32,11 @@ import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.BlockCommandSender;
import java.util.Locale;
import java.util.UUID;
import javax.annotation.Nullable;
@ -91,7 +93,12 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
@Override
public void print(Component component) {
TextAdapter.sendComponent(sender, WorldEditText.format(component));
TextAdapter.sendComponent(sender, WorldEditText.format(component, getLocale()));
}
@Override
public Locale getLocale() {
return Locale.US;
}
@Override

View File

@ -30,6 +30,7 @@ import org.enginehub.piston.inject.MapBackedValueStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@ -52,7 +53,7 @@ class BukkitCommandInspector implements CommandInspector {
public String getShortText(Command command) {
Optional<org.enginehub.piston.Command> mapping = dispatcher.getCommand(command.getName());
if (mapping.isPresent()) {
return reduceToText(mapping.get().getDescription());
return reduceToText(mapping.get().getDescription(), Locale.US);
} else {
logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";
@ -63,7 +64,7 @@ class BukkitCommandInspector implements CommandInspector {
public String getFullText(Command command) {
Optional<org.enginehub.piston.Command> mapping = dispatcher.getCommand(command.getName());
if (mapping.isPresent()) {
return reduceToText(mapping.get().getFullHelp());
return reduceToText(mapping.get().getFullHelp(), Locale.US);
} else {
logger.warn("BukkitCommandInspector doesn't know how about the command '" + command + "'");
return "Help text not available";

View File

@ -31,6 +31,7 @@ import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Locale;
import java.util.UUID;
import javax.annotation.Nullable;
@ -94,7 +95,7 @@ public class BukkitCommandSender extends AbstractNonPlayerActor {
@Override
public void print(Component component) {
TextAdapter.sendComponent(sender, WorldEditText.format(component));
TextAdapter.sendComponent(sender, WorldEditText.format(component, getLocale()));
}
@Override
@ -111,6 +112,11 @@ public class BukkitCommandSender extends AbstractNonPlayerActor {
public void checkPermission(String permission) throws AuthorizationException {
}
@Override
public Locale getLocale() {
return Locale.US;
}
@Override
public SessionKey getSessionKey() {
return new SessionKey() {

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
@ -33,13 +34,13 @@ import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.formatting.WorldEditText;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -130,7 +131,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
@Override
public void print(Component component) {
TextAdapter.sendComponent(player, WorldEditText.format(component));
TextAdapter.sendComponent(player, WorldEditText.format(component, getLocale()));
}
@Override
@ -216,6 +217,11 @@ public class BukkitPlayer extends AbstractPlayerActor {
return player.teleport(BukkitAdapter.adapt(location));
}
@Override
public Locale getLocale() {
return Locale.forLanguageTag(player.getLocale().replace('_', '-'));
}
@Nullable
@Override
public <T> T getFacet(Class<? extends T> cls) {

View File

@ -43,6 +43,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -168,8 +169,9 @@ public class BukkitServerInterface implements MultiUserPlatform {
Stream.of(command.getName()),
command.getAliases().stream()
).toArray(String[]::new);
return new CommandInfo(reduceToText(command.getUsage()),
reduceToText(command.getDescription()), aliases,
// TODO Handle localisation correctly
return new CommandInfo(reduceToText(command.getUsage(), Locale.US),
reduceToText(command.getDescription(), Locale.US), aliases,
inspector, permissionsArray);
}).collect(Collectors.toList()));
}

View File

@ -32,6 +32,7 @@ import com.sk89q.worldedit.util.formatting.text.serializer.plain.PlainComponentS
import org.slf4j.Logger;
import java.io.File;
import java.util.Locale;
import java.util.UUID;
public class CLICommandSender implements Actor {
@ -97,7 +98,7 @@ public class CLICommandSender implements Actor {
@Override
public void print(Component component) {
print(PlainComponentSerializer.INSTANCE.serialize(WorldEditText.format(component)));
print(PlainComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale())));
}
@Override
@ -138,6 +139,11 @@ public class CLICommandSender implements Actor {
public void dispatchCUIEvent(CUIEvent event) {
}
@Override
public Locale getLocale() {
return Locale.getDefault();
}
@Override
public SessionKey getSessionKey() {
return new SessionKey() {

View File

@ -1,11 +1,14 @@
import net.minecrell.gradle.licenser.LicenseExtension
import org.gradle.plugins.ide.idea.model.IdeaModel
import com.mendhak.gradlecrowdin.DownloadTranslationsTask
import com.mendhak.gradlecrowdin.UploadSourceFileTask
plugins {
id("java-library")
id("net.ltgt.apt-eclipse")
id("net.ltgt.apt-idea")
id("antlr")
id("com.mendhak.gradlecrowdin")
}
applyPlatformAndCoreConfiguration()
@ -84,3 +87,32 @@ sourceSets {
}
}
}
val crowdinApiKey = "crowdin_apikey"
fun Project.applyPlatformCrowdInConfig() {
if (!project.hasProperty(crowdinApiKey)) ext[crowdinApiKey] = ""
apply(plugin = "com.mendhak.gradlecrowdin")
tasks.named<UploadSourceFileTask>("crowdinUpload") {
apiKey = crowdinApiKey
projectId = "worldedit-core"
files = arrayOf(
object {
var name = "strings.json"
var source = "$projectDir/src/main/resources/lang/strings.json"
}
)
}
tasks.named<DownloadTranslationsTask>("crowdinDownload") {
apiKey = crowdinApiKey
destination = "$projectDir/src/main/resources/lang"
projectId = "worldedit-core"
}
tasks.named("processResources").configure {
dependsOn("crowdinDownload")
}
}

View File

@ -7,9 +7,10 @@ import com.sk89q.worldedit.util.formatting.text.TranslatableComponent
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent
import com.sk89q.worldedit.util.formatting.text.format.TextDecoration
import org.enginehub.piston.util.TextHelper
import java.util.Locale
fun reduceToRst(component: Component): String {
val formatted = WorldEditText.format(component)
val formatted = WorldEditText.format(component, Locale.US)
return formatAsRst(formatted).toString()
}

View File

@ -48,12 +48,14 @@ import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.concurrency.EvenMoreExecutors;
import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.io.file.FileSelectionAbortedException;
import com.sk89q.worldedit.util.io.file.FilenameException;
import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
import com.sk89q.worldedit.util.io.file.InvalidFilenameException;
import com.sk89q.worldedit.util.task.SimpleSupervisor;
import com.sk89q.worldedit.util.task.Supervisor;
import com.sk89q.worldedit.util.translation.TranslationManager;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData;
@ -64,6 +66,7 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.script.ScriptException;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
@ -108,6 +111,7 @@ public final class WorldEdit {
private final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(
EvenMoreExecutors.newBoundedCachedThreadPool(0, 1, 20, "WorldEdit Task Executor - %s"));
private final Supervisor supervisor = new SimpleSupervisor();
private final TranslationManager translationManager = new TranslationManager(this);
private final BlockFactory blockFactory = new BlockFactory(this);
private final ItemFactory itemFactory = new ItemFactory(this);
@ -223,6 +227,15 @@ public final class WorldEdit {
return sessions;
}
/**
* Return the translation manager.
*
* @return the translation manager
*/
public TranslationManager getTranslationManager() {
return translationManager;
}
/**
* Gets the path to a file. This method will check to see if the filename
* has valid characters and has an extension. It also prevents directory
@ -684,13 +697,13 @@ public final class WorldEdit {
engine.evaluate(script, filename, vars);
} catch (ScriptException e) {
player.printError("Failed to execute:");
player.printRaw(e.getMessage());
player.print(TextComponent.of(e.getMessage()));
logger.warn("Failed to execute script", e);
} catch (NumberFormatException | WorldEditException e) {
throw e;
} catch (Throwable e) {
player.printError("Failed to execute (see console):");
player.printRaw(e.getClass().getCanonicalName());
player.print(TextComponent.of(e.getClass().getCanonicalName()));
logger.warn("Failed to execute script", e);
} finally {
for (EditSession editSession : scriptContext.getEditSessions()) {

View File

@ -61,19 +61,19 @@ import static org.enginehub.piston.part.CommandParts.arg;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class ApplyBrushCommands {
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape"), TextComponent.of("The shape of the region"))
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape"), TranslatableComponent.of("worldedit.brush.apply.shape"))
.defaultsTo(ImmutableList.of())
.ofTypes(ImmutableList.of(Key.of(RegionFactory.class)))
.build();
private static final CommandArgument RADIUS = arg(TranslatableComponent.of("radius"), TextComponent.of("The size of the brush"))
private static final CommandArgument RADIUS = arg(TranslatableComponent.of("radius"), TranslatableComponent.of("worldedit.brush.apply.radius"))
.defaultsTo(ImmutableList.of("5"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
public static void register(CommandManagerService service, CommandManager commandManager, CommandRegistrationHandler registration) {
commandManager.register("apply", builder -> {
builder.description(TextComponent.of("Apply brush, apply a function to every block"));
builder.description(TranslatableComponent.of("worldedit.brush.apply.description"));
builder.action(org.enginehub.piston.Command.Action.NULL_ACTION);
CommandManager manager = service.newCommandManager();
@ -86,7 +86,7 @@ public class ApplyBrushCommands {
builder.condition(new PermissionCondition(ImmutableSet.of("worldedit.brush.apply")));
builder.addParts(REGION_FACTORY, RADIUS);
builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), TextComponent.of("Type of brush to use"))
builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), TranslatableComponent.of("worldedit.brush.apply.type"))
.withCommands(manager.getAllCommands().collect(Collectors.toList()))
.required()
.build());
@ -125,8 +125,7 @@ public class ApplyBrushCommands {
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction) throws WorldEditException {
player.print(TextComponent.builder().append("WARNING: ", TextColor.RED, TextDecoration.BOLD)
.append("This brush simulates item usages. Its effects may not work on all platforms, may not be undo-able," +
" and may cause strange interactions with other mods/plugins. Use at your own risk.").build());
.append(TranslatableComponent.of("worldedit.brush.apply.item.warning")).build());
setApplyBrush(parameters, player, localSession, new ItemUseFactory(item, direction));
}

View File

@ -45,6 +45,11 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.component.TextUtils;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeData;
import com.sk89q.worldedit.world.biome.BiomeType;
@ -56,10 +61,12 @@ import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
/**
* Implements biome-related commands such as "/biomelist".
@ -117,24 +124,24 @@ public class BiomeCommands {
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
Set<BiomeType> biomes = new HashSet<>();
String qualifier;
String messageKey;
if (useLineOfSight) {
Location blockPosition = player.getBlockTrace(300);
if (blockPosition == null) {
player.printError("No block in sight!");
player.printError(TranslatableComponent.of("worldedit.raytrace.noblock"));
return;
}
BiomeType biome = player.getWorld().getBiome(blockPosition.toVector().toBlockPoint().toBlockVector2());
biomes.add(biome);
qualifier = "at line of sight point";
messageKey = "worldedit.biomeinfo.lineofsight";
} else if (usePosition) {
BiomeType biome = player.getWorld().getBiome(player.getLocation().toVector().toBlockPoint().toBlockVector2());
biomes.add(biome);
qualifier = "at your position";
messageKey = "worldedit.biomeinfo.position";
} else {
World world = player.getWorld();
Region region = session.getSelection(world);
@ -149,18 +156,18 @@ public class BiomeCommands {
}
}
qualifier = "in your selection";
messageKey = "worldedit.biomeinfo.selection";
}
player.print(biomes.size() != 1 ? "Biomes " + qualifier + ":" : "Biome " + qualifier + ":");
for (BiomeType biome : biomes) {
List<Component> components = biomes.stream().map(biome -> {
BiomeData data = biomeRegistry.getData(biome);
if (data != null) {
player.print(" " + data.getName());
return TextComponent.of(data.getName()).hoverEvent(HoverEvent.showText(TextComponent.of(biome.getId())));
} else {
player.print(" <unknown #" + biome.getId() + ">");
return TextComponent.of(biome.getId());
}
}
}).collect(Collectors.toList());
player.printInfo(TranslatableComponent.of(pluraliseI18n(messageKey, biomes.size()), TextUtils.join(components, TextComponent.of(", "))));
}
@Command(
@ -193,7 +200,10 @@ public class BiomeCommands {
FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace);
Operations.completeLegacy(visitor);
player.print("Biomes were changed in " + visitor.getAffected() + " columns. You may have to rejoin your game (or close and reopen your world) to see a change.");
player.printInfo(TranslatableComponent.of(
pluraliseI18n("worldedit.setbiome.changed", visitor.getAffected()),
TextComponent.of(visitor.getAffected())
));
}
}

View File

@ -55,6 +55,8 @@ import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.session.request.RequestExtent;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
@ -88,7 +90,7 @@ public class BrushCommands {
desc = "Unbind a bound brush from your current item"
)
void none(Player player, LocalSession session) throws WorldEditException {
ToolCommands.setToolNone(player, session, "Brush");
ToolCommands.setToolNone(player, session, true);
}
@Command(
@ -116,7 +118,7 @@ public class BrushCommands {
tool.setBrush(new SphereBrush(), "worldedit.brush.sphere");
}
player.print(String.format("Sphere brush shape equipped (%.0f).", radius));
player.printInfo(TranslatableComponent.of("worldedit.brush.sphere.equip", TextComponent.of((int) radius)));
}
@Command(
@ -147,7 +149,7 @@ public class BrushCommands {
tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder");
}
player.print(String.format("Cylinder brush shape equipped (%.0f by %d).", radius, height));
player.printInfo(TranslatableComponent.of("worldedit.brush.cylinder.equip", TextComponent.of((int) radius), TextComponent.of(height)));
}
@Command(
@ -183,7 +185,7 @@ public class BrushCommands {
BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType());
tool.setBrush(new ClipboardBrush(newHolder, ignoreAir, usingOrigin, pasteEntities, pasteBiomes, sourceMask), "worldedit.brush.clipboard");
player.print("Clipboard brush shape equipped.");
player.printInfo(TranslatableComponent.of("worldedit.brush.clipboard.equip"));
}
@Command(
@ -205,7 +207,12 @@ public class BrushCommands {
tool.setSize(radius);
tool.setBrush(new SmoothBrush(iterations, mask), "worldedit.brush.smooth");
player.print(String.format("Smooth brush equipped (%.0f x %dx, using %s).", radius, iterations, mask == null ? "any block" : "filter"));
player.printInfo(TranslatableComponent.of(
"worldedit.brush.smooth.equip",
TextComponent.of((int) radius),
TextComponent.of(iterations),
TextComponent.of(mask == null ? "any block" : "filter")
));
}
@Command(
@ -225,7 +232,7 @@ public class BrushCommands {
tool.setMask(new BlockTypeMask(new RequestExtent(), BlockTypes.FIRE));
tool.setBrush(new SphereBrush(), "worldedit.brush.ex");
player.print(String.format("Extinguisher equipped (%.0f).", radius));
player.printInfo(TranslatableComponent.of("worldedit.brush.extinguish.equip", TextComponent.of((int) radius)));
}
@Command(
@ -245,8 +252,7 @@ public class BrushCommands {
tool.setSize(radius);
tool.setBrush(new GravityBrush(fromMaxY), "worldedit.brush.gravity");
player.print(String.format("Gravity brush equipped (%.0f).",
radius));
player.printInfo(TranslatableComponent.of("worldedit.brush.gravity.equip", TextComponent.of((int) radius)));
}
@Command(
@ -302,7 +308,7 @@ public class BrushCommands {
tool.setSize(radius);
tool.setBrush(new ButcherBrush(flags), "worldedit.brush.butcher");
player.print(String.format("Butcher brush equipped (%.0f).", radius));
player.printInfo(TranslatableComponent.of("worldedit.brush.butcher.equip", TextComponent.of((int) radius)));
}
@Command(
@ -404,6 +410,6 @@ public class BrushCommands {
tool.setFill(null);
tool.setBrush(new OperationFactoryBrush(factory, shape, session), permission);
player.print("Set brush to " + factory);
player.printInfo(TranslatableComponent.of("worldedit.brush.operation.equip", TextComponent.of(factory.toString())));
}
}

View File

@ -45,18 +45,21 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import java.util.List;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import java.util.List;
/**
* Clipboard commands.
*/
@ -87,9 +90,7 @@ public class ClipboardCommands {
Operations.completeLegacy(copy);
session.setClipboard(new ClipboardHolder(clipboard));
List<String> messages = Lists.newArrayList();
copy.addStatusMessages(messages);
messages.forEach(actor::print);
copy.getStatusMessages().forEach(actor::print);
}
@Command(
@ -122,9 +123,7 @@ public class ClipboardCommands {
Operations.completeLegacy(copy);
session.setClipboard(new ClipboardHolder(clipboard));
List<String> messages = Lists.newArrayList();
copy.addStatusMessages(messages);
messages.forEach(actor::print);
copy.getStatusMessages().forEach(actor::print);
}
@Command(
@ -153,7 +152,7 @@ public class ClipboardCommands {
ClipboardHolder holder = session.getClipboard();
Clipboard clipboard = holder.getClipboard();
Region region = clipboard.getRegion();
List<String> messages = Lists.newArrayList();
List<Component> messages = Lists.newArrayList();
BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(actor);
if (!onlySelect) {
@ -166,7 +165,7 @@ public class ClipboardCommands {
.maskSource(sourceMask)
.build();
Operations.completeLegacy(operation);
operation.addStatusMessages(messages);
messages.addAll(Lists.newArrayList(operation.getStatusMessages()));
}
if (selectPasted || onlySelect) {
@ -180,9 +179,9 @@ public class ClipboardCommands {
}
if (onlySelect) {
actor.print("Selected clipboard paste region.");
actor.printInfo(TranslatableComponent.of("worldedit.paste.selected"));
} else {
actor.print("The clipboard has been pasted at " + to);
actor.printInfo(TranslatableComponent.of("worldedit.paste.pasted", TextComponent.of(to.toString())));
}
messages.forEach(actor::print);
}
@ -205,7 +204,7 @@ public class ClipboardCommands {
if (Math.abs(yRotate % 90) > 0.001 ||
Math.abs(xRotate % 90) > 0.001 ||
Math.abs(zRotate % 90) > 0.001) {
actor.printDebug("Note: Interpolation is not yet supported, so angles that are multiples of 90 is recommended.");
actor.printDebug(TranslatableComponent.of("worldedit.rotate.no-interpolation"));
}
ClipboardHolder holder = session.getClipboard();
@ -214,7 +213,7 @@ public class ClipboardCommands {
transform = transform.rotateX(-xRotate);
transform = transform.rotateZ(-zRotate);
holder.setTransform(holder.getTransform().combine(transform));
actor.print("The clipboard copy has been rotated.");
actor.printInfo(TranslatableComponent.of("worldedit.rotate.rotated"));
}
@Command(
@ -229,7 +228,7 @@ public class ClipboardCommands {
AffineTransform transform = new AffineTransform();
transform = transform.scale(direction.abs().multiply(-2).add(1, 1, 1).toVector3());
holder.setTransform(holder.getTransform().combine(transform));
actor.print("The clipboard copy has been flipped.");
actor.printInfo(TranslatableComponent.of("worldedit.flip.flipped"));
}
@Command(
@ -239,6 +238,6 @@ public class ClipboardCommands {
@CommandPermissions("worldedit.clipboard.clear")
public void clearClipboard(Actor actor, LocalSession session) throws WorldEditException {
session.setClipboard(null);
actor.print("Clipboard cleared.");
actor.printInfo(TranslatableComponent.of("worldedit.clearclipboard.cleared"));
}
}

View File

@ -48,6 +48,7 @@ import java.util.List;
import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION;
import static com.sk89q.worldedit.internal.command.CommandUtil.requireIV;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
/**
* Extracted from {@link SelectionCommands} to allow importing of {@link Command}.
@ -89,7 +90,7 @@ public class ExpandCommands {
private static Command createVertCommand(CommandManager commandManager) {
return commandManager.newCommand("vert")
.description(TextComponent.of("Vertically expand the selection to world limits."))
.description(TranslatableComponent.of("worldedit.expand.description.vert"))
.action(parameters -> {
expandVert(
requireIV(Key.of(LocalSession.class), "localSession", parameters),
@ -110,8 +111,10 @@ public class ExpandCommands {
session.getRegionSelector(player.getWorld()).learnChanges();
int newSize = region.getArea();
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
player.print("Region expanded " + (newSize - oldSize)
+ " blocks [top-to-bottom].");
int changeSize = newSize - oldSize;
player.printInfo(
TranslatableComponent.of(pluraliseI18n("worldedit.expand.expanded.vert", changeSize), TextComponent.of(changeSize))
);
} catch (RegionOperationException e) {
player.printError(e.getMessage());
}
@ -148,7 +151,8 @@ public class ExpandCommands {
session.getRegionSelector(world).explainRegionAdjust(actor, session);
actor.print("Region expanded " + (newSize - oldSize) + " block(s).");
int changeSize = newSize - oldSize;
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.expand.expanded", changeSize), TextComponent.of(changeSize)));
}
}

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.command;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
@ -36,6 +38,9 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.item.ItemType;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
@ -50,8 +55,6 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* General WorldEdit commands.
*/
@ -85,14 +88,17 @@ public class GeneralCommands {
limit = limit == null ? config.defaultChangeLimit : Math.max(-1, limit);
if (!mayDisable && config.maxChangeLimit > -1) {
if (limit > config.maxChangeLimit) {
actor.printError("Your maximum allowable limit is " + config.maxChangeLimit + ".");
actor.printError(TranslatableComponent.of("worldedit.limit.too-high", TextComponent.of(config.maxChangeLimit)));
return;
}
}
session.setBlockChangeLimit(limit);
actor.print("Block change limit set to " + limit + "."
+ (limit == config.defaultChangeLimit ? "" : " (Use //limit to go back to the default.)"));
Component component = TextComponent.empty().append(TranslatableComponent.of("worldedit.limit.set", TextComponent.of(limit)));
if (limit != config.defaultChangeLimit) {
component.append(TranslatableComponent.of("worldedit.limit.return-to-default", TextColor.GRAY));
}
actor.printInfo(component);
}
@Command(
@ -109,14 +115,17 @@ public class GeneralCommands {
limit = limit == null ? config.calculationTimeout : Math.max(-1, limit);
if (!mayDisable && config.maxCalculationTimeout > -1) {
if (limit > config.maxCalculationTimeout) {
actor.printError("Your maximum allowable timeout is " + config.maxCalculationTimeout + " ms.");
actor.printError(TranslatableComponent.of("worldedit.timeout.too-high", TextComponent.of(config.maxCalculationTimeout)));
return;
}
}
session.setTimeout(limit);
actor.print("Timeout time set to " + limit + " ms."
+ (limit == config.calculationTimeout ? "" : " (Use //timeout to go back to the default.)"));
Component component = TextComponent.empty().append(TranslatableComponent.of("worldedit.timeout.set", TextComponent.of(limit)));
if (limit != config.calculationTimeout) {
component.append(TranslatableComponent.of("worldedit.timeout.return-to-default", TextColor.GRAY));
}
actor.printInfo(component);
}
@Command(
@ -129,16 +138,16 @@ public class GeneralCommands {
Boolean fastMode) {
boolean hasFastMode = session.hasFastMode();
if (fastMode != null && fastMode == hasFastMode) {
actor.printError("Fast mode already " + (fastMode ? "enabled" : "disabled") + ".");
actor.printError(TranslatableComponent.of(fastMode ? "worldedit.fast.enabled.already" : "worldedit.fast.disabled.already"));
return;
}
if (hasFastMode) {
session.setFastMode(false);
actor.print("Fast mode disabled.");
actor.printInfo(TranslatableComponent.of("worldedit.fast.disabled"));
} else {
session.setFastMode(true);
actor.print("Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.");
actor.printInfo(TranslatableComponent.of("worldedit.fast.enabled"));
}
}
@ -151,10 +160,10 @@ public class GeneralCommands {
@Arg(desc = "The reorder mode", def = "")
EditSession.ReorderMode reorderMode) {
if (reorderMode == null) {
actor.print("The reorder mode is " + session.getReorderMode().getDisplayName());
actor.printInfo(TranslatableComponent.of("worldedit.reorder.current", TextComponent.of(session.getReorderMode().getDisplayName())));
} else {
session.setReorderMode(reorderMode);
actor.print("The reorder mode is now " + session.getReorderMode().getDisplayName());
actor.printInfo(TranslatableComponent.of("worldedit.reorder.set", TextComponent.of(session.getReorderMode().getDisplayName())));
}
}
@ -171,17 +180,17 @@ public class GeneralCommands {
}
boolean useServerCui = session.shouldUseServerCUI();
if (drawSelection != null && drawSelection == useServerCui) {
player.printError("Server CUI already " + (useServerCui ? "enabled" : "disabled") + ".");
player.printError(TranslatableComponent.of(useServerCui ? "worldedit.drawsel.enabled.already" : "worldedit.drawsel.disabled.already"));
return;
}
if (useServerCui) {
session.setUseServerCUI(false);
session.updateServerCUI(player);
player.print("Server CUI disabled.");
player.printInfo(TranslatableComponent.of("worldedit.drawsel.disabled"));
} else {
session.setUseServerCUI(true);
session.updateServerCUI(player);
player.print("Server CUI enabled. This only supports cuboid regions, with a maximum size of 32x32x32.");
player.printInfo(TranslatableComponent.of("worldedit.drawsel.enabled"));
}
}
@ -234,10 +243,10 @@ public class GeneralCommands {
Mask mask) {
if (mask == null) {
session.setMask(null);
actor.print("Global mask disabled.");
actor.printInfo(TranslatableComponent.of("worldedit.gmask.disabled"));
} else {
session.setMask(mask);
actor.print("Global mask set.");
actor.printInfo(TranslatableComponent.of("worldedit.gmask.set"));
}
}
@ -248,9 +257,9 @@ public class GeneralCommands {
)
public void togglePlace(Player player, LocalSession session) {
if (session.togglePlacementPosition()) {
player.print("Now placing at pos #1.");
player.printInfo(TranslatableComponent.of("worldedit.toggleplace.pos1"));
} else {
player.print("Now placing at the block you stand in.");
player.printInfo(TranslatableComponent.of("worldedit.toggleplace.player"));
}
}
@ -271,11 +280,11 @@ public class GeneralCommands {
List<String> query) {
String search = String.join(" ", query);
if (search.length() <= 2) {
actor.printError("Enter a longer search string (len > 2).");
actor.printError(TranslatableComponent.of("worldedit.searchitem.too-short"));
return;
}
if (blocksOnly && itemsOnly) {
actor.printError("You cannot use both the 'b' and 'i' flags simultaneously.");
actor.printError(TranslatableComponent.of("worldedit.searchitem.b-and-i"));
return;
}

View File

@ -27,6 +27,8 @@ import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
@ -68,7 +70,7 @@ public class HistoryCommands {
player.checkPermission("worldedit.history.undo.other");
undoSession = worldEdit.getSessionManager().findByName(playerName);
if (undoSession == null) {
player.printError("Unable to find session for " + playerName);
player.printError(TranslatableComponent.of("worldedit.session.cant-find-session", TextComponent.of(playerName)));
return;
}
}
@ -83,9 +85,9 @@ public class HistoryCommands {
}
}
if (timesUndone > 0) {
player.print("Undid " + timesUndone + " available edits.");
player.printInfo(TranslatableComponent.of("worldedit.undo.undone", TextComponent.of(timesUndone)));
} else {
player.printError("Nothing left to undo.");
player.printError(TranslatableComponent.of("worldedit.undo.none"));
}
}
@ -106,7 +108,7 @@ public class HistoryCommands {
player.checkPermission("worldedit.history.redo.other");
redoSession = worldEdit.getSessionManager().findByName(playerName);
if (redoSession == null) {
player.printError("Unable to find session for " + playerName);
player.printError(TranslatableComponent.of("worldedit.session.cant-find-session", TextComponent.of(playerName)));
return;
}
}
@ -121,9 +123,9 @@ public class HistoryCommands {
}
}
if (timesRedone > 0) {
player.print("Redid " + timesRedone + " available edits.");
player.printInfo(TranslatableComponent.of("worldedit.redo.redid", TextComponent.of(timesRedone)));
} else {
player.printError("Nothing left to redo.");
player.printError(TranslatableComponent.of("worldedit.redo.none"));
}
}
@ -135,7 +137,7 @@ public class HistoryCommands {
@CommandPermissions("worldedit.history.clear")
public void clearHistory(Actor actor, LocalSession session) {
session.clearHistory();
actor.print("History cleared.");
actor.printInfo(TranslatableComponent.of("worldedit.clearhistory.cleared"));
}
}

View File

@ -27,6 +27,8 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
@ -34,6 +36,7 @@ import org.enginehub.piston.annotation.param.Switch;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
/**
* Commands for moving the player around.
@ -61,7 +64,7 @@ public class NavigationCommands {
@CommandPermissions("worldedit.navigation.unstuck")
public void unstuck(Player player) throws WorldEditException {
player.findFreePosition();
player.print("There you go!");
player.printInfo(TranslatableComponent.of("worldedit.unstuck.moved"));
}
@Command(
@ -81,9 +84,9 @@ public class NavigationCommands {
}
}
if (ascentLevels == 0) {
player.printError("No free spot above you found.");
player.printError(TranslatableComponent.of("worldedit.ascend.obstructed"));
} else {
player.print((ascentLevels != 1) ? "Ascended " + ascentLevels + " levels." : "Ascended a level.");
player.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.ascend.moved", ascentLevels), TextComponent.of(ascentLevels)));
}
}
@ -104,9 +107,9 @@ public class NavigationCommands {
}
}
if (descentLevels == 0) {
player.printError("No free spot below you found.");
player.printError(TranslatableComponent.of("worldedit.descend.obstructed"));
} else {
player.print((descentLevels != 1) ? "Descended " + descentLevels + " levels." : "Descended a level.");
player.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.descend.moved", descentLevels), TextComponent.of(descentLevels)));
}
}
@ -127,9 +130,9 @@ public class NavigationCommands {
boolean alwaysGlass = getAlwaysGlass(forceFlight, forceGlass);
if (player.ascendToCeiling(clearance, alwaysGlass)) {
player.print("Whoosh!");
player.printInfo(TranslatableComponent.of("worldedit.ceil.moved"));
} else {
player.printError("No free spot above you found.");
player.printError(TranslatableComponent.of("worldedit.ceil.obstructed"));
}
}
@ -140,9 +143,9 @@ public class NavigationCommands {
@CommandPermissions("worldedit.navigation.thru.command")
public void thru(Player player) throws WorldEditException {
if (player.passThroughForwardWall(6)) {
player.print("Whoosh!");
player.printInfo(TranslatableComponent.of("worldedit.thru.moved"));
} else {
player.printError("No free spot ahead of you found.");
player.printError(TranslatableComponent.of("worldedit.thru.obstructed"));
}
}
@ -157,9 +160,9 @@ public class NavigationCommands {
Location pos = player.getSolidBlockTrace(300);
if (pos != null) {
player.findFreePosition(pos);
player.print("Poof!");
player.printInfo(TranslatableComponent.of("worldedit.jumpto.moved"));
} else {
player.printError("No block in sight!");
player.printError(TranslatableComponent.of("worldedit.jumpto.none"));
}
}
@ -178,9 +181,9 @@ public class NavigationCommands {
boolean forceGlass) throws WorldEditException {
boolean alwaysGlass = getAlwaysGlass(forceFlight, forceGlass);
if (player.ascendUpwards(distance, alwaysGlass)) {
player.print("Whoosh!");
player.printInfo(TranslatableComponent.of("worldedit.up.moved"));
} else {
player.printError("You would hit something above you.");
player.printError(TranslatableComponent.of("worldedit.up.obstructed"));
}
}

View File

@ -61,24 +61,24 @@ import static org.enginehub.piston.part.CommandParts.arg;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class PaintBrushCommands {
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape"), TextComponent.of("The shape of the region"))
private static final CommandArgument REGION_FACTORY = arg(TranslatableComponent.of("shape"), TranslatableComponent.of("worldedit.brush.paint.shape"))
.defaultsTo(ImmutableList.of())
.ofTypes(ImmutableList.of(Key.of(RegionFactory.class)))
.build();
private static final CommandArgument RADIUS = arg(TranslatableComponent.of("radius"), TextComponent.of("The size of the brush"))
private static final CommandArgument RADIUS = arg(TranslatableComponent.of("radius"), TranslatableComponent.of("worldedit.brush.paint.size"))
.defaultsTo(ImmutableList.of("5"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
private static final CommandArgument DENSITY = arg(TranslatableComponent.of("density"), TextComponent.of("The density of the brush"))
private static final CommandArgument DENSITY = arg(TranslatableComponent.of("density"), TranslatableComponent.of("worldedit.brush.paint.density"))
.defaultsTo(ImmutableList.of("20"))
.ofTypes(ImmutableList.of(Key.of(double.class)))
.build();
public static void register(CommandManagerService service, CommandManager commandManager, CommandRegistrationHandler registration) {
commandManager.register("paint", builder -> {
builder.description(TextComponent.of("Paint brush, apply a function to a surface"));
builder.description(TranslatableComponent.of("worldedit.brush.paint.description"));
builder.action(org.enginehub.piston.Command.Action.NULL_ACTION);
CommandManager manager = service.newCommandManager();
@ -91,7 +91,7 @@ public class PaintBrushCommands {
builder.condition(new PermissionCondition(ImmutableSet.of("worldedit.brush.paint")));
builder.addParts(REGION_FACTORY, RADIUS, DENSITY);
builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), TextComponent.of("Type of brush to use"))
builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), TranslatableComponent.of("worldedit.brush.paint.type"))
.withCommands(manager.getAllCommands().collect(Collectors.toList()))
.required()
.build());
@ -131,8 +131,7 @@ public class PaintBrushCommands {
@Direction(includeDiagonals = true)
com.sk89q.worldedit.util.Direction direction) throws WorldEditException {
player.print(TextComponent.builder().append("WARNING: ", TextColor.RED, TextDecoration.BOLD)
.append("This brush simulates item usages. Its effects may not work on all platforms, may not be undo-able," +
" and may cause strange interactions with other mods/plugins. Use at your own risk.").build());
.append(TranslatableComponent.of("worldedit.brush.paint.item.warning")).build());
setPaintBrush(parameters, player, localSession, new ItemUseFactory(item, direction));
}

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.command;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
@ -56,6 +55,10 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.util.formatting.component.TextUtils;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
@ -99,12 +102,11 @@ public class RegionCommands {
RegionVisitor visitor = new RegionVisitor(region, set);
Operations.completeBlindly(visitor);
List<String> messages = Lists.newArrayList();
visitor.addStatusMessages(messages);
List<Component> messages = Lists.newArrayList(visitor.getStatusMessages());
if (messages.isEmpty()) {
actor.print("Operation completed.");
actor.printInfo(TranslatableComponent.of("worldedit.set.done"));
} else {
actor.print("Operation completed (" + Joiner.on(", ").join(messages) + ").");
actor.printInfo(TranslatableComponent.of("worldedit.set.done.verbose", TextUtils.join(messages, TextComponent.of(", "))));
}
return visitor.getAffected();

View File

@ -27,11 +27,11 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
@ -76,7 +76,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError("Snapshot/backup restore is not configured.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-configured"));
return;
}
@ -101,7 +101,7 @@ public class SnapshotCommands {
}
}
} catch (MissingWorldException ex) {
actor.printError("No snapshots were found for this world.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-for-world"));
}
}
@ -117,7 +117,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError("Snapshot/backup restore is not configured.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-configured"));
return;
}
@ -128,12 +128,12 @@ public class SnapshotCommands {
if (snapshot != null) {
session.setSnapshot(null);
actor.print("Now using newest snapshot.");
actor.printInfo(TranslatableComponent.of("worldedit.snapshot.use.newest"));
} else {
actor.printError("No snapshots were found.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-found"));
}
} catch (MissingWorldException ex) {
actor.printError("No snapshots were found for this world.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-for-world"));
}
} else {
try {
@ -156,7 +156,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError("Snapshot/backup restore is not configured.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-configured"));
return;
}
@ -179,7 +179,7 @@ public class SnapshotCommands {
session.setSnapshot(snapshot);
actor.print("Snapshot set to: " + snapshot.getName());
} catch (MissingWorldException e) {
actor.printError("No snapshots were found for this world.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-for-world"));
}
}
@ -195,7 +195,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError("Snapshot/backup restore is not configured.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-configured"));
return;
}
@ -210,7 +210,7 @@ public class SnapshotCommands {
actor.print("Snapshot set to: " + snapshot.getName());
}
} catch (MissingWorldException ex) {
actor.printError("No snapshots were found for this world.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-for-world"));
}
}
@ -226,7 +226,7 @@ public class SnapshotCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError("Snapshot/backup restore is not configured.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-configured"));
return;
}
@ -240,7 +240,7 @@ public class SnapshotCommands {
actor.print("Snapshot set to: " + snapshot.getName());
}
} catch (MissingWorldException ex) {
actor.printError("No snapshots were found for this world.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-for-world"));
}
}

View File

@ -29,6 +29,8 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.DataException;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.snapshot.InvalidSnapshotException;
@ -68,7 +70,7 @@ public class SnapshotUtilCommands {
LocalConfiguration config = we.getConfiguration();
if (config.snapshotRepo == null) {
actor.printError("Snapshot/backup restore is not configured.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-configured"));
return;
}
@ -79,7 +81,7 @@ public class SnapshotUtilCommands {
try {
snapshot = config.snapshotRepo.getSnapshot(snapshotName);
} catch (InvalidSnapshotException e) {
actor.printError("That snapshot does not exist or is not available.");
actor.printError(TranslatableComponent.of("worldedit.restore.not-available"));
return;
}
} else {
@ -92,7 +94,7 @@ public class SnapshotUtilCommands {
snapshot = config.snapshotRepo.getDefaultSnapshot(world.getName());
if (snapshot == null) {
actor.printError("No snapshots were found. See console for details.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-found-console"));
// Okay, let's toss some debugging information!
File dir = config.snapshotRepo.getDirectory();
@ -109,7 +111,7 @@ public class SnapshotUtilCommands {
return;
}
} catch (MissingWorldException ex) {
actor.printError("No snapshots were found for this world.");
actor.printError(TranslatableComponent.of("worldedit.restore.none-for-world"));
return;
}
}
@ -119,9 +121,9 @@ public class SnapshotUtilCommands {
// Load chunk store
try {
chunkStore = snapshot.getChunkStore();
actor.print("Snapshot '" + snapshot.getName() + "' loaded; now restoring...");
actor.printInfo(TranslatableComponent.of("worldedit.restore.loaded", TextComponent.of(snapshot.getName())));
} catch (DataException | IOException e) {
actor.printError("Failed to load snapshot: " + e.getMessage());
actor.printError(TranslatableComponent.of("worldedit.restore.failed", TextComponent.of(e.getMessage())));
return;
}
@ -135,18 +137,17 @@ public class SnapshotUtilCommands {
if (restore.hadTotalFailure()) {
String error = restore.getLastErrorMessage();
if (!restore.getMissingChunks().isEmpty()) {
actor.printError("Chunks were not present in snapshot.");
actor.printError(TranslatableComponent.of("worldedit.restore.chunk-not-present"));
} else if (error != null) {
actor.printError("Errors prevented any blocks from being restored.");
actor.printError("Last error: " + error);
actor.printError(TranslatableComponent.of("worldedit.restore.block-place-failed"));
actor.printError(TranslatableComponent.of("worldedit.restore.block-place-error", TextComponent.of(error)));
} else {
actor.printError("No chunks could be loaded. (Bad archive?)");
actor.printError(TranslatableComponent.of("worldedit.restore.chunk-load-failed"));
}
} else {
actor.print(String.format("Restored; %d "
+ "missing chunks and %d other errors.",
restore.getMissingChunks().size(),
restore.getErrorChunks().size()));
actor.printInfo(TranslatableComponent.of("worldedit.restore.restored",
TextComponent.of(restore.getMissingChunks().size()),
TextComponent.of(restore.getErrorChunks().size())));
}
} finally {
try {

View File

@ -29,6 +29,8 @@ import com.sk89q.worldedit.command.tool.SinglePickaxe;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
@ -49,7 +51,7 @@ public class SuperPickaxeCommands {
public void single(Player player, LocalSession session) throws WorldEditException {
session.setSuperPickaxe(new SinglePickaxe());
session.enableSuperPickAxe();
player.print("Mode changed. Left click with a pickaxe. // to disable.");
player.printInfo(TranslatableComponent.of("worldedit.superpickaxe.mode.single"));
}
@Command(
@ -64,13 +66,13 @@ public class SuperPickaxeCommands {
LocalConfiguration config = we.getConfiguration();
if (range > config.maxSuperPickaxeSize) {
player.printError("Maximum range: " + config.maxSuperPickaxeSize);
player.printError(TranslatableComponent.of("worldedit.superpickaxe.max-range", TextComponent.of(config.maxSuperPickaxeSize)));
return;
}
session.setSuperPickaxe(new AreaPickaxe(range));
session.enableSuperPickAxe();
player.print("Mode changed. Left click with a pickaxe. // to disable.");
player.printInfo(TranslatableComponent.of("worldedit.superpickaxe.mode.area"));
}
@Command(
@ -86,12 +88,12 @@ public class SuperPickaxeCommands {
LocalConfiguration config = we.getConfiguration();
if (range > config.maxSuperPickaxeSize) {
player.printError("Maximum range: " + config.maxSuperPickaxeSize);
player.printError(TranslatableComponent.of("worldedit.superpickaxe.max-range", TextComponent.of(config.maxSuperPickaxeSize)));
return;
}
session.setSuperPickaxe(new RecursivePickaxe(range));
session.enableSuperPickAxe();
player.print("Mode changed. Left click with a pickaxe. // to disable.");
player.printInfo(TranslatableComponent.of("worldedit.superpickaxe.mode.recursive"));
}
}

View File

@ -24,7 +24,6 @@ import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.command.tool.BlockDataCyler;
import com.sk89q.worldedit.command.tool.BlockReplacer;
import com.sk89q.worldedit.command.tool.DistanceWand;
@ -122,10 +121,10 @@ public class ToolCommands {
return "/tool " + name;
}
static void setToolNone(Player player, LocalSession session, String type)
static void setToolNone(Player player, LocalSession session, boolean isBrush)
throws InvalidToolBindException {
session.setTool(player.getItemInHand(HandSide.MAIN_HAND).getType(), null);
player.print(type + " unbound from your current item.");
player.printInfo(TranslatableComponent.of(isBrush ? "worldedit.brush.none.equip" : "worldedit.tool.none.equip"));
}
private final WorldEdit we;
@ -140,7 +139,7 @@ public class ToolCommands {
desc = "Unbind a bound tool from your current item"
)
public void none(Player player, LocalSession session) throws WorldEditException {
setToolNone(player, session, "Tool");
setToolNone(player, session, false);
}
@Command(
@ -153,7 +152,7 @@ public class ToolCommands {
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new SelectionWand());
player.print("Selection wand bound to " + itemType.getName() + ".");
player.printInfo(TranslatableComponent.of("worldedit.tool.selwand.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -164,9 +163,9 @@ public class ToolCommands {
@CommandPermissions("worldedit.setwand")
public void navwand(Player player, LocalSession session) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new NavigationWand());
player.print("Navigation wand bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new NavigationWand());
player.printInfo(TranslatableComponent.of("worldedit.tool.navWand.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -176,10 +175,9 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.info")
public void info(Player player, LocalSession session) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new QueryTool());
player.print("Info tool bound to "
+ itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new QueryTool());
player.printInfo(TranslatableComponent.of("worldedit.tool.info.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -191,9 +189,9 @@ public class ToolCommands {
@Arg(desc = "Type of tree to generate", def = "tree")
TreeGenerator.TreeType type) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new TreePlanter(type));
player.print("Tree tool bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new TreePlanter(type));
player.printInfo(TranslatableComponent.of("worldedit.tool.tree.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -205,9 +203,9 @@ public class ToolCommands {
@Arg(desc = "The pattern of blocks to place")
Pattern pattern) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new BlockReplacer(pattern));
player.print("Block replacer tool bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new BlockReplacer(pattern));
player.printInfo(TranslatableComponent.of("worldedit.tool.repl.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -217,9 +215,9 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.data-cycler")
public void cycler(Player player, LocalSession session) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new BlockDataCyler());
player.print("Block data cycler tool bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new BlockDataCyler());
player.printInfo(TranslatableComponent.of("worldedit.tool.data-cycler.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -241,9 +239,9 @@ public class ToolCommands {
return;
}
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new FloodFillTool(range, pattern));
player.print("Block flood fill tool bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new FloodFillTool(range, pattern));
player.printInfo(TranslatableComponent.of("worldedit.tool.floodfill.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -253,10 +251,9 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.deltree")
public void deltree(Player player, LocalSession session) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new FloatingTreeRemover());
player.print("Floating tree remover tool bound to "
+ itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new FloatingTreeRemover());
player.printInfo(TranslatableComponent.of("worldedit.tool.deltree.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -266,9 +263,9 @@ public class ToolCommands {
@CommandPermissions("worldedit.tool.farwand")
public void farwand(Player player, LocalSession session) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new DistanceWand());
player.print("Far wand tool bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new DistanceWand());
player.printInfo(TranslatableComponent.of("worldedit.tool.farwand.equip", TextComponent.of(itemType.getName())));
}
@Command(
@ -282,10 +279,10 @@ public class ToolCommands {
Pattern primary,
@Arg(desc = "Pattern to set on right-click")
Pattern secondary) throws WorldEditException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new LongRangeBuildTool(primary, secondary));
player.print("Long-range building tool bound to " + itemStack.getType().getName() + ".");
final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new LongRangeBuildTool(primary, secondary));
player.printInfo(TranslatableComponent.of("worldedit.tool.lrbuild.equip", TextComponent.of(itemType.getName())));
String primaryName = "pattern";
String secondaryName = "pattern";
if (primary instanceof BlockStateHolder) {
@ -294,7 +291,6 @@ public class ToolCommands {
if (secondary instanceof BlockStateHolder) {
secondaryName = ((BlockStateHolder<?>) secondary).getBlockType().getName();
}
player.print("Left-click set to " + primaryName + "; right-click set to "
+ secondaryName + ".");
player.printInfo(TranslatableComponent.of("worldedit.tool.lrbuild.set", TextComponent.of(primaryName), TextComponent.of(secondaryName)));
}
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.command;
import static com.sk89q.worldedit.command.util.Logging.LogMode.PLACEMENT;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
@ -52,6 +53,7 @@ import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -99,7 +101,7 @@ public class UtilityCommands {
BlockVector3 pos = session.getPlacementPosition(actor);
int affected = editSession.fillXZ(pos, pattern, radius, depth, false);
actor.print(affected + " block(s) have been created.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.fill.created", affected), TextComponent.of(affected)));
return affected;
}
@ -123,7 +125,7 @@ public class UtilityCommands {
BlockVector3 pos = session.getPlacementPosition(actor);
int affected = editSession.fillXZ(pos, pattern, radius, depth, true);
actor.print(affected + " block(s) have been created.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.fillr.created", affected), TextComponent.of(affected)));
return affected;
}
@ -140,9 +142,8 @@ public class UtilityCommands {
boolean waterlogged) throws WorldEditException {
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
int affected = editSession.drainArea(
session.getPlacementPosition(actor), radius, waterlogged);
actor.print(affected + " block(s) have been changed.");
int affected = editSession.drainArea(session.getPlacementPosition(actor), radius, waterlogged);
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.drain.drained", affected), TextComponent.of(affected)));
return affected;
}
@ -159,7 +160,7 @@ public class UtilityCommands {
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.LAVA);
actor.print(affected + " block(s) have been changed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.fixlava.fixed", affected), TextComponent.of(affected)));
return affected;
}
@ -176,7 +177,7 @@ public class UtilityCommands {
radius = Math.max(0, radius);
we.checkMaxRadius(radius);
int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.WATER);
actor.print(affected + " block(s) have been changed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.fixwater.fixed", affected), TextComponent.of(affected)));
return affected;
}
@ -197,7 +198,7 @@ public class UtilityCommands {
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
int affected = editSession.removeAbove(session.getPlacementPosition(actor), size, height);
actor.print(affected + " block(s) have been removed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.removeabove.removed", affected), TextComponent.of(affected)));
return affected;
}
@ -218,7 +219,7 @@ public class UtilityCommands {
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
int affected = editSession.removeBelow(session.getPlacementPosition(actor), size, height);
actor.print(affected + " block(s) have been removed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.removebelow.removed", affected), TextComponent.of(affected)));
return affected;
}
@ -238,7 +239,7 @@ public class UtilityCommands {
we.checkMaxRadius(radius);
int affected = editSession.removeNear(session.getPlacementPosition(actor), mask, radius);
actor.print(affected + " block(s) have been removed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.removenear.removed", affected), TextComponent.of(affected)));
return affected;
}
@ -269,7 +270,7 @@ public class UtilityCommands {
}
int affected = editSession.replaceBlocks(region, from, to);
actor.print(affected + " block(s) have been replaced.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.replacenear.replaced", affected), TextComponent.of(affected)));
return affected;
}
@ -287,7 +288,7 @@ public class UtilityCommands {
we.checkMaxRadius(size);
int affected = editSession.simulateSnow(session.getPlacementPosition(actor), size);
actor.print(affected + " surface(s) covered. Let it snow~");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.snow.created", affected), TextComponent.of(affected)));
return affected;
}
@ -305,7 +306,7 @@ public class UtilityCommands {
we.checkMaxRadius(size);
int affected = editSession.thaw(session.getPlacementPosition(actor), size);
actor.print(affected + " surface(s) thawed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.thaw.removed", affected), TextComponent.of(affected)));
return affected;
}
@ -326,7 +327,7 @@ public class UtilityCommands {
final boolean onlyNormalDirt = !convertCoarse;
final int affected = editSession.green(session.getPlacementPosition(actor), size, onlyNormalDirt);
actor.print(affected + " surface(s) greened.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.green.changed", affected), TextComponent.of(affected)));
return affected;
}
@ -337,7 +338,7 @@ public class UtilityCommands {
)
@CommandPermissions("worldedit.extinguish")
@Logging(PLACEMENT)
public void extinguish(Actor actor, LocalSession session, EditSession editSession,
public int extinguish(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The radius of the square to remove in", def = "")
Integer radius) throws WorldEditException {
@ -349,7 +350,8 @@ public class UtilityCommands {
Mask mask = new BlockTypeMask(editSession, BlockTypes.FIRE);
int affected = editSession.removeNear(session.getPlacementPosition(actor), mask, size);
actor.print(affected + " block(s) have been removed.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.extinguish.removed", affected), TextComponent.of(affected)));
return affected;
}
@Command(
@ -382,7 +384,7 @@ public class UtilityCommands {
if (radius == null) {
radius = config.butcherDefaultRadius;
} else if (radius < -1) {
actor.printError("Use -1 to remove all mobs in loaded chunks");
actor.printError(TranslatableComponent.of("worldedit.butcher.explain-all"));
return 0;
} else if (radius == -1) {
if (config.butcherMaxRadius != -1) {
@ -405,7 +407,11 @@ public class UtilityCommands {
int killed = killMatchingEntities(radius, actor, flags::createFunction);
actor.print("Killed " + killed + (killed != 1 ? " mobs" : " mob") + (radius < 0 ? "" : " in a radius of " + radius) + ".");
actor.printInfo(TranslatableComponent.of(
pluraliseI18n("worldedit.butcher.killed", killed),
TextComponent.of(killed),
TextComponent.of(radius)
));
return killed;
}
@ -423,13 +429,12 @@ public class UtilityCommands {
@Arg(desc = "The radius of the cuboid to remove from")
int radius) throws WorldEditException {
if (radius < -1) {
actor.printError("Use -1 to remove all entities in loaded chunks");
actor.printError(TranslatableComponent.of("worldedit.remove.explain-all"));
return 0;
}
int removed = killMatchingEntities(radius, actor, remover::createFunction);
actor.print("Marked " + removed + (removed != 1 ? " entities" : " entity") + " for removal.");
actor.printInfo(TranslatableComponent.of(pluraliseI18n("worldedit.remove.removed", removed), TextComponent.of(removed)));
return removed;
}
@ -460,10 +465,10 @@ public class UtilityCommands {
return killed;
}
// get the formatter with the system locale. in the future, if we can get a local from a player, we can use that
private static final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.getDefault());
static {
formatter.applyPattern("#,##0.#####"); // pattern is locale-insensitive. this can translate to "1.234,56789"
private DecimalFormat formatForLocale(Locale locale) {
DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(locale);
format.applyPattern("#,##0.#####");
return format;
}
@Command(
@ -479,14 +484,13 @@ public class UtilityCommands {
try {
expression = Expression.compile(String.join(" ", input));
} catch (ExpressionException e) {
actor.printError(String.format(
"'%s' could not be parsed as a valid expression", input));
actor.printError(TranslatableComponent.of("worldedit.calc.invalid", TextComponent.of(String.join(" ", input))));
return;
}
WorldEditAsyncCommandBuilder.createAndSendMessage(actor, () -> {
double result = expression.evaluate(
new double[]{}, WorldEdit.getInstance().getSessionManager().get(actor).getTimeout());
String formatted = Double.isNaN(result) ? "NaN" : formatter.format(result);
String formatted = Double.isNaN(result) ? "NaN" : formatForLocale(actor.getLocale()).format(result);
return SubtleFormat.wrap(input + " = ").append(TextComponent.of(formatted, TextColor.LIGHT_PURPLE));
}, null);
}

View File

@ -30,9 +30,13 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.NoCapablePlatformException;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.util.formatting.component.MessageBox;
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.util.paste.ActorCallbackPaste;
import com.sk89q.worldedit.util.report.ConfigReport;
import com.sk89q.worldedit.util.report.ReportList;
@ -45,14 +49,13 @@ import org.enginehub.piston.annotation.param.Switch;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.zone.ZoneRulesException;
import java.util.List;
import java.util.Locale;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class WorldEditCommands {
@ -70,25 +73,31 @@ public class WorldEditCommands {
desc = "Get WorldEdit version"
)
public void version(Actor actor) {
actor.print("WorldEdit version " + WorldEdit.getVersion());
actor.print("https://github.com/EngineHub/worldedit/");
actor.printInfo(TranslatableComponent.of("worldedit.version.version", TextComponent.of(WorldEdit.getVersion())));
actor.printInfo(TextComponent.of("https://github.com/EngineHub/worldedit/"));
PlatformManager pm = we.getPlatformManager();
actor.printDebug("----------- Platforms -----------");
TextComponentProducer producer = new TextComponentProducer();
for (Platform platform : pm.getPlatforms()) {
actor.printDebug(String.format("* %s (%s)", platform.getPlatformName(), platform.getPlatformVersion()));
producer.append(
TextComponent.of("* ", TextColor.GRAY)
.append(TextComponent.of(platform.getPlatformName()))
.append(TextComponent.of("(" + platform.getPlatformVersion() + ")"))
).newline();
}
actor.print(new MessageBox("Platforms", producer, TextColor.GRAY).create());
actor.printDebug("----------- Capabilities -----------");
producer.reset();
for (Capability capability : Capability.values()) {
try {
Platform platform = pm.queryCapability(capability);
actor.printDebug(String.format("%s: %s", capability.name(), platform != null ? platform.getPlatformName() : "NONE"));
} catch (NoCapablePlatformException e) {
actor.printDebug(String.format("%s: %s", capability.name(), "NONE"));
}
Platform platform = pm.queryCapability(capability);
producer.append(
TextComponent.of(capability.name(), TextColor.GRAY)
.append(TextComponent.of(": ")
.append(TextComponent.of(platform != null ? platform.getPlatformName() : "NONE")))
).newline();
}
actor.print(new MessageBox("Capabilities", producer, TextColor.GRAY).create());
}
@Command(
@ -99,7 +108,7 @@ public class WorldEditCommands {
public void reload(Actor actor) {
we.getPlatformManager().queryCapability(Capability.CONFIGURATION).reload();
we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration()));
actor.print("Configuration reloaded!");
actor.printInfo(TranslatableComponent.of("worldedit.reload.config"));
}
@Command(
@ -117,15 +126,15 @@ public class WorldEditCommands {
try {
File dest = new File(we.getConfiguration().getWorkingDirectory(), "report.txt");
Files.write(result, dest, Charset.forName("UTF-8"));
actor.print("WorldEdit report written to " + dest.getAbsolutePath());
Files.write(result, dest, StandardCharsets.UTF_8);
actor.printInfo(TranslatableComponent.of("worldedit.report.written", TextComponent.of(dest.getAbsolutePath())));
} catch (IOException e) {
actor.printError("Failed to write report: " + e.getMessage());
actor.printError(TranslatableComponent.of("worldedit.report.error", TextComponent.of(e.getMessage())));
}
if (pastebin) {
actor.checkPermission("worldedit.report.pastebin");
ActorCallbackPaste.pastebin(we.getSupervisor(), actor, result, "WorldEdit report: %s.report");
ActorCallbackPaste.pastebin(we.getSupervisor(), actor, result, TranslatableComponent.builder("worldedit.report.callback"));
}
}
@ -148,12 +157,13 @@ public class WorldEditCommands {
try {
ZoneId tz = ZoneId.of(timezone);
session.setTimezone(tz);
actor.print("Timezone set for this session to: " + tz.getDisplayName(
TextStyle.FULL, Locale.ENGLISH
));
actor.print("The current time in that timezone is: " + dateFormat.format(ZonedDateTime.now(tz)));
actor.printInfo(TranslatableComponent.of("worldedit.timezone.set", TextComponent.of(tz.getDisplayName(
TextStyle.FULL, actor.getLocale()
))));
actor.print(TranslatableComponent.of("worldedit.timezone.current",
TextComponent.of(dateFormat.withLocale(actor.getLocale()).format(ZonedDateTime.now(tz)))));
} catch (ZoneRulesException e) {
actor.printError("Invalid timezone");
actor.printError(TranslatableComponent.of("worldedit.timezone.invalid"));
}
}

View File

@ -28,6 +28,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -83,7 +84,7 @@ public class AreaPickaxe implements BlockTool {
}
}
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}

View File

@ -30,6 +30,8 @@ import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState;
@ -61,12 +63,12 @@ public class BlockDataCyler implements DoubleActionBlockTool {
if (!config.allowedDataCycleBlocks.isEmpty()
&& !player.hasPermission("worldedit.override.data-cycler")
&& !config.allowedDataCycleBlocks.contains(block.getBlockType().getId())) {
player.printError("You are not permitted to cycle the data value of that block.");
player.printError(TranslatableComponent.of("worldedit.tool.data-cycler.block-not-permitted"));
return true;
}
if (block.getStates().keySet().isEmpty()) {
player.printError("That block's data cannot be cycled!");
player.printError(TranslatableComponent.of("worldedit.tool.data-cycler.cant-cycle"));
} else {
Property<?> currentProperty = selectedProperties.get(player.getUniqueId());
@ -88,9 +90,13 @@ public class BlockDataCyler implements DoubleActionBlockTool {
try {
editSession.setBlock(blockPoint, newBlock);
player.print("Value of " + currentProperty.getName() + " is now " + currentProperty.getValues().get(index));
player.printInfo(TranslatableComponent.of(
"worldedit.tool.data-cycler.new-value",
TextComponent.of(currentProperty.getName()),
TextComponent.of(String.valueOf(currentProperty.getValues().get(index)))
));
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}
@ -101,7 +107,7 @@ public class BlockDataCyler implements DoubleActionBlockTool {
index = (index + 1) % properties.size();
currentProperty = properties.get(index);
selectedProperties.put(player.getUniqueId(), currentProperty);
player.print("Now cycling " + currentProperty.getName());
player.printInfo(TranslatableComponent.of("worldedit.tool.data-cycler.cycling", TextComponent.of(currentProperty.getName())));
}
}

View File

@ -30,6 +30,8 @@ import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BaseBlock;
/**
@ -77,7 +79,7 @@ public class BlockReplacer implements DoubleActionBlockTool {
if (targetBlock != null) {
pattern = targetBlock;
player.print("Replacer tool switched to: " + targetBlock.getBlockType().getName());
player.printInfo(TranslatableComponent.of("worldedit.tool.repl.switched", TextComponent.of(targetBlock.getBlockType().getName())));
}
return true;

View File

@ -35,6 +35,7 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import javax.annotation.Nullable;
@ -183,7 +184,7 @@ public class BrushTool implements TraceTool {
Location target = player.getBlockTrace(getRange(), true, traceMask);
if (target == null) {
player.printError("No block in sight!");
player.printError(TranslatableComponent.of("worldedit.tool.no-block"));
return true;
}
@ -207,7 +208,7 @@ public class BrushTool implements TraceTool {
try {
brush.build(editSession, target.toVector().toBlockPoint(), material, size);
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}

View File

@ -28,6 +28,7 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
/**
* A wand that can be used at a distance.
@ -74,7 +75,7 @@ public class DistanceWand extends BrushTool implements DoubleActionTraceTool {
}
if (target == null) {
player.printError("No block in sight!");
player.printError(TranslatableComponent.of("worldedit.tool.no-block"));
return null;
}

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockState;
@ -72,7 +73,7 @@ public class FloatingTreeRemover implements BlockTool {
final BlockState state = world.getBlock(clicked.toVector().toBlockPoint());
if (!isTreeBlock(state.getBlockType())) {
player.printError("That's not a tree.");
player.printError(TranslatableComponent.of("worldedit.tool.deltree.not-tree"));
return true;
}
@ -80,7 +81,7 @@ public class FloatingTreeRemover implements BlockTool {
try {
final Set<BlockVector3> blockSet = bfs(world, clicked.toVector().toBlockPoint());
if (blockSet == null) {
player.printError("That's not a floating tree.");
player.printError(TranslatableComponent.of("worldedit.tool.deltree.not-floating"));
return true;
}
@ -91,7 +92,7 @@ public class FloatingTreeRemover implements BlockTool {
}
}
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -73,7 +74,7 @@ public class FloodFillTool implements BlockTool {
try {
recurse(editSession, origin, origin, range, initialType, new HashSet<>());
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}

View File

@ -31,6 +31,7 @@ import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BaseBlock;
/**
@ -118,7 +119,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
}
if (target == null) {
player.printError("No block in sight!");
player.printError(TranslatableComponent.of("worldedit.tool.no-block"));
return null;
}

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
public class NavigationWand implements DoubleActionTraceTool {
@Override
@ -40,7 +41,7 @@ public class NavigationWand implements DoubleActionTraceTool {
if (pos != null) {
player.findFreePosition(pos);
} else {
player.printError("No block in sight (or too far)!");
player.printError(TranslatableComponent.of("worldedit.jumpto.none"));
}
return true;
}
@ -56,7 +57,7 @@ public class NavigationWand implements DoubleActionTraceTool {
}
if (!player.passThroughForwardWall(Math.max(1, maxDist - 10))) {
player.printError("Nothing to pass through (or too far)!");
player.printError(TranslatableComponent.of("worldedit.thru.obstructed"));
}
return true;
}

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
@ -58,15 +59,15 @@ public class QueryTool implements BlockTool {
builder.append(TextComponent.of("@" + clicked.toVector().toBlockPoint() + ": ", TextColor.BLUE));
builder.append(TextComponent.of(block.getBlockType().getName(), TextColor.YELLOW));
builder.append(TextComponent.of(" (" + block + ") ", TextColor.GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Block state"))));
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of("worldedit.tool.info.blockstate.hover"))));
final OptionalInt internalId = BlockStateIdAccess.getBlockStateId(block.toImmutableState());
if (internalId.isPresent()) {
builder.append(TextComponent.of(" (" + internalId.getAsInt() + ") ", TextColor.DARK_GRAY)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Internal ID"))));
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of("worldedit.tool.info.internalid.hover"))));
}
builder.append(TextComponent.of(" (" + world.getBlockLightLevel(blockPoint) + "/"
+ world.getBlockLightLevel(blockPoint.add(0, 1, 0)) + ")", TextColor.WHITE)
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Block Light/Light Above"))));
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of("worldedit.tool.info.light.hover"))));
player.print(builder.build());

View File

@ -28,6 +28,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -74,7 +75,7 @@ public class RecursivePickaxe implements BlockTool {
recurse(server, editSession, world, clicked.toVector().toBlockPoint(),
clicked.toVector().toBlockPoint(), range, initialType, new HashSet<>());
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}

View File

@ -28,6 +28,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -55,7 +56,7 @@ public class SinglePickaxe implements BlockTool {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop);
editSession.setBlock(blockPoint, BlockTypes.AIR.getDefaultState());
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
}
return true;

View File

@ -29,6 +29,7 @@ import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
/**
* Plants a tree.
@ -62,10 +63,10 @@ public class TreePlanter implements BlockTool {
}
if (!successful) {
player.printError("A tree can't go there.");
player.printError(TranslatableComponent.of("worldedit.tool.tree.obstructed"));
}
} catch (MaxChangedBlocksException e) {
player.printError("Max. blocks changed reached.");
player.printError(TranslatableComponent.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}

View File

@ -55,7 +55,7 @@ public final class AsyncCommandBuilder<T> {
@Nullable
private String description;
@Nullable
private String delayMessage;
private Component delayMessage;
@Nullable
private Component successMessage;
@ -84,7 +84,12 @@ public final class AsyncCommandBuilder<T> {
return this;
}
@Deprecated
public AsyncCommandBuilder<T> sendMessageAfterDelay(String message) {
return sendMessageAfterDelay(TextComponent.of(checkNotNull(message)));
}
public AsyncCommandBuilder<T> sendMessageAfterDelay(Component message) {
this.delayMessage = checkNotNull(message);
return this;
}

View File

@ -24,6 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.Timer;
@ -34,7 +36,12 @@ public class FutureProgressListener implements Runnable {
private final MessageTimerTask task;
@Deprecated
public FutureProgressListener(Actor sender, String message) {
this(sender, TextComponent.of(message));
}
public FutureProgressListener(Actor sender, Component message) {
checkNotNull(sender);
checkNotNull(message);
@ -47,8 +54,13 @@ public class FutureProgressListener implements Runnable {
task.cancel();
}
@Deprecated
public static void addProgressListener(ListenableFuture<?> future, Actor sender, String message) {
future.addListener(new FutureProgressListener(sender, message), MoreExecutors.directExecutor());
}
public static void addProgressListener(ListenableFuture<?> future, Actor sender, Component message) {
future.addListener(new FutureProgressListener(sender, message), MoreExecutors.directExecutor());
}
}

View File

@ -22,15 +22,22 @@ package com.sk89q.worldedit.command.util;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.TimerTask;
public class MessageTimerTask extends TimerTask {
private final Actor sender;
private final String message;
private final Component message;
@Deprecated
MessageTimerTask(Actor sender, String message) {
this(sender, TextComponent.of(message));
}
MessageTimerTask(Actor sender, Component message) {
checkNotNull(sender);
checkNotNull(message);

View File

@ -24,8 +24,10 @@ import com.sk89q.worldedit.session.SessionOwner;
import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.auth.Subject;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import java.io.File;
import java.util.Locale;
/**
* An object that can perform actions in WorldEdit.
@ -52,30 +54,65 @@ public interface Actor extends Identifiable, SessionOwner, Subject {
* Print a message.
*
* @param msg The message text
* @deprecated Use component-based functions (print)
*/
@Deprecated
void printRaw(String msg);
/**
* Print a WorldEdit message.
*
* @param msg The message text
* @deprecated Use component-based functions (printDebug)
*/
@Deprecated
void printDebug(String msg);
/**
* Print a WorldEdit message.
*
* @param msg The message text
* @deprecated Use component-based functions (printInfo)
*/
@Deprecated
void print(String msg);
/**
* Print a WorldEdit error.
*
* @param msg The error message text
* @deprecated Use component-based functions (printError)
*/
@Deprecated
void printError(String msg);
/**
* Print a WorldEdit error.
*
* @param component The component to print
*/
default void printError(Component component) {
print(component.color(TextColor.RED));
}
/**
* Print a WorldEdit message.
*
* @param component The component to print
*/
default void printInfo(Component component) {
print(component.color(TextColor.LIGHT_PURPLE));
}
/**
* Print a WorldEdit message.
*
* @param component The component to print
*/
default void printDebug(Component component) {
print(component.color(TextColor.GRAY));
}
/**
* Print a {@link Component}.
*
@ -120,4 +157,10 @@ public interface Actor extends Identifiable, SessionOwner, Subject {
*/
void dispatchCUIEvent(CUIEvent event);
/**
* Get the locale of this actor.
*
* @return The locale
*/
Locale getLocale();
}

View File

@ -533,15 +533,15 @@ public final class PlatformCommandManager {
if (config.profile) {
long time = System.currentTimeMillis() - start;
double timeS = (time / 1000.0);
int changed = editSession.getBlockChangeCount();
if (time > 0) {
double throughput = changed / (time / 1000.0);
actor.printDebug((time / 1000.0) + "s elapsed (history: "
+ changed + " changed; "
+ Math.round(throughput) + " blocks/sec).");
} else {
actor.printDebug((time / 1000.0) + "s elapsed.");
}
double throughput = timeS == 0 ? changed : changed / timeS;
actor.printDebug(TranslatableComponent.of(
"worldedit.command.time-elapsed",
TextComponent.of(timeS),
TextComponent.of(changed),
TextComponent.of(Math.round(throughput))
));
}
worldEdit.flushBlockBag(actor, editSession);
@ -577,7 +577,7 @@ public final class PlatformCommandManager {
private void handleUnknownException(Actor actor, Throwable t) {
actor.printError("Please report this error: [See console]");
actor.printRaw(t.getClass().getName() + ": " + t.getMessage());
actor.print(TextComponent.of(t.getClass().getName() + ": " + t.getMessage()));
log.error("An unexpected error while handling a WorldEdit command", t);
}

View File

@ -34,10 +34,6 @@ import com.sk89q.worldedit.event.platform.Interaction;
import com.sk89q.worldedit.event.platform.PlatformInitializeEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location;

View File

@ -36,6 +36,7 @@ import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.gamemode.GameMode;
import java.util.Locale;
import java.util.UUID;
import javax.annotation.Nullable;
@ -183,4 +184,9 @@ class PlayerProxy extends AbstractPlayerActor {
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
basePlayer.floatAt(x, y, z, alwaysGlass);
}
@Override
public Locale getLocale() {
return basePlayer.getLocale();
}
}

View File

@ -109,10 +109,6 @@ public class ChunkBatchingExtent extends AbstractBufferingExtent {
@Override
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
};
}

View File

@ -146,10 +146,6 @@ public class FastModeExtent extends AbstractDelegateExtent {
@Override
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
};
}

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.function.factory;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.GuavaUtil.firstNonNull;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
@ -36,7 +37,12 @@ import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import java.util.Collection;
import java.util.List;
public class Deform implements Contextual<Operation> {
@ -186,9 +192,11 @@ public class Deform implements Contextual<Operation> {
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
messages.add("deformed using " + expression);
public Iterable<Component> getStatusMessages() {
return Lists.newArrayList(TranslatableComponent.of("worldedit.operation.deform.expression",
TextComponent.of(expression).color(TextColor.LIGHT_PURPLE)));
}
}

View File

@ -80,10 +80,6 @@ public class ChangeSetExecutor implements Operation {
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
/**
* Create a new undo operation.
*

View File

@ -21,8 +21,11 @@ package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Iterables;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.Component;
import java.util.Collection;
import java.util.List;
/**
@ -60,9 +63,8 @@ public class DelegateOperation implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
original.addStatusMessages(messages);
delegate.addStatusMessages(messages);
public Iterable<Component> getStatusMessages() {
return Iterables.concat(original.getStatusMessages(), delegate.getStatusMessages());
}
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
@ -46,7 +47,12 @@ import com.sk89q.worldedit.math.transform.Identity;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import java.util.ArrayList;
import java.util.List;
/**
@ -337,25 +343,16 @@ public class ForwardExtentCopy implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
StringBuilder msg = new StringBuilder();
msg.append(affectedBlocks).append(" block(s)");
if (affectedBiomeCols > 0) {
if (affectedEntities > 0) {
msg.append(", ");
} else {
msg.append(" and ");
}
msg.append(affectedBiomeCols).append(" biome(s)");
}
if (affectedEntities > 0) {
if (affectedBiomeCols > 0) {
msg.append(",");
}
msg.append(" and ").append(affectedEntities).append(" entities(s)");
}
msg.append(" affected.");
messages.add(msg.toString());
public Iterable<Component> getStatusMessages() {
List<Component> messages = new ArrayList<>();
messages.add(TranslatableComponent.of(pluraliseI18n("worldedit.operation.affected.block", affectedBlocks),
TextComponent.of(affectedBlocks)).color(TextColor.LIGHT_PURPLE));
messages.add(TranslatableComponent.of(pluraliseI18n("worldedit.operation.affected.biome", affectedBiomeCols),
TextComponent.of(affectedBiomeCols)).color(TextColor.LIGHT_PURPLE));
messages.add(TranslatableComponent.of(pluraliseI18n("worldedit.operation.affected.entity", affectedEntities),
TextComponent.of(affectedEntities)).color(TextColor.LIGHT_PURPLE));
return messages;
}
}

View File

@ -20,8 +20,12 @@
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* An task that may be split into multiple steps to be run sequentially
@ -56,7 +60,22 @@ public interface Operation {
* of the operation.
*
* @param messages The list to add messages to
* @deprecated Will be removed in WorldEdit 8.0 - use the Component variant
*/
void addStatusMessages(List<String> messages);
@Deprecated
default void addStatusMessages(List<String> messages) {
}
/**
* Gets an iterable of messages that describe the current status of the
* operation.
*
* @return The status messages
*/
default Iterable<Component> getStatusMessages() {
// TODO Remove legacy code WorldEdit 8.0.0
List<String> oldMessages = new ArrayList<>();
addStatusMessages(oldMessages);
return oldMessages.stream().map(TextComponent::of).collect(Collectors.toList());
}
}

View File

@ -21,13 +21,16 @@ package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.formatting.text.Component;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.stream.Collectors;
/**
* Executes multiple queues in order.
@ -105,10 +108,8 @@ public class OperationQueue implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
for (Operation operation : operations) {
operation.addStatusMessages(messages);
}
public Iterable<Component> getStatusMessages() {
return Iterables.concat(operations.stream().map(Operation::getStatusMessages).collect(Collectors.toList()));
}
}

View File

@ -49,8 +49,4 @@ public class SetLocatedBlocks implements Operation {
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
}

View File

@ -20,13 +20,19 @@
package com.sk89q.worldedit.function.visitor;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -119,10 +125,9 @@ public abstract class BreadthFirstSearch implements Operation {
* @param position the position
*/
public void visit(BlockVector3 position) {
BlockVector3 blockVector = position;
if (!visited.contains(blockVector)) {
queue.add(blockVector);
visited.add(blockVector);
if (!visited.contains(position)) {
queue.add(position);
visited.add(position);
}
}
@ -133,11 +138,10 @@ public abstract class BreadthFirstSearch implements Operation {
* @param to the block under question
*/
private void visit(BlockVector3 from, BlockVector3 to) {
BlockVector3 blockVector = to;
if (!visited.contains(blockVector)) {
visited.add(blockVector);
if (!visited.contains(to)) {
visited.add(to);
if (isVisitable(from, to)) {
queue.add(blockVector);
queue.add(to);
}
}
}
@ -183,8 +187,11 @@ public abstract class BreadthFirstSearch implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
messages.add(getAffected() + " blocks affected");
public Iterable<Component> getStatusMessages() {
return Lists.newArrayList(TranslatableComponent.of(
pluraliseI18n("worldedit.operation.affected.block", getAffected()),
TextComponent.of(getAffected())
).color(TextColor.LIGHT_PURPLE));
}
}

View File

@ -20,13 +20,20 @@
package com.sk89q.worldedit.function.visitor;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@ -77,8 +84,11 @@ public class EntityVisitor implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
messages.add(getAffected() + " entities affected");
public Iterable<Component> getStatusMessages() {
return Lists.newArrayList(TranslatableComponent.of(
pluraliseI18n("worldedit.operation.affected.entity", getAffected()),
TextComponent.of(getAffected())
).color(TextColor.LIGHT_PURPLE));
}
}

View File

@ -20,14 +20,21 @@
package com.sk89q.worldedit.function.visitor;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.FlatRegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import java.util.Collection;
import java.util.List;
/**
@ -78,8 +85,11 @@ public class FlatRegionVisitor implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
messages.add(getAffected() + " columns affected");
public Iterable<Component> getStatusMessages() {
return Lists.newArrayList(TranslatableComponent.of(
pluraliseI18n("worldedit.operation.affected.column", getAffected()),
TextComponent.of(getAffected())
).color(TextColor.LIGHT_PURPLE));
}
}

View File

@ -128,8 +128,4 @@ public class LayerVisitor implements Operation {
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
}

View File

@ -19,14 +19,19 @@
package com.sk89q.worldedit.function.visitor;
import static com.sk89q.worldedit.util.translation.LocalisationHelpers.pluraliseI18n;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import java.util.List;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
/**
* Utility class to apply region functions to {@link com.sk89q.worldedit.regions.Region}.
@ -67,8 +72,11 @@ public class RegionVisitor implements Operation {
}
@Override
public void addStatusMessages(List<String> messages) {
messages.add(getAffected() + " blocks affected");
public Iterable<Component> getStatusMessages() {
return Lists.newArrayList(TranslatableComponent.of(
pluraliseI18n("worldedit.operation.affected.block", getAffected()),
TextComponent.of(getAffected())
).color(TextColor.LIGHT_PURPLE));
}
}

View File

@ -32,6 +32,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.io.file.FilenameException;
import com.sk89q.worldedit.world.block.BaseBlock;
@ -114,7 +115,7 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @param message a message
*/
public void print(String message) {
player.print(message);
player.printInfo(TextComponent.of(message));
}
/**
@ -123,16 +124,16 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @param message a message
*/
public void error(String message) {
player.printError(message);
player.printError(TextComponent.of(message));
}
/**
* Print an raw message to the user.
* Print a raw message to the user.
*
* @param message a message
*/
public void printRaw(String message) {
player.printRaw(message);
player.print(TextComponent.of(message));
}
/**

View File

@ -19,11 +19,14 @@
package com.sk89q.worldedit.util.formatting;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.util.formatting.text.Component;
import org.enginehub.piston.config.ConfigHolder;
import org.enginehub.piston.config.TextConfig;
import org.enginehub.piston.util.TextHelper;
import java.util.Locale;
public class WorldEditText {
public static final ConfigHolder CONFIG_HOLDER = ConfigHolder.create();
@ -31,12 +34,12 @@ public class WorldEditText {
CONFIG_HOLDER.getConfig(TextConfig.commandPrefix()).setValue("/");
}
public static Component format(Component component) {
return CONFIG_HOLDER.replace(component);
public static Component format(Component component, Locale locale) {
return CONFIG_HOLDER.replace(WorldEdit.getInstance().getTranslationManager().convertText(component, locale));
}
public static String reduceToText(Component component) {
return TextHelper.reduceToText(format(component));
public static String reduceToText(Component component, Locale locale) {
return TextHelper.reduceToText(format(component, locale));
}
private WorldEditText() {

View File

@ -36,13 +36,22 @@ public class MessageBox extends TextComponentProducer {
private static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 47;
private TextComponentProducer contents;
private TextColor borderColor;
/**
* Create a new box.
*/
public MessageBox(String title, TextComponentProducer contents) {
this(title, contents, TextColor.YELLOW);
}
/**
* Create a new box.
*/
public MessageBox(String title, TextComponentProducer contents, TextColor borderColor) {
checkNotNull(title);
this.borderColor = borderColor;
append(centerAndBorder(TextComponent.of(title))).newline();
this.contents = contents;
}
@ -74,7 +83,7 @@ public class MessageBox extends TextComponentProducer {
private TextComponent createBorder(int count) {
return TextComponent.of(Strings.repeat("-", count),
TextColor.YELLOW, Sets.newHashSet(TextDecoration.STRIKETHROUGH));
borderColor, Sets.newHashSet(TextDecoration.STRIKETHROUGH));
}
/**

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.formatting.component;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.List;
public class TextUtils {
private TextUtils() {
}
/**
* Join an array of components with a joiner component.
*
* @param components The components to join
* @param joiner The joiner component
* @return The joined component
*/
public static Component join(List<Component> components, Component joiner) {
TextComponent.Builder builder = TextComponent.builder();
for (int i = 0; i < components.size(); i++) {
builder.append(components.get(i));
if (i < components.size() - 1) {
builder.append(joiner);
}
}
return builder.build();
}
}

View File

@ -40,4 +40,17 @@ public class ResourceLoader {
}
return url;
}
public static URL getResourceRoot(String name) throws IOException {
URL url = ResourceLoader.class.getResource("/" + name);
if (url == null) {
try {
return new URL("modjar://worldedit/" + name);
} catch (Exception e) {
// Not forge.
}
throw new IOException("Could not find " + name);
}
return url;
}
}

View File

@ -21,6 +21,8 @@ package com.sk89q.worldedit.util.paste;
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.task.Supervisor;
import java.net.URL;
@ -41,7 +43,9 @@ public final class ActorCallbackPaste {
* @param sender The sender
* @param content The content
* @param successMessage The message, formatted with {@link String#format(String, Object...)} on success
* @deprecated Use the Component-based version
*/
@Deprecated
public static void pastebin(Supervisor supervisor, final Actor sender, String content, final String successMessage) {
Callable<URL> task = paster.paste(content);
@ -53,4 +57,24 @@ public final class ActorCallbackPaste {
.buildAndExec(Pasters.getExecutor());
}
/**
* Submit data to a pastebin service and inform the sender of
* success or failure.
*
* @param supervisor The supervisor instance
* @param sender The sender
* @param content The content
* @param successMessage The message builder, given the URL as an arg
*/
public static void pastebin(Supervisor supervisor, final Actor sender, String content, final TranslatableComponent.Builder successMessage) {
Callable<URL> task = paster.paste(content);
AsyncCommandBuilder.wrap(task, sender)
.registerWithSupervisor(supervisor, "Submitting content to a pastebin service.")
.sendMessageAfterDelay(TranslatableComponent.of("worldedit.pastebin.uploading"))
.onSuccess((String) null, url -> sender.printInfo(successMessage.args(TextComponent.of(url.toString())).build()))
.onFailure("Failed to submit paste", null)
.buildAndExec(Pasters.getExecutor());
}
}

View File

@ -0,0 +1,42 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.translation;
public class LocalisationHelpers {
private LocalisationHelpers() {
}
/**
* Turn a translation key into a ".singular" or ".plural"
* depending on what the given number is.
*
* @param translationKey The base translation key
* @param number The number
* @return The key with .plural or .singular appended
*/
public static String pluraliseI18n(String translationKey, float number) {
if (number == 1) {
return translationKey + ".singular";
} else {
return translationKey + ".plural";
}
}
}

View File

@ -0,0 +1,144 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.translation;
import com.google.common.io.Files;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.renderer.FriendlyComponentRenderer;
import com.sk89q.worldedit.util.io.ResourceLoader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
/**
* Handles translations for the plugin.
*
* These should be in the following format:
* plugin.component.message[.meta]*
*
* Where,
* plugin = worldedit
* component = The part of the plugin, eg expand
* message = A descriptor for which message, eg, expanded
* meta = Any extra information such as plural/singular (Can have none to infinite)
*/
public class TranslationManager {
private static final Gson gson = new GsonBuilder().create();
private static final Type STRING_MAP_TYPE = new TypeToken<Map<String, String>>() {}.getType();
private final Map<Locale, Map<String, String>> translationMap = new HashMap<>();
private final FriendlyComponentRenderer<Locale> friendlyComponentRenderer = FriendlyComponentRenderer.from(
(locale, key) -> new MessageFormat(getTranslationMap(locale).getOrDefault(key, key), locale));
private Locale defaultLocale = Locale.ENGLISH;
private final WorldEdit worldEdit;
private final Set<Locale> checkedLocales = new HashSet<>();
public TranslationManager(WorldEdit worldEdit) {
this.worldEdit = worldEdit;
}
public void setDefaultLocale(Locale defaultLocale) {
this.defaultLocale = defaultLocale;
}
private Map<String, String> parseTranslationFile(File file) throws IOException {
return gson.fromJson(Files.toString(file, StandardCharsets.UTF_8), STRING_MAP_TYPE);
}
private Map<String, String> parseTranslationFile(URL file) throws IOException {
return gson.fromJson(Resources.toString(file, StandardCharsets.UTF_8), STRING_MAP_TYPE);
}
private Optional<Map<String, String>> loadTranslationFile(String filename) {
File localFile = worldEdit.getWorkingDirectoryFile("lang/" + filename);
if (localFile.exists()) {
try {
return Optional.of(parseTranslationFile(localFile));
} catch (IOException e) {
return Optional.empty();
}
} else {
try {
return Optional.of(parseTranslationFile(ResourceLoader.getResourceRoot("lang/" + filename)));
} catch (IOException e) {
return Optional.empty();
}
}
}
private boolean tryLoadTranslations(Locale locale) {
if (checkedLocales.contains(locale)) {
return false;
}
checkedLocales.add(locale);
Optional<Map<String, String>> langData = loadTranslationFile(locale.getLanguage() + "-" + locale.getCountry() + "/strings.json");
if (!langData.isPresent()) {
langData = loadTranslationFile(locale.getLanguage() + "/strings.json");
}
if (langData.isPresent()) {
translationMap.put(locale, langData.get());
return true;
}
if (locale.equals(defaultLocale)) {
translationMap.put(Locale.ENGLISH, loadTranslationFile("strings.json").orElseThrow(
() -> new RuntimeException("Failed to load WorldEdit strings!")
));
return true;
}
return false;
}
private Map<String, String> getTranslationMap(Locale locale) {
Map<String, String> translations = translationMap.get(locale);
if (translations == null) {
if (tryLoadTranslations(locale)) {
return getTranslationMap(locale);
}
if (!locale.equals(defaultLocale)) {
translations = getTranslationMap(defaultLocale);
}
}
return translations;
}
public Component convertText(Component component, Locale locale) {
return friendlyComponentRenderer.render(component, locale);
}
}

View File

@ -0,0 +1 @@
*/

View File

@ -0,0 +1,198 @@
{
"worldedit.expand.description.vert": "Vertically expand the selection to world limits.",
"worldedit.expand.expanded.singular": "Region expanded {0} block",
"worldedit.expand.expanded.plural": "Region expanded {0} blocks",
"worldedit.expand.expanded.vert.singular": "Region expanded {0} block (top-to-bottom).",
"worldedit.expand.expanded.vert.plural": "Region expanded {0} blocks (top-to-bottom).",
"worldedit.biomeinfo.lineofsight.singular": "Biome at line of sight point: {0}",
"worldedit.biomeinfo.lineofsight.plural": "Biomes at line of sight point: {0}",
"worldedit.biomeinfo.position.singular": "Biome at your position: {0}",
"worldedit.biomeinfo.position.plural": "Biomes at your position: {0}",
"worldedit.biomeinfo.selection.singular": "Biome in your selection: {0}",
"worldedit.biomeinfo.selection.plural": "Biomes in your selection: {0}",
"worldedit.brush.apply.description": "Apply brush, apply a function to every block",
"worldedit.brush.apply.radius": "The size of the brush",
"worldedit.brush.apply.shape": "The shape of the region",
"worldedit.brush.apply.type": "Type of brush to use",
"worldedit.brush.apply.item.warning": "This brush simulates item usages. Its effects may not work on all platforms, may not be undo-able, and may cause strange interactions with other mods/plugins. Use at your own risk.",
"worldedit.brush.paint.description": "Paint brush, apply a function to a surface",
"worldedit.brush.paint.size": "The size of the brush",
"worldedit.brush.paint.shape": "The shape of the region",
"worldedit.brush.paint.density": "The density of the brush",
"worldedit.brush.paint.type": "Type of brush to use",
"worldedit.brush.paint.item.warning": "This brush simulates item usages. Its effects may not work on all platforms, may not be undo-able, and may cause strange interactions with other mods/plugins. Use at your own risk.",
"worldedit.brush.sphere.equip": "Sphere brush shape equipped ({0}).",
"worldedit.brush.cylinder.equip": "Cylinder brush shape equipped ({0} by {1}).",
"worldedit.brush.clipboard.equip": "Clipboard brush shape equipped.",
"worldedit.brush.smooth.equip": "Smooth brush equipped ({0} x {1}x using {2}).",
"worldedit.brush.extinguish.equip": "Extinguisher equipped ({0}).",
"worldedit.brush.gravity.equip": "Gravity brush equipped ({0}).",
"worldedit.brush.butcher.equip": "Butcher brush equipped ({0}).",
"worldedit.brush.operation.equip": "Set brush to {0}.",
"worldedit.brush.none.equip": "Brush unbound from your current item.",
"worldedit.setbiome.changed.singular": "Biomes were changed in {0} column. You may have to rejoin your game (or close and reopen your world) to see a change.",
"worldedit.setbiome.changed.plural": "Biomes were changed in {0} columns. You may have to rejoin your game (or close and reopen your world) to see a change.",
"worldedit.drawsel.disabled": "Server CUI disabled.",
"worldedit.drawsel.enabled": "Server CUI enabled. This only supports cuboid regions, with a maximum size of 32x32x32.",
"worldedit.drawsel.disabled.already": "Server CUI already disabled.",
"worldedit.drawsel.enabled.already": "Server CUI already enabled.",
"worldedit.limit.too-high": "Your maximum allowable limit is {0}.",
"worldedit.limit.set": "Block change limit set to {0}.",
"worldedit.limit.return-to-default": " (Use //limit to go back to the default.)",
"worldedit.timeout.too-high": "Your maximum allowable timeout is {0}ms.",
"worldedit.timeout.set": "Timeout time set to {0} ms.",
"worldedit.timeout.return-to-default": " (Use //timeout to go back to the default.)",
"worldedit.fast.disabled": "Fast mode disabled.",
"worldedit.fast.enabled": "Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.",
"worldedit.fast.disabled.already": "Fast mode already disabled.",
"worldedit.fast.enabled.already": "Fast mode already enabled.",
"worldedit.reorder.current": "The reorder mode is {0}",
"worldedit.reorder.set": "The reorder mode is now {0}",
"worldedit.gmask.disabled": "Global mask disabled.",
"worldedit.gmask.set": "Global mask set.",
"worldedit.toggleplace.pos1": "Now placing at pos #1.",
"worldedit.toggleplace.player": "Now placing at the block you stand in.",
"worldedit.searchitem.too-short": "Enter a longer search string (len > 2).",
"worldedit.searchitem.b-and-i": "You cannot use both the 'b' and 'i' flags simultaneously.",
"worldedit.undo.undone": "Undid {0} available edits.",
"worldedit.undo.none": "Nothing left to undo.",
"worldedit.redo.undone": "Redid {0} available edits.",
"worldedit.redo.none": "Nothing left to redo.",
"worldedit.clearhistory.cleared": "History cleared.",
"worldedit.raytrace.noblock": "No block in sight!",
"worldedit.restore.not-configured": "Snapshot/backup restore is not configured.",
"worldedit.restore.not-available": "That snapshot does not exist or is not available.",
"worldedit.restore.failed": "Failed to load snapshot: {0}",
"worldedit.restore.loaded": "Snapshot '{0}' loaded; now restoring...",
"worldedit.restore.restored": "Restored; {0} missing chunks and {1} other errors.",
"worldedit.restore.none-for-world": "No snapshots were found for this world.",
"worldedit.restore.none-found": "No snapshots were found.",
"worldedit.restore.none-found-console": "No snapshots were found. See console for details.",
"worldedit.restore.chunk-not-present": "Chunks were not present in snapshot.",
"worldedit.restore.chunk-load-failed": "No chunks could be loaded. (Bad archive?)",
"worldedit.restore.block-place-failed": "Errors prevented any blocks from being restored.",
"worldedit.restore.block-place-error": "Last error: {0}",
"worldedit.snapshot.use.newest": "Now using newest snapshot.",
"worldedit.drain.drained.singular": "{0} block has been drained.",
"worldedit.drain.drained.plural": "{0} blocks have been drained.",
"worldedit.fill.created.singular": "{0} block has been filled.",
"worldedit.fill.created.plural": "{0} blocks have been filled.",
"worldedit.fillr.created.singular": "{0} block has been filled.",
"worldedit.fillr.created.plural": "{0} blocks have been filled.",
"worldedit.fixlava.fixed.singular": "{0} block has been fixed.",
"worldedit.fixlava.fixed.plural": "{0} blocks have been fixed.",
"worldedit.fixwater.fixed.singular": "{0} block has been fixed.",
"worldedit.fixwater.fixed.plural": "{0} blocks have been fixed.",
"worldedit.removeabove.removed.singular": "{0} block has been removed.",
"worldedit.removeabove.removed.plural": "{0} blocks have been removed.",
"worldedit.removebelow.removed.singular": "{0} block has been removed.",
"worldedit.removebelow.removed.plural": "{0} blocks have been removed.",
"worldedit.removenear.removed.singular": "{0} block has been removed.",
"worldedit.removenear.removed.plural": "{0} blocks have been removed.",
"worldedit.replacenear.replaced.singular": "{0} block has been replaced.",
"worldedit.replacenear.replaced.plural": "{0} blocks have been replaced.",
"worldedit.snow.created.singular": "{0} surface has been covered.",
"worldedit.snow.created.plural": "{0} surfaces have been covered.",
"worldedit.thaw.removed.singular": "{0} block has been thawed.",
"worldedit.thaw.removed.plural": "{0} blocks have been thawed.",
"worldedit.green.changed.singular": "{0} block has been greened.",
"worldedit.green.changed.plural": "{0} blocks have been greened.",
"worldedit.extinguish.removed.singular": "{0} fire has been extinguished.",
"worldedit.extinguish.removed.plural": "{0} fires have been extinguished.",
"worldedit.butcher.killed.singular": "{0} mob has been killed in a radius of {1}.",
"worldedit.butcher.killed.plural": "{0} mobs have been killed in a radius of {1}.",
"worldedit.butcher.explain-all": "Use -1 to remove all mobs in loaded chunks",
"worldedit.remove.removed.singular": "{0} entity has been marked for removal.",
"worldedit.remove.removed.plural": "{0} entities have been marked for removal.",
"worldedit.remove.explain-all": "Use -1 to remove all entities in loaded chunks",
"worldedit.calc.invalid": "'{0}' could not be parsed as a valid expression",
"worldedit.paste.pasted": "The clipboard has been pasted at {0}",
"worldedit.paste.selected": "Selected clipboard paste region.",
"worldedit.rotate.no-interpolation": "Note: Interpolation is not yet supported, so angles that are multiples of 90 is recommended.",
"worldedit.rotate.rotated": "The clipboard copy has been rotated.",
"worldedit.flip.flipped": "The clipboard copy has been flipped.",
"worldedit.clearclipboard.cleared": "Clipboard cleared.",
"worldedit.set.done": "Operation completed.",
"worldedit.set.done.verbose": "Operation completed ({0}).",
"worldedit.unstuck.moved": "There you go!",
"worldedit.ascend.obstructed": "No free spot above you found.",
"worldedit.ascend.moved.singular": "Ascended a level.",
"worldedit.ascend.moved.plural": "Ascended {0} levels.",
"worldedit.descend.obstructed": "No free spot below you found.",
"worldedit.descend.moved.singular": "Descended a level.",
"worldedit.descend.moved.plural": "Descended {0} levels.",
"worldedit.ceil.obstructed": "No free spot above you found.",
"worldedit.ceil.moved": "Woosh!",
"worldedit.thru.obstructed": "No free spot ahead of you found.",
"worldedit.thru.moved": "Woosh!",
"worldedit.jumpto.moved": "Poof!",
"worldedit.jumpto.none": "No block in sight (or too far away)!",
"worldedit.up.obstructed": "You would hit something above you.",
"worldedit.up.moved": "Woosh!",
"worldedit.reload.config": "Configuration reloaded!",
"worldedit.report.written": "WorldEdit report written to {0}",
"worldedit.report.error": "Failed to write report: {0}",
"worldedit.report.callback": "WorldEdit report: {0}.report",
"worldedit.timezone.invalid": "Invalid timezone",
"worldedit.timezone.set": "Timezone set for this session to: {0}",
"worldedit.timezone.current": "The current time in that timezone is: {0}",
"worldedit.version.version": "WorldEdit version {0}",
"worldedit.command.time-elapsed": "{0}s elapsed (history: {1} changed; {2} blocks/sec).",
"worldedit.pastebin.uploading": "(Please wait... sending output to pastebin...)",
"worldedit.session.cant-find-session": "Unable to find session for {0}",
"worldedit.tool.max-block-changes": "Max blocks change limit reached.",
"worldedit.tool.no-block": "No block in sight!",
"worldedit.tool.repl.equip": "Block replacer tool bound to {0}.",
"worldedit.tool.repl.switched": "Replacer tool switched to: {0}",
"worldedit.tool.data-cycler.equip": "Block data cycler tool bound to {0}.",
"worldedit.tool.data-cycler.block-not-permitted": "You are not permitted to cycle the data value of that block.",
"worldedit.tool.data-cycler.cant-cycle": "That block's data cannot be cycled!",
"worldedit.tool.data-cycler.new-value": "Value of {0} is now {1}.",
"worldedit.tool.data-cycler.cycling": "Now cycling {0}.",
"worldedit.tool.deltree.equip": "Floating tree remover tool bound to {0}.",
"worldedit.tool.deltree.not-tree": "That's not a tree.",
"worldedit.tool.deltree.not-floating": "That's not a floating tree.",
"worldedit.tool.tree.equip": "Tree tool bound to {0}.",
"worldedit.tool.tree.obstructed": "A tree can't go there.",
"worldedit.tool.info.equip": "Info tool bound to {0}.",
"worldedit.tool.info.blockstate.hover": "Block state",
"worldedit.tool.info.internalid.hover": "Internal ID",
"worldedit.tool.info.light.hover": "Block Light/Light Above",
"worldedit.tool.none.equip": "Tool unbound from your current item.",
"worldedit.tool.selwand.equip": "Selection wand bound to {0}.",
"worldedit.tool.navwand.equip": "Navigation wand bound to {0}.",
"worldedit.tool.floodfill.equip": "Block flood fill tool bound to {0}.",
"worldedit.tool.farwand.equip": "Far wand tool bound to {0}.",
"worldedit.tool.lrbuild.equip": "Long-range building tool bound to {0}.",
"worldedit.tool.lrbuild.set": "Left-click set to {0}; right-click set to {1}.",
"worldedit.superpickaxe.mode.single": "Mode is now single. Left click with a pickaxe. // to disable.",
"worldedit.superpickaxe.mode.area": "Mode is now area. Left click with a pickaxe. // to disable.",
"worldedit.superpickaxe.mode.recursive": "Mode is now recursive. Left click with a pickaxe. // to disable.",
"worldedit.superpickaxe.max-range": "Maximum range is {0}.",
"worldedit.operation.affected.biome.singular": "{0} biome affected",
"worldedit.operation.affected.biome.plural": "{0} biomes affected",
"worldedit.operation.affected.block.singular": "{0} block affected",
"worldedit.operation.affected.block.plural": "{0} blocks affected",
"worldedit.operation.affected.column.singular": "{0} column affected",
"worldedit.operation.affected.column.plural": "{0} columns affected",
"worldedit.operation.affected.entity.singular": "{0} entity affected",
"worldedit.operation.affected.entity.plural": "{0} entities affected",
"worldedit.operation.deform.expression": "deformed using {0}"
}

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.fabric.mixin.AccessorServerPlayerEntity;
import com.sk89q.worldedit.fabric.net.handler.WECUIPacketHandler;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.math.BlockVector3;
@ -56,6 +57,7 @@ import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Locale;
import java.util.UUID;
public class FabricPlayer extends AbstractPlayerActor {
@ -128,6 +130,11 @@ public class FabricPlayer extends AbstractPlayerActor {
this.player.networkHandler.sendPacket(packet);
}
@Override
public Locale getLocale() {
return Locale.forLanguageTag(((AccessorServerPlayerEntity) this.player).getClientLanguage().replace("_", "-"));
}
@Override
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
@ -152,7 +159,7 @@ public class FabricPlayer extends AbstractPlayerActor {
@Override
public void print(Component component) {
this.player.sendMessage(Text.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component))));
this.player.sendMessage(Text.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))));
}
private void sendColorized(String msg, Formatting formatting) {

View File

@ -0,0 +1,31 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.fabric.mixin;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ServerPlayerEntity.class)
public interface AccessorServerPlayerEntity {
@Accessor("clientLanguage")
String getClientLanguage();
}

View File

@ -27,6 +27,7 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

View File

@ -4,7 +4,8 @@
"compatibilityLevel": "JAVA_8",
"mixins": [
"MixinServerPlayerEntity",
"MixinMinecraftServer"
"MixinMinecraftServer",
"AccessorServerPlayerEntity"
],
"server": [
],

View File

@ -55,6 +55,7 @@ import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import java.io.IOException;
import java.util.Locale;
import java.util.UUID;
import javax.annotation.Nullable;
@ -153,7 +154,7 @@ public class ForgePlayer extends AbstractPlayerActor {
@Override
public void print(Component component) {
this.player.sendMessage(ITextComponent.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component))));
this.player.sendMessage(ITextComponent.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))));
}
private void sendColorized(String msg, TextFormatting formatting) {
@ -203,6 +204,11 @@ public class ForgePlayer extends AbstractPlayerActor {
}
}
@Override
public Locale getLocale() {
return Locale.forLanguageTag(player.language.replace('_', '-'));
}
@Override
public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) {
World world = getWorld();

View File

@ -1 +1,2 @@
public net.minecraft.server.MinecraftServer field_211151_aa # serverTime
public net.minecraft.server.MinecraftServer field_211151_aa # serverTime
public net.minecraft.entity.player.ServerPlayerEntity field_71148_cg # language

View File

@ -54,17 +54,17 @@ public abstract class CommandAdapter implements CommandCallable {
@Override
public Optional<Text> getShortDescription(CommandSource source) {
return Optional.of(command.getDescription())
.map(SpongeTextAdapter::convert);
.map(desc -> SpongeTextAdapter.convert(desc, source.getLocale()));
}
@Override
public Optional<Text> getHelp(CommandSource source) {
return Optional.of(command.getFullHelp())
.map(SpongeTextAdapter::convert);
.map(help -> SpongeTextAdapter.convert(help, source.getLocale()));
}
@Override
public Text getUsage(CommandSource source) {
return convert(command.getUsage());
return convert(command.getUsage(), source.getLocale());
}
}

View File

@ -37,6 +37,7 @@ import org.spongepowered.api.text.format.TextColors;
import org.spongepowered.api.text.serializer.TextSerializers;
import java.io.File;
import java.util.Locale;
import java.util.UUID;
import javax.annotation.Nullable;
@ -94,7 +95,7 @@ public class SpongeCommandSender implements Actor {
@Override
public void print(Component component) {
TextAdapter.sendComponent(sender, WorldEditText.format(component));
TextAdapter.sendComponent(sender, WorldEditText.format(component, getLocale()));
}
private void sendColorized(String msg, TextColor formatting) {
@ -141,6 +142,11 @@ public class SpongeCommandSender implements Actor {
public void dispatchCUIEvent(CUIEvent event) {
}
@Override
public Locale getLocale() {
return Locale.US;
}
@Override
public SessionKey getSessionKey() {
return new SessionKey() {

View File

@ -51,6 +51,7 @@ import org.spongepowered.api.text.serializer.TextSerializers;
import org.spongepowered.api.world.World;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Optional;
import java.util.UUID;
@ -154,7 +155,7 @@ public class SpongePlayer extends AbstractPlayerActor {
@Override
public void print(Component component) {
TextAdapter.sendComponent(player, WorldEditText.format(component));
TextAdapter.sendComponent(player, WorldEditText.format(component, getLocale()));
}
private void sendColorized(String msg, TextColor formatting) {
@ -231,6 +232,11 @@ public class SpongePlayer extends AbstractPlayerActor {
}
}
@Override
public Locale getLocale() {
return player.getLocale();
}
@Override
public SessionKey getSessionKey() {
return new SessionKeyImpl(player.getUniqueId(), player.getName());

View File

@ -25,10 +25,12 @@ import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSer
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.serializer.TextSerializers;
import java.util.Locale;
public class SpongeTextAdapter {
public static Text convert(Component component) {
component = WorldEditText.format(component);
public static Text convert(Component component, Locale locale) {
component = WorldEditText.format(component, locale);
return TextSerializers.JSON.deserialize(GsonComponentSerializer.INSTANCE.serialize(component));
}