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
This commit is contained in:
Yetanotherx 2011-12-31 23:16:39 -05:00 committed by zml2008
parent 616f9a2360
commit 3b87953da0
12 changed files with 220 additions and 129 deletions

View File

@ -34,7 +34,7 @@ import com.sk89q.worldedit.tools.SinglePickaxe;
import com.sk89q.worldedit.tools.BlockTool; import com.sk89q.worldedit.tools.BlockTool;
import com.sk89q.worldedit.tools.Tool; import com.sk89q.worldedit.tools.Tool;
import com.sk89q.worldedit.bags.BlockBag; 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.CUIEvent;
import com.sk89q.worldedit.cui.SelectionShapeEvent; import com.sk89q.worldedit.cui.SelectionShapeEvent;
import com.sk89q.worldedit.masks.Mask; import com.sk89q.worldedit.masks.Mask;
@ -71,6 +71,7 @@ public class LocalSession {
private String lastScript; private String lastScript;
private boolean beenToldVersion = false; private boolean beenToldVersion = false;
private boolean hasCUISupport = false; private boolean hasCUISupport = false;
private int cuiVersion = -1;
private boolean fastMode = false; private boolean fastMode = false;
private Mask mask; private Mask mask;
private TimeZone timezone = TimeZone.getDefault(); private TimeZone timezone = TimeZone.getDefault();
@ -570,14 +571,34 @@ public class LocalSession {
return; return;
} }
final String legacyTypeId = selector.getLegacyTypeId(); if (selector instanceof CUIRegion) {
if (legacyTypeId != null) { CUIRegion tempSel = (CUIRegion) selector;
player.dispatchCUIEvent(new SelectionShapeEvent(legacyTypeId));
} if (tempSel.getProtocolVersion() > cuiVersion) {
player.dispatchCUIEvent(new SelectionShapeEvent(selector.getTypeId())); 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; 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. * Detect date from a user's input.
* *

View File

@ -140,8 +140,8 @@ public class BukkitPlayer extends LocalPlayer {
@Override @Override
public void dispatchCUIHandshake() { public void dispatchCUIHandshake() {
player.sendRawMessage("\u00A74\u00A75\u00A73\u00A74");
player.sendRawMessage("\u00A75\u00A76\u00A74\u00A75"); player.sendRawMessage("\u00A75\u00A76\u00A74\u00A75");
player.sendRawMessage("\u00A74\u00A75\u00A73\u00A74");
} }
public Player getPlayer() { public Player getPlayer() {

View File

@ -24,6 +24,7 @@ import org.bukkit.Bukkit;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerListener; import org.bukkit.event.player.PlayerListener;
@ -32,15 +33,17 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldVector; import com.sk89q.worldedit.WorldVector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* Handles all events thrown in relation to a Player * Handles all events thrown in relation to a Player
*/ */
public class WorldEditPlayerListener extends PlayerListener { public class WorldEditPlayerListener extends PlayerListener {
/**
* Plugin.
*/
private WorldEditPlugin 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 * 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_QUIT", this);
plugin.registerEvent("PLAYER_INTERACT", this); plugin.registerEvent("PLAYER_INTERACT", this);
plugin.registerEvent("PLAYER_COMMAND_PREPROCESS", this, Event.Priority.Low); 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, " ")); event.setMessage(StringUtil.joinString(split, " "));
} }
private boolean ignoreLeftClickAir = false;
/** /**
* Called when a player interacts * 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 ) {
}
}
}
}
} }

View File

@ -32,7 +32,6 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.cui.CUIEvent;
public class WorldEditCommands { public class WorldEditCommands {
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
@ -79,13 +78,10 @@ public class WorldEditCommands {
usage = "", usage = "",
desc = "Complete CUI handshake", desc = "Complete CUI handshake",
min = 0, min = 0,
max = 1 max = 0
) )
public void cui(CommandContext args, LocalSession session, LocalPlayer player, public void cui(CommandContext args, LocalSession session, LocalPlayer player,
EditSession editSession) throws WorldEditException { 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.setCUISupport(true);
session.dispatchCUISetup(player); session.dispatchCUISetup(player);
} }

View File

@ -21,9 +21,6 @@ package com.sk89q.worldedit.cui;
public interface CUIEvent { 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 getTypeId();
public String[] getParameters(); public String[] getParameters();

View File

@ -1,26 +0,0 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.cui;
import com.sk89q.worldedit.LocalPlayer;
public interface CUIPointBasedRegion {
public void describeCUI(LocalPlayer player);
}

View File

@ -0,0 +1,65 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
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();
}

View File

@ -27,7 +27,7 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.cui.CUIPointBasedRegion; import com.sk89q.worldedit.cui.CUIRegion;
import com.sk89q.worldedit.cui.SelectionPointEvent; import com.sk89q.worldedit.cui.SelectionPointEvent;
/** /**
@ -35,7 +35,7 @@ import com.sk89q.worldedit.cui.SelectionPointEvent;
* *
* @author sk89q * @author sk89q
*/ */
public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion { public class CuboidRegionSelector implements RegionSelector, CUIRegion {
protected BlockVector pos1; protected BlockVector pos1;
protected BlockVector pos2; protected BlockVector pos2;
protected CuboidRegion region; protected CuboidRegion region;
@ -173,24 +173,6 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
return lines; 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() { public int getArea() {
if (pos1 == null) { if (pos1 == null) {
return -1; return -1;
@ -202,4 +184,32 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
return region.getArea(); 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";
}
} }

View File

@ -27,7 +27,7 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector; 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.SelectionEllipsoidPointEvent;
import com.sk89q.worldedit.cui.SelectionPointEvent; import com.sk89q.worldedit.cui.SelectionPointEvent;
@ -36,7 +36,7 @@ import com.sk89q.worldedit.cui.SelectionPointEvent;
* *
* @author TomyLobo * @author TomyLobo
*/ */
public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedRegion { public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
protected EllipsoidRegion region; protected EllipsoidRegion region;
public EllipsoidRegionSelector(LocalWorld world) { public EllipsoidRegionSelector(LocalWorld world) {
@ -93,9 +93,7 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedReg
player.print("Center position set to " + region.getCenter() + "."); player.print("Center position set to " + region.getCenter() + ".");
} }
session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(0, region.getCenter())); session.describeCUI(player);
session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius()));
legacyDescribeCUI(player, session);
} }
public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) { 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() + "."); player.print("Radius set to " + region.getRadius() + ".");
} }
session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius())); session.describeCUI(player);
legacyDescribeCUI(player, session);
} }
public void explainRegionAdjust(LocalPlayer player, LocalSession session) { public void explainRegionAdjust(LocalPlayer player, LocalSession session) {
legacyDescribeCUI(player, session); session.describeCUI(player);
} }
public boolean isDefined() { public boolean isDefined() {
@ -157,35 +154,30 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIPointBasedReg
return lines; return lines;
} }
public String getTypeId() { public int getArea() {
return "ellipsoid"; 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"; return "cuboid";
} }
public void describeCUI(LocalPlayer player) { public int getProtocolVersion() {
player.dispatchCUIEvent(new SelectionEllipsoidPointEvent(0, region.getCenter())); return 1;
player.dispatchCUIEvent(new SelectionEllipsoidPointEvent(1, region.getRadius()));
legacyDescribeCUI(player);
} }
protected void legacyDescribeCUI(LocalPlayer player, LocalSession session) { public String getTypeID() {
if (!session.hasCUISupport()) { return "ellipsoid";
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();
} }
@Override @Override

View File

@ -29,7 +29,7 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector; 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.SelectionMinMaxEvent;
import com.sk89q.worldedit.cui.SelectionPoint2DEvent; import com.sk89q.worldedit.cui.SelectionPoint2DEvent;
import com.sk89q.worldedit.cui.SelectionShapeEvent; import com.sk89q.worldedit.cui.SelectionShapeEvent;
@ -39,7 +39,7 @@ import com.sk89q.worldedit.cui.SelectionShapeEvent;
* *
* @author sk89q * @author sk89q
*/ */
public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedRegion { public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
protected BlockVector pos1; protected BlockVector pos1;
protected Polygonal2DRegion region; protected Polygonal2DRegion region;
@ -116,7 +116,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) { public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) {
player.print("Starting a new polygon at " + 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 SelectionPoint2DEvent(0, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); 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()); return Collections.singletonList("# points: " + region.size());
} }
public String getTypeId() {
return "polygon2d";
}
public String getLegacyTypeId() {
return null;
}
public int getArea() { public int getArea() {
return region.getArea(); return region.getArea();
} }
@ -190,12 +182,30 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
return region.getPoints().size(); return region.getPoints().size();
} }
public void describeCUI(LocalPlayer player) { public void describeCUI(LocalSession session, LocalPlayer player) {
final List<BlockVector2D> points = region.getPoints(); final List<BlockVector2D> points = region.getPoints();
for (int id = 0; id < points.size(); id++) { 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";
}
} }

View File

@ -131,20 +131,6 @@ public interface RegionSelector {
*/ */
public String getTypeName(); 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. * Get lines of information about the selection.
* *

View File

@ -23,7 +23,6 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.cui.SelectionEllipsoidPointEvent;
/** /**
* Selector for spheres. * Selector for spheres.
@ -65,8 +64,7 @@ public class SphereRegionSelector extends EllipsoidRegionSelector {
player.print("Radius set to " + region.getRadius().getX() + "."); player.print("Radius set to " + region.getRadius().getX() + ".");
} }
session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius())); session.describeCUI(player);
legacyDescribeCUI(player, session);
} }
@Override @Override