Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow NBT on wand items #2755

Merged
merged 3 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.fastasyncworldedit.core.util.gson;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.util.concurrency.LazyReference;
import com.sk89q.worldedit.util.nbt.TagStringIO;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;

import java.io.IOException;
import java.lang.reflect.Type;

public final class BaseItemAdapter implements JsonDeserializer<BaseItem>, JsonSerializer<BaseItem> {

@Override
public BaseItem deserialize(JsonElement json, Type type, JsonDeserializationContext cont) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
JsonElement id = jsonObject.get("id");
if (id != null) {
ItemType itemType = ItemTypes.get(id.getAsString());
if (itemType == null) {
throw new JsonParseException("Could not parse item type `" + id + "`");
}
return new BaseItem(itemType);
}
ItemType itemType = cont.deserialize(jsonObject.get("itemType").getAsJsonObject(), ItemType.class);
JsonElement nbt = jsonObject.get("nbt");
if (nbt == null) {
return new BaseItem(itemType);
}
try {
return new BaseItem(itemType, LazyReference.computed(TagStringIO.get().asCompound(nbt.getAsString())));
} catch (IOException e) {
throw new JsonParseException("Could not deserialize BaseItem", e);
}
}

@Override
public JsonElement serialize(
final BaseItem baseItem,
final Type type,
final JsonSerializationContext jsonSerializationContext
) {
JsonObject obj = new JsonObject();
obj.add("itemType", jsonSerializationContext.serialize(baseItem.getType()));
try {
obj.add("nbt", baseItem.getNbt() == null ? null : new JsonPrimitive(TagStringIO.get().asString(baseItem.getNbt())));
return obj;
} catch (IOException e) {
throw new JsonParseException("Could not deserialize BaseItem", e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import com.sk89q.worldedit.command.tool.SinglePickaxe;
import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extent.NullExtent;
Expand Down Expand Up @@ -80,7 +81,6 @@
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.snapshot.experimental.Snapshot;
import com.zaxxer.sparsebits.SparseBitSet;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
Expand Down Expand Up @@ -182,8 +182,10 @@ public Object remove(int index) {
private String lastScript;
private RegionSelectorType defaultSelector;
private boolean useServerCUI = false; // Save this to not annoy players.
private ItemType wandItem;
private ItemType navWandItem;
//FAWE start - allow NBT
private BaseItem wandItem;
private BaseItem navWandItem;
//FAWE end

/**
* Construct the object.
Expand Down Expand Up @@ -1199,7 +1201,7 @@ public Tool getTool(ItemType item, Player player) {
tool = tools.get(item.getInternalId());
}
if (tool == SelectionWand.INSTANCE && !SelectionWand.INSTANCE.canUse(player)) {
tools.remove(wandItem.getInternalId());
tools.remove(wandItem.getType().getInternalId());
loadDefaults(player, true); // Permissions have changed so redo the player's current tools.
return null;
}
Expand Down Expand Up @@ -1253,18 +1255,20 @@ public void loadDefaults(Actor actor, boolean force) {
if (loadDefaults || force) {
loadDefaults = false;
LocalConfiguration config = WorldEdit.getInstance().getConfiguration();
ParserContext context = new ParserContext();
context.setActor(actor);
if (wandItem == null) {
wandItem = ItemTypes.parse(config.wandItem);
wandItem = WorldEdit.getInstance().getItemFactory().parseFromInput(config.wandItem, context);
}
if (navWandItem == null) {
navWandItem = ItemTypes.parse(config.navigationWand);
navWandItem = WorldEdit.getInstance().getItemFactory().parseFromInput(config.navigationWand, context);
}
synchronized (this.tools) {
if (tools.get(navWandItem.getInternalId()) == null && NavigationWand.INSTANCE.canUse(actor)) {
tools.put(navWandItem.getInternalId(), NavigationWand.INSTANCE);
if (tools.get(navWandItem.getType().getInternalId()) == null && NavigationWand.INSTANCE.canUse(actor)) {
tools.put(navWandItem.getType().getInternalId(), NavigationWand.INSTANCE);
}
if (tools.get(wandItem.getInternalId()) == null && SelectionWand.INSTANCE.canUse(actor)) {
tools.put(wandItem.getInternalId(), SelectionWand.INSTANCE);
if (tools.get(wandItem.getType().getInternalId()) == null && SelectionWand.INSTANCE.canUse(actor)) {
tools.put(wandItem.getType().getInternalId(), SelectionWand.INSTANCE);
}
}
}
Expand Down Expand Up @@ -1334,10 +1338,24 @@ public BrushTool getBrush(ItemType item) {
* @param item the item type
* @param tool the tool to set, which can be {@code null}
* @throws InvalidToolBindException if the item can't be bound to that item
* @deprecated use {@link #setTool(BaseItem, Tool)}
*/
@Deprecated
public void setTool(ItemType item, @Nullable Tool tool) throws InvalidToolBindException {
if (item.hasBlockType()) {
throw new InvalidToolBindException(item, Caption.of("worldedit.error.blocks-cant-be-used"));
setTool(new BaseItem(item), tool);
}

/**
* Set the tool.
*
* @param item the item type
* @param tool the tool to set, which can be {@code null}
* @throws InvalidToolBindException if the item can't be bound to that item
* @since TODO
*/
public void setTool(BaseItem item, @Nullable Tool tool) throws InvalidToolBindException {
if (item.getType().hasBlockType()) {
throw new InvalidToolBindException(item.getType(), Caption.of("worldedit.error.blocks-cant-be-used"));
}
if (tool instanceof SelectionWand) {
changeTool(this.wandItem, this.wandItem = item, tool);
Expand All @@ -1348,25 +1366,25 @@ public void setTool(ItemType item, @Nullable Tool tool) throws InvalidToolBindEx
setDirty();
return;
}
setTool(item.getDefaultState(), tool, null);
setTool(item, tool, null);
}

public void setTool(Player player, @Nullable Tool tool) throws InvalidToolBindException {
BaseItemStack item = player.getItemInHand(HandSide.MAIN_HAND);
setTool(item, tool, player);
}

private void changeTool(ItemType oldType, ItemType newType, Tool newTool) {
if (oldType != null) {
private void changeTool(BaseItem oldItem, BaseItem newItem, Tool newTool) {
if (oldItem != null) {
synchronized (this.tools) {
this.tools.remove(oldType.getInternalId());
this.tools.remove(oldItem.getType().getInternalId());
}
}
synchronized (this.tools) {
if (newTool == null) {
this.tools.remove(newType.getInternalId());
this.tools.remove(newItem.getType().getInternalId());
} else {
this.tools.put(newType.getInternalId(), newTool);
this.tools.put(newItem.getType().getInternalId(), newTool);
}
}
}
Expand All @@ -1376,11 +1394,11 @@ public void setTool(BaseItem item, @Nullable Tool tool, Player player) throws In
if (type.hasBlockType() && type.getBlockType().getMaterial().isAir()) {
throw new InvalidToolBindException(type, Caption.of("worldedit.error.blocks-cant-be-used"));
} else if (tool instanceof SelectionWand) {
changeTool(this.wandItem, this.wandItem = item.getType(), tool);
changeTool(this.wandItem, this.wandItem = item, tool);
setDirty();
return;
} else if (tool instanceof NavigationWand) {
changeTool(this.navWandItem, this.navWandItem = item.getType(), tool);
changeTool(this.navWandItem, this.navWandItem = item, tool);
setDirty();
return;
}
Expand Down Expand Up @@ -1877,20 +1895,46 @@ public TextureUtil getTextureUtil() {
* Get the preferred wand item for this user, or {@code null} to use the default
*
* @return item id of wand item, or {@code null}
* @deprecated use {@link #getWandBaseItem()}
*/
@Deprecated
public String getWandItem() {
return wandItem.getId();
return wandItem.getType().getId();
}

/**
* Get the preferred navigation wand item for this user, or {@code null} to use the default
*
* @return item id of nav wand item, or {@code null}
* @deprecated use {@link #getNavWandBaseItem()}
*/
@Deprecated
public String getNavWandItem() {
return navWandItem.getId();
return navWandItem.getType().getId();
}

//FAWE start
/**
* Get the preferred wand item for this user, or {@code null} to use the default
*
* @return item id of wand item, or {@code null}
* @since TODO
*/
public BaseItem getWandBaseItem() {
return wandItem == null ? null : new BaseItem(wandItem.getType(), wandItem.getNbtReference());
}

/**
* Get the preferred navigation wand item for this user, or {@code null} to use the default
*
* @return item id of nav wand item, or {@code null}
* @since TODO
*/
public BaseItem getNavWandBaseItem() {
return navWandItem == null ? null : new BaseItem(navWandItem.getType(), navWandItem.getNbtReference());
}
//FAWE end

/**
* Get the last block distribution stored in this session.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public ItemType getType() {
* @param itemType The type to set
*/
public void setType(ItemType itemType) {
checkNotNull(itemType);
this.itemType = itemType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.command.argument.SelectorChoice;
import com.sk89q.worldedit.command.tool.NavigationWand;
Expand All @@ -38,6 +39,8 @@
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
Expand Down Expand Up @@ -325,22 +328,29 @@ public void wand(
//FAWE start
session.loadDefaults(player, true);
//FAWE end
String wandId = navWand ? session.getNavWandItem() : session.getWandItem();
if (wandId == null) {
wandId = navWand ? we.getConfiguration().navigationWand : we.getConfiguration().wandItem;
}
ItemType itemType = ItemTypes.parse(wandId);
if (itemType == null) {
player.print(Caption.of("worldedit.wand.invalid"));
return;
BaseItem wand = navWand ? session.getNavWandBaseItem() : session.getWandBaseItem();
if (wand == null) {
String wandId = navWand ? we.getConfiguration().navigationWand : we.getConfiguration().wandItem;
//FAWE start - allow item NBT
ParserContext parserContext = new ParserContext();
parserContext.setActor(player);
parserContext.setSession(session);
try {
wand = WorldEdit.getInstance().getItemFactory().parseFromInput(wandId, parserContext);
} catch (InputParseException e) {
player.print(Caption.of("worldedit.wand.invalid"));
return;
}
}
player.giveItem(new BaseItemStack(itemType, 1));
System.out.println("a "+ wand);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stop finding my debug

player.giveItem(new BaseItemStack(wand.getType(), wand.getNbtReference(), 1));
//FAWE end
//FAWE start - instance-iate session
if (navWand) {
session.setTool(itemType, NavigationWand.INSTANCE);
session.setTool(wand, NavigationWand.INSTANCE);
player.print(Caption.of("worldedit.wand.navwand.info"));
} else {
session.setTool(itemType, SelectionWand.INSTANCE);
session.setTool(wand, SelectionWand.INSTANCE);
player.print(Caption.of("worldedit.wand.selwand.info"));
//FAWE end
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static void setToolNone(Player player, LocalSession session, boolean isBrush)
throws InvalidToolBindException {
//FAWE start
isBrush = session.getTool(player) instanceof BrushTool;
session.setTool(player.getItemInHand(HandSide.MAIN_HAND).getType(), null);
session.setTool(player.getItemInHand(HandSide.MAIN_HAND), null);
//FAWE end
player.print(Caption.of(isBrush ? "worldedit.brush.none.equip" : "worldedit.tool.none.equip"));
}
Expand All @@ -163,7 +163,7 @@ private static void setTool(
String translationKey
) throws InvalidToolBindException {
BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), tool);
session.setTool(itemStack, tool);
player.print(Caption.of(translationKey, itemStack.getRichName()));
sendUnbindInstruction(player, UNBIND_COMMAND_COMPONENT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void load() {
logFile = getString("log-file", logFile);
logFormat = getString("log-format", logFormat);
registerHelp = getBool("register-help", registerHelp);
wandItem = getString("wand-item", wandItem).toLowerCase(Locale.ROOT);
wandItem = getString("wand-item", wandItem);
try {
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
} catch (Throwable ignored) {
Expand All @@ -122,7 +122,7 @@ public void load() {
useInventory = getBool("use-inventory", useInventory);
useInventoryOverride = getBool("use-inventory-override", useInventoryOverride);
useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
navigationWand = getString("nav-wand-item", navigationWand).toLowerCase(Locale.ROOT);
navigationWand = getString("nav-wand-item", navigationWand);
try {
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
} catch (Throwable ignored) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void load() {

profile = config.getBoolean("debug", profile);
traceUnflushedSessions = config.getBoolean("debugging.trace-unflushed-sessions", traceUnflushedSessions);
wandItem = convertLegacyItem(config.getString("wand-item", wandItem)).toLowerCase(Locale.ROOT);
wandItem = convertLegacyItem(config.getString("wand-item", wandItem));

defaultChangeLimit = Math.max(-1, config.getInt(
"limits.max-blocks-changed.default", defaultChangeLimit));
Expand Down Expand Up @@ -130,7 +130,7 @@ public void load() {
useInventoryCreativeOverride
);

navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand)).toLowerCase(Locale.ROOT);
navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand));
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

package com.sk89q.worldedit.util.gson;

import com.fastasyncworldedit.core.util.gson.BaseItemAdapter;
import com.fastasyncworldedit.core.util.gson.ItemTypeAdapter;
import com.fastasyncworldedit.core.util.gson.RegionSelectorAdapter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.RegionSelector;
Expand All @@ -48,6 +50,7 @@ public static GsonBuilder createBuilder() {
//FAWE start
gsonBuilder.registerTypeAdapter(RegionSelector.class, new RegionSelectorAdapter());
gsonBuilder.registerTypeAdapter(ItemType.class, new ItemTypeAdapter());
gsonBuilder.registerTypeAdapter(BaseItem.class, new BaseItemAdapter());
//FAWE end
return gsonBuilder;
}
Expand Down
Loading