More file moving.

This commit is contained in:
sk89q
2011-05-01 01:30:33 -07:00
parent 4bcbfa76ef
commit 582b98dad0
206 changed files with 133 additions and 2 deletions

View File

@ -0,0 +1,130 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit.migration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashMap;
import org.bukkit.util.config.Configuration;
public class ConfigurationPermissionsResolver implements PermissionsResolver {
private Configuration config;
private Map<String,Set<String>> userPermissionsCache;
private Set<String> defaultPermissionsCache;
private Map<String,Set<String>> userGroups;
public ConfigurationPermissionsResolver(Configuration config) {
this.config = config;
}
public void load() {
userGroups = new HashMap<String,Set<String>>();
userPermissionsCache = new HashMap<String,Set<String>>();
defaultPermissionsCache = new HashSet<String>();
Map<String,Set<String>> userGroupPermissions = new HashMap<String,Set<String>>();
List<String> groupKeys = config.getKeys("permissions.groups");
if (groupKeys != null) {
for (String key : groupKeys) {
List<String> permissions =
config.getStringList("permissions.groups." + key + ".permissions", null);
if (permissions.size() > 0) {
Set<String> groupPerms = new HashSet<String>(permissions);
userGroupPermissions.put(key, groupPerms);
if (key.equals("default")) {
defaultPermissionsCache.addAll(permissions);
}
}
}
}
List<String> userKeys = config.getKeys("permissions.users");
if (userKeys != null) {
for (String key : userKeys) {
Set<String> permsCache = new HashSet<String>();
List<String> permissions =
config.getStringList("permissions.users." + key + ".permissions", null);
if (permissions.size() > 0) {
permsCache.addAll(permissions);
}
List<String> groups =
config.getStringList("permissions.users." + key + ".groups", null);
groups.add("default");
if (groups.size() > 0) {
for (String group : groups) {
Set<String> groupPerms = userGroupPermissions.get(group);
if (groupPerms != null) {
permsCache.addAll(groupPerms);
}
}
}
userPermissionsCache.put(key.toLowerCase(), permsCache);
userGroups.put(key.toLowerCase(), new HashSet<String>(groups));
}
}
}
public boolean hasPermission(String player, String permission) {
int dotPos = permission.lastIndexOf(".");
if (dotPos > -1) {
if (hasPermission(player, permission.substring(0, dotPos))) {
return true;
}
}
Set<String> perms = userPermissionsCache.get(player.toLowerCase());
if (perms == null) {
return defaultPermissionsCache.contains(permission)
|| defaultPermissionsCache.contains("*");
}
return perms.contains("*") || perms.contains(permission);
}
public boolean inGroup(String player, String group) {
Set<String> groups = userGroups.get(player.toLowerCase());
if (groups == null) {
return false;
}
return groups.contains(group);
}
public String[] getGroups(String player) {
Set<String> groups = userGroups.get(player.toLowerCase());
if (groups == null) {
return new String[0];
}
return groups.toArray(new String[groups.size()]);
}
}

View File

