From 3b87953da050b3ebce6a8df95a4d2eae7103aaf8 Mon Sep 17 00:00:00 2001 From: Yetanotherx Date: Sat, 31 Dec 2011 23:16:39 -0500 Subject: [PATCH] Add cuiVersion to LocalSession and set it via incoming CUI event Refactor region selectors to handle legacy versions a bit better. Because chat doesn't allow the section sign to be sent, I have to send non-color codes. Meh. closes #158 --- .../com/sk89q/worldedit/LocalSession.java | 55 +++++++++++++--- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 2 +- .../bukkit/WorldEditPlayerListener.java | 34 ++++++++-- .../worldedit/commands/WorldEditCommands.java | 6 +- .../com/sk89q/worldedit/cui/CUIEvent.java | 3 - .../worldedit/cui/CUIPointBasedRegion.java | 26 -------- .../com/sk89q/worldedit/cui/CUIRegion.java | 65 +++++++++++++++++++ .../regions/CuboidRegionSelector.java | 50 ++++++++------ .../regions/EllipsoidRegionSelector.java | 52 +++++++-------- .../regions/Polygonal2DRegionSelector.java | 38 +++++++---- .../worldedit/regions/RegionSelector.java | 14 ---- .../regions/SphereRegionSelector.java | 4 +- 12 files changed, 220 insertions(+), 129 deletions(-) delete mode 100644 src/main/java/com/sk89q/worldedit/cui/CUIPointBasedRegion.java create mode 100644 src/main/java/com/sk89q/worldedit/cui/CUIRegion.java diff --git a/src/main/java/com/sk89q/worldedit/LocalSession.java b/src/main/java/com/sk89q/worldedit/LocalSession.java index 05c2a1fb7..12b28bbec 100644 --- a/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -34,7 +34,7 @@ import com.sk89q.worldedit.tools.SinglePickaxe; import com.sk89q.worldedit.tools.BlockTool; import com.sk89q.worldedit.tools.Tool; import com.sk89q.worldedit.bags.BlockBag; -import com.sk89q.worldedit.cui.CUIPointBasedRegion; +import com.sk89q.worldedit.cui.CUIRegion; import com.sk89q.worldedit.cui.CUIEvent; import com.sk89q.worldedit.cui.SelectionShapeEvent; import com.sk89q.worldedit.masks.Mask; @@ -71,6 +71,7 @@ public class LocalSession { private String lastScript; private boolean beenToldVersion = false; private boolean hasCUISupport = false; + private int cuiVersion = -1; private boolean fastMode = false; private Mask mask; private TimeZone timezone = TimeZone.getDefault(); @@ -570,14 +571,34 @@ public class LocalSession { return; } - final String legacyTypeId = selector.getLegacyTypeId(); - if (legacyTypeId != null) { - player.dispatchCUIEvent(new SelectionShapeEvent(legacyTypeId)); - } - player.dispatchCUIEvent(new SelectionShapeEvent(selector.getTypeId())); + if (selector instanceof CUIRegion) { + CUIRegion tempSel = (CUIRegion) selector; + + if (tempSel.getProtocolVersion() > cuiVersion) { + player.dispatchCUIEvent(new SelectionShapeEvent(tempSel.getLegacyTypeID())); + tempSel.describeLegacyCUI(this, player); + } else { + player.dispatchCUIEvent(new SelectionShapeEvent(tempSel.getTypeID())); + tempSel.describeCUI(this, player); + } + + } + } + + public void describeCUI(LocalPlayer player) { + if (!hasCUISupport) { + return; + } + + if (selector instanceof CUIRegion) { + CUIRegion tempSel = (CUIRegion) selector; + + if (tempSel.getProtocolVersion() > cuiVersion) { + tempSel.describeLegacyCUI(this, player); + } else { + tempSel.describeCUI(this, player); + } - if (selector instanceof CUIPointBasedRegion) { - ((CUIPointBasedRegion) selector).describeCUI(player); } } @@ -599,6 +620,24 @@ public class LocalSession { hasCUISupport = true; } + /** + * Gets the client's CUI protocol version + * + * @return + */ + public int getCUIVersion() { + return cuiVersion; + } + + /** + * Sets the client's CUI protocol version + * + * @param CUIVersion + */ + public void setCUIVersion(int CUIVersion) { + this.cuiVersion = CUIVersion; + } + /** * Detect date from a user's input. * diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 49e1e453d..e74ebe688 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -140,8 +140,8 @@ public class BukkitPlayer extends LocalPlayer { @Override public void dispatchCUIHandshake() { - player.sendRawMessage("\u00A74\u00A75\u00A73\u00A74"); player.sendRawMessage("\u00A75\u00A76\u00A74\u00A75"); + player.sendRawMessage("\u00A74\u00A75\u00A73\u00A74"); } public Player getPlayer() { diff --git a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlayerListener.java b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlayerListener.java index 9056528a9..a020858f8 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlayerListener.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlayerListener.java @@ -24,6 +24,7 @@ import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.event.Event; import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerListener; @@ -32,15 +33,17 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldVector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Handles all events thrown in relation to a Player */ public class WorldEditPlayerListener extends PlayerListener { - /** - * Plugin. - */ + private WorldEditPlugin plugin; + private boolean ignoreLeftClickAir = false; + private final static Pattern cuipattern = Pattern.compile("u00a74u00a75u00a73u00a74([^|]*)\\|?(.*)"); /** * Called when a player plays an animation, such as an arm swing @@ -59,6 +62,7 @@ public class WorldEditPlayerListener extends PlayerListener { plugin.registerEvent("PLAYER_QUIT", this); plugin.registerEvent("PLAYER_INTERACT", this); plugin.registerEvent("PLAYER_COMMAND_PREPROCESS", this, Event.Priority.Low); + plugin.registerEvent("PLAYER_CHAT", this); } /** @@ -92,8 +96,6 @@ public class WorldEditPlayerListener extends PlayerListener { event.setMessage(StringUtil.joinString(split, " ")); } - private boolean ignoreLeftClickAir = false; - /** * Called when a player interacts * @@ -162,4 +164,26 @@ public class WorldEditPlayerListener extends PlayerListener { } } } + + @Override + public void onPlayerChat(PlayerChatEvent event) { + if (event.isCancelled()) { + return; + } + + Matcher matcher = cuipattern.matcher(event.getMessage()); + 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 ) { + } + } + + } + } } diff --git a/src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java b/src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java index f22261fe9..c68477887 100644 --- a/src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/WorldEditCommands.java @@ -32,7 +32,6 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.cui.CUIEvent; public class WorldEditCommands { private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); @@ -79,13 +78,10 @@ public class WorldEditCommands { usage = "", desc = "Complete CUI handshake", min = 0, - max = 1 + max = 0 ) public void cui(CommandContext args, LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { - if (args.getInteger(0, -1) < CUIEvent.MIN_PROTOCOL) { - player.printError("You are using an outdated version of WorldEdit CUI! The CUI may have reduced functionality until you update."); - } session.setCUISupport(true); session.dispatchCUISetup(player); } diff --git a/src/main/java/com/sk89q/worldedit/cui/CUIEvent.java b/src/main/java/com/sk89q/worldedit/cui/CUIEvent.java index 2169ddc46..690bc395e 100644 --- a/src/main/java/com/sk89q/worldedit/cui/CUIEvent.java +++ b/src/main/java/com/sk89q/worldedit/cui/CUIEvent.java @@ -21,9 +21,6 @@ package com.sk89q.worldedit.cui; public interface CUIEvent { - // The required protocol versions for communicating with the CUI - public static final int MIN_PROTOCOL = -1, CURRENT_PROTOCOL = 0; // TODO: Yetanotherx releases a new WECUI with protocol version 0. - public String getTypeId(); public String[] getParameters(); diff --git a/src/main/java/com/sk89q/worldedit/cui/CUIPointBasedRegion.java b/src/main/java/com/sk89q/worldedit/cui/CUIPointBasedRegion.java deleted file mode 100644 index dbe38072b..000000000 --- a/src/main/java/com/sk89q/worldedit/cui/CUIPointBasedRegion.java +++ /dev/null @@ -1,26 +0,0 @@ -// $Id$ -/* - * WorldEdit - * Copyright (C) 2010, 2011 sk89q - * - * 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.cui; - -import com.sk89q.worldedit.LocalPlayer; - -public interface CUIPointBasedRegion { - public void describeCUI(LocalPlayer player); -} diff --git a/src/main/java/com/sk89q/worldedit/cui/CUIRegion.java b/src/main/java/com/sk89q/worldedit/cui/CUIRegion.java new file mode 100644 index 000000000..85c3819cf --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/cui/CUIRegion.java @@ -0,0 +1,65 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q + * + * 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.cui; + +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalSession; + +public interface CUIRegion { + + /** + * Sends CUI events describing the region for + * versions of CUI equal to or greater than the + * value supplied by getProtocolVersion(). + * + */ + public void describeCUI(LocalSession session, LocalPlayer player); + + /** + * Sends CUI events describing the region for + * versions of CUI smaller than the value + * supplied by getProtocolVersion(). + * + */ + public void describeLegacyCUI(LocalSession session, LocalPlayer player); + + /** + * Returns the CUI version that is required to send + * up-to-date data. If the CUI version is smaller than + * this value, the legacy methods will be called. + * + * @return + */ + public int getProtocolVersion(); + + /** + * Returns the type ID to send to CUI in the selection event. + * @return + */ + public String getTypeID(); + + /** + * Returns the type ID to send to CUI in the selection + * event if the CUI is in legacy mode. + * + * @return + */ + public String getLegacyTypeID(); +} diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java index 03c2dfbcd..b2c584fef 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java @@ -27,7 +27,7 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIPointBasedRegion; +import com.sk89q.worldedit.cui.CUIRegion; import com.sk89q.worldedit.cui.SelectionPointEvent; /** @@ -35,7 +35,7 @@ import com.sk89q.worldedit.cui.SelectionPointEvent; * * @author sk89q */ -public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion { +public class CuboidRegionSelector implements RegionSelector, CUIRegion { protected BlockVector pos1; protected BlockVector pos2; protected CuboidRegion region; @@ -173,24 +173,6 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion return lines; } - public String getTypeId() { - return "cuboid"; - } - - public String getLegacyTypeId() { - return null; - } - - public void describeCUI(LocalPlayer player) { - if (pos1 != null) { - player.dispatchCUIEvent(new SelectionPointEvent(0, pos1, getArea())); - } - - if (pos2 != null) { - player.dispatchCUIEvent(new SelectionPointEvent(1, pos2, getArea())); - } - } - public int getArea() { if (pos1 == null) { return -1; @@ -202,4 +184,32 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion return region.getArea(); } + + public void describeCUI(LocalSession session, LocalPlayer player) { + if (pos1 != null) { + session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos1, getArea())); + } + + if (pos2 != null) { + session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos2, getArea())); + } + } + + public void describeLegacyCUI(LocalSession session, LocalPlayer player) { + describeCUI(session, player); + } + + public int getProtocolVersion() { + return 0; + } + + public String getTypeID() { + return "cuboid"; + } + + public String getLegacyTypeID() { + return "cuboid"; + } + + } diff --git a/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java index a818401b4..746f0025b 100644 --- a/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegionSelector.java @@ -27,7 +27,7 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIPointBasedRegion; +import com.sk89q.worldedit.cui.CUIRegion; import com.sk89q.worldedit.cui.SelectionEllipsoidPointEvent; import com.sk89q.worldedit.cui.SelectionPointEvent; @@ -36,7 +36,7 @@ import com.sk89q.worldedit.cui.SelectionPointEvent; * * @author TomyLobo */ -public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedRegion { +public class EllipsoidRegionSelector implements RegionSelector, CUIRegion { protected EllipsoidRegion region; public EllipsoidRegionSelector(LocalWorld world) { @@ -93,9 +93,7 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedReg player.print("Center position set to " + region.getCenter() + "."); } - session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(0, region.getCenter())); - session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius())); - legacyDescribeCUI(player, session); + session.describeCUI(player); } public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) { @@ -105,12 +103,11 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedReg player.print("Radius set to " + region.getRadius() + "."); } - session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius())); - legacyDescribeCUI(player, session); + session.describeCUI(player); } public void explainRegionAdjust(LocalPlayer player, LocalSession session) { - legacyDescribeCUI(player, session); + session.describeCUI(player); } public boolean isDefined() { @@ -157,35 +154,30 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedReg return lines; } - public String getTypeId() { - return "ellipsoid"; + public int getArea() { + return region.getArea(); } - public String getLegacyTypeId() { + public void describeCUI(LocalSession session, LocalPlayer player) { + session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(0, region.getCenter())); + session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius())); + } + + public void describeLegacyCUI(LocalSession session, LocalPlayer player) { + session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea())); + session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea())); + } + + public String getLegacyTypeID() { return "cuboid"; } - public void describeCUI(LocalPlayer player) { - player.dispatchCUIEvent(new SelectionEllipsoidPointEvent(0, region.getCenter())); - player.dispatchCUIEvent(new SelectionEllipsoidPointEvent(1, region.getRadius())); - legacyDescribeCUI(player); + public int getProtocolVersion() { + return 1; } - protected void legacyDescribeCUI(LocalPlayer player, LocalSession session) { - if (!session.hasCUISupport()) { - return; - } - - legacyDescribeCUI(player); - } - - private void legacyDescribeCUI(LocalPlayer player) { - player.dispatchCUIEvent(new SelectionPointEvent(0, region.getMinimumPoint(), getArea())); - player.dispatchCUIEvent(new SelectionPointEvent(1, region.getMaximumPoint(), getArea())); - } - - public int getArea() { - return region.getArea(); + public String getTypeID() { + return "ellipsoid"; } @Override diff --git a/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java index 5db2d59bc..3cceb5809 100644 --- a/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java @@ -29,7 +29,7 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.CUIPointBasedRegion; +import com.sk89q.worldedit.cui.CUIRegion; import com.sk89q.worldedit.cui.SelectionMinMaxEvent; import com.sk89q.worldedit.cui.SelectionPoint2DEvent; import com.sk89q.worldedit.cui.SelectionShapeEvent; @@ -39,7 +39,7 @@ import com.sk89q.worldedit.cui.SelectionShapeEvent; * * @author sk89q */ -public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedRegion { +public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { protected BlockVector pos1; protected Polygonal2DRegion region; @@ -116,7 +116,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) { player.print("Starting a new polygon at " + pos + "."); - session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeId())); + session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID())); session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea())); session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); } @@ -174,14 +174,6 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR return Collections.singletonList("# points: " + region.size()); } - public String getTypeId() { - return "polygon2d"; - } - - public String getLegacyTypeId() { - return null; - } - public int getArea() { return region.getArea(); } @@ -190,12 +182,30 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR return region.getPoints().size(); } - public void describeCUI(LocalPlayer player) { + public void describeCUI(LocalSession session, LocalPlayer player) { final List points = region.getPoints(); for (int id = 0; id < points.size(); id++) { - player.dispatchCUIEvent(new SelectionPoint2DEvent(id, points.get(id), getArea())); + session.dispatchCUIEvent(player, new SelectionPoint2DEvent(id, points.get(id), getArea())); } - player.dispatchCUIEvent(new SelectionMinMaxEvent(region.minY, region.maxY)); + session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); } + + public void describeLegacyCUI(LocalSession session, LocalPlayer player) { + describeCUI(session, player); + } + + public int getProtocolVersion() { + return 0; + } + + public String getTypeID() { + return "polygon2d"; + } + + public String getLegacyTypeID() { + return "polygon2d"; + } + + } diff --git a/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java index 935928405..6da17f2a1 100644 --- a/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java @@ -131,20 +131,6 @@ public interface RegionSelector { */ public String getTypeName(); - /** - * Get a lowercase space-less ID. - * - * @return - */ - public String getTypeId(); - - /** - * Gets an alternative ID, for which this region selector also sends data. - * - * @return - */ - public String getLegacyTypeId(); - /** * Get lines of information about the selection. * diff --git a/src/main/java/com/sk89q/worldedit/regions/SphereRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/SphereRegionSelector.java index 2eb3c56f6..17ac97e7b 100644 --- a/src/main/java/com/sk89q/worldedit/regions/SphereRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/SphereRegionSelector.java @@ -23,7 +23,6 @@ import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.cui.SelectionEllipsoidPointEvent; /** * Selector for spheres. @@ -65,8 +64,7 @@ public class SphereRegionSelector extends EllipsoidRegionSelector { player.print("Radius set to " + region.getRadius().getX() + "."); } - session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius())); - legacyDescribeCUI(player, session); + session.describeCUI(player); } @Override