Commits vergleichen

...

20 Commits
main ... fabric

Autor SHA1 Nachricht Datum
Aurora
6bea77933f
add DefaultAllowedDataCycleBlocks to prevent NPE 2020-09-26 14:55:46 +02:00
Aurora
4511884bca
comment out block registry because thats making sense i guess? 2020-09-26 12:59:04 +02:00
Aurora
aceb7ed0b5
update loom 2020-09-26 12:58:41 +02:00
Aurora
4f08cfa71a
Remove doctools again 2020-09-26 10:30:06 +02:00
Aurora
a7af79bd76
Fix compiling
Co-authored-by: zml2008
2020-09-26 09:47:14 +02:00
Aurora
3d98eef205
continue working on fabric module 2020-09-25 22:49:12 +02:00
wizjany
9ca2d28648 Add fungi and chorus plant tree types.
Closes #1411.
2020-09-25 21:08:25 +02:00
Aurora
117f848ec4
starting work on Fabric 2020-09-25 21:06:04 +02:00
Aurora
0be054f714 Merge branch 'main' of https://github.com/IntellectualSites/FastAsyncWorldEdit into fabric 2020-09-25 20:33:15 +02:00
Octavia Togami
461a0689ab Reject empty split array in block parser
Fixes #1521.
2020-09-23 19:19:28 +02:00
Octavia Togami
95640fe44f [Fabric, Forge] Update build files for 1.16.3
No actual changes, beta 4 is functional, but this was to ensure it
compiled.
2020-09-23 19:16:35 +02:00
Aurora
13b89900ab Merge branch 'main' of https://github.com/aurorasmiles/FastAsyncWorldEdit into main 2020-09-23 19:05:26 +02:00
wea_ondara
425c875c56 Merge remote-tracking branch 'upsteam/main' into main 2020-09-23 17:49:47 +02:00
dordsor21
ab0c5e2db7 Squash errors and debug to aid fixing #652 properly 2020-09-23 17:49:02 +02:00
dordsor21
0f0aa5c3ec Fix #647 2020-09-23 17:49:02 +02:00
Aurora
b5492f3ffa Fix toggle permission (#644)
* Fixes #529
* fix superperms perm toggling

Co-authored-by: @weaondara <wea_ondara@alpenblock.net>
2020-09-23 17:49:02 +02:00
Aurora
05ffff65d0 Fix entity rotation (#642)
* fix entity rotation
fixes #577 
Co-authored-by: wea_ondara <wea_ondara@alpenblock.net>
2020-09-23 17:49:02 +02:00
Aurora
b796b7dc75 Merge branch 'main' of https://github.com/IntellectualSites/FastAsyncWorldEdit into main 2020-09-21 16:20:24 +02:00
Aurora
f55aded50b Merge branch 'main' of https://github.com/IntellectualSites/FastAsyncWorldEdit into main 2020-09-20 15:36:22 +02:00
Aurora
58daec9cd4
Update the issue template 2020-09-20 11:54:20 +02:00
41 geänderte Dateien mit 997 neuen und 710 gelöschten Zeilen

Datei anzeigen

@ -52,11 +52,11 @@ dependencies {
implementation("com.github.jengelman.gradle.plugins:shadow:5.2.0")
implementation("net.ltgt.apt-eclipse:net.ltgt.apt-eclipse.gradle.plugin:0.21")
implementation("net.ltgt.apt-idea:net.ltgt.apt-idea.gradle.plugin:0.21")
//implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.16.0")
//implementation("gradle.plugin.org.spongepowered:spongegradle:0.9.0")
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.16.0")
implementation("gradle.plugin.org.spongepowered:spongegradle:0.9.0")
//implementation("net.minecraftforge.gradle:ForgeGradle:3.0.181")
//implementation("net.fabricmc:fabric-loom:$loomVersion")
//implementation("net.fabricmc:sponge-mixin:$mixinVersion")
implementation("net.fabricmc:fabric-loom:$loomVersion")
implementation("net.fabricmc:sponge-mixin:$mixinVersion")
implementation("gradle.plugin.com.mendhak.gradlecrowdin:plugin:0.1.0")
implementation("org.enginehub.gradle:gradle-codecov-plugin:0.1.0")
}

Datei anzeigen

@ -126,6 +126,18 @@ fun Project.applyShadowConfiguration() {
}
}
fun Project.addJarManifest(includeClasspath: Boolean = false) {
tasks.named<Jar>("jar") {
val attributes = mutableMapOf(
"WorldEdit-Version" to project(":worldedit-core").version
)
if (includeClasspath) {
attributes["Class-Path"] = CLASSPATH
}
manifest.attributes(attributes)
}
}
val CLASSPATH = listOf("truezip", "truevfs", "js")
.map { "$it.jar" }
.flatMap { listOf(it, "WorldEdit/$it") }

Datei anzeigen

@ -7,5 +7,5 @@ org.gradle.configureondemand=true
org.gradle.parallel=true
org.gradle.caching=true
loom.version=0.2.6-20200124.104118-60
mixin.version=0.8+build.17
loom.version=0.5.9
mixin.version=0.8.1+build.21

Datei anzeigen

@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit"
include("worldedit-libs")
listOf("bukkit", "core").forEach {
listOf("bukkit", "core", "fabric").forEach {
include("worldedit-libs:$it")
include("worldedit-$it")
}

Datei anzeigen

@ -342,6 +342,9 @@ public class BukkitWorld extends AbstractWorld {
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
World world = getWorld();
TreeType bukkitType = toBukkitTreeType(type);
if (bukkitType == TreeType.CHORUS_PLANT) {
pt = pt.add(0, 1, 0); // bukkit skips the feature gen which does this offset normally, so we have to add it back
}
return type != null && world.generateTree(BukkitAdapter.adapt(world, pt), bukkitType,
new EditSessionBlockChangeDelegate(editSession));
}

Datei anzeigen

@ -56,6 +56,7 @@ public abstract class LocalConfiguration {
public boolean profile = false;
public boolean traceUnflushedSessions = false;
public Set<String> disallowedBlocks = new HashSet<>();
public Set<String> defaultAllowedDataCycleBlocks = new HashSet<>();
protected BlockMask disallowedBlocksMask;
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;
@ -168,6 +169,10 @@ public abstract class LocalConfiguration {
return blockTypes.stream().filter(Objects::nonNull).map(BlockType::getId).toArray(String[]::new);
}
protected String[] getDefaultAllowedDataCycleBlocks() {
return new String[0];
}
/**
* Load the configuration.
*/

Datei anzeigen

@ -19,18 +19,11 @@
package com.sk89q.worldedit.extension.factory.parser;
import com.boydti.fawe.config.Caption;
import com.boydti.fawe.jnbt.JSON2NBT;
import com.boydti.fawe.jnbt.NBTException;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.StringMan;
import com.google.common.collect.Maps;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.SignBlock;
import com.sk89q.worldedit.blocks.SkullBlock;
@ -42,17 +35,16 @@ import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.SlottableBlockBag;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.internal.util.DeprecationUtil;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.HandSide;
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.BaseBlock;
import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.FuzzyBlockState;
@ -60,7 +52,6 @@ import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@ -80,12 +71,15 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
try {
return ((Player) actor).getBlockInHand(handSide);
} catch (NotABlockException e) {
throw new InputParseException("You're not holding a block!");
throw new InputParseException(e.getRichMessage());
} catch (WorldEditException e) {
throw new InputParseException("Unknown error occurred: " + e.getMessage(), e);
throw new InputParseException(TranslatableComponent.of("worldedit.error.unknown", e.getRichMessage()), e);
}
} else {
throw new InputParseException("The user is not a player!");
throw new InputParseException(TranslatableComponent.of(
"worldedit.error.parser.player-only",
TextComponent.of(handSide == HandSide.MAIN_HAND ? "hand" : "offhand")
));
}
}
@ -113,7 +107,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
}
}
private static String[] EMPTY_STRING_ARRAY = {};
private static final String[] EMPTY_STRING_ARRAY = {};
/**
* Backwards compatibility for wool colours in block syntax.
@ -166,7 +160,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
}
}
private static Map<Property<?>, Object> parseProperties(BlockType type, String[] stateProperties, ParserContext context) throws NoMatchException {
private static Map<Property<?>, Object> parseProperties(BlockType type, String[] stateProperties, ParserContext context) throws InputParseException {
Map<Property<?>, Object> blockStates = new HashMap<>();
if (stateProperties.length > 0) { // Block data not yet detected
@ -175,35 +169,51 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
try {
String[] parts = parseableData.split("=");
if (parts.length != 2) {
throw new NoMatchException("Bad state format in " + parseableData);
throw new InputParseException(
TranslatableComponent.of("worldedit.error.parser.bad-state-format",
TextComponent.of(parseableData))
);
}
@SuppressWarnings("unchecked")
Property<Object> propertyKey = (Property<Object>) type.getPropertyMap().get(parts[0]);
if (propertyKey == null) {
if (context.getActor() != null) {
throw new NoMatchException("Unknown property " + parts[0] + " for block " + type.getId());
throw new NoMatchException(TranslatableComponent.of(
"worldedit.error.parser.unknown-property",
TextComponent.of(parts[0]),
TextComponent.of(type.getId())
));
} else {
WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.getId());
}
return Maps.newHashMap();
}
if (blockStates.containsKey(propertyKey)) {
throw new NoMatchException("Duplicate property " + parts[0]);
throw new InputParseException(TranslatableComponent.of(
"worldedit.error.parser.duplicate-property",
TextComponent.of(parts[0])
));
}
Object value;
try {
value = propertyKey.getValueFor(parts[1]);
} catch (IllegalArgumentException e) {
throw new NoMatchException("Unknown value " + parts[1] + " for state " + parts[0]);
throw new NoMatchException(TranslatableComponent.of(
"worldedit.error.parser.unknown-value",
TextComponent.of(parts[1]),
TextComponent.of(propertyKey.getName())
));
}
blockStates.put(propertyKey, value);
} catch (NoMatchException e) {
} catch (InputParseException e) {
throw e; // Pass-through
} catch (Exception e) {
WorldEdit.logger.warn("Unknown state '" + parseableData + "'", e);
throw new NoMatchException("Unknown state '" + parseableData + "'");
throw new InputParseException(TranslatableComponent.of(
"worldedit.error.parser.bad-state-format",
TextComponent.of(parseableData)
));
}
}
}
@ -232,9 +242,13 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
}
private BaseBlock parseLogic(String input, ParserContext context) throws InputParseException {
String[] blockAndExtraData = input.trim().split("\\|", 2);
blockAndExtraData[0] = woolMapper(blockAndExtraData[0]);
BlockType blockType = null;
Map<Property<?>, Object> blockStates = new HashMap<>();
String[] blockAndExtraData = input.trim().split("\\|");
if (blockAndExtraData.length == 0) {
throw new NoMatchException(TranslatableComponent.of("worldedit.error.unknown-block", TextComponent.of(input)));
}
blockAndExtraData[0] = woolMapper(blockAndExtraData[0]);
BlockState state = null;
@ -243,31 +257,19 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
try {
String[] split = blockAndExtraData[0].split(":", 2);
if (split.length == 0) {
throw new InputParseException("Invalid colon.");
throw new InputParseException(TranslatableComponent.of("worldedit.error.parser.invalid-colon"));
} else if (split.length == 1) {
state = LegacyMapper.getInstance().getBlockFromLegacy(Integer.parseInt(split[0]));
} else if (MathMan.isInteger(split[0])) {
int id = Integer.parseInt(split[0]);
int data = Integer.parseInt(split[1]);
if (data < 0 || data >= 16) {
throw new InputParseException("Invalid data " + data);
}
state = LegacyMapper.getInstance().getBlockFromLegacy(id, data);
} else {
BlockType type = BlockTypes.get(split[0].toLowerCase(Locale.ROOT));
if (type != null) {
int data = Integer.parseInt(split[1]);
if (data < 0 || data >= 16) {
throw new InputParseException("Invalid data " + data);
}
state = LegacyMapper.getInstance().getBlockFromLegacy(type.getLegacyCombinedId() >> 4, data);
state = LegacyMapper.getInstance().getBlockFromLegacy(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
}
if (state != null) {
blockType = state.getBlockType();
}
} catch (NumberFormatException ignored) {
}
}
CompoundTag nbt = null;
if (state == null) {
String typeString;
String stateString = null;
@ -277,91 +279,79 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
} else {
typeString = blockAndExtraData[0].substring(0, stateStart);
if (stateStart + 1 >= blockAndExtraData[0].length()) {
throw new InputParseException("Invalid format. Hanging bracket @ " + stateStart + ".");
throw new InputParseException(TranslatableComponent.of("worldedit.error.parser.hanging-lbracket", TextComponent.of(stateStart)));
}
int stateEnd = blockAndExtraData[0].lastIndexOf(']');
if (stateEnd < 0) {
throw new InputParseException("Invalid format. Unclosed property.");
throw new InputParseException(TranslatableComponent.of("worldedit.error.parser.missing-rbracket"));
}
stateString = blockAndExtraData[0].substring(stateStart + 1, blockAndExtraData[0].length() - 1);
}
if (typeString.isEmpty()) {
throw new InputParseException(TranslatableComponent.of(
"worldedit.error.parser.bad-state-format",
TextComponent.of(blockAndExtraData[0])
));
}
String[] stateProperties = EMPTY_STRING_ARRAY;
if(stateString != null) {
if (stateString != null) {
stateProperties = stateString.split(",");
}
if (typeString.isEmpty()) {
throw new InputParseException("Invalid format");
}
if ("hand".equalsIgnoreCase(typeString)) {
// Get the block type from the item in the user's hand.
final BaseBlock blockInHand = getBlockInHand(context.requireActor(), HandSide.MAIN_HAND);
state = blockInHand.toBlockState();
nbt = blockInHand.getNbtData();
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
blockType = blockInHand.getBlockType();
blockStates.putAll(blockInHand.getStates());
} else if ("offhand".equalsIgnoreCase(typeString)) {
// Get the block type from the item in the user's off hand.
final BaseBlock blockInHand = getBlockInHand(context.requireActor(), HandSide.OFF_HAND);
state = blockInHand.toBlockState();
nbt = blockInHand.getNbtData();
} else if (typeString.matches("pos[0-9]+")) {
int index = Integer.parseInt(typeString.replaceAll("[a-z]+", ""));
if (blockInHand.getClass() != BaseBlock.class) {
return blockInHand;
}
blockType = blockInHand.getBlockType();
blockStates.putAll(blockInHand.getStates());
} else if ("pos1".equalsIgnoreCase(typeString)) {
// Get the block type from the "primary position"
final World world = context.requireWorld();
final BlockVector3 primaryPosition;
try {
primaryPosition = context.requireSession().getRegionSelector(world).getVertices().get(index - 1);
primaryPosition = context.requireSession().getRegionSelector(world).getPrimaryPosition();
} catch (IncompleteRegionException e) {
throw new InputParseException("Your selection is not complete.");
throw new InputParseException(TranslatableComponent.of("worldedit.error.incomplete-region"));
}
state = world.getBlock(primaryPosition);
} else if (typeString.matches("slot[0-9]+")) {
int slot = Integer.parseInt(typeString.substring(4)) - 1;
Actor actor = context.requireActor();
if (!(actor instanceof Player)) {
throw new InputParseException("The user is not a player!");
}
Player player = (Player) actor;
BlockBag bag = player.getInventoryBlockBag();
if (!(bag instanceof SlottableBlockBag)) {
throw new InputParseException("Unsupported!");
}
SlottableBlockBag slottable = (SlottableBlockBag) bag;
BaseItem item = slottable.getItem(slot);
final BlockState blockInHand = world.getBlock(primaryPosition);
if (!item.getType().hasBlockType()) {
throw new InputParseException("You're not holding a block!");
}
state = item.getType().getBlockType().getDefaultState();
nbt = item.getNbtData();
blockType = blockInHand.getBlockType();
blockStates.putAll(blockInHand.getStates());
} else {
BlockType type = BlockTypes.parse(typeString.toLowerCase(Locale.ROOT));
if (type != null) {
state = type.getDefaultState();
}
if (state == null) {
throw new NoMatchException(
"Does not match a valid block type: '" + input + "'");
}
}
if (nbt == null) {
nbt = state.getNbtData();
// Attempt to lookup a block from ID or name.
blockType = BlockTypes.get(typeString.toLowerCase(Locale.ROOT));
}
blockStates.putAll(parseProperties(state.getBlockType(), stateProperties, context));
if (blockType == null) {
throw new NoMatchException(TranslatableComponent.of("worldedit.error.unknown-block", TextComponent.of(input)));
}
blockStates.putAll(parseProperties(blockType, stateProperties, context));
if (context.isPreferringWildcard()) {
if (stateString == null || stateString.isEmpty()) {
state = new FuzzyBlockState(state);
} else {
FuzzyBlockState.Builder fuzzyBuilder = FuzzyBlockState.builder();
fuzzyBuilder.type(state.getBlockType());
fuzzyBuilder.type(blockType);
for (Map.Entry<Property<?>, Object> blockState : blockStates.entrySet()) {
@SuppressWarnings("unchecked")
Property<Object> objProp = (Property<Object>) blockState.getKey();
fuzzyBuilder.withProperty(objProp, blockState.getValue());
}
state = fuzzyBuilder.build();
}
} else {
// No wildcards allowed => eliminate them. (Start with default state)
state = blockType.getDefaultState();
for (Map.Entry<Property<?>, Object> blockState : blockStates.entrySet()) {
@SuppressWarnings("unchecked")
Property<Object> objProp = (Property<Object>) blockState.getKey();
@ -370,87 +360,60 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
}
}
// this should be impossible but IntelliJ isn't that smart
if (state == null) {
throw new NoMatchException("Does not match a valid block type: '" + input + "'");
}
if (blockAndExtraData.length > 1 && blockAndExtraData[1].startsWith("{")) {
String joined = StringMan.join(Arrays.copyOfRange(blockAndExtraData, 1, blockAndExtraData.length), "|");
try {
nbt = JSON2NBT.getTagFromJson(joined);
} catch (NBTException e) {
throw new NoMatchException(e.getMessage());
}
if (blockType == null) {
throw new NoMatchException(TranslatableComponent.of("worldedit.error.unknown-block", TextComponent.of(input)));
}
// Check if the item is allowed
BlockType blockType = state.getBlockType();
if (context.isRestricted()) {
Actor actor = context.requireActor();
if (actor != null && !actor.hasPermission("worldedit.anyblock")
&& worldEdit.getConfiguration().disallowedBlocks.contains(blockType.getId())) {
throw new DisallowedUsageException("You are not allowed to use '" + input + "'");
throw new DisallowedUsageException(TranslatableComponent.of("worldedit.error.disallowed-block", TextComponent.of(input)));
}
}
if (nbt != null) {
return validate(context, state.toBaseBlock(nbt));
if (!context.isTryingLegacy()) {
return state.toBaseBlock();
}
if (blockType == BlockTypes.SIGN || blockType == BlockTypes.WALL_SIGN
|| BlockCategories.SIGNS.contains(blockType)) {
if (DeprecationUtil.isSign(blockType)) {
// Allow special sign text syntax
String[] text = new String[4];
text[0] = blockAndExtraData.length > 1 ? blockAndExtraData[1] : "";
text[1] = blockAndExtraData.length > 2 ? blockAndExtraData[2] : "";
text[2] = blockAndExtraData.length > 3 ? blockAndExtraData[3] : "";
text[3] = blockAndExtraData.length > 4 ? blockAndExtraData[4] : "";
return validate(context, new SignBlock(state, text));
return new SignBlock(state, text);
} else if (blockType == BlockTypes.SPAWNER) {
// Allow setting mob spawn type
if (blockAndExtraData.length > 1) {
String mobName = blockAndExtraData[1];
EntityType ent = EntityTypes.get(mobName.toLowerCase(Locale.ROOT));
if (ent == null) {
throw new NoMatchException("Unknown entity type '" + mobName + "'");
throw new NoMatchException(TranslatableComponent.of("worldedit.error.unknown-entity", TextComponent.of(mobName)));
}
mobName = ent.getId();
if (!worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS).isValidMobType(mobName)) {
throw new NoMatchException("Unknown mob type '" + mobName + "'");
throw new NoMatchException(TranslatableComponent.of("worldedit.error.unknown-mob", TextComponent.of(mobName)));
}
return validate(context, new MobSpawnerBlock(state, mobName));
return new MobSpawnerBlock(state, mobName);
} else {
//noinspection ConstantConditions
return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.getId()));
return new MobSpawnerBlock(state, EntityTypes.PIG.getId());
}
} else if (blockType == BlockTypes.PLAYER_HEAD || blockType == BlockTypes.PLAYER_WALL_HEAD) {
// allow setting type/player/rotation
if (blockAndExtraData.length <= 1) {
return validate(context, new SkullBlock(state));
return new SkullBlock(state);
}
String type = blockAndExtraData[1];
return validate(context, new SkullBlock(state, type.replace(" ", "_"))); // valid MC usernames
return new SkullBlock(state, type.replace(" ", "_")); // valid MC usernames
} else {
return validate(context, state.toBaseBlock());
return state.toBaseBlock();
}
}
private <T extends BlockStateHolder> T validate(ParserContext context, T holder) {
if (context.isRestricted()) {
Actor actor = context.requireActor();
if (!actor.hasPermission("worldedit.anyblock") && worldEdit.getConfiguration().checkDisallowedBlocks(holder)) {
throw new DisallowedUsageException(Caption.toString(Caption.of("fawe.error.block.not.allowed", holder)));
}
CompoundTag nbt = holder.getNbtData();
if (nbt != null) {
if (!actor.hasPermission("worldedit.anyblock")) {
throw new DisallowedUsageException("You are not allowed to use nbt'");
}
}
}
return holder;
}
}

Datei anzeigen

@ -91,7 +91,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
disallowedBlocks = getStringSet("disallowed-blocks", getDefaultDisallowedBlocks());
disallowedBlocksMask = null;
allowedDataCycleBlocks =
new HashSet<>(getStringSet("limits.allowed-data-cycle-blocks", null));
new HashSet<>(getStringSet("limits.allowed-data-cycle-blocks", getDefaultAllowedDataCycleBlocks()));
defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit);
maxChangeLimit = getInt("max-changed-blocks", maxChangeLimit);
defaultVerticalHeight = getInt("default-vertical-height", defaultVerticalHeight);

Datei anzeigen

@ -40,7 +40,7 @@ import javax.annotation.Nullable;
/**
* Tree generator.
*/
public class TreeGenerator {
public final class TreeGenerator {
public enum TreeType {
TREE("Oak tree", "oak", "tree", "regular"),
@ -82,10 +82,12 @@ public class TreeGenerator {
JUNGLE_BUSH("Jungle bush", "junglebush", "jungleshrub"),
RED_MUSHROOM("Red mushroom", "redmushroom", "redgiantmushroom"),
BROWN_MUSHROOM("Brown mushroom", "brownmushroom", "browngiantmushroom"),
CRIMSON_FUNGUS("Crimson fungus", "crimsonfungus", "rednethermushroom"),
WARPED_FUNGUS("Warped fungus", "warpedfungus", "greennethermushroom"),
RANDOM_MUSHROOM("Random mushroom", "randmushroom", "randommushroom") {
@Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
TreeType[] choices = { RED_MUSHROOM, BROWN_MUSHROOM };
TreeType[] choices = { RED_MUSHROOM, BROWN_MUSHROOM, CRIMSON_FUNGUS, WARPED_FUNGUS };
return choices[TreeGenerator.RANDOM.nextInt(choices.length)].generate(editSession, pos);
}
},
@ -99,6 +101,13 @@ public class TreeGenerator {
return true;
}
},
CHORUS_PLANT("Chorus plant", "chorusplant") {
@Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {
// chorus plants have to generate starting in the end stone itself, not the air above the ground
return editSession.getWorld().generateTree(this, editSession, pos.subtract(0, 1, 0));
}
},
RANDOM("Random tree", "rand", "random") {
@Override
public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException {

Datei anzeigen

@ -1,15 +1,33 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import net.fabricmc.loom.LoomGradleExtension
import net.fabricmc.loom.task.RemapJarTask
buildscript {
repositories {
mavenCentral()
maven {
name = "Fabric"
url = uri("https://maven.fabricmc.net/")
}
}
dependencies {
classpath("net.fabricmc:fabric-loom:${versions.loom}")
}
}
applyPlatformAndCoreConfiguration()
applyShadowConfiguration()
apply(plugin = "fabric-loom")
apply(plugin = "java-library")
val minecraftVersion = "1.15.2"
val yarnMappings = "1.15.2+build.14:v2"
val loaderVersion = "0.7.8+build.189"
configure<LoomGradleExtension> {
accessWidener("src/main/resources/worldedit.accesswidener")
}
val minecraftVersion = "1.16.3"
val yarnMappings = "1.16.3+build.1:v2"
val loaderVersion = "0.9.3+build.207"
configurations.all {
resolutionStrategy {
@ -17,30 +35,74 @@ configurations.all {
}
}
val fabricApiConfiguration: Configuration = configurations.create("fabricApi")
repositories {
maven {
name = "Fabric"
url = uri("https://maven.fabricmc.net/")
}
}
dependencies {
"compile"(project(":worldedit-core"))
"compile"("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1")
"api"(project(":worldedit-core"))
"implementation"("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1")
"minecraft"("com.mojang:minecraft:$minecraftVersion")
"mappings"("net.fabricmc:yarn:$yarnMappings")
"modCompile"("net.fabricmc:fabric-loader:$loaderVersion")
"modImplementation"("net.fabricmc:fabric-loader:$loaderVersion")
listOf(
"net.fabricmc.fabric-api:fabric-api-base:0.1.2+28f8190f42",
"net.fabricmc.fabric-api:fabric-events-interaction-v0:0.2.6+12515ed975",
"net.fabricmc.fabric-api:fabric-events-lifecycle-v0:0.1.2+b7f9825de8",
"net.fabricmc.fabric-api:fabric-networking-v0:0.1.7+12515ed975"
).forEach {
// [1] declare fabric-api dependency...
"fabricApi"("net.fabricmc.fabric-api:fabric-api:0.20.2+build.402-1.16")
// [2] Load the API dependencies from the fabric mod json...
@Suppress("UNCHECKED_CAST")
val fabricModJson = file("src/main/resources/fabric.mod.json").bufferedReader().use {
groovy.json.JsonSlurper().parse(it) as Map<String, Map<String, *>>
}
val wantedDependencies = (fabricModJson["depends"] ?: error("no depends in fabric.mod.json")).keys
.filter { it == "fabric-api-base" || it.contains(Regex("v\\d$")) }
.map { "net.fabricmc.fabric-api:$it" }
logger.lifecycle("Looking for these dependencies:")
for (wantedDependency in wantedDependencies) {
logger.lifecycle(wantedDependency)
}
// [3] and now we resolve it to pick out what we want :D
val fabricApiDependencies = fabricApiConfiguration.incoming.resolutionResult.allDependencies
.onEach {
if (it is UnresolvedDependencyResult) {
throw kotlin.IllegalStateException("Failed to resolve Fabric API", it.failure)
}
}
.filterIsInstance<ResolvedDependencyResult>()
// pick out transitive dependencies
.flatMap {
it.selected.dependencies
}
// grab the requested versions
.map { it.requested }
.filterIsInstance<ModuleComponentSelector>()
// map to standard notation
.associateByTo(
mutableMapOf(),
keySelector = { "${it.group}:${it.module}" },
valueTransform = { "${it.group}:${it.module}:${it.version}" }
)
fabricApiDependencies.keys.retainAll(wantedDependencies)
// sanity check
for (wantedDep in wantedDependencies) {
check(wantedDep in fabricApiDependencies) { "Fabric API library $wantedDep is missing!" }
}
fabricApiDependencies.values.forEach {
"include"(it)
"modImplementation"(it)
}
// Hook these up manually, because Fabric doesn't seem to quite do it properly.
"compileClasspath"("net.fabricmc:sponge-mixin:${project.versions.mixin}")
"compileOnly"("net.fabricmc:sponge-mixin:${project.versions.mixin}")
"annotationProcessor"("net.fabricmc:sponge-mixin:${project.versions.mixin}")
"annotationProcessor"("net.fabricmc:fabric-loom:${project.versions.loom}")
"testCompile"("org.mockito:mockito-core:1.9.0-rc1")
}
configure<BasePluginConvention> {
@ -62,15 +124,10 @@ tasks.named<Copy>("processResources") {
}
}
tasks.named<Jar>("jar") {
manifest {
attributes("Class-Path" to CLASSPATH,
"WorldEdit-Version" to project.version)
}
}
addJarManifest(includeClasspath = true)
tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("dist-dev")
archiveFileName.set(archiveFileName.get().substringBeforeLast('.') + "-dev.jar")
dependencies {
relocate("org.slf4j", "com.sk89q.worldedit.slf4j")
relocate("org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge")
@ -97,6 +154,7 @@ tasks.register<RemapJarTask>("remapShadowJar") {
input.set(shadowJar.archiveFile)
archiveFileName.set(shadowJar.archiveFileName.get().replace(Regex("-dev\\.jar$"), ".jar"))
addNestedDependencies.set(true)
remapAccessWidener.set(true)
}
tasks.named("assemble").configure {

Datei anzeigen

@ -19,10 +19,6 @@
package com.sk89q.worldedit.fabric;
import static com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer;
import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;
import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
@ -50,6 +46,10 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import static com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer;
import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;
public final class CommandWrapper {
@ -60,8 +60,7 @@ public final class CommandWrapper {
ImmutableList.Builder<String> aliases = ImmutableList.builder();
aliases.add(command.getName()).addAll(command.getAliases());
Command<ServerCommandSource> commandRunner =
ctx -> {
Command<ServerCommandSource> commandRunner = ctx -> {
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
adaptPlayer(ctx.getSource().getPlayer()),
ctx.getInput()

Datei anzeigen

@ -19,8 +19,6 @@
package com.sk89q.worldedit.fabric;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableList;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
@ -45,8 +43,9 @@ import com.sk89q.worldedit.world.item.ItemTypes;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.state.StateFactory;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.DirectionProperty;
import net.minecraft.util.Identifier;
import net.minecraft.util.StringIdentifiable;
@ -57,11 +56,26 @@ import net.minecraft.world.biome.Biome;
import java.util.Comparator;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public final class FabricAdapter {
@Nullable
private static MinecraftServer server;
private static MinecraftServer requireServer() {
return Objects.requireNonNull(server, "No server injected");
}
static void setServer(@Nullable MinecraftServer server) {
FabricAdapter.server = server;
}
private FabricAdapter() {
}
@ -70,11 +84,16 @@ public final class FabricAdapter {
}
public static Biome adapt(BiomeType biomeType) {
return Registry.BIOME.get(new Identifier(biomeType.getId()));
return requireServer()
.getRegistryManager()
.get(Registry.BIOME_KEY)
.get(new Identifier(biomeType.getId()));
}
public static BiomeType adapt(Biome biome) {
return BiomeTypes.get(Registry.BIOME.getId(biome).toString());
Identifier id = requireServer().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
Objects.requireNonNull(id, "biome is not registered");
return BiomeTypes.get(id.toString());
}
public static Vector3 adapt(Vec3d vector) {
@ -102,7 +121,10 @@ public final class FabricAdapter {
}
}
public static Direction adaptEnumFacing(net.minecraft.util.math.Direction face) {
public static Direction adaptEnumFacing(@Nullable net.minecraft.util.math.Direction face) {
if (face == null) {
return null;
}
switch (face) {
case NORTH: return Direction.NORTH;
case SOUTH: return Direction.SOUTH;
@ -155,7 +177,8 @@ public final class FabricAdapter {
return props;
}
private static net.minecraft.block.BlockState applyProperties(StateFactory<Block, net.minecraft.block.BlockState> stateContainer,
@SuppressWarnings({ "unchecked", "rawtypes" })
private static net.minecraft.block.BlockState applyProperties(StateManager<Block, net.minecraft.block.BlockState> stateContainer,
net.minecraft.block.BlockState newState, Map<Property<?>, Object> states) {
for (Map.Entry<Property<?>, Object> state : states.entrySet()) {
net.minecraft.state.property.Property property = stateContainer.getProperty(state.getKey().getName());
@ -166,7 +189,7 @@ public final class FabricAdapter {
value = adapt(dir);
} else if (property instanceof net.minecraft.state.property.EnumProperty) {
String enumName = (String) value;
value = ((net.minecraft.state.property.EnumProperty<?>) property).getValue((String) value).orElseGet(() -> {
value = ((net.minecraft.state.property.EnumProperty<?>) property).parse((String) value).orElseGet(() -> {
throw new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName);
});
}
@ -180,7 +203,7 @@ public final class FabricAdapter {
Block mcBlock = adapt(blockState.getBlockType());
net.minecraft.block.BlockState newState = mcBlock.getDefaultState();
Map<Property<?>, Object> states = blockState.getStates();
return applyProperties(mcBlock.getStateFactory(), newState, states);
return applyProperties(mcBlock.getStateManager(), newState, states);
}
public static BlockState adapt(net.minecraft.block.BlockState blockState) {

Datei anzeigen

@ -19,39 +19,45 @@
package com.sk89q.worldedit.fabric;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.biome.BiomeData;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import net.minecraft.world.biome.Biome;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
/**
* Provides access to biome data in Fabric.
*/
class FabricBiomeRegistry implements BiomeRegistry {
@Deprecated
@Override
public BiomeData getData(BiomeType biome) {
return new FabricBiomeData(FabricAdapter.adapt(biome));
return new FabricBiomeData(biome);
}
/**
* Cached biome data information.
*/
@Deprecated
private static class FabricBiomeData implements BiomeData {
private final Biome biome;
private final BiomeType biome;
/**
* Create a new instance.
*
* @param biome the base biome
*/
private FabricBiomeData(Biome biome) {
private FabricBiomeData(BiomeType biome) {
this.biome = biome;
}
@SuppressWarnings("deprecation")
@Override
public String getName() {
return biome.getName().asFormattedString();
return biome.getId();
}
}

Datei anzeigen

@ -33,8 +33,11 @@ import java.util.stream.Collectors;
public class FabricBlockCategoryRegistry implements BlockCategoryRegistry {
@Override
public Set<BlockType> getCategorisedByName(String category) {
return Optional.ofNullable(BlockTags.getContainer().get(new Identifier(category)))
.map(Tag::values).orElse(Collections.emptySet())
.stream().map(FabricAdapter::adapt).collect(Collectors.toSet());
return Optional.ofNullable(BlockTags.getTagGroup().getTag(new Identifier(category)))
.map(Tag::values)
.orElse(Collections.emptyList())
.stream()
.map(FabricAdapter::adapt)
.collect(Collectors.toSet());
}
}

Datei anzeigen

@ -21,6 +21,7 @@ package com.sk89q.worldedit.fabric;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.PassthroughBlockMaterial;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.piston.PistonBehavior;
@ -34,10 +35,12 @@ import javax.annotation.Nullable;
public class FabricBlockMaterial extends PassthroughBlockMaterial {
private final Material delegate;
private final BlockState block;
public FabricBlockMaterial(Material delegate, @Nullable BlockMaterial secondary) {
public FabricBlockMaterial(Material delegate, BlockState block, @Nullable BlockMaterial secondary) {
super(secondary);
this.delegate = delegate;
this.block = block;
}
@Override
@ -82,7 +85,7 @@ public class FabricBlockMaterial extends PassthroughBlockMaterial {
@Override
public boolean isToolRequired() {
return !delegate.canBreakByHand();
return block.isToolRequired();
}
@Override

Datei anzeigen

@ -20,16 +20,13 @@
package com.sk89q.worldedit.fabric;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockRegistry;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.HashMap;
@ -39,24 +36,15 @@ import java.util.TreeMap;
public class FabricBlockRegistry extends BundledBlockRegistry {
private Map<Material, FabricBlockMaterial> materialMap = new HashMap<>();
@Nullable
@Override
public String getName(BlockType blockType) {
Block block = FabricAdapter.adapt(blockType);
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
return block.getName().asFormattedString();
} else {
return super.getName(blockType);
}
}
private final Map<net.minecraft.block.BlockState, FabricBlockMaterial> materialMap = new HashMap<>();
@Override
public BlockMaterial getMaterial(BlockType blockType) {
Block block = FabricAdapter.adapt(blockType);
return materialMap.computeIfAbsent(block.getDefaultState().getMaterial(),
m -> new FabricBlockMaterial(m, super.getMaterial(blockType)));
return materialMap.computeIfAbsent(
block.getDefaultState(),
m -> new FabricBlockMaterial(m.getMaterial(), m, super.getMaterial(blockType))
);
}
@Override

Datei anzeigen

@ -21,7 +21,7 @@ package com.sk89q.worldedit.fabric;
import com.sk89q.worldedit.util.PropertiesConfiguration;
import java.io.File;
import java.nio.file.Path;
public class FabricConfiguration extends PropertiesConfiguration {
@ -29,7 +29,7 @@ public class FabricConfiguration extends PropertiesConfiguration {
public boolean cheatMode = false;
public FabricConfiguration(FabricWorldEdit mod) {
super(new File(mod.getWorkingDir(), "worldedit.properties"));
super(mod.getWorkingDir().resolve("worldedit.properties"));
}
@Override
@ -39,7 +39,7 @@ public class FabricConfiguration extends PropertiesConfiguration {
}
@Override
public File getWorkingDirectory() {
public Path getWorkingDirectoryPath() {
return FabricWorldEdit.inst.getWorkingDir();
}
}

Datei anzeigen

@ -33,18 +33,19 @@ import com.google.gson.JsonParseException;
import com.mojang.datafixers.DSL.TypeReference;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.DataFixerBuilder;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.serialization.Dynamic;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.fabric.internal.NBTConverter;
import net.minecraft.datafixer.NbtOps;
import net.minecraft.datafixer.Schemas;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.nbt.FloatTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Identifier;
@ -66,25 +67,28 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
* Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2)
*
* <p>
* We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy
* which is safer, faster and cleaner code.
* </p>
*
* <p>
* The pre DFU code did not fail when the Source version was unknown.
* </p>
*
* <p>
* This class also provides util methods for converting compounds to wrap the update call to
* receive the source version in the compound
*
* receive the source version in the compound.
* </p>
*/
@SuppressWarnings("UnnecessarilyQualifiedStaticUsage")
@SuppressWarnings({ "UnnecessarilyQualifiedStaticUsage", "unchecked", "rawtypes" })
class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer {
@SuppressWarnings("unchecked")
@Override
public <T> T fixUp(FixType<T> type, T original, int srcVer) {
if (type == FixTypes.CHUNK) {
@ -131,7 +135,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) {
StringBuilder sb = new StringBuilder();
sb.append(tagCompound.getString("Name"));
if (tagCompound.containsKey("Properties", 10)) {
if (tagCompound.contains("Properties", 10)) {
sb.append('[');
net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties");
sb.append(props.getKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(",")));
@ -168,8 +172,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
}
private static String fixName(String key, int srcVer, TypeReference type) {
return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, new StringTag(key)), srcVer, DATA_VERSION)
.asString().orElse(key);
return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, StringTag.of(key)), srcVer, DATA_VERSION)
.asString().result().orElse(key);
}
private static final NbtOps OPS_NBT = NbtOps.INSTANCE;
@ -181,7 +185,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private final Map<LegacyType, List<DataInspector>> inspectors = new EnumMap<>(LegacyType.class);
// Set on build
private DataFixer fixer;
private final DataFixer fixer;
private static final Map<String, LegacyType> DFU_TO_LEGACY = new HashMap<>();
public enum LegacyType {
@ -281,7 +285,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
}
public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) {
int i = cmp.containsKey("DataVersion", 99) ? cmp.getInt("DataVersion") : -1;
int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1;
return convert(type, cmp, i);
}
@ -460,6 +464,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private void registerEntityItemListEquipment(String type) {
registerEntityItemList(type, "ArmorItems", "HandItems");
}
private static final Map<String, Identifier> OLD_ID_TO_KEY_MAP = new HashMap<>();
static {
@ -587,17 +592,17 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
}
private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) {
if (nbttagcompound.containsKey(key, 10)) {
if (nbttagcompound.contains(key, 10)) {
convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer);
}
}
private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) {
if (nbttagcompound.containsKey(key, 9)) {
if (nbttagcompound.contains(key, 9)) {
ListTag nbttaglist = nbttagcompound.getList(key, 10);
for (int j = 0; j < nbttaglist.size(); ++j) {
nbttaglist.add(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompoundTag(j), sourceVer, targetVer));
nbttaglist.add(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer));
}
}
@ -605,7 +610,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterEquipment implements DataConverter {
DataConverterEquipment() {}
DataConverterEquipment() {
}
@Override
public int getDataVersion() {
@ -617,14 +623,14 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
ListTag nbttaglist = cmp.getList("Equipment", 10);
ListTag nbttaglist1;
if (!nbttaglist.isEmpty() && !cmp.containsKey("HandItems", 10)) {
if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) {
nbttaglist1 = new ListTag();
nbttaglist1.add(nbttaglist.get(0));
nbttaglist1.add(new net.minecraft.nbt.CompoundTag());
cmp.put("HandItems", nbttaglist1);
}
if (nbttaglist.size() > 1 && !cmp.containsKey("ArmorItem", 10)) {
if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) {
nbttaglist1 = new ListTag();
nbttaglist1.add(nbttaglist.get(1));
nbttaglist1.add(nbttaglist.get(2));
@ -634,23 +640,23 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
}
cmp.remove("Equipment");
if (cmp.containsKey("DropChances", 9)) {
if (cmp.contains("DropChances", 9)) {
nbttaglist1 = cmp.getList("DropChances", 5);
ListTag nbttaglist2;
if (!cmp.containsKey("HandDropChances", 10)) {
if (!cmp.contains("HandDropChances", 10)) {
nbttaglist2 = new ListTag();
nbttaglist2.add(new FloatTag(nbttaglist1.getFloat(0)));
nbttaglist2.add(new FloatTag(0.0F));
nbttaglist2.add(FloatTag.of(nbttaglist1.getFloat(0)));
nbttaglist2.add(FloatTag.of(0.0F));
cmp.put("HandDropChances", nbttaglist2);
}
if (!cmp.containsKey("ArmorDropChances", 10)) {
if (!cmp.contains("ArmorDropChances", 10)) {
nbttaglist2 = new ListTag();
nbttaglist2.add(new FloatTag(nbttaglist1.getFloat(1)));
nbttaglist2.add(new FloatTag(nbttaglist1.getFloat(2)));
nbttaglist2.add(new FloatTag(nbttaglist1.getFloat(3)));
nbttaglist2.add(new FloatTag(nbttaglist1.getFloat(4)));
nbttaglist2.add(FloatTag.of(nbttaglist1.getFloat(1)));
nbttaglist2.add(FloatTag.of(nbttaglist1.getFloat(2)));
nbttaglist2.add(FloatTag.of(nbttaglist1.getFloat(3)));
nbttaglist2.add(FloatTag.of(nbttaglist1.getFloat(4)));
cmp.put("ArmorDropChances", nbttaglist2);
}
@ -666,7 +672,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Map<String, String> b = Maps.newHashMap();
private static final Map<String, String> c = Maps.newHashMap();
DataInspectorBlockEntity() {}
DataInspectorBlockEntity() {
}
@Nullable
private static String convertEntityId(int i, String s) {
@ -680,12 +687,12 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (!cmp.containsKey("tag", 10)) {
if (!cmp.contains("tag", 10)) {
return cmp;
} else {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
if (nbttagcompound1.containsKey("BlockEntityTag", 10)) {
if (nbttagcompound1.contains("BlockEntityTag", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag");
String s = cmp.getString("id");
String s1 = convertEntityId(sourceVer, s);
@ -696,7 +703,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
// DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s);
flag = false;
} else {
flag = !nbttagcompound2.containsKey("id");
flag = !nbttagcompound2.contains("id");
nbttagcompound2.putString("id", s1);
}
@ -807,13 +814,14 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Logger a = LogManager.getLogger(FabricDataFixer.class);
DataInspectorEntity() {}
DataInspectorEntity() {
}
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
if (nbttagcompound1.containsKey("EntityTag", 10)) {
if (nbttagcompound1.contains("EntityTag", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag");
String s = cmp.getString("id");
String s1;
@ -834,7 +842,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
DataInspectorEntity.a.warn("Unable to resolve Entity for ItemInstance: {}", s);
flag = false;
} else {
flag = !nbttagcompound2.containsKey("id", 8);
flag = !nbttagcompound2.contains("id", 8);
nbttagcompound2.putString("id", s1);
}
@ -885,6 +893,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
return nbttagcompound;
}
}
private static class DataInspectorItem extends DataInspectorTagged {
private final String[] keys;
@ -907,14 +916,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final String[] materials = new String[2268];
DataConverterMaterialId() {}
DataConverterMaterialId() {
}
public int getDataVersion() {
return 102;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if (cmp.containsKey("id", 99)) {
if (cmp.contains("id", 99)) {
short short0 = cmp.getShort("id");
if (short0 > 0 && short0 < materials.length && materials[short0] != null) {
@ -1246,7 +1256,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterArmorStand implements DataConverter {
DataConverterArmorStand() {}
DataConverterArmorStand() {
}
public int getDataVersion() {
return 147;
@ -1263,25 +1274,26 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterBanner implements DataConverter {
DataConverterBanner() {}
DataConverterBanner() {
}
public int getDataVersion() {
return 804;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if ("minecraft:banner".equals(cmp.getString("id")) && cmp.containsKey("tag", 10)) {
if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
if (nbttagcompound1.containsKey("BlockEntityTag", 10)) {
if (nbttagcompound1.contains("BlockEntityTag", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag");
if (nbttagcompound2.containsKey("Base", 99)) {
if (nbttagcompound2.contains("Base", 99)) {
cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15));
if (nbttagcompound1.containsKey("display", 10)) {
if (nbttagcompound1.contains("display", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display");
if (nbttagcompound3.containsKey("Lore", 9)) {
if (nbttagcompound3.contains("Lore", 9)) {
ListTag nbttaglist = nbttagcompound3.getList("Lore", 8);
if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) {
@ -1310,7 +1322,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final String[] potions = new String[128];
DataConverterPotionId() {}
DataConverterPotionId() {
}
public int getDataVersion() {
return 102;
@ -1321,7 +1334,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
short short0 = cmp.getShort("Damage");
if (!nbttagcompound1.containsKey("Potion", 8)) {
if (!nbttagcompound1.contains("Potion", 8)) {
String s = DataConverterPotionId.potions[short0 & 127];
nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s);
@ -1475,7 +1488,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final String[] eggs = new String[256];
DataConverterSpawnEgg() {}
DataConverterSpawnEgg() {
}
public int getDataVersion() {
return 105;
@ -1487,7 +1501,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag");
short short0 = cmp.getShort("Damage");
if (!nbttagcompound2.containsKey("id", 8)) {
if (!nbttagcompound2.contains("id", 8)) {
String s = DataConverterSpawnEgg.eggs[short0 & 255];
if (s != null) {
@ -1579,9 +1593,10 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterMinecart implements DataConverter {
private static final List<String> a = Lists.newArrayList(new String[] { "MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"});
private static final List<String> a = Lists.newArrayList(new String[] { "MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock" });
DataConverterMinecart() {}
DataConverterMinecart() {
}
public int getDataVersion() {
return 106;
@ -1606,7 +1621,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterMobSpawner implements DataConverter {
DataConverterMobSpawner() {}
DataConverterMobSpawner() {
}
public int getDataVersion() {
return 107;
@ -1616,7 +1632,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
if (!"MobSpawner".equals(cmp.getString("id"))) {
return cmp;
} else {
if (cmp.containsKey("EntityId", 8)) {
if (cmp.contains("EntityId", 8)) {
String s = cmp.getString("EntityId");
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData");
@ -1625,13 +1641,13 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
cmp.remove("EntityId");
}
if (cmp.containsKey("SpawnPotentials", 9)) {
if (cmp.contains("SpawnPotentials", 9)) {
ListTag nbttaglist = cmp.getList("SpawnPotentials", 10);
for (int i = 0; i < nbttaglist.size(); ++i) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompoundTag(i);
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(i);
if (nbttagcompound2.containsKey("Type", 8)) {
if (nbttagcompound2.contains("Type", 8)) {
net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties");
nbttagcompound3.putString("id", nbttagcompound2.getString("Type"));
@ -1649,14 +1665,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterUUID implements DataConverter {
DataConverterUUID() {}
DataConverterUUID() {
}
public int getDataVersion() {
return 108;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if (cmp.containsKey("UUID", 8)) {
if (cmp.contains("UUID", 8)) {
cmp.putUuid("UUID", UUID.fromString(cmp.getString("UUID")));
}
@ -1668,7 +1685,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Set<String> a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie");
DataConverterHealth() {}
DataConverterHealth() {
}
public int getDataVersion() {
return 109;
@ -1678,11 +1696,11 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
if (DataConverterHealth.a.contains(cmp.getString("id"))) {
float f;
if (cmp.containsKey("HealF", 99)) {
if (cmp.contains("HealF", 99)) {
f = cmp.getFloat("HealF");
cmp.remove("HealF");
} else {
if (!cmp.containsKey("Health", 99)) {
if (!cmp.contains("Health", 99)) {
return cmp;
}
@ -1698,14 +1716,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterSaddle implements DataConverter {
DataConverterSaddle() {}
DataConverterSaddle() {
}
public int getDataVersion() {
return 110;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if ("EntityHorse".equals(cmp.getString("id")) && !cmp.containsKey("SaddleItem", 10) && cmp.getBoolean("Saddle")) {
if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag();
nbttagcompound1.putString("id", "minecraft:saddle");
@ -1721,7 +1740,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterHanging implements DataConverter {
DataConverterHanging() {}
DataConverterHanging() {
}
public int getDataVersion() {
return 111;
@ -1732,16 +1752,16 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
boolean flag = "Painting".equals(s);
boolean flag1 = "ItemFrame".equals(s);
if ((flag || flag1) && !cmp.containsKey("Facing", 99)) {
if ((flag || flag1) && !cmp.contains("Facing", 99)) {
Direction enumdirection;
if (cmp.containsKey("Direction", 99)) {
if (cmp.contains("Direction", 99)) {
enumdirection = Direction.fromHorizontal(cmp.getByte("Direction"));
cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getOffsetX());
cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getOffsetY());
cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getOffsetZ());
cmp.remove("Direction");
if (flag1 && cmp.containsKey("ItemRotation", 99)) {
if (flag1 && cmp.contains("ItemRotation", 99)) {
cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2));
}
} else {
@ -1758,7 +1778,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterDropChances implements DataConverter {
DataConverterDropChances() {}
DataConverterDropChances() {
}
public int getDataVersion() {
return 113;
@ -1767,14 +1788,14 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
ListTag nbttaglist;
if (cmp.containsKey("HandDropChances", 9)) {
if (cmp.contains("HandDropChances", 9)) {
nbttaglist = cmp.getList("HandDropChances", 5);
if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) {
cmp.remove("HandDropChances");
}
}
if (cmp.containsKey("ArmorDropChances", 9)) {
if (cmp.contains("ArmorDropChances", 9)) {
nbttaglist = cmp.getList("ArmorDropChances", 5);
if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) {
cmp.remove("ArmorDropChances");
@ -1787,14 +1808,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterRiding implements DataConverter {
DataConverterRiding() {}
DataConverterRiding() {
}
public int getDataVersion() {
return 135;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
while (cmp.containsKey("Riding", 10)) {
while (cmp.contains("Riding", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp);
this.convert(cmp, nbttagcompound1);
@ -1821,7 +1843,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterBook implements DataConverter {
DataConverterBook() {}
DataConverterBook() {
}
public int getDataVersion() {
return 165;
@ -1831,7 +1854,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
if ("minecraft:written_book".equals(cmp.getString("id"))) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
if (nbttagcompound1.containsKey("pages", 9)) {
if (nbttagcompound1.contains("pages", 9)) {
ListTag nbttaglist = nbttagcompound1.getList("pages", 8);
for (int i = 0; i < nbttaglist.size(); ++i) {
@ -1875,7 +1898,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
object = new LiteralText("");
}
nbttaglist.set(i, new StringTag(Text.Serializer.toJson((Text) object)));
nbttaglist.set(i, StringTag.of(Text.Serializer.toJson((Text) object)));
}
nbttagcompound1.put("pages", nbttaglist);
@ -1890,14 +1913,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Identifier a = new Identifier("cooked_fished");
DataConverterCookedFish() {}
DataConverterCookedFish() {
}
public int getDataVersion() {
return 502;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if (cmp.containsKey("id", 8) && DataConverterCookedFish.a.equals(new Identifier(cmp.getString("id")))) {
if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(new Identifier(cmp.getString("id")))) {
cmp.putString("id", "minecraft:cooked_fish");
}
@ -1909,7 +1933,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Random a = new Random();
DataConverterZombie() {}
DataConverterZombie() {
}
public int getDataVersion() {
return 502;
@ -1917,10 +1942,10 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) {
if (!cmp.containsKey("ZombieType", 99)) {
if (!cmp.contains("ZombieType", 99)) {
int i = -1;
if (cmp.containsKey("VillagerProfession", 99)) {
if (cmp.contains("VillagerProfession", 99)) {
try {
i = this.convert(cmp.getInt("VillagerProfession"));
} catch (RuntimeException runtimeexception) {
@ -1948,7 +1973,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterVBO implements DataConverter {
DataConverterVBO() {}
DataConverterVBO() {
}
public int getDataVersion() {
return 505;
@ -1962,7 +1988,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterGuardian implements DataConverter {
DataConverterGuardian() {}
DataConverterGuardian() {
}
public int getDataVersion() {
return 700;
@ -1983,7 +2010,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterSkeleton implements DataConverter {
DataConverterSkeleton() {}
DataConverterSkeleton() {
}
public int getDataVersion() {
return 701;
@ -2010,7 +2038,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterZombieType implements DataConverter {
DataConverterZombieType() {}
DataConverterZombieType() {
}
public int getDataVersion() {
return 702;
@ -2045,7 +2074,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterHorse implements DataConverter {
DataConverterHorse() {}
DataConverterHorse() {
}
public int getDataVersion() {
return 703;
@ -2089,7 +2119,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Map<String, String> a = Maps.newHashMap();
DataConverterTileEntity() {}
DataConverterTileEntity() {
}
public int getDataVersion() {
return 704;
@ -2136,7 +2167,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Map<String, String> a = Maps.newHashMap();
DataConverterEntity() {}
DataConverterEntity() {
}
public int getDataVersion() {
return 704;
@ -2233,7 +2265,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterPotionWater implements DataConverter {
DataConverterPotionWater() {}
DataConverterPotionWater() {
}
public int getDataVersion() {
return 806;
@ -2245,11 +2278,11 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
if (!nbttagcompound1.containsKey("Potion", 8)) {
if (!nbttagcompound1.contains("Potion", 8)) {
nbttagcompound1.putString("Potion", "minecraft:water");
}
if (!cmp.containsKey("tag", 10)) {
if (!cmp.contains("tag", 10)) {
cmp.put("tag", nbttagcompound1);
}
}
@ -2260,14 +2293,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterShulker implements DataConverter {
DataConverterShulker() {}
DataConverterShulker() {
}
public int getDataVersion() {
return 808;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.containsKey("Color", 99)) {
if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) {
cmp.putByte("Color", (byte) 10);
}
@ -2277,19 +2311,20 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterShulkerBoxItem implements DataConverter {
public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"};
public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" };
DataConverterShulkerBoxItem() {}
DataConverterShulkerBoxItem() {
}
public int getDataVersion() {
return 813;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.containsKey("tag", 10)) {
if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag");
if (nbttagcompound1.containsKey("BlockEntityTag", 10)) {
if (nbttagcompound1.contains("BlockEntityTag", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag");
if (nbttagcompound2.getList("Items", 10).isEmpty()) {
@ -2317,7 +2352,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterShulkerBoxBlock implements DataConverter {
DataConverterShulkerBoxBlock() {}
DataConverterShulkerBoxBlock() {
}
public int getDataVersion() {
return 813;
@ -2334,14 +2370,15 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterLang implements DataConverter {
DataConverterLang() {}
DataConverterLang() {
}
public int getDataVersion() {
return 816;
}
public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
if (cmp.containsKey("lang", 8)) {
if (cmp.contains("lang", 8)) {
cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT));
}
@ -2351,7 +2388,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterTotem implements DataConverter {
DataConverterTotem() {}
DataConverterTotem() {
}
public int getDataVersion() {
return 820;
@ -2370,7 +2408,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static final Logger a = LogManager.getLogger(FabricDataFixer.class);
DataConverterBedBlock() {}
DataConverterBedBlock() {
}
public int getDataVersion() {
return 1125;
@ -2387,7 +2426,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10);
for (int k = 0; k < nbttaglist1.size(); ++k) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompoundTag(k);
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k);
byte b0 = nbttagcompound2.getByte("Y");
byte[] abyte = nbttagcompound2.getByteArray("Blocks");
@ -2416,7 +2455,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterBedItem implements DataConverter {
DataConverterBedItem() {}
DataConverterBedItem() {
}
public int getDataVersion() {
return 1125;
@ -2434,17 +2474,17 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataConverterSignText implements DataConverter {
public static final Gson a = new GsonBuilder().registerTypeAdapter(Text.class, new JsonDeserializer() {
Text a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
MutableText a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
if (jsonelement.isJsonPrimitive()) {
return new LiteralText(jsonelement.getAsString());
} else if (jsonelement.isJsonArray()) {
JsonArray jsonarray = jsonelement.getAsJsonArray();
Text iTextComponent = null;
Iterator iterator = jsonarray.iterator();
MutableText iTextComponent = null;
Iterator<JsonElement> iterator = jsonarray.iterator();
while (iterator.hasNext()) {
JsonElement jsonelement1 = (JsonElement) iterator.next();
Text iTextComponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext);
JsonElement jsonelement1 = iterator.next();
MutableText iTextComponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext);
if (iTextComponent == null) {
iTextComponent = iTextComponent1;
@ -2464,7 +2504,8 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
}
}).create();
DataConverterSignText() {}
DataConverterSignText() {
}
public int getDataVersion() {
return 101;
@ -2529,10 +2570,10 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataInspectorPlayerVehicle implements DataInspector {
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (cmp.containsKey("RootVehicle", 10)) {
if (cmp.contains("RootVehicle", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle");
if (nbttagcompound1.containsKey("Entity", 10)) {
if (nbttagcompound1.contains("Entity", 10)) {
convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer);
}
}
@ -2544,7 +2585,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataInspectorLevelPlayer implements DataInspector {
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (cmp.containsKey("Player", 10)) {
if (cmp.contains("Player", 10)) {
convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer);
}
@ -2559,23 +2600,23 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
int j;
net.minecraft.nbt.CompoundTag nbttagcompound1;
if (cmp.containsKey("entities", 9)) {
if (cmp.contains("entities", 9)) {
nbttaglist = cmp.getList("entities", 10);
for (j = 0; j < nbttaglist.size(); ++j) {
nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j);
if (nbttagcompound1.containsKey("nbt", 10)) {
if (nbttagcompound1.contains("nbt", 10)) {
convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer);
}
}
}
if (cmp.containsKey("blocks", 9)) {
if (cmp.contains("blocks", 9)) {
nbttaglist = cmp.getList("blocks", 10);
for (j = 0; j < nbttaglist.size(); ++j) {
nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j);
if (nbttagcompound1.containsKey("nbt", 10)) {
if (nbttagcompound1.contains("nbt", 10)) {
convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer);
}
}
@ -2588,12 +2629,12 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataInspectorChunks implements DataInspector {
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (cmp.containsKey("Level", 10)) {
if (cmp.contains("Level", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level");
ListTag nbttaglist;
int j;
if (nbttagcompound1.containsKey("Entities", 9)) {
if (nbttagcompound1.contains("Entities", 9)) {
nbttaglist = nbttagcompound1.getList("Entities", 10);
for (j = 0; j < nbttaglist.size(); ++j) {
@ -2601,7 +2642,7 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
}
}
if (nbttagcompound1.containsKey("TileEntities", 9)) {
if (nbttagcompound1.contains("TileEntities", 9)) {
nbttaglist = nbttagcompound1.getList("TileEntities", 10);
for (j = 0; j < nbttaglist.size(); ++j) {
@ -2617,11 +2658,11 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
private static class DataInspectorEntityPassengers implements DataInspector {
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (cmp.containsKey("Passengers", 9)) {
if (cmp.contains("Passengers", 9)) {
ListTag nbttaglist = cmp.getList("Passengers", 10);
for (int j = 0; j < nbttaglist.size(); ++j) {
nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompoundTag(j), sourceVer, targetVer));
nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer));
}
}
@ -2634,11 +2675,11 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
convertItems(cmp, "Inventory", sourceVer, targetVer);
convertItems(cmp, "EnderItems", sourceVer, targetVer);
if (cmp.containsKey("ShoulderEntityLeft", 10)) {
if (cmp.contains("ShoulderEntityLeft", 10)) {
convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer);
}
if (cmp.containsKey("ShoulderEntityRight", 10)) {
if (cmp.contains("ShoulderEntityRight", 10)) {
convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer);
}
@ -2651,14 +2692,14 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (entityVillager.equals(new Identifier(cmp.getString("id"))) && cmp.containsKey("Offers", 10)) {
if (entityVillager.equals(new Identifier(cmp.getString("id"))) && cmp.contains("Offers", 10)) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Offers");
if (nbttagcompound1.containsKey("Recipes", 9)) {
if (nbttagcompound1.contains("Recipes", 9)) {
ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10);
for (int j = 0; j < nbttaglist.size(); ++j) {
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompoundTag(j);
net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(j);
convertItem(nbttagcompound2, "buy", sourceVer, targetVer);
convertItem(nbttagcompound2, "buyB", sourceVer, targetVer);
@ -2695,11 +2736,11 @@ class FabricDataFixer extends DataFixerBuilder implements com.sk89q.worldedit.wo
@Override
public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
if (tileEntityMobSpawner.equals(new Identifier(cmp.getString("id")))) {
if (cmp.containsKey("SpawnPotentials", 9)) {
if (cmp.contains("SpawnPotentials", 9)) {
ListTag nbttaglist = cmp.getList("SpawnPotentials", 10);
for (int j = 0; j < nbttaglist.size(); ++j) {
net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompoundTag(j);
net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompound(j);
convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer);
}

Datei anzeigen

@ -19,8 +19,6 @@
package com.sk89q.worldedit.fabric;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
@ -35,9 +33,10 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import java.lang.ref.WeakReference;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
class FabricEntity implements Entity {
private final WeakReference<net.minecraft.entity.Entity> entityRef;
@ -64,7 +63,7 @@ class FabricEntity implements Entity {
public Location getLocation() {
net.minecraft.entity.Entity entity = entityRef.get();
if (entity != null) {
Vector3 position = Vector3.at(entity.x, entity.y, entity.z);
Vector3 position = Vector3.at(entity.getX(), entity.getY(), entity.getZ());
float yaw = entity.yaw;
float pitch = entity.pitch;

Datei anzeigen

@ -19,10 +19,7 @@
package com.sk89q.worldedit.fabric;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
import net.minecraft.entity.EnderEyeEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ExperienceOrbEntity;
import net.minecraft.entity.FallingBlockEntity;
@ -36,15 +33,17 @@ import net.minecraft.entity.decoration.painting.PaintingEntity;
import net.minecraft.entity.mob.AmbientEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.passive.GolemEntity;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.Projectile;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.village.Trader;
import static com.google.common.base.Preconditions.checkNotNull;
public class FabricEntityProperties implements EntityProperties {
private final Entity entity;
@ -61,7 +60,7 @@ public class FabricEntityProperties implements EntityProperties {
@Override
public boolean isProjectile() {
return entity instanceof EnderEyeEntity || entity instanceof Projectile;
return entity instanceof ProjectileEntity;
}
@Override

Datei anzeigen

@ -33,8 +33,11 @@ import java.util.stream.Collectors;
public class FabricItemCategoryRegistry implements ItemCategoryRegistry {
@Override
public Set<ItemType> getCategorisedByName(String category) {
return Optional.ofNullable(ItemTags.getContainer().get(new Identifier(category)))
.map(Tag::values).orElse(Collections.emptySet())
.stream().map(FabricAdapter::adapt).collect(Collectors.toSet());
return Optional.ofNullable(ItemTags.getTagGroup().getTag(new Identifier(category)))
.map(Tag::values)
.orElse(Collections.emptyList())
.stream()
.map(FabricAdapter::adapt)
.collect(Collectors.toSet());
}
}

Datei anzeigen

@ -19,24 +19,26 @@
package com.sk89q.worldedit.fabric;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.item.Item;
import javax.annotation.Nullable;
public class FabricItemRegistry extends BundledItemRegistry {
@Nullable
@Override
public String getName(ItemType itemType) {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
final Item item = FabricAdapter.adapt(itemType);
return I18n.translate(item.getTranslationKey());
public Component getRichName(ItemType itemType) {
return TranslatableComponent.of(
FabricAdapter.adapt(itemType).getTranslationKey()
);
}
return super.getName(itemType);
@Override
public Component getRichName(BaseItemStack itemStack) {
return TranslatableComponent.of(
FabricAdapter.adapt(itemStack).getTranslationKey()
);
}
}

Datei anzeigen

@ -30,7 +30,7 @@ public interface FabricPermissionsProvider {
class VanillaPermissionsProvider implements FabricPermissionsProvider {
private FabricPlatform platform;
private final FabricPlatform platform;
public VanillaPermissionsProvider(FabricPlatform platform) {
this.platform = platform;
@ -39,12 +39,13 @@ public interface FabricPermissionsProvider {
@Override
public boolean hasPermission(ServerPlayerEntity player, String permission) {
FabricConfiguration configuration = platform.getConfiguration();
return configuration.cheatMode ||
player.server.getPlayerManager().isOperator(player.getGameProfile()) ||
(configuration.creativeEnable && player.interactionManager.getGameMode() == GameMode.CREATIVE);
return configuration.cheatMode
|| player.server.getPlayerManager().isOperator(player.getGameProfile())
|| (configuration.creativeEnable && player.interactionManager.getGameMode() == GameMode.CREATIVE);
}
@Override
public void registerPermission(String permission) {}
public void registerPermission(String permission) {
}
}
}

Datei anzeigen

@ -20,6 +20,7 @@
package com.sk89q.worldedit.fabric;
import com.google.common.collect.Sets;
import com.mojang.brigadier.CommandDispatcher;
import com.sk89q.worldedit.command.util.PermissionCondition;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
@ -35,15 +36,16 @@ import com.sk89q.worldedit.world.registry.Registries;
import net.minecraft.SharedConstants;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.level.ServerWorldProperties;
import org.enginehub.piston.Command;
import org.enginehub.piston.CommandManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -51,6 +53,7 @@ import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import static java.util.stream.Collectors.toList;
@ -61,10 +64,12 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform {
private final FabricDataFixer dataFixer;
private final @Nullable Watchdog watchdog;
private boolean hookingEvents = false;
private CommandDispatcher<ServerCommandSource> nativeDispatcher;
FabricPlatform(FabricWorldEdit mod, MinecraftServer server) {
this.mod = mod;
this.server = server;
this.nativeDispatcher = server.getCommandManager().getDispatcher();
this.dataFixer = new FabricDataFixer(getDataVersion());
this.watchdog = server instanceof MinecraftDedicatedServer
? (Watchdog) server : null;
@ -138,7 +143,7 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform {
return world;
} else {
for (ServerWorld ws : server.getWorlds()) {
if (ws.getLevelProperties().getLevelName().equals(world.getName())) {
if (((ServerWorldProperties) ws.getLevelProperties()).getLevelName().equals(world.getName())) {
return new FabricWorld(ws);
}
}
@ -147,13 +152,18 @@ class FabricPlatform extends AbstractPlatform implements MultiUserPlatform {
}
}
public void setNativeDispatcher(CommandDispatcher<ServerCommandSource> nativeDispatcher) {
this.nativeDispatcher = nativeDispatcher;
}
@Override
public void registerCommands(CommandManager manager) {
if (server == null) return;
net.minecraft.server.command.CommandManager mcMan = server.getCommandManager();
if (server == null) {
return;
}
for (Command command : manager.getAllCommands().collect(toList())) {
CommandWrapper.register(mcMan.getDispatcher(), command);
CommandWrapper.register(nativeDispatcher, command);
Set<String> perms = command.getCondition().as(PermissionCondition.class)
.map(PermissionCondition::getPermissions)
.orElseGet(Collections::emptySet);

Datei anzeigen

@ -25,8 +25,8 @@ 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.internal.ExtendedPlayerEntity;
import com.sk89q.worldedit.fabric.internal.NBTConverter;
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;
@ -35,6 +35,7 @@ import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.WorldEditText;
import com.sk89q.worldedit.util.formatting.component.TextUtils;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
import com.sk89q.worldedit.world.World;
@ -44,22 +45,23 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import io.netty.buffer.Unpooled;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Locale;
import java.util.UUID;
import javax.annotation.Nullable;
public class FabricPlayer extends AbstractPlayerActor {
@ -85,7 +87,7 @@ public class FabricPlayer extends AbstractPlayerActor {
@Override
public String getName() {
return this.player.getName().asFormattedString();
return this.player.getName().asString();
}
@Override
@ -95,7 +97,7 @@ public class FabricPlayer extends AbstractPlayerActor {
@Override
public Location getLocation() {
Vector3 position = Vector3.at(this.player.x, this.player.y, this.player.z);
Vector3 position = Vector3.at(this.player.getX(), this.player.getY(), this.player.getZ());
return new Location(
FabricWorldEdit.inst.getWorld(this.player.world),
position,
@ -133,41 +135,45 @@ public class FabricPlayer extends AbstractPlayerActor {
@Override
public Locale getLocale() {
return Locale.forLanguageTag(((AccessorServerPlayerEntity) this.player).getClientLanguage().replace("_", "-"));
return TextUtils.getLocaleByMinecraftTag(((ExtendedPlayerEntity) this.player).getLanguage());
}
@Override
@Deprecated
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
this.player.sendMessage(new LiteralText(part));
this.player.sendMessage(new LiteralText(part), false);
}
}
@Override
@Deprecated
public void printDebug(String msg) {
sendColorized(msg, Formatting.GRAY);
}
@Override
@Deprecated
public void print(String msg) {
sendColorized(msg, Formatting.LIGHT_PURPLE);
}
@Override
@Deprecated
public void printError(String msg) {
sendColorized(msg, Formatting.RED);
}
@Override
public void print(Component component) {
this.player.sendMessage(Text.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))));
this.player.sendMessage(Text.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))), false);
}
private void sendColorized(String msg, Formatting formatting) {
for (String part : msg.split("\n")) {
LiteralText component = new LiteralText(part);
component.getStyle().setColor(formatting);
this.player.sendMessage(component);
MutableText component = new LiteralText(part)
.styled(style -> style.withColor(formatting));
this.player.sendMessage(component, false);
}
}
@ -192,6 +198,11 @@ public class FabricPlayer extends AbstractPlayerActor {
return FabricWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm);
}
@Override
public void setPermission(String permission, boolean value) {
}
@Nullable
@Override
public <T> T getFacet(Class<? extends T> cls) {
@ -246,6 +257,11 @@ public class FabricPlayer extends AbstractPlayerActor {
}
}
@Override
public void sendTitle(Component title, Component sub) {
}
@Override
public SessionKey getSessionKey() {
return new SessionKeyImpl(player.getUuid(), player.getName().getString());

Datei anzeigen

@ -19,36 +19,45 @@
package com.sk89q.worldedit.fabric;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import com.google.common.util.concurrent.Futures;
import com.mojang.serialization.Dynamic;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.fabric.internal.ExtendedMinecraftServer;
import com.sk89q.worldedit.fabric.internal.FabricWorldNativeAccess;
import com.sk89q.worldedit.fabric.internal.NBTConverter;
import com.sk89q.worldedit.fabric.mixin.AccessorLevelProperties;
import com.sk89q.worldedit.fabric.mixin.AccessorServerChunkManager;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.util.io.file.SafeFiles;
import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.RegenOptions;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
@ -57,77 +66,78 @@ import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerChunkManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Clearable;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.dynamic.RegistryOps;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.WorldSaveHandler;
import net.minecraft.world.biome.DefaultBiomeFeatures;
import net.minecraft.world.WorldProperties;
import net.minecraft.world.biome.source.BiomeAccessType;
import net.minecraft.world.biome.source.BiomeArray;
import net.minecraft.world.biome.source.HorizontalVoronoiBiomeAccessType;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkManager;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.gen.feature.BirchTreeFeature;
import net.minecraft.world.gen.feature.DarkOakTreeFeature;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.HugeBrownMushroomFeature;
import net.minecraft.world.gen.feature.HugeRedMushroomFeature;
import net.minecraft.world.gen.feature.JungleGroundBushFeature;
import net.minecraft.world.gen.feature.JungleTreeFeature;
import net.minecraft.world.gen.feature.LargeOakTreeFeature;
import net.minecraft.world.gen.feature.MegaJungleTreeFeature;
import net.minecraft.world.gen.feature.MegaPineTreeFeature;
import net.minecraft.world.gen.feature.OakTreeFeature;
import net.minecraft.world.gen.feature.PineTreeFeature;
import net.minecraft.world.gen.feature.PlantedFeatureConfig;
import net.minecraft.world.gen.feature.SavannaTreeFeature;
import net.minecraft.world.gen.feature.SpruceTreeFeature;
import net.minecraft.world.gen.feature.SwampTreeFeature;
import net.minecraft.world.level.LevelProperties;
import net.minecraft.world.dimension.DimensionOptions;
import net.minecraft.world.gen.GeneratorOptions;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.ConfiguredFeatures;
import net.minecraft.world.level.ServerWorldProperties;
import net.minecraft.world.level.storage.LevelStorage;
import java.io.File;
import java.lang.ref.WeakReference;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
/**
* An adapter to Minecraft worlds for WorldEdit.
*/
public class FabricWorld extends AbstractWorld {
private static final Random random = new Random();
private static final int UPDATE = 1, NOTIFY = 2;
private static final net.minecraft.block.BlockState JUNGLE_LOG = Blocks.JUNGLE_LOG.getDefaultState();
private static final net.minecraft.block.BlockState JUNGLE_LEAF = Blocks.JUNGLE_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE);
private static final net.minecraft.block.BlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE);
private static Identifier getDimensionRegistryKey(World world) {
return Objects.requireNonNull(world.getServer(), "server cannot be null")
.getRegistryManager()
.getDimensionTypes()
.getId(world.getDimension());
}
private final WeakReference<World> worldRef;
private final FabricWorldNativeAccess worldNativeAccess;
@ -143,21 +153,6 @@ public class FabricWorld extends AbstractWorld {
this.worldNativeAccess = new FabricWorldNativeAccess(worldRef);
}
/**
* Get the underlying handle to the world.
*
* @return the world
* @throws WorldEditException thrown if a reference to the world was lost (i.e. world was unloaded)
*/
public World getWorldChecked() throws WorldEditException {
World world = worldRef.get();
if (world != null) {
return world;
} else {
throw new WorldReferenceLostException("The reference to the world was lost (i.e. the world may have been unloaded)");
}
}
/**
* Get the underlying handle to the world.
*
@ -175,32 +170,46 @@ public class FabricWorld extends AbstractWorld {
@Override
public String getName() {
return getWorld().getLevelProperties().getLevelName();
WorldProperties levelProperties = getWorld().getLevelProperties();
return ((ServerWorldProperties) levelProperties).getLevelName();
}
@Override
public String getId() {
return getWorld().getLevelProperties().getLevelName()
.replace(" ", "_").toLowerCase(Locale.ROOT)
+ getWorld().dimension.getType().getSuffix();
return getName() + "_" + getDimensionRegistryKey(getWorld());
}
@Override
public void refreshChunk(int chunkX, int chunkZ) {
}
@Override
public IChunkGet get(int x, int z) {
return null;
}
@Override
public void sendFakeChunk(@Nullable Player player, ChunkPacket packet) {
}
@Override
public Path getStoragePath() {
final World world = getWorld();
if (world instanceof ServerWorld) {
return ((ServerWorld) world).getSaveHandler().getWorldDir().toPath();
}
return null;
MinecraftServer server = world.getServer();
checkState(server instanceof ExtendedMinecraftServer, "Need a server world");
return ((ExtendedMinecraftServer) server).getStoragePath(world);
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
clearContainerBlockContents(position);
return worldNativeAccess.setBlock(position, block, sideEffects);
}
@Override
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
public Set<SideEffect> applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) {
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
return Sets.intersection(FabricWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
}
@ -223,21 +232,37 @@ public class FabricWorld extends AbstractWorld {
}
@Override
public BiomeType getBiome(BlockVector2 position) {
checkNotNull(position);
return FabricAdapter.adapt(getWorld().getBiome(new BlockPos(position.getBlockX(), 0, position.getBlockZ())));
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
return false;
}
@Override
public boolean setBiome(BlockVector2 position, BiomeType biome) {
public boolean fullySupports3DBiomes() {
BiomeAccessType biomeAccessType = getWorld().getDimension().getBiomeAccessType();
return !(biomeAccessType instanceof HorizontalVoronoiBiomeAccessType);
}
@Override
public BiomeType getBiome(BlockVector3 position) {
checkNotNull(position);
Chunk chunk = getWorld().getChunk(position.getX() >> 4, position.getZ() >> 4);
return getBiomeInChunk(position, chunk);
}
private BiomeType getBiomeInChunk(BlockVector3 position, Chunk chunk) {
BiomeArray biomeArray = checkNotNull(chunk.getBiomeArray());
return FabricAdapter.adapt(biomeArray.getBiomeForNoiseGen(position.getX() >> 2, position.getY() >> 2, position.getZ() >> 2));
}
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
checkNotNull(position);
checkNotNull(biome);
Chunk chunk = getWorld().getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4, ChunkStatus.FULL, false);
if (chunk == null) {
return false;
}
chunk.getBiomeArray()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = FabricAdapter.adapt(biome);
Chunk chunk = getWorld().getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4);
MutableBiomeArray biomeArray = MutableBiomeArray.inject(checkNotNull(chunk.getBiomeArray()));
biomeArray.setBiome(position.getX(), position.getY(), position.getZ(), FabricAdapter.adapt(biome));
chunk.setShouldSave(true);
return true;
}
@ -255,7 +280,7 @@ public class FabricWorld extends AbstractWorld {
return false;
}
fakePlayer.setStackInHand(Hand.MAIN_HAND, stack);
fakePlayer.setPositionAndAngles(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
fakePlayer.updatePositionAndAngles(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
(float) face.toVector().toYaw(), (float) face.toVector().toPitch());
final BlockPos blockPos = FabricAdapter.toBlockPos(position);
final BlockHitResult rayTraceResult = new BlockHitResult(FabricAdapter.toVec3(position),
@ -264,11 +289,10 @@ public class FabricWorld extends AbstractWorld {
ActionResult used = stack.useOnBlock(itemUseContext);
if (used != ActionResult.SUCCESS) {
// try activating the block
if (getWorld().getBlockState(blockPos).activate(world, fakePlayer, Hand.MAIN_HAND, rayTraceResult)) {
used = ActionResult.SUCCESS;
} else {
used = stack.getItem().use(world, fakePlayer, Hand.MAIN_HAND).getResult();
used = getWorld().getBlockState(blockPos).onUse(world, fakePlayer, Hand.MAIN_HAND, rayTraceResult);
}
if (used != ActionResult.SUCCESS) {
used = stack.use(world, fakePlayer, Hand.MAIN_HAND).getResult();
}
return used == ActionResult.SUCCESS;
}
@ -295,84 +319,181 @@ public class FabricWorld extends AbstractWorld {
@Override
public boolean regenerate(Region region, EditSession editSession) {
// Don't even try to regen if it's going to fail.
ChunkManager provider = getWorld().getChunkManager();
if (!(provider instanceof ServerChunkManager)) {
return false;
}
File saveFolder = Files.createTempDir();
// register this just in case something goes wrong
// normally it should be deleted at the end of this method
saveFolder.deleteOnExit();
try {
private void doRegen(Region region, Extent extent, RegenOptions options) throws Exception {
Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
LevelStorage levelStorage = LevelStorage.create(tempDir);
try (LevelStorage.Session session = levelStorage.createSession("WorldEditTempGen")) {
ServerWorld originalWorld = (ServerWorld) getWorld();
long seed = options.getSeed().orElse(originalWorld.getSeed());
AccessorLevelProperties levelProperties = (AccessorLevelProperties)
originalWorld.getServer().getSaveProperties();
GeneratorOptions originalOpts = levelProperties.getGeneratorOptions();
MinecraftServer server = originalWorld.getServer();
WorldSaveHandler saveHandler = new WorldSaveHandler(saveFolder, originalWorld.getSaveHandler().getWorldDir().getName(), server, server.getDataFixer());
World freshWorld = new ServerWorld(server, server.getWorkerExecutor(), saveHandler, originalWorld.getLevelProperties(),
originalWorld.dimension.getType(), originalWorld.getProfiler(), new NoOpChunkStatusListener());
// Pre-gen all the chunks
// We need to also pull one more chunk in every direction
CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16));
for (BlockVector2 chunk : expandedPreGen.getChunks()) {
freshWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ());
RegistryOps<Tag> nbtRegOps = RegistryOps.of(
NbtOps.INSTANCE,
((ExtendedMinecraftServer) originalWorld.getServer())
.getServerResourceManager().getResourceManager(),
(DynamicRegistryManager.Impl) originalWorld.getServer().getRegistryManager()
);
GeneratorOptions newOpts = GeneratorOptions.CODEC
.encodeStart(nbtRegOps, originalOpts)
.flatMap(tag ->
GeneratorOptions.CODEC.parse(
recursivelySetSeed(new Dynamic<>(nbtRegOps, tag), seed, new HashSet<>())
)
)
.get().map(
l -> l,
error -> {
throw new IllegalStateException("Unable to map GeneratorOptions: " + error.message());
}
);
FabricWorld from = new FabricWorld(freshWorld);
for (BlockVector3 vec : region) {
editSession.setBlock(vec, from.getFullBlock(vec));
levelProperties.setGeneratorOptions(newOpts);
RegistryKey<World> worldRegKey = originalWorld.getRegistryKey();
DimensionOptions dimGenOpts = newOpts.getDimensions().get(worldRegKey.getValue());
checkNotNull(dimGenOpts, "No DimensionOptions for %s", worldRegKey);
try (ServerWorld serverWorld = new ServerWorld(
originalWorld.getServer(), Util.getMainWorkerExecutor(), session,
((ServerWorldProperties) originalWorld.getLevelProperties()),
worldRegKey,
originalWorld.getDimension(),
new WorldEditGenListener(),
dimGenOpts.getChunkGenerator(),
originalWorld.isDebugWorld(),
seed,
// No spawners are needed for this world.
ImmutableList.of(),
// This controls ticking, we don't need it so set it to false.
false
)) {
regenForWorld(region, extent, serverWorld, options);
// drive the server executor until all tasks are popped off
while (originalWorld.getServer().runTask()) {
Thread.yield();
}
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
} finally {
saveFolder.delete();
levelProperties.setGeneratorOptions(originalOpts);
}
} finally {
SafeFiles.tryHardToDeleteDir(tempDir);
}
}
return true;
@SuppressWarnings("unchecked")
private Dynamic<Tag> recursivelySetSeed(Dynamic<Tag> dynamic, long seed, Set<Dynamic<Tag>> seen) {
if (!seen.add(dynamic)) {
return dynamic;
}
return dynamic.updateMapValues(pair -> {
if (pair.getFirst().asString("").equals("seed")) {
return pair.mapSecond(v -> v.createLong(seed));
}
if (pair.getSecond().getValue() instanceof net.minecraft.nbt.CompoundTag) {
return pair.mapSecond(v -> recursivelySetSeed((Dynamic<Tag>) v, seed, seen));
}
return pair;
});
}
private void regenForWorld(Region region, Extent extent, ServerWorld serverWorld,
RegenOptions options) throws WorldEditException {
List<CompletableFuture<Chunk>> chunkLoadings = submitChunkLoadTasks(region, serverWorld);
// drive executor until loading finishes
((AccessorServerChunkManager) serverWorld.getChunkManager()).getMainThreadExecutor()
.runTasks(() -> {
// bail out early if a future fails
if (chunkLoadings.stream().anyMatch(ftr ->
ftr.isDone() && Futures.getUnchecked(ftr) == null
)) {
return false;
}
return chunkLoadings.stream().allMatch(CompletableFuture::isDone);
});
Map<ChunkPos, Chunk> chunks = new HashMap<>();
for (CompletableFuture<Chunk> future : chunkLoadings) {
@Nullable
Chunk chunk = future.getNow(null);
checkState(chunk != null, "Failed to generate a chunk, regen failed.");
chunks.put(chunk.getPos(), chunk);
}
for (BlockVector3 vec : region) {
BlockPos pos = FabricAdapter.toBlockPos(vec);
Chunk chunk = chunks.get(new ChunkPos(pos));
BlockStateHolder<?> state = FabricAdapter.adapt(chunk.getBlockState(pos));
BlockEntity blockEntity = chunk.getBlockEntity(pos);
if (blockEntity != null) {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
blockEntity.toTag(tag);
state = state.toBaseBlock(NBTConverter.fromNative(tag));
}
extent.setBlock(vec, state.toBaseBlock());
if (options.shouldRegenBiomes()) {
BiomeType biome = getBiomeInChunk(vec, chunk);
extent.setBiome(vec, biome);
}
}
}
private List<CompletableFuture<Chunk>> submitChunkLoadTasks(Region region, ServerWorld world) {
AccessorServerChunkManager chunkManager = (AccessorServerChunkManager) world.getChunkManager();
List<CompletableFuture<Chunk>> chunkLoadings = new ArrayList<>();
// Pre-gen all the chunks
for (BlockVector2 chunk : region.getChunks()) {
chunkLoadings.add(
chunkManager.callGetChunkFuture(chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)
.thenApply(either -> either.left().orElse(null))
);
}
return chunkLoadings;
}
@Nullable
private static Feature<? extends FeatureConfig> createTreeFeatureGenerator(TreeType type) {
private static ConfiguredFeature<?, ?> createTreeFeatureGenerator(TreeType type) {
switch (type) {
case TREE: return new OakTreeFeature(DefaultFeatureConfig::deserialize, true);
case BIG_TREE: return new LargeOakTreeFeature(DefaultFeatureConfig::deserialize, true);
case REDWOOD: return new PineTreeFeature(DefaultFeatureConfig::deserialize);
case TALL_REDWOOD: return new SpruceTreeFeature(DefaultFeatureConfig::deserialize, true);
case BIRCH: return new BirchTreeFeature(DefaultFeatureConfig::deserialize, true, false);
case JUNGLE: return new MegaJungleTreeFeature(DefaultFeatureConfig::deserialize, true, 10, 20, JUNGLE_LOG, JUNGLE_LEAF);
case SMALL_JUNGLE: return new JungleTreeFeature(DefaultFeatureConfig::deserialize, true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, false);
case SHORT_JUNGLE: return new JungleTreeFeature(DefaultFeatureConfig::deserialize, true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, true);
case JUNGLE_BUSH: return new JungleGroundBushFeature(DefaultFeatureConfig::deserialize, JUNGLE_LOG, JUNGLE_SHRUB);
case SWAMP: return new SwampTreeFeature(DefaultFeatureConfig::deserialize);
case ACACIA: return new SavannaTreeFeature(DefaultFeatureConfig::deserialize, true);
case DARK_OAK: return new DarkOakTreeFeature(DefaultFeatureConfig::deserialize, true);
case MEGA_REDWOOD: return new MegaPineTreeFeature(DefaultFeatureConfig::deserialize, true, random.nextBoolean());
case TALL_BIRCH: return new BirchTreeFeature(DefaultFeatureConfig::deserialize, true, true);
case RED_MUSHROOM: return new HugeRedMushroomFeature(PlantedFeatureConfig::deserialize);
case BROWN_MUSHROOM: return new HugeBrownMushroomFeature(PlantedFeatureConfig::deserialize);
// Based off of the SaplingGenerator class, as well as uses of DefaultBiomeFeatures fields
case TREE: return ConfiguredFeatures.OAK;
case BIG_TREE: return ConfiguredFeatures.FANCY_OAK;
case REDWOOD: return ConfiguredFeatures.SPRUCE;
case TALL_REDWOOD: return ConfiguredFeatures.MEGA_SPRUCE;
case MEGA_REDWOOD: return ConfiguredFeatures.MEGA_PINE;
case BIRCH: return ConfiguredFeatures.BIRCH;
case JUNGLE: return ConfiguredFeatures.MEGA_JUNGLE_TREE;
case SMALL_JUNGLE: return ConfiguredFeatures.JUNGLE_TREE;
case SHORT_JUNGLE: return ConfiguredFeatures.JUNGLE_TREE_NO_VINE;
case JUNGLE_BUSH: return ConfiguredFeatures.JUNGLE_BUSH;
case SWAMP: return ConfiguredFeatures.SWAMP_TREE;
case ACACIA: return ConfiguredFeatures.ACACIA;
case DARK_OAK: return ConfiguredFeatures.DARK_OAK;
case TALL_BIRCH: return ConfiguredFeatures.BIRCH_TALL;
case RED_MUSHROOM: return ConfiguredFeatures.HUGE_RED_MUSHROOM;
case BROWN_MUSHROOM: return ConfiguredFeatures.HUGE_BROWN_MUSHROOM;
case WARPED_FUNGUS: return ConfiguredFeatures.WARPED_FUNGI;
case CRIMSON_FUNGUS: return ConfiguredFeatures.CRIMSON_FUNGI;
case CHORUS_PLANT: return ConfiguredFeatures.CHORUS_PLANT;
case RANDOM: return createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
default:
return null;
}
}
private FeatureConfig createFeatureConfig(TreeType type) {
if (type == TreeType.RED_MUSHROOM || type == TreeType.BROWN_MUSHROOM) {
return new PlantedFeatureConfig(true);
} else {
return new DefaultFeatureConfig();
}
}
@Override
public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
@SuppressWarnings("unchecked")
Feature<FeatureConfig> generator = (Feature<FeatureConfig>) createTreeFeatureGenerator(type);
return generator != null
&& generator.generate(getWorld(), getWorld().getChunkManager().getChunkGenerator(), random,
FabricAdapter.toBlockPos(position), createFeatureConfig(type));
public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) {
ConfiguredFeature<?, ?> generator = createTreeFeatureGenerator(type);
ServerWorld world = (ServerWorld) getWorld();
ServerChunkManager chunkManager = world.getChunkManager();
return generator != null && generator.generate(
world, chunkManager.getChunkGenerator(), random,
FabricAdapter.toBlockPos(position)
);
}
@Override
@ -389,19 +510,22 @@ public class FabricWorld extends AbstractWorld {
public void fixLighting(Iterable<BlockVector2> chunks) {
World world = getWorld();
for (BlockVector2 chunk : chunks) {
world.getChunkManager().getLightingProvider().suppressLight(new ChunkPos(chunk.getBlockX(), chunk.getBlockZ()), true);
world.getChunkManager().getLightingProvider().setColumnEnabled(
new ChunkPos(chunk.getBlockX(), chunk.getBlockZ()), true
);
}
}
@Override
public boolean playEffect(Vector3 position, int type, int data) {
getWorld().playLevelEvent(type, FabricAdapter.toBlockPos(position.toBlockPoint()), data);
// TODO update sound API
// getWorld().playSound(type, FabricAdapter.toBlockPos(position.toBlockPoint()), data);
return true;
}
@Override
public WeatherType getWeather() {
LevelProperties info = getWorld().getLevelProperties();
WorldProperties info = getWorld().getLevelProperties();
if (info.isThundering()) {
return WeatherTypes.THUNDER_STORM;
}
@ -413,7 +537,7 @@ public class FabricWorld extends AbstractWorld {
@Override
public long getRemainingWeatherDuration() {
LevelProperties info = getWorld().getLevelProperties();
ServerWorldProperties info = (ServerWorldProperties) getWorld().getLevelProperties();
if (info.isThundering()) {
return info.getThunderTime();
}
@ -430,7 +554,7 @@ public class FabricWorld extends AbstractWorld {
@Override
public void setWeather(WeatherType weatherType, long duration) {
LevelProperties info = getWorld().getLevelProperties();
ServerWorldProperties info = (ServerWorldProperties) getWorld().getLevelProperties();
if (weatherType == WeatherTypes.THUNDER_STORM) {
info.setClearWeatherTime(0);
info.setThundering(true);
@ -453,7 +577,12 @@ public class FabricWorld extends AbstractWorld {
@Override
public BlockVector3 getSpawnPosition() {
return FabricAdapter.adapt(getWorld().getSpawnPos());
WorldProperties worldProps = getWorld().getLevelProperties();
return BlockVector3.at(
worldProps.getSpawnX(),
worldProps.getSpawnY(),
worldProps.getSpawnZ()
);
}
@Override
@ -507,13 +636,19 @@ public class FabricWorld extends AbstractWorld {
@Override
public List<? extends Entity> getEntities(Region region) {
final World world = getWorld();
if (!(world instanceof ServerWorld)) {
return Collections.emptyList();
}
return ((ServerWorld) world).getEntities(null, entity -> true)
.stream()
.filter(e -> region.contains(FabricAdapter.adapt(e.getBlockPos())))
.map(FabricEntity::new).collect(Collectors.toList());
Box box = new Box(
FabricAdapter.toBlockPos(region.getMinimumPoint()),
FabricAdapter.toBlockPos(region.getMaximumPoint().add(BlockVector3.ONE))
);
List<net.minecraft.entity.Entity> nmsEntities = world.getEntitiesByType(
null,
box,
e -> region.contains(FabricAdapter.adapt(e.getBlockPos()))
);
return ImmutableList.copyOf(Lists.transform(
nmsEntities,
FabricEntity::new
));
}
@Override
@ -522,10 +657,10 @@ public class FabricWorld extends AbstractWorld {
if (!(world instanceof ServerWorld)) {
return Collections.emptyList();
}
return ((ServerWorld) world).getEntities(null, entity -> true)
.stream()
.map(FabricEntity::new)
.collect(Collectors.toList());
return ImmutableList.copyOf(Iterables.transform(
((ServerWorld) world).iterateEntities(),
FabricEntity::new
));
}
@Nullable
@ -533,7 +668,9 @@ public class FabricWorld extends AbstractWorld {
public Entity createEntity(Location location, BaseEntity entity) {
World world = getWorld();
final Optional<EntityType<?>> entityType = EntityType.get(entity.getType().getId());
if (!entityType.isPresent()) return null;
if (!entityType.isPresent()) {
return null;
}
net.minecraft.entity.Entity createdEntity = entityType.get().create(world);
if (createdEntity != null) {
CompoundTag nativeTag = entity.getNbtData();
@ -545,7 +682,7 @@ public class FabricWorld extends AbstractWorld {
createdEntity.fromTag(tag);
}
createdEntity.setPositionAndAngles(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
createdEntity.updatePositionAndAngles(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
world.spawnEntity(createdEntity);
return new FabricEntity(createdEntity);
@ -554,27 +691,4 @@ public class FabricWorld extends AbstractWorld {
}
}
/**
* Thrown when the reference to the world is lost.
*/
@SuppressWarnings("serial")
private static final class WorldReferenceLostException extends WorldEditException {
private WorldReferenceLostException(String message) {
super(message);
}
}
private static class NoOpChunkStatusListener implements WorldGenerationProgressListener {
@Override
public void start(ChunkPos chunkPos) {
}
@Override
public void setChunkStatus(ChunkPos chunkPos, @Nullable ChunkStatus chunkStatus) {
}
@Override
public void stop() {
}
}
}

Datei anzeigen

@ -19,13 +19,13 @@
package com.sk89q.worldedit.fabric;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer;
import com.mojang.brigadier.CommandDispatcher;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.fabric.net.handler.WECUIPacketHandler;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
@ -35,22 +35,25 @@ import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.fabricmc.fabric.api.event.server.ServerStartCallback;
import net.fabricmc.fabric.api.event.server.ServerStopCallback;
import net.fabricmc.fabric.api.event.server.ServerTickCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.ItemTags;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
@ -65,6 +68,9 @@ import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer;
/**
* The Fabric implementation of WorldEdit.
*/
@ -95,7 +101,7 @@ public class FabricWorldEdit implements ModInitializer {
);
// Setup working directory
workingDir = new File(FabricLoader.getInstance().getConfigDirectory(), "worldedit").toPath();
workingDir = FabricLoader.getInstance().getConfigDir().resolve("worldedit");
if (!Files.exists(workingDir)) {
try {
Files.createDirectory(workingDir);
@ -106,15 +112,34 @@ public class FabricWorldEdit implements ModInitializer {
WECUIPacketHandler.init();
ServerTickCallback.EVENT.register(ThreadSafeCache.getInstance());
ServerStartCallback.EVENT.register(this::onStartServer);
ServerStopCallback.EVENT.register(this::onStopServer);
ServerTickEvents.END_SERVER_TICK.register(ThreadSafeCache.getInstance());
CommandRegistrationCallback.EVENT.register(this::registerCommands);
ServerLifecycleEvents.SERVER_STARTED.register(this::onStartServer);
ServerLifecycleEvents.SERVER_STOPPING.register(this::onStopServer);
AttackBlockCallback.EVENT.register(this::onLeftClickBlock);
UseBlockCallback.EVENT.register(this::onRightClickBlock);
UseItemCallback.EVENT.register(this::onRightClickAir);
LOGGER.info("WorldEdit for Fabric (version " + getInternalVersion() + ") is loaded");
}
private void registerCommands(CommandDispatcher<ServerCommandSource> dispatcher, boolean dedicated) {
PlatformManager manager = WorldEdit.getInstance().getPlatformManager();
if (manager.getPlatforms().isEmpty()) {
// We'll register as part of our platform initialization later.
return;
}
// This is a re-register (due to /reload), we must add our commands now
Platform commandsPlatform = manager.queryCapability(Capability.USER_COMMANDS);
if (commandsPlatform != platform || !platform.isHookingEvents()) {
// We're not in control of commands/events -- do not re-register.
return;
}
platform.setNativeDispatcher(dispatcher);
platform.registerCommands(manager.getPlatformCommandManager().getCommandManager());
}
private void setupPlatform(MinecraftServer server) {
this.platform = new FabricPlatform(this, server);
@ -123,14 +148,13 @@ public class FabricWorldEdit implements ModInitializer {
this.provider = new FabricPermissionsProvider.VanillaPermissionsProvider(platform);
}
private void setupRegistries() {
private void setupRegistries(MinecraftServer server) {
// Blocks
for (Identifier name : Registry.BLOCK.getIds()) {
/*for (Identifier name : Registry.BLOCK.getIds()) {
if (BlockType.REGISTRY.get(name.toString()) == null) {
BlockType.REGISTRY.register(name.toString(), new BlockType(name.toString(),
input -> FabricAdapter.adapt(FabricAdapter.adapt(input.getBlockType()).getDefaultState())));
}
BlockType.REGISTRY.register(name.toString(), new BlockType(name.toString(), FabricAdapter.adapt(name));
}
}*/
// Items
for (Identifier name : Registry.ITEM.getIds()) {
if (ItemType.REGISTRY.get(name.toString()) == null) {
@ -144,18 +168,18 @@ public class FabricWorldEdit implements ModInitializer {
}
}
// Biomes
for (Identifier name : Registry.BIOME.getIds()) {
for (Identifier name : server.getRegistryManager().get(Registry.BIOME_KEY).getIds()) {
if (BiomeType.REGISTRY.get(name.toString()) == null) {
BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString()));
}
}
// Tags
for (Identifier name : BlockTags.getContainer().getKeys()) {
for (Identifier name : BlockTags.getTagGroup().getTagIds()) {
if (BlockCategory.REGISTRY.get(name.toString()) == null) {
BlockCategory.REGISTRY.register(name.toString(), new BlockCategory(name.toString()));
}
}
for (Identifier name : ItemTags.getContainer().getKeys()) {
for (Identifier name : ItemTags.getTagGroup().getTagIds()) {
if (ItemCategory.REGISTRY.get(name.toString()) == null) {
ItemCategory.REGISTRY.register(name.toString(), new ItemCategory(name.toString()));
}
@ -163,12 +187,16 @@ public class FabricWorldEdit implements ModInitializer {
}
private void onStartServer(MinecraftServer minecraftServer) {
FabricAdapter.setServer(minecraftServer);
setupPlatform(minecraftServer);
setupRegistries();
setupRegistries(minecraftServer);
config = new FabricConfiguration(this);
config.load();
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
minecraftServer.reloadResources(
minecraftServer.getDataPackManager().getEnabledNames()
);
}
private void onStopServer(MinecraftServer minecraftServer) {
@ -198,8 +226,9 @@ public class FabricWorldEdit implements ModInitializer {
blockPos.getY(),
blockPos.getZ()
);
com.sk89q.worldedit.util.Direction weDirection = FabricAdapter.adaptEnumFacing(direction);
if (we.handleBlockLeftClick(player, pos)) {
if (we.handleBlockLeftClick(player, pos, weDirection)) {
return ActionResult.SUCCESS;
}
@ -210,12 +239,6 @@ public class FabricWorldEdit implements ModInitializer {
return ActionResult.PASS;
}
public void onLeftClickAir(PlayerEntity playerEntity, World world, Hand hand) {
WorldEdit we = WorldEdit.getInstance();
FabricPlayer player = adaptPlayer((ServerPlayerEntity) playerEntity);
we.handleArmSwing(player);
}
private ActionResult onRightClickBlock(PlayerEntity playerEntity, World world, Hand hand, BlockHitResult blockHitResult) {
if (shouldSkip() || hand == Hand.OFF_HAND || world.isClient) {
return ActionResult.PASS;
@ -229,8 +252,9 @@ public class FabricWorldEdit implements ModInitializer {
blockHitResult.getBlockPos().getY(),
blockHitResult.getBlockPos().getZ()
);
com.sk89q.worldedit.util.Direction direction = FabricAdapter.adaptEnumFacing(blockHitResult.getSide());
if (we.handleBlockRightClick(player, pos)) {
if (we.handleBlockRightClick(player, pos, direction)) {
return ActionResult.SUCCESS;
}
@ -241,19 +265,20 @@ public class FabricWorldEdit implements ModInitializer {
return ActionResult.PASS;
}
private ActionResult onRightClickAir(PlayerEntity playerEntity, World world, Hand hand) {
private TypedActionResult<ItemStack> onRightClickAir(PlayerEntity playerEntity, World world, Hand hand) {
ItemStack stackInHand = playerEntity.getStackInHand(hand);
if (shouldSkip() || hand == Hand.OFF_HAND || world.isClient) {
return ActionResult.PASS;
return TypedActionResult.pass(stackInHand);
}
WorldEdit we = WorldEdit.getInstance();
FabricPlayer player = adaptPlayer((ServerPlayerEntity) playerEntity);
if (we.handleRightClick(player)) {
return ActionResult.SUCCESS;
return TypedActionResult.success(stackInHand);
}
return ActionResult.PASS;
return TypedActionResult.pass(stackInHand);
}
// TODO Pass empty left click to server
@ -303,8 +328,8 @@ public class FabricWorldEdit implements ModInitializer {
*
* @return the working directory
*/
public File getWorkingDir() {
return this.workingDir.toFile();
public Path getWorkingDir() {
return this.workingDir;
}
/**

Datei anzeigen

@ -19,14 +19,14 @@
package com.sk89q.worldedit.fabric;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.registry.state.Property;
import java.util.List;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkArgument;
class PropertyAdapter<T extends Comparable<T>> implements Property<T> {
private final net.minecraft.state.property.Property<T> property;
@ -49,7 +49,7 @@ class PropertyAdapter<T extends Comparable<T>> implements Property<T> {
@Override
public T getValueFor(String string) throws IllegalArgumentException {
Optional<T> val = property.getValue(string);
Optional<T> val = property.parse(string);
checkArgument(val.isPresent(), "%s has no value for %s", getName(), string);
return val.get();
}

Datei anzeigen

@ -19,11 +19,10 @@
package com.sk89q.worldedit.fabric;
import net.fabricmc.fabric.api.event.server.ServerTickCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@ -32,11 +31,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
/**
* Caches data that cannot be accessed from another thread safely.
*/
public class ThreadSafeCache implements ServerTickCallback {
public class ThreadSafeCache implements ServerTickEvents.EndTick {
private static final long REFRESH_DELAY = 1000 * 30;
private static final ThreadSafeCache INSTANCE = new ThreadSafeCache();
private Set<UUID> onlineIds = Collections.emptySet();
private Set<UUID> onlineIds = new CopyOnWriteArraySet<>();
private long lastRefresh = 0;
/**
@ -49,7 +48,7 @@ public class ThreadSafeCache implements ServerTickCallback {
}
@Override
public void tick(MinecraftServer server) {
public void onEndTick(MinecraftServer server) {
long now = System.currentTimeMillis();
if (now - lastRefresh > REFRESH_DELAY) {

Datei anzeigen

@ -27,10 +27,9 @@ import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.stat.Stat;
import net.minecraft.text.Text;
import net.minecraft.world.dimension.DimensionType;
import javax.annotation.Nullable;
import java.util.UUID;
import javax.annotation.Nullable;
public class WorldEditFakePlayer extends ServerPlayerEntity {
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
@ -52,17 +51,8 @@ public class WorldEditFakePlayer extends ServerPlayerEntity {
}
@Override
public void sendMessage(Text component) {
}
@Override
public void addChatMessage(Text component, boolean opt) {
}
@Nullable
@Override
public Entity changeDimension(DimensionType dimensionType) {
return this;
public void sendMessage(Text message, boolean actionBar) {
super.sendMessage(message, actionBar);
}
@Override

Datei anzeigen

@ -31,13 +31,15 @@ import net.minecraft.server.world.ServerChunkManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.WorldChunk;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Objects;
public class FabricWorldNativeAccess implements WorldNativeAccess<WorldChunk, BlockState, BlockPos> {
private static final int UPDATE = 1, NOTIFY = 2;
private static final int UPDATE = 1;
private static final int NOTIFY = 2;
private final WeakReference<World> world;
@ -75,7 +77,7 @@ public class FabricWorldNativeAccess implements WorldNativeAccess<WorldChunk, Bl
@Override
public BlockState getValidBlockForPosition(BlockState block, BlockPos position) {
return Block.getRenderingState(block, getWorld(), position);
return Block.postProcessState(block, getWorld(), position);
}
@Override
@ -96,7 +98,7 @@ public class FabricWorldNativeAccess implements WorldNativeAccess<WorldChunk, Bl
return false;
}
tileEntity.setLocation(getWorld(), position);
tileEntity.fromTag(nativeTag);
tileEntity.fromTag(getWorld().getBlockState(position), nativeTag);
return true;
}
@ -119,17 +121,16 @@ public class FabricWorldNativeAccess implements WorldNativeAccess<WorldChunk, Bl
public void notifyNeighbors(BlockPos pos, BlockState oldState, BlockState newState) {
getWorld().updateNeighbors(pos, oldState.getBlock());
if (newState.hasComparatorOutput()) {
getWorld().updateHorizontalAdjacent(pos, newState.getBlock());
getWorld().updateComparators(pos, newState.getBlock());
}
}
@Override
public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState) {
public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState, int recursionLimit) {
World world = getWorld();
// method_11637 = updateDiagonalNeighbors
oldState.method_11637(world, pos, NOTIFY);
newState.updateNeighborStates(world, pos, NOTIFY);
newState.method_11637(world, pos, NOTIFY);
oldState.prepare(world, pos, NOTIFY, recursionLimit);
newState.updateNeighbors(world, pos, NOTIFY, recursionLimit);
newState.prepare(world, pos, NOTIFY, recursionLimit);
}
@Override

Datei anzeigen

@ -28,6 +28,7 @@ import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntArrayTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongArrayTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
@ -59,6 +60,9 @@ public final class NBTConverter {
} else if (tag instanceof LongTag) {
return toNative((LongTag) tag);
} else if (tag instanceof LongArrayTag) {
return toNative((LongArrayTag) tag);
} else if (tag instanceof StringTag) {
return toNative((StringTag) tag);
@ -104,24 +108,27 @@ public final class NBTConverter {
}
public static net.minecraft.nbt.LongTag toNative(LongTag tag) {
return new net.minecraft.nbt.LongTag(tag.getValue());
return net.minecraft.nbt.LongTag.of(tag.getValue());
}
public static net.minecraft.nbt.LongArrayTag toNative(LongArrayTag tag) {
return new net.minecraft.nbt.LongArrayTag(tag.getValue().clone());
}
public static net.minecraft.nbt.StringTag toNative(StringTag tag) {
return new net.minecraft.nbt.StringTag(tag.getValue());
return net.minecraft.nbt.StringTag.of(tag.getValue());
}
public static net.minecraft.nbt.IntTag toNative(IntTag tag) {
return new net.minecraft.nbt.IntTag(tag.getValue());
return net.minecraft.nbt.IntTag.of(tag.getValue());
}
public static net.minecraft.nbt.ByteTag toNative(ByteTag tag) {
return new net.minecraft.nbt.ByteTag(tag.getValue());
return net.minecraft.nbt.ByteTag.of(tag.getValue());
}
public static net.minecraft.nbt.ByteArrayTag toNative(ByteArrayTag tag) {
byte[] value = tag.getValue();
return new net.minecraft.nbt.ByteArrayTag(Arrays.copyOf(value, value.length));
return new net.minecraft.nbt.ByteArrayTag(tag.getValue().clone());
}
public static net.minecraft.nbt.CompoundTag toNative(CompoundTag tag) {
@ -133,15 +140,15 @@ public final class NBTConverter {
}
public static net.minecraft.nbt.FloatTag toNative(FloatTag tag) {
return new net.minecraft.nbt.FloatTag(tag.getValue());
return net.minecraft.nbt.FloatTag.of(tag.getValue());
}
public static net.minecraft.nbt.ShortTag toNative(ShortTag tag) {
return new net.minecraft.nbt.ShortTag(tag.getValue());
return net.minecraft.nbt.ShortTag.of(tag.getValue());
}
public static net.minecraft.nbt.DoubleTag toNative(DoubleTag tag) {
return new net.minecraft.nbt.DoubleTag(tag.getValue());
return net.minecraft.nbt.DoubleTag.of(tag.getValue());
}
public static Tag fromNative(net.minecraft.nbt.Tag other) {
@ -157,6 +164,9 @@ public final class NBTConverter {
} else if (other instanceof net.minecraft.nbt.LongTag) {
return fromNative((net.minecraft.nbt.LongTag) other);
} else if (other instanceof net.minecraft.nbt.LongArrayTag) {
return fromNative((net.minecraft.nbt.LongArrayTag) other);
} else if (other instanceof net.minecraft.nbt.StringTag) {
return fromNative((net.minecraft.nbt.StringTag) other);
@ -191,7 +201,7 @@ public final class NBTConverter {
}
public static ListTag fromNative(net.minecraft.nbt.ListTag other) {
other = (net.minecraft.nbt.ListTag) other.copy();
other = other.copy();
List<Tag> list = new ArrayList<>();
Class<? extends Tag> listClass = StringTag.class;
int tags = other.size();
@ -211,6 +221,10 @@ public final class NBTConverter {
return new LongTag(other.getLong());
}
public static LongArrayTag fromNative(net.minecraft.nbt.LongArrayTag other) {
return new LongArrayTag(other.getLongArray().clone());
}
public static StringTag fromNative(net.minecraft.nbt.StringTag other) {
return new StringTag(other.asString());
}
@ -224,15 +238,14 @@ public final class NBTConverter {
}
public static ByteArrayTag fromNative(net.minecraft.nbt.ByteArrayTag other) {
byte[] value = other.getByteArray();
return new ByteArrayTag(Arrays.copyOf(value, value.length));
return new ByteArrayTag(other.getByteArray().clone());
}
public static CompoundTag fromNative(net.minecraft.nbt.CompoundTag other) {
Set<String> tags = other.getKeys();
Map<String, Tag> map = new HashMap<>();
for (String tagName : tags) {
map.put(tagName, fromNative(other.getTag(tagName)));
map.put(tagName, fromNative(other.get(tagName)));
}
return new CompoundTag(map);
}

Datei anzeigen

@ -1,31 +0,0 @@
/*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://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
String getClientLanguage();
}

Datei anzeigen

@ -20,15 +20,22 @@
package com.sk89q.worldedit.fabric.mixin;
import com.sk89q.worldedit.extension.platform.Watchdog;
import net.minecraft.server.ServerTask;
import com.sk89q.worldedit.fabric.internal.ExtendedMinecraftServer;
import net.minecraft.resource.ServerResourceManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.NonBlockingThreadExecutor;
import net.minecraft.util.SystemUtil;
import net.minecraft.server.ServerTask;
import net.minecraft.util.Util;
import net.minecraft.util.thread.ReentrantThreadExecutor;
import net.minecraft.world.World;
import net.minecraft.world.level.storage.LevelStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.nio.file.Path;
@Mixin(MinecraftServer.class)
public abstract class MixinMinecraftServer extends NonBlockingThreadExecutor<ServerTask> implements Watchdog {
public abstract class MixinMinecraftServer extends ReentrantThreadExecutor<ServerTask> implements Watchdog, ExtendedMinecraftServer {
public MixinMinecraftServer(String name) {
super(name);
@ -36,10 +43,20 @@ public abstract class MixinMinecraftServer extends NonBlockingThreadExecutor<Ser
@Shadow
private long timeReference;
@Shadow
protected LevelStorage.Session session;
@Override
public void tick() {
timeReference = SystemUtil.getMeasuringTimeMs();
timeReference = Util.getMeasuringTimeMs();
}
@Override
public Path getStoragePath(World world) {
return session.getWorldDirectory(world.getRegistryKey()).toPath();
}
@Accessor()
@Override
public abstract ServerResourceManager getServerResourceManager();
}

Datei anzeigen

@ -20,11 +20,11 @@
package com.sk89q.worldedit.fabric.mixin;
import com.mojang.authlib.GameProfile;
import com.sk89q.worldedit.fabric.FabricWorldEdit;
import net.minecraft.container.ContainerListener;
import com.sk89q.worldedit.fabric.internal.ExtendedPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.c2s.play.ClientSettingsC2SPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -32,14 +32,23 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayerEntity.class)
public abstract class MixinServerPlayerEntity extends PlayerEntity implements ContainerListener {
public abstract class MixinServerPlayerEntity extends PlayerEntity implements ExtendedPlayerEntity {
public MixinServerPlayerEntity(World world, GameProfile gameProfile) {
super(world, gameProfile);
private String language = "en_us";
public MixinServerPlayerEntity(World world, BlockPos blockPos, float yaw, GameProfile gameProfile) {
super(world, blockPos, yaw, gameProfile);
}
@Inject(method = "swingHand", at = @At(value = "HEAD"))
public void onSwing(Hand hand, CallbackInfo injectionInfo) {
FabricWorldEdit.inst.onLeftClickAir(this, this.world, hand);
@Inject(method = "setClientSettings", at = @At(value = "HEAD"))
public void setClientSettings(ClientSettingsC2SPacket clientSettingsC2SPacket,
CallbackInfo callbackInfo) {
this.language = ((AccessorClientSettingsC2SPacket) clientSettingsC2SPacket).getLanguage();
}
@Override
public String getLanguage() {
return language;
}
}

Datei anzeigen

@ -11,7 +11,6 @@ disallowed-blocks=minecraft:oak_sapling,minecraft:jungle_sapling,minecraft:dark_
max-super-pickaxe-size=5
max-brush-radius=10
craftscript-dir=craftscripts
no-double-slash=false
wand-item=minecraft:wooden_axe
shell-save-type=
scripting-timeout=3000
@ -20,6 +19,7 @@ use-inventory-creative-override=false
log-file=worldedit.log
log-format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n
max-changed-blocks=-1
default-vertical-height=256
nav-wand-distance=50
butcher-default-radius=-1
default-max-changed-blocks=-1

Datei anzeigen

@ -9,7 +9,7 @@
"sk89q",
"wizjany",
"TomyLobo",
"kenzierocks",
"octylFractal",
"Me4502"
],
"contact": {
@ -30,11 +30,13 @@
"depends": {
"fabricloader": ">=0.4.0",
"fabric-api-base": "*",
"fabric-events-lifecycle-v0": "*",
"fabric-command-api-v1": "*",
"fabric-lifecycle-events-v1": "*",
"fabric-events-interaction-v0": "*",
"fabric-networking-v0": "*"
},
"mixins": [
"worldedit.mixins.json"
]
],
"accessWidener" : "worldedit.accesswidener"
}

Datei anzeigen

@ -0,0 +1,2 @@
accessWidener v1 named
accessible class net/minecraft/server/world/ServerChunkManager$MainThreadExecutor

Datei anzeigen

@ -3,9 +3,12 @@
"package": "com.sk89q.worldedit.fabric.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
"MixinBiomeArray",
"MixinServerPlayerEntity",
"MixinMinecraftServer",
"AccessorServerPlayerEntity"
"AccessorClientSettingsC2SPacket",
"AccessorLevelProperties",
"AccessorServerChunkManager"
],
"server": [
],

Datei anzeigen

@ -12,12 +12,12 @@ plugins {
applyPlatformAndCoreConfiguration()
applyShadowConfiguration()
val minecraftVersion = "1.16.2"
val minecraftVersion = "1.16.3"
val nextMajorMinecraftVersion: String = minecraftVersion.split('.').let { (useless, major) ->
"$useless.${major.toInt() + 1}"
}
val mappingsMinecraftVersion = "1.16"
val forgeVersion = "32.0.92"
val forgeVersion = "34.0.0"
configurations.all {
resolutionStrategy {