@ -0,0 +1,189 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit.migration;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.HashMap;
public class FlatFilePermissionsResolver implements PermissionsResolver {
private Map<String,Set<String>> userPermissionsCache;
private Set<String> defaultPermissionsCache;
private Map<String,Set<String>> userGroups;
public FlatFilePermissionsResolver() {
}
public static boolean filesExists() {
return (new File("perms_groups.txt")).exists()
&& (new File("perms_users.txt")).exists();
}
public Map<String,Set<String>> loadGroupPermissions() {
Map<String,Set<String>> userGroupPermissions = new HashMap<String,Set<String>>();
File file = new File("perms_groups.txt");
FileReader input = null;
try {
input = new FileReader(file);
BufferedReader buff = new BufferedReader(input);
String line;
while ((line = buff.readLine()) != null) {
line = line.trim();
// Blank line
if (line.length() == 0) {
continue;
} else if (line.charAt(0) == ';' || line.charAt(0) == '#') {
continue;
}
String[] parts = line.split(":");
String key = parts[0];
if (parts.length > 1) {
String[] perms = parts[1].split(",");
Set<String> groupPerms = new HashSet<String>(Arrays.asList(perms));
userGroupPermissions.put(key, groupPerms);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e2) {
}
}
return userGroupPermissions;
}
public void load() {
userGroups = new HashMap<String,Set<String>>();
userPermissionsCache = new HashMap<String,Set<String>>();
defaultPermissionsCache = new HashSet<String>();
Map<String,Set<String>> userGroupPermissions = loadGroupPermissions();
if (userGroupPermissions.containsKey("default")) {
defaultPermissionsCache = userGroupPermissions.get("default");
}
File file = new File("perms_users.txt");
FileReader input = null;
try {
input = new FileReader(file);
BufferedReader buff = new BufferedReader(input);
String line;
while ((line = buff.readLine()) != null) {
Set<String> permsCache = new HashSet<String>();
line = line.trim();
// Blank line
if (line.length() == 0) {
continue;
} else if (line.charAt(0) == ';' || line.charAt(0) == '#') {
continue;
}
String[] parts = line.split(":");
String key = parts[0];
if (parts.length > 1) {
String[] groups = (parts[1] + ",default").split(",");
String[] perms = parts.length > 2 ? parts[2].split(",") : new String[0];
permsCache.addAll(Arrays.asList(perms));
for (String group : groups) {
Set<String> groupPerms = userGroupPermissions.get(group);
if (groupPerms != null) {
permsCache.addAll(groupPerms);
}
}
userPermissionsCache.put(key.toLowerCase(), permsCache);
userGroups.put(key.toLowerCase(), new HashSet<String>(Arrays.asList(groups)));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e2) {
}
}
}
public boolean hasPermission(String player, String permission) {
int dotPos = permission.lastIndexOf(".");
if (dotPos > -1) {
if (hasPermission(player, permission.substring(0, dotPos))) {
return true;
}
}
Set<String> perms = userPermissionsCache.get(player.toLowerCase());
if (perms == null) {
return defaultPermissionsCache.contains(permission)
|| defaultPermissionsCache.contains("*");
}
return perms.contains("*") || perms.contains(permission);
}
public boolean inGroup(String player, String group) {
Set<String> groups = userGroups.get(player.toLowerCase());
if (groups == null) {
return false;
}
return groups.contains(group);
}
public String[] getGroups(String player) {
Set<String> groups = userGroups.get(player.toLowerCase());
if (groups == null) {
return new String[0];
}
return groups.toArray(new String[groups.size()]);
}
}

View File

@ -0,0 +1,114 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit.migration;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import com.nijikokun.bukkit.Permissions.Permissions;
public class NijiPermissionsResolver implements PermissionsResolver {
private Server server;
private Permissions api;
public void load() {
}
public NijiPermissionsResolver(Server server)
throws PluginAccessException, MissingPluginException {
this.server = server;
PluginManager manager = server.getPluginManager();
Plugin plugin = manager.getPlugin("Permissions");
if (plugin == null) {
throw new MissingPluginException();
}
try {
api = (Permissions)plugin;
} catch (ClassCastException e) {
throw new PluginAccessException();
}
}
@SuppressWarnings("static-access")
public boolean hasPermission(String name, String permission) {
try {
Player player = server.getPlayer(name);
if (player == null) return false;
try {
return api.getHandler().has(player, permission);
} catch (Throwable t) {
return api.Security.permission(player, permission);
}
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
@SuppressWarnings({ "static-access", "deprecation" })
public boolean inGroup(String name, String group) {
try {
Player player = server.getPlayer(name);
if (player == null) return false;
try {
return api.getHandler().inGroup(player.getWorld().getName(), name, group);
} catch (Throwable t) {
return api.Security.inGroup(name, group);
}
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
@SuppressWarnings({ "static-access", "deprecation" })
public String[] getGroups(String name) {
try {
Player player = server.getPlayer(name);
if (player == null) return new String[0];
String group;
try {
group = api.getHandler().getGroup(player.getWorld().getName(), player.getName());
} catch (Throwable t) {
group = api.Security.getGroup(player.getName());
}
if (group == null) {
return new String[0];
} else {
return new String[]{ group };
}
} catch (Throwable t) {
t.printStackTrace();
return new String[0];
}
}
public static class PluginAccessException extends Exception {
private static final long serialVersionUID = 7044832912491608706L;
}
public static class MissingPluginException extends Exception {
private static final long serialVersionUID = 7044832912491608706L;
}
}

View File

@ -0,0 +1,26 @@
// $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.bukkit.migration;
public interface PermissionsProvider {
public boolean hasPermission(String name, String permission);
public boolean inGroup(String player, String group);
public String[] getGroups(String player);
}

View File

@ -0,0 +1,27 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit.migration;
public interface PermissionsResolver {
public void load();
public boolean hasPermission(String name, String permission);
public boolean inGroup(String player, String group);
public String[] getGroups(String player);
}

View File

@ -0,0 +1,113 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit.migration;
import java.util.logging.Logger;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.config.Configuration;
public class PermissionsResolverManager implements PermissionsResolver {
private Configuration config;
private Server server;
private PermissionsResolver perms;
private String name;
private Logger logger;
public PermissionsResolverManager(Configuration config, Server server, String name, Logger logger) {
this.config = config;
this.server = server;
this.name = name;
this.logger = logger;
findResolver();
}
public void findResolver() {
if (tryPluginPermissionsResolver()) return;
if (tryNijiPermissions()) return;
if (tryFlatFilePermissions()) return;
perms = new ConfigurationPermissionsResolver(config);
logger.info(name + ": No known permissions plugin detected. Using configuration file for permissions.");
}
private boolean tryNijiPermissions() {
try {
perms = new NijiPermissionsResolver(server);
logger.info(name + ": Permissions plugin detected! Using Permissions plugin for permissions.");
return true;
} catch (Throwable e) {
return false;
}
}
private boolean tryFlatFilePermissions() {
if (FlatFilePermissionsResolver.filesExists()) {
perms = new FlatFilePermissionsResolver();
logger.info(name + ": perms_groups.txt and perms_users.txt detected! Using flat file permissions.");
return true;
}
return false;
}
private boolean tryPluginPermissionsResolver() {
for (Plugin plugin : server.getPluginManager().getPlugins()) {
if (plugin instanceof PermissionsProvider) {
perms = new PluginPermissionsResolver(
(PermissionsProvider) plugin);
logger.info(name + ": Using plugin '"
+ plugin.getDescription().getName() + " for permissions.");
return true;
}
}
return false;
}
public void setPluginPermissionsResolver(Plugin plugin) {
if (!(plugin instanceof PermissionsProvider)) {
return;
}
perms = new PluginPermissionsResolver(
(PermissionsProvider) plugin);
logger.info(name + ": Using plugin '"
+ plugin.getDescription().getName() + " for permissions.");
}
public void load() {
perms.load();
}
public boolean hasPermission(String name, String permission) {
return perms.hasPermission(name, permission);
}
public boolean inGroup(String player, String group) {
return perms.inGroup(player, group);
}
public String[] getGroups(String player) {
return perms.getGroups(player);
}
}

View File

@ -0,0 +1,78 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit.migration;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.event.server.ServerListener;
import org.bukkit.plugin.Plugin;
public class PermissionsResolverServerListener extends ServerListener {
private PermissionsResolverManager manager;
public PermissionsResolverServerListener(PermissionsResolverManager manager) {
this.manager = manager;
}
/**
* Called when a plugin is enabled
*
* @param event Relevant event details
*/
@Override
public void onPluginEnable(PluginEnableEvent event) {
Plugin plugin = event.getPlugin();
String name = plugin.getDescription().getName();
if (plugin instanceof PermissionsProvider) {
manager.setPluginPermissionsResolver(plugin);
} else if (name.equalsIgnoreCase("GroupUsers") || name.equalsIgnoreCase("Permissions")) {
manager.findResolver();
manager.load();
}
}
/**
* Called when a plugin is disabled
*
* @param event Relevant event details
*/
@Override
public void onPluginDisable(PluginDisableEvent event) {
Plugin plugin = event.getPlugin();
String name = plugin.getDescription().getName();
if (plugin instanceof PermissionsProvider
|| name.equalsIgnoreCase("GroupUsers")
|| name.equalsIgnoreCase("Permissions")) {
manager.findResolver();
manager.load();
}
}
public void register(Plugin plugin) {
plugin.getServer().getPluginManager().registerEvent(Event.Type.PLUGIN_ENABLE,
this, Priority.Normal, plugin);
plugin.getServer().getPluginManager().registerEvent(Event.Type.PLUGIN_DISABLE,
this, Priority.Normal, plugin);
}
}

View File

@ -0,0 +1,45 @@
// $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.bukkit.migration;
public class PluginPermissionsResolver implements PermissionsResolver {
protected PermissionsProvider resolver;
public PluginPermissionsResolver(PermissionsProvider resolver) {
this.resolver = resolver;
}
public void load() {
}
public boolean hasPermission(String name, String permission) {
return resolver.hasPermission(name, permission);
}
public boolean inGroup(String player, String group) {
return resolver.inGroup(player, group);
}
public String[] getGroups(String player) {
return resolver.getGroups(player);
}
}

View File

@ -0,0 +1,87 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Byte_Array</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class ByteArrayTag extends Tag {
/**
* The value.
*/
private final byte[] value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public ByteArrayTag(String name, byte[] value) {
super(name);
this.value = value;
}
@Override
public byte[] getValue() {
return value;
}
@Override
public String toString() {
StringBuilder hex = new StringBuilder();
for (byte b : value) {
String hexDigits = Integer.toHexString(b).toUpperCase();
if (hexDigits.length() == 1) {
hex.append("0");
}
hex.append(hexDigits).append(" ");
}
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Byte_Array" + append + ": " + hex.toString();
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Byte</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class ByteTag extends Tag {
/**
* The value.
*/
private final byte value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public ByteTag(String name, byte value) {
super(name);
this.value = value;
}
@Override
public Byte getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Byte" + append + ": " + value;
}
}

View File

@ -0,0 +1,90 @@
package com.sk89q.jnbt;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.Collections;
import java.util.Map;
import com.sk89q.jnbt.Tag;
/**
* The <code>TAG_Compound</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class CompoundTag extends Tag {
/**
* The value.
*/
private final Map<String, Tag> value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public CompoundTag(String name, Map<String, Tag> value) {
super(name);
this.value = Collections.unmodifiableMap(value);
}
@Override
public Map<String, Tag> getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_Compound" + append + ": " + value.size()
+ " entries\r\n{\r\n");
for (Map.Entry<String, Tag> entry : value.entrySet()) {
bldr.append(" "
+ entry.getValue().toString().replaceAll("\r\n", "\r\n ")
+ "\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Double</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class DoubleTag extends Tag {
/**
* The value.
*/
private final double value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public DoubleTag(String name, double value) {
super(name);
this.value = value;
}
@Override
public Double getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Double" + append + ": " + value;
}
}

View File

@ -0,0 +1,63 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_End</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class EndTag extends Tag {
/**
* Creates the tag.
*/
public EndTag() {
super("");
}
@Override
public Object getValue() {
return null;
}
@Override
public String toString() {
return "TAG_End";
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Float</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class FloatTag extends Tag {
/**
* The value.
*/
private final float value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public FloatTag(String name, float value) {
super(name);
this.value = value;
}
@Override
public Float getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Float" + append + ": " + value;
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Int</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class IntTag extends Tag {
/**
* The value.
*/
private final int value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public IntTag(String name, int value) {
super(name);
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Int" + append + ": " + value;
}
}

View File

@ -0,0 +1,108 @@
package com.sk89q.jnbt;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.Collections;
import java.util.List;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.Tag;
/**
* The <code>TAG_List</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class ListTag extends Tag {
/**
* The type.
*/
private final Class<? extends Tag> type;
/**
* The value.
*/
private final List<Tag> value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param type
* The type of item in the list.
* @param value
* The value.
*/
public ListTag(String name, Class<? extends Tag> type, List<Tag> value) {
super(name);
this.type = type;
this.value = Collections.unmodifiableList(value);
}
/**
* Gets the type of item in this list.
*
* @return The type of item in this list.
*/
public Class<? extends Tag> getType() {
return type;
}
@Override
public List<Tag> getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_List" + append + ": " + value.size()
+ " entries of type " + NBTUtils.getTypeName(type)
+ "\r\n{\r\n");
for (Tag t : value) {
bldr.append(" " + t.toString().replaceAll("\r\n", "\r\n ")
+ "\r\n");
}
bldr.append("}");
return bldr.toString();
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Long</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class LongTag extends Tag {
/**
* The value.
*/
private final long value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public LongTag(String name, long value) {
super(name);
this.value = value;
}
@Override
public Long getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Long" + append + ": " + value;
}
}

View File

@ -0,0 +1,66 @@
package com.sk89q.jnbt;
import java.nio.charset.Charset;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* A class which holds constant values.
*
* @author Graham Edgecombe
*
*/
public final class NBTConstants {
/**
* The character set used by NBT (UTF-8).
*/
public static final Charset CHARSET = Charset.forName("UTF-8");
/**
* Tag type constants.
*/
public static final int TYPE_END = 0, TYPE_BYTE = 1, TYPE_SHORT = 2,
TYPE_INT = 3, TYPE_LONG = 4, TYPE_FLOAT = 5, TYPE_DOUBLE = 6,
TYPE_BYTE_ARRAY = 7, TYPE_STRING = 8, TYPE_LIST = 9,
TYPE_COMPOUND = 10;
/**
* Default private constructor.
*/
private NBTConstants() {
}
}

View File

@ -0,0 +1,211 @@
package com.sk89q.jnbt;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.EndTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
/**
* <p>
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* streams, and produces an object graph of subclasses of the <code>Tag</code>
* object.
* </p>
*
* <p>
* The NBT format was created by Markus Persson, and the specification may be
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
* http://www.minecraft.net/docs/NBT.txt</a>.
* </p>
*
* @author Graham Edgecombe
*
*/
public final class NBTInputStream implements Closeable {
/**
* The data input stream.
*/
private final DataInputStream is;
/**
* Creates a new <code>NBTInputStream</code>, which will source its data
* from the specified input stream.
*
* @param is
* The input stream.
* @throws IOException
* if an I/O error occurs.
*/
public NBTInputStream(InputStream is) throws IOException {
this.is = new DataInputStream(is);
}
/**
* Reads an NBT tag from the stream.
*
* @return The tag that was read.
* @throws IOException
* if an I/O error occurs.
*/
public Tag readTag() throws IOException {
return readTag(0);
}
/**
* Reads an NBT from the stream.
*
* @param depth
* The depth of this tag.
* @return The tag that was read.
* @throws IOException
* if an I/O error occurs.
*/
private Tag readTag(int depth) throws IOException {
int type = is.readByte() & 0xFF;
String name;
if (type != NBTConstants.TYPE_END) {
int nameLength = is.readShort() & 0xFFFF;
byte[] nameBytes = new byte[nameLength];
is.readFully(nameBytes);
name = new String(nameBytes, NBTConstants.CHARSET);
} else {
name = "";
}
return readTagPayload(type, name, depth);
}
/**
* Reads the payload of a tag, given the name and type.
*
* @param type
* The type.
* @param name
* The name.
* @param depth
* The depth.
* @return The tag.
* @throws IOException
* if an I/O error occurs.
*/
private Tag readTagPayload(int type, String name, int depth)
throws IOException {
switch (type) {
case NBTConstants.TYPE_END:
if (depth == 0) {
throw new IOException(
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
} else {
return new EndTag();
}
case NBTConstants.TYPE_BYTE:
return new ByteTag(name, is.readByte());
case NBTConstants.TYPE_SHORT:
return new ShortTag(name, is.readShort());
case NBTConstants.TYPE_INT:
return new IntTag(name, is.readInt());
case NBTConstants.TYPE_LONG:
return new LongTag(name, is.readLong());
case NBTConstants.TYPE_FLOAT:
return new FloatTag(name, is.readFloat());
case NBTConstants.TYPE_DOUBLE:
return new DoubleTag(name, is.readDouble());
case NBTConstants.TYPE_BYTE_ARRAY:
int length = is.readInt();
byte[] bytes = new byte[length];
is.readFully(bytes);
return new ByteArrayTag(name, bytes);
case NBTConstants.TYPE_STRING:
length = is.readShort();
bytes = new byte[length];
is.readFully(bytes);
return new StringTag(name, new String(bytes, NBTConstants.CHARSET));
case NBTConstants.TYPE_LIST:
int childType = is.readByte();
length = is.readInt();
List<Tag> tagList = new ArrayList<Tag>();
for (int i = 0; i < length; i++) {
Tag tag = readTagPayload(childType, "", depth + 1);
if (tag instanceof EndTag) {
throw new IOException("TAG_End not permitted in a list.");
}
tagList.add(tag);
}
return new ListTag(name, NBTUtils.getTypeClass(childType), tagList);
case NBTConstants.TYPE_COMPOUND:
Map<String, Tag> tagMap = new HashMap<String, Tag>();
while (true) {
Tag tag = readTag(depth + 1);
if (tag instanceof EndTag) {
break;
} else {
tagMap.put(tag.getName(), tag);
}
}
return new CompoundTag(name, tagMap);
default:
throw new IOException("Invalid tag type: " + type + ".");
}
}
public void close() throws IOException {
is.close();
}
}

View File

@ -0,0 +1,316 @@
package com.sk89q.jnbt;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.EndTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.NBTUtils;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* <p>
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
* <code>Tag</code> objects to an underlying <code>OutputStream</code>.
* </p>
*
* <p>
* The NBT format was created by Markus Persson, and the specification may be
* found at <a href="http://www.minecraft.net/docs/NBT.txt">
* http://www.minecraft.net/docs/NBT.txt</a>.
* </p>
*
* @author Graham Edgecombe
*
*/
public final class NBTOutputStream implements Closeable {
/**
* The output stream.
*/
private final DataOutputStream os;
/**
* Creates a new <code>NBTOutputStream</code>, which will write data to the
* specified underlying output stream.
*
* @param os
* The output stream.
* @throws IOException
* if an I/O error occurs.
*/
public NBTOutputStream(OutputStream os) throws IOException {
this.os = new DataOutputStream(new GZIPOutputStream(os));
}
/**
* Writes a tag.
*
* @param tag
* The tag to write.
* @throws IOException
* if an I/O error occurs.
*/
public void writeTag(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
String name = tag.getName();
byte[] nameBytes = name.getBytes(NBTConstants.CHARSET);
os.writeByte(type);
os.writeShort(nameBytes.length);
os.write(nameBytes);
if (type == NBTConstants.TYPE_END) {
throw new IOException("Named TAG_End not permitted.");
}
writeTagPayload(tag);
}
/**
* Writes tag payload.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeTagPayload(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
switch (type) {
case NBTConstants.TYPE_END:
writeEndTagPayload((EndTag) tag);
break;
case NBTConstants.TYPE_BYTE:
writeByteTagPayload((ByteTag) tag);
break;
case NBTConstants.TYPE_SHORT:
writeShortTagPayload((ShortTag) tag);
break;
case NBTConstants.TYPE_INT:
writeIntTagPayload((IntTag) tag);
break;
case NBTConstants.TYPE_LONG:
writeLongTagPayload((LongTag) tag);
break;
case NBTConstants.TYPE_FLOAT:
writeFloatTagPayload((FloatTag) tag);
break;
case NBTConstants.TYPE_DOUBLE:
writeDoubleTagPayload((DoubleTag) tag);
break;
case NBTConstants.TYPE_BYTE_ARRAY:
writeByteArrayTagPayload((ByteArrayTag) tag);
break;
case NBTConstants.TYPE_STRING:
writeStringTagPayload((StringTag) tag);
break;
case NBTConstants.TYPE_LIST:
writeListTagPayload((ListTag) tag);
break;
case NBTConstants.TYPE_COMPOUND:
writeCompoundTagPayload((CompoundTag) tag);
break;
default:
throw new IOException("Invalid tag type: " + type + ".");
}
}
/**
* Writes a <code>TAG_Byte</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeByteTagPayload(ByteTag tag) throws IOException {
os.writeByte(tag.getValue());
}
/**
* Writes a <code>TAG_Byte_Array</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeByteArrayTagPayload(ByteArrayTag tag) throws IOException {
byte[] bytes = tag.getValue();
os.writeInt(bytes.length);
os.write(bytes);
}
/**
* Writes a <code>TAG_Compound</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeCompoundTagPayload(CompoundTag tag) throws IOException {
for (Tag childTag : tag.getValue().values()) {
writeTag(childTag);
}
os.writeByte((byte) 0); // end tag - better way?
}
/**
* Writes a <code>TAG_List</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeListTagPayload(ListTag tag) throws IOException {
Class<? extends Tag> clazz = tag.getType();
List<Tag> tags = tag.getValue();
int size = tags.size();
os.writeByte(NBTUtils.getTypeCode(clazz));
os.writeInt(size);
for (int i = 0; i < size; i++) {
writeTagPayload(tags.get(i));
}
}
/**
* Writes a <code>TAG_String</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeStringTagPayload(StringTag tag) throws IOException {
byte[] bytes = tag.getValue().getBytes(NBTConstants.CHARSET);
os.writeShort(bytes.length);
os.write(bytes);
}
/**
* Writes a <code>TAG_Double</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeDoubleTagPayload(DoubleTag tag) throws IOException {
os.writeDouble(tag.getValue());
}
/**
* Writes a <code>TAG_Float</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeFloatTagPayload(FloatTag tag) throws IOException {
os.writeFloat(tag.getValue());
}
/**
* Writes a <code>TAG_Long</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeLongTagPayload(LongTag tag) throws IOException {
os.writeLong(tag.getValue());
}
/**
* Writes a <code>TAG_Int</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeIntTagPayload(IntTag tag) throws IOException {
os.writeInt(tag.getValue());
}
/**
* Writes a <code>TAG_Short</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeShortTagPayload(ShortTag tag) throws IOException {
os.writeShort(tag.getValue());
}
/**
* Writes a <code>TAG_Empty</code> tag.
*
* @param tag
* The tag.
* @throws IOException
* if an I/O error occurs.
*/
private void writeEndTagPayload(EndTag tag) {
/* empty */
}
public void close() throws IOException {
os.close();
}
}

View File

@ -0,0 +1,178 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.EndTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* A class which contains NBT-related utility methods.
*
* @author Graham Edgecombe
*
*/
public final class NBTUtils {
/**
* Gets the type name of a tag.
*
* @param clazz
* The tag class.
* @return The type name.
*/
public static String getTypeName(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return "TAG_Byte_Array";
} else if (clazz.equals(ByteTag.class)) {
return "TAG_Byte";
} else if (clazz.equals(CompoundTag.class)) {
return "TAG_Compound";
} else if (clazz.equals(DoubleTag.class)) {
return "TAG_Double";
} else if (clazz.equals(EndTag.class)) {
return "TAG_End";
} else if (clazz.equals(FloatTag.class)) {
return "TAG_Float";
} else if (clazz.equals(IntTag.class)) {
return "TAG_Int";
} else if (clazz.equals(ListTag.class)) {
return "TAG_List";
} else if (clazz.equals(LongTag.class)) {
return "TAG_Long";
} else if (clazz.equals(ShortTag.class)) {
return "TAG_Short";
} else if (clazz.equals(StringTag.class)) {
return "TAG_String";
} else {
throw new IllegalArgumentException("Invalid tag classs ("
+ clazz.getName() + ").");
}
}
/**
* Gets the type code of a tag class.
*
* @param clazz
* The tag class.
* @return The type code.
* @throws IllegalArgumentException
* if the tag class is invalid.
*/
public static int getTypeCode(Class<? extends Tag> clazz) {
if (clazz.equals(ByteArrayTag.class)) {
return NBTConstants.TYPE_BYTE_ARRAY;
} else if (clazz.equals(ByteTag.class)) {
return NBTConstants.TYPE_BYTE;
} else if (clazz.equals(CompoundTag.class)) {
return NBTConstants.TYPE_COMPOUND;
} else if (clazz.equals(DoubleTag.class)) {
return NBTConstants.TYPE_DOUBLE;
} else if (clazz.equals(EndTag.class)) {
return NBTConstants.TYPE_END;
} else if (clazz.equals(FloatTag.class)) {
return NBTConstants.TYPE_FLOAT;
} else if (clazz.equals(IntTag.class)) {
return NBTConstants.TYPE_INT;
} else if (clazz.equals(ListTag.class)) {
return NBTConstants.TYPE_LIST;
} else if (clazz.equals(LongTag.class)) {
return NBTConstants.TYPE_LONG;
} else if (clazz.equals(ShortTag.class)) {
return NBTConstants.TYPE_SHORT;
} else if (clazz.equals(StringTag.class)) {
return NBTConstants.TYPE_STRING;
} else {
throw new IllegalArgumentException("Invalid tag classs ("
+ clazz.getName() + ").");
}
}
/**
* Gets the class of a type of tag.
*
* @param type
* The type.
* @return The class.
* @throws IllegalArgumentException
* if the tag type is invalid.
*/
public static Class<? extends Tag> getTypeClass(int type) {
switch (type) {
case NBTConstants.TYPE_END:
return EndTag.class;
case NBTConstants.TYPE_BYTE:
return ByteTag.class;
case NBTConstants.TYPE_SHORT:
return ShortTag.class;
case NBTConstants.TYPE_INT:
return IntTag.class;
case NBTConstants.TYPE_LONG:
return LongTag.class;
case NBTConstants.TYPE_FLOAT:
return FloatTag.class;
case NBTConstants.TYPE_DOUBLE:
return DoubleTag.class;
case NBTConstants.TYPE_BYTE_ARRAY:
return ByteArrayTag.class;
case NBTConstants.TYPE_STRING:
return StringTag.class;
case NBTConstants.TYPE_LIST:
return ListTag.class;
case NBTConstants.TYPE_COMPOUND:
return CompoundTag.class;
default:
throw new IllegalArgumentException("Invalid tag type : " + type
+ ".");
}
}
/**
* Default private constructor.
*/
private NBTUtils() {
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_Short</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class ShortTag extends Tag {
/**
* The value.
*/
private final short value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public ShortTag(String name, short value) {
super(name);
this.value = value;
}
@Override
public Short getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_Short" + append + ": " + value;
}
}

View File

@ -0,0 +1,79 @@
package com.sk89q.jnbt;
import com.sk89q.jnbt.Tag;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The <code>TAG_String</code> tag.
*
* @author Graham Edgecombe
*
*/
public final class StringTag extends Tag {
/**
* The value.
*/
private final String value;
/**
* Creates the tag.
*
* @param name
* The name.
* @param value
* The value.
*/
public StringTag(String name, String value) {
super(name);
this.value = value;
}
@Override
public String getValue() {
return value;
}
@Override
public String toString() {
String name = getName();
String append = "";
if (name != null && !name.equals("")) {
append = "(\"" + this.getName() + "\")";
}
return "TAG_String" + append + ": " + value;
}
}

View File

@ -0,0 +1,75 @@
package com.sk89q.jnbt;
/*
* JNBT License
*
* Copyright (c) 2010 Graham Edgecombe
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the JNBT team nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Represents a single NBT tag.
*
* @author Graham Edgecombe
*
*/
public abstract class Tag {
/**
* The name of this tag.
*/
private final String name;
/**
* Creates the tag with the specified name.
*
* @param name
* The name.
*/
public Tag(String name) {
this.name = name;
}
/**
* Gets the name of this tag.
*
* @return The name of this tag.
*/
public final String getName() {
return name;
}
/**
* Gets the value of this tag.
*
* @return The value of this tag.
*/
public abstract Object getValue();
}

View File

@ -0,0 +1,68 @@
// $Id$
/*
* Copyright (C) 2010 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.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This annotation indicates a command. Methods should be marked with this
* annotation to tell {@link CommandsManager} that the method is a command.
* Note that the method name can actually be anything.
*
* @author sk89q
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Command {
/**
* A list of aliases for the command. The first alias is the most
* important -- it is the main name of the command. (The method name
* is never used for anything).
*/
String[] aliases();
/**
* Usage instruction. Example text for usage could be
* <code>[-h] [name] [message]</code>.
*/
String usage() default "";
/**
* A short description for the command.
*/
String desc();
/**
* The minimum number of arguments. This should be 0 or above.
*/
int min() default 0;
/**
* The maximum number of arguments. Use -1 for an unlimited number
* of arguments.
*/
int max() default -1;
/**
* Flags allow special processing for flags such as -h in the command,
* allowing users to easily turn on a flag. This is a string with
* each character being a flag. Use A-Z and a-z as possible flags.
*/
String flags() default "";
}

View File

@ -0,0 +1,131 @@
// $Id$
/*
* Copyright (C) 2010 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.minecraft.util.commands;
import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
public class CommandContext {
protected String[] args;
protected Set<Character> flags = new HashSet<Character>();
public CommandContext(String args) {
this(args.split(" "));
}
public CommandContext(String[] args) {
ArrayList<String> splitArgs = new ArrayList<String>();
for (String arg : args) {
if (!arg.equals(null) && !arg.equals("")) {
splitArgs.add(arg);
}
}
args = splitArgs.toArray(new String[0]);
int i = 1;
for (; i < args.length; i++) {
if (args[i].length() == 0) {
// Ignore this
} else if (args[i].charAt(0) == '-' && args[i].matches("^-[a-zA-Z]+$")) {
for (int k = 1; k < args[i].length(); k++) {
flags.add(args[i].charAt(k));
}
} else {
break;
}
}
String[] newArgs = new String[args.length - i + 1];
System.arraycopy(args, i, newArgs, 1, args.length - i);
newArgs[0] = args[0];
this.args = newArgs;
}
public String getCommand() {
return args[0];
}
public boolean matches(String command) {
return args[0].equalsIgnoreCase(command);
}
public String getString(int index) {
return args[index + 1];
}
public String getString(int index, String def) {
return index + 1 < args.length ? args[index + 1] : def;
}
public String getJoinedStrings(int initialIndex) {
initialIndex = initialIndex + 1;
StringBuilder buffer = new StringBuilder(args[initialIndex]);
for (int i = initialIndex + 1; i < args.length; i++) {
buffer.append(" ").append(args[i]);
}
return buffer.toString();
}
public int getInteger(int index) throws NumberFormatException {
return Integer.parseInt(args[index + 1]);
}
public int getInteger(int index, int def) throws NumberFormatException {
return index + 1 < args.length ? Integer.parseInt(args[index + 1]) : def;
}
public double getDouble(int index) throws NumberFormatException {
return Double.parseDouble(args[index + 1]);
}
public double getDouble(int index, double def) throws NumberFormatException {
return index + 1 < args.length ? Double.parseDouble(args[index + 1]) : def;
}
public String[] getSlice(int index) {
String[] slice = new String[args.length - index];
System.arraycopy(args, index, slice, 0, args.length - index);
return slice;
}
public String[] getPaddedSlice(int index, int padding) {
String[] slice = new String[args.length - index + padding];
System.arraycopy(args, index, slice, padding, args.length - index);
return slice;
}
public boolean hasFlag(char ch) {
return flags.contains(ch);
}
public Set<Character> getFlags() {
return flags;
}
public int length() {
return args.length;
}
public int argsLength() {
return args.length - 1;
}
}

View File

@ -0,0 +1,37 @@
// $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.minecraft.util.commands;
public class CommandException extends Exception {
private static final long serialVersionUID = 870638193072101739L;
public CommandException() {
super();
}
public CommandException(String message) {
super(message);
}
public CommandException(Throwable t) {
super(t);
}
}

View File

@ -0,0 +1,37 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Indicates a list of permissions that should be checked.
*
* @author sk89q
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermissions {
/**
* A list of permissions. Only one permission has to be met
* for the command to be permitted.
*/
String[] value();
}

View File

@ -0,0 +1,29 @@
// $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.minecraft.util.commands;
/**
* Thrown when not enough permissions are satisfied.
*
* @author sk89q
*/
public class CommandPermissionsException extends CommandException {
private static final long serialVersionUID = -602374621030168291L;
}

View File

@ -0,0 +1,35 @@
// $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.minecraft.util.commands;
public class CommandUsageException extends CommandException {
private static final long serialVersionUID = -6761418114414516542L;
protected String usage;
public CommandUsageException(String message, String usage) {
super(message);
this.usage = usage;
}
public String getUsage() {
return usage;
}
}

View File

@ -0,0 +1,388 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.minecraft.util.commands;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sk89q.util.StringUtil;
/**
* Manager for handling commands. This allows you to easily process commands,
* including nested commands, by correctly annotating methods of a class.
* The commands are thus declaratively defined, and it's easy to spot
* how permissions and commands work out, and it decreases the opportunity
* for errors because the consistency would cause any odd balls to show.
* The manager also handles some boilerplate code such as number of arguments
* checking and printing usage.
*
* <p>To use this, it is merely a matter of registering classes containing
* the commands (as methods with the proper annotations) with the
* manager. When you want to process a command, use one of the
* <code>execute</code> methods. If something is wrong, such as incorrect
* usage, insufficient permissions, or a missing command altogether, an
* exception will be raised for upstream handling.
*
* <p>To mark a method as a command, use {@link Command}. For nested commands,
* see {@link NestedCommand}. To handle permissions, use
* {@link CommandPermissions}.
*
* <p>This uses Java reflection extensively, but to reduce the overhead of
* reflection, command lookups are completely cached on registration. This
* allows for fast command handling. Method invocation still has to be done
* with reflection, but this is quite fast in that of itself.
*
* @author sk89q
* @param <T> command sender class
*/
public abstract class CommandsManager<T> {
/**
* Mapping of commands (including aliases) with a description. Root
* commands are stored under a key of null, whereas child commands are
* cached under their respective {@link Method}.
*/
protected Map<Method, Map<String, Method>> commands
= new HashMap<Method, Map<String, Method>>();
/**
* Mapping of commands (not including aliases) with a description.
*/
protected Map<String, String> descs = new HashMap<String, String>();
/**
* Register an object that contains commands (denoted by
* {@link Command}. The methods are
* cached into a map for later usage and it reduces the overhead of
* reflection (method lookup via reflection is relatively slow).
*
* @param cls
*/
public void register(Class<?> cls) {
registerMethods(cls, null);
}
/**
* Register the methods of a class.
*
* @param cls
* @param parent
*/
private void registerMethods(Class<?> cls, Method parent) {
Map<String, Method> map;
// Make a new hash map to cache the commands for this class
// as looking up methods via reflection is fairly slow
if (commands.containsKey(parent)) {
map = commands.get(parent);
} else {
map = new HashMap<String, Method>();
commands.put(parent, map);
}
for (Method method : cls.getMethods()) {
if (!method.isAnnotationPresent(Command.class)) {
continue;
}
Command cmd = method.getAnnotation(Command.class);
// Cache the aliases too
for (String alias : cmd.aliases()) {
map.put(alias, method);
}
// Build a list of commands and their usage details, at least for
// root level commands
if (parent == null) {
if (cmd.usage().length() == 0) {
descs.put(cmd.aliases()[0], cmd.desc());
} else {
descs.put(cmd.aliases()[0], cmd.usage() + " - " + cmd.desc());
}
}
// Look for nested commands -- if there are any, those have
// to be cached too so that they can be quickly looked
// up when processing commands
if (method.isAnnotationPresent(NestedCommand.class)) {
NestedCommand nestedCmd = method.getAnnotation(NestedCommand.class);
for (Class<?> nestedCls : nestedCmd.value()) {
registerMethods(nestedCls, method);
}
}
}
}
/**
* Checks to see whether there is a command named such at the root level.
* This will check aliases as well.
*
* @param command
* @return
*/
public boolean hasCommand(String command) {
return commands.get(null).containsKey(command.toLowerCase());
}
/**
* Get a list of command descriptions. This is only for root commands.
*
* @return
*/
public Map<String, String> getCommands() {
return descs;
}
/**
* Get the usage string for a command.
*
* @param args
* @param level
* @param cmd
* @return
*/
protected String getUsage(String[] args, int level, Command cmd) {
StringBuilder command = new StringBuilder();
command.append("/");
for (int i = 0; i <= level; i++) {
command.append(args[i] + " ");
}
command.append(cmd.flags().length() > 0 ? "[-" + cmd.flags() + "] " : "");
command.append(cmd.usage());
return command.toString();
}
/**
* Get the usage string for a nested command.
*
* @param args
* @param level
* @param method
* @param player
* @return
* @throws CommandException
*/
protected String getNestedUsage(String[] args, int level,
Method method, T player) throws CommandException {
StringBuilder command = new StringBuilder();
command.append("/");
for (int i = 0; i <= level; i++) {
command.append(args[i] + " ");
}
Map<String, Method> map = commands.get(method);
boolean found = false;
command.append("<");
Set<String> allowedCommands = new HashSet<String>();
for (Map.Entry<String, Method> entry : map.entrySet()) {
Method childMethod = entry.getValue();
found = true;
if (hasPermission(childMethod, player)) {
Command childCmd = childMethod.getAnnotation(Command.class);
allowedCommands.add(childCmd.aliases()[0]);
}
}
if (allowedCommands.size() > 0) {
command.append(StringUtil.joinString(allowedCommands, "|", 0));
} else {
if (!found) {
command.append("?");
} else {
//command.append("action");
throw new CommandPermissionsException();
}
}
command.append(">");
return command.toString();
}
/**
* Attempt to execute a command. This version takes a separate command
* name (for the root command) and then a list of following arguments.
*
* @param cmd command to run
* @param args arguments
* @param player command source
* @param methodArgs method arguments
* @throws CommandException
*/
public void execute(String cmd, String[] args, T player,
Object ... methodArgs) throws CommandException {
String[] newArgs = new String[args.length + 1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = cmd;
Object[] newMethodArgs = new Object[methodArgs.length + 1];
System.arraycopy(methodArgs, 0, newMethodArgs, 1, methodArgs.length);
executeMethod(null, newArgs, player, newMethodArgs, 0);
}
/**
* Attempt to execute a command.
*
* @param args
* @param player
* @param methodArgs
* @throws CommandException
*/
public void execute(String[] args, T player,
Object ... methodArgs) throws CommandException {
Object[] newMethodArgs = new Object[methodArgs.length + 1];
System.arraycopy(methodArgs, 0, newMethodArgs, 1, methodArgs.length);
executeMethod(null, args, player, newMethodArgs, 0);
}
/**
* Attempt to execute a command.
*
* @param parent
* @param args
* @param player
* @param methodArgs
* @param level
* @throws CommandException
*/
public void executeMethod(Method parent, String[] args,
T player, Object[] methodArgs, int level) throws CommandException {
String cmdName = args[level];
Map<String, Method> map = commands.get(parent);
Method method = map.get(cmdName.toLowerCase());
if (method == null) {
if (parent == null) { // Root
throw new UnhandledCommandException();
} else {
throw new MissingNestedCommandException("Unknown command: " + cmdName,
getNestedUsage(args, level - 1, parent, player));
}
}
if (!hasPermission(method, player)) {
throw new CommandPermissionsException();
}
int argsCount = args.length - 1 - level;
if (method.isAnnotationPresent(NestedCommand.class)) {
if (argsCount == 0) {
throw new MissingNestedCommandException("Sub-command required.",
getNestedUsage(args, level, method, player));
} else {
executeMethod(method, args, player, methodArgs, level + 1);
}
} else {
Command cmd = method.getAnnotation(Command.class);
String[] newArgs = new String[args.length - level];
System.arraycopy(args, level, newArgs, 0, args.length - level);
CommandContext context = new CommandContext(newArgs);
if (context.argsLength() < cmd.min()) {
throw new CommandUsageException("Too few arguments.",
getUsage(args, level, cmd));
}
if (cmd.max() != -1 && context.argsLength() > cmd.max()) {
throw new CommandUsageException("Too many arguments.",
getUsage(args, level, cmd));
}
for (char flag : context.getFlags()) {
if (cmd.flags().indexOf(String.valueOf(flag)) == -1) {
throw new CommandUsageException("Unknown flag: " + flag,
getUsage(args, level, cmd));
}
}
methodArgs[0] = context;
try {
method.invoke(null, methodArgs);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
if (e.getCause() instanceof CommandException) {
throw (CommandException) e.getCause();
}
throw new WrappedCommandException(e.getCause());
}
}
}
/**
* Returns whether a player has access to a command.
*
* @param method
* @param player
* @return
*/
protected boolean hasPermission(Method method, T player) {
CommandPermissions perms = method.getAnnotation(CommandPermissions.class);
if (perms == null) {
return true;
}
for (String perm : perms.value()) {
if (hasPermission(player, perm)) {
return true;
}
}
return false;
}
/**
* Returns whether a player permission..
*
* @param player
* @param perm
* @return
*/
public abstract boolean hasPermission(T player, String perm);
}

View File

@ -0,0 +1,29 @@
// $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.minecraft.util.commands;
public class MissingNestedCommandException extends CommandUsageException {
private static final long serialVersionUID = -4382896182979285355L;
public MissingNestedCommandException(String message, String usage) {
super(message, usage);
}
}

View File

@ -0,0 +1,41 @@
// $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.minecraft.util.commands;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Indicates a nested command. Mark methods with this annotation to tell
* {@link CommandsManager} that a method is merely a shell for child
* commands. Note that the body of a method marked with this annotation
* will never called. Additionally, not all fields of {@link Command} apply
* when it is used in conjunction with this annotation, although both
* are still required.
*
* @author sk89q
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface NestedCommand {
/**
* A list of classes with the child commands.
*/
Class<?>[] value();
}

View File

@ -0,0 +1,25 @@
// $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.minecraft.util.commands;
public class UnhandledCommandException extends CommandException {
private static final long serialVersionUID = 3370887306593968091L;
}

View File

@ -0,0 +1,28 @@
// $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.minecraft.util.commands;
public class WrappedCommandException extends CommandException {
private static final long serialVersionUID = -4075721444847778918L;
public WrappedCommandException(Throwable t) {
super(t);
}
}

View File

@ -0,0 +1,166 @@
// $Id$
/*
* Copyright (C) 2010 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.util;
import java.util.Collection;
/**
* String utilities.
*
* @author sk89q
*/
public class StringUtil {
/**
* Trim a string if it is longer than a certain length.
*
* @param str
* @param len
* @return
*/
public static String trimLength(String str, int len) {
if (str.length() > len) {
return str.substring(0, len);
}
return str;
}
/**
* Join an array of strings into a string.
*
* @param str
* @param delimiter
* @param initialIndex
* @return
*/
public static String joinString(String[] str, String delimiter,
int initialIndex) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder(str[initialIndex]);
for (int i = initialIndex + 1; i < str.length; i++) {
buffer.append(delimiter).append(str[i]);
}
return buffer.toString();
}
/**
* Join an array of strings into a string.
*
* @param str
* @param delimiter
* @param initialIndex
* @param quote
* @return
*/
public static String joinQuotedString(String[] str, String delimiter,
int initialIndex, String quote) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder();
buffer.append(quote);
buffer.append(str[initialIndex]);
buffer.append(quote);
for (int i = initialIndex + 1; i < str.length; i++) {
buffer.append(delimiter).append(quote).append(str[i]).append(quote);
}
return buffer.toString();
}
/**
* Join an array of strings into a string.
*
* @param str
* @param delimiter
* @return
*/
public static String joinString(String[] str, String delimiter) {
return joinString(str, delimiter, 0);
}
/**
* Join an array of strings into a string.
*
* @param str
* @param delimiter
* @param initialIndex
* @return
*/
public static String joinString(Object[] str, String delimiter,
int initialIndex) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder(str[initialIndex].toString());
for (int i = initialIndex + 1; i < str.length; i++) {
buffer.append(delimiter).append(str[i].toString());
}
return buffer.toString();
}
/**
* Join an array of strings into a string.
*
* @param str
* @param delimiter
* @param initialIndex
* @return
*/
public static String joinString(int[] str, String delimiter,
int initialIndex) {
if (str.length == 0) {
return "";
}
StringBuilder buffer = new StringBuilder(Integer.toString(str[initialIndex]));
for (int i = initialIndex + 1; i < str.length; i++) {
buffer.append(delimiter).append(Integer.toString(str[i]));
}
return buffer.toString();
}
/**
* Join an list of strings into a string.
*
* @param str
* @param delimiter
* @param initialIndex
* @return
*/
public static String joinString(Collection<?> str, String delimiter,
int initialIndex) {
if (str.size() == 0) {
return "";
}
StringBuilder buffer = new StringBuilder();
int i = 0;
for (Object o : str) {
if (i >= initialIndex) {
if (i > 0) {
buffer.append(delimiter);
}
buffer.append(o.toString());
}
i++;
}
return buffer.toString();
}
}

View File

@ -0,0 +1,100 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Extension of Vector that supports being compared as ints (for accuracy).
*
* @author sk89q
*/
public class BlockVector extends Vector {
/**
* Construct the Vector object.
*
* @param pt
*/
public BlockVector(Vector pt) {
super(pt);
}
/**
* Construct the Vector object.
*
* @param x
* @param y
* @param z
*/
public BlockVector(int x, int y, int z) {
super(x, y, z);
}
/**
* Construct the Vector object.
*
*
* @param x
* @param y
* @param z
*/
public BlockVector(float x, float y, float z) {
super(x, y, z);
}
/**
* Construct the Vector object.
*
*
* @param x
* @param y
* @param z
*/
public BlockVector(double x, double y, double z) {
super(x, y, z);
}
/**
* Checks if another object is equivalent.
*
* @param obj
* @return whether the other object is equivalent
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector)) {
return false;
}
Vector other = (Vector)obj;
return (int)other.getX() == (int)this.x && (int)other.getY() == (int)this.y
&& (int)other.getZ() == (int)this.z;
}
/**
* Gets the hash code.
*
* @return hash code
*/
@Override
public int hashCode() {
return (Integer.valueOf((int)x).hashCode() >> 13) ^
(Integer.valueOf((int)y).hashCode() >> 7) ^
Integer.valueOf((int)z).hashCode();
}
}

View File

@ -0,0 +1,93 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Extension of Vector2D that supports being compared as ints (for accuracy).
*
* @author sk89q
*/
public class BlockVector2D extends Vector2D {
/**
* Construct the Vector object.
*
* @param pt
*/
public BlockVector2D(Vector2D pt) {
super(pt);
}
/**
* Construct the Vector object.
*
* @param x
* @param z
*/
public BlockVector2D(int x, int z) {
super(x, z);
}
/**
* Construct the Vector object.
*
* @param x
* @param z
*/
public BlockVector2D(float x, float z) {
super(x, z);
}
/**
* Construct the Vector object.
*
* @param x
* @param z
*/
public BlockVector2D(double x, double z) {
super(x, z);
}
/**
* Checks if another object is equivalent.
*
* @param obj
* @return whether the other object is equivalent
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector2D)) {
return false;
}
Vector2D other = (Vector2D)obj;
return (int)other.x == (int)this.x && (int)other.z == (int)this.z;
}
/**
* Gets the hash code.
*
* @return hash code
*/
@Override
public int hashCode() {
return (Integer.valueOf((int)x).hashCode() >> 13) ^
Integer.valueOf((int)z).hashCode();
}
}

View File

@ -0,0 +1,111 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Extension of Vector that supports being compared as ints (for accuracy).
*
* @author sk89q
*/
public class BlockWorldVector extends WorldVector {
/**
* Construct the Vector object.
*
* @param pt
*/
public BlockWorldVector(WorldVector pt) {
super(pt.getWorld(), pt);
}
/**
* Construct the Vector object.
* @param world
*
* @param pt
*/
public BlockWorldVector(LocalWorld world, Vector pt) {
super(world, pt);
}
/**
* Construct the Vector object.
*
* @param world
* @param x
* @param y
* @param z
*/
public BlockWorldVector(LocalWorld world, int x, int y, int z) {
super(world, x, y, z);
}
/**
* Construct the Vector object.
*
* @param world
* @param x
* @param y
* @param z
*/
public BlockWorldVector(LocalWorld world, float x, float y, float z) {
super(world, x, y, z);
}
/**
* Construct the Vector object.
*
* @param world
* @param x
* @param y
* @param z
*/
public BlockWorldVector(LocalWorld world, double x, double y, double z) {
super(world, x, y, z);
}
/**
* Checks if another object is equivalent.
*
* @param obj
* @return whether the other object is equivalent
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof WorldVector)) {
return false;
}
WorldVector other = (WorldVector)obj;
return (int)other.getX() == (int)this.x && (int)other.getY() == (int)this.y
&& (int)other.getZ() == (int)this.z;
}
/**
* Gets the hash code.
*
* @return hash code
*/
@Override
public int hashCode() {
return (Integer.valueOf((int)x).hashCode() >> 13) ^
(Integer.valueOf((int)y).hashCode() >> 7) ^
Integer.valueOf((int)z).hashCode();
}
}

View File

@ -0,0 +1,105 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
* @param <T>
*/
public class Countable<T> implements Comparable<Countable<T>> {
/**
* ID.
*/
private T id;
/**
* Amount.
*/
private int amount;
/**
* Construct the object.
*
* @param id
* @param amount
*/
public Countable(T id, int amount) {
this.id = id;
this.amount = amount;
}
/**
* @return the id
*/
public T getID() {
return id;
}
/**
* @param id the id to set
*/
public void setID(T id) {
this.id = id;
}
/**
* @return the amount
*/
public int getAmount() {
return amount;
}
/**
* @param amount the amount to set
*/
public void setAmount(int amount) {
this.amount = amount;
}
/**
* Decrement the amount.
*/
public void decrement() {
this.amount--;
}
/**
* Increment the amount.
*/
public void increment() {
this.amount++;
}
/**
* Comparison.
*
* @param other
* @return
*/
public int compareTo(Countable<T> other) {
if (amount > other.amount) {
return 1;
} else if (amount == other.amount) {
return 0;
} else {
return -1;
}
}
}

View File

@ -0,0 +1,566 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.data.*;
import java.io.*;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
/**
* The clipboard remembers the state of a cuboid region.
*
* @author sk89q
*/
public class CuboidClipboard {
/**
* Flip direction.
*/
public enum FlipDirection {
NORTH_SOUTH,
WEST_EAST,
UP_DOWN
}
private BaseBlock[][][] data;
private Vector offset;
private Vector origin;
private Vector size;
/**
* Constructs the clipboard.
*
* @param size
*/
public CuboidClipboard(Vector size) {
this.size = size;
data = new BaseBlock[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
origin = new Vector();
offset = new Vector();
}
/**
* Constructs the clipboard.
*
* @param size
* @param origin
*/
public CuboidClipboard(Vector size, Vector origin) {
this.size = size;
data = new BaseBlock[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
this.origin = origin;
offset = new Vector();
}
/**
* Constructs the clipboard.
*
* @param size
* @param origin
* @param offset
*/
public CuboidClipboard(Vector size, Vector origin, Vector offset) {
this.size = size;
data = new BaseBlock[size.getBlockX()][size.getBlockY()][size.getBlockZ()];
this.origin = origin;
this.offset = offset;
}
/**
* Get the width (X-direction) of the clipboard.
*
* @return width
*/
public int getWidth() {
return size.getBlockX();
}
/**
* Get the length (Z-direction) of the clipboard.
*
* @return length
*/
public int getLength() {
return size.getBlockZ();
}
/**
* Get the height (Y-direction) of the clipboard.
*
* @return height
*/
public int getHeight() {
return size.getBlockY();
}
/**
* Rotate the clipboard in 2D. It can only rotate by angles divisible by 90.
*
* @param angle in degrees
*/
public void rotate2D(int angle) {
angle = angle % 360;
if (angle % 90 != 0) { // Can only rotate 90 degrees at the moment
return;
}
boolean reverse = angle < 0;
int numRotations = (int)Math.floor(angle / 90.0);
int width = getWidth();
int length = getLength();
int height = getHeight();
Vector sizeRotated = size.transform2D(angle, 0, 0, 0, 0);
int shiftX = sizeRotated.getX() < 0 ? -sizeRotated.getBlockX() - 1 : 0;
int shiftZ = sizeRotated.getZ() < 0 ? -sizeRotated.getBlockZ() - 1 : 0;
BaseBlock newData[][][] = new BaseBlock
[Math.abs(sizeRotated.getBlockX())]
[Math.abs(sizeRotated.getBlockY())]
[Math.abs(sizeRotated.getBlockZ())];
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
Vector v = (new Vector(x, 0, z)).transform2D(angle, 0, 0, 0, 0);
int newX = v.getBlockX();
int newZ = v.getBlockZ();
for (int y = 0; y < height; y++) {
BaseBlock block = data[x][y][z];
newData[shiftX + newX][y][shiftZ + newZ] = block;
if (reverse) {
for (int i = 0; i < numRotations; i++) {
block.rotate90Reverse();
}
} else {
for (int i = 0; i < numRotations; i++) {
block.rotate90();
}
}
}
}
}
data = newData;
size = new Vector(Math.abs(sizeRotated.getBlockX()),
Math.abs(sizeRotated.getBlockY()),
Math.abs(sizeRotated.getBlockZ()));
offset = offset.transform2D(angle, 0, 0, 0, 0)
.subtract(shiftX, 0, shiftZ);;
}
/**
* Flip the clipboard.
*
* @param dir
*/
public void flip(FlipDirection dir) {
int width = getWidth();
int length = getLength();
int height = getHeight();
if (dir == FlipDirection.NORTH_SOUTH) {
int len = (int)Math.floor(width / 2);
for (int xs = 0; xs < len; xs++) {
for (int z = 0; z < length; z++) {
for (int y = 0; y < height; y++) {
BaseBlock old = data[xs][y][z];
old.flip();
data[xs][y][z] = data[width - xs - 1][y][z];
data[width - xs - 1][y][z] = old;
}
}
}
} else if (dir == FlipDirection.WEST_EAST) {
int len = (int)Math.floor(length / 2);
for (int zs = 0; zs < len; zs++) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
BaseBlock old = data[x][y][zs];
old.flip();
data[x][y][zs] = data[x][y][length - zs - 1];
data[x][y][length - zs - 1] = old;
}
}
}
} else if (dir == FlipDirection.UP_DOWN) {
int len = (int)Math.floor(height / 2);
for (int ys = 0; ys < len; ys++) {
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
BaseBlock old = data[x][ys][z];
data[x][ys][z] = data[x][height - ys - 1][z];
data[x][height - ys - 1][z] = old;
}
}
}
}
}
/**
* Copy to the clipboard.
*
* @param editSession
*/
public void copy(EditSession editSession) {
for (int x = 0; x < size.getBlockX(); x++) {
for (int y = 0; y < size.getBlockY(); y++) {
for (int z = 0; z < size.getBlockZ(); z++) {
data[x][y][z] =
editSession.getBlock(new Vector(x, y, z).add(getOrigin()));
}
}
}
}
/**
* Paste from the clipboard.
*
* @param editSession
* @param newOrigin Position to paste it from
* @param noAir True to not paste air
* @throws MaxChangedBlocksException
*/
public void paste(EditSession editSession, Vector newOrigin, boolean noAir)
throws MaxChangedBlocksException {
place(editSession, newOrigin.add(offset), noAir);
}
/**
* Places the blocks in a position from the minimum corner.
*
* @param editSession
* @param pos
* @param noAir
* @throws MaxChangedBlocksException
*/
public void place(EditSession editSession, Vector pos, boolean noAir)
throws MaxChangedBlocksException {
for (int x = 0; x < size.getBlockX(); x++) {
for (int y = 0; y < size.getBlockY(); y++) {
for (int z = 0; z < size.getBlockZ(); z++) {
if (noAir && data[x][y][z].isAir())
continue;
editSession.setBlock(new Vector(x, y, z).add(pos),
data[x][y][z]);
}
}
}
}
/**
* Get one point in the copy. The point is relative to the origin
* of the copy (0, 0, 0) and not to the actual copy origin.
*
* @param pos
* @return null
* @throws ArrayIndexOutOfBoundsException
*/
public BaseBlock getPoint(Vector pos) throws ArrayIndexOutOfBoundsException {
return data[pos.getBlockX()][pos.getBlockY()][pos.getBlockZ()];
}
/**
* Get the size of the copy.
*
* @return
*/
public Vector getSize() {
return size;
}
/**
* Saves the clipboard data to a .schematic-format file.
*
* @param path
* @throws IOException
* @throws DataException
*/
public void saveSchematic(File path) throws IOException, DataException {
int width = getWidth();
int height = getHeight();
int length = getLength();
if (width > 65535) {
throw new DataException("Width of region too large for a .schematic");
}
if (height > 65535) {
throw new DataException("Height of region too large for a .schematic");
}
if (length > 65535) {
throw new DataException("Length of region too large for a .schematic");
}
HashMap<String,Tag> schematic = new HashMap<String,Tag>();
schematic.put("Width", new ShortTag("Width", (short)width));
schematic.put("Length", new ShortTag("Length", (short)length));
schematic.put("Height", new ShortTag("Height", (short)height));
schematic.put("Materials", new StringTag("Materials", "Alpha"));
schematic.put("WEOriginX", new IntTag("WEOriginX", getOrigin().getBlockX()));
schematic.put("WEOriginY", new IntTag("WEOriginY", getOrigin().getBlockY()));
schematic.put("WEOriginZ", new IntTag("WEOriginZ", getOrigin().getBlockZ()));
schematic.put("WEOffsetX", new IntTag("WEOffsetX", getOffset().getBlockX()));
schematic.put("WEOffsetY", new IntTag("WEOffsetY", getOffset().getBlockY()));
schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", getOffset().getBlockZ()));
// Copy
byte[] blocks = new byte[width * height * length];
byte[] blockData = new byte[width * height * length];
ArrayList<Tag> tileEntities = new ArrayList<Tag>();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
int index = y * width * length + z * width + x;
blocks[index] = (byte)data[x][y][z].getType();
blockData[index] = (byte)data[x][y][z].getData();
// Store TileEntity data
if (data[x][y][z] instanceof TileEntityBlock) {
TileEntityBlock tileEntityBlock =
(TileEntityBlock)data[x][y][z];
// Get the list of key/values from the block
Map<String,Tag> values = tileEntityBlock.toTileEntityNBT();
if (values != null) {
values.put("id", new StringTag("id",
tileEntityBlock.getTileEntityID()));
values.put("x", new IntTag("x", x));
values.put("y", new IntTag("y", y));
values.put("z", new IntTag("z", z));
CompoundTag tileEntityTag =
new CompoundTag("TileEntity", values);
tileEntities.add(tileEntityTag);
}
}
}
}
}
schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
schematic.put("Data", new ByteArrayTag("Data", blockData));
schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, tileEntities));
// Build and output
CompoundTag schematicTag = new CompoundTag("Schematic", schematic);
NBTOutputStream stream = new NBTOutputStream(new FileOutputStream(path));
stream.writeTag(schematicTag);
stream.close();
}
/**
* Load a .schematic file into a clipboard.
*
* @param path
* @return clipboard
* @throws DataException
* @throws IOException
*/
public static CuboidClipboard loadSchematic(File path)
throws DataException, IOException {
FileInputStream stream = new FileInputStream(path);
NBTInputStream nbtStream = new NBTInputStream(
new GZIPInputStream(stream));
Vector origin = new Vector();
Vector offset = new Vector();
// Schematic tag
CompoundTag schematicTag = (CompoundTag)nbtStream.readTag();
if (!schematicTag.getName().equals("Schematic")) {
throw new DataException("Tag \"Schematic\" does not exist or is not first");
}
// Check
Map<String,Tag> schematic = schematicTag.getValue();
if (!schematic.containsKey("Blocks")) {
throw new DataException("Schematic file is missing a \"Blocks\" tag");
}
// Get information
short width = (Short)getChildTag(schematic, "Width", ShortTag.class).getValue();
short length = (Short)getChildTag(schematic, "Length", ShortTag.class).getValue();
short height = (Short)getChildTag(schematic, "Height", ShortTag.class).getValue();
try {
int originX = (Integer)getChildTag(schematic, "WEOriginX", IntTag.class).getValue();
int originY = (Integer)getChildTag(schematic, "WEOriginY", IntTag.class).getValue();
int originZ = (Integer)getChildTag(schematic, "WEOriginZ", IntTag.class).getValue();
origin = new Vector(originX, originY, originZ);
} catch (DataException e) {
// No origin data
}
try {
int offsetX = (Integer)getChildTag(schematic, "WEOffsetX", IntTag.class).getValue();
int offsetY = (Integer)getChildTag(schematic, "WEOffsetY", IntTag.class).getValue();
int offsetZ = (Integer)getChildTag(schematic, "WEOffsetZ", IntTag.class).getValue();
offset = new Vector(offsetX, offsetY, offsetZ);
} catch (DataException e) {
// No offset data
}
// Check type of Schematic
String materials = (String)getChildTag(schematic, "Materials", StringTag.class).getValue();
if (!materials.equals("Alpha")) {
throw new DataException("Schematic file is not an Alpha schematic");
}
// Get blocks
byte[] blocks = (byte[])getChildTag(schematic, "Blocks", ByteArrayTag.class).getValue();
byte[] blockData = (byte[])getChildTag(schematic, "Data", ByteArrayTag.class).getValue();
// Need to pull out tile entities
List<Tag> tileEntities = (List<Tag>)((ListTag)getChildTag(schematic, "TileEntities", ListTag.class))
.getValue();
Map<BlockVector,Map<String,Tag>> tileEntitiesMap =
new HashMap<BlockVector,Map<String,Tag>>();
for (Tag tag : tileEntities) {
if (!(tag instanceof CompoundTag)) continue;
CompoundTag t = (CompoundTag)tag;
int x = 0;
int y = 0;
int z = 0;
Map<String,Tag> values = new HashMap<String,Tag>();
for (Map.Entry<String,Tag> entry : t.getValue().entrySet()) {
if (entry.getKey().equals("x")) {
if (entry.getValue() instanceof IntTag) {
x = ((IntTag)entry.getValue()).getValue();
}
} else if (entry.getKey().equals("y")) {
if (entry.getValue() instanceof IntTag) {
y = ((IntTag)entry.getValue()).getValue();
}
} else if (entry.getKey().equals("z")) {
if (entry.getValue() instanceof IntTag) {
z = ((IntTag)entry.getValue()).getValue();
}
}
values.put(entry.getKey(), entry.getValue());
}
BlockVector vec = new BlockVector(x, y, z);
tileEntitiesMap.put(vec, values);
}
Vector size = new Vector(width, height, length);
CuboidClipboard clipboard = new CuboidClipboard(size);
clipboard.setOrigin(origin);
clipboard.setOffset(offset);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) {
int index = y * width * length + z * width + x;
BlockVector pt = new BlockVector(x, y, z);
BaseBlock block;
if (blocks[index] == BlockID.WALL_SIGN || blocks[index] == BlockID.SIGN_POST) {
block = new SignBlock(blocks[index], blockData[index]);
} else if (blocks[index] == BlockID.CHEST) {
block = new ChestBlock(blockData[index]);
} else if (blocks[index] == BlockID.FURNACE || blocks[index] == BlockID.BURNING_FURNACE) {
block = new FurnaceBlock(blocks[index], blockData[index]);
} else if (blocks[index] == BlockID.DISPENSER) {
block = new DispenserBlock(blockData[index]);
} else if (blocks[index] == BlockID.MOB_SPAWNER) {
block = new MobSpawnerBlock(blockData[index]);
} else if (blocks[index] == BlockID.NOTE_BLOCK) {
block = new NoteBlock(blockData[index]);
} else {
block = new BaseBlock(blocks[index], blockData[index]);
}
if (block instanceof TileEntityBlock
&& tileEntitiesMap.containsKey(pt)) {
((TileEntityBlock)block).fromTileEntityNBT(
tileEntitiesMap.get(pt));
}
clipboard.data[x][y][z] = block;
}
}
}
return clipboard;
}
/**
* Get child tag of a NBT structure.
*
* @param items
* @param key
* @param expected
* @return child tag
* @throws DataException
*/
private static Tag getChildTag(Map<String,Tag> items, String key,
Class<? extends Tag> expected) throws DataException {
if (!items.containsKey(key)) {
throw new DataException("Schematic file is missing a \"" + key + "\" tag");
}
Tag tag = items.get(key);
if (!expected.isInstance(tag)) {
throw new DataException(
key + " tag is not of tag type " + expected.getName());
}
return tag;
}
/**
* @return the origin
*/
public Vector getOrigin() {
return origin;
}
/**
* @param origin the origin to set
*/
public void setOrigin(Vector origin) {
this.origin = origin;
}
/**
* @return the offset
*/
public Vector getOffset() {
return offset;
}
/**
* @param offset
*/
public void setOffset(Vector offset) {
this.offset = offset;
}
}

