geforkt von Mirrors/FastAsyncWorldEdit
Use pagination for //distr and store results. (#496)
Dieser Commit ist enthalten in:
Ursprung
a2b3aabbbf
Commit
508ece9e0f
@ -47,16 +47,20 @@ import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
|||||||
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
|
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
import com.sk89q.worldedit.session.request.Request;
|
||||||
|
import com.sk89q.worldedit.util.Countable;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
import com.sk89q.worldedit.world.snapshot.Snapshot;
|
import com.sk89q.worldedit.world.snapshot.Snapshot;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@ -95,6 +99,7 @@ public class LocalSession {
|
|||||||
private transient ZoneId timezone = ZoneId.systemDefault();
|
private transient ZoneId timezone = ZoneId.systemDefault();
|
||||||
private transient BlockVector3 cuiTemporaryBlock;
|
private transient BlockVector3 cuiTemporaryBlock;
|
||||||
private transient EditSession.ReorderMode reorderMode = EditSession.ReorderMode.MULTI_STAGE;
|
private transient EditSession.ReorderMode reorderMode = EditSession.ReorderMode.MULTI_STAGE;
|
||||||
|
private transient List<Countable<BlockState>> lastDistribution;
|
||||||
|
|
||||||
// Saved properties
|
// Saved properties
|
||||||
private String lastScript;
|
private String lastScript;
|
||||||
@ -973,4 +978,20 @@ public class LocalSession {
|
|||||||
public String getNavWandItem() {
|
public String getNavWandItem() {
|
||||||
return navWandItem;
|
return navWandItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the last block distribution stored in this session.
|
||||||
|
*
|
||||||
|
* @return block distribution or {@code null}
|
||||||
|
*/
|
||||||
|
public List<Countable<BlockState>> getLastDistribution() {
|
||||||
|
return lastDistribution == null ? null : Collections.unmodifiableList(lastDistribution);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a block distribution in this session.
|
||||||
|
*/
|
||||||
|
public void setLastDistribution(List<Countable<BlockState>> dist) {
|
||||||
|
lastDistribution = dist;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ import com.sk89q.worldedit.command.tool.SelectionWand;
|
|||||||
import com.sk89q.worldedit.command.util.CommandPermissions;
|
import com.sk89q.worldedit.command.util.CommandPermissions;
|
||||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||||
import com.sk89q.worldedit.command.util.Logging;
|
import com.sk89q.worldedit.command.util.Logging;
|
||||||
|
import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
|
||||||
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
|
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.function.block.BlockDistributionCounter;
|
import com.sk89q.worldedit.function.block.BlockDistributionCounter;
|
||||||
@ -56,14 +56,15 @@ import com.sk89q.worldedit.regions.selector.SphereRegionSelector;
|
|||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.Countable;
|
import com.sk89q.worldedit.util.Countable;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.util.formatting.component.BlockDistributionResult;
|
||||||
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
||||||
|
import com.sk89q.worldedit.util.formatting.component.PaginationBox;
|
||||||
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
|
||||||
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
|
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
||||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||||
@ -71,11 +72,11 @@ import com.sk89q.worldedit.world.storage.ChunkStore;
|
|||||||
import org.enginehub.piston.annotation.Command;
|
import org.enginehub.piston.annotation.Command;
|
||||||
import org.enginehub.piston.annotation.CommandContainer;
|
import org.enginehub.piston.annotation.CommandContainer;
|
||||||
import org.enginehub.piston.annotation.param.Arg;
|
import org.enginehub.piston.annotation.param.Arg;
|
||||||
|
import org.enginehub.piston.annotation.param.ArgFlag;
|
||||||
import org.enginehub.piston.annotation.param.Switch;
|
import org.enginehub.piston.annotation.param.Switch;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION;
|
import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION;
|
||||||
@ -468,13 +469,16 @@ public class SelectionCommands {
|
|||||||
desc = "Get the distribution of blocks in the selection"
|
desc = "Get the distribution of blocks in the selection"
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.analysis.distr")
|
@CommandPermissions("worldedit.analysis.distr")
|
||||||
public void distr(Player player, LocalSession session, EditSession editSession,
|
public void distr(Player player, LocalSession session,
|
||||||
@Switch(name = 'c', desc = "Get the distribution of the clipboard instead")
|
@Switch(name = 'c', desc = "Get the distribution of the clipboard instead")
|
||||||
boolean clipboardDistr,
|
boolean clipboardDistr,
|
||||||
@Switch(name = 'd', desc = "Separate blocks by state")
|
@Switch(name = 'd', desc = "Separate blocks by state")
|
||||||
boolean separateStates) throws WorldEditException {
|
boolean separateStates,
|
||||||
|
@ArgFlag(name = 'p', desc = "Gets page from a previous distribution.", def = "")
|
||||||
|
Integer page) throws WorldEditException {
|
||||||
List<Countable<BlockState>> distribution;
|
List<Countable<BlockState>> distribution;
|
||||||
|
|
||||||
|
if (page == null) {
|
||||||
if (clipboardDistr) {
|
if (clipboardDistr) {
|
||||||
Clipboard clipboard = session.getClipboard().getClipboard(); // throws if missing
|
Clipboard clipboard = session.getClipboard().getClipboard(); // throws if missing
|
||||||
BlockDistributionCounter count = new BlockDistributionCounter(clipboard, separateStates);
|
BlockDistributionCounter count = new BlockDistributionCounter(clipboard, separateStates);
|
||||||
@ -482,36 +486,28 @@ public class SelectionCommands {
|
|||||||
Operations.completeBlindly(visitor);
|
Operations.completeBlindly(visitor);
|
||||||
distribution = count.getDistribution();
|
distribution = count.getDistribution();
|
||||||
} else {
|
} else {
|
||||||
|
try (EditSession editSession = session.createEditSession(player)) {
|
||||||
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()), separateStates);
|
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()), separateStates);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
session.setLastDistribution(distribution);
|
||||||
|
page = 1;
|
||||||
|
} else {
|
||||||
|
distribution = session.getLastDistribution();
|
||||||
|
if (distribution == null) {
|
||||||
|
player.printError("No previous distribution.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (distribution.isEmpty()) { // *Should* always be false
|
if (distribution.isEmpty()) { // *Should* always be false
|
||||||
player.printError("No blocks counted.");
|
player.printError("No blocks counted.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: doing things like region.getArea is inaccurate for non-cuboids.
|
final int finalPage = page;
|
||||||
int size = distribution.stream().mapToInt(Countable::getAmount).sum();
|
WorldEditAsyncCommandBuilder.createAndSendMessage(player,
|
||||||
player.print("# total blocks: " + size);
|
() -> new BlockDistributionResult(distribution, separateStates).create(finalPage), null);
|
||||||
|
|
||||||
for (Countable<BlockState> c : distribution) {
|
|
||||||
String name = c.getID().getBlockType().getName();
|
|
||||||
String str;
|
|
||||||
if (separateStates) {
|
|
||||||
str = String.format("%-7s (%.3f%%) %s (%s)",
|
|
||||||
String.valueOf(c.getAmount()),
|
|
||||||
c.getAmount() / (double) size * 100,
|
|
||||||
name,
|
|
||||||
c.getID().getAsString());
|
|
||||||
} else {
|
|
||||||
str = String.format("%-7s (%.3f%%) %s (%s)",
|
|
||||||
String.valueOf(c.getAmount()),
|
|
||||||
c.getAmount() / (double) size * 100,
|
|
||||||
name,
|
|
||||||
c.getID().getBlockType().getId());
|
|
||||||
}
|
|
||||||
player.print(str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.google.common.base.Strings;
|
||||||
|
import com.sk89q.worldedit.util.Countable;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlockDistributionResult extends PaginationBox {
|
||||||
|
|
||||||
|
private final List<Countable<BlockState>> distribution;
|
||||||
|
private final int totalBlocks;
|
||||||
|
private final boolean separateStates;
|
||||||
|
|
||||||
|
public BlockDistributionResult(List<Countable<BlockState>> distribution, boolean separateStates) {
|
||||||
|
super("Block Distribution", "//distr -p %page%" + (separateStates ? " -d" : ""));
|
||||||
|
this.distribution = distribution;
|
||||||
|
// note: doing things like region.getArea is inaccurate for non-cuboids.
|
||||||
|
this.totalBlocks = distribution.stream().mapToInt(Countable::getAmount).sum();
|
||||||
|
this.separateStates = separateStates;
|
||||||
|
setComponentsPerPage(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent(int number) {
|
||||||
|
Countable<BlockState> c = distribution.get(number);
|
||||||
|
TextComponent.Builder line = TextComponent.builder();
|
||||||
|
|
||||||
|
final int count = c.getAmount();
|
||||||
|
|
||||||
|
final double perc = count / (double) totalBlocks * 100;
|
||||||
|
final int maxDigits = (int) (Math.log10(totalBlocks) + 1);
|
||||||
|
final int curDigits = (int) (Math.log10(count) + 1);
|
||||||
|
line.append(String.format("%s%.3f%% ", perc < 10 ? " " : "", perc), TextColor.GOLD);
|
||||||
|
final int space = maxDigits - curDigits;
|
||||||
|
String pad = Strings.repeat(" ", space == 0 ? 2 : 2 * space + 1);
|
||||||
|
line.append(String.format("%s%s", count, pad), TextColor.YELLOW);
|
||||||
|
|
||||||
|
final BlockState state = c.getID();
|
||||||
|
final BlockType blockType = state.getBlockType();
|
||||||
|
TextComponent blockName = TextComponent.of(blockType.getName(), TextColor.LIGHT_PURPLE);
|
||||||
|
TextComponent toolTip;
|
||||||
|
if (separateStates && state != blockType.getDefaultState()) {
|
||||||
|
toolTip = TextComponent.of(state.getAsString(), TextColor.GRAY);
|
||||||
|
blockName = blockName.append(TextComponent.of("*", TextColor.LIGHT_PURPLE));
|
||||||
|
} else {
|
||||||
|
toolTip = TextComponent.of(blockType.getId(), TextColor.GRAY);
|
||||||
|
}
|
||||||
|
blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip));
|
||||||
|
line.append(blockName);
|
||||||
|
|
||||||
|
return line.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComponentsSize() {
|
||||||
|
return distribution.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component create(int page) throws InvalidComponentException {
|
||||||
|
super.getContents().append(TextComponent.of("Total Block Count: " + totalBlocks, TextColor.GRAY))
|
||||||
|
.append(TextComponent.newline());
|
||||||
|
return super.create(page);
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren