From d0684c75826b3f8f91fc5c97be72bf8f6a9e2895 Mon Sep 17 00:00:00 2001 From: zml2008 Date: Thu, 2 Aug 2012 19:26:19 -0700 Subject: [PATCH] Add initial implementation of WECUI handling via Packet250 for Spout Update for latest Spout changes --- .../sk89q/worldedit/spout/SpoutPlayer.java | 48 +++++++-------- .../worldedit/spout/SpoutPlayerBlockBag.java | 4 +- .../worldedit/spout/WorldEditCUICodec.java | 60 +++++++++++++++++++ .../worldedit/spout/WorldEditCUIMessage.java | 53 ++++++++++++++++ .../spout/WorldEditCUIMessageHandler.java | 52 ++++++++++++++++ .../worldedit/spout/WorldEditListener.java | 22 ------- .../worldedit/spout/WorldEditPlugin.java | 9 ++- 7 files changed, 196 insertions(+), 52 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/spout/WorldEditCUICodec.java create mode 100644 src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java create mode 100644 src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessageHandler.java diff --git a/src/main/java/com/sk89q/worldedit/spout/SpoutPlayer.java b/src/main/java/com/sk89q/worldedit/spout/SpoutPlayer.java index 5ed3e114e..741b17bbe 100644 --- a/src/main/java/com/sk89q/worldedit/spout/SpoutPlayer.java +++ b/src/main/java/com/sk89q/worldedit/spout/SpoutPlayer.java @@ -30,8 +30,10 @@ import com.sk89q.worldedit.WorldVector; import com.sk89q.worldedit.bags.BlockBag; import com.sk89q.worldedit.cui.CUIEvent; +import org.spout.api.Client; import org.spout.api.chat.style.ChatStyle; import org.spout.api.entity.Entity; +import org.spout.api.entity.component.Controller; import org.spout.api.geo.discrete.Point; import org.spout.api.inventory.ItemStack; import org.spout.api.player.Player; @@ -52,9 +54,13 @@ public class SpoutPlayer extends LocalPlayer { @Override public int getItemInHand() { - VanillaPlayer vanillaPlayer = (VanillaPlayer) player.getEntity().getController(); - ItemStack itemStack = vanillaPlayer.getInventory().getQuickbar().getCurrentItem(); - return itemStack != null ? ((VanillaMaterial) itemStack.getMaterial()).getMinecraftId() : 0; + Controller controller = player.getController(); + if (controller instanceof VanillaPlayer) { + ItemStack itemStack = ((VanillaPlayer) controller).getInventory().getQuickbar().getCurrentItem(); + return itemStack != null ? ((VanillaMaterial) itemStack.getMaterial()).getMinecraftId() : 0; + } else { + return 0; + } } @Override @@ -64,25 +70,28 @@ public class SpoutPlayer extends LocalPlayer { @Override public WorldVector getPosition() { - Point loc = player.getEntity().getPosition(); + Point loc = player.getPosition(); return new WorldVector(SpoutUtil.getLocalWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ()); } @Override public double getPitch() { - return player.getEntity().getPitch(); + return player.getPitch(); } @Override public double getYaw() { - return player.getEntity().getYaw(); + return player.getYaw(); } @Override public void giveItem(int type, int amt) { - VanillaPlayer vanillaPlayer = (VanillaPlayer) player.getEntity().getController(); - vanillaPlayer.getInventory().addItem(new ItemStack(VanillaMaterials.getMaterial((short) type), amt), false); + Controller controller = player.getController(); + if (controller instanceof VanillaPlayer) { + ((VanillaPlayer) controller).getInventory() + .addItem(new ItemStack(VanillaMaterials.getMaterial((short) type), amt), false); + } } @Override @@ -115,10 +124,9 @@ public class SpoutPlayer extends LocalPlayer { @Override public void setPosition(Vector pos, float pitch, float yaw) { - final Entity entity = player.getEntity(); - entity.setPosition(SpoutUtil.toPoint(entity.getWorld(), pos)); - entity.setPitch(pitch); - entity.setYaw(yaw); + player.setPosition(SpoutUtil.toPoint(player.getWorld(), pos)); + player.setPitch(pitch); + player.setYaw(yaw); player.getNetworkSynchronizer().setPositionDirty(); } @@ -139,24 +147,12 @@ public class SpoutPlayer extends LocalPlayer { @Override public LocalWorld getWorld() { - return SpoutUtil.getLocalWorld(player.getEntity().getWorld()); + return SpoutUtil.getLocalWorld(player.getWorld()); } @Override public void dispatchCUIEvent(CUIEvent event) { - String[] params = event.getParameters(); - - if (params.length > 0) { - player.sendRawMessage("\u00A75\u00A76\u00A74\u00A75" + event.getTypeId() - + "|" + StringUtil.joinString(params, "|")); - } else { - player.sendRawMessage("\u00A75\u00A76\u00A74\u00A75" + event.getTypeId()); - } - } - - @Override - public void dispatchCUIHandshake() { - player.sendRawMessage("\u00A75\u00A76\u00A74\u00A75"); + player.getSession().send(player.getSession().getEngine() instanceof Client, new WorldEditCUIMessage(event)); } public Player getPlayer() { diff --git a/src/main/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java b/src/main/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java index ac4efbcc4..8b3c00523 100644 --- a/src/main/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java +++ b/src/main/java/com/sk89q/worldedit/spout/SpoutPlayerBlockBag.java @@ -60,7 +60,7 @@ public class SpoutPlayerBlockBag extends BlockBag { */ private void loadInventory() { if (items == null) { - items = VanillaPlayerUtil.getInventory(player.getEntity()).getContents(); + items = VanillaPlayerUtil.getInventory(player).getContents(); } } @@ -207,7 +207,7 @@ public class SpoutPlayerBlockBag extends BlockBag { @Override public void flushChanges() { if (items != null) { - InventoryBase inv = VanillaPlayerUtil.getInventory(player.getEntity()); + InventoryBase inv = VanillaPlayerUtil.getInventory(player); for (int i = 0; i < items.length && i < inv.getSize(); ++i) { inv.setItem(i, items[i]); } diff --git a/src/main/java/com/sk89q/worldedit/spout/WorldEditCUICodec.java b/src/main/java/com/sk89q/worldedit/spout/WorldEditCUICodec.java new file mode 100644 index 000000000..b24a4adb4 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/spout/WorldEditCUICodec.java @@ -0,0 +1,60 @@ +/* + * WorldEdit + * Copyright (C) 2012 sk89q 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 . + */ + +package com.sk89q.worldedit.spout; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.spout.api.protocol.MessageCodec; +import org.spout.api.util.Named; + +import java.nio.charset.Charset; + +/** + * @author zml2008 + */ +public class WorldEditCUICodec extends MessageCodec implements Named { + public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8"); + + public WorldEditCUICodec(int opcode) { + super(WorldEditCUIMessage.class, opcode); + } + + @Override + public ChannelBuffer encode(WorldEditCUIMessage message) { + byte[] data = message.getMessage().getBytes(UTF_8_CHARSET); + + ChannelBuffer buffer = ChannelBuffers.buffer(data.length + 2); + buffer.writeShort(data.length); + buffer.writeBytes(data); + return buffer; + } + + @Override + public WorldEditCUIMessage decode(ChannelBuffer buffer) { + byte[] data = new byte[buffer.readShort()]; + buffer.readBytes(data); + String message = new String(data, UTF_8_CHARSET); + return new WorldEditCUIMessage(message); + } + + @Override + public String getName() { + return "WECUI"; + } +} diff --git a/src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java b/src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java new file mode 100644 index 000000000..c1b22df57 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessage.java @@ -0,0 +1,53 @@ +/* + * WorldEdit + * Copyright (C) 2012 sk89q 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 . + */ + +package com.sk89q.worldedit.spout; + +import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.cui.CUIEvent; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.spout.api.protocol.Message; +import org.spout.api.util.SpoutToStringStyle; + +public class WorldEditCUIMessage extends Message { + private final String message; + + public WorldEditCUIMessage(String mesage) { + this.message = mesage; + } + + public WorldEditCUIMessage(CUIEvent event) { + String[] params = event.getParameters(); + if (params.length > 0) { + this.message = event.getTypeId() + '|' + StringUtil.joinString(event.getParameters(), "|"); + } else { + this.message = event.getTypeId(); + } + } + + public String getMessage() { + return message; + } + + @Override + public String toString() { + return new ToStringBuilder(this, SpoutToStringStyle.INSTANCE) + .append("message", message) + .toString(); + } +} diff --git a/src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessageHandler.java b/src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessageHandler.java new file mode 100644 index 000000000..901897448 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/spout/WorldEditCUIMessageHandler.java @@ -0,0 +1,52 @@ +/* + * WorldEdit + * Copyright (C) 2012 sk89q 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 . + */ + +package com.sk89q.worldedit.spout; + +import com.sk89q.worldedit.LocalSession; +import org.spout.api.protocol.MessageHandler; +import org.spout.api.protocol.Session; + +/** + * MessageHandler for WorldEditCUIMessage + */ +public class WorldEditCUIMessageHandler extends MessageHandler { + private final WorldEditPlugin plugin; + + public WorldEditCUIMessageHandler(WorldEditPlugin plugin) { + this.plugin = plugin; + } + + @Override + public void handleServer(Session session, WorldEditCUIMessage message) { + LocalSession localSession = plugin.getSession(session.getPlayer()); + if (localSession.hasCUISupport()) { // Already initialized + return; + } + + String[] text = message.getMessage().split("\\|"); + if (text.length > 1 && text[0].equalsIgnoreCase("v")) { // enough fields and right message + localSession.setCUISupport(true); + try { + localSession.setCUIVersion(Integer.parseInt(text[1])); + } catch (NumberFormatException e) { + plugin.getLogger().warning("Error while reading CUI init message: " + e.getMessage()); + } + } + } +} diff --git a/src/main/java/com/sk89q/worldedit/spout/WorldEditListener.java b/src/main/java/com/sk89q/worldedit/spout/WorldEditListener.java index 21ff18914..4a4e220ae 100644 --- a/src/main/java/com/sk89q/worldedit/spout/WorldEditListener.java +++ b/src/main/java/com/sk89q/worldedit/spout/WorldEditListener.java @@ -179,28 +179,6 @@ public class WorldEditListener implements Listener { } } - @EventHandler - public void onPlayerChat(PlayerChatEvent event) { - if (event.isCancelled()) { - return; - } - - Matcher matcher = cuipattern.matcher(event.getMessage().getPlainString()); - if (matcher.find()) { - String type = matcher.group(1); - String args = matcher.group(2); - - if( type.equals("v") ) { - try { - plugin.getSession(event.getPlayer()).setCUIVersion(Integer.parseInt(args)); - event.setCancelled(true); - } catch( NumberFormatException e ) { - } - } - - } - } - @EventHandler public void onWorldLoad(WorldLoadEvent event) { if (event.getWorld().getGenerator() instanceof BiomeGenerator) { diff --git a/src/main/java/com/sk89q/worldedit/spout/WorldEditPlugin.java b/src/main/java/com/sk89q/worldedit/spout/WorldEditPlugin.java index 2afa683ce..cdaacb161 100644 --- a/src/main/java/com/sk89q/worldedit/spout/WorldEditPlugin.java +++ b/src/main/java/com/sk89q/worldedit/spout/WorldEditPlugin.java @@ -36,6 +36,7 @@ import org.spout.api.command.CommandSource; import org.spout.api.geo.World; import org.spout.api.player.Player; import org.spout.api.plugin.CommonPlugin; +import org.spout.api.protocol.Protocol; import org.spout.api.scheduler.TaskPriority; import java.io.*; @@ -99,6 +100,10 @@ public class WorldEditPlugin extends CommonPlugin { // Now we can register events! registerEvents(); + for (Protocol proto : Protocol.getProtocols()) { + proto.registerPacket(WorldEditCUICodec.class, new WorldEditCUIMessageHandler(this)); + } + getEngine().getScheduler().scheduleAsyncRepeatingTask(this, new SessionTimer(controller, getEngine()), 6 * 1000, 6 * 1000, TaskPriority.LOWEST); } @@ -304,7 +309,7 @@ public class WorldEditPlugin extends CommonPlugin { } LocalSession session = controller.getSession(wrapPlayer(player)); - RegionSelector selector = session.getRegionSelector(SpoutUtil.getLocalWorld(player.getEntity().getWorld())); + RegionSelector selector = session.getRegionSelector(SpoutUtil.getLocalWorld(player.getWorld())); try { Region region = selector.getRegion(); @@ -341,7 +346,7 @@ public class WorldEditPlugin extends CommonPlugin { LocalSession session = controller.getSession(wrapPlayer(player)); RegionSelector sel = selection.getRegionSelector(); - session.setRegionSelector(SpoutUtil.getLocalWorld(player.getEntity().getWorld()), sel); + session.setRegionSelector(SpoutUtil.getLocalWorld(player.getWorld()), sel); session.dispatchCUISelection(wrapPlayer(player)); }