View File

@ -0,0 +1,43 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public class DisallowedItemException extends WorldEditException {
private static final long serialVersionUID = -8080026411461549979L;
private String type;
public DisallowedItemException(String type) {
this.type = type;
}
public DisallowedItemException(String type, String message) {
super(message);
this.type = type;
}
public String getID() {
return type;
}
}

View File

@ -0,0 +1,188 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
/**
* Double array lists to work like a Map, but not really.
*
* @author sk89q
* @param <A>
* @param <B>
*/
public class DoubleArrayList<A,B> implements Iterable<Map.Entry<A,B>> {
/**
* First list.
*/
private List<A> listA = new ArrayList<A>();
/**
* Second list.
*/
private List<B> listB = new ArrayList<B>();
/**
* Is reversed when iterating.
*/
private boolean isReversed = false;
/**
* Construct the object.
*
* @param isReversed
*/
public DoubleArrayList(boolean isReversed) {
this.isReversed = isReversed;
}
/**
* Add an item.
*
* @param a
* @param b
*/
public void put(A a, B b) {
listA.add(a);
listB.add(b);
}
/**
* Get size.
* @return
*/
public int size() {
return listA.size();
}
/**
* Clear the list.
*/
public void clear() {
listA.clear();
listB.clear();
}
/**
* Get an entry set.
*
* @return
*/
public Iterator<Map.Entry<A,B>> iterator() {
if (isReversed) {
return new ReverseEntryIterator<Map.Entry<A,B>>(
listA.listIterator(listA.size()),
listB.listIterator(listB.size()));
} else {
return new ForwardEntryIterator<Map.Entry<A,B>>(
listA.iterator(),
listB.iterator());
}
}
/**
* Entry iterator.
*
* @param <T>
*/
public class ForwardEntryIterator<T extends Map.Entry<A,B>>
implements Iterator<Map.Entry<A,B>> {
private Iterator<A> keyIterator;
private Iterator<B> valueIterator;
public ForwardEntryIterator(Iterator<A> keyIterator, Iterator<B> valueIterator) {
this.keyIterator = keyIterator;
this.valueIterator = valueIterator;
}
public boolean hasNext() {
return keyIterator.hasNext();
}
public Map.Entry<A,B> next() throws NoSuchElementException {
return new Entry<A,B>(keyIterator.next(), valueIterator.next());
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* Entry iterator.
*
* @param <T>
*/
public class ReverseEntryIterator<T extends Map.Entry<A,B>>
implements Iterator<Map.Entry<A,B>> {
private ListIterator<A> keyIterator;
private ListIterator<B> valueIterator;
public ReverseEntryIterator(ListIterator<A> keyIterator, ListIterator<B> valueIterator) {
this.keyIterator = keyIterator;
this.valueIterator = valueIterator;
}
public boolean hasNext() {
return keyIterator.hasPrevious();
}
public Map.Entry<A,B> next() throws NoSuchElementException {
return new Entry<A,B>(keyIterator.previous(), valueIterator.previous());
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* Class to masquerade as Map.Entry.
*
* @param <C>
* @param <D>
*/
public class Entry<C,D> implements Map.Entry<A,B> {
private A key;
private B value;
private Entry(A key, B value) {
this.key = key;
this.value = value;
}
public A getKey() {
return key;
}
public B getValue() {
return value;
}
public B setValue(B value) {
throw new UnsupportedOperationException();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author Albert
*/
public class EmptyClipboardException extends WorldEditException {
private static final long serialVersionUID = -3197424556127109425L;
}

View File

@ -0,0 +1,32 @@
// $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;
public class FileSelectionAbortedException extends FilenameException {
private static final long serialVersionUID = 7377072269988014886L;
public FileSelectionAbortedException() {
super("");
}
public FileSelectionAbortedException(String msg) {
super("", msg);
}
}

View File

@ -0,0 +1,40 @@
// $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;
public class FilenameException extends WorldEditException {
private static final long serialVersionUID = 6072601657326106265L;
private String filename;
public FilenameException(String filename) {
super();
this.filename = filename;
}
public FilenameException(String filename, String msg) {
super(msg);
this.filename = filename;
}
public String getFilename() {
return filename;
}
}

View File

@ -0,0 +1,32 @@
// $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;
public class FilenameResolutionException extends FilenameException {
private static final long serialVersionUID = 4673670296313383121L;
public FilenameResolutionException(String filename) {
super(filename);
}
public FilenameResolutionException(String filename, String msg) {
super(filename, msg);
}
}

View File

@ -0,0 +1,165 @@
package com.sk89q.worldedit;
// $Id$
/*
* WorldEditLibrary
* Copyright (C) 2010 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/>.
*/
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.filtering.HeightMapFilter;
import com.sk89q.worldedit.regions.Region;
/**
* Allows applications of Kernels onto the region's heightmap.
* Currently only used for smoothing (with a GaussianKernel).
*
* @author Grum
*/
public class HeightMap {
private int[] data;
private int width;
private int height;
private Region region;
private EditSession session;
/**
* Constructs the HeightMap
*
* @param session
* @param region
*/
public HeightMap(EditSession session, Region region) {
this.session = session;
this.region = region;
this.width = region.getWidth();
this.height = region.getLength();
int minX = region.getMinimumPoint().getBlockX();
int minY = region.getMinimumPoint().getBlockY();
int minZ = region.getMinimumPoint().getBlockZ();
int maxY = region.getMaximumPoint().getBlockY();
// Store current heightmap data
data = new int[width * height];
for (int z = 0; z < height; z++) {
for (int x = 0; x < width; x++) {
data[z * width + x] = session.getHighestTerrainBlock(x + minX, z + minZ, minY, maxY);
}
}
}
/**
* Apply the filter 'iterations' amount times.
*
* @param filter
* @param iterations
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
public int applyFilter(HeightMapFilter filter, int iterations) throws MaxChangedBlocksException {
int[] newData = new int[data.length];
System.arraycopy(data, 0, newData, 0, data.length);
for (int i = 0; i < iterations; i++)
newData = filter.filter(newData, width, height);
return apply(newData);
}
/**
* Apply a raw heightmap to the region
*
* @param data
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
public int apply(int[] data) throws MaxChangedBlocksException {
Vector minY = region.getMinimumPoint();
int originX = minY.getBlockX();
int originY = minY.getBlockY();
int originZ = minY.getBlockZ();
int maxY = region.getMaximumPoint().getBlockY();
BaseBlock fillerAir = new BaseBlock(0);
int blocksChanged = 0;
// Apply heightmap
for (int z = 0; z < height; z++) {
for (int x = 0; x < width; x++) {
int index = z * width + x;
int curHeight = this.data[index];
// Clamp newHeight within the selection area
int newHeight = Math.min(maxY, data[index]);
// Offset x,z to be 'real' coordinates
int X = x + originX;
int Z = z + originZ;
// We are keeping the topmost blocks so take that in account for the scale
double scale = (double) (curHeight - originY) / (double) (newHeight - originY);
// Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding)
BaseBlock existing = session.getBlock(new Vector(X, curHeight, Z));
// Skip water/lava
if (existing.getType() < 8 || existing.getType() > 11) {
session.setBlock(new Vector(X, newHeight, Z), existing);
blocksChanged++;
// Grow -- start from 1 below top replacing airblocks
for (int y = newHeight - 1 - originY; y >= 0; y--) {
int copyFrom = (int) (y * scale);
session.setBlock(new Vector(X, originY + y, Z), session.getBlock(new Vector(X, originY + copyFrom, Z)));
blocksChanged++;
}
}
} else if (curHeight > newHeight) {
// Shrink -- start from bottom
for (int y = 0; y < newHeight - originY; y++) {
int copyFrom = (int) (y * scale);
session.setBlock(new Vector(X, originY + y, Z), session.getBlock(new Vector(X, originY + copyFrom, Z)));
blocksChanged++;
}
// Set the top block of the column to be the same type
// (this could otherwise go wrong with rounding)
session.setBlock(new Vector(X, newHeight, Z), session.getBlock(new Vector(X, curHeight, Z)));
blocksChanged++;
// Fill rest with air
for (int y = newHeight + 1; y <= curHeight; y++) {
session.setBlock(new Vector(X, y, Z), fillerAir);
blocksChanged++;
}
}
}
}
// Drop trees to the floor -- TODO
return blocksChanged;
}
}

View File

@ -0,0 +1,30 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Raised when a region is not fully defined.
*
* @author sk89q
*/
public class IncompleteRegionException extends WorldEditException {
private static final long serialVersionUID = 458988897980179094L;
}

View File

@ -0,0 +1,32 @@
// $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;
public class InvalidFilenameException extends FilenameException {
private static final long serialVersionUID = 7377072269988014886L;
public InvalidFilenameException(String filename) {
super(filename);
}
public InvalidFilenameException(String filename, String msg) {
super(filename, msg);
}
}

View File

@ -0,0 +1,32 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public class InvalidItemException extends DisallowedItemException {
private static final long serialVersionUID = -2739618871154124586L;
public InvalidItemException(String type, String message) {
super(type, message);
}
}

View File

@ -0,0 +1,35 @@
// $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;
public class InvalidToolBindException extends WorldEditException {
private static final long serialVersionUID = -1865311004052447699L;
private int itemId;
public InvalidToolBindException(int itemId, String msg) {
super(msg);
this.itemId = itemId;
}
public int getItemId() {
return itemId;
}
}

View File

@ -0,0 +1,78 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import com.sk89q.worldedit.snapshots.SnapshotRepository;
/**
* Represents WorldEdit's configuration.
*
* @author sk89q
*/
public abstract class LocalConfiguration {
protected static final int[] defaultDisallowedBlocks = new int[] {
6, 7, 14, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 39, 31,
32, 33, 34, 36, 37, 38, 39, 40, 46, 50, 51, 56, 59, 69, 73, 74,
75, 76, 77, 81, 83
};
public boolean profile = false;
public Set<Integer> disallowedBlocks = new HashSet<Integer>();
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;
public String shellSaveType = "";
public SnapshotRepository snapshotRepo = null;
public int maxRadius = -1;
public int maxSuperPickaxeSize = 5;
public int maxBrushRadius = 6;
public boolean logCommands = false;
public boolean registerHelp = true;
public int wandItem = 271;
public boolean superPickaxeDrop = true;
public boolean superPickaxeManyDrop = true;
public boolean noDoubleSlash = false;
public boolean useInventory = false;
public boolean useInventoryOverride = false;
public int navigationWand = 345;
public int navigationWandMaxDistance = 50;
public int scriptTimeout = 3000;
public Set<Integer> allowedDataCycleBlocks = new HashSet<Integer>();
public String saveDir = "schematics";
public String scriptsDir = "craftscripts";
public boolean showFirstUseVersion = true;
/**
* Loads the configuration.
*/
public abstract void load();
/**
* Get the working directory to work from.
*
* @return
*/
public File getWorkingDirectory() {
return new File(".");
}
}

View File

@ -0,0 +1,617 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import java.io.File;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.cui.CUIEvent;
import com.sk89q.worldedit.util.TargetBlock;
/**
*
* @author sk89q
*/
public abstract class LocalPlayer {
/**
* Server.
*/
protected ServerInterface server;
/**
* Construct the object.
*
* @param server
*/
protected LocalPlayer(ServerInterface server) {
this.server = server;
}
/**
* Returns true if the player is holding a pick axe.
*
* @return whether a pick axe is held
*/
public boolean isHoldingPickAxe() {
int item = getItemInHand();
return item == 257 || item == 270 || item == 274 || item == 278
|| item == 285;
}
/**
* Find a position for the player to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The player will be teleported to
* that free position.
*
* @param searchPos search position
*/
public void findFreePosition(WorldVector searchPos) {
LocalWorld world = searchPos.getWorld();
int x = searchPos.getBlockX();
int y = Math.max(0, searchPos.getBlockY());
int origY = y;
int z = searchPos.getBlockZ();
byte free = 0;
while (y <= 129) {
if (BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
free++;
} else {
free = 0;
}
if (free == 2) {
if (y - 1 != origY) {
setPosition(new Vector(x + 0.5, y - 1, z + 0.5));
}
return;
}
y++;
}
}
/**
* Set the player on the ground.
*
* @param searchPos
*/
public void setOnGround(WorldVector searchPos) {
LocalWorld world = searchPos.getWorld();
int x = searchPos.getBlockX();
int y = Math.max(0, searchPos.getBlockY());
int z = searchPos.getBlockZ();
while (y >= 0) {
if (!BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
setPosition(new Vector(x + 0.5, y + 1, z + 0.5));
return;
}
y--;
}
}
/**
* Find a position for the player to stand that is not inside a block.
* Blocks above the player will be iteratively tested until there is
* a series of two free blocks. The player will be teleported to
* that free position.
*/
public void findFreePosition() {
findFreePosition(getBlockIn());
}
/**
* Go up one level to the next free space above.
*
* @return true if a spot was found
*/
public boolean ascendLevel() {
Vector pos = getBlockIn();
int x = pos.getBlockX();
int y = Math.max(0, pos.getBlockY());
int z = pos.getBlockZ();
LocalWorld world = getPosition().getWorld();
byte free = 0;
byte spots = 0;
while (y <= 129) {
if (BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
free++;
} else {
free = 0;
}
if (free == 2) {
spots++;
if (spots == 2) {
int type = world.getBlockType(new Vector(x, y - 2, z));
// Don't get put in lava!
if (type == 10 || type == 11) {
return false;
}
setPosition(new Vector(x + 0.5, y - 1, z + 0.5));
return true;
}
}
y++;
}
return false;
}
/**
* Go up one level to the next free space above.
*
* @return true if a spot was found
*/
public boolean descendLevel() {
Vector pos = getBlockIn();
int x = pos.getBlockX();
int y = Math.max(0, pos.getBlockY() - 1);
int z = pos.getBlockZ();
LocalWorld world = getPosition().getWorld();
byte free = 0;
while (y >= 1) {
if (BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
free++;
} else {
free = 0;
}
if (free == 2) {
// So we've found a spot, but we have to drop the player
// lightly and also check to see if there's something to
// stand upon
while (y >= 0) {
int type = world.getBlockType(new Vector(x, y, z));
// Don't want to end up in lava
if (type != 0 && type != 10 && type != 11) {
// Found a block!
setPosition(new Vector(x + 0.5, y + 1, z + 0.5));
return true;
}
y--;
}
return false;
}
y--;
}
return false;
}
/**
* Ascend to the ceiling above.
*
* @param clearance
* @return whether the player was moved
*/
public boolean ascendToCeiling(int clearance) {
Vector pos = getBlockIn();
int x = pos.getBlockX();
int initialY = Math.max(0, pos.getBlockY());
int y = Math.max(0, pos.getBlockY() + 2);
int z = pos.getBlockZ();
LocalWorld world = getPosition().getWorld();
// No free space above
if (world.getBlockType(new Vector(x, y, z)) != 0) {
return false;
}
while (y <= 127) {
// Found a ceiling!
if (!BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
int platformY = Math.max(initialY, y - 3 - clearance);
world.setBlockType(new Vector(x, platformY, z),
BlockType.GLASS.getID());
setPosition(new Vector(x + 0.5, platformY + 1, z + 0.5));
return true;
}
y++;
}
return false;
}
/**
* Just go up.
*
* @param distance
* @return whether the player was moved
*/
public boolean ascendUpwards(int distance) {
Vector pos = getBlockIn();
int x = pos.getBlockX();
int initialY = Math.max(0, pos.getBlockY());
int y = Math.max(0, pos.getBlockY() + 1);
int z = pos.getBlockZ();
int maxY = Math.min(128, initialY + distance);
LocalWorld world = getPosition().getWorld();
while (y <= 129) {
if (!BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
break; // Hit something
} else if (y > maxY + 1) {
break;
} else if (y == maxY + 1) {
world.setBlockType(new Vector(x, y - 2, z),
BlockType.GLASS.getID());
setPosition(new Vector(x + 0.5, y - 1, z + 0.5));
return true;
}
y++;
}
return false;
}
/**
* Get the point of the block that is being stood in.
*
* @return point
*/
public WorldVector getBlockIn() {
WorldVector pos = getPosition();
return WorldVector.toBlockPoint(pos.getWorld(), pos.getX(),
pos.getY(), pos.getZ());
}
/**
* Get the point of the block that is being stood upon.
*
* @return point
*/
public WorldVector getBlockOn() {
WorldVector pos = getPosition();
return WorldVector.toBlockPoint(pos.getWorld(), pos.getX(),
pos.getY() - 1, pos.getZ());
}
/**
* Get the point of the block being looked at. May return null.
*
* @param range
* @return point
*/
public WorldVector getBlockTrace(int range) {
TargetBlock tb = new TargetBlock(this, range, 0.2);
return tb.getTargetBlock();
}
/**
* Get the point of the block being looked at. May return null.
*
* @param range
* @return point
*/
public WorldVector getSolidBlockTrace(int range) {
TargetBlock tb = new TargetBlock(this, range, 0.2);
return tb.getSolidTargetBlock();
}
/**
* Get the player's cardinal direction (N, W, NW, etc.). May return null.
*
* @return
*/
public PlayerDirection getCardinalDirection() {
// From hey0's code
double rot = (getYaw() - 90) % 360;
if (rot < 0) {
rot += 360.0;
}
return getDirection(rot);
}
/**
* Returns direction according to rotation. May return null.
*
* @param rot
* @return
*/
private static PlayerDirection getDirection(double rot) {
if (0 <= rot && rot < 22.5) {
return PlayerDirection.NORTH;
} else if (22.5 <= rot && rot < 67.5) {
return PlayerDirection.NORTH_EAST;
} else if (67.5 <= rot && rot < 112.5) {
return PlayerDirection.EAST;
} else if (112.5 <= rot && rot < 157.5) {
return PlayerDirection.SOUTH_EAST;
} else if (157.5 <= rot && rot < 202.5) {
return PlayerDirection.SOUTH;
} else if (202.5 <= rot && rot < 247.5) {
return PlayerDirection.SOUTH_WEST;
} else if (247.5 <= rot && rot < 292.5) {
return PlayerDirection.WEST;
} else if (292.5 <= rot && rot < 337.5) {
return PlayerDirection.NORTH_WEST;
} else if (337.5 <= rot && rot < 360.0) {
return PlayerDirection.NORTH;
} else {
return null;
}
}
/**
* Get the ID of the item that the player is holding.
*
* @return
*/
public abstract int getItemInHand();
/**
* Get the name of the player.
*
* @return String
*/
public abstract String getName();
/**
* Get the player's position.
*
* @return point
*/
public abstract WorldVector getPosition();
/**
* Get the player's world.
*
* @return point
*/
public abstract LocalWorld getWorld();
/**
* Get the player's view pitch.
*
* @return pitch
*/
/**
* Get the player's view pitch.
*
* @return pitch
*/
public abstract double getPitch();
/**
* Get the player's view yaw.
*
* @return yaw
*/
/**
* Get the player's view yaw.
*
* @return yaw
*/
public abstract double getYaw();
/**
* Gives the player an item.
*
* @param type
* @param amt
*/
public abstract void giveItem(int type, int amt);
/**
* Pass through the wall that you are looking at.
*
* @param range
* @return whether the player was pass through
*/
public boolean passThroughForwardWall(int range) {
int searchDist = 0;
TargetBlock hitBlox = new TargetBlock(this, range, 0.2);
LocalWorld world = getPosition().getWorld();
BlockWorldVector block;
boolean firstBlock = true;
int freeToFind = 2;
boolean inFree = false;
while ((block = hitBlox.getNextBlock()) != null) {
boolean free = BlockType.canPassThrough(world.getBlockType(block));
if (firstBlock) {
firstBlock = false;
if (!free) {
freeToFind--;
continue;
}
}
searchDist++;
if (searchDist > 20) {
return false;
}
if (inFree != free) {
if (free) {
freeToFind--;
}
}
if (freeToFind == 0) {
setOnGround(block);
return true;
}
inFree = free;
}
return false;
}
/**
* Print a message.
*
* @param msg
*/
public abstract void printRaw(String msg);
/**
* Print a WorldEdit message.
*
* @param msg
*/
public abstract void printDebug(String msg);
/**
* Print a WorldEdit message.
*
* @param msg
*/
public abstract void print(String msg);
/**
* Print a WorldEdit error.
*
* @param msg
*/
public abstract void printError(String msg);
/**
* Move the player.
*
* @param pos
* @param pitch
* @param yaw
*/
public abstract void setPosition(Vector pos, float pitch, float yaw);
/**
* Move the player.
*
* @param pos
*/
public void setPosition(Vector pos) {
setPosition(pos, (float)getPitch(), (float)getYaw());
}
/**
* Get a player's list of groups.
*
* @return
*/
public abstract String[] getGroups();
/**
* Get this player's block bag.
*
* @return
*/
public abstract BlockBag getInventoryBlockBag();
/**
* Checks if a player has permission.
*
* @param perm
* @return
*/
public abstract boolean hasPermission(String perm);
/**
* Open a file open dialog.
*
* @param extensions null to allow all
* @return
*/
public File openFileOpenDialog(String[] extensions) {
printError("File dialogs are not supported in your environment.");
return null;
}
/**
* Open a file save dialog.
*
* @param extensions null to allow all
* @return
*/
public File openFileSaveDialog(String[] extensions) {
printError("File dialogs are not supported in your environment.");
return null;
}
/**
* Returns true if the player can destroy bedrock.
*
* @return
*/
public boolean canDestroyBedrock() {
return hasPermission("worldedit.override.bedrock");
}
/**
* Send a CUI event.
*
* @param event
*/
public void dispatchCUIEvent(CUIEvent event) {
}
/**
* Send the CUI handshake.
*/
public void dispatchCUIHandshake() {
}
/**
* Returns true if equal.
*
* @param other
* @return whether the other object is equivalent
*/
@Override
public boolean equals(Object other) {
if (!(other instanceof LocalPlayer)) {
return false;
}
LocalPlayer other2 = (LocalPlayer)other;
return other2.getName().equals(getName());
}
/**
* Gets the hash code.
*
* @return hash code
*/
@Override
public int hashCode() {
return getName().hashCode();
}
}

View File

@ -0,0 +1,618 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.TimeZone;
import com.sk89q.jchronic.Chronic;
import com.sk89q.jchronic.Options;
import com.sk89q.jchronic.utils.Span;
import com.sk89q.jchronic.utils.Time;
import com.sk89q.worldedit.snapshots.Snapshot;
import com.sk89q.worldedit.tools.BrushTool;
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.CUIEvent;
import com.sk89q.worldedit.cui.SelectionPointEvent;
import com.sk89q.worldedit.cui.SelectionShapeEvent;
import com.sk89q.worldedit.regions.CuboidRegionSelector;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
/**
* An instance of this represents the WorldEdit session of a user. A session
* stores history and settings. Sessions are not tied particularly to any
* player and can be shuffled between players, saved, and loaded.
*
* @author sk89q
*/
public class LocalSession {
public static int MAX_HISTORY_SIZE = 15;
private LocalConfiguration config;
private LocalWorld selectionWorld;
private RegionSelector selector = new CuboidRegionSelector();
private boolean placeAtPos1 = false;
private LinkedList<EditSession> history = new LinkedList<EditSession>();
private int historyPointer = 0;
private CuboidClipboard clipboard;
private boolean toolControl = true;
private boolean superPickaxe = false;
private BlockTool pickaxeMode = new SinglePickaxe();
private Map<Integer, Tool> tools
= new HashMap<Integer, Tool>();
private int maxBlocksChanged = -1;
private boolean useInventory;
private Snapshot snapshot;
private String lastScript;
private boolean beenToldVersion = false;
private boolean hasCUISupport = false;
private TimeZone timezone = TimeZone.getDefault();
/**
* Construct the object.
*
* @param config
*/
public LocalSession(LocalConfiguration config) {
this.config = config;
}
/**
* Get the session's timezone.
*
* @return
*/
public TimeZone getTimeZone() {
return timezone;
}
/**
* Set the session's timezone.
*
* @param timezone
*/
public void setTimezone(TimeZone timezone) {
this.timezone = timezone;
}
/**
* Clear history.
*/
public void clearHistory() {
history.clear();
historyPointer = 0;
}
/**
* Remember an edit session for the undo history. If the history maximum
* size is reached, old edit sessions will be discarded.
*
* @param editSession
*/
public void remember(EditSession editSession) {
// Don't store anything if no changes were made
if (editSession.size() == 0) { return; }
// Destroy any sessions after this undo point
while (historyPointer < history.size()) {
history.remove(historyPointer);
}
history.add(editSession);
while (history.size() > MAX_HISTORY_SIZE) {
history.remove(0);
}
historyPointer = history.size();
}
/**
* Performs an undo.
*
* @param newBlockBag
* @return whether anything was undone
*/
public EditSession undo(BlockBag newBlockBag) {
historyPointer--;
if (historyPointer >= 0) {
EditSession editSession = history.get(historyPointer);
EditSession newEditSession =
new EditSession(editSession.getWorld(), -1, newBlockBag);
newEditSession.enableQueue();
editSession.undo(newEditSession);
return editSession;
} else {
historyPointer = 0;
return null;
}
}
/**
* Performs a redo
*
* @param newBlockBag
* @return whether anything was redone
*/
public EditSession redo(BlockBag newBlockBag) {
if (historyPointer < history.size()) {
EditSession editSession = history.get(historyPointer);
EditSession newEditSession =
new EditSession(editSession.getWorld(), -1, newBlockBag);
newEditSession.enableQueue();
editSession.redo(newEditSession);
historyPointer++;
return editSession;
}
return null;
}
/**
* Get the region selector for defining the selection. If the selection
* was defined for a different world, the old selection will be discarded.
*
* @param world
* @return position
*/
public RegionSelector getRegionSelector(LocalWorld world) {
if (selectionWorld == null) {
selectionWorld = world;
} else if (!selectionWorld.equals(world)) {
selectionWorld = world;
selector.clear();
}
return selector;
}
/**
* Get the region selector. This won't check worlds so make sure that
* this region selector isn't used blindly.
*
* @return position
*/
public RegionSelector getRegionSelector() {
return selector;
}
/**
* Set the region selector.
*
* @param world
* @param selector
*/
public void setRegionSelector(LocalWorld world, RegionSelector selector) {
selectionWorld = world;
this.selector = selector;
}
/**
* Returns true if the region is fully defined.
*
* @return
*/
@Deprecated
public boolean isRegionDefined() {
return selector.isDefined();
}
/**
* Returns true if the region is fully defined for the specified world.
*
* @param world
* @return
*/
public boolean isSelectionDefined(LocalWorld world) {
if (selectionWorld == null || !selectionWorld.equals(world)) {
return false;
}
return selector.isDefined();
}
/**
* Use <code>getSelection()</code>.
*
* @return region
* @throws IncompleteRegionException
*/
@Deprecated
public Region getRegion() throws IncompleteRegionException {
return selector.getRegion();
}
/**
* Get the selection region. If you change the region, you should
* call learnRegionChanges(). If the selection is defined in
* a different world, the <code>IncompleteRegionException</code>
* exception will be thrown.
*
* @param world
* @return region
* @throws IncompleteRegionException
*/
public Region getSelection(LocalWorld world) throws IncompleteRegionException {
if (selectionWorld == null || !selectionWorld.equals(world)) {
throw new IncompleteRegionException();
}
return selector.getRegion();
}
/**
* Get the selection world.
*
* @return
*/
public LocalWorld getSelectionWorld() {
return selectionWorld;
}
/**
* Gets the clipboard.
*
* @return clipboard, may be null
* @throws EmptyClipboardException
*/
public CuboidClipboard getClipboard() throws EmptyClipboardException {
if (clipboard == null) {
throw new EmptyClipboardException();
}
return clipboard;
}
/**
* Sets the clipboard.
*
* @param clipboard
*/
public void setClipboard(CuboidClipboard clipboard) {
this.clipboard = clipboard;
}
/**
* See if tool control is enabled.
*
* @return true if enabled
*/
public boolean isToolControlEnabled() {
return toolControl;
}
/**
* Change tool control setting.
*
* @param toolControl
*/
public void setToolControl(boolean toolControl) {
this.toolControl = toolControl;
}
/**
* Get the maximum number of blocks that can be changed in an edit session.
*
* @return block change limit
*/
public int getBlockChangeLimit() {
return maxBlocksChanged;
}
/**
* Set the maximum number of blocks that can be changed.
*
* @param maxBlocksChanged
*/
public void setBlockChangeLimit(int maxBlocksChanged) {
this.maxBlocksChanged = maxBlocksChanged;
}
/**
* Checks whether the super pick axe is enabled.
*
* @return status
*/
public boolean hasSuperPickAxe() {
return superPickaxe;
}
/**
* Enable super pick axe.
*/
public void enableSuperPickAxe() {
superPickaxe = true;
}
/**
* Disable super pick axe.
*/
public void disableSuperPickAxe() {
superPickaxe = false;
}
/**
* Toggle the super pick axe.
*
* @return status
*/
public boolean toggleSuperPickAxe() {
superPickaxe = !superPickaxe;
return superPickaxe;
}
/**
* Get the placement position.
*
* @param player
* @return position
* @throws IncompleteRegionException
*/
public Vector getPlacementPosition(LocalPlayer player)
throws IncompleteRegionException {
if (!placeAtPos1) {
return player.getBlockIn();
}
return selector.getPrimaryPosition();
}
/**
* Toggle placement position.
*
* @return
*/
public boolean togglePlacementPosition() {
placeAtPos1 = !placeAtPos1;
return placeAtPos1;
}
/**
* Get a block bag for a player.
*
* @param player
* @return
*/
public BlockBag getBlockBag(LocalPlayer player) {
if (!useInventory) {
return null;
}
return player.getInventoryBlockBag();
}
/**
* Get the snapshot that has been selected.
*
* @return the snapshot
*/
public Snapshot getSnapshot() {
return snapshot;
}
/**
* Select a snapshot.
*
* @param snapshot
*/
public void setSnapshot(Snapshot snapshot) {
this.snapshot = snapshot;
}
/**
* @return the superPickaxeMode
*/
public BlockTool getSuperPickaxe() {
return pickaxeMode;
}
/**
* Set the super pickaxe tool.
*
* @param tool
*/
public void setSuperPickaxe(BlockTool tool) {
this.pickaxeMode = tool;
}
/**
* Get the tool assigned to the item.
*
* @param item
* @return the tool
*/
public Tool getTool(int item) {
return tools.get(item);
}
/**
* Get the brush tool assigned to the item. If there is no tool assigned
* or the tool is not assigned, the slot will be replaced with the
* brush tool.
*
* @param item
* @return the tool
* @throws InvalidToolBindException
*/
public BrushTool getBrushTool(int item) throws InvalidToolBindException {
Tool tool = getTool(item);
if (tool == null || !(tool instanceof BrushTool)) {
tool = new BrushTool();
setTool(item, tool);
}
return (BrushTool)tool;
}
/**
* Set the tool.
*
* @param item
* @param tool the tool to set
* @throws InvalidToolBindException
*/
public void setTool(int item, Tool tool) throws InvalidToolBindException {
if (item > 0 && item < 255) {
throw new InvalidToolBindException(item, "Blocks can't be used");
} else if (item == 263 || item == 348) {
throw new InvalidToolBindException(item, "Item is not usuable");
} else if (item == config.wandItem) {
throw new InvalidToolBindException(item, "Already used for the wand");
} else if (item == config.navigationWand) {
throw new InvalidToolBindException(item, "Already used for the navigation wand");
}
this.tools.put(item, tool);
}
/**
* Returns whether inventory usage is enabled for this session.
*
* @return the useInventory
*/
public boolean isUsingInventory() {
return useInventory;
}
/**
* Set the state of inventory usage.
*
* @param useInventory the useInventory to set
*/
public void setUseInventory(boolean useInventory) {
this.useInventory = useInventory;
}
/**
* Get the last script used.
*
* @return the lastScript
*/
public String getLastScript() {
return lastScript;
}
/**
* Set the last script used.
*
* @param lastScript the lastScript to set
*/
public void setLastScript(String lastScript) {
this.lastScript = lastScript;
}
/**
* Tell the player the WorldEdit version.
*
* @param player
*/
public void tellVersion(LocalPlayer player) {
if (config.showFirstUseVersion) {
if (!beenToldVersion) {
player.printRaw("\u00A78WorldEdit ver. " + WorldEdit.getVersion()
+ " (http://sk89q.com/projects/worldedit/)");
beenToldVersion = true;
}
}
}
/**
* Dispatch a CUI event but only if the player has CUI support.
*
* @param player
* @param event
*/
public void dispatchCUIEvent(LocalPlayer player, CUIEvent event) {
if (hasCUISupport) {
player.dispatchCUIEvent(event);
}
}
/**
* Dispatch the initial setup CUI messages.
*
* @param player
*/
public void dispatchCUISetup(LocalPlayer player) {
if (!hasCUISupport) {
return;
}
if (selector != null) {
dispatchCUISelection(player);
}
}
/**
* Send the selection information.
*
* @param player
*/
public void dispatchCUISelection(LocalPlayer player) {
if (!hasCUISupport) {
return;
}
player.dispatchCUIEvent(
new SelectionShapeEvent(selector.getTypeId()));
if (selector instanceof CUIPointBasedRegion) {
Vector[] points = ((CUIPointBasedRegion) selector).getCUIPoints();
int size = selector.getArea();
int i = 0;
for (Vector pt : points) {
if (pt != null) {
player.dispatchCUIEvent(
new SelectionPointEvent(i, pt, size));
}
i++;
}
}
}
/**
* Sets the status of CUI support.
*
* @param support
*/
public void setCUISupport(boolean support) {
hasCUISupport = true;
}
/**
* Detect date from a user's input.
*
* @param input
* @return
*/
public Calendar detectDate(String input) {
Time.setTimeZone(getTimeZone());
Options opt = new com.sk89q.jchronic.Options();
opt.setNow(Calendar.getInstance(getTimeZone()));
Span date = Chronic.parse(input, opt);
if (date == null) {
return null;
} else {
return date.getBeginCalendar();
}
}
}

View File

@ -0,0 +1,305 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import java.util.Random;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.regions.Region;
/**
* Represents a world.
*
* @author sk89q
*/
public abstract class LocalWorld {
/**
* List of removable entity types.
*/
public enum EntityType {
ARROWS,
ITEMS,
PAINTINGS,
BOATS,
MINECARTS,
TNT,
}
/**
* Random generator.
*/
protected Random random = new Random();
/**
* Set block type.
*
* @param pt
* @param type
* @return
*/
public abstract boolean setBlockType(Vector pt, int type);
/**
* Get block type.
*
* @param pt
* @return
*/
public abstract int getBlockType(Vector pt);
/**
* Set block data.
*
* @param pt
* @param data
*/
public abstract void setBlockData(Vector pt, int data);
/**
* Get block data.
*
* @param pt
* @return
*/
public abstract int getBlockData(Vector pt);
/**
* Get block light level.
*
* @param pt
* @return
*/
public abstract int getBlockLightLevel(Vector pt);
/**
* Regenerate an area.
*
* @param region
* @param editSession
* @return
*/
public abstract boolean regenerate(Region region, EditSession editSession);
/**
* Attempts to accurately copy a BaseBlock's extra data to the world.
*
* @param pt
* @param block
* @return
*/
public abstract boolean copyToWorld(Vector pt, BaseBlock block);
/**
* Attempts to read a BaseBlock's extra data from the world.
*
* @param pt
* @param block
* @return
*/
public abstract boolean copyFromWorld(Vector pt, BaseBlock block);
/**
* Clear a chest's contents.
*
* @param pt
* @return
*/
public abstract boolean clearContainerBlockContents(Vector pt);
/**
* Generate a tree at a location.
*
* @param editSession
* @param pt
* @return
* @throws MaxChangedBlocksException
*/
public abstract boolean generateTree(EditSession editSession, Vector pt)
throws MaxChangedBlocksException;
/**
* Generate a big tree at a location.
*
* @param editSession
* @param pt
* @return
* @throws MaxChangedBlocksException
*/
public abstract boolean generateBigTree(EditSession editSession, Vector pt)
throws MaxChangedBlocksException;
/**
* Generate a birch tree at a location.
*
* @param editSession
* @param pt
* @return
* @throws MaxChangedBlocksException
*/
public abstract boolean generateBirchTree(EditSession editSession, Vector pt)
throws MaxChangedBlocksException;
/**
* Generate a redwood tree at a location.
*
* @param editSession
* @param pt
* @return
* @throws MaxChangedBlocksException
*/
public abstract boolean generateRedwoodTree(EditSession editSession,
Vector pt) throws MaxChangedBlocksException;
/**
* Generate a tall redwood tree at a location.
*
* @param editSession
* @param pt
* @return
* @throws MaxChangedBlocksException
*/
public abstract boolean generateTallRedwoodTree(EditSession editSession,
Vector pt) throws MaxChangedBlocksException;
/**
* Drop an item.
*
* @param pt
* @param item
* @param times
*/
public void dropItem(Vector pt, BaseItemStack item, int times) {
for (int i = 0; i < times; i++) {
dropItem(pt, item);
}
}
/**
* Drop an item.
*
* @param pt
* @param item
*/
public abstract void dropItem(Vector pt, BaseItemStack item);
/**
* Simulate a block being mined.
*
* @param pt
*/
public void simulateBlockMine(Vector pt) {
int type = getBlockType(pt);
//setBlockType(pt, 0);
if (type == 1) { dropItem(pt, new BaseItemStack(4)); } // Stone
else if (type == 2) { dropItem(pt, new BaseItemStack(3)); } // Grass
else if (type == 7) { } // Bedrock
else if (type == 8) { } // Water
else if (type == 9) { } // Water
else if (type == 10) { } // Lava
else if (type == 11) { } // Lava
else if (type == 13) { // Gravel
dropItem(pt, new BaseItemStack(type));
if (random.nextDouble() >= 0.9) {
dropItem(pt, new BaseItemStack(318));
}
}
else if (type == 16) { dropItem(pt, new BaseItemStack(263)); } // Coal ore
else if (type == 17) { dropItem(pt, new BaseItemStack(17, 1, (short)getBlockData(pt))); } // Log
else if (type == 18) { // Leaves
if (random.nextDouble() > 0.95) {
dropItem(pt, new BaseItemStack(6));
}
}
else if (type == 20) { } // Glass
else if (type == 21) { dropItem(pt, new BaseItemStack(351, 1, (short)4), (random.nextInt(5)+4)); }
else if (type == 26) { dropItem(pt, new BaseItemStack(355)); } // Bed
else if (type == 35) { dropItem(pt, new BaseItemStack(35, 1, (short)getBlockData(pt))); } // Cloth
else if (type == 43) { // Double step
dropItem(pt, new BaseItemStack(44, 1, (short)getBlockData(pt)), 2);
}
else if (type == 44) { dropItem(pt, new BaseItemStack(44, 1, (short)getBlockData(pt))); } // Step
else if (type == 47) { } // Bookshelves
else if (type == 51) { } // Fire
else if (type == 52) { } // Mob spawner
else if (type == 53) { dropItem(pt, new BaseItemStack(5)); } // Wooden stairs
else if (type == 55) { dropItem(pt, new BaseItemStack(331)); } // Redstone wire
else if (type == 56) { dropItem(pt, new BaseItemStack(264)); } // Diamond ore
else if (type == 59) { dropItem(pt, new BaseItemStack(295)); } // Crops
else if (type == 60) { dropItem(pt, new BaseItemStack(3)); } // Soil
else if (type == 62) { dropItem(pt, new BaseItemStack(61)); } // Furnace
else if (type == 63) { dropItem(pt, new BaseItemStack(323)); } // Sign post
else if (type == 64) { dropItem(pt, new BaseItemStack(324)); } // Wood door
else if (type == 67) { dropItem(pt, new BaseItemStack(4)); } // Cobblestone stairs
else if (type == 68) { dropItem(pt, new BaseItemStack(323)); } // Wall sign
else if (type == 71) { dropItem(pt, new BaseItemStack(330)); } // Iron door
else if (type == 73) { dropItem(pt, new BaseItemStack(331), (random.nextInt(2)+4)); } // Redstone ore
else if (type == 74) { dropItem(pt, new BaseItemStack(331), (random.nextInt(2)+4)); } // Glowing redstone ore
else if (type == 75) { dropItem(pt, new BaseItemStack(76)); } // Redstone torch
else if (type == 78) { } // Snow
else if (type == 79) { } // Ice
else if (type == 82) { dropItem(pt, new BaseItemStack(337), 4); } // Clay
else if (type == 83) { dropItem(pt, new BaseItemStack(338)); } // Reed
else if (type == 89) { dropItem(pt, new BaseItemStack(348)); } // Lightstone
else if (type == 90) { } // Portal
else if (type == 93) { dropItem(pt, new BaseItemStack(356)); } // Repeater
else if (type == 94) { dropItem(pt, new BaseItemStack(356)); } // Repeater
else if (type != 0) {
dropItem(pt, new BaseItemStack(type));
}
}
/**
* Kill mobs in an area.
*
* @param origin
* @param radius
* @return
*/
public abstract int killMobs(Vector origin, int radius);
/**
* Remove entities in an area.
*
* @param type
* @param origin
* @param radius
* @return
*/
public abstract int removeEntities(EntityType type, Vector origin, int radius);
/**
* Compare if the other world is equal.
*
* @param other
* @return
*/
@Override
public abstract boolean equals(Object other);
/**
* Hash code.
*
* @return
*/
@Override
public abstract int hashCode();
}

View File

@ -0,0 +1,65 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.Level;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* Used for formatting.
*
* @author sk89q
*/
public class LogFormat extends Formatter {
@Override
public String format(LogRecord record) {
StringBuilder text = new StringBuilder();
Level level = record.getLevel();
if (level == Level.FINEST) {
text.append("[FINEST] ");
} else if (level == Level.FINER) {
text.append("[FINER] ");
} else if (level == Level.FINE) {
text.append("[FINE] ");
} else if (level == Level.INFO) {
text.append("[INFO] ");
} else if (level == Level.WARNING) {
text.append("[WARNING] ");
} else if (level == Level.SEVERE) {
text.append("[SEVERE] ");
}
text.append(record.getMessage());
text.append("\r\n");
Throwable t = record.getThrown();
if (t != null) {
StringWriter writer = new StringWriter();
t.printStackTrace(new PrintWriter(writer));
text.append(writer.toString());
}
return text.toString();
}
}

View File

@ -0,0 +1,38 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public class MaxChangedBlocksException extends WorldEditException {
private static final long serialVersionUID = -2621044030640945259L;
int maxBlocks;
public MaxChangedBlocksException(int maxBlocks) {
this.maxBlocks = maxBlocks;
}
public int getBlockLimit() {
return maxBlocks;
}
}

View File

@ -0,0 +1,29 @@
// $Id$
/*
* WorldEditLibrary
* Copyright (C) 2010 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;
/**
* Thrown when a maximum radius is reached.
*
* @author sk89q
*/
public class MaxRadiusException extends WorldEditException {
private static final long serialVersionUID = -8405382841529528119L;
}

View File

@ -0,0 +1,56 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Direction.
*/
public enum PlayerDirection {
NORTH(new Vector(-1, 0, 0), new Vector(0, 0, 1), true),
NORTH_EAST((new Vector(-1, 0, -1)).normalize(), (new Vector(-1, 0, 1)).normalize(), false),
EAST(new Vector(0, 0, -1), new Vector(-1, 0, 0), true),
SOUTH_EAST((new Vector(1, 0, -1)).normalize(), (new Vector(-1, 0, -1)).normalize(), false),
SOUTH(new Vector(1, 0, 0), new Vector(0, 0, -1), true),
SOUTH_WEST((new Vector(1, 0, 1)).normalize(), (new Vector(1, 0, -1)).normalize(), false),
WEST(new Vector(0, 0, 1), new Vector(1, 0, 0), true),
NORTH_WEST((new Vector(-1, 0, 1)).normalize(), (new Vector(1, 0, 1)).normalize(), false);
private Vector dir;
private Vector leftDir;
private boolean isOrthogonal;
PlayerDirection(Vector vec, Vector leftDir, boolean isOrthogonal) {
this.dir = vec;
this.leftDir = leftDir;
this.isOrthogonal = isOrthogonal;
}
public Vector vector() {
return dir;
}
public Vector leftVector() {
return leftDir;
}
public boolean isOrthogonal() {
return isOrthogonal;
}
}

View File

@ -0,0 +1,86 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.masks.Mask;
/**
* An edit session that will only replace blocks as specified.
*
* @author sk89q
*/
public class ReplacingEditSession extends EditSession {
/**
* Filter to use to filter blocks.
*/
private Mask mask;
/**
* Construct the object.
*
* @param world
* @param maxBlocks
* @param mask
*/
public ReplacingEditSession(LocalWorld world,
int maxBlocks, Mask mask) {
super(world, maxBlocks);
this.mask = mask;
}
/**
* Construct the object.
*
* @param world
* @param maxBlocks
* @param blockBag
* @param mask
*/
public ReplacingEditSession(LocalWorld world, int maxBlocks,
BlockBag blockBag, Mask mask) {
super(world, maxBlocks, blockBag);
this.mask = mask;
}
/**
* Sets a block without changing history.
*
* @param pt
* @param block
* @return Whether the block changed
*/
@Override
public boolean rawSetBlock(Vector pt, BaseBlock block) {
int y = pt.getBlockY();
if (y < 0 || y > 127) {
return false;
}
if (!mask.matches(this, pt)) {
return false;
}
return super.rawSetBlock(pt, block);
}
}

View File

@ -0,0 +1,47 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public abstract class ServerInterface {
/**
* Resolves an item name to its ID.
*
* @param name
* @return
*/
public abstract int resolveItem(String name);
/**
* Checks if a mob type is valid.
*
* @param type
* @return
*/
public abstract boolean isValidMobType(String type);
/**
* Reload WorldEdit configuration.
*/
public abstract void reload();
}

View File

@ -0,0 +1,38 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public class UnknownDirectionException extends WorldEditException {
private static final long serialVersionUID = 5705931351293248358L;
private String dir;
public UnknownDirectionException(String dir) {
this.dir = dir;
}
public String getDirection() {
return dir;
}
}

View File

@ -0,0 +1,39 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Thrown when no item exist by the ID.
*
* @author sk89q
*/
public class UnknownItemException extends WorldEditException {
private static final long serialVersionUID = 2661079183700565880L;
private String type;
public UnknownItemException(String type) {
this.type = type;
}
public String getID() {
return type;
}
}

View File

@ -0,0 +1,639 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public class Vector {
protected final double x, y, z;
/**
* Construct the Vector object.
*
* @param x
* @param y
* @param z
*/
public Vector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Construct the Vector object.
*
* @param x
* @param y
* @param z
*/
public Vector(int x, int y, int z) {
this.x = (double)x;
this.y = (double)y;
this.z = (double)z;
}
/**
* Construct the Vector object.
*
* @param x
* @param y
* @param z
*/
public Vector(float x, float y, float z) {
this.x = (double)x;
this.y = (double)y;
this.z = (double)z;
}
/**
* Construct the Vector object.
*
* @param pt
*/
public Vector(Vector pt) {
this.x = pt.x;
this.y = pt.y;
this.z = pt.z;
}
/**
* Construct the Vector object.
*/
public Vector() {
this.x = 0;
this.y = 0;
this.z = 0;
}
/**
* @return the x
*/
public double getX() {
return x;
}
/**
* @return the x
*/
public int getBlockX() {
return (int)Math.round(x);
}
/**
* Set X.
*
* @param x
* @return new vector
*/
public Vector setX(double x) {
return new Vector(x, y, z);
}
/**
* Set X.
*
* @param x
* @return new vector
*/
public Vector setX(int x) {
return new Vector(x, y, z);
}
/**
* @return the y
*/
public double getY() {
return y;
}
/**
* @return the y
*/
public int getBlockY() {
return (int)Math.round(y);
}
/**
* Set Y.
*
* @param y
* @return new vector
*/
public Vector setY(double y) {
return new Vector(x, y, z);
}
/**
* Set Y.
*
* @param y
* @return new vector
*/
public Vector setY(int y) {
return new Vector(x, y, z);
}
/**
* @return the z
*/
public double getZ() {
return z;
}
/**
* @return the z
*/
public int getBlockZ() {
return (int)Math.round(z);
}
/**
* Set Z.
*
* @param z
* @return new vector
*/
public Vector setZ(double z) {
return new Vector(x, y, z);
}
/**
* Set Z.
*
* @param z
* @return new vector
*/
public Vector setZ(int z) {
return new Vector(x, y, z);
}
/**
* Adds two points.
*
* @param other
* @return New point
*/
public Vector add(Vector other) {
return new Vector(x + other.x, y + other.y, z + other.z);
}
/**
* Adds two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector add(double x, double y, double z) {
return new Vector(this.x + x, this.y + y, this.z + z);
}
/**
* Adds two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector add(int x, int y, int z) {
return new Vector(this.x + x, this.y + y, this.z + z);
}
/**
* Adds points.
*
* @param others
* @return New point
*/
public Vector add(Vector ... others) {
double newX = x, newY = y, newZ = z;
for (int i = 0; i < others.length; i++) {
newX += others[i].x;
newY += others[i].y;
newZ += others[i].z;
}
return new Vector(newX, newY, newZ);
}
/**
* Subtracts two points.
*
* @param other
* @return New point
*/
public Vector subtract(Vector other) {
return new Vector(x - other.x, y - other.y, z - other.z);
}
/**
* Subtract two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector subtract(double x, double y, double z) {
return new Vector(this.x - x, this.y - y, this.z - z);
}
/**
* Subtract two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector subtract(int x, int y, int z) {
return new Vector(this.x - x, this.y - y, this.z - z);
}
/**
* Subtract points.
*
* @param others
* @return New point
*/
public Vector subtract(Vector ... others) {
double newX = x, newY = y, newZ = z;
for (int i = 0; i < others.length; i++) {
newX -= others[i].x;
newY -= others[i].y;
newZ -= others[i].z;
}
return new Vector(newX, newY, newZ);
}
/**
* Multiplies two points.
*
* @param other
* @return New point
*/
public Vector multiply(Vector other) {
return new Vector(x * other.x, y * other.y, z * other.z);
}
/**
* Multiply two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector multiply(double x, double y, double z) {
return new Vector(this.x * x, this.y * y, this.z * z);
}
/**
* Multiply two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector multiply(int x, int y, int z) {
return new Vector(this.x * x, this.y * y, this.z * z);
}
/**
* Multiply points.
*
* @param others
* @return New point
*/
public Vector multiply(Vector ... others) {
double newX = x, newY = y, newZ = z;
for (int i = 0; i < others.length; i++) {
newX *= others[i].x;
newY *= others[i].y;
newZ *= others[i].z;
}
return new Vector(newX, newY, newZ);
}
/**
* Scalar multiplication.
*
* @param n
* @return New point
*/
public Vector multiply(double n) {
return new Vector(this.x * n, this.y * n, this.z * n);
}
/**
* Scalar multiplication.
*
* @param n
* @return New point
*/
public Vector multiply(float n) {
return new Vector(this.x * n, this.y * n, this.z * n);
}
/**
* Scalar multiplication.
*
* @param n
* @return New point
*/
public Vector multiply(int n) {
return new Vector(this.x * n, this.y * n, this.z * n);
}
/**
* Divide two points.
*
* @param other
* @return New point
*/
public Vector divide(Vector other) {
return new Vector(x / other.x, y / other.y, z / other.z);
}
/**
* Divide two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector divide(double x, double y, double z) {
return new Vector(this.x / x, this.y / y, this.z / z);
}
/**
* Divide two points.
*
* @param x
* @param y
* @param z
* @return New point
*/
public Vector divide(int x, int y, int z) {
return new Vector(this.x / x, this.y / y, this.z / z);
}
/**
* Scalar division.
*
* @param n
* @return new point
*/
public Vector divide(int n) {
return new Vector(x / n, y / n, z / n);
}
/**
* Scalar division.
*
* @param n
* @return new point
*/
public Vector divide(double n) {
return new Vector(x / n, y / n, z / n);
}
/**
* Scalar division.
*
* @param n
* @return new point
*/
public Vector divide(float n) {
return new Vector(x / n, y / n, z / n);
}
/**
* Get the length of the vector.
*
* @return distance
*/
public double length() {
return Math.sqrt(Math.pow(x, 2) +
Math.pow(y, 2) +
Math.pow(z, 2));
}
/**
* Get the distance away from a point.
*
* @param pt
* @return distance
*/
public double distance(Vector pt) {
return Math.sqrt(Math.pow(pt.x - x, 2) +
Math.pow(pt.y - y, 2) +
Math.pow(pt.z - z, 2));
}
/**
* Get the distance away from a point, squared.
*
* @param pt
* @return distance
*/
public double distanceSq(Vector pt) {
return Math.pow(pt.x - x, 2) +
Math.pow(pt.y - y, 2) +
Math.pow(pt.z - z, 2);
}
/**
* Get the normalized vector.
*
* @return vector
*/
public Vector normalize() {
return divide(length());
}
/**
* Checks to see if a vector is contained with another.
*
* @param min
* @param max
* @return
*/
public boolean containedWithin(Vector min, Vector max) {
return x >= min.getX() && x <= max.getX()
&& y >= min.getY() && y <= max.getY()
&& z >= min.getZ() && z <= max.getZ();
}
/**
* Checks to see if a vector is contained with another.
*
* @param min
* @param max
* @return
*/
public boolean containedWithinBlock(Vector min, Vector max) {
return getBlockX() >= min.getBlockX() && getBlockX() <= max.getBlockX()
&& getBlockY() >= min.getBlockY() && getBlockY() <= max.getBlockY()
&& getBlockZ() >= min.getBlockZ() && getBlockZ() <= max.getBlockY();
}
/**
* Clamp the Y component.
*
* @param min
* @param max
* @return
*/
public Vector clampY(int min, int max) {
return new Vector(x, Math.max(min, Math.min(max, y)), z);
}
/**
* 2D transformation.
*
* @param angle in degrees
* @param aboutX
* @param aboutZ
* @param translateX
* @param translateZ
* @return
*/
public Vector transform2D(double angle,
double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x;
double z = this.z;
double x2 = x * Math.cos(angle) - z * Math.sin(angle);
double z2 = x * Math.sin(angle) + z * Math.cos(angle);
return new Vector(x2 + aboutX + translateX,
y,
z2 + aboutZ + translateZ);
}
/**
* Get a block point from a point.
*
* @param x
* @param y
* @param z
* @return point
*/
public static Vector toBlockPoint(double x, double y, double z) {
return new Vector((int)Math.floor(x),
(int)Math.floor(y),
(int)Math.floor(z));
}
/**
* Get a block point from a point.
*
* @return point
*/
public BlockVector toBlockPoint() {
return new BlockVector((int)Math.floor(x),
(int)Math.floor(y),
(int)Math.floor(z));
}
/**
* Checks if another object is equivalent.
*
* @param obj
* @return whether the other object is equivalent
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector)) {
return false;
}
Vector other = (Vector)obj;
return other.getX() == this.x && other.getY() == this.y && other.getZ() == this.z;
}
/**
* Gets the hash code.
*
* @return hash code
*/
@Override
public int hashCode() {
return ((new Double(x)).hashCode() >> 13) ^
((new Double(y)).hashCode() >> 7) ^
(new Double(z)).hashCode();
}
/**
* Returns string representation "(x, y, z)".
*
* @return string
*/
@Override
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}
/**
* Gets a BlockVector version.
*
* @return BlockVector
*/
public BlockVector toBlockVector() {
return new BlockVector(this);
}
/**
* Gets the minimum components of two vectors.
*
* @param v1
* @param v2
* @return minimum
*/
public static Vector getMinimum(Vector v1, Vector v2) {
return new Vector(
Math.min(v1.getX(), v2.getX()),
Math.min(v1.getY(), v2.getY()),
Math.min(v1.getZ(), v2.getZ()));
}
/**
* Gets the maximum components of two vectors.
*
* @param v1
* @param v2
* @return maximum
*/
public static Vector getMaximum(Vector v1, Vector v2) {
return new Vector(
Math.max(v1.getX(), v2.getX()),
Math.max(v1.getY(), v2.getY()),
Math.max(v1.getZ(), v2.getZ()));
}
}

View File

@ -0,0 +1,193 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public class Vector2D {
protected final double x, z;
/**
* Construct the Vector2D object.
*
* @param x
* @param z
*/
public Vector2D(double x, double z) {
this.x = x;
this.z = z;
}
/**
* Construct the Vector2D object.
*
* @param x
* @param z
*/
public Vector2D(int x, int z) {
this.x = (double)x;
this.z = (double)z;
}
/**
* Construct the Vector2D object.
*
* @param x
* @param z
*/
public Vector2D(float x, float z) {
this.x = (double)x;
this.z = (double)z;
}
/**
* Construct the Vector2D object.
*
* @param pt
*/
public Vector2D(Vector2D pt) {
this.x = pt.x;
this.z = pt.z;
}
/**
* Construct the Vector2D object.
*/
public Vector2D() {
this.x = 0;
this.z = 0;
}
/**
* @return the x
*/
public double getX() {
return x;
}
/**
* @return the x
*/
public int getBlockX() {
return (int)Math.round(x);
}
/**
* Set X.
*
* @param x
* @return new vector
*/
public Vector2D setX(double x) {
return new Vector2D(x, z);
}
/**
* Set X.
*
* @param x
* @return new vector
*/
public Vector2D setX(int x) {
return new Vector2D(x, z);
}
/**
* @return the z
*/
public double getZ() {
return z;
}
/**
* @return the z
*/
public int getBlockZ() {
return (int)Math.round(z);
}
/**
* Set Z.
*
* @param z
* @return new vector
*/
public Vector2D setZ(double z) {
return new Vector2D(x, z);
}
/**
* Set Z.
*
* @param z
* @return new vector
*/
public Vector2D setZ(int z) {
return new Vector2D(x, z);
}
/**
* Gets a BlockVector version.
*
* @return BlockVector
*/
public BlockVector2D toBlockVector2D() {
return new BlockVector2D(this);
}
/**
* Checks if another object is equivalent.
*
* @param obj
* @return whether the other object is equivalent
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector2D)) {
return false;
}
Vector other = (Vector)obj;
return other.x == this.x && other.z == this.z;
}
/**
* Gets the hash code.
*
* @return hash code
*/
@Override
public int hashCode() {
return ((new Double(x)).hashCode() >> 13) ^
(new Double(z)).hashCode();
}
/**
* Returns string representation "(x, y, z)".
*
* @return string
*/
@Override
public String toString() {
return "(" + x + ", " + z + ")";
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
*
* @author sk89q
*/
public abstract class WorldEditException extends Exception {
private static final long serialVersionUID = 3201997990797993987L;
protected WorldEditException() {
}
protected WorldEditException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,30 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* Raised when WorldEdit is not installed.
*
* @author sk89q
*/
public class WorldEditNotInstalled extends WorldEditException {
private static final long serialVersionUID = -4698408698930848121L;
}

View File

@ -0,0 +1,30 @@
// $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;
/**
* Represents a WorldEdit operation.
*
* @author sk89q
*/
public abstract class WorldEditOperation {
public abstract void run(LocalSession session,
LocalPlayer player, EditSession editSession) throws Throwable;
}

View File

@ -0,0 +1,126 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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;
/**
* A vector with a world component.
*
* @author sk89q
*/
public class WorldVector extends Vector {
/**
* Represents the world.
*/
private LocalWorld world;
/**
* Construct the Vector object.
*
* @param world
* @param x
* @param y
* @param z
*/
public WorldVector(LocalWorld world, double x, double y, double z) {
super(x, y, z);
this.world = world;
}
/**
* Construct the Vector object.
*
* @param world
* @param x
* @param y
* @param z
*/
public WorldVector(LocalWorld world, int x, int y, int z) {
super(x, y, z);
this.world = world;
}
/**
* Construct the Vector object.
*
* @param world
* @param x
* @param y
* @param z
*/
public WorldVector(LocalWorld world, float x, float y, float z) {
super(x, y, z);
this.world = world;
}
/**
* Construct the Vector object.
*
* @param world
* @param pt
*/
public WorldVector(LocalWorld world, Vector pt) {
super(pt);
this.world = world;
}
/**
* Construct the Vector object.
*
* @param world
*/
public WorldVector(LocalWorld world) {
super();
this.world = world;
}
/**
* Get the world.
*
* @return
*/
public LocalWorld getWorld() {
return world;
}
/**
* Get a block point from a point.
*
* @param world
* @param x
* @param y
* @param z
* @return point
*/
public static WorldVector toBlockPoint(LocalWorld world, double x, double y,
double z) {
return new WorldVector(world, (int)Math.floor(x),
(int)Math.floor(y),
(int)Math.floor(z));
}
/**
* Gets a BlockVector version.
*
* @return BlockWorldVector
*/
public BlockWorldVector toWorldBlockVector() {
return new BlockWorldVector(this);
}
}

View File

@ -0,0 +1,153 @@
// $Id$
/*
* CraftBook
* Copyright (C) 2010 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.bags;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.*;
/**
* Represents a source to get blocks from and store removed ones.
*
* @author sk89q
*/
public abstract class BlockBag {
/**
* Stores a block as if it was mined.
*
* @param id
* @throws BlockBagException
*/
public void storeDroppedBlock(int id) throws BlockBagException {
int dropped = BlockType.getDroppedBlock(id);
if (dropped > 0) {
storeBlock(dropped);
}
}
/**
* Sets a block as if it was placed by hand.
*
* @param id
* @throws BlockBagException
*/
public void fetchPlacedBlock(int id) throws BlockBagException {
try {
// Blocks that can't be fetched...
if (id == BlockID.BEDROCK
|| id == BlockID.GOLD_ORE
|| id == BlockID.IRON_ORE
|| id == BlockID.COAL_ORE
|| id == BlockID.DIAMOND_ORE
|| id == BlockID.LEAVES
|| id == BlockID.TNT
|| id == BlockID.MOB_SPAWNER
|| id == BlockID.CROPS
|| id == BlockID.REDSTONE_ORE
|| id == BlockID.GLOWING_REDSTONE_ORE
|| id == BlockID.SNOW
|| id == BlockID.LIGHTSTONE
|| id == BlockID.PORTAL) {
throw new UnplaceableBlockException();
}
// Override liquids
if (id == BlockID.WATER
|| id == BlockID.STATIONARY_WATER
|| id == BlockID.LAVA
|| id == BlockID.STATIONARY_LAVA) {
return;
}
fetchBlock(id);
} catch (OutOfBlocksException e) {
// Look for cobblestone
if (id == BlockID.STONE) {
fetchBlock(BlockID.COBBLESTONE);
// Look for dirt
} else if (id == BlockID.GRASS) {
fetchBlock(BlockID.DIRT);
// Look for redstone dust
} else if (id == BlockID.REDSTONE_WIRE) {
fetchBlock(331);
// Look for furnace
} else if (id == BlockID.BURNING_FURNACE) {
fetchBlock(BlockID.FURNACE);
// Look for lit redstone torch
} else if (id == BlockID.REDSTONE_TORCH_OFF) {
fetchBlock(BlockID.REDSTONE_TORCH_ON);
// Look for signs
} else if (id == BlockID.WALL_SIGN || id == BlockID.SIGN_POST) {
fetchBlock(323);
} else {
throw e;
}
}
}
/**
* Get a block.
*
* @param id
* @throws BlockBagException
*/
public abstract void fetchBlock(int id) throws BlockBagException;
/**
* Store a block.
*
* @param id
* @throws BlockBagException
*/
public abstract void storeBlock(int id) throws BlockBagException;
/**
* Checks to see if a block exists without removing it.
*
* @param id
* @return whether the block exists
*/
public boolean peekBlock(int id) {
try {
fetchBlock(id);
storeBlock(id);
return true;
} catch (BlockBagException e) {
return false;
}
}
/**
* Flush any changes. This is called at the end.
*/
public abstract void flushChanges();
/**
* Adds a position to be used a source.
*
* @param pos
*/
public abstract void addSourcePosition(Vector pos);
/**
* Adds a position to be used a source.
*
* @param pos
*/
public abstract void addSingleSourcePosition(Vector pos);
}

View File

@ -0,0 +1,28 @@
// $Id$
/*
* CraftBook
* Copyright (C) 2010 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.bags;
/**
*
* @author sk89q
*/
public class BlockBagException extends Exception {
private static final long serialVersionUID = 4672190086028430655L;
}

View File

@ -0,0 +1,28 @@
// $Id$
/*
* CraftBook
* Copyright (C) 2010 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.bags;
/**
*
* @author sk89q
*/
public class OutOfBlocksException extends BlockBagException {
private static final long serialVersionUID = 7495899825677689509L;
}

View File

@ -0,0 +1,48 @@
// $Id$
/*
* CraftBook
* Copyright (C) 2010 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.bags;
/**
*
* @author sk89q
*/
public class OutOfSpaceException extends BlockBagException {
private static final long serialVersionUID = -2962840237632916821L;
/**
* Stores the block ID.
*/
private int id;
/**
* Construct the object.
* @param id
*/
public OutOfSpaceException(int id) {
this.id = id;
}
/**
* @return the id
*/
public int getID() {
return id;
}
}

View File

@ -0,0 +1,30 @@
// $Id$
/*
* CraftBook
* Copyright (C) 2010 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.bags;
/**
*
* @author sk89q
*/
public class UnplaceableBlockException extends BlockBagException {
private static final long serialVersionUID = 7227883966999843526L;
}

View File

@ -0,0 +1,116 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.worldedit.data.BlockData;
/**
* Represents a block.
*
* @author sk89q
*/
public class BaseBlock {
/**
* BaseBlock type.
*/
private short type = 0;
/**
* BaseBlock data.
*/
private char data = 0;
/**
* Construct the block with its type.
*
* @param type
*/
public BaseBlock(int type) {
this.type = (short)type;
}
/**
* Construct the block with its type and data.
*
* @param type
* @param data
*/
public BaseBlock(int type, int data) {
this.type = (short)type;
this.data = (char)data;
}
/**
* @return the type
*/
public int getType() {
return (int)type;
}
/**
* @param type the type to set
*/
public void setType(int type) {
this.type = (short)type;
}
/**
* @return the data
*/
public int getData() {
return (int)data;
}
/**
* @param data the data to set
*/
public void setData(int data) {
this.data = (char)data;
}
/**
* Returns true if it's air.
*
* @return if air
*/
public boolean isAir() {
return type == 0;
}
/**
* Rotate this block 90 degrees.
*/
public void rotate90() {
data = (char)BlockData.rotate90(type, data);
}
/**
* Rotate this block -90 degrees.
*/
public void rotate90Reverse() {
data = (char)BlockData.rotate90Reverse(type, data);
}
/**
* Flip this block.
*/
public void flip() {
data = (char)BlockData.flip(type, data);
}
}

View File

@ -0,0 +1,85 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
/**
* Represents an item.
*
* @author sk89q
*/
public class BaseItem {
/**
* Item ID.
*/
private int id;
/**
* Item damage.
*/
private short damage;
/**
* Construct the object.
*
* @param id
*/
public BaseItem(int id) {
this.id = id;
this.damage = 0;
}
/**
* Construct the object.
*
* @param id
* @param damage
*/
public BaseItem(int id, short damage) {
this.id = id;
this.damage = damage;
}
/**
* @return the id
*/
public int getType() {
return id;
}
/**
* @param id the id to set
*/
public void setType(int id) {
this.id = id;
}
/**
* @return the damage
*/
public short getDamage() {
return damage;
}
/**
* @param damage the damage to set
*/
public void setDamage(short damage) {
this.damage = damage;
}
}

View File

@ -0,0 +1,78 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
/**
* Represents a stack of BaseItems.
*
* @author sk89q
*/
public class BaseItemStack extends BaseItem {
/**
* Amount of an item.
*/
private int amount = 1;
/**
* Construct the object.
*
* @param id
*/
public BaseItemStack(int id) {
super(id);
}
/**
* Construct the object.
*
* @param id
* @param amount
*/
public BaseItemStack(int id, int amount) {
super(id);
this.amount = amount;
}
/**
* Construct the object.
*
* @param id
* @param amount
* @param damage
*/
public BaseItemStack(int id, int amount, short damage) {
super(id, damage);
this.amount = amount;
}
/**
* @return the amount
*/
public int getAmount() {
return amount;
}
/**
* @param amount the amount to set
*/
public void setAmount(int amount) {
this.amount = amount;
}
}

View File

@ -0,0 +1,119 @@
// $Id$
/*
* CraftBook
* Copyright (C) 2010 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.blocks;
/**
* List of block IDs.
*
* @author sk89q
*/
public final class BlockID {
public static final int AIR = 0;
public static final int STONE = 1;
public static final int GRASS = 2;
public static final int DIRT = 3;
public static final int COBBLESTONE = 4;
public static final int WOOD = 5;
public static final int SAPLING = 6;
public static final int BEDROCK = 7;
public static final int WATER = 8;
public static final int STATIONARY_WATER = 9;
public static final int LAVA = 10;
public static final int STATIONARY_LAVA = 11;
public static final int SAND = 12;
public static final int GRAVEL = 13;
public static final int GOLD_ORE = 14;
public static final int IRON_ORE = 15;
public static final int COAL_ORE = 16;
public static final int LOG = 17;
public static final int LEAVES = 18;
public static final int SPONGE = 19;
public static final int GLASS = 20;
public static final int LAPIS_LAZULI_ORE = 21;
public static final int LAPIS_LAZULI_BLOCK = 22;
public static final int DISPENSER = 23;
public static final int SANDSTONE = 24;
public static final int NOTE_BLOCK = 25;
public static final int BED = 26;
public static final int POWERED_RAIL = 27;
public static final int DETECTOR_RAIL = 28;
public static final int WEB = 30;
public static final int CLOTH = 35;
public static final int YELLOW_FLOWER = 37;
public static final int RED_FLOWER = 38;
public static final int BROWN_MUSHROOM = 39;
public static final int RED_MUSHROOM = 40;
public static final int GOLD_BLOCK = 41;
public static final int IRON_BLOCK = 42;
public static final int DOUBLE_STEP = 43;
public static final int STEP = 44;
public static final int BRICK = 45;
public static final int TNT = 46;
public static final int BOOKCASE = 47;
public static final int MOSSY_COBBLESTONE = 48;
public static final int OBSIDIAN = 49;
public static final int TORCH = 50;
public static final int FIRE = 51;
public static final int MOB_SPAWNER = 52;
public static final int WOODEN_STAIRS = 53;
public static final int CHEST = 54;
public static final int REDSTONE_WIRE = 55;
public static final int DIAMOND_ORE = 56;
public static final int DIAMOND_BLOCK = 57;
public static final int WORKBENCH = 58;
public static final int CROPS = 59;
public static final int SOIL = 60;
public static final int FURNACE = 61;
public static final int BURNING_FURNACE = 62;
public static final int SIGN_POST = 63;
public static final int WOODEN_DOOR = 64;
public static final int LADDER = 65;
public static final int MINECART_TRACKS = 66;
public static final int COBBLESTONE_STAIRS = 67;
public static final int WALL_SIGN = 68;
public static final int LEVER = 69;
public static final int STONE_PRESSURE_PLATE = 70;
public static final int IRON_DOOR = 71;
public static final int WOODEN_PRESSURE_PLATE = 72;
public static final int REDSTONE_ORE = 73;
public static final int GLOWING_REDSTONE_ORE = 74;
public static final int REDSTONE_TORCH_OFF = 75;
public static final int REDSTONE_TORCH_ON = 76;
public static final int STONE_BUTTON = 77;
public static final int SNOW = 78;
public static final int ICE = 79;
public static final int SNOW_BLOCK = 80;
public static final int CACTUS = 81;
public static final int CLAY = 82;
public static final int REED = 83;
public static final int JUKEBOX = 84;
public static final int FENCE = 85;
public static final int PUMPKIN = 86;
public static final int NETHERSTONE = 87;
public static final int NETHERRACK = 87;
public static final int SLOW_SAND = 88;
public static final int LIGHTSTONE = 89;
public static final int PORTAL = 90;
public static final int JACKOLANTERN = 91;
public static final int CAKE_BLOCK = 92;
public static final int REDSTONE_REPEATER_OFF = 93;
public static final int REDSTONE_REPEATER_ON = 94;
public static final int LOCKED_CHEST = 95;
}

View File

@ -0,0 +1,538 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumSet;
/**
* Block types.
*
* @author sk89q
*/
public enum BlockType {
AIR(0, "Air", "air"),
STONE(1, "Stone", new String[] {"stone", "rock"}),
GRASS(2, "Grass", "grass"),
DIRT(3, "Dirt", "dirt"),
COBBLESTONE(4, "Cobblestone", new String[] {"cobblestone", "cobble"}),
WOOD(5, "Wood", new String[] {"wood", "woodplank", "plank", "woodplanks", "planks"}),
SAPLING(6, "Sapling", "sapling"),
BEDROCK(7, "Bedrock", new String[] {"adminium", "bedrock"}),
WATER(8, "Water", new String[] {"watermoving", "movingwater"}),
STATIONARY_WATER(9, "Water (stationary)",
new String[] {"water", "waterstationary", "stationarywater", "stillwater"}),
LAVA(10, "Lava", new String[] {"lavamoving", "movinglava"}),
STATIONARY_LAVA(11, "Lava (stationary)",
new String[] {"lava", "lavastationary", "stationarylava", "stilllava"}),
SAND(12, "Sand", "sand"),
GRAVEL(13, "Gravel", "gravel"),
GOLD_ORE(14, "Gold ore", "goldore"),
IRON_ORE(15, "Iron ore", "ironore"),
COAL_ORE(16, "Coal ore", "coalore"),
LOG(17, "Log", new String[] {"log", "tree", "pine", "oak", "birch", "redwood"}),
LEAVES(18, "Leaves", new String[] {"leaves", "leaf"}),
SPONGE(19, "Sponge", "sponge"),
GLASS(20, "Glass", "glass"),
LAPIS_LAZULI_ORE(21, "Lapis lazuli ore", new String[] {"lapislazuliore", "blueore", "lapisore"}),
LAPIS_LAZULI(22, "Lapis lazuli", new String[] {"lapislazuli", "lapislazuliblock", "bluerock"}),
DISPENSER(23, "Dispenser", "dispenser"),
SANDSTONE(24, "Sandstone", "sandstone"),
NOTE_BLOCK(25, "Note block", new String[] {"musicblock", "noteblock", "note", "music", "instrument"}),
BED(26, "Bed", "bed"),
POWERED_RAIL(27, "Powered Rail",
new String[] {"poweredrail", "boosterrail", "poweredtrack", "boostertrack"}),
DETECTOR_RAIL(28, "Detector Rail", "detectorrail"),
WEB(30, "Web", new String[] {"web", "spiderweb"}),
CLOTH(35, "Wool", new String[] {"cloth", "wool"}),
YELLOW_FLOWER(37, "Yellow flower", new String[] {"yellowflower", "flower"}),
RED_FLOWER(38, "Red rose", new String[] {"redflower", "redrose", "rose"}),
BROWN_MUSHROOM(39, "Brown mushroom", new String[] {"brownmushroom", "mushroom"}),
RED_MUSHROOM(40, "Red mushroom", "redmushroom"),
GOLD_BLOCK(41, "Gold block", new String[] {"gold", "goldblock"}),
IRON_BLOCK(42, "Iron block", new String[] {"iron", "ironblock"}),
DOUBLE_STEP(43, "Double step", new String[] {"doubleslab", "doublestoneslab", "doublestep"}),
STEP(44, "Step", new String[] {"slab", "stoneslab", "step", "halfstep"}),
BRICK(45, "Brick", new String[] {"brick", "brickblock"}),
TNT(46, "TNT", "tnt"),
BOOKCASE(47, "Bookcase", new String[] {"bookshelf", "bookshelves"}),
MOSSY_COBBLESTONE(48, "Cobblestone (mossy)",
new String[] {"mossycobblestone", "mossstone", "mossystone",
"mosscobble", "mossycobble", "moss", "mossy", "sossymobblecone"}),
OBSIDIAN(49, "Obsidian", "obsidian"),
TORCH(50, "Torch", "torch"),
FIRE(51, "Fire", new String[] {"fire", "flame", "flames"}),
MOB_SPAWNER(52, "Mob spawner", new String[] {"mobspawner", "spawner"}),
WOODEN_STAIRS(53, "Wooden stairs",
new String[] {"woodstair", "woodstairs", "woodenstair", "woodenstairs"}),
CHEST(54, "Chest", new String[] {"chest", "storage"}),
REDSTONE_WIRE(55, "Redstone wire", "redstone"),
DIAMOND_ORE(56, "Diamond ore", "diamondore"),
DIAMOND_BLOCK(57, "Diamond block", new String[] {"diamond", "diamondblock"}),
WORKBENCH(58, "Workbench", new String[] {"workbench", "table", "craftingtable"}),
CROPS(59, "Crops", new String[] {"crops", "crop", "plant", "plants"}),
SOIL(60, "Soil", new String[] {"soil", "farmland"}),
FURNACE(61, "Furnace", "furnace"),
BURNING_FURNACE(62, "Furnace (burning)", new String[] {"burningfurnace", "litfurnace"}),
SIGN_POST(63, "Sign post", new String[] {"sign", "signpost"}),
WOODEN_DOOR(64, "Wooden door", new String[] {"wooddoor", "woodendoor", "door"}),
LADDER(65, "Ladder", "ladder"),
MINECART_TRACKS(66, "Minecart tracks",
new String[] {"track", "tracks", "minecrattrack", "minecarttracks", "rails", "rail"}),
COBBLESTONE_STAIRS(67, "Cobblestone stairs",
new String[] {"cobblestonestair", "cobblestonestairs", "cobblestair", "cobblestairs"}),
WALL_SIGN(68, "Wall sign", "wallsign"),
LEVER(69, "Lever", new String[] {"lever", "switch", "stonelever", "stoneswitch"}),
STONE_PRESSURE_PLATE(70, "Stone pressure plate",
new String[] {"stonepressureplate", "stoneplate"}),
IRON_DOOR(71, "Iron Door", "irondoor"),
WOODEN_PRESSURE_PLATE(72, "Wooden pressure plate",
new String[] {"woodpressureplate", "woodplate", "woodenpressureplate", "woodenplate"}),
REDSTONE_ORE(73, "Redstone ore", "redstoneore"),
GLOWING_REDSTONE_ORE(74, "Glowing redstone ore", "glowingredstoneore"),
REDSTONE_TORCH_OFF(75, "Redstone torch (off)",
new String[] {"redstonetorchoff", "rstorchoff"}),
REDSTONE_TORCH_ON(76, "Redstone torch (on)",
new String [] {"redstonetorch", "redstonetorchon", "rstorchon"}),
STONE_BUTTON(77, "Stone Button", new String[] {"stonebutton", "button"}),
SNOW(78, "Snow", "snow"),
ICE(79, "Ice", "ice"),
SNOW_BLOCK(80, "Snow block", "snowblock"),
CACTUS(81, "Cactus", new String[] {"cactus", "cacti"}),
CLAY(82, "Clay", "clay"),
SUGAR_CANE(83, "Reed", new String[] {"reed", "cane", "sugarcane", "sugarcanes"}),
JUKEBOX(84, "Jukebox", new String[] {"jukebox", "stereo", "recordplayer"}),
FENCE(85, "Fence", "fence"),
PUMPKIN(86, "Pumpkin", "pumpkin"),
NETHERRACK(87, "Netherrack",
new String[] {"redmossycobblestone", "redcobblestone", "redmosstone",
"redcobble", "netherstone", "netherrack", "nether", "hellstone"}),
SOUL_SAND(88, "Soul sand",
new String[] {"slowmud", "mud", "soulsand", "hellmud"}),
GLOWSTONE(89, "Glowstone",
new String[] {"brittlegold", "glowstone", "lightstone", "brimstone", "australium"}),
PORTAL(90, "Portal", "portal"),
JACK_O_LANTERN(91, "Pumpkin (on)",
new String[] {"pumpkinlighted", "pumpkinon", "litpumpkin", "jackolantern"}),
CAKE(92, "Cake", new String[] {"cake", "cakeblock"}),
REDSTONE_REPEATER_OFF(93, "Redstone repeater (off)", new String[] {"diodeoff", "redstonerepeater", "repeater", "delayer"}),
REDSTONE_REPEATER_ON(94, "Redstone repeater (on)", new String[] {"diode", "diodeon", "redstonerepeateron", "repeateron", "delayeron"}),
LOCKED_CHEST(95, "Locked chest", new String[] {"lockedchest", "steveco", "supplycrate", "valveneedstoworkonep3nottf2kthx"});
/**
* Stores a list of dropped blocks for blocks.
*/
private static final Map<Integer,Integer> blockDrops = new HashMap<Integer,Integer>();
/**
* Static constructor.
*/
static {
blockDrops.put(1, 4);
blockDrops.put(2, 3);
blockDrops.put(3, 3);
blockDrops.put(4, 4);
blockDrops.put(5, 5);
blockDrops.put(6, 6);
blockDrops.put(7, -1);
blockDrops.put(12, 12);
blockDrops.put(13, 13);
blockDrops.put(14, 14);
blockDrops.put(15, 15);
blockDrops.put(16, 16);
blockDrops.put(17, 17);
blockDrops.put(18, 18);
blockDrops.put(19, 19);
blockDrops.put(20, 20); // Have to drop glass for //undo
blockDrops.put(21, 21); // Block damage drops not implemented
blockDrops.put(22, 22);
blockDrops.put(23, 23);
blockDrops.put(24, 24);
blockDrops.put(25, 25);
blockDrops.put(26, 355);
blockDrops.put(27, 27);
blockDrops.put(28, 28);
blockDrops.put(30, 30);
blockDrops.put(35, 35);
blockDrops.put(37, 37);
blockDrops.put(38, 38);
blockDrops.put(39, 39);
blockDrops.put(40, 40);
blockDrops.put(41, 41);
blockDrops.put(42, 42);
blockDrops.put(43, 43);
blockDrops.put(44, 44);
blockDrops.put(45, 45);
blockDrops.put(47, 47);
blockDrops.put(48, 48);
blockDrops.put(49, 49);
blockDrops.put(50, 50);
blockDrops.put(53, 53);
blockDrops.put(54, 54);
blockDrops.put(55, 331);
blockDrops.put(56, 264);
blockDrops.put(57, 57);
blockDrops.put(58, 58);
blockDrops.put(59, 295);
blockDrops.put(60, 60);
blockDrops.put(61, 61);
blockDrops.put(62, 61);
blockDrops.put(63, 323);
blockDrops.put(64, 324);
blockDrops.put(65, 65);
blockDrops.put(66, 66);
blockDrops.put(67, 67);
blockDrops.put(68, 323);
blockDrops.put(69, 69);
blockDrops.put(70, 70);
blockDrops.put(71, 330);
blockDrops.put(72, 72);
blockDrops.put(73, 331);
blockDrops.put(74, 331);
blockDrops.put(75, 76);
blockDrops.put(76, 76);
blockDrops.put(77, 77);
blockDrops.put(78, 332);
blockDrops.put(80, 80);
blockDrops.put(81, 81);
blockDrops.put(82, 82);
blockDrops.put(83, 338);
blockDrops.put(84, 84);
blockDrops.put(85, 85);
blockDrops.put(86, 86);
blockDrops.put(87, 87);
blockDrops.put(88, 88);
blockDrops.put(89, 348);
blockDrops.put(91, 91);
blockDrops.put(92, 354);
blockDrops.put(93, 356);
blockDrops.put(94, 356);
blockDrops.put(95, 95);
}
/**
* Stores a map of the IDs for fast access.
*/
private static final Map<Integer,BlockType> ids = new HashMap<Integer,BlockType>();
/**
* Stores a map of the names for fast access.
*/
private static final Map<String,BlockType> lookup = new HashMap<String,BlockType>();
private final int id;
private final String name;
private final String[] lookupKeys;
static {
for(BlockType type : EnumSet.allOf(BlockType.class)) {
ids.put(type.id, type);
for (String key : type.lookupKeys) {
lookup.put(key, type);
}
}
}
/**
* Construct the type.
*
* @param id
* @param name
*/
BlockType(int id, String name, String lookupKey) {
this.id = id;
this.name = name;
this.lookupKeys = new String[]{lookupKey};
}
/**
* Construct the type.
*
* @param id
* @param name
*/
BlockType(int id, String name, String[] lookupKeys) {
this.id = id;
this.name = name;
this.lookupKeys = lookupKeys;
}
/**
* Return type from ID. May return null.
*
* @param id
* @return
*/
public static BlockType fromID(int id) {
return ids.get(id);
}
/**
* Return type from name. May return null.
*
* @param name
* @return
*/
public static BlockType lookup(String name) {
return lookup.get(name.toLowerCase());
}
/**
* Get block numeric ID.
*
* @return
*/
public int getID() {
return id;
}
/**
* Get user-friendly block name.
*
* @return
*/
public String getName() {
return name;
}
/**
* Checks to see whether a block should be placed last.
*
* @return
*/
public boolean shouldPlaceLast() {
return shouldPlaceLast(id);
}
/**
* Checks to see whether a block should be placed last.
*
* @param id
* @return
*/
public static boolean shouldPlaceLast(int id) {
return id == 6 // Saplings
|| id == 26 // Beds
|| id == 27 // Powered rails
|| id == 28 // Detector rails
|| id == 37 // Yellow flower
|| id == 38 // Red flower
|| id == 39 // Brown mushroom
|| id == 40 // Red mush room
|| id == 50 // Torch
|| id == 51 // Fire
|| id == 55 // Redstone wire
|| id == 59 // Crops
|| id == 63 // Sign post
|| id == 64 // Wooden door
|| id == 65 // Ladder
|| id == 66 // Minecart tracks
|| id == 68 // Wall sign
|| id == 69 // Lever
|| id == 70 // Stone pressure plate
|| id == 71 // Iron door
|| id == 72 // Wooden pressure plate
|| id == 75 // Redstone torch (off)
|| id == 76 // Redstone torch (on)
|| id == 77 // Stone button
|| id == 78 // Snow
|| id == 81 // Cactus
|| id == 83 // Reed
|| id == 90 // Portal
|| id == 92 // Cake
|| id == 93 // Repeater (off)
|| id == 94; // Repeater (on)
}
/**
* Checks whether a block can be passed through.
*
* @param id
* @return
*/
public static boolean canPassThrough(int id) {
return id == 0 // Air
|| id == 8 // Water
|| id == 9 // Water
|| id == 6 // Saplings
|| id == 27 // Powered rails
|| id == 28 // Detector rails
|| id == 30 // Web <- someone will hate me for this
|| id == 37 // Yellow flower
|| id == 38 // Red flower
|| id == 39 // Brown mushroom
|| id == 40 // Red mush room
|| id == 50 // Torch
|| id == 51 // Fire
|| id == 55 // Redstone wire
|| id == 59 // Crops
|| id == 63 // Sign post
|| id == 65 // Ladder
|| id == 66 // Minecart tracks
|| id == 68 // Wall sign
|| id == 69 // Lever
|| id == 70 // Stone pressure plate
|| id == 72 // Wooden pressure plate
|| id == 75 // Redstone torch (off)
|| id == 76 // Redstone torch (on)
|| id == 77 // Stone button
|| id == 78 // Snow
|| id == 83 // Reed
|| id == 90 // Portal
|| id == 93 // Diode (off)
|| id == 94; // Diode (on)
}
/**
* Returns true if the block uses its data value.
*
* @param id
* @return
*/
public static boolean usesData(int id) {
return id == 6 // Saplings
|| id == 8 // Water
|| id == 9 // Water
|| id == 10 // Lava
|| id == 11 // Lava
|| id == 17 // Wood
|| id == 18 // Leaves
|| id == 23 // Dispenser
|| id == 25 // Note Block
|| id == 26 // Bed
|| id == 27 // Powered rails
|| id == 28 // Detector rails
|| id == 35 // Wool
|| id == 43 // Double slab
|| id == 44 // Slab
|| id == 50 // Torch
|| id == 53 // Wooden stairs
|| id == 55 // Redstone wire
|| id == 59 // Crops
|| id == 60 // Soil
|| id == 61 // Furnace
|| id == 62 // Furnace
|| id == 63 // Sign post
|| id == 64 // Wooden door
|| id == 65 // Ladder
|| id == 66 // Minecart track
|| id == 67 // Cobblestone stairs
|| id == 68 // Wall sign
|| id == 69 // Lever
|| id == 70 // Stone pressure plate
|| id == 71 // Iron door
|| id == 72 // Wooden pressure plate
|| id == 75 // Redstone torch (off)
|| id == 76 // Redstone torch (on)
|| id == 77 // Stone button
|| id == 81 // Cactus
|| id == 86 // Pumpkin
|| id == 91 // Jack-o-lantern
|| id == 92 // Cake
|| id == 93 // Redstone repeater (off)
|| id == 94; // Redstone repeater (on)
}
/**
* Returns true if the block is a container block.
*
* @param id
* @return
*/
public static boolean isContainerBlock(int id) {
return id == 23 // Dispenser
|| id == 61 // Furnace
|| id == 62 // Furnace
|| id == 54; // Chest
}
/**
* Returns true if a block uses redstone in some way.
*
* @param id
* @return
*/
public static boolean isRedstoneBlock(int id) {
return id == 27 // Powered rail
|| id == 28 // Detector rail
|| id == 69 // Lever
|| id == 70 // Stone pressure plate
|| id == 72 // Wood pressure plate
|| id == 76 // Redstone torch
|| id == 75 // Redstone torch
|| id == 77 // Stone button
|| id == 55 // Redstone wire
|| id == 64 // Wooden door
|| id == 71 // Iron door
|| id == 46 // TNT
|| id == 23 // Dispenser
|| id == 25 // Note block
|| id == 93 // Diode (off)
|| id == 94; // Diode (on)
}
/**
* Returns true if a block can transfer redstone.
* Made this since isRedstoneBlock was getting big.
*
* @param id
* @return
*/
public static boolean canTransferRedstone(int id) {
return id == 75 // Redstone torch (off)
|| id == 76 // Redstone torch (on)
|| id == 55 // Redstone wire
|| id == 93 // Diode (off)
|| id == 94; // Diode (on)
}
/**
* Yay for convenience methods.
*
* @param id
* @return
*/
public static boolean isRedstoneSource(int id) {
return id == 28 // Detector rail
|| id == 75 // Redstone torch (off)
|| id == 76 // Redstone torch (on)
|| id == 69 // Lever
|| id == 70 // Stone plate
|| id == 72 // Wood plate
|| id == 77; // Button
}
/**
* Get the block or item that would have been dropped. If nothing is
* dropped, 0 will be returned. If the block should not be destroyed
* (i.e. bedrock), -1 will be returned.
*
* @param id
* @return
*/
public static int getDroppedBlock(int id) {
Integer dropped = blockDrops.get(id);
if (dropped == null) {
return 0;
}
return dropped;
}
}

View File

@ -0,0 +1,165 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.data.*;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
/**
* Represents chests.
*
* @author sk89q
*/
public class ChestBlock extends BaseBlock implements TileEntityBlock, ContainerBlock {
/**
* Store the list of items.
*/
private BaseItemStack[] items;
/**
* Construct the chest block.
*/
public ChestBlock() {
super(54);
items = new BaseItemStack[27];
}
/**
* Construct the chest block.
*
* @param data
*/
public ChestBlock(int data) {
super(54, data);
items = new BaseItemStack[27];
}
/**
* Construct the chest block.
*
* @param data
* @param items
*/
public ChestBlock(int data, BaseItemStack[] items) {
super(54, data);
this.items = items;
}
/**
* Get the list of items.
*
* @return
*/
public BaseItemStack[] getItems() {
return items;
}
/**
* Set the list of items.
*/
public void setItems(BaseItemStack[] items) {
this.items = items;
}
/**
* Get the tile entity ID.
*
* @return
*/
public String getTileEntityID() {
return "Chest";
}
/**
* Store additional tile entity data. Returns true if the data is used.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException {
List<Tag> itemsList = new ArrayList<Tag>();
for (int i = 0; i < items.length; i++) {
BaseItemStack item = items[i];
if (item != null) {
Map<String,Tag> data = new HashMap<String,Tag>();
CompoundTag itemTag = new CompoundTag("Items", data);
data.put("id", new ShortTag("id", (short)item.getType()));
data.put("Damage", new ShortTag("Damage", item.getDamage()));
data.put("Count", new ByteTag("Count", (byte)item.getAmount()));
data.put("Slot", new ByteTag("Slot", (byte)i));
itemsList.add(itemTag);
}
}
Map<String,Tag> values = new HashMap<String,Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class, itemsList));
return values;
}
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException {
if (values == null) {
return;
}
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("Chest")) {
throw new DataException("'Chest' tile entity expected");
}
ListTag items = (ListTag)Chunk.getChildTag(values, "Items", ListTag.class);
BaseItemStack[] newItems = new BaseItemStack[27];
for (Tag tag : items.getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException("CompoundTag expected as child tag of Chest's Items");
}
CompoundTag item = (CompoundTag)tag;
Map<String,Tag> itemValues = item.getValue();
short id = (Short)((ShortTag)Chunk.getChildTag(itemValues, "id", ShortTag.class))
.getValue();
short damage = (Short)((ShortTag)Chunk.getChildTag(itemValues, "Damage", ShortTag.class))
.getValue();
byte count = (Byte)((ByteTag)Chunk.getChildTag(itemValues, "Count", ByteTag.class))
.getValue();
byte slot = (Byte)((ByteTag)Chunk.getChildTag(itemValues, "Slot", ByteTag.class))
.getValue();
if (slot >= 0 && slot <= 26) {
newItems[slot] = new BaseItemStack(id, count, damage);
}
}
this.items = newItems;
}
}

View File

@ -0,0 +1,133 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumSet;
/**
* Cloth colors.
*
* @author sk89q
*/
public enum ClothColor {
WHITE(0, "White", "white"),
ORANGE(1, "Orange", "orange"),
MAGENTA(2, "Magenta", "magenta"),
LIGHT_BLUE(3, "Light blue", "lightblue"),
YELLOW(4, "Yellow", "yellow"),
LIGHT_GREEN(5, "Light green", "lightgreen"),
PINK(6, "Pink", new String[] {"pink", "lightred"}),
GRAY(7, "Gray", new String[] {"grey", "gray"}),
LIGHT_GRAY(8, "Light gray", new String[] {"lightgrey", "lightgray"}),
CYAN(9, "Cyan", new String[] {"cyan", "turquoise"}),
PURPLE(10, "Purple", new String[] {"purple", "violet"}),
BLUE(11, "Blue", "blue"),
BROWN(12, "Brown", new String[] {"brown", "cocoa", "coffee"}),
DARK_GREEN(13, "Dark green", new String[] {"green", "darkgreen", "cactusgreen", "cactigreen"}),
RED(14, "Red", "red"),
BLACK(15, "Black", "black");
/**
* Stores a map of the IDs for fast access.
*/
private static final Map<Integer,ClothColor> ids = new HashMap<Integer,ClothColor>();
/**
* Stores a map of the names for fast access.
*/
private static final Map<String,ClothColor> lookup = new HashMap<String,ClothColor>();
private final int id;
private final String name;
private final String[] lookupKeys;
static {
for (ClothColor type : EnumSet.allOf(ClothColor.class)) {
ids.put(type.id, type);
for (String key : type.lookupKeys) {
lookup.put(key, type);
}
}
}
/**
* Construct the type.
*
* @param id
* @param name
*/
ClothColor(int id, String name, String lookupKey) {
this.id = id;
this.name = name;
this.lookupKeys = new String[]{lookupKey};
}
/**
* Construct the type.
*
* @param id
* @param name
*/
ClothColor(int id, String name, String[] lookupKeys) {
this.id = id;
this.name = name;
this.lookupKeys = lookupKeys;
}
/**
* Return type from ID. May return null.
*
* @param id
* @return
*/
public static ClothColor fromID(int id) {
return ids.get(id);
}
/**
* Return type from name. May return null.
*
* @param name
* @return
*/
public static ClothColor lookup(String name) {
return lookup.get(name.toLowerCase());
}
/**
* Get item numeric ID.
*
* @return
*/
public int getID() {
return id;
}
/**
* Get user-friendly item name.
*
* @return
*/
public String getName() {
return name;
}
}

View File

@ -0,0 +1,41 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
/**
* Represents a block that stores items.
*
* @author sk89q
*/
public interface ContainerBlock {
/**
* Get the list of items.
*
* @return
*/
public BaseItemStack[] getItems();
/**
* Set the list of items.
*
* @param items
*/
public void setItems(BaseItemStack[] items);
}

View File

@ -0,0 +1,165 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.data.*;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
/**
* Represents dispensers.
*
* @author sk89q
*/
public class DispenserBlock extends BaseBlock implements TileEntityBlock, ContainerBlock {
/**
* Store the list of items.
*/
private BaseItemStack[] items;
/**
* Construct the chest block.
*/
public DispenserBlock() {
super(54);
items = new BaseItemStack[9];
}
/**
* Construct the chest block.
*
* @param data
*/
public DispenserBlock(int data) {
super(23, data);
items = new BaseItemStack[9];
}
/**
* Construct the chest block.
*
* @param data
* @param items
*/
public DispenserBlock(int data, BaseItemStack[] items) {
super(23, data);
this.items = items;
}
/**
* Get the list of items.
*
* @return
*/
public BaseItemStack[] getItems() {
return items;
}
/**
* Set the list of items.
*/
public void setItems(BaseItemStack[] items) {
this.items = items;
}
/**
* Get the tile entity ID.
*
* @return
*/
public String getTileEntityID() {
return "Trap";
}
/**
* Store additional tile entity data. Returns true if the data is used.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException {
List<Tag> itemsList = new ArrayList<Tag>();
for (int i = 0; i < items.length; i++) {
BaseItemStack item = items[i];
if (item != null) {
Map<String,Tag> data = new HashMap<String,Tag>();
CompoundTag itemTag = new CompoundTag("Items", data);
data.put("id", new ShortTag("id", (short)item.getType()));
data.put("Damage", new ShortTag("Damage", item.getDamage()));
data.put("Count", new ByteTag("Count", (byte)item.getAmount()));
data.put("Slot", new ByteTag("Slot", (byte)i));
itemsList.add(itemTag);
}
}
Map<String,Tag> values = new HashMap<String,Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class, itemsList));
return values;
}
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException {
if (values == null) {
return;
}
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("Trap")) {
throw new DataException("'Trap' tile entity expected");
}
ListTag items = (ListTag)Chunk.getChildTag(values, "Items", ListTag.class);
BaseItemStack[] newItems = new BaseItemStack[27];
for (Tag tag : items.getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException("CompoundTag expected as child tag of Trap Items");
}
CompoundTag item = (CompoundTag)tag;
Map<String,Tag> itemValues = item.getValue();
short id = (Short)((ShortTag)Chunk.getChildTag(itemValues, "id", ShortTag.class))
.getValue();
short damage = (Short)((ShortTag)Chunk.getChildTag(itemValues, "Damage", ShortTag.class))
.getValue();
byte count = (Byte)((ByteTag)Chunk.getChildTag(itemValues, "Count", ByteTag.class))
.getValue();
byte slot = (Byte)((ByteTag)Chunk.getChildTag(itemValues, "Slot", ByteTag.class))
.getValue();
if (slot >= 0 && slot <= 26) {
newItems[slot] = new BaseItemStack(id, count, damage);
}
}
this.items = newItems;
}
}

View File

@ -0,0 +1,218 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.data.*;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
/**
* Represents furnaces.
*
* @author sk89q
*/
public class FurnaceBlock extends BaseBlock implements TileEntityBlock, ContainerBlock {
/**
* Store the list of items.
*/
private BaseItemStack[] items;
/**
* Fuel time.
*/
private short burnTime;
/**
* Cook time.
*/
private short cookTime;
/**
* Construct the chest block.
*
* @param type
*/
public FurnaceBlock(int type) {
super(type);
items = new BaseItemStack[2];
}
/**
* Construct the chest block.
*
* @param type
* @param data
*/
public FurnaceBlock(int type, int data) {
super(type, data);
items = new BaseItemStack[2];
}
/**
* Construct the chest block.
*
* @param type
* @param data
* @param items
*/
public FurnaceBlock(int type, int data, BaseItemStack[] items) {
super(type, data);
this.items = items;
}
/**
* Get the list of items.
*
* @return
*/
public BaseItemStack[] getItems() {
return items;
}
/**
* Set the list of items.
*/
public void setItems(BaseItemStack[] items) {
this.items = items;
}
/**
* @return the burnTime
*/
public short getBurnTime() {
return burnTime;
}
/**
* @param burnTime the burnTime to set
*/
public void setBurnTime(short burnTime) {
this.burnTime = burnTime;
}
/**
* @return the cookTime
*/
public short getCookTime() {
return cookTime;
}
/**
* @param cookTime the cookTime to set
*/
public void setCookTime(short cookTime) {
this.cookTime = cookTime;
}
/**
* Get the tile entity ID.
*
* @return
*/
public String getTileEntityID() {
return "Furnace";
}
/**
* Store additional tile entity data. Returns true if the data is used.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException {
List<Tag> itemsList = new ArrayList<Tag>();
for (int i = 0; i < items.length; i++) {
BaseItemStack item = items[i];
if (item != null) {
Map<String,Tag> data = new HashMap<String,Tag>();
CompoundTag itemTag = new CompoundTag("Items", data);
data.put("id", new ShortTag("id", (short)item.getType()));
data.put("Damage", new ShortTag("Damage", item.getDamage()));
data.put("Count", new ByteTag("Count", (byte)item.getAmount()));
data.put("Slot", new ByteTag("Slot", (byte)i));
itemsList.add(itemTag);
}
}
Map<String,Tag> values = new HashMap<String,Tag>();
values.put("Items", new ListTag("Items", CompoundTag.class, itemsList));
values.put("BurnTime", new ShortTag("BurnTime", burnTime));
values.put("CookTime", new ShortTag("CookTime", cookTime));
return values;
}
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException {
if (values == null) {
return;
}
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("Furnace")) {
throw new DataException("'Furnace' tile entity expected");
}
ListTag items = (ListTag)Chunk.getChildTag(values, "Items", ListTag.class);
BaseItemStack[] newItems = new BaseItemStack[27];
for (Tag tag : items.getValue()) {
if (!(tag instanceof CompoundTag)) {
throw new DataException("CompoundTag expected as child tag of Trap Items");
}
CompoundTag item = (CompoundTag)tag;
Map<String,Tag> itemValues = item.getValue();
short id = (Short)((ShortTag)Chunk.getChildTag(itemValues, "id", ShortTag.class))
.getValue();
short damage = (Short)((ShortTag)Chunk.getChildTag(itemValues, "Damage", ShortTag.class))
.getValue();
byte count = (Byte)((ByteTag)Chunk.getChildTag(itemValues, "Count", ByteTag.class))
.getValue();
byte slot = (Byte)((ByteTag)Chunk.getChildTag(itemValues, "Slot", ByteTag.class))
.getValue();
if (slot >= 0 && slot <= 26) {
newItems[slot] = new BaseItemStack(id, count, damage);
}
}
this.items = newItems;
t = values.get("BurnTime");
if (t instanceof ShortTag) {
burnTime = ((ShortTag)t).getValue();
}
t = values.get("CookTime");
if (t instanceof ShortTag) {
cookTime = ((ShortTag)t).getValue();
}
}
}

View File

@ -0,0 +1,411 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumSet;
/**
* ItemType types.
*
* @author sk89q
*/
public enum ItemType {
// Blocks
AIR(0, "Air", "air"),
STONE(1, "Stone", new String[] {"stone", "rock"}),
GRASS(2, "Grass", "grass"),
DIRT(3, "Dirt", "dirt"),
COBBLESTONE(4, "Cobblestone", new String[] {"cobblestone", "cobble"}),
WOOD(5, "Wood", new String[] {"wood", "woodplank", "plank", "woodplanks", "planks"}),
SAPLING(6, "Sapling", "sapling"),
BEDROCK(7, "Bedrock", new String[] {"adminium", "bedrock"}),
WATER(8, "Water", new String[] {"watermoving", "movingwater"}),
STATIONARY_WATER(9, "Water (stationary)",
new String[] {"water", "waterstationary", "stationarywater", "stillwater"}),
LAVA(10, "Lava", new String[] {"lavamoving", "movinglava"}),
STATIONARY_LAVA(11, "Lava (stationary)",
new String[] {"lava", "lavastationary", "stationarylava", "stilllava"}),
SAND(12, "Sand", "sand"),
GRAVEL(13, "Gravel", "gravel"),
GOLD_ORE(14, "Gold ore", "goldore"),
IRON_ORE(15, "Iron ore", "ironore"),
COAL_ORE(16, "Coal ore", "coalore"),
LOG(17, "Log", new String[] {"log", "tree", "pine", "oak", "birch", "redwood"}),
LEAVES(18, "Leaves", new String[] {"leaves", "leaf"}),
SPONGE(19, "Sponge", "sponge"),
GLASS(20, "Glass", "glass"),
LAPIS_LAZULI_ORE(21, "Lapis lazuli ore", new String[] {"lapislazuliore", "blueore", "lapisore"}),
LAPIS_LAZULI(22, "Lapis lazuli", new String[] {"lapislazuli", "lapislazuliblock", "bluerock"}),
DISPENSER(23, "Dispenser", "dispenser"),
SANDSTONE(24, "Sandstone", "sandstone"),
NOTE_BLOCK(25, "Note block", new String[] {"musicblock", "noteblock", "note", "music", "instrument"}),
BED(26, "Bed", "bed"),
POWERED_RAIL(27, "Powered Rail",
new String[] {"poweredrail", "boosterrail", "poweredtrack", "boostertrack"}),
DETECTOR_RAIL(28, "Detector Rail", "detectorrail"),
WEB(30, "Web", new String[] {"web", "spiderweb"}),
CLOTH(35, "Wool", new String[] {"cloth", "wool"}),
YELLOW_FLOWER(37, "Yellow flower", new String[] {"yellowflower", "flower"}),
RED_FLOWER(38, "Red rose", new String[] {"redflower", "redrose", "rose"}),
BROWN_MUSHROOM(39, "Brown mushroom", new String[] {"brownmushroom", "mushroom"}),
RED_MUSHROOM(40, "Red mushroom", "redmushroom"),
GOLD_BLOCK(41, "Gold block", new String[] {"gold", "goldblock"}),
IRON_BLOCK(42, "Iron block", new String[] {"iron", "ironblock"}),
DOUBLE_STEP(43, "Double step", new String[] {"doubleslab", "doublestoneslab", "doublestep"}),
STEP(44, "Step", new String[] {"slab", "stoneslab", "step", "halfstep"}),
BRICK(45, "Brick", new String[] {"brick", "brickblock"}),
TNT(46, "TNT", "tnt"),
BOOKCASE(47, "Bookcase", new String[] {"bookshelf", "bookshelves"}),
MOSSY_COBBLESTONE(48, "Cobblestone (mossy)",
new String[] {"mossycobblestone", "mossstone", "mossystone",
"mosscobble", "mossycobble", "moss", "mossy", "sossymobblecone"}),
OBSIDIAN(49, "Obsidian", "obsidian"),
TORCH(50, "Torch", "torch"),
FIRE(51, "Fire", new String[] {"fire", "flame", "flames"}),
MOB_SPAWNER(52, "Mob spawner", new String[] {"mobspawner", "spawner"}),
WOODEN_STAIRS(53, "Wooden stairs",
new String[] {"woodstair", "woodstairs", "woodenstair", "woodenstairs"}),
CHEST(54, "Chest", new String[] {"chest", "storage"}),
REDSTONE_WIRE(55, "Redstone wire", "redstone"),
DIAMOND_ORE(56, "Diamond ore", "diamondore"),
DIAMOND_BLOCK(57, "Diamond block", new String[] {"diamond", "diamondblock"}),
WORKBENCH(58, "Workbench", new String[] {"workbench", "table", "craftingtable"}),
CROPS(59, "Crops", new String[] {"crops", "crop", "plant", "plants"}),
SOIL(60, "Soil", new String[] {"soil", "farmland"}),
FURNACE(61, "Furnace", "furnace"),
BURNING_FURNACE(62, "Furnace (burning)", new String[] {"burningfurnace", "litfurnace"}),
SIGN_POST(63, "Sign post", new String[] {"sign", "signpost"}),
WOODEN_DOOR(64, "Wooden door", new String[] {"wooddoor", "woodendoor", "door"}),
LADDER(65, "Ladder", "ladder"),
MINECART_TRACKS(66, "Minecart tracks",
new String[] {"track", "tracks", "minecrattrack", "minecarttracks", "rails", "rail"}),
COBBLESTONE_STAIRS(67, "Cobblestone stairs",
new String[] {"cobblestonestair", "cobblestonestairs", "cobblestair", "cobblestairs"}),
WALL_SIGN(68, "Wall sign", "wallsign"),
LEVER(69, "Lever", new String[] {"lever", "switch", "stonelever", "stoneswitch"}),
STONE_PRESSURE_PLATE(70, "Stone pressure plate",
new String[] {"stonepressureplate", "stoneplate"}),
IRON_DOOR(71, "Iron Door", "irondoor"),
WOODEN_PRESSURE_PLATE(72, "Wooden pressure plate",
new String[] {"woodpressureplate", "woodplate", "woodenpressureplate", "woodenplate"}),
REDSTONE_ORE(73, "Redstone ore", "redstoneore"),
GLOWING_REDSTONE_ORE(74, "Glowing redstone ore", "glowingredstoneore"),
REDSTONE_TORCH_OFF(75, "Redstone torch (off)",
new String[] {"redstonetorchoff", "rstorchoff"}),
REDSTONE_TORCH_ON(76, "Redstone torch (on)",
new String [] {"redstonetorch", "redstonetorchon", "rstorchon"}),
STONE_BUTTON(77, "Stone Button", new String[] {"stonebutton", "button"}),
SNOW(78, "Snow", "snow"),
ICE(79, "Ice", "ice"),
SNOW_BLOCK(80, "Snow block", "snowblock"),
CACTUS(81, "Cactus", new String[] {"cactus", "cacti"}),
CLAY(82, "Clay", "clay"),
SUGAR_CANE(83, "Reed", new String[] {"reed", "cane", "sugarcane", "sugarcanes"}),
JUKEBOX(84, "Jukebox", new String[] {"jukebox", "stereo", "recordplayer"}),
FENCE(85, "Fence", "fence"),
PUMPKIN(86, "Pumpkin", "pumpkin"),
NETHERRACK(87, "Netherrack",
new String[] {"redmossycobblestone", "redcobblestone", "redmosstone",
"redcobble", "netherstone", "netherrack", "nether", "hellstone"}),
SOUL_SAND(88, "Soul sand",
new String[] {"slowmud", "mud", "soulsand", "hellmud"}),
GLOWSTONE(89, "Glowstone",
new String[] {"brittlegold", "glowstone", "lightstone", "brimstone", "australium"}),
PORTAL(90, "Portal", "portal"),
JACK_O_LANTERN(91, "Pumpkin (on)",
new String[] {"pumpkinlighted", "pumpkinon", "litpumpkin", "jackolantern"}),
CAKE(92, "Cake", new String[] {"cake", "cakeblock"}),
REDSTONE_REPEATER_OFF(93, "Redstone repeater (off)", new String[] {"diodeoff", "redstonerepeater", "repeater", "delayer"}),
REDSTONE_REPEATER_ON(94, "Redstone repeater (on)", new String[] {"diode", "diodeon", "redstonerepeateron", "repeateron", "delayeron"}),
LOCKED_CHEST(95, "Locked chest", new String[] {"lockedchest", "steveco", "supplycrate", "valveneedstoworkonep3nottf2kthx"}),
// Items
IRON_SHOVEL(256, "Iron shovel", "ironshovel"),
IRON_PICK(257, "Iron pick", new String[] {"ironpick", "ironpickaxe"}),
IRON_AXE(258, "Iron axe", "ironaxe"),
FLINT_AND_TINDER(259, "Flint and tinder",
new String[] {"flintandtinder", "lighter", "flintandsteel", "flintsteel",
"flintandiron", "flintnsteel", "flintniron", "flintntinder"}),
RED_APPLE(260, "Red apple", new String[] {"redapple", "apple"}),
BOW(261, "Bow", "bow"),
ARROW(262, "Arrow", "arrow"),
COAL(263, "Coal", "coal"),
DIAMOND(264, "Diamond", "diamond"),
IRON_BAR(265, "Iron bar", "ironbar"),
GOLD_BAR(266, "Gold bar", "goldbar"),
IRON_SWORD(267, "Iron sword", "ironsword"),
WOOD_SWORD(268, "Wooden sword", "woodsword"),
WOOD_SHOVEL(269, "Wooden shovel", "woodshovel"),
WOOD_PICKAXE(270, "Wooden pickaxe", new String[] {"woodpick", "woodpickaxe"}),
WOOD_AXE(271, "Wooden axe", "woodaxe"),
STONE_SWORD(272, "Stone sword", "stonesword"),
STONE_SHOVEL(273, "Stone shovel", "stoneshovel"),
STONE_PICKAXE(274, "Stone pickaxe", new String[] {"stonepick", "stonepickaxe"}),
STONE_AXE(275, "Stone pickaxe", "stoneaxe"),
DIAMOND_SWORD(276, "Diamond sword", "diamondsword"),
DIAMOND_SHOVEL(277, "Diamond shovel", "diamondshovel"),
DIAMOND_PICKAXE(278, "Diamond pickaxe", new String[] {"diamondpick", "diamondpickaxe"}),
DIAMOND_AXE(279, "Diamond axe", "diamondaxe"),
STICK(280, "Stick", "stick"),
BOWL(281, "Bowl", "bowl"),
MUSHROOM_SOUP(282, "Mushroom soup", new String[] {"mushroomsoup", "soup", "brbsoup"}),
GOLD_SWORD(283, "Golden sword", "goldsword"),
GOLD_SHOVEL(284, "Golden shovel", "goldshovel"),
GOLD_PICKAXE(285, "Golden pickaxe", new String[] {"goldpick", "goldpickaxe"}),
GOLD_AXE(286, "Golden axe", "goldaxe"),
STRING(287, "String", "string"),
FEATHER(288, "Feather", "feather"),
SULPHUR(289, "Sulphur", new String[] {"sulphur", "sulfur", "gunpowder"}),
WOOD_HOE(290, "Wooden hoe", "woodhoe"),
STONE_HOE(291, "Stone hoe", "stonehoe"),
IRON_HOE(292, "Iron hoe", "ironhoe"),
DIAMOND_HOE(293, "Diamond hoe", "diamondhoe"),
GOLD_HOE(294, "Golden hoe", "goldhoe"),
SEEDS(295, "Seeds", new String[] {"seeds", "seed"}),
WHEAT(296, "Wheat", "wheat"),
BREAD(297, "Bread", "bread"),
LEATHER_HELMET(298, "Leather helmet", "leatherhelmet"),
LEATHER_CHEST(299, "Leather chestplate", "leatherchest"),
LEATHER_PANTS(300, "Leather pants", "leatherpants"),
LEATHER_BOOTS(301, "Leather boots", "leatherboots"),
CHAINMAIL_HELMET(302, "Chainmail helmet", "chainmailhelmet"),
CHAINMAIL_CHEST(303, "Chainmail chestplate", "chainmailchest"),
CHAINMAIL_PANTS(304, "Chainmail pants", "chainmailpants"),
CHAINMAIL_BOOTS(305, "Chainmail boots", "chainmailboots"),
IRON_HELMET(306, "Iron helmet", "ironhelmet"),
IRON_CHEST(307, "Iron chestplate", "ironchest"),
IRON_PANTS(308, "Iron pants", "ironpants"),
IRON_BOOTS(309, "Iron boots", "ironboots"),
DIAMOND_HELMET(310, "Diamond helmet", "diamondhelmet"),
DIAMOND_CHEST(311, "Diamond chestplate", "diamondchest"),
DIAMOND_PANTS(312, "Diamond pants", "diamondpants"),
DIAMOND_BOOTS(313, "Diamond boots", "diamondboots"),
GOLD_HELMET(314, "Gold helmet", "goldhelmet"),
GOLD_CHEST(315, "Gold chestplate", "goldchest"),
GOLD_PANTS(316, "Gold pants", "goldpants"),
GOLD_BOOTS(317, "Gold boots", "goldboots"),
FLINT(318, "Flint", "flint"),
RAW_PORKCHOP(319, "Raw porkchop",
new String[] {"rawpork", "rawporkchop", "rawbacon", "baconstrips", "rawmeat"}),
COOKED_PORKCHOP(320, "Cooked porkchop",
new String[] {"pork", "cookedpork", "cookedporkchop", "cookedbacon", "bacon", "meat"}),
PAINTING(321, "Painting", "painting"),
GOLD_APPLE(322, "Golden apple", new String[] {"goldapple", "goldenapple"}),
SIGN(323, "Wooden sign", "sign"),
WOODEN_DOOR_ITEM(324, "Wooden door", new String[] {"wooddoor", "door"}),
BUCKET(325, "Bucket", new String[] {"bucket", "bukkit"}),
WATER_BUCKET(326, "Water bucket", new String[] {"waterbucket", "waterbukkit"}),
LAVA_BUCKET(327, "Lava bucket", new String[] {"lavabucket", "lavabukkit"}),
MINECART(328, "Minecart", new String[] {"minecart", "cart"}),
SADDLE(329, "Saddle", "saddle"),
IRON_DOOR_ITEM(330, "Iron door", "irondoor"),
REDSTONE_DUST(331, "Redstone dust", new String[] {"redstonedust", "reddust"}),
SNOWBALL(332, "Snowball", "snowball"),
WOOD_BOAT(333, "Wooden boat", new String[] {"woodboat", "woodenboat", "boat"}),
LEATHER(334, "Leather", new String[] {"leather", "cowhide"}),
MILK_BUCKET(335, "Milk bucket", new String[] {"milkbucket", "milk", "milkbukkit"}),
BRICK_BAR(336, "Brick", "brick"),
CLAY_BALL(337, "Clay", "clay"),
SUGAR_CANE_ITEM(338, "Sugar cane", new String[] {"sugarcane", "reed", "reeds"}),
PAPER(339, "Paper", "paper"),
BOOK(340, "Book", "book"),
SLIME_BALL(341, "Slime ball", new String[] {"slimeball", "slime"}),
STORAGE_MINECART(342, "Storage minecart", new String[] {"storageminecart", "storagecart"}),
POWERED_MINECART(343, "Powered minecart", new String[] {"poweredminecart", "poweredcart"}),
EGG(344, "Egg", "egg"),
COMPASS(345, "Compass", "compass"),
FISHING_ROD(346, "Fishing rod", new String[] {"fishingrod", "fishingpole"}),
WATCH(347, "Watch", new String[] {"watch", "clock", "timer" }),
LIGHTSTONE_DUST(348, "Glowstone dust", new String[] {
"lightstonedust", "glowstonedone", "brightstonedust",
"brittlegolddust", "brimstonedust"}),
RAW_FISH(349, "Raw fish", new String[] {"rawfish", "fish"}),
COOKED_FISH(350, "Cooked fish", "cookedfish"),
INK_SACK(351, "Ink sac", new String[] {"inksac", "ink", "dye", "inksack"}),
BONE(352, "Bone", "bone"),
SUGAR(353, "Sugar", "sugar"),
CAKE_ITEM(354, "Cake", "cake"),
BED_ITEM(355, "Bed", "bed"),
REDSTONE_REPEATER(356, "Redstone repeater", new String[] {"redstonerepeater", "diode", "delayer"}),
COOKIE(357, "Cookie", "cookie"),
GOLD_RECORD(2256, "Gold Record", new String[] {"goldrecord", "golddisc"}),
GREEN_RECORD(2257, "Green Record", new String[] {"greenrecord", "greenddisc"});
/**
* Stores a map of the IDs for fast access.
*/
private static final Map<Integer,ItemType> ids = new HashMap<Integer,ItemType>();
/**
* Stores a map of the names for fast access.
*/
private static final Map<String,ItemType> lookup = new HashMap<String,ItemType>();
private final int id;
private final String name;
private final String[] lookupKeys;
static {
for (ItemType type : EnumSet.allOf(ItemType.class)) {
ids.put(type.id, type);
for (String key : type.lookupKeys) {
lookup.put(key, type);
}
}
}
/**
* Construct the type.
*
* @param id
* @param name
*/
ItemType(int id, String name, String lookupKey) {
this.id = id;
this.name = name;
this.lookupKeys = new String[] {lookupKey};
}
/**
* Construct the type.
*
* @param id
* @param name
*/
ItemType(int id, String name, String[] lookupKeys) {
this.id = id;
this.name = name;
this.lookupKeys = lookupKeys;
}
/**
* Return type from ID. May return null.
*
* @param id
* @return
*/
public static ItemType fromID(int id) {
return ids.get(id);
}
/**
* Get a name for the item.
*
* @param id
* @return
*/
public static String toName(int id) {
ItemType type = ids.get(id);
if (type != null) {
return type.getName();
} else {
return "#" + id;
}
}
/**
* Get a name for a held item.
*
* @param id
* @return
*/
public static String toHeldName(int id) {
if (id == 0) {
return "Hand";
}
ItemType type = ids.get(id);
if (type != null) {
return type.getName();
} else {
return "#" + id;
}
}
/**
* Return type from name. May return null.
*
* @param name
* @return
*/
public static ItemType lookup(String name) {
return lookup.get(name.toLowerCase());
}
/**
* Get item numeric ID.
*
* @return
*/
public int getID() {
return id;
}
/**
* Get user-friendly item name.
*
* @return
*/
public String getName() {
return name;
}
/**
* Get a list of aliases.
*
* @return
*/
public String[] getAliases() {
return lookupKeys;
}
/**
* Returns true if an item should not be stacked.
*
* @param id
* @return
*/
public static boolean shouldNotStack(int id) {
return (id >= 256 && id <= 259)
|| id == 261
|| (id >= 267 && id <= 279)
|| (id >= 281 && id <= 286)
|| (id >= 290 && id <= 294)
|| (id >= 298 && id <= 317)
|| (id >= 325 && id <= 327)
|| id == 335
|| id == 354
|| id == 355
|| id >= 2256;
}
/**
* Returns true if an item uses its damage value for something
* other than damage.
*
* @param id
* @return
*/
public static boolean usesDamageValue(int id) {
return id == 35
|| id == 351;
}
}

View File

@ -0,0 +1,159 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.data.*;
import java.util.Map;
import java.util.HashMap;
/**
* Represents chests.
*
* @author sk89q
*/
public class MobSpawnerBlock extends BaseBlock implements TileEntityBlock {
/**
* Store mob spawn type.
*/
private String mobType;
/**
* Delay until next spawn.
*/
private short delay;
/**
* Construct the mob spawner block.
*
*/
public MobSpawnerBlock() {
super(52);
this.mobType = "Pig";
}
/**
* Construct the mob spawner block.
*
* @param mobType
*/
public MobSpawnerBlock(String mobType) {
super(52);
this.mobType = mobType;
}
/**
* Construct the mob spawner block.
*
* @param data
*/
public MobSpawnerBlock(int data) {
super(52, data);
}
/**
* Construct the mob spawner block.
*
* @param data
* @param mobType
*/
public MobSpawnerBlock(int data, String mobType) {
super(52, data);
this.mobType = mobType;
}
/**
* Get the mob type.
*
* @return
*/
public String getMobType() {
return mobType;
}
/**
* Set the mob type.
*
* @param mobType
*/
public void setMobType(String mobType) {
this.mobType = mobType;
}
/**
* @return the delay
*/
public short getDelay() {
return delay;
}
/**
* @param delay the delay to set
*/
public void setDelay(short delay) {
this.delay = delay;
}
/**
* Get the tile entity ID.
*
* @return
*/
public String getTileEntityID() {
return "MobSpawner";
}
/**
* Store additional tile entity data. Returns true if the data is used.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException {
Map<String,Tag> values = new HashMap<String,Tag>();
values.put("EntityId", new StringTag("EntityId", mobType));
values.put("Delay", new ShortTag("Delay", delay));
return values;
}
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException {
if (values == null) {
return;
}
Tag t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("MobSpawner")) {
throw new DataException("'MobSpawner' tile entity expected");
}
StringTag mobTypeTag = (StringTag)Chunk.getChildTag(values, "EntityId", StringTag.class);
ShortTag delayTag = (ShortTag)Chunk.getChildTag(values, "Delay", ShortTag.class);
this.mobType = mobTypeTag.getValue();
this.delay = delayTag.getValue();
}
}

View File

@ -0,0 +1,126 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.data.*;
import java.util.Map;
import java.util.HashMap;
/**
*
* @author sk89q
*/
public class NoteBlock extends BaseBlock implements TileEntityBlock {
/**
* Stores the pitch.
*/
private byte note;
/**
* Construct the note block.
*/
public NoteBlock() {
super(25);
this.note = 0;
}
/**
* Construct the note block.
*
* @param data
*/
public NoteBlock(int data) {
super(25, data);
this.note = 0;
}
/**
* Construct the note block.
*
* @param data
* @param note
*/
public NoteBlock(int data, byte note) {
super(25, data);
this.note = note;
}
/**
* @return the note
*/
public byte getNote() {
return note;
}
/**
* @param note the note to set
*/
public void setNote(byte note) {
this.note = note;
}
/**
* Return the name of the title entity ID.
*
* @return title entity ID
*/
public String getTileEntityID() {
return "Music";
}
/**
* Store additional tile entity data. Returns true if the data is used.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException {
Map<String,Tag> values = new HashMap<String,Tag>();
values.put("note", new ByteTag("note", note));
return values;
}
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException {
if (values == null) {
return;
}
Tag t;
t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("Music")) {
throw new DataException("'Music' tile entity expected");
}
t = values.get("note");
if (t instanceof ByteTag) {
note = ((ByteTag)t).getValue();
}
}
}

View File

@ -0,0 +1,140 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.data.*;
import java.util.Map;
import java.util.HashMap;
/**
*
* @author sk89q
*/
public class SignBlock extends BaseBlock implements TileEntityBlock {
/**
* Stores the sign's text.
*/
private String[] text;
/**
* Construct the sign without text.
*
* @param type
* @param data
*/
public SignBlock(int type, int data) {
super(type, data);
this.text = new String[]{ "", "", "", "" };
}
/**
* Construct the sign with text.
*
* @param type
* @param data
* @param text
*/
public SignBlock(int type, int data, String[] text) {
super(type, data);
this.text = text;
}
/**
* @return the text
*/
public String[] getText() {
return text;
}
/**
* @param text the text to set
*/
public void setText(String[] text) {
this.text = text;
}
/**
* Return the name of the title entity ID.
*
* @return title entity ID
*/
public String getTileEntityID() {
return "Sign";
}
/**
* Store additional tile entity data. Returns true if the data is used.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException {
Map<String,Tag> values = new HashMap<String,Tag>();
values.put("Text1", new StringTag("Text1", text[0]));
values.put("Text2", new StringTag("Text2", text[1]));
values.put("Text3", new StringTag("Text3", text[2]));
values.put("Text4", new StringTag("Text4", text[3]));
return values;
}
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException {
if (values == null) {
return;
}
Tag t;
text = new String[]{ "", "", "", "" };
t = values.get("id");
if (!(t instanceof StringTag) || !((StringTag)t).getValue().equals("Sign")) {
throw new DataException("'Sign' tile entity expected");
}
t = values.get("Text1");
if (t instanceof StringTag) {
text[0] = ((StringTag)t).getValue();
}
t = values.get("Text2");
if (t instanceof StringTag) {
text[1] = ((StringTag)t).getValue();
}
t = values.get("Text3");
if (t instanceof StringTag) {
text[2] = ((StringTag)t).getValue();
}
t = values.get("Text4");
if (t instanceof StringTag) {
text[3] = ((StringTag)t).getValue();
}
}
}

View File

@ -0,0 +1,54 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.blocks;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.data.*;
import java.util.Map;
/**
* A class implementing this interface has extra TileEntityBlock data to store.
*
* @author sk89q
*/
public interface TileEntityBlock {
/**
* Return the name of the title entity ID.
*
* @return title entity ID
*/
public String getTileEntityID();
/**
* Store additional tile entity data.
*
* @return map of values
* @throws DataException
*/
public Map<String,Tag> toTileEntityNBT()
throws DataException;
/**
* Get additional information from the title entity data.
*
* @param values
* @throws DataException
*/
public void fromTileEntityNBT(Map<String,Tag> values)
throws DataException;
}

View File

@ -0,0 +1,112 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import java.io.IOException;
import java.util.HashSet;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.util.config.Configuration;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LogFormat;
import com.sk89q.worldedit.snapshots.SnapshotRepository;
public class BukkitConfiguration extends LocalConfiguration {
private Configuration config;
private Logger logger;
public boolean noOpPermissions = false;
public BukkitConfiguration(Configuration config, Logger logger) {
this.config = config;
this.logger = logger;
}
@Override
public void load() {
showFirstUseVersion = false;
profile = config.getBoolean("debug", profile);
wandItem = config.getInt("wand-item", wandItem);
defaultChangeLimit = Math.max(-1, config.getInt(
"limits.max-blocks-changed.default", defaultChangeLimit));
maxChangeLimit = Math.max(-1,
config.getInt("limits.max-blocks-changed.maximum", maxChangeLimit));
maxRadius = Math.max(-1, config.getInt("limits.max-radius", maxRadius));
maxSuperPickaxeSize = Math.max(1, config.getInt(
"limits.max-super-pickaxe-size", maxSuperPickaxeSize));
registerHelp = true;
logCommands = config.getBoolean("logging.log-commands", logCommands);
superPickaxeDrop = config.getBoolean("super-pickaxe.drop-items",
superPickaxeDrop);
superPickaxeManyDrop = config.getBoolean(
"super-pickaxe.many-drop-items", superPickaxeManyDrop);
noDoubleSlash = config.getBoolean("no-double-slash", noDoubleSlash);
useInventory = config.getBoolean("use-inventory.enable", useInventory);
useInventoryOverride = config.getBoolean("use-inventory.allow-override",
useInventoryOverride);
maxBrushRadius = config.getInt("limits.max-brush-radius", maxBrushRadius);
navigationWand = config.getInt("navigation-wand.item", navigationWand);
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
scriptTimeout = config.getInt("scripting.timeout", scriptTimeout);
scriptsDir = config.getString("scripting.dir", scriptsDir);
saveDir = config.getString("saving.dir", saveDir);
disallowedBlocks = new HashSet<Integer>(config.getIntList("limits.disallowed-blocks", null));
allowedDataCycleBlocks = new HashSet<Integer>(config.getIntList("limits.allowed-data-cycle-blocks", null));
noOpPermissions = config.getBoolean("no-op-permissions", false);
LocalSession.MAX_HISTORY_SIZE = Math.max(15, config.getInt("history.size", 15));
String snapshotsDir = config.getString("snapshots.directory", "");
if (!snapshotsDir.trim().equals("")) {
snapshotRepo = new SnapshotRepository(snapshotsDir);
} else {
snapshotRepo = null;
}
String type = config.getString("shell-save-type", "").trim();
shellSaveType = type.equals("") ? null : type;
String logFile = config.getString("logging.file", "");
if (!logFile.equals("")) {
try {
FileHandler handler = new FileHandler(logFile, true);
handler.setFormatter(new LogFormat());
logger.addHandler(handler);
} catch (IOException e) {
logger.log(Level.WARNING, "Could not use log file " + logFile + ": "
+ e.getMessage());
}
} else {
for (Handler handler : logger.getHandlers()) {
logger.removeHandler(handler);
}
}
}
}

View File

@ -0,0 +1,136 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.cui.CUIEvent;
public class BukkitPlayer extends LocalPlayer {
private Player player;
private WorldEditPlugin plugin;
public BukkitPlayer(WorldEditPlugin plugin, ServerInterface server, Player player) {
super(server);
this.plugin = plugin;
this.player = player;
}
@Override
public int getItemInHand() {
ItemStack itemStack = player.getItemInHand();
return itemStack != null ? itemStack.getTypeId() : 0;
}
@Override
public String getName() {
return player.getName();
}
@Override
public WorldVector getPosition() {
Location loc = player.getLocation();
return new WorldVector(new BukkitWorld(loc.getWorld()),
loc.getX(), loc.getY(), loc.getZ());
}
@Override
public double getPitch() {
return player.getLocation().getPitch();
}
@Override
public double getYaw() {
return player.getLocation().getYaw();
}
@Override
public void giveItem(int type, int amt) {
player.getInventory().addItem(new ItemStack(type, amt));
}
@Override
public void printRaw(String msg) {
player.sendMessage(msg);
}
@Override
public void print(String msg) {
player.sendMessage("\u00A7d" + msg);
}
@Override
public void printDebug(String msg) {
player.sendMessage("\u00A77" + msg);
}
@Override
public void printError(String msg) {
player.sendMessage("\u00A7c" + msg);
}
@Override
public void setPosition(Vector pos, float pitch, float yaw) {
player.teleport(new Location(player.getWorld(), pos.getX(), pos.getY(),
pos.getZ(), yaw, pitch));
}
@Override
public String[] getGroups() {
return plugin.getPermissionsResolver().getGroups(player.getName());
}
@Override
public BlockBag getInventoryBlockBag() {
return new BukkitPlayerBlockBag(player);
}
@Override
public boolean hasPermission(String perm) {
return (!plugin.getLocalConfiguration().noOpPermissions && player.isOp())
|| plugin.getPermissionsResolver().hasPermission(player.getName(), perm);
}
@Override
public LocalWorld getWorld() {
return new BukkitWorld(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");
}
}

View File

@ -0,0 +1,193 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bags.*;
public class BukkitPlayerBlockBag extends BlockBag {
/**
* Player instance.
*/
private Player player;
/**
* The player's inventory;
*/
private ItemStack[] items;
/**
* Construct the object.
*
* @param player
*/
public BukkitPlayerBlockBag(Player player) {
this.player = player;
}
/**
* Loads inventory on first use.
*/
private void loadInventory() {
if (items == null) {
items = player.getInventory().getContents();
}
}
/**
* Get the player.
*
* @return
*/
public Player getPlayer() {
return player;
}
/**
* Get a block.
*
* @param id
*/
@Override
public void fetchBlock(int id) throws BlockBagException {
if (id == 0) {
throw new IllegalArgumentException("Can't fetch air block");
}
loadInventory();
boolean found = false;
for (int slot = 0; slot < items.length; slot++) {
ItemStack item = items[slot];
if (item == null) continue;
if (item.getTypeId() == id) {
int amount = item.getAmount();
// Unlimited
if (amount < 0) {
return;
}
if (amount > 1) {
item.setAmount(amount - 1);
found = true;
} else {
items[slot] = null;
found = true;
}
break;
}
}
if (found) {
} else {
throw new OutOfBlocksException();
}
}
/**
* Store a block.
*
* @param id
*/
@Override
public void storeBlock(int id) throws BlockBagException {
if (id == 0) {
throw new IllegalArgumentException("Can't store air block");
}
loadInventory();
boolean found = false;
int freeSlot = -1;
for (int slot = 0; slot < items.length; slot++) {
ItemStack item = items[slot];
// Delay using up a free slot until we know there are no stacks
// of this item to merge into
if (item == null) {
if (freeSlot == -1) {
freeSlot = slot;
}
continue;
}
if (item.getTypeId() == id) {
int amount = item.getAmount();
// Unlimited
if (amount < 0) {
return;
}
if (amount < 64) {
item.setAmount(amount + 1);
found = true;
break;
}
}
}
if (!found && freeSlot > -1) {
items[freeSlot] = new ItemStack(id, 1);
found = true;
}
if (found) {
} else {
throw new OutOfSpaceException(id);
}
}
/**
* Flush any changes. This is called at the end.
*/
@Override
public void flushChanges() {
if (items != null) {
player.getInventory().setContents(items);
items = null;
}
}
/**
* Adds a position to be used a source.
*
* @param pos
*/
@Override
public void addSourcePosition(Vector pos) {
}
/**
* Adds a position to be used a source.
*
* @param pos
*/
@Override
public void addSingleSourcePosition(Vector pos) {
}
}

View File

@ -0,0 +1,51 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import org.bukkit.*;
import org.bukkit.entity.CreatureType;
import com.sk89q.worldedit.ServerInterface;
public class BukkitServerInterface extends ServerInterface {
public Server server;
public WorldEditPlugin plugin;
public BukkitServerInterface(WorldEditPlugin plugin, Server server) {
this.plugin = plugin;
this.server = server;
}
@Override
public int resolveItem(String name) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isValidMobType(String type) {
return CreatureType.fromName(type) != null;
}
@Override
public void reload() {
plugin.loadConfiguration();
}
}

View File

@ -0,0 +1,58 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import java.util.List;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
public class BukkitUtil {
private BukkitUtil() {
}
public static Location toLocation(World world, Vector loc) {
return new Location(world, loc.getX(), loc.getY(), loc.getZ());
}
public static BlockVector toVector(Block block) {
return new BlockVector(block.getX(), block.getY(), block.getZ());
}
public static Vector toVector(Location loc) {
return new Vector(loc.getX(), loc.getY(), loc.getZ());
}
public static Vector toVector(org.bukkit.util.Vector vector) {
return new Vector(vector.getX(), vector.getY(), vector.getZ());
}
public static Player matchSinglePlayer(Server server, String name) {
List<Player> players = server.matchPlayer(name);
if (players.size() == 0) {
return null;
}
return players.get(0);
}
}

View File

@ -0,0 +1,613 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Furnace;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.Sign;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Slime;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.World;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.regions.Region;
public class BukkitWorld extends LocalWorld {
private World world;
/**
* Construct the object.
* @param world
*/
public BukkitWorld(World world) {
this.world = world;
}
/**
* Get the world handle.
*
* @return
*/
public World getWorld() {
return world;
}
/**
* Set block type.
*
* @param pt
* @param type
* @return
*/
@Override
public boolean setBlockType(Vector pt, int type) {
return world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).setTypeId(type);
}
/**
* Get block type.
*
* @param pt
* @return
*/
@Override
public int getBlockType(Vector pt) {
return world.getBlockTypeIdAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
}
/**
* Set block data.
*
* @param pt
* @param data
*/
@Override
public void setBlockData(Vector pt, int data) {
world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).setData((byte)data);
}
/**
* Get block data.
*
* @param pt
* @return
*/
@Override
public int getBlockData(Vector pt) {
return world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getData();
}
/**
* Get block light level.
*
* @param pt
* @return
*/
@Override
public int getBlockLightLevel(Vector pt) {
return world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel();
}
/**
* Regenerate an area.
*
* @param region
* @param editSession
* @return
*/
@Override
public boolean regenerate(Region region, EditSession editSession) {
BaseBlock[] history = new BaseBlock[16 * 16 * 128];
for (Vector2D chunk : region.getChunks()) {
Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16);
// First save all the blocks inside
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 128; y++) {
for (int z = 0; z < 16; z++) {
Vector pt = min.add(x, y, z);
int index = y * 16 * 16 + z * 16 + x;
history[index] = editSession.getBlock(pt);
}
}
}
try {
world.regenerateChunk(chunk.getBlockX(), chunk.getBlockZ());
} catch (Throwable t) {
t.printStackTrace();
}
// Then restore
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 128; y++) {
for (int z = 0; z < 16; z++) {
Vector pt = min.add(x, y, z);
int index = y * 16 * 16 + z * 16 + x;
// We have to restore the block if it was outside
if (!region.contains(pt)) {
editSession.smartSetBlock(pt, history[index]);
} else { // Otherwise fool with history
editSession.rememberChange(pt, history[index],
editSession.rawGetBlock(pt));
}
}
}
}
}
return true;
}
/**
* Attempts to accurately copy a BaseBlock's extra data to the world.
*
* @param pt
* @param block
* @return
*/
@Override
public boolean copyToWorld(Vector pt, BaseBlock block) {
// Signs
if (block instanceof SignBlock) {
setSignText(pt, ((SignBlock)block).getText());
return true;
// Furnaces
} else if (block instanceof FurnaceBlock) {
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof Furnace)) return false;
Furnace bukkit = (Furnace)state;
FurnaceBlock we = (FurnaceBlock)block;
bukkit.setBurnTime(we.getBurnTime());
bukkit.setCookTime(we.getCookTime());
return setContainerBlockContents(pt, ((ContainerBlock)block).getItems());
// Chests/dispenser
} else if (block instanceof ContainerBlock) {
return setContainerBlockContents(pt, ((ContainerBlock)block).getItems());
// Mob spawners
} else if (block instanceof MobSpawnerBlock) {
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof CreatureSpawner)) return false;
CreatureSpawner bukkit = (CreatureSpawner)state;
MobSpawnerBlock we = (MobSpawnerBlock)block;
bukkit.setCreatureTypeId(we.getMobType());
bukkit.setDelay(we.getDelay());
return true;
// Note block
} else if (block instanceof NoteBlock) {
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof org.bukkit.block.NoteBlock)) return false;
org.bukkit.block.NoteBlock bukkit = (org.bukkit.block.NoteBlock)state;
NoteBlock we = (NoteBlock)block;
bukkit.setNote(we.getNote());
return true;
}
return false;
}
/**
* Attempts to read a BaseBlock's extra data from the world.
*
* @param pt
* @param block
* @return
*/
@Override
public boolean copyFromWorld(Vector pt, BaseBlock block) {
// Signs
if (block instanceof SignBlock) {
((SignBlock)block).setText(getSignText(pt));
return true;
// Furnaces
} else if (block instanceof FurnaceBlock) {
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof Furnace)) return false;
Furnace bukkit = (Furnace)state;
FurnaceBlock we = (FurnaceBlock)block;
we.setBurnTime(bukkit.getBurnTime());
we.setCookTime(bukkit.getCookTime());
((ContainerBlock)block).setItems(getContainerBlockContents(pt));
return true;
// Chests/dispenser
} else if (block instanceof ContainerBlock) {
((ContainerBlock)block).setItems(getContainerBlockContents(pt));
return true;
// Mob spawners
} else if (block instanceof MobSpawnerBlock) {
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof CreatureSpawner)) return false;
CreatureSpawner bukkit = (CreatureSpawner)state;
MobSpawnerBlock we = (MobSpawnerBlock)block;
we.setMobType(bukkit.getCreatureTypeId());
we.setDelay((short)bukkit.getDelay());
return true;
// Note block
} else if (block instanceof NoteBlock) {
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof org.bukkit.block.NoteBlock)) return false;
org.bukkit.block.NoteBlock bukkit = (org.bukkit.block.NoteBlock)state;
NoteBlock we = (NoteBlock)block;
we.setNote(bukkit.getNote());
}
return false;
}
/**
* Clear a chest's contents.
*
* @param pt
*/
@Override
public boolean clearContainerBlockContents(Vector pt) {
Block block = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (block == null) {
return false;
}
BlockState state = block.getState();
if (!(state instanceof org.bukkit.block.ContainerBlock)) {
return false;
}
org.bukkit.block.ContainerBlock chest = (org.bukkit.block.ContainerBlock)state;
Inventory inven = chest.getInventory();
inven.clear();
return true;
}
/**
* Generate a tree at a location.
*
* @param pt
* @return
*/
@Override
public boolean generateTree(EditSession editSession, Vector pt) {
return world.generateTree(BukkitUtil.toLocation(world, pt), TreeType.TREE,
new EditSessionBlockChangeDelegate(editSession));
}
/**
* Generate a big tree at a location.
*
* @param pt
* @return
*/
@Override
public boolean generateBigTree(EditSession editSession, Vector pt) {
return world.generateTree(BukkitUtil.toLocation(world, pt), TreeType.BIG_TREE,
new EditSessionBlockChangeDelegate(editSession));
}
/**
* Generate a birch tree at a location.
*
* @param pt
* @return
*/
@Override
public boolean generateBirchTree(EditSession editSession, Vector pt) {
return world.generateTree(BukkitUtil.toLocation(world, pt), TreeType.BIRCH,
new EditSessionBlockChangeDelegate(editSession));
}
/**
* Generate a redwood tree at a location.
*
* @param pt
* @return
*/
@Override
public boolean generateRedwoodTree(EditSession editSession, Vector pt) {
return world.generateTree(BukkitUtil.toLocation(world, pt), TreeType.REDWOOD,
new EditSessionBlockChangeDelegate(editSession));
}
/**
* Generate a redwood tree at a location.
*
* @param pt
* @return
*/
@Override
public boolean generateTallRedwoodTree(EditSession editSession, Vector pt) {
return world.generateTree(BukkitUtil.toLocation(world, pt), TreeType.TALL_REDWOOD,
new EditSessionBlockChangeDelegate(editSession));
}
/**
* Drop an item.
*
* @param pt
* @param item
*/
@Override
public void dropItem(Vector pt, BaseItemStack item) {
ItemStack bukkitItem = new ItemStack(item.getType(), item.getAmount(),
(byte)item.getDamage());
world.dropItemNaturally(toLocation(pt), bukkitItem);
}
/**
* Kill mobs in an area.
*
* @param origin
* @param radius -1 for all mobs
* @return
*/
@Override
public int killMobs(Vector origin, int radius) {
int num = 0;
double radiusSq = Math.pow(radius, 2);
for (LivingEntity ent : world.getLivingEntities()) {
if (ent instanceof Creature || ent instanceof Ghast || ent instanceof Slime) {
if (radius == -1
|| origin.distanceSq(BukkitUtil.toVector(ent.getLocation())) <= radiusSq) {
ent.remove();
num++;
}
}
}
return num;
}
/**
* Remove entities in an area.
*
* @param origin
* @param radius
* @return
*/
@Override
public int removeEntities(EntityType type, Vector origin, int radius) {
int num = 0;
double radiusSq = Math.pow(radius, 2);
for (Entity ent : world.getEntities()) {
if (radius != -1
&& origin.distanceSq(BukkitUtil.toVector(ent.getLocation())) > radiusSq) {
continue;
}
switch (type) {
case ARROWS:
if (ent instanceof Arrow) {
ent.remove();
num++;
}
break;
case BOATS:
if (ent instanceof Boat) {
ent.remove();
num++;
}
break;
case ITEMS:
if (ent instanceof Item) {
ent.remove();
num++;
}
break;
case MINECARTS:
if (ent instanceof Minecart) {
ent.remove();
num++;
}
break;
case PAINTINGS:
if (ent instanceof Painting) {
ent.remove();
num++;
}
break;
case TNT:
if (ent instanceof TNTPrimed) {
ent.remove();
num++;
}
break;
default:
continue;
}
}
return num;
}
private Location toLocation(Vector pt) {
return new Location(world, pt.getX(), pt.getY(), pt.getZ());
}
/**
* Set a sign's text.
*
* @param pt
* @param text
* @return
*/
private boolean setSignText(Vector pt, String[] text) {
Block block = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (block == null) return false;
BlockState state = block.getState();
if (state == null || !(state instanceof Sign)) return false;
Sign sign = (Sign)state;
sign.setLine(0, text[0]);
sign.setLine(1, text[1]);
sign.setLine(2, text[2]);
sign.setLine(3, text[3]);
sign.update();
return true;
}
/**
* Get a sign's text.
*
* @param pt
* @return
*/
private String[] getSignText(Vector pt) {
Block block = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (block == null) return new String[] { "", "", "", "" };
BlockState state = block.getState();
if (state == null || !(state instanceof Sign)) return new String[] { "", "", "", "" };
Sign sign = (Sign)state;
String line0 = sign.getLine(0);
String line1 = sign.getLine(1);
String line2 = sign.getLine(2);
String line3 = sign.getLine(3);
return new String[] {
line0 != null ? line0 : "",
line1 != null ? line1 : "",
line2 != null ? line2 : "",
line3 != null ? line3 : "",
};
}
/**
* Get a container block's contents.
*
* @param pt
* @return
*/
private BaseItemStack[] getContainerBlockContents(Vector pt) {
Block block = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (block == null) {
return new BaseItemStack[0];
}
BlockState state = block.getState();
if (!(state instanceof org.bukkit.block.ContainerBlock)) {
return new BaseItemStack[0];
}
org.bukkit.block.ContainerBlock container = (org.bukkit.block.ContainerBlock)state;
Inventory inven = container.getInventory();
int size = inven.getSize();
BaseItemStack[] contents = new BaseItemStack[size];
for (int i = 0; i < size; i++) {
ItemStack bukkitStack = inven.getItem(i);
if (bukkitStack.getTypeId() > 0) {
contents[i] = new BaseItemStack(
bukkitStack.getTypeId(),
bukkitStack.getAmount(),
bukkitStack.getDurability());
}
}
return contents;
}
/**
* Set a container block's contents.
*
* @param pt
* @param contents
* @return
*/
private boolean setContainerBlockContents(Vector pt, BaseItemStack[] contents) {
Block block = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (block == null) {
return false;
}
BlockState state = block.getState();
if (!(state instanceof org.bukkit.block.ContainerBlock)) {
return false;
}
org.bukkit.block.ContainerBlock chest = (org.bukkit.block.ContainerBlock)state;
Inventory inven = chest.getInventory();
int size = inven.getSize();
for (int i = 0; i < size; i++) {
if (i >= contents.length) {
break;
}
if (contents[i] != null) {
inven.setItem(i, new ItemStack(contents[i].getType(),
contents[i].getAmount(),
(byte)contents[i].getDamage()));
} else {
inven.setItem(i, null);
}
}
return true;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof BukkitWorld)) {
return false;
}
return ((BukkitWorld)other).world.equals(world);
}
@Override
public int hashCode() {
return world.hashCode();
}
}

View File

@ -0,0 +1,59 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import org.bukkit.BlockChangeDelegate;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
* Proxy class to catch calls to set blocks.
*
* @author sk89q
*/
public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
private EditSession editSession;
public EditSessionBlockChangeDelegate(EditSession editSession) {
this.editSession = editSession;
}
public boolean setRawTypeId(int x, int y, int z, int typeId) {
try {
return editSession.setBlock(new Vector(x, y, z), new BaseBlock(typeId));
} catch (MaxChangedBlocksException ex) {
return false;
}
}
public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data) {
try {
return editSession.setBlock(new Vector(x, y, z), new BaseBlock(typeId, data));
} catch (MaxChangedBlocksException ex) {
return false;
}
}
public int getTypeId(int x, int y, int z) {
return editSession.getBlockType(new Vector(x, y, z));
}
}

View File

@ -0,0 +1,42 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 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.bukkit;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.LocalSession;
public class WorldEditAPI {
private WorldEditPlugin plugin;
public WorldEditAPI(WorldEditPlugin plugin) {
this.plugin = plugin;
}
/**
* Get the session for a player.
*
* @param player
* @return
*/
public LocalSession getSession(Player player) {
return plugin.getWorldEdit().getSession(
new BukkitPlayer(plugin, plugin.getServerInterface(), player));
}
}

Some files were not shown because too many files have changed in this diff Show More