Initial commit (Forge 1291).
This commit is contained in:
BIN
src/main/guava10.zip
Normal file
BIN
src/main/guava10.zip
Normal file
Binary file not shown.
91
src/main/java/jline/AnsiWindowsTerminal.java
Normal file
91
src/main/java/jline/AnsiWindowsTerminal.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2009 the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* MODIFICATIONS: methods to deal with wrapping the output stream.
|
||||
*/
|
||||
|
||||
package jline;
|
||||
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
import org.fusesource.jansi.AnsiOutputStream;
|
||||
import org.fusesource.jansi.WindowsAnsiOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* ANSI-supported {@link WindowsTerminal}.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AnsiWindowsTerminal
|
||||
extends WindowsTerminal
|
||||
{
|
||||
private final boolean ansiSupported = detectAnsiSupport();
|
||||
|
||||
@Override
|
||||
public OutputStream wrapOutIfNeeded(OutputStream out) {
|
||||
return wrapOutputStream(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ansi output stream handler. We return whatever was
|
||||
* passed if we determine we cannot handle ansi based on Kernel32 calls.
|
||||
*
|
||||
* @return an @{link AltWindowAnsiOutputStream} instance or the passed
|
||||
* stream.
|
||||
*/
|
||||
private static OutputStream wrapOutputStream(final OutputStream stream) {
|
||||
String os = System.getProperty("os.name");
|
||||
if( os.startsWith("Windows") ) {
|
||||
// On windows we know the console does not interpret ANSI codes..
|
||||
try {
|
||||
return new WindowsAnsiOutputStream(stream);
|
||||
} catch (Throwable ignore) {
|
||||
// this happens when JNA is not in the path.. or
|
||||
// this happens when the stdout is being redirected to a file.
|
||||
}
|
||||
// Use the ANSIOutputStream to strip out the ANSI escape sequences.
|
||||
return new AnsiOutputStream(stream);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
private static boolean detectAnsiSupport() {
|
||||
AnsiConsole.systemInstall(); // CraftBukkit - install Windows JNI library
|
||||
OutputStream out = AnsiConsole.wrapOutputStream(new ByteArrayOutputStream());
|
||||
try {
|
||||
out.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// ignore;
|
||||
}
|
||||
return out instanceof WindowsAnsiOutputStream;
|
||||
}
|
||||
|
||||
public AnsiWindowsTerminal() throws Exception {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnsiSupported() {
|
||||
return ansiSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWeirdWrap() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
227
src/main/java/jline/internal/TerminalLineSettings.java
Normal file
227
src/main/java/jline/internal/TerminalLineSettings.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*/
|
||||
|
||||
package jline.internal;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Provides access to terminal line settings via <tt>stty</tt>.
|
||||
*
|
||||
* @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
|
||||
* @author <a href="mailto:dwkemp@gmail.com">Dale Kemp</a>
|
||||
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
|
||||
* @author <a href="mailto:jbonofre@apache.org">Jean-Baptiste Onofré</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class TerminalLineSettings
|
||||
{
|
||||
public static final String JLINE_STTY = "jline.stty";
|
||||
|
||||
public static final String DEFAULT_STTY = "stty";
|
||||
|
||||
public static final String JLINE_SH = "jline.sh";
|
||||
|
||||
public static final String DEFAULT_SH = "sh";
|
||||
|
||||
private String sttyCommand;
|
||||
|
||||
private String shCommand;
|
||||
|
||||
private String config;
|
||||
|
||||
private long configLastFetched;
|
||||
|
||||
public TerminalLineSettings() throws IOException, InterruptedException {
|
||||
sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY);
|
||||
shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH);
|
||||
config = get("-a");
|
||||
configLastFetched = System.currentTimeMillis();
|
||||
|
||||
Log.debug("Config: ", config);
|
||||
|
||||
// sanity check
|
||||
if (config.length() == 0) {
|
||||
throw new IOException(MessageFormat.format("Unrecognized stty code: {0}", config));
|
||||
}
|
||||
}
|
||||
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void restore() throws IOException, InterruptedException {
|
||||
set("sane");
|
||||
}
|
||||
|
||||
public String get(final String args) throws IOException, InterruptedException {
|
||||
return stty(args);
|
||||
}
|
||||
|
||||
public void set(final String args) throws IOException, InterruptedException {
|
||||
stty(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Get the value of a stty property, including the management of a cache.
|
||||
* </p>
|
||||
*
|
||||
* @param name the stty property.
|
||||
* @return the stty property value.
|
||||
*/
|
||||
public int getProperty(String name) {
|
||||
assert name != null;
|
||||
// CraftBukkit start
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
// tty properties are cached so we don't have to worry too much about getting term widht/height
|
||||
if (config == null || currentTime - configLastFetched > 1000) {
|
||||
config = get("-a");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.debug("Failed to query stty ", name, "\n", e);
|
||||
}
|
||||
|
||||
// always update the last fetched time and try to parse the output
|
||||
if (currentTime - configLastFetched > 1000) {
|
||||
configLastFetched = currentTime;
|
||||
}
|
||||
|
||||
return this.getProperty(name, config);
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Parses a stty output (provided by stty -a) and return the value of a given property.
|
||||
* </p>
|
||||
*
|
||||
* @param name property name.
|
||||
* @param stty string resulting of stty -a execution.
|
||||
* @return value of the given property.
|
||||
*/
|
||||
protected static int getProperty(String name, String stty) {
|
||||
// try the first kind of regex
|
||||
Pattern pattern = Pattern.compile(name + "\\s+=\\s+([^;]*)[;\\n\\r]");
|
||||
Matcher matcher = pattern.matcher(stty);
|
||||
if (!matcher.find()) {
|
||||
// try a second kind of regex
|
||||
pattern = Pattern.compile(name + "\\s+([^;]*)[;\\n\\r]");
|
||||
matcher = pattern.matcher(stty);
|
||||
if (!matcher.find()) {
|
||||
// try a second try of regex
|
||||
pattern = Pattern.compile("(\\S*)\\s+" + name);
|
||||
matcher = pattern.matcher(stty);
|
||||
if (!matcher.find()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseControlChar(matcher.group(1));
|
||||
}
|
||||
|
||||
private static int parseControlChar(String str) {
|
||||
// under
|
||||
if ("<undef>".equals(str)) {
|
||||
return -1;
|
||||
}
|
||||
// octal
|
||||
if (str.charAt(0) == '0') {
|
||||
return Integer.parseInt(str, 8);
|
||||
}
|
||||
// decimal
|
||||
if (str.charAt(0) >= '1' && str.charAt(0) <= '9') {
|
||||
return Integer.parseInt(str, 10);
|
||||
}
|
||||
// control char
|
||||
if (str.charAt(0) == '^') {
|
||||
if (str.charAt(1) == '?') {
|
||||
return 127;
|
||||
} else {
|
||||
return str.charAt(1) - 64;
|
||||
}
|
||||
} else if (str.charAt(0) == 'M' && str.charAt(1) == '-') {
|
||||
if (str.charAt(2) == '^') {
|
||||
if (str.charAt(3) == '?') {
|
||||
return 127 + 128;
|
||||
} else {
|
||||
return str.charAt(3) - 64 + 128;
|
||||
}
|
||||
} else {
|
||||
return str.charAt(2) + 128;
|
||||
}
|
||||
} else {
|
||||
return str.charAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
private String stty(final String args) throws IOException, InterruptedException {
|
||||
assert args != null;
|
||||
return exec(String.format("%s %s < /dev/tty", sttyCommand, args));
|
||||
}
|
||||
|
||||
private String exec(final String cmd) throws IOException, InterruptedException {
|
||||
assert cmd != null;
|
||||
return exec(shCommand, "-c", cmd);
|
||||
}
|
||||
|
||||
private String exec(final String... cmd) throws IOException, InterruptedException {
|
||||
assert cmd != null;
|
||||
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
|
||||
Log.trace("Running: ", cmd);
|
||||
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
|
||||
InputStream in = null;
|
||||
InputStream err = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
int c;
|
||||
in = p.getInputStream();
|
||||
while ((c = in.read()) != -1) {
|
||||
bout.write(c);
|
||||
}
|
||||
err = p.getErrorStream();
|
||||
while ((c = err.read()) != -1) {
|
||||
bout.write(c);
|
||||
}
|
||||
out = p.getOutputStream();
|
||||
p.waitFor();
|
||||
}
|
||||
finally {
|
||||
close(in, out, err);
|
||||
}
|
||||
|
||||
String result = bout.toString();
|
||||
|
||||
Log.trace("Result: ", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void close(final Closeable... closeables) {
|
||||
for (Closeable c : closeables) {
|
||||
try {
|
||||
c.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package net.minecraft.entity;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.command.server.CommandBlockLogic;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.IChatComponent;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
// CraftBukkit - package-private -> public
|
||||
public class EntityMinecartCommandBlockListener extends CommandBlockLogic
|
||||
{
|
||||
final EntityMinecartCommandBlock field_145768_a;
|
||||
|
||||
EntityMinecartCommandBlockListener(EntityMinecartCommandBlock p_i45320_1_)
|
||||
{
|
||||
this.field_145768_a = p_i45320_1_;
|
||||
this.sender = (org.bukkit.craftbukkit.entity.CraftMinecartCommand) p_i45320_1_.getBukkitEntity(); // CraftBukkit - Set the sender
|
||||
}
|
||||
|
||||
public void func_145756_e()
|
||||
{
|
||||
this.field_145768_a.getDataWatcher().updateObject(23, this.func_145753_i());
|
||||
this.field_145768_a.getDataWatcher().updateObject(24, IChatComponent.Serializer.func_150696_a(this.func_145749_h()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the position for this command sender.
|
||||
*/
|
||||
public ChunkCoordinates getPlayerCoordinates()
|
||||
{
|
||||
return new ChunkCoordinates(MathHelper.floor_double(this.field_145768_a.posX), MathHelper.floor_double(this.field_145768_a.posY + 0.5D), MathHelper.floor_double(this.field_145768_a.posZ));
|
||||
}
|
||||
|
||||
public World getEntityWorld()
|
||||
{
|
||||
return this.field_145768_a.worldObj;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int func_145751_f()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void func_145757_a(ByteBuf p_145757_1_)
|
||||
{
|
||||
p_145757_1_.writeInt(field_145768_a.getEntityId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package net.minecraft.inventory;
|
||||
|
||||
// CraftBukkit start
|
||||
import java.util.List;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
// CraftBukkit end
|
||||
|
||||
public class ContainerEnchantTableInventory extends InventoryBasic // CraftBukkit -> public
|
||||
{
|
||||
/** The brewing stand this slot belongs to. */
|
||||
final ContainerEnchantment container;
|
||||
|
||||
// CraftBukkit start
|
||||
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
public org.bukkit.entity.Player player;
|
||||
private int maxStack = MAX_STACK;
|
||||
|
||||
public ItemStack[] getContents()
|
||||
{
|
||||
return this.inventoryContents;
|
||||
}
|
||||
|
||||
public void onOpen(CraftHumanEntity who)
|
||||
{
|
||||
transaction.add(who);
|
||||
}
|
||||
|
||||
public void onClose(CraftHumanEntity who)
|
||||
{
|
||||
transaction.remove(who);
|
||||
}
|
||||
|
||||
public List<HumanEntity> getViewers()
|
||||
{
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.InventoryHolder getOwner()
|
||||
{
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setMaxStackSize(int size)
|
||||
{
|
||||
maxStack = size;
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
ContainerEnchantTableInventory(ContainerEnchantment par1ContainerEnchantment, String par2Str, boolean par3, int par4)
|
||||
{
|
||||
super(par2Str, par3, par4);
|
||||
this.container = par1ContainerEnchantment;
|
||||
this.setMaxStackSize(1); // CraftBukkit
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't
|
||||
* this more of a set than a get?*
|
||||
*/
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
return maxStack; // CraftBukkit
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an the contents of an Inventory change, usually
|
||||
*/
|
||||
public void markDirty()
|
||||
{
|
||||
super.markDirty();
|
||||
this.container.onCraftMatrixChanged((IInventory) this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package net.minecraft.inventory;
|
||||
|
||||
// CraftBukkit start
|
||||
import java.util.List;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
// CraftBukkit end
|
||||
|
||||
public class ContainerRepairInventory extends InventoryBasic // CraftBukkit - public
|
||||
{
|
||||
final ContainerRepair repairContainer;
|
||||
|
||||
// CraftBukkit start
|
||||
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
public org.bukkit.entity.Player player;
|
||||
private int maxStack = MAX_STACK;
|
||||
|
||||
public ItemStack[] getContents()
|
||||
{
|
||||
return this.inventoryContents;
|
||||
}
|
||||
|
||||
public void onOpen(CraftHumanEntity who)
|
||||
{
|
||||
transaction.add(who);
|
||||
}
|
||||
|
||||
public void onClose(CraftHumanEntity who)
|
||||
{
|
||||
transaction.remove(who);
|
||||
}
|
||||
|
||||
public List<HumanEntity> getViewers()
|
||||
{
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public org.bukkit.inventory.InventoryHolder getOwner()
|
||||
{
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setMaxStackSize(int size)
|
||||
{
|
||||
maxStack = size;
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
ContainerRepairInventory(ContainerRepair par1ContainerRepair, String par2Str, boolean par3, int par4)
|
||||
{
|
||||
super(par2Str, par3, par4);
|
||||
this.repairContainer = par1ContainerRepair;
|
||||
this.setMaxStackSize(1); // CraftBukkit
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an the contents of an Inventory change, usually
|
||||
*/
|
||||
public void markDirty()
|
||||
{
|
||||
super.markDirty();
|
||||
this.repairContainer.onCraftMatrixChanged((IInventory) this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package net.minecraft.server.network;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.NetHandlerLoginServer.LoginState;
|
||||
import net.minecraft.util.CryptManager;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
||||
|
||||
// CraftBukkit start
|
||||
import org.bukkit.craftbukkit.util.Waitable;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.PlayerPreLoginEvent;
|
||||
// CraftBukkit end
|
||||
|
||||
class ThreadPlayerLookupUUID extends Thread
|
||||
{
|
||||
final NetHandlerLoginServer field_151292_a;
|
||||
private MinecraftServer mcServer; // Cauldron
|
||||
|
||||
ThreadPlayerLookupUUID(NetHandlerLoginServer p_i45296_1_, String p_i45296_2_)
|
||||
{
|
||||
super(p_i45296_2_);
|
||||
this.field_151292_a = p_i45296_1_;
|
||||
this.mcServer = NetHandlerLoginServer.getMinecraftServer(this.field_151292_a); // Cauldron
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
GameProfile gameprofile = NetHandlerLoginServer.getGameProfile(this.field_151292_a);
|
||||
try
|
||||
{
|
||||
// Spigot Start
|
||||
if (!this.mcServer.isServerInOnlineMode())
|
||||
{
|
||||
this.field_151292_a.initUUID();
|
||||
fireLoginEvents();
|
||||
return;
|
||||
}
|
||||
// Spigot End
|
||||
String s = (new BigInteger(CryptManager.getServerIdHash(NetHandlerLoginServer.getLoginServerId(this.field_151292_a), this.mcServer.getKeyPair().getPublic(), NetHandlerLoginServer.getSecretKey(this.field_151292_a)))).toString(16);
|
||||
NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, this.mcServer.func_147130_as().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s));
|
||||
|
||||
if (NetHandlerLoginServer.getGameProfile(this.field_151292_a) != null)
|
||||
{
|
||||
fireLoginEvents(); // Spigot
|
||||
}
|
||||
else if (this.mcServer.isSinglePlayer())
|
||||
{
|
||||
NetHandlerLoginServer.getLogger().warn("Failed to verify username but will let them in anyway!");
|
||||
NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, this.field_151292_a.func_152506_a(gameprofile));
|
||||
NetHandlerLoginServer.setLoginState(this.field_151292_a, LoginState.READY_TO_ACCEPT);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.field_151292_a.func_147322_a("Failed to verify username!");
|
||||
NetHandlerLoginServer.getLogger().error("Username \'" + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName() + "\' tried to join with an invalid session");
|
||||
}
|
||||
}
|
||||
catch (AuthenticationUnavailableException authenticationunavailableexception)
|
||||
{
|
||||
if (this.mcServer.isSinglePlayer())
|
||||
{
|
||||
NetHandlerLoginServer.getLogger().warn("Authentication servers are down but will let them in anyway!");
|
||||
NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, this.field_151292_a.func_152506_a(gameprofile));
|
||||
NetHandlerLoginServer.setLoginState(this.field_151292_a, LoginState.READY_TO_ACCEPT);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.field_151292_a.func_147322_a("Authentication servers are down. Please try again later, sorry!");
|
||||
NetHandlerLoginServer.getLogger().error("Couldn\'t verify username because servers are unavailable");
|
||||
}
|
||||
// CraftBukkit start - catch all exceptions
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
this.field_151292_a.func_147322_a("Failed to verify username!");
|
||||
this.mcServer.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName(), exception);
|
||||
// CraftBukkit end
|
||||
}
|
||||
}
|
||||
|
||||
private void fireLoginEvents() throws Exception
|
||||
{
|
||||
// CraftBukkit start - fire PlayerPreLoginEvent
|
||||
if (!this.field_151292_a.field_147333_a.isChannelOpen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String playerName = NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName();
|
||||
java.net.InetAddress address = ((java.net.InetSocketAddress) this.field_151292_a.field_147333_a.getSocketAddress()).getAddress();
|
||||
java.util.UUID uniqueId = NetHandlerLoginServer.getGameProfile(this.field_151292_a).getId();
|
||||
final org.bukkit.craftbukkit.CraftServer server = this.mcServer.server;
|
||||
|
||||
AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId);
|
||||
server.getPluginManager().callEvent(asyncEvent);
|
||||
|
||||
if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0)
|
||||
{
|
||||
final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId);
|
||||
|
||||
if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED)
|
||||
{
|
||||
event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage());
|
||||
}
|
||||
|
||||
Waitable<PlayerPreLoginEvent.Result> waitable = new Waitable<PlayerPreLoginEvent.Result>()
|
||||
{
|
||||
@Override
|
||||
protected PlayerPreLoginEvent.Result evaluate()
|
||||
{
|
||||
server.getPluginManager().callEvent(event);
|
||||
return event.getResult();
|
||||
}
|
||||
};
|
||||
|
||||
NetHandlerLoginServer.getMinecraftServer(this.field_151292_a).processQueue.add(waitable);
|
||||
|
||||
if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED)
|
||||
{
|
||||
this.field_151292_a.func_147322_a(event.getKickMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED)
|
||||
{
|
||||
this.field_151292_a.func_147322_a(asyncEvent.getKickMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
NetHandlerLoginServer.getLogger().info("UUID of player " + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName() + " is " + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getId());;
|
||||
NetHandlerLoginServer.setLoginState(this.field_151292_a, LoginState.READY_TO_ACCEPT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package net.minecraft.tileentity;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.command.server.CommandBlockLogic;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.world.World;
|
||||
// CraftBukkit - package-private -> public
|
||||
public class TileEntityCommandBlockListener extends CommandBlockLogic
|
||||
{
|
||||
final TileEntityCommandBlock field_145767_a;
|
||||
|
||||
TileEntityCommandBlockListener(TileEntityCommandBlock p_i45441_1_)
|
||||
{
|
||||
this.field_145767_a = p_i45441_1_;
|
||||
sender = new org.bukkit.craftbukkit.command.CraftBlockCommandSender(this); // CraftBukkit - add sender
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the position for this command sender.
|
||||
*/
|
||||
public ChunkCoordinates getPlayerCoordinates()
|
||||
{
|
||||
return new ChunkCoordinates(this.field_145767_a.xCoord, this.field_145767_a.yCoord, this.field_145767_a.zCoord);
|
||||
}
|
||||
|
||||
public World getEntityWorld()
|
||||
{
|
||||
return this.field_145767_a.getWorldObj();
|
||||
}
|
||||
|
||||
public void func_145752_a(String p_145752_1_)
|
||||
{
|
||||
super.func_145752_a(p_145752_1_);
|
||||
this.field_145767_a.markDirty();
|
||||
}
|
||||
|
||||
public void func_145756_e()
|
||||
{
|
||||
this.field_145767_a.getWorldObj().markBlockForUpdate(this.field_145767_a.xCoord, this.field_145767_a.yCoord, this.field_145767_a.zCoord);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public int func_145751_f()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void func_145757_a(ByteBuf p_145757_1_)
|
||||
{
|
||||
p_145757_1_.writeInt(field_145767_a.xCoord);
|
||||
p_145757_1_.writeInt(field_145767_a.yCoord);
|
||||
p_145757_1_.writeInt(field_145767_a.zCoord);
|
||||
}
|
||||
}
|
||||
469
src/main/java/net/minecraftforge/cauldron/CauldronHooks.java
Normal file
469
src/main/java/net/minecraftforge/cauldron/CauldronHooks.java
Normal file
@@ -0,0 +1,469 @@
|
||||
package net.minecraftforge.cauldron;
|
||||
|
||||
import gnu.trove.map.hash.TObjectIntHashMap;
|
||||
import gnu.trove.map.hash.TObjectLongHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.ChunkCoordinates;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class CauldronHooks
|
||||
{
|
||||
// Some mods such as Twilight Forest listen for specific events as their WorldProvider loads to hotload its dimension. This prevents this from happening so MV can create worlds using the same provider without issue.
|
||||
public static boolean craftWorldLoading = false;
|
||||
public static int tickingDimension = 0;
|
||||
public static ChunkCoordIntPair tickingChunk = null;
|
||||
public static Map<Class<? extends TileEntity>, TileEntityCache> tileEntityCache = new HashMap<Class<? extends TileEntity>, TileEntityCache>();
|
||||
|
||||
private static TObjectLongHashMap<CollisionWarning> recentWarnings = new TObjectLongHashMap<CollisionWarning>();
|
||||
|
||||
public static void logInfo(String msg, Object... args)
|
||||
{
|
||||
MinecraftServer.getServer().logInfo(MessageFormat.format(msg, args));
|
||||
}
|
||||
|
||||
public static void logWarning(String msg, Object... args)
|
||||
{
|
||||
MinecraftServer.getServer().logWarning(MessageFormat.format(msg, args));
|
||||
}
|
||||
|
||||
public static void logSevere(String msg, Object... args)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere(MessageFormat.format(msg, args));
|
||||
}
|
||||
|
||||
public static void logStack()
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.logWithStackTraces.getValue())
|
||||
{
|
||||
Throwable ex = new Throwable();
|
||||
ex.fillInStackTrace();
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logEntityDeath(Entity entity)
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.entityDeathLogging.getValue())
|
||||
{
|
||||
logInfo("Dim: {0} setDead(): {1}", entity.worldObj.provider.dimensionId, entity);
|
||||
logStack();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logEntityDespawn(Entity entity, String reason)
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.entityDespawnLogging.getValue())
|
||||
{
|
||||
logInfo("Dim: {0} Despawning ({1}): {2}", entity.worldObj.provider.dimensionId, reason, entity);
|
||||
//logInfo("Chunk Is Active: {0}", entity.worldObj.inActiveChunk(entity));
|
||||
logStack();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logEntitySpawn(World world, Entity entity, SpawnReason spawnReason)
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.entitySpawnLogging.getValue())
|
||||
{
|
||||
logInfo("Dim: {0} Spawning ({1}): {2}", world.provider.dimensionId, spawnReason, entity);
|
||||
logInfo("Dim: {0} Entities Last Tick: {1}", world.provider.dimensionId, world.entitiesTicked);
|
||||
logInfo("Dim: {0} Tiles Last Tick: {1}", world.provider.dimensionId, world.tilesTicked);
|
||||
//logInfo("Chunk Is Active: {0}", world.inActiveChunk(entity));
|
||||
logStack();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logChunkLoad(ChunkProviderServer provider, String msg, int x, int z, boolean logLoadOnRequest)
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.chunkLoadLogging.getValue())
|
||||
{
|
||||
logInfo("{0} Chunk At [{1}] ({2}, {3})", msg, provider.worldObj.provider.dimensionId, x, z);
|
||||
if (logLoadOnRequest)
|
||||
{
|
||||
logLoadOnRequest(provider, x, z);
|
||||
}
|
||||
logStack();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logChunkUnload(ChunkProviderServer provider, int x, int z, String msg)
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.chunkUnloadLogging.getValue())
|
||||
{
|
||||
logInfo("{0} [{1}] ({2}, {3})", msg, provider.worldObj.provider.dimensionId, x, z);
|
||||
long currentTick = MinecraftServer.getServer().getTickCounter();
|
||||
long lastAccessed = provider.lastAccessed(x, z);
|
||||
long diff = currentTick - lastAccessed;
|
||||
logInfo(" Last accessed: {0, number} Current Tick: {1, number} [{2, number}]", lastAccessed, currentTick, diff);
|
||||
}
|
||||
}
|
||||
|
||||
private static void logLoadOnRequest(ChunkProviderServer provider, int x, int z)
|
||||
{
|
||||
long currentTick = MinecraftServer.getServer().getTickCounter();
|
||||
long lastAccessed = provider.lastAccessed(x, z);
|
||||
long diff = currentTick - lastAccessed;
|
||||
logInfo(" Last accessed: {0, number} Current Tick: {1, number} [{2, number}]", lastAccessed, currentTick, diff);
|
||||
logInfo(" Finding Spawn Point: {0}", provider.worldObj.findingSpawnPoint);
|
||||
logInfo(" Load chunk on request: {0}", provider.loadChunkOnProvideRequest);
|
||||
logInfo(" Calling Forge Tick: {0}", MinecraftServer.callingForgeTick);
|
||||
logInfo(" Load chunk on forge tick: {0}", MinecraftServer.cauldronConfig.loadChunkOnForgeTick.getValue());
|
||||
long providerTickDiff = currentTick - provider.initialTick;
|
||||
if (providerTickDiff <= 100)
|
||||
{
|
||||
logInfo(" Current Tick - Initial Tick: {0, number}", providerTickDiff);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkBoundingBoxSize(Entity entity, AxisAlignedBB aabb)
|
||||
{
|
||||
if (!(entity instanceof EntityLivingBase) || entity instanceof EntityPlayer) return false; // only check living entities that are not players
|
||||
int logSize = MinecraftServer.cauldronConfig.largeBoundingBoxLogSize.getValue();
|
||||
if (logSize <= 0 || !MinecraftServer.cauldronConfig.checkEntityBoundingBoxes.getValue()) return false;
|
||||
int x = MathHelper.floor_double(aabb.minX);
|
||||
int x1 = MathHelper.floor_double(aabb.maxX + 1.0D);
|
||||
int y = MathHelper.floor_double(aabb.minY);
|
||||
int y1 = MathHelper.floor_double(aabb.maxY + 1.0D);
|
||||
int z = MathHelper.floor_double(aabb.minZ);
|
||||
int z1 = MathHelper.floor_double(aabb.maxZ + 1.0D);
|
||||
|
||||
int size = Math.abs(x1-x) * Math.abs(y1-y) * Math.abs(z1-z);
|
||||
if (size > MinecraftServer.cauldronConfig.largeBoundingBoxLogSize.getValue())
|
||||
{
|
||||
logWarning("Entity being removed for bounding box restrictions");
|
||||
logWarning("BB Size: {0} > {1} avg edge: {2}", size, logSize, aabb.getAverageEdgeLength());
|
||||
logWarning("Motion: ({0}, {1}, {2})", entity.motionX, entity.motionY, entity.motionZ);
|
||||
logWarning("Calculated bounding box: {0}", aabb);
|
||||
logWarning("Entity bounding box: {0}", entity.getBoundingBox());
|
||||
logWarning("Entity: {0}", entity);
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
entity.writeToNBT(tag);
|
||||
logWarning("Entity NBT: {0}", tag);
|
||||
logStack();
|
||||
entity.setDead();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkEntitySpeed(Entity entity, double x, double y, double z)
|
||||
{
|
||||
int maxSpeed = MinecraftServer.cauldronConfig.entityMaxSpeed.getValue();
|
||||
if (maxSpeed > 0 && MinecraftServer.cauldronConfig.checkEntityMaxSpeeds.getValue())
|
||||
{
|
||||
double distance = x * x + z * z;
|
||||
if (distance > maxSpeed)
|
||||
{
|
||||
if (MinecraftServer.cauldronConfig.logEntitySpeedRemoval.getValue())
|
||||
{
|
||||
logInfo("Speed violation: {0} was over {1} - Removing Entity: {2}", distance, maxSpeed, entity);
|
||||
if (entity instanceof EntityLivingBase)
|
||||
{
|
||||
EntityLivingBase livingBase = (EntityLivingBase)entity;
|
||||
logInfo("Entity Motion: ({0}, {1}, {2}) Move Strafing: {3} Move Forward: {4}", entity.motionX, entity.motionY, entity.motionZ, livingBase.moveStrafing, livingBase.moveForward);
|
||||
}
|
||||
|
||||
if (MinecraftServer.cauldronConfig.logWithStackTraces.getValue())
|
||||
{
|
||||
logInfo("Move offset: ({0}, {1}, {2})", x, y, z);
|
||||
logInfo("Motion: ({0}, {1}, {2})", entity.motionX, entity.motionY, entity.motionZ);
|
||||
logInfo("Entity: {0}", entity);
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
entity.writeToNBT(tag);
|
||||
logInfo("Entity NBT: {0}", tag);
|
||||
logStack();
|
||||
}
|
||||
}
|
||||
if (entity instanceof EntityPlayer) // Skip killing players
|
||||
{
|
||||
entity.motionX = 0;
|
||||
entity.motionY = 0;
|
||||
entity.motionZ = 0;
|
||||
return false;
|
||||
}
|
||||
// Remove the entity;
|
||||
entity.isDead = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void logEntitySize(World world, Entity entity, List list)
|
||||
{
|
||||
if (!MinecraftServer.cauldronConfig.logEntityCollisionChecks.getValue()) return;
|
||||
long largeCountLogSize = MinecraftServer.cauldronConfig.largeCollisionLogSize.getValue();
|
||||
if (largeCountLogSize > 0 && world.entitiesTicked > largeCountLogSize)
|
||||
{
|
||||
logWarning("Entity size > {0, number} at: {1}", largeCountLogSize, entity);
|
||||
}
|
||||
if (list == null) return;
|
||||
long largeCollisionLogSize = MinecraftServer.cauldronConfig.largeCollisionLogSize.getValue();
|
||||
if (largeCollisionLogSize > 0 &&
|
||||
(MinecraftServer.getServer().getTickCounter() % 10) == 0 &&
|
||||
list.size() >= largeCollisionLogSize)
|
||||
{
|
||||
CauldronHooks.CollisionWarning warning = new CauldronHooks.CollisionWarning(world, entity);
|
||||
if (recentWarnings.contains(warning))
|
||||
{
|
||||
long lastWarned = recentWarnings.get(warning);
|
||||
if ((MinecraftServer.getSystemTimeMillis() - lastWarned) < 30000) return;
|
||||
}
|
||||
recentWarnings.put(warning, System.currentTimeMillis());
|
||||
logWarning("Entity collision > {0, number} at: {1}", largeCollisionLogSize, entity);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CollisionWarning
|
||||
{
|
||||
public ChunkCoordinates chunkCoords;
|
||||
public int dimensionId;
|
||||
|
||||
public CollisionWarning(World world, Entity entity)
|
||||
{
|
||||
this.dimensionId = world.provider.dimensionId;
|
||||
this.chunkCoords = new ChunkCoordinates(entity.chunkCoordX, entity.chunkCoordY, entity.chunkCoordZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object otherObj)
|
||||
{
|
||||
if (!(otherObj instanceof CollisionWarning) || (otherObj == null)) return false;
|
||||
CollisionWarning other = (CollisionWarning) otherObj;
|
||||
return (other.dimensionId == this.dimensionId) && other.chunkCoords.equals(this.chunkCoords);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return chunkCoords.hashCode() + dimensionId;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canTileEntityTick(TileEntity tileEntity, World world)
|
||||
{
|
||||
if (tileEntity == null || world.tileentityConfig == null) return false;
|
||||
if (MinecraftServer.tileEntityConfig.skipTileEntityTicks.getValue())
|
||||
{
|
||||
TileEntityCache teCache = tileEntityCache.get(tileEntity.getClass());
|
||||
if (teCache == null)
|
||||
{
|
||||
String teConfigPath = tileEntity.getClass().getName().replace(".", "-");
|
||||
teConfigPath = teConfigPath.replaceAll("[^A-Za-z0-9\\-]", ""); // Fix up odd class names to prevent YAML errors
|
||||
teCache = new TileEntityCache(tileEntity.getClass(), world.getWorldInfo().getWorldName().toLowerCase(), teConfigPath, world.tileentityConfig.getBoolean(teConfigPath + ".tick-no-players", false), world.tileentityConfig.getInt(teConfigPath + ".tick-interval", 1));
|
||||
tileEntityCache.put(tileEntity.getClass(), teCache);
|
||||
}
|
||||
|
||||
// Tick with no players near?
|
||||
if (!teCache.tickNoPlayers && !world.isActiveBlockCoord(tileEntity.xCoord, tileEntity.zCoord))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip tick interval
|
||||
if (teCache.tickInterval > 0 && (world.getWorldInfo().getWorldTotalTime() % teCache.tickInterval == 0L))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean canUpdate(TileEntity tileEntity)
|
||||
{
|
||||
if (tileEntity == null || !tileEntity.canUpdate() || MinecraftServer.bannedTileEntityUpdates.contains(tileEntity.getClass())) return false; // quick exit
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void writeChunks(File file, boolean logAll)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (file.getParentFile() != null)
|
||||
{
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
FileWriter fileWriter = new FileWriter(file);
|
||||
JsonWriter writer = new JsonWriter(fileWriter);
|
||||
writer.setIndent(" ");
|
||||
writer.beginArray();
|
||||
|
||||
for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds)
|
||||
{
|
||||
writer.beginObject();
|
||||
writer.name("name").value(world.getWorld().getName());
|
||||
writer.name("dimensionId").value(world.provider.dimensionId);
|
||||
writer.name("players").value(world.playerEntities.size());
|
||||
writer.name("loadedChunks").value(world.theChunkProviderServer.loadedChunkHashMap.size());
|
||||
writer.name("activeChunks").value(world.activeChunkSet.size());
|
||||
writer.name("entities").value(world.loadedEntityList.size());
|
||||
writer.name("tiles").value(world.loadedTileEntityList.size());
|
||||
|
||||
TObjectIntHashMap<ChunkCoordIntPair> chunkEntityCounts = new TObjectIntHashMap<ChunkCoordIntPair>();
|
||||
TObjectIntHashMap<Class> classEntityCounts = new TObjectIntHashMap<Class>();
|
||||
TObjectIntHashMap<Entity> entityCollisionCounts = new TObjectIntHashMap<Entity>();
|
||||
Set<ChunkCoordinates> collidingCoords = new HashSet<ChunkCoordinates>();
|
||||
for (int i = 0; i < world.loadedEntityList.size(); i++)
|
||||
{
|
||||
Entity entity = (Entity) world.loadedEntityList.get(i);
|
||||
ChunkCoordIntPair chunkCoords = new ChunkCoordIntPair((int) entity.posX >> 4, (int) entity.posZ >> 4);
|
||||
chunkEntityCounts.adjustOrPutValue(chunkCoords, 1, 1);
|
||||
classEntityCounts.adjustOrPutValue(entity.getClass(), 1, 1);
|
||||
if ((entity.boundingBox != null) && logAll)
|
||||
{
|
||||
ChunkCoordinates coords = new ChunkCoordinates((int)Math.floor(entity.posX), (int)Math.floor(entity.posY), (int)Math.floor(entity.posZ));
|
||||
if (!collidingCoords.contains(coords))
|
||||
{
|
||||
collidingCoords.add(coords);
|
||||
int size = entity.worldObj.getEntitiesWithinAABBExcludingEntity(entity, entity.boundingBox.expand(1, 1, 1)).size();
|
||||
if (size < 5)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
entityCollisionCounts.put(entity, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TObjectIntHashMap<ChunkCoordIntPair> chunkTileCounts = new TObjectIntHashMap<ChunkCoordIntPair>();
|
||||
TObjectIntHashMap<Class> classTileCounts = new TObjectIntHashMap<Class>();
|
||||
writer.name("tiles").beginArray();
|
||||
for (int i = 0; i < world.loadedTileEntityList.size(); i++)
|
||||
{
|
||||
TileEntity tile = (TileEntity) world.loadedTileEntityList.get(i);
|
||||
if (logAll)
|
||||
{
|
||||
writer.beginObject();
|
||||
writer.name("type").value(tile.getClass().toString());
|
||||
writer.name("x").value(tile.xCoord);
|
||||
writer.name("y").value(tile.yCoord);
|
||||
writer.name("z").value(tile.zCoord);
|
||||
writer.name("isInvalid").value(tile.isInvalid());
|
||||
writer.name("canUpdate").value(tile.canUpdate());
|
||||
writer.name("block").value("" + tile.getBlockType());
|
||||
writer.endObject();
|
||||
}
|
||||
ChunkCoordIntPair chunkCoords = new ChunkCoordIntPair(tile.xCoord >> 4, tile.zCoord >> 4);
|
||||
chunkTileCounts.adjustOrPutValue(chunkCoords, 1, 1);
|
||||
classTileCounts.adjustOrPutValue(tile.getClass(), 1, 1);
|
||||
}
|
||||
writer.endArray();
|
||||
|
||||
if (logAll)
|
||||
{
|
||||
writeChunkCounts(writer, "topEntityColliders", entityCollisionCounts, 20);
|
||||
}
|
||||
writeChunkCounts(writer, "entitiesByClass", classEntityCounts);
|
||||
writeChunkCounts(writer, "entitiesByChunk", chunkEntityCounts);
|
||||
|
||||
writeChunkCounts(writer, "tilesByClass", classTileCounts);
|
||||
writeChunkCounts(writer, "tilesByChunk", chunkTileCounts);
|
||||
|
||||
writer.endObject(); // Dimension
|
||||
}
|
||||
writer.endArray(); // Dimensions
|
||||
writer.close();
|
||||
fileWriter.close();
|
||||
}
|
||||
catch (Throwable throwable)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("Could not save chunk info report to " + file);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void writeChunkCounts(JsonWriter writer, String name, final TObjectIntHashMap<T> map) throws IOException
|
||||
{
|
||||
writeChunkCounts(writer, name, map, 0);
|
||||
}
|
||||
|
||||
private static <T> void writeChunkCounts(JsonWriter writer, String name, final TObjectIntHashMap<T> map, int max) throws IOException
|
||||
{
|
||||
List<T> sortedCoords = new ArrayList<T>(map.keySet());
|
||||
Collections.sort(sortedCoords, new Comparator<T>()
|
||||
{
|
||||
@Override
|
||||
public int compare(T s1, T s2)
|
||||
{
|
||||
return map.get(s2) - map.get(s1);
|
||||
}
|
||||
});
|
||||
|
||||
int i = 0;
|
||||
writer.name(name).beginArray();
|
||||
for (T key : sortedCoords)
|
||||
{
|
||||
if ((max > 0) && (i++ > max))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (map.get(key) < 5)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
writer.beginObject();
|
||||
writer.name("key").value(key.toString());
|
||||
writer.name("count").value(map.get(key));
|
||||
writer.endObject();
|
||||
}
|
||||
writer.endArray();
|
||||
}
|
||||
|
||||
public static void dumpHeap(File file, boolean live)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (file.getParentFile() != null)
|
||||
{
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
|
||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
Object hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz);
|
||||
Method m = clazz.getMethod("dumpHeap", String.class, boolean.class);
|
||||
m.invoke(hotspotMBean, file.getPath(), live);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
logSevere("Could not write heap to {0}", file);
|
||||
}
|
||||
}
|
||||
|
||||
public static void enableThreadContentionMonitoring()
|
||||
{
|
||||
if (!MinecraftServer.cauldronConfig.enableThreadContentionMonitoring.getValue()) return;
|
||||
java.lang.management.ThreadMXBean mbean = java.lang.management.ManagementFactory.getThreadMXBean();
|
||||
mbean.setThreadContentionMonitoringEnabled(true);
|
||||
}
|
||||
}
|
||||
147
src/main/java/net/minecraftforge/cauldron/CauldronUtils.java
Normal file
147
src/main/java/net/minecraftforge/cauldron/CauldronUtils.java
Normal file
@@ -0,0 +1,147 @@
|
||||
package net.minecraftforge.cauldron;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public class CauldronUtils {
|
||||
private static boolean deobfuscated = false;
|
||||
|
||||
public static boolean isOverridingUpdateEntity(Class<? extends TileEntity> c)
|
||||
{
|
||||
Class clazz = null;
|
||||
String method = deobfuscatedEnvironment() ? "updateEntity" : "func_145845_h"; // updateEntity
|
||||
try
|
||||
{
|
||||
clazz = c.getMethod(method).getDeclaringClass();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
//e.printStackTrace(); no need for spam
|
||||
}
|
||||
|
||||
return clazz != TileEntity.class;
|
||||
}
|
||||
|
||||
public static boolean canTileEntityUpdate(Class<? extends TileEntity> c)
|
||||
{
|
||||
boolean canUpdate = false;
|
||||
try
|
||||
{
|
||||
Constructor<? extends TileEntity> ctor = c.getConstructor();
|
||||
TileEntity te = ctor.newInstance();
|
||||
canUpdate = te.canUpdate();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
return canUpdate;
|
||||
}
|
||||
|
||||
public static <T> void dumpAndSortClassList(List<Class<? extends T>> classList)
|
||||
{
|
||||
List<String> sortedClassList = new ArrayList<String>();
|
||||
for (Class clazz : classList)
|
||||
{
|
||||
sortedClassList.add(clazz.getName());
|
||||
}
|
||||
Collections.sort(sortedClassList);
|
||||
if (MinecraftServer.tileEntityConfig.enableTECanUpdateWarning.getValue())
|
||||
{
|
||||
for (String aSortedClassList : sortedClassList) {
|
||||
MinecraftServer.getServer().logInfo("Detected TE " + aSortedClassList + " with canUpdate set to true and no updateEntity override!. This is NOT good, please report to mod author as this can hurt performance.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean migrateWorlds(String worldType, String oldWorldContainer, String newWorldContainer, String worldName)
|
||||
{
|
||||
boolean result = true;
|
||||
File newWorld = new File(new File(newWorldContainer), worldName);
|
||||
File oldWorld = new File(new File(oldWorldContainer), worldName);
|
||||
|
||||
if ((!newWorld.isDirectory()) && (oldWorld.isDirectory()))
|
||||
{
|
||||
MinecraftServer.getServer().logInfo("---- Migration of old " + worldType + " folder required ----");
|
||||
MinecraftServer.getServer().logInfo("Cauldron has moved back to using the Forge World structure, your " + worldType + " folder will be moved to a new location in order to operate correctly.");
|
||||
MinecraftServer.getServer().logInfo("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Cauldron in the future.");
|
||||
MinecraftServer.getServer().logInfo("Attempting to move " + oldWorld + " to " + newWorld + "...");
|
||||
|
||||
if (newWorld.exists())
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("A file or folder already exists at " + newWorld + "!");
|
||||
MinecraftServer.getServer().logInfo("---- Migration of old " + worldType + " folder failed ----");
|
||||
result = false;
|
||||
}
|
||||
else if (newWorld.getParentFile().mkdirs() || newWorld.getParentFile().exists())
|
||||
{
|
||||
MinecraftServer.getServer().logInfo("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld);
|
||||
|
||||
// Migrate world data
|
||||
try
|
||||
{
|
||||
com.google.common.io.Files.move(oldWorld, newWorld);
|
||||
}
|
||||
catch (IOException exception)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("Unable to move world data.");
|
||||
exception.printStackTrace();
|
||||
result = false;
|
||||
}
|
||||
try
|
||||
{
|
||||
com.google.common.io.Files.copy(new File(oldWorld.getParent(), "level.dat"), new File(newWorld, "level.dat"));
|
||||
}
|
||||
catch (IOException exception)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("Unable to migrate world level.dat.");
|
||||
}
|
||||
|
||||
MinecraftServer.getServer().logInfo("---- Migration of old " + worldType + " folder complete ----");
|
||||
}
|
||||
else result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static InventoryHolder getOwner(TileEntity tileentity)
|
||||
{
|
||||
org.bukkit.block.BlockState state = tileentity.worldObj.getWorld().getBlockAt(tileentity.xCoord, tileentity.yCoord, tileentity.zCoord).getState();
|
||||
|
||||
if (state instanceof InventoryHolder)
|
||||
{
|
||||
return (InventoryHolder) state;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean deobfuscatedEnvironment()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Are we in a 'decompiled' environment?
|
||||
byte[] bs = ((net.minecraft.launchwrapper.LaunchClassLoader)CauldronUtils.class.getClassLoader()).getClassBytes("net.minecraft.world.World");
|
||||
if (bs != null)
|
||||
{
|
||||
//FMLRelaunchLog.info("Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation");
|
||||
deobfuscated = true;
|
||||
}
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
}
|
||||
return deobfuscated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.minecraftforge.cauldron;
|
||||
|
||||
public class CompatibilityMarker {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.minecraftforge.cauldron;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public class TileEntityCache {
|
||||
|
||||
public Class<? extends TileEntity> tileEntityClass;
|
||||
public boolean tickNoPlayers = false;
|
||||
public int tickInterval = 1;
|
||||
public String configPath;
|
||||
public String worldName;
|
||||
|
||||
public TileEntityCache(Class<? extends TileEntity> tileEntityClass, String worldName, String configPath, boolean tickNoPlayers, int tickInterval)
|
||||
{
|
||||
this.tileEntityClass = tileEntityClass;
|
||||
this.worldName = worldName;
|
||||
this.tickNoPlayers = tickNoPlayers;
|
||||
this.tickInterval = tickInterval;
|
||||
this.configPath = configPath;
|
||||
}
|
||||
}
|
||||
109
src/main/java/net/minecraftforge/cauldron/VersionInfo.java
Normal file
109
src/main/java/net/minecraftforge/cauldron/VersionInfo.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package net.minecraftforge.cauldron;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import argo.jdom.JdomParser;
|
||||
import argo.jdom.JsonNode;
|
||||
import argo.jdom.JsonRootNode;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.OutputSupplier;
|
||||
|
||||
public class VersionInfo {
|
||||
public static final VersionInfo INSTANCE = new VersionInfo();
|
||||
public final JsonRootNode versionData;
|
||||
|
||||
public VersionInfo()
|
||||
{
|
||||
InputStream installProfile = getClass().getResourceAsStream("/cauldron_libs.json");
|
||||
JdomParser parser = new JdomParser();
|
||||
|
||||
try
|
||||
{
|
||||
versionData = parser.parse(new InputStreamReader(installProfile, Charsets.UTF_8));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getProfileName()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","profileName");
|
||||
}
|
||||
|
||||
public static String getVersionTarget()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","target");
|
||||
}
|
||||
public static File getLibraryPath(File root)
|
||||
{
|
||||
String path = INSTANCE.versionData.getStringValue("install","path");
|
||||
String[] split = Iterables.toArray(Splitter.on(':').omitEmptyStrings().split(path), String.class);
|
||||
File dest = root;
|
||||
Iterable<String> subSplit = Splitter.on('.').omitEmptyStrings().split(split[0]);
|
||||
for (String part : subSplit)
|
||||
{
|
||||
dest = new File(dest, part);
|
||||
}
|
||||
dest = new File(new File(dest, split[1]), split[2]);
|
||||
String fileName = split[1]+"-"+split[2]+".jar";
|
||||
return new File(dest,fileName);
|
||||
}
|
||||
|
||||
public static String getVersion()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","version");
|
||||
}
|
||||
|
||||
public static String getWelcomeMessage()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","welcome");
|
||||
}
|
||||
|
||||
public static String getLogoFileName()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","logo");
|
||||
}
|
||||
|
||||
public static JsonNode getVersionInfo()
|
||||
{
|
||||
return INSTANCE.versionData.getNode("versionInfo");
|
||||
}
|
||||
|
||||
public static File getMinecraftFile(File path)
|
||||
{
|
||||
return new File(new File(path, getMinecraftVersion()),getMinecraftVersion()+".jar");
|
||||
}
|
||||
public static String getContainedFile()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","filePath");
|
||||
}
|
||||
public static void extractFile(File path) throws IOException
|
||||
{
|
||||
INSTANCE.doFileExtract(path);
|
||||
}
|
||||
|
||||
private void doFileExtract(File path) throws IOException
|
||||
{
|
||||
InputStream inputStream = getClass().getResourceAsStream("/"+getContainedFile());
|
||||
OutputSupplier<FileOutputStream> outputSupplier = Files.newOutputStreamSupplier(path);
|
||||
System.out.println("doFileExtract path = " + path.getAbsolutePath() + ", inputStream = " + inputStream + ", outputSupplier = " + outputSupplier);
|
||||
ByteStreams.copy(inputStream, outputSupplier);
|
||||
}
|
||||
|
||||
public static String getMinecraftVersion()
|
||||
{
|
||||
return INSTANCE.versionData.getStringValue("install","minecraft");
|
||||
}
|
||||
}
|
||||
29
src/main/java/net/minecraftforge/cauldron/api/Cauldron.java
Normal file
29
src/main/java/net/minecraftforge/cauldron/api/Cauldron.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package net.minecraftforge.cauldron.api;
|
||||
|
||||
import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary;
|
||||
|
||||
/**
|
||||
* Represents the Bukkit plugin interface to Cauldron, for version and singleton handling
|
||||
*/
|
||||
public class Cauldron {
|
||||
private static CauldronApi instance;
|
||||
public static void setInterface(CauldronApi cauldron) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
instance = cauldron;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current CauldronApi singleton
|
||||
*
|
||||
* @return current instance of CauldronApi. will always be present.
|
||||
*/
|
||||
public static CauldronApi getInterface() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static BukkitOreDictionary getOreDictionary() {
|
||||
return instance.getOreDictionary();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.minecraftforge.cauldron.api;
|
||||
|
||||
import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary;
|
||||
|
||||
/**
|
||||
* Represents the Bukkit plugin interface to Forge features.
|
||||
*/
|
||||
public interface CauldronApi {
|
||||
/**
|
||||
* Get the ore dictionary interface.
|
||||
*
|
||||
* @return ore dictionary interface
|
||||
*/
|
||||
public BukkitOreDictionary getOreDictionary();
|
||||
|
||||
/**
|
||||
* Get the fishing interface.
|
||||
*
|
||||
* @return the fishing interface
|
||||
*/
|
||||
public Fishing getFishingInterface();
|
||||
}
|
||||
72
src/main/java/net/minecraftforge/cauldron/api/Fishing.java
Normal file
72
src/main/java/net/minecraftforge/cauldron/api/Fishing.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package net.minecraftforge.cauldron.api;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Bukkit interface to Forge's FishingHooks class.
|
||||
*/
|
||||
public interface Fishing {
|
||||
|
||||
/**
|
||||
* Add a WeightedRandomFishable to the 'fish' results table.
|
||||
*
|
||||
* @param fish fishable item
|
||||
*/
|
||||
public void addFish(WeightedRandomFishable fish);
|
||||
|
||||
/**
|
||||
* Add a WeightedRandomFishable to the 'junk' results table.
|
||||
*
|
||||
* @param fish fishable item
|
||||
*/
|
||||
public void addJunk(WeightedRandomFishable fish);
|
||||
|
||||
/**
|
||||
* Add a WeightedRandomFishable to the 'treasure' results table.
|
||||
*
|
||||
* @param fish fishable item
|
||||
*/
|
||||
public void addTreasure(WeightedRandomFishable fish);
|
||||
|
||||
/**
|
||||
* Remove WeightedRandomFishables from the 'fish' results table.
|
||||
* Modifications to the Fishable objects will not be kept.
|
||||
*
|
||||
* @param test a Predicate giving the removal condition
|
||||
*/
|
||||
public void removeMatchingFish(Predicate<WeightedRandomFishable> test);
|
||||
|
||||
/**
|
||||
* Remove WeightedRandomFishables from the 'junk' results table.
|
||||
* Modifications to the Fishable objects will not be kept.
|
||||
*
|
||||
* @param test a Predicate giving the removal condition
|
||||
*/
|
||||
public void removeMatchingJunk(Predicate<WeightedRandomFishable> test);
|
||||
|
||||
/**
|
||||
* Remove WeightedRandomFishables from the 'treasure' results table.
|
||||
* Modifications to the Fishable objects will not be kept.
|
||||
*
|
||||
* @param test a Predicate giving the removal condition
|
||||
*/
|
||||
public void removeMatchingTreasure(Predicate<WeightedRandomFishable> test);
|
||||
|
||||
/**
|
||||
* Get the item pulled up from a simulated fishing attempt.
|
||||
*
|
||||
* @param rand the Random instance to use
|
||||
* @param baseChance roughly, a percentage chance (0-1) to
|
||||
* get a fish
|
||||
* @param fishingLuckEnchantmentLevel the value of {@link org.bukkit.enchantments.Enchantment#LUCK}
|
||||
* on the fishing rod
|
||||
* @param fishingSpeedEnchantmentLevel the value of {@link org.bukkit.enchantments.Enchantment#LURE}
|
||||
* on the fishing rod
|
||||
* @return the item fished
|
||||
*/
|
||||
public ItemStack getRandomFishable(Random rand, float baseChance, int fishingLuckEnchantmentLevel, int fishingSpeedEnchantmentLevel);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package net.minecraftforge.cauldron.api;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class WeightedRandomFishable {
|
||||
private ItemStack itemStack;
|
||||
private int weight;
|
||||
private boolean hasRandomEnchantments;
|
||||
private float damageFraction;
|
||||
|
||||
public WeightedRandomFishable(ItemStack itemStack, int weight) {
|
||||
this.itemStack = itemStack;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setting this value results in fished items having random damage when fished. The damage is in a triangular
|
||||
* random distribution (think about rolling 2 dice), with the wide end at 100% and
|
||||
* the narrow end at (100% - damageFraction).
|
||||
*
|
||||
* For use in a chaining constructor.
|
||||
*
|
||||
* @param damageFraction low boundary for random distribution
|
||||
* @return this WeightedRandomFishable, for chaining
|
||||
*/
|
||||
public final WeightedRandomFishable withDamageFraction(float damageFraction) {
|
||||
damageFraction = damageFraction;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this WeightedRandomFishable as receiving random enchantments.
|
||||
* @return this WeightedRandomFishable, for chaining
|
||||
*/
|
||||
public final WeightedRandomFishable withRandomEnchantments() {
|
||||
hasRandomEnchantments = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this WeightedRandomFishable receives random enchantments.
|
||||
* (Use this method if loading from another source, such as a config file.)
|
||||
* @return this WeightedRandomFishable, for chaining
|
||||
*/
|
||||
public final WeightedRandomFishable withRandomEnchantments(boolean hasEnchants) {
|
||||
hasRandomEnchantments = hasEnchants;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public boolean hasRandomEnchantments() {
|
||||
return hasRandomEnchantments;
|
||||
}
|
||||
|
||||
public float getDamageFraction() {
|
||||
return damageFraction;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.minecraftforge.cauldron.api.inventory;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The Forge Ore Dictionary provides a way for multiple items to share a common
|
||||
* identifier - for instance, "ingotCopper" - and be used interchangeably in
|
||||
* crafting recipes.
|
||||
* <p/>
|
||||
* This class provides a read-only interface to the ore dictionary using Bukkit
|
||||
* classes, instead of NMS classes.
|
||||
*/
|
||||
public interface BukkitOreDictionary {
|
||||
/**
|
||||
* If an item's damage is a wildcard, this will be returned for the item
|
||||
* damage.
|
||||
*/
|
||||
public static final int WILDCARD_VALUE = Short.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Check the OreDictionaryEntry for a given name. The name can be later
|
||||
* retrieved using {@link #getOreName(OreDictionaryEntry)}, and having an
|
||||
* entry is required to call {@link #getDefinitions(OreDictionaryEntry)}.
|
||||
*
|
||||
* @param name name in the ore dictionary
|
||||
* @return ore dictionary entry, or null if name is not present
|
||||
*/
|
||||
public OreDictionaryEntry getOreEntry(String name);
|
||||
|
||||
/**
|
||||
* Get the string name defined for the given OreDictionaryEntry.
|
||||
* <p/>
|
||||
* This is called by {@link OreDictionaryEntry#getName()}.
|
||||
*
|
||||
* @param entry ore dictionary entry
|
||||
* @return ore dictionary name
|
||||
*/
|
||||
public String getOreName(OreDictionaryEntry entry);
|
||||
|
||||
/**
|
||||
* Get all of the OreDictionaryEntry objects registered to the given
|
||||
* ItemStack.
|
||||
*
|
||||
* @param itemStack itemstack to check - amount is ignored
|
||||
* @return immutable list of ore dictionary entries
|
||||
*/
|
||||
public List<OreDictionaryEntry> getOreEntries(ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Get all of the OreDictionaryEntry objects registered to the given
|
||||
* material and no item damage.
|
||||
*
|
||||
* @param material material to check
|
||||
* @return immutable list of ore dictionary entries
|
||||
*/
|
||||
public List<OreDictionaryEntry> getOreEntries(Material material);
|
||||
|
||||
/**
|
||||
* Get all of the ItemStacks registered to the given ore dictionary entry.
|
||||
* <p/>
|
||||
* Quantity should be ignored.
|
||||
*
|
||||
* @param entry ore dictionary entry
|
||||
* @return immutable list of itemstacks
|
||||
*/
|
||||
public List<ItemStack> getDefinitions(OreDictionaryEntry entry);
|
||||
|
||||
/**
|
||||
* Get all ore names in the dictionary. The returned list may contain
|
||||
* multiple null values or duplicates.
|
||||
*
|
||||
* @return all ore dictionary names
|
||||
*/
|
||||
public List<String> getAllOreNames();
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.minecraftforge.cauldron.api.inventory;
|
||||
|
||||
import net.minecraftforge.cauldron.api.Cauldron;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An OreDictionaryEntry is an opaque reference to an entry in the Forge Ore
|
||||
* Dictionary. This class has reference equality.
|
||||
*/
|
||||
public class OreDictionaryEntry {
|
||||
private static List<OreDictionaryEntry> oreDictionaryEntries = new ArrayList<OreDictionaryEntry>();
|
||||
|
||||
/**
|
||||
* Get an OreDictionaryEntry instance, using an instance cache to preserve
|
||||
* reference equality.
|
||||
*
|
||||
* @param id opaque ore dictionary id
|
||||
* @return object wrapper around id
|
||||
*/
|
||||
public static OreDictionaryEntry valueOf(int id) {
|
||||
if (id < 0) throw new IllegalArgumentException("ore dictionary IDs are not negative");
|
||||
|
||||
while (oreDictionaryEntries.size() < id + 1) {
|
||||
oreDictionaryEntries.add(new OreDictionaryEntry(oreDictionaryEntries.size()));
|
||||
}
|
||||
return oreDictionaryEntries.get(id);
|
||||
}
|
||||
|
||||
private int id;
|
||||
private OreDictionaryEntry(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the opaque ID of this ore-dictionary entry.
|
||||
*
|
||||
* Plugins should not inspect the results of this call. Results may not be
|
||||
* the same across multiple server startups.
|
||||
*
|
||||
* @return Opaque id number.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the Ore Dictionary for the string identifier of this entry.
|
||||
*
|
||||
* @return ore dictionary string
|
||||
* @see net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary#getOreName(OreDictionaryEntry)
|
||||
*/
|
||||
public String getName() {
|
||||
return Cauldron.getOreDictionary().getOreName(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("OreDictionary{id=%d,name=%s}", id, getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.minecraftforge.cauldron.apiimpl;
|
||||
|
||||
import net.minecraftforge.cauldron.api.Cauldron;
|
||||
import net.minecraftforge.cauldron.api.CauldronApi;
|
||||
import net.minecraftforge.cauldron.api.Fishing;
|
||||
import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary;
|
||||
import net.minecraftforge.cauldron.apiimpl.inventory.OreDictionaryInterface;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
public class CauldronPluginInterface implements CauldronApi {
|
||||
private BukkitOreDictionary oreDictionary = new OreDictionaryInterface();
|
||||
private Fishing fishingInterface = new FishingInterface();
|
||||
|
||||
public void install() {
|
||||
Cauldron.setInterface(this);
|
||||
Bukkit.getServicesManager().register(CauldronApi.class, this, null, ServicePriority.Highest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitOreDictionary getOreDictionary() {
|
||||
return oreDictionary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fishing getFishingInterface() {
|
||||
return fishingInterface;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.minecraftforge.cauldron.apiimpl;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import net.minecraftforge.cauldron.api.Fishing;
|
||||
import net.minecraftforge.cauldron.api.WeightedRandomFishable;
|
||||
import net.minecraftforge.common.FishingHooks;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class FishingInterface implements Fishing {
|
||||
private static net.minecraft.util.WeightedRandomFishable toNms(WeightedRandomFishable bukkit) {
|
||||
net.minecraft.util.WeightedRandomFishable ret =
|
||||
new net.minecraft.util.WeightedRandomFishable(
|
||||
CraftItemStack.asNMSCopy(bukkit.getItemStack()),
|
||||
bukkit.getWeight()).func_150709_a(bukkit.getDamageFraction());
|
||||
if (bukkit.hasRandomEnchantments()) {
|
||||
ret.func_150707_a();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static WeightedRandomFishable toBukkit(net.minecraft.util.WeightedRandomFishable nms) {
|
||||
return new WeightedRandomFishable(CraftItemStack.asBukkitCopy(nms.field_150711_b), nms.itemWeight)
|
||||
.withDamageFraction(nms.field_150712_c)
|
||||
.withRandomEnchantments(nms.field_150710_d);
|
||||
}
|
||||
|
||||
private static class PredicateProxy implements Predicate<net.minecraft.util.WeightedRandomFishable> {
|
||||
private Predicate<WeightedRandomFishable> bukkitPredicate;
|
||||
|
||||
public PredicateProxy(Predicate<WeightedRandomFishable> predicate) {
|
||||
this.bukkitPredicate = predicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(net.minecraft.util.WeightedRandomFishable input) {
|
||||
return bukkitPredicate.apply(toBukkit(input));
|
||||
}
|
||||
}
|
||||
|
||||
private static PredicateProxy toNms(Predicate<WeightedRandomFishable> predicate) {
|
||||
return new PredicateProxy(predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFish(WeightedRandomFishable fish) {
|
||||
FishingHooks.addFish(toNms(fish));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addJunk(WeightedRandomFishable fish) {
|
||||
FishingHooks.addJunk(toNms(fish));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreasure(WeightedRandomFishable fish) {
|
||||
FishingHooks.addTreasure(toNms(fish));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMatchingFish(Predicate<WeightedRandomFishable> test) {
|
||||
FishingHooks.removeFish(toNms(test));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMatchingJunk(Predicate<WeightedRandomFishable> test) {
|
||||
FishingHooks.removeJunk(toNms(test));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMatchingTreasure(Predicate<WeightedRandomFishable> test) {
|
||||
FishingHooks.removeTreasure(toNms(test));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getRandomFishable(Random rand, float baseChance, int fishingLuckEnchantmentLevel, int fishingSpeedEnchantmentLevel) {
|
||||
return CraftItemStack.asCraftMirror(FishingHooks.getRandomFishable(rand, baseChance, fishingLuckEnchantmentLevel, fishingSpeedEnchantmentLevel));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package net.minecraftforge.cauldron.apiimpl.inventory;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary;
|
||||
import net.minecraftforge.cauldron.api.inventory.OreDictionaryEntry;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OreDictionaryInterface implements BukkitOreDictionary {
|
||||
private Map<String, String> normalizedToCanonicalMap = null;
|
||||
|
||||
private void initializeMap() {
|
||||
normalizedToCanonicalMap = new HashMap<String, String>();
|
||||
|
||||
for (String str : getAllOreNames()) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
normalizedToCanonicalMap.put(Material.normalizeName(str), str);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OreDictionaryEntry getOreEntry(String name) {
|
||||
if (normalizedToCanonicalMap == null) {
|
||||
initializeMap();
|
||||
}
|
||||
|
||||
String canonical = normalizedToCanonicalMap.get(Material.normalizeName(name));
|
||||
if (canonical == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return OreDictionaryEntry.valueOf(OreDictionary.getOreID(canonical));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OreDictionaryEntry> getOreEntries(ItemStack itemStack) {
|
||||
int[] ids = OreDictionary.getOreIDs(CraftItemStack.asNMSCopy(itemStack));
|
||||
|
||||
ImmutableList.Builder<OreDictionaryEntry> builder = ImmutableList.builder();
|
||||
for (int id : ids) {
|
||||
builder.add(OreDictionaryEntry.valueOf(id));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OreDictionaryEntry> getOreEntries(Material material) {
|
||||
return getOreEntries(new ItemStack(material));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOreName(OreDictionaryEntry entry) {
|
||||
return OreDictionary.getOreName(entry.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDefinitions(OreDictionaryEntry entry) {
|
||||
@SuppressWarnings("deprecation")
|
||||
List<net.minecraft.item.ItemStack> items = OreDictionary.getOres(entry.getId());
|
||||
|
||||
ImmutableList.Builder<ItemStack> builder = ImmutableList.builder();
|
||||
for (net.minecraft.item.ItemStack nmsItem : items) {
|
||||
builder.add(CraftItemStack.asCraftMirror(nmsItem));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllOreNames() {
|
||||
return Arrays.asList(OreDictionary.getOreNames());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.minecraftforge.cauldron.block;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public class CraftCustomContainer extends CraftBlockState implements InventoryHolder {
|
||||
private final CraftWorld world;
|
||||
private final net.minecraft.inventory.IInventory container;
|
||||
|
||||
public CraftCustomContainer(Block block) {
|
||||
super(block);
|
||||
world = (CraftWorld) block.getWorld();
|
||||
container = (IInventory)world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
CraftInventory inventory = new CraftInventory(container);
|
||||
return inventory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
package net.minecraftforge.cauldron.command;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.cauldron.CauldronHooks;
|
||||
import net.minecraftforge.cauldron.configuration.BoolSetting;
|
||||
import net.minecraftforge.cauldron.configuration.IntSetting;
|
||||
import net.minecraftforge.cauldron.configuration.Setting;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class CauldronCommand extends Command
|
||||
{
|
||||
private static final List<String> COMMANDS = ImmutableList.of("get", "set", "tick-interval", "save", "reload", "chunks", "heap");
|
||||
private static final List<String> CHUNK_COMMANDS = ImmutableList.of("print", "dump");
|
||||
|
||||
public CauldronCommand()
|
||||
{
|
||||
super("cauldron");
|
||||
this.description = "Toggle certain Cauldron options";
|
||||
|
||||
this.usageMessage = "/cauldron [" + StringUtils.join(COMMANDS, '|') + "] <option> [value]";
|
||||
this.setPermission("cauldron.command.cauldron");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args)
|
||||
{
|
||||
if (!testPermission(sender))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((args.length > 0) && "heap".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
processHeap(sender, args);
|
||||
return true;
|
||||
}
|
||||
if ((args.length > 0) && "chunks".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
processChunks(sender, args);
|
||||
return true;
|
||||
}
|
||||
if ((args.length == 1) && "save".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
MinecraftServer.getServer().cauldronConfig.save();
|
||||
sender.sendMessage(ChatColor.GREEN + "Config file saved");
|
||||
return true;
|
||||
}
|
||||
if ((args.length == 1) && "reload".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
MinecraftServer.getServer().cauldronConfig.load();
|
||||
for (int i = 0; i < MinecraftServer.getServer().worlds.size(); i++)
|
||||
{
|
||||
MinecraftServer.getServer().worlds.get(i).cauldronConfig.init(); // reload world configs
|
||||
}
|
||||
sender.sendMessage(ChatColor.GREEN + "Config file reloaded");
|
||||
return true;
|
||||
}
|
||||
if (args.length < 2)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("tick-interval".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return intervalSet(sender, args);
|
||||
}
|
||||
if ("get".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return getToggle(sender, args);
|
||||
}
|
||||
else if ("set".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return setToggle(sender, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processHeap(CommandSender sender, String[] args)
|
||||
{
|
||||
File file = new File(new File(new File("."), "dumps"), "heap-dump-" + new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()) + "-server.bin");
|
||||
sender.sendMessage("Writing chunk info to: " + file);
|
||||
CauldronHooks.dumpHeap(file, true);
|
||||
sender.sendMessage("Chunk info complete");
|
||||
}
|
||||
|
||||
private void processChunks(CommandSender sender, String[] args)
|
||||
{
|
||||
sender.sendMessage(ChatColor.GOLD + "Dimension stats: ");
|
||||
for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds)
|
||||
{
|
||||
sender.sendMessage(ChatColor.GOLD + "Dimension: " + ChatColor.GRAY + world.provider.dimensionId +
|
||||
ChatColor.GOLD + " Loaded Chunks: " + ChatColor.GRAY + world.theChunkProviderServer.loadedChunkHashMap.size() +
|
||||
ChatColor.GOLD + " Active Chunks: " + ChatColor.GRAY + world.activeChunkSet.size() +
|
||||
ChatColor.GOLD + " Entities: " + ChatColor.GRAY + world.loadedEntityList.size() +
|
||||
ChatColor.GOLD + " Tile Entities: " + ChatColor.GRAY + world.loadedTileEntityList.size()
|
||||
);
|
||||
sender.sendMessage(ChatColor.GOLD + " Entities Last Tick: " + ChatColor.GRAY + world.entitiesTicked +
|
||||
ChatColor.GOLD + " Tiles Last Tick: " + ChatColor.GRAY + world.tilesTicked +
|
||||
ChatColor.GOLD + " Removed Entities: " + ChatColor.GRAY + world.unloadedEntityList.size() +
|
||||
ChatColor.GOLD + " Removed Tile Entities: " + ChatColor.GRAY + world.field_147483_b.size()
|
||||
);
|
||||
}
|
||||
|
||||
if ((args.length < 2) || !"dump".equalsIgnoreCase(args[1]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
boolean dumpAll = ((args.length > 2) && "all".equalsIgnoreCase(args[2]));
|
||||
|
||||
File file = new File(new File(new File("."), "chunk-dumps"), "chunk-info-" + new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()) + "-server.txt");
|
||||
sender.sendMessage("Writing chunk info to: " + file);
|
||||
CauldronHooks.writeChunks(file, dumpAll);
|
||||
sender.sendMessage("Chunk info complete");
|
||||
}
|
||||
|
||||
private boolean getToggle(CommandSender sender, String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Setting toggle = MinecraftServer.getServer().cauldronConfig.getSettings().get(args[1]);
|
||||
// check config directly
|
||||
if (toggle == null && MinecraftServer.getServer().cauldronConfig.isSet(args[1]))
|
||||
{
|
||||
if (MinecraftServer.getServer().cauldronConfig.isBoolean(args[1]))
|
||||
{
|
||||
toggle = new BoolSetting(MinecraftServer.getServer().cauldronConfig, args[1], MinecraftServer.getServer().cauldronConfig.getBoolean(args[1], false), "");
|
||||
}
|
||||
else if (MinecraftServer.getServer().cauldronConfig.isInt(args[1]))
|
||||
{
|
||||
toggle = new IntSetting(MinecraftServer.getServer().cauldronConfig, args[1], MinecraftServer.getServer().cauldronConfig.getInt(args[1], 1), "");
|
||||
}
|
||||
if (toggle != null)
|
||||
{
|
||||
MinecraftServer.getServer().cauldronConfig.getSettings().put(toggle.path, toggle);
|
||||
MinecraftServer.getServer().cauldronConfig.load();
|
||||
}
|
||||
}
|
||||
if (toggle == null)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Could not find option: " + args[1]);
|
||||
return false;
|
||||
}
|
||||
Object value = toggle.getValue();
|
||||
String option = (Boolean.TRUE.equals(value) ? ChatColor.GREEN : ChatColor.RED) + " " + value;
|
||||
sender.sendMessage(ChatColor.GOLD + args[1] + " " + option);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean intervalSet(CommandSender sender, String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
int setting = NumberUtils.toInt(args[2], 1);
|
||||
MinecraftServer.getServer().cauldronConfig.set(args[1], setting);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setToggle(CommandSender sender, String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Setting toggle = MinecraftServer.getServer().cauldronConfig.getSettings().get(args[1]);
|
||||
// check config directly
|
||||
if (toggle == null && MinecraftServer.getServer().cauldronConfig.isSet(args[1]))
|
||||
{
|
||||
toggle = new BoolSetting(MinecraftServer.getServer().cauldronConfig, args[1], MinecraftServer.getServer().cauldronConfig.getBoolean(args[1], false), "");
|
||||
MinecraftServer.getServer().cauldronConfig.getSettings().put(toggle.path, toggle);
|
||||
MinecraftServer.getServer().cauldronConfig.load();
|
||||
}
|
||||
if (toggle == null)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Could not find option: " + args[1]);
|
||||
return false;
|
||||
}
|
||||
if (args.length == 2)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + args[0] + " " + args[1] + " [value]");
|
||||
return false;
|
||||
}
|
||||
toggle.setValue(args[2]);
|
||||
Object value = toggle.getValue();
|
||||
String option = (Boolean.TRUE.equals(value) ? ChatColor.GREEN : ChatColor.RED) + " " + value;
|
||||
sender.sendMessage(ChatColor.GOLD + args[1] + " " + option);
|
||||
// Special case for load-on-request
|
||||
if (toggle == MinecraftServer.getServer().cauldronConfig.loadChunkOnRequest)
|
||||
{
|
||||
for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds)
|
||||
{
|
||||
world.theChunkProviderServer.loadChunkOnProvideRequest = MinecraftServer.getServer().cauldronConfig.loadChunkOnRequest.getValue();
|
||||
}
|
||||
}
|
||||
MinecraftServer.getServer().cauldronConfig.save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args)
|
||||
{
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
|
||||
if (args.length == 1)
|
||||
{
|
||||
return StringUtil.copyPartialMatches(args[0], COMMANDS, new ArrayList<String>(COMMANDS.size()));
|
||||
}
|
||||
if (((args.length == 2) && "get".equalsIgnoreCase(args[0])) || "set".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return StringUtil.copyPartialMatches(args[1], MinecraftServer.getServer().cauldronConfig.getSettings().keySet(), new ArrayList<String>(MinecraftServer.getServer().cauldronConfig.getSettings().size()));
|
||||
}
|
||||
else if ((args.length == 2) && "chunks".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return StringUtil.copyPartialMatches(args[1], CHUNK_COMMANDS, new ArrayList<String>(CHUNK_COMMANDS.size()));
|
||||
}
|
||||
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package net.minecraftforge.cauldron.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.cauldron.configuration.BoolSetting;
|
||||
import net.minecraftforge.cauldron.configuration.IntSetting;
|
||||
import net.minecraftforge.cauldron.configuration.Setting;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class TileEntityCommand extends Command
|
||||
{
|
||||
private static final List<String> COMMANDS = ImmutableList.of("get", "set", "save", "reload");
|
||||
|
||||
public TileEntityCommand()
|
||||
{
|
||||
super("cauldron_te");
|
||||
this.description = "Toggle certain TileEntity options";
|
||||
|
||||
this.usageMessage = "/cauldron_te [" + StringUtils.join(COMMANDS, '|') + "] <option> [value]";
|
||||
this.setPermission("cauldron.command.cauldron_te");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args)
|
||||
{
|
||||
if (!testPermission(sender))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((args.length == 1) && "save".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
MinecraftServer.getServer().tileEntityConfig.save();
|
||||
sender.sendMessage(ChatColor.GREEN + "Config file saved");
|
||||
return true;
|
||||
}
|
||||
if ((args.length == 1) && "reload".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
MinecraftServer.getServer().tileEntityConfig.load();
|
||||
sender.sendMessage(ChatColor.GREEN + "Config file reloaded");
|
||||
return true;
|
||||
}
|
||||
if (args.length < 2)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("get".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return getToggle(sender, args);
|
||||
}
|
||||
else if ("set".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return setToggle(sender, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean getToggle(CommandSender sender, String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Setting toggle = MinecraftServer.getServer().tileEntityConfig.getSettings().get(args[1]);
|
||||
// check config directly
|
||||
if (toggle == null && MinecraftServer.getServer().tileEntityConfig.isSet(args[1]))
|
||||
{
|
||||
if (MinecraftServer.getServer().tileEntityConfig.isBoolean(args[1]))
|
||||
{
|
||||
toggle = new BoolSetting(MinecraftServer.getServer().tileEntityConfig, args[1], MinecraftServer.getServer().tileEntityConfig.getBoolean(args[1], false), "");
|
||||
}
|
||||
else if (MinecraftServer.getServer().tileEntityConfig.isInt(args[1]))
|
||||
{
|
||||
toggle = new IntSetting(MinecraftServer.getServer().tileEntityConfig, args[1], MinecraftServer.getServer().tileEntityConfig.getInt(args[1], 1), "");
|
||||
}
|
||||
if (toggle != null)
|
||||
{
|
||||
MinecraftServer.getServer().tileEntityConfig.getSettings().put(toggle.path, toggle);
|
||||
MinecraftServer.getServer().tileEntityConfig.load();
|
||||
}
|
||||
}
|
||||
if (toggle == null)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Could not find option: " + args[1]);
|
||||
return false;
|
||||
}
|
||||
Object value = toggle.getValue();
|
||||
String option = (Boolean.TRUE.equals(value) ? ChatColor.GREEN : ChatColor.RED) + " " + value;
|
||||
sender.sendMessage(ChatColor.GOLD + args[1] + " " + option);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean intervalSet(CommandSender sender, String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
int setting = NumberUtils.toInt(args[2], 1);
|
||||
MinecraftServer.getServer().tileEntityConfig.set(args[1], setting);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setToggle(CommandSender sender, String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Setting toggle = MinecraftServer.getServer().tileEntityConfig.getSettings().get(args[1]);
|
||||
// check config directly
|
||||
if (toggle == null && MinecraftServer.getServer().tileEntityConfig.isSet(args[1]))
|
||||
{
|
||||
toggle = new BoolSetting(MinecraftServer.getServer().tileEntityConfig, args[1], MinecraftServer.getServer().tileEntityConfig.getBoolean(args[1], false), "");
|
||||
MinecraftServer.getServer().tileEntityConfig.getSettings().put(toggle.path, toggle);
|
||||
MinecraftServer.getServer().tileEntityConfig.load();
|
||||
}
|
||||
if (toggle == null)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Could not find option: " + args[1]);
|
||||
return false;
|
||||
}
|
||||
if (args.length == 2)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + args[0] + " " + args[1] + " [value]");
|
||||
return false;
|
||||
}
|
||||
toggle.setValue(args[2]);
|
||||
Object value = toggle.getValue();
|
||||
String option = (Boolean.TRUE.equals(value) ? ChatColor.GREEN : ChatColor.RED) + " " + value;
|
||||
sender.sendMessage(ChatColor.GOLD + args[1] + " " + option);
|
||||
MinecraftServer.getServer().tileEntityConfig.save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args)
|
||||
{
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
|
||||
if (args.length == 1)
|
||||
{
|
||||
return StringUtil.copyPartialMatches(args[0], COMMANDS, new ArrayList<String>(COMMANDS.size()));
|
||||
}
|
||||
if (((args.length == 2) && "get".equalsIgnoreCase(args[0])) || "set".equalsIgnoreCase(args[0]))
|
||||
{
|
||||
return StringUtil.copyPartialMatches(args[1], MinecraftServer.getServer().tileEntityConfig.getSettings().keySet(), new ArrayList<String>(MinecraftServer.getServer().tileEntityConfig.getSettings().size()));
|
||||
}
|
||||
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
|
||||
public class BoolSetting extends Setting<Boolean>
|
||||
{
|
||||
private Boolean value;
|
||||
private ConfigBase config;
|
||||
|
||||
public BoolSetting(ConfigBase config, String path, Boolean def, String description)
|
||||
{
|
||||
super(path, def, description);
|
||||
this.value = def;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value)
|
||||
{
|
||||
this.value = BooleanUtils.toBooleanObject(value);
|
||||
this.value = this.value == null ? def : this.value;
|
||||
config.set(path, this.value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.cauldron.command.CauldronCommand;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class CauldronConfig extends ConfigBase
|
||||
{
|
||||
private final String HEADER = "This is the main configuration file for Cauldron.\n"
|
||||
+ "\n"
|
||||
+ "If you need help with the configuration or have any questions related to Cauldron,\n"
|
||||
+ "join us at the IRC or drop by our forums and leave a post.\n"
|
||||
+ "\n"
|
||||
+ "IRC: #cauldron @ irc.esper.net ( http://webchat.esper.net/?channel=cauldron )\n"
|
||||
+ "Forums: http://cauldron.minecraftforge.net/\n";
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
// Logging options
|
||||
public final BoolSetting dumpMaterials = new BoolSetting(this, "settings.dump-materials", false, "Dumps all materials with their corresponding id's");
|
||||
public final BoolSetting disableWarnings = new BoolSetting(this, "logging.disabled-warnings", false, "Disable warning messages to server admins");
|
||||
public final BoolSetting worldLeakDebug = new BoolSetting(this, "logging.world-leak-debug", false, "Log worlds that appear to be leaking (buggy)");
|
||||
public final BoolSetting connectionLogging = new BoolSetting(this, "logging.connection", false, "Log connections");
|
||||
public final BoolSetting tickIntervalLogging = new BoolSetting(this, "logging.tick-intervals", false, "Log when skip interval handlers are ticked");
|
||||
public final BoolSetting chunkLoadLogging = new BoolSetting(this, "logging.chunk-load", false, "Log when chunks are loaded (dev)");
|
||||
public final BoolSetting chunkUnloadLogging = new BoolSetting(this, "logging.chunk-unload", false, "Log when chunks are unloaded (dev)");
|
||||
public final BoolSetting entitySpawnLogging = new BoolSetting(this, "logging.entity-spawn", false, "Log when living entities are spawned (dev)");
|
||||
public final BoolSetting entityDespawnLogging = new BoolSetting(this, "logging.entity-despawn", false, "Log when living entities are despawned (dev)");
|
||||
public final BoolSetting entityDeathLogging = new BoolSetting(this, "logging.entity-death", false, "Log when an entity is destroyed (dev)");
|
||||
public final BoolSetting logWithStackTraces = new BoolSetting(this, "logging.detailed-logging", false, "Add stack traces to dev logging");
|
||||
public final BoolSetting dumpChunksOnDeadlock = new BoolSetting(this, "logging.dump-chunks-on-deadlock", false, "Dump chunks in the event of a deadlock (helps to debug the deadlock)");
|
||||
public final BoolSetting dumpHeapOnDeadlock = new BoolSetting(this, "logging.dump-heap-on-deadlock", false, "Dump the heap in the event of a deadlock (helps to debug the deadlock)");
|
||||
public final BoolSetting dumpThreadsOnWarn = new BoolSetting(this, "logging.dump-threads-on-warn", false, "Dump the the server thread on deadlock warning (delps to debug the deadlock)");
|
||||
public final BoolSetting logEntityCollisionChecks = new BoolSetting(this, "logging.entity-collision-checks", false, "Whether to log entity collision/count checks");
|
||||
public final BoolSetting logEntitySpeedRemoval = new BoolSetting(this, "logging.entity-speed-removal", false, "Whether to log entity removals due to speed");
|
||||
public final IntSetting largeCollisionLogSize = new IntSetting(this, "logging.collision-warn-size", 200, "Number of colliding entities in one spot before logging a warning. Set to 0 to disable");
|
||||
public final IntSetting largeEntityCountLogSize = new IntSetting(this, "logging.entity-count-warn-size", 0, "Number of entities in one dimension logging a warning. Set to 0 to disable");
|
||||
|
||||
// General settings
|
||||
public final BoolSetting loadChunkOnRequest = new BoolSetting(this, "settings.load-chunk-on-request", true, "Forces Chunk Loading on 'Provide' requests (speedup for mods that don't check if a chunk is loaded");
|
||||
public final BoolSetting loadChunkOnForgeTick = new BoolSetting(this, "settings.load-chunk-on-forge-tick", false, "Forces Chunk Loading during Forge Server Tick events");
|
||||
public final BoolSetting checkEntityBoundingBoxes = new BoolSetting(this, "settings.check-entity-bounding-boxes", true, "Removes a living entity that exceeds the max bounding box size.");
|
||||
public final BoolSetting checkEntityMaxSpeeds = new BoolSetting(this, "settings.check-entity-max-speeds", false, "Removes any entity that exceeds max speed.");
|
||||
public final IntSetting largeBoundingBoxLogSize = new IntSetting(this, "settings.entity-bounding-box-max-size", 1000, "Max size of an entity's bounding box before removing it (either being too large or bugged and 'moving' too fast)");
|
||||
public final IntSetting entityMaxSpeed = new IntSetting(this, "settings.entity-max-speed", 100, "Square of the max speed of an entity before removing it");
|
||||
|
||||
// Debug settings
|
||||
public final BoolSetting enableThreadContentionMonitoring = new BoolSetting(this, "debug.thread-contention-monitoring", false, "Set true to enable Java's thread contention monitoring for thread dumps");
|
||||
|
||||
// Server options
|
||||
public final BoolSetting infiniteWaterSource = new BoolSetting(this, "world-settings.default.infinite-water-source", true, "Vanilla water source behavior - is infinite");
|
||||
public final BoolSetting flowingLavaDecay = new BoolSetting(this, "world-settings.default.flowing-lava-decay", false, "Lava behaves like vanilla water when source block is removed");
|
||||
public final BoolSetting fakePlayerLogin = new BoolSetting(this, "fake-players.do-login", false, "Raise login events for fake players");
|
||||
|
||||
// Plug-in options
|
||||
public final BoolSetting remapPluginFile = new BoolSetting(this, "plugin-settings.default.remap-plugin-file", false, "Remap the plugin file (dev)");
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
public CauldronConfig(String fileName, String commandName)
|
||||
{
|
||||
super(fileName, commandName);
|
||||
init();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
settings.put(dumpMaterials.path, dumpMaterials);
|
||||
settings.put(disableWarnings.path, disableWarnings);
|
||||
settings.put(worldLeakDebug.path, worldLeakDebug);
|
||||
settings.put(connectionLogging.path, connectionLogging);
|
||||
settings.put(tickIntervalLogging.path, tickIntervalLogging);
|
||||
settings.put(chunkLoadLogging.path, chunkLoadLogging);
|
||||
settings.put(chunkUnloadLogging.path, chunkUnloadLogging);
|
||||
settings.put(entitySpawnLogging.path, entitySpawnLogging);
|
||||
settings.put(entityDespawnLogging.path, entityDespawnLogging);
|
||||
settings.put(entityDeathLogging.path, entityDeathLogging);
|
||||
settings.put(logWithStackTraces.path, logWithStackTraces);
|
||||
settings.put(dumpChunksOnDeadlock.path, dumpChunksOnDeadlock);
|
||||
settings.put(dumpHeapOnDeadlock.path, dumpHeapOnDeadlock);
|
||||
settings.put(dumpThreadsOnWarn.path, dumpThreadsOnWarn);
|
||||
settings.put(logEntityCollisionChecks.path, logEntityCollisionChecks);
|
||||
settings.put(logEntitySpeedRemoval.path, logEntitySpeedRemoval);
|
||||
settings.put(largeCollisionLogSize.path, largeCollisionLogSize);
|
||||
settings.put(largeEntityCountLogSize.path, largeEntityCountLogSize);
|
||||
settings.put(loadChunkOnRequest.path, loadChunkOnRequest);
|
||||
settings.put(loadChunkOnForgeTick.path, loadChunkOnForgeTick);
|
||||
settings.put(checkEntityBoundingBoxes.path, checkEntityBoundingBoxes);
|
||||
settings.put(checkEntityMaxSpeeds.path, checkEntityMaxSpeeds);
|
||||
settings.put(largeBoundingBoxLogSize.path, largeBoundingBoxLogSize);
|
||||
settings.put(enableThreadContentionMonitoring.path, enableThreadContentionMonitoring);
|
||||
settings.put(infiniteWaterSource.path, infiniteWaterSource);
|
||||
settings.put(flowingLavaDecay.path, flowingLavaDecay);
|
||||
settings.put(fakePlayerLogin.path, fakePlayerLogin);
|
||||
settings.put(remapPluginFile.path, remapPluginFile);
|
||||
load();
|
||||
}
|
||||
|
||||
public void addCommands()
|
||||
{
|
||||
commands.put(this.commandName, new CauldronCommand());
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
try
|
||||
{
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
String header = HEADER + "\n";
|
||||
for (Setting toggle : settings.values())
|
||||
{
|
||||
if (!toggle.description.equals(""))
|
||||
header += "Setting: " + toggle.path + " Default: " + toggle.def + " # " + toggle.description + "\n";
|
||||
|
||||
config.addDefault(toggle.path, toggle.def);
|
||||
settings.get(toggle.path).setValue(config.getString(toggle.path));
|
||||
}
|
||||
config.options().header(header);
|
||||
config.options().copyDefaults(true);
|
||||
|
||||
version = getInt("config-version", 1);
|
||||
set("config-version", 1);
|
||||
|
||||
this.saveWorldConfigs();
|
||||
this.save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("Could not load " + this.configFile);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
public class CauldronWorldConfig extends WorldConfig
|
||||
{
|
||||
public boolean entityDespawnImmediate = true;
|
||||
|
||||
public CauldronWorldConfig(String worldName, ConfigBase configFile)
|
||||
{
|
||||
super(worldName, configFile);
|
||||
init();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
entityDespawnImmediate = getBoolean( "entity-despawn-immediate", true);
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.cauldron.CauldronHooks;
|
||||
import net.minecraftforge.cauldron.TileEntityCache;
|
||||
import net.minecraftforge.cauldron.command.CauldronCommand;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
public abstract class ConfigBase
|
||||
{
|
||||
protected final File configFile;
|
||||
protected final String commandName;
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
protected YamlConfiguration config;
|
||||
protected int version;
|
||||
protected Map<String, Command> commands;
|
||||
protected Map<String, Setting> settings = new HashMap<String, Setting>();
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
public ConfigBase(String fileName, String commandName)
|
||||
{
|
||||
this.configFile = new File(fileName);
|
||||
this.config = YamlConfiguration.loadConfiguration(configFile);
|
||||
this.commandName = commandName;
|
||||
this.commands = new HashMap<String, Command>();
|
||||
this.addCommands();
|
||||
}
|
||||
|
||||
protected abstract void addCommands();
|
||||
|
||||
public Map<String, Setting> getSettings()
|
||||
{
|
||||
return settings;
|
||||
}
|
||||
|
||||
public void registerCommands()
|
||||
{
|
||||
for (Map.Entry<String, Command> entry : commands.entrySet())
|
||||
{
|
||||
MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), this.commandName, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
try
|
||||
{
|
||||
config.save(configFile);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("Could not save " + configFile);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveWorldConfigs()
|
||||
{
|
||||
for (int i = 0; i < MinecraftServer.getServer().worlds.size(); ++i)
|
||||
{
|
||||
WorldServer worldserver = MinecraftServer.getServer().worlds.get(i);
|
||||
|
||||
if (worldserver != null)
|
||||
{
|
||||
if (worldserver.cauldronConfig != null)
|
||||
{
|
||||
worldserver.cauldronConfig.save();
|
||||
}
|
||||
if (worldserver.tileentityConfig != null)
|
||||
{
|
||||
worldserver.tileentityConfig.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void load();
|
||||
|
||||
public void set(String path, Object val)
|
||||
{
|
||||
config.set(path, val);
|
||||
}
|
||||
|
||||
public boolean isSet(String path)
|
||||
{
|
||||
return config.isSet(path);
|
||||
}
|
||||
|
||||
public boolean isInt(String path)
|
||||
{
|
||||
return config.isInt(path);
|
||||
}
|
||||
|
||||
public boolean isBoolean(String path)
|
||||
{
|
||||
return config.isBoolean(path);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path)
|
||||
{
|
||||
return config.getBoolean(path);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path, boolean def)
|
||||
{
|
||||
return getBoolean(path, def, true);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path, boolean def, boolean useDefault)
|
||||
{
|
||||
if (useDefault)
|
||||
{
|
||||
config.addDefault(path, def);
|
||||
}
|
||||
return config.getBoolean(path, def);
|
||||
}
|
||||
|
||||
public int getInt(String path)
|
||||
{
|
||||
return config.getInt(path);
|
||||
}
|
||||
|
||||
public int getInt(String path, int def)
|
||||
{
|
||||
config.addDefault(path, def);
|
||||
return config.getInt(path, config.getInt(path));
|
||||
}
|
||||
|
||||
private <T> List getList(String path, T def)
|
||||
{
|
||||
config.addDefault(path, def);
|
||||
return config.getList(path, config.getList(path));
|
||||
}
|
||||
|
||||
public String getString(String path, String def)
|
||||
{
|
||||
return getString(path, def, true);
|
||||
}
|
||||
|
||||
public String getString(String path, String def, boolean useDefault)
|
||||
{
|
||||
if (useDefault)
|
||||
{
|
||||
config.addDefault(path, def);
|
||||
}
|
||||
return config.getString(path, def);
|
||||
}
|
||||
|
||||
public String getFakePlayer(String className, String defaultName)
|
||||
{
|
||||
return getString("fake-players." + className + ".username", defaultName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
public class IntSetting extends Setting<Integer>
|
||||
{
|
||||
private Integer value;
|
||||
private ConfigBase config;
|
||||
|
||||
public IntSetting(ConfigBase config, String path, Integer def, String description)
|
||||
{
|
||||
super(path, def, description);
|
||||
this.value = def;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value)
|
||||
{
|
||||
this.value = org.apache.commons.lang.math.NumberUtils.toInt(value, def);
|
||||
config.set(path, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
|
||||
public abstract class Setting<T>
|
||||
{
|
||||
public final String path;
|
||||
public final T def;
|
||||
public final String description;
|
||||
|
||||
public Setting(String path, T def, String description)
|
||||
{
|
||||
this.path = path;
|
||||
this.def = def;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public abstract T getValue();
|
||||
|
||||
public abstract void setValue(String value);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.cauldron.CauldronHooks;
|
||||
import net.minecraftforge.cauldron.TileEntityCache;
|
||||
import net.minecraftforge.cauldron.command.TileEntityCommand;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class TileEntityConfig extends ConfigBase
|
||||
{
|
||||
private final String HEADER = "This is the main configuration file for TileEntities.\n"
|
||||
+ "\n"
|
||||
+ "If you need help with the configuration or have any questions related to Cauldron,\n"
|
||||
+ "join us at the IRC or drop by our forums and leave a post.\n"
|
||||
+ "\n"
|
||||
+ "IRC: #cauldron @ irc.esper.net ( http://webchat.esper.net/?channel=cauldron )\n"
|
||||
+ "Forums: http://cauldron.minecraftforge.net/\n";
|
||||
|
||||
/* ======================================================================== */
|
||||
public final BoolSetting skipTileEntityTicks = new BoolSetting(this, "settings.skip-tileentity-ticks", true, "If enabled, turns on tileentity tick skip feature when no players are near.");
|
||||
public final BoolSetting enableTECanUpdateWarning = new BoolSetting(this, "debug.enable-te-can-update-warning", false, "Set true to detect which tileentities should not be ticking.");
|
||||
public final BoolSetting enableTEInventoryWarning = new BoolSetting(this, "debug.enable-te-inventory-warning", false, "Set true to detect which tileentities with inventory failed to detect size for Bukkit's InventoryType enum. Note: This may detect a false-positive.");
|
||||
public final BoolSetting enableTEPlaceWarning = new BoolSetting(this, "debug.enable-te-place-warning", false, "Warn when a mod requests tile entity from a block that doesn't support one");
|
||||
public final BoolSetting preventInvalidTileEntityUpdates = new BoolSetting(this, "settings.prevent-invalid-tileentity-updates", true, "Used to determine if a tileentity should tick and if not the TE is added to a ban list. Note: This should help improve performance.");
|
||||
/* ======================================================================== */
|
||||
|
||||
public TileEntityConfig(String fileName, String commandName)
|
||||
{
|
||||
super(fileName, commandName);
|
||||
init();
|
||||
}
|
||||
|
||||
public void addCommands()
|
||||
{
|
||||
commands.put(this.commandName, new TileEntityCommand());
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
settings.put(skipTileEntityTicks.path, skipTileEntityTicks);
|
||||
settings.put(enableTECanUpdateWarning.path, enableTECanUpdateWarning);
|
||||
settings.put(enableTEInventoryWarning.path, enableTEInventoryWarning);
|
||||
settings.put(enableTEPlaceWarning.path, enableTEPlaceWarning);
|
||||
settings.put(preventInvalidTileEntityUpdates.path, preventInvalidTileEntityUpdates);
|
||||
load();
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
try
|
||||
{
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
String header = HEADER + "\n";
|
||||
for (Setting toggle : settings.values())
|
||||
{
|
||||
if (!toggle.description.equals(""))
|
||||
header += "Setting: " + toggle.path + " Default: " + toggle.def + " # " + toggle.description + "\n";
|
||||
|
||||
config.addDefault(toggle.path, toggle.def);
|
||||
settings.get(toggle.path).setValue(config.getString(toggle.path));
|
||||
}
|
||||
config.options().header(header);
|
||||
config.options().copyDefaults(true);
|
||||
|
||||
version = getInt("config-version", 1);
|
||||
set("config-version", 1);
|
||||
|
||||
for (TileEntityCache teCache : CauldronHooks.tileEntityCache.values())
|
||||
{
|
||||
teCache.tickNoPlayers = config.getBoolean( "world-settings." + teCache.worldName + "." + teCache.configPath + ".tick-no-players", config.getBoolean( "world-settings.default." + teCache.configPath + ".tick-no-players") );
|
||||
teCache.tickInterval = config.getInt( "world-settings." + teCache.worldName + "." + teCache.configPath + ".tick-interval", config.getInt( "world-settings.default." + teCache.configPath + ".tick-interval") );
|
||||
}
|
||||
this.saveWorldConfigs();
|
||||
this.save();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MinecraftServer.getServer().logSevere("Could not load " + this.configFile);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
public class TileEntityWorldConfig extends WorldConfig
|
||||
{
|
||||
public TileEntityWorldConfig(String worldName, ConfigBase configFile)
|
||||
{
|
||||
super(worldName, configFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package net.minecraftforge.cauldron.configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class WorldConfig
|
||||
{
|
||||
private final String worldName;
|
||||
public ConfigBase baseConfig;
|
||||
private boolean verbose;
|
||||
|
||||
public WorldConfig(String worldName, ConfigBase configFile)
|
||||
{
|
||||
this.worldName = worldName.toLowerCase();
|
||||
this.baseConfig = configFile;
|
||||
if (worldName.toLowerCase().contains("dummy")) return;
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
baseConfig.save();
|
||||
}
|
||||
|
||||
private void log(String s)
|
||||
{
|
||||
if ( verbose )
|
||||
{
|
||||
MinecraftServer.getServer().logInfo( s );
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String path, Object val)
|
||||
{
|
||||
baseConfig.config.set( path, val );
|
||||
}
|
||||
|
||||
public boolean isBoolean(String path)
|
||||
{
|
||||
return baseConfig.config.isBoolean(path);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path, boolean def)
|
||||
{
|
||||
if (baseConfig.settings.get("world-settings.default." + path) == null)
|
||||
{
|
||||
baseConfig.settings.put("world-settings.default." + path, new BoolSetting(baseConfig, "world-settings.default." + path, def, ""));
|
||||
}
|
||||
|
||||
baseConfig.config.addDefault( "world-settings.default." + path, def );
|
||||
return baseConfig.config.getBoolean( "world-settings." + worldName + "." + path, baseConfig.config.getBoolean( "world-settings.default." + path ) );
|
||||
}
|
||||
|
||||
private double getDouble(String path, double def)
|
||||
{
|
||||
baseConfig.config.addDefault( "world-settings.default." + path, def );
|
||||
return baseConfig.config.getDouble( "world-settings." + worldName + "." + path, baseConfig.config.getDouble( "world-settings.default." + path ) );
|
||||
}
|
||||
|
||||
public int getInt(String path, int def)
|
||||
{
|
||||
if (baseConfig.settings.get("world-settings.default." + path) == null)
|
||||
{
|
||||
baseConfig.settings.put("world-settings.default." + path, new IntSetting(baseConfig, "world-settings.default." + path, def, ""));
|
||||
}
|
||||
|
||||
baseConfig.config.addDefault( "world-settings.default." + path, def );
|
||||
return baseConfig.config.getInt( "world-settings." + worldName + "." + path, baseConfig.config.getInt( "world-settings.default." + path ) );
|
||||
}
|
||||
|
||||
private <T> List getList(String path, T def)
|
||||
{
|
||||
baseConfig.config.addDefault( "world-settings.default." + path, def );
|
||||
return (List<T>) baseConfig.config.getList( "world-settings." + worldName + "." + path, baseConfig.config.getList( "world-settings.default." + path ) );
|
||||
}
|
||||
|
||||
private String getString(String path, String def)
|
||||
{
|
||||
baseConfig.config.addDefault( "world-settings.default." + path, def );
|
||||
return baseConfig.config.getString( "world-settings." + worldName + "." + path, baseConfig.config.getString( "world-settings.default." + path ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.minecraftforge.cauldron.entity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import cpw.mods.fml.common.registry.EntityRegistry;
|
||||
|
||||
public class CraftCustomEntity extends CraftEntity {
|
||||
|
||||
public Class<? extends Entity> entityClass;
|
||||
public String entityName;
|
||||
|
||||
public CraftCustomEntity(CraftServer server, net.minecraft.entity.Entity entity) {
|
||||
super(server, entity);
|
||||
this.entityClass = entity.getClass();
|
||||
this.entityName = EntityRegistry.getCustomEntityTypeName(entityClass);
|
||||
if (entityName == null)
|
||||
entityName = entity.getCommandSenderName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.entity.Entity getHandle() {
|
||||
return (net.minecraft.entity.Entity) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.entityName;
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
EntityType type = EntityType.fromName(this.entityName);
|
||||
if (type != null)
|
||||
return type;
|
||||
else return EntityType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.minecraftforge.cauldron.inventory;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
|
||||
public class CraftCustomInventory extends CraftInventory {
|
||||
|
||||
public CraftCustomInventory(IInventory inventory) {
|
||||
super(inventory);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.minecraftforge.cauldron.inventory;
|
||||
|
||||
import net.minecraft.inventory.Container;
|
||||
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class CraftCustomInventoryView extends CraftInventoryView {
|
||||
|
||||
public CraftCustomInventoryView(HumanEntity player, Inventory viewing,
|
||||
Container container) {
|
||||
super(player, viewing, container);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.minecraftforge.cauldron.inventory;
|
||||
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
|
||||
/**
|
||||
* Bukkit API wrapper for non-vanilla IRecipe classes
|
||||
*/
|
||||
public class CustomModRecipe implements Recipe {
|
||||
private IRecipe iRecipe;
|
||||
|
||||
public CustomModRecipe(IRecipe iRecipe) {
|
||||
this.iRecipe = iRecipe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getResult() {
|
||||
return CraftItemStack.asCraftMirror(iRecipe.getRecipeOutput());
|
||||
}
|
||||
|
||||
public IRecipe getHandle() {
|
||||
return iRecipe;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache license, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the license for the specific language governing permissions and
|
||||
* limitations under the license.
|
||||
*/
|
||||
package org.apache.logging.log4j.core.appender;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.logging.log4j.core.Filter;
|
||||
import org.apache.logging.log4j.core.Layout;
|
||||
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginElement;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
|
||||
import org.apache.logging.log4j.core.helpers.Booleans;
|
||||
import org.apache.logging.log4j.core.helpers.Loader;
|
||||
import org.apache.logging.log4j.core.layout.PatternLayout;
|
||||
import org.apache.logging.log4j.util.PropertiesUtil;
|
||||
|
||||
/**
|
||||
* ConsoleAppender appends log events to <code>System.out</code> or
|
||||
* <code>System.err</code> using a layout specified by the user. The
|
||||
* default target is <code>System.out</code>.
|
||||
* @doubt accessing System.out or .err as a byte stream instead of a writer
|
||||
* bypasses the JVM's knowledge of the proper encoding. (RG) Encoding
|
||||
* is handled within the Layout. Typically, a Layout will generate a String
|
||||
* and then call getBytes which may use a configured encoding or the system
|
||||
* default. OTOH, a Writer cannot print byte streams.
|
||||
*/
|
||||
@Plugin(name = "Console", category = "Core", elementType = "appender", printObject = true)
|
||||
public final class ConsoleAppender extends AbstractOutputStreamAppender {
|
||||
|
||||
private static final String JANSI_CLASS = "org.fusesource.jansi.WindowsAnsiOutputStream";
|
||||
private static ConsoleManagerFactory factory = new ConsoleManagerFactory();
|
||||
|
||||
/**
|
||||
* Enumeration of console destinations.
|
||||
*/
|
||||
public enum Target {
|
||||
/** Standard output. */
|
||||
SYSTEM_OUT,
|
||||
/** Standard error output. */
|
||||
SYSTEM_ERR
|
||||
}
|
||||
|
||||
private ConsoleAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
|
||||
final OutputStreamManager manager,
|
||||
final boolean ignoreExceptions) {
|
||||
super(name, layout, filter, ignoreExceptions, true, manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Console Appender.
|
||||
* @param layout The layout to use (required).
|
||||
* @param filter The Filter or null.
|
||||
* @param t The target ("SYSTEM_OUT" or "SYSTEM_ERR"). The default is "SYSTEM_OUT".
|
||||
* @param follow If true will follow changes to the underlying output stream.
|
||||
* @param name The name of the Appender (required).
|
||||
* @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise
|
||||
* they are propagated to the caller.
|
||||
* @return The ConsoleAppender.
|
||||
*/
|
||||
@PluginFactory
|
||||
public static ConsoleAppender createAppender(
|
||||
@PluginElement("Layout") Layout<? extends Serializable> layout,
|
||||
@PluginElement("Filters") final Filter filter,
|
||||
@PluginAttribute("target") final String t,
|
||||
@PluginAttribute("name") final String name,
|
||||
@PluginAttribute("follow") final String follow,
|
||||
@PluginAttribute("ignoreExceptions") final String ignore) {
|
||||
if (name == null) {
|
||||
LOGGER.error("No name provided for ConsoleAppender");
|
||||
return null;
|
||||
}
|
||||
if (layout == null) {
|
||||
layout = PatternLayout.createLayout(null, null, null, null, null);
|
||||
}
|
||||
final boolean isFollow = Boolean.parseBoolean(follow);
|
||||
final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
|
||||
final Target target = t == null ? Target.SYSTEM_OUT : Target.valueOf(t);
|
||||
return new ConsoleAppender(name, layout, filter, getManager(isFollow, target, layout), ignoreExceptions);
|
||||
}
|
||||
|
||||
private static OutputStreamManager getManager(final boolean follow, final Target target, final Layout<? extends Serializable> layout) {
|
||||
final String type = target.name();
|
||||
final OutputStream os = getOutputStream(follow, target);
|
||||
return OutputStreamManager.getManager(target.name() + "." + follow, new FactoryData(os, type, layout), factory);
|
||||
}
|
||||
|
||||
private static OutputStream getOutputStream(final boolean follow, final Target target) {
|
||||
final String enc = Charset.defaultCharset().name();
|
||||
PrintStream printStream = null;
|
||||
try {
|
||||
printStream = target == Target.SYSTEM_OUT ?
|
||||
follow ? new PrintStream(new SystemOutStream(), true, enc) : System.out :
|
||||
follow ? new PrintStream(new SystemErrStream(), true, enc) : System.err;
|
||||
} catch (final UnsupportedEncodingException ex) { // should never happen
|
||||
throw new IllegalStateException("Unsupported default encoding " + enc, ex);
|
||||
}
|
||||
final PropertiesUtil propsUtil = PropertiesUtil.getProperties();
|
||||
if (!propsUtil.getStringProperty("os.name").startsWith("Windows") ||
|
||||
propsUtil.getBooleanProperty("log4j.skipJansi")) {
|
||||
return printStream;
|
||||
}
|
||||
try {
|
||||
final ClassLoader loader = Loader.getClassLoader();
|
||||
// We type the parameter as a wildcard to avoid a hard reference to Jansi.
|
||||
final Class<?> clazz = loader.loadClass(JANSI_CLASS);
|
||||
final Constructor<?> constructor = clazz.getConstructor(OutputStream.class);
|
||||
return (OutputStream) constructor.newInstance(printStream);
|
||||
} catch (final ClassNotFoundException cnfe) {
|
||||
LOGGER.debug("Jansi is not installed, cannot find {}", JANSI_CLASS);
|
||||
} catch (final NoSuchMethodException nsme) {
|
||||
LOGGER.warn("{} is missing the proper constructor", JANSI_CLASS);
|
||||
} catch (final Throwable ex) { // CraftBukkit - Exception -> Throwable
|
||||
LOGGER.warn("Unable to instantiate {}", JANSI_CLASS);
|
||||
}
|
||||
return printStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of OutputStream that redirects to the current System.err.
|
||||
*/
|
||||
private static class SystemErrStream extends OutputStream {
|
||||
public SystemErrStream() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// do not close sys err!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
System.err.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final byte[] b) throws IOException {
|
||||
System.err.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final byte[] b, final int off, final int len)
|
||||
throws IOException {
|
||||
System.err.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final int b) {
|
||||
System.err.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of OutputStream that redirects to the current System.out.
|
||||
*/
|
||||
private static class SystemOutStream extends OutputStream {
|
||||
public SystemOutStream() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// do not close sys out!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
System.out.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final byte[] b) throws IOException {
|
||||
System.out.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final byte[] b, final int off, final int len)
|
||||
throws IOException {
|
||||
System.out.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final int b) throws IOException {
|
||||
System.out.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data to pass to factory method.
|
||||
*/
|
||||
private static class FactoryData {
|
||||
private final OutputStream os;
|
||||
private final String type;
|
||||
private final Layout<? extends Serializable> layout;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param os The OutputStream.
|
||||
* @param type The name of the target.
|
||||
* @param layout A Serializable layout
|
||||
*/
|
||||
public FactoryData(final OutputStream os, final String type, final Layout<? extends Serializable> layout) {
|
||||
this.os = os;
|
||||
this.type = type;
|
||||
this.layout = layout;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create the Appender.
|
||||
*/
|
||||
private static class ConsoleManagerFactory implements ManagerFactory<OutputStreamManager, FactoryData> {
|
||||
|
||||
/**
|
||||
* Create an OutputStreamManager.
|
||||
* @param name The name of the entity to manage.
|
||||
* @param data The data required to create the entity.
|
||||
* @return The OutputStreamManager
|
||||
*/
|
||||
@Override
|
||||
public OutputStreamManager createManager(final String name, final FactoryData data) {
|
||||
return new OutputStreamManager(data.os, data.type, data.layout);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
73
src/main/java/org/bukkit/craftbukkit/CraftArt.java
Normal file
73
src/main/java/org/bukkit/craftbukkit/CraftArt.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import org.bukkit.Art;
|
||||
|
||||
// Safety class, will break if either side changes
|
||||
public class CraftArt {
|
||||
|
||||
public static Art NotchToBukkit(net.minecraft.entity.item.EntityPainting.EnumArt art) {
|
||||
switch (art) {
|
||||
case Kebab: return Art.KEBAB;
|
||||
case Aztec: return Art.AZTEC;
|
||||
case Alban: return Art.ALBAN;
|
||||
case Aztec2: return Art.AZTEC2;
|
||||
case Bomb: return Art.BOMB;
|
||||
case Plant: return Art.PLANT;
|
||||
case Wasteland: return Art.WASTELAND;
|
||||
case Pool: return Art.POOL;
|
||||
case Courbet: return Art.COURBET;
|
||||
case Sea: return Art.SEA;
|
||||
case Sunset: return Art.SUNSET;
|
||||
case Creebet: return Art.CREEBET;
|
||||
case Wanderer: return Art.WANDERER;
|
||||
case Graham: return Art.GRAHAM;
|
||||
case Match: return Art.MATCH;
|
||||
case Bust: return Art.BUST;
|
||||
case Stage: return Art.STAGE;
|
||||
case Void: return Art.VOID;
|
||||
case SkullAndRoses: return Art.SKULL_AND_ROSES;
|
||||
case Fighters: return Art.FIGHTERS;
|
||||
case Pointer: return Art.POINTER;
|
||||
case Pigscene: return Art.PIGSCENE;
|
||||
case BurningSkull: return Art.BURNINGSKULL;
|
||||
case Skeleton: return Art.SKELETON;
|
||||
case DonkeyKong: return Art.DONKEYKONG;
|
||||
case Wither: return Art.WITHER;
|
||||
default:
|
||||
throw new AssertionError(art);
|
||||
}
|
||||
}
|
||||
|
||||
public static net.minecraft.entity.item.EntityPainting.EnumArt BukkitToNotch(Art art) {
|
||||
switch (art) {
|
||||
case KEBAB: return net.minecraft.entity.item.EntityPainting.EnumArt.Kebab;
|
||||
case AZTEC: return net.minecraft.entity.item.EntityPainting.EnumArt.Aztec;
|
||||
case ALBAN: return net.minecraft.entity.item.EntityPainting.EnumArt.Alban;
|
||||
case AZTEC2: return net.minecraft.entity.item.EntityPainting.EnumArt.Aztec2;
|
||||
case BOMB: return net.minecraft.entity.item.EntityPainting.EnumArt.Bomb;
|
||||
case PLANT: return net.minecraft.entity.item.EntityPainting.EnumArt.Plant;
|
||||
case WASTELAND: return net.minecraft.entity.item.EntityPainting.EnumArt.Wasteland;
|
||||
case POOL: return net.minecraft.entity.item.EntityPainting.EnumArt.Pool;
|
||||
case COURBET: return net.minecraft.entity.item.EntityPainting.EnumArt.Courbet;
|
||||
case SEA: return net.minecraft.entity.item.EntityPainting.EnumArt.Sea;
|
||||
case SUNSET: return net.minecraft.entity.item.EntityPainting.EnumArt.Sunset;
|
||||
case CREEBET: return net.minecraft.entity.item.EntityPainting.EnumArt.Creebet;
|
||||
case WANDERER: return net.minecraft.entity.item.EntityPainting.EnumArt.Wanderer;
|
||||
case GRAHAM: return net.minecraft.entity.item.EntityPainting.EnumArt.Graham;
|
||||
case MATCH: return net.minecraft.entity.item.EntityPainting.EnumArt.Match;
|
||||
case BUST: return net.minecraft.entity.item.EntityPainting.EnumArt.Bust;
|
||||
case STAGE: return net.minecraft.entity.item.EntityPainting.EnumArt.Stage;
|
||||
case VOID: return net.minecraft.entity.item.EntityPainting.EnumArt.Void;
|
||||
case SKULL_AND_ROSES: return net.minecraft.entity.item.EntityPainting.EnumArt.SkullAndRoses;
|
||||
case FIGHTERS: return net.minecraft.entity.item.EntityPainting.EnumArt.Fighters;
|
||||
case POINTER: return net.minecraft.entity.item.EntityPainting.EnumArt.Pointer;
|
||||
case PIGSCENE: return net.minecraft.entity.item.EntityPainting.EnumArt.Pigscene;
|
||||
case BURNINGSKULL: return net.minecraft.entity.item.EntityPainting.EnumArt.BurningSkull;
|
||||
case SKELETON: return net.minecraft.entity.item.EntityPainting.EnumArt.Skeleton;
|
||||
case DONKEYKONG: return net.minecraft.entity.item.EntityPainting.EnumArt.DonkeyKong;
|
||||
case WITHER: return net.minecraft.entity.item.EntityPainting.EnumArt.Wither;
|
||||
default:
|
||||
throw new AssertionError(art);
|
||||
}
|
||||
}
|
||||
}
|
||||
346
src/main/java/org/bukkit/craftbukkit/CraftChunk.java
Normal file
346
src/main/java/org/bukkit/craftbukkit/CraftChunk.java
Normal file
@@ -0,0 +1,346 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
|
||||
public class CraftChunk implements Chunk {
|
||||
private WeakReference<net.minecraft.world.chunk.Chunk> weakChunk;
|
||||
private final net.minecraft.world.WorldServer worldServer;
|
||||
private final int x;
|
||||
private final int z;
|
||||
private static final byte[] emptyData = new byte[2048];
|
||||
private static final short[] emptyBlockIDs = new short[4096];
|
||||
private static final byte[] emptySkyLight = new byte[2048];
|
||||
|
||||
public CraftChunk(net.minecraft.world.chunk.Chunk chunk) {
|
||||
if (!(chunk instanceof net.minecraft.world.chunk.EmptyChunk)) {
|
||||
this.weakChunk = new WeakReference<net.minecraft.world.chunk.Chunk>(chunk);
|
||||
}
|
||||
|
||||
worldServer = (net.minecraft.world.WorldServer) getHandle().worldObj;
|
||||
x = getHandle().xPosition;
|
||||
z = getHandle().zPosition;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return worldServer.getWorld();
|
||||
}
|
||||
|
||||
public CraftWorld getCraftWorld() {
|
||||
return (CraftWorld) getWorld();
|
||||
}
|
||||
|
||||
public net.minecraft.world.chunk.Chunk getHandle() {
|
||||
net.minecraft.world.chunk.Chunk c = weakChunk.get();
|
||||
|
||||
if (c == null) {
|
||||
c = worldServer.getChunkFromChunkCoords(x, z);
|
||||
|
||||
if (!(c instanceof net.minecraft.world.chunk.EmptyChunk)) {
|
||||
weakChunk = new WeakReference<net.minecraft.world.chunk.Chunk>(c);
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void breakLink() {
|
||||
weakChunk.clear();
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftChunk{" + "x=" + getX() + "z=" + getZ() + '}';
|
||||
}
|
||||
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
return new CraftBlock(this, (getX() << 4) | (x & 0xF), y & 0xFF, (getZ() << 4) | (z & 0xF));
|
||||
}
|
||||
|
||||
public Entity[] getEntities() {
|
||||
int count = 0, index = 0;
|
||||
net.minecraft.world.chunk.Chunk chunk = getHandle();
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
count += chunk.entityLists[i].size();
|
||||
}
|
||||
|
||||
Entity[] entities = new Entity[count];
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (Object obj : chunk.entityLists[i].toArray()) {
|
||||
if (!(obj instanceof net.minecraft.entity.Entity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entities[index++] = ((net.minecraft.entity.Entity) obj).getBukkitEntity();
|
||||
}
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
public BlockState[] getTileEntities() {
|
||||
int index = 0;
|
||||
net.minecraft.world.chunk.Chunk chunk = getHandle();
|
||||
BlockState[] entities = new BlockState[chunk.chunkTileEntityMap.size()];
|
||||
|
||||
for (Object obj : chunk.chunkTileEntityMap.keySet().toArray()) {
|
||||
if (!(obj instanceof net.minecraft.world.ChunkPosition)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
net.minecraft.world.ChunkPosition position = (net.minecraft.world.ChunkPosition) obj;
|
||||
entities[index++] = worldServer.getWorld().getBlockAt(position.chunkPosX + (chunk.xPosition << 4), position.chunkPosY, position.chunkPosZ + (chunk.zPosition << 4)).getState();
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return getWorld().isChunkLoaded(this);
|
||||
}
|
||||
|
||||
public boolean load() {
|
||||
return getWorld().loadChunk(getX(), getZ(), true);
|
||||
}
|
||||
|
||||
public boolean load(boolean generate) {
|
||||
return getWorld().loadChunk(getX(), getZ(), generate);
|
||||
}
|
||||
|
||||
public boolean unload() {
|
||||
return getWorld().unloadChunk(getX(), getZ());
|
||||
}
|
||||
|
||||
public boolean unload(boolean save) {
|
||||
return getWorld().unloadChunk(getX(), getZ(), save);
|
||||
}
|
||||
|
||||
public boolean unload(boolean save, boolean safe) {
|
||||
return getWorld().unloadChunk(getX(), getZ(), save, safe);
|
||||
}
|
||||
|
||||
public ChunkSnapshot getChunkSnapshot() {
|
||||
return getChunkSnapshot(true, false, false);
|
||||
}
|
||||
|
||||
public ChunkSnapshot getChunkSnapshot(boolean includeMaxBlockY, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
net.minecraft.world.chunk.Chunk chunk = getHandle();
|
||||
|
||||
net.minecraft.world.chunk.storage.ExtendedBlockStorage[] cs = chunk.getBlockStorageArray(); /* Get sections */
|
||||
short[][] sectionBlockIDs = new short[cs.length][];
|
||||
byte[][] sectionBlockData = new byte[cs.length][];
|
||||
byte[][] sectionSkyLights = new byte[cs.length][];
|
||||
byte[][] sectionEmitLights = new byte[cs.length][];
|
||||
boolean[] sectionEmpty = new boolean[cs.length];
|
||||
|
||||
for (int i = 0; i < cs.length; i++) {
|
||||
if (cs[i] == null) { /* Section is empty? */
|
||||
sectionBlockIDs[i] = emptyBlockIDs;
|
||||
sectionBlockData[i] = emptyData;
|
||||
sectionSkyLights[i] = emptySkyLight;
|
||||
sectionEmitLights[i] = emptyData;
|
||||
sectionEmpty[i] = true;
|
||||
} else { /* Not empty */
|
||||
short[] blockids = new short[4096];
|
||||
byte[] baseids = cs[i].getBlockLSBArray();
|
||||
|
||||
/* Copy base IDs */
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
blockids[j] = (short) (baseids[j] & 0xFF);
|
||||
}
|
||||
|
||||
if (cs[i].getBlockMSBArray() != null) { /* If we've got extended IDs */
|
||||
// Spigot start
|
||||
if (cs[i].getBlockMSBArray().isTrivialArray()) {
|
||||
int tval = cs[i].getBlockMSBArray().getTrivialArrayValue();
|
||||
if (tval != 0) {
|
||||
tval = tval << 8;
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
blockids[j] |= tval;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
byte[] extids = cs[i].getBlockMSBArray().getValueArray();
|
||||
// Spigot end
|
||||
|
||||
for (int j = 0; j < 2048; j++) {
|
||||
short b = (short) (extids[j] & 0xFF);
|
||||
|
||||
if (b == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
blockids[j<<1] |= (b & 0x0F) << 8;
|
||||
blockids[(j<<1)+1] |= (b & 0xF0) << 4;
|
||||
}
|
||||
} // Spigot
|
||||
}
|
||||
|
||||
sectionBlockIDs[i] = blockids;
|
||||
|
||||
/* Get block data nibbles */
|
||||
// Spigot start
|
||||
if (cs[i].getMetadataArray().isTrivialArray() && (cs[i].getMetadataArray().getTrivialArrayValue() == 0)) {
|
||||
sectionBlockData[i] = emptyData;
|
||||
} else {
|
||||
sectionBlockData[i] = new byte[2048];
|
||||
cs[i].getMetadataArray().copyToByteArray(sectionBlockData[i], 0);
|
||||
}
|
||||
if (cs[i].getSkylightArray() == null) {
|
||||
sectionSkyLights[i] = emptyData;
|
||||
}
|
||||
else if (cs[i].getSkylightArray().isTrivialArray()) {
|
||||
if (cs[i].getSkylightArray().getTrivialArrayValue() == 0) {
|
||||
sectionSkyLights[i] = emptyData;
|
||||
} else if (cs[i].getSkylightArray().getTrivialArrayValue() == 15) {
|
||||
sectionSkyLights[i] = emptySkyLight;
|
||||
} else {
|
||||
sectionSkyLights[i] = new byte[2048];
|
||||
cs[i].getSkylightArray().copyToByteArray(sectionSkyLights[i], 0);
|
||||
}
|
||||
} else {
|
||||
sectionSkyLights[i] = new byte[2048];
|
||||
cs[i].getSkylightArray().copyToByteArray(sectionSkyLights[i], 0);
|
||||
}
|
||||
if (cs[i].getBlocklightArray().isTrivialArray() && (cs[i].getBlocklightArray().getTrivialArrayValue() == 0)) {
|
||||
sectionEmitLights[i] = emptyData;
|
||||
} else {
|
||||
sectionEmitLights[i] = new byte[2048];
|
||||
cs[i].getBlocklightArray().copyToByteArray(sectionEmitLights[i], 0);
|
||||
}
|
||||
// Spigot end
|
||||
}
|
||||
}
|
||||
|
||||
int[] hmap = null;
|
||||
|
||||
if (includeMaxBlockY) {
|
||||
hmap = new int[256]; // Get copy of height map
|
||||
System.arraycopy(chunk.heightMap, 0, hmap, 0, 256);
|
||||
}
|
||||
|
||||
net.minecraft.world.biome.BiomeGenBase[] biome = null;
|
||||
double[] biomeTemp = null;
|
||||
double[] biomeRain = null;
|
||||
|
||||
if (includeBiome || includeBiomeTempRain) {
|
||||
net.minecraft.world.biome.WorldChunkManager wcm = chunk.worldObj.getWorldChunkManager();
|
||||
|
||||
if (includeBiome) {
|
||||
biome = new net.minecraft.world.biome.BiomeGenBase[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biome[i] = chunk.getBiomeGenForWorldCoords(i & 0xF, i >> 4, wcm);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeBiomeTempRain) {
|
||||
biomeTemp = new double[256];
|
||||
biomeRain = new double[256];
|
||||
float[] dat = getTemperatures(wcm, getX() << 4, getZ() << 4);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biomeTemp[i] = dat[i];
|
||||
}
|
||||
|
||||
dat = wcm.getRainfall(null, getX() << 4, getZ() << 4, 16, 16);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biomeRain[i] = dat[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
World world = getWorld();
|
||||
return new CraftChunkSnapshot(getX(), getZ(), world.getName(), world.getFullTime(), sectionBlockIDs, sectionBlockData, sectionSkyLights, sectionEmitLights, sectionEmpty, hmap, biome, biomeTemp, biomeRain);
|
||||
}
|
||||
|
||||
public static ChunkSnapshot getEmptyChunkSnapshot(int x, int z, CraftWorld world, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
net.minecraft.world.biome.BiomeGenBase[] biome = null;
|
||||
double[] biomeTemp = null;
|
||||
double[] biomeRain = null;
|
||||
|
||||
if (includeBiome || includeBiomeTempRain) {
|
||||
net.minecraft.world.biome.WorldChunkManager wcm = world.getHandle().getWorldChunkManager();
|
||||
|
||||
if (includeBiome) {
|
||||
biome = new net.minecraft.world.biome.BiomeGenBase[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biome[i] = world.getHandle().getBiomeGenForCoords((x << 4) + (i & 0xF), (z << 4) + (i >> 4));
|
||||
}
|
||||
}
|
||||
|
||||
if (includeBiomeTempRain) {
|
||||
biomeTemp = new double[256];
|
||||
biomeRain = new double[256];
|
||||
float[] dat = getTemperatures(wcm, x << 4, z << 4);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biomeTemp[i] = dat[i];
|
||||
}
|
||||
|
||||
dat = wcm.getRainfall(null, x << 4, z << 4, 16, 16);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biomeRain[i] = dat[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill with empty data */
|
||||
int hSection = world.getMaxHeight() >> 4;
|
||||
short[][] blockIDs = new short[hSection][];
|
||||
byte[][] skyLight = new byte[hSection][];
|
||||
byte[][] emitLight = new byte[hSection][];
|
||||
byte[][] blockData = new byte[hSection][];
|
||||
boolean[] empty = new boolean[hSection];
|
||||
|
||||
for (int i = 0; i < hSection; i++) {
|
||||
blockIDs[i] = emptyBlockIDs;
|
||||
skyLight[i] = emptySkyLight;
|
||||
emitLight[i] = emptyData;
|
||||
blockData[i] = emptyData;
|
||||
empty[i] = true;
|
||||
}
|
||||
|
||||
return new CraftChunkSnapshot(x, z, world.getName(), world.getFullTime(), blockIDs, blockData, skyLight, emitLight, empty, new int[256], biome, biomeTemp, biomeRain);
|
||||
}
|
||||
|
||||
private static float[] getTemperatures(net.minecraft.world.biome.WorldChunkManager chunkmanager, int chunkX, int chunkZ) {
|
||||
net.minecraft.world.biome.BiomeGenBase[] biomes = chunkmanager.getBiomesForGeneration(null, chunkX, chunkZ, 16, 16);
|
||||
float[] temps = new float[biomes.length];
|
||||
|
||||
for (int i = 0; i < biomes.length; i++) {
|
||||
float temp = biomes[i].temperature; // Vanilla of olde: ((int) biomes[i].temperature * 65536.0F) / 65536.0F
|
||||
|
||||
if (temp > 1F) {
|
||||
temp = 1F;
|
||||
}
|
||||
|
||||
temps[i] = temp;
|
||||
}
|
||||
|
||||
return temps;
|
||||
}
|
||||
|
||||
static {
|
||||
Arrays.fill(emptySkyLight, (byte) 0xFF);
|
||||
}
|
||||
}
|
||||
96
src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
Normal file
96
src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java
Normal file
@@ -0,0 +1,96 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a static, thread-safe snapshot of chunk of blocks
|
||||
* Purpose is to allow clean, efficient copy of a chunk data to be made, and then handed off for processing in another thread (e.g. map rendering)
|
||||
*/
|
||||
public class CraftChunkSnapshot implements ChunkSnapshot {
|
||||
private final int x, z;
|
||||
private final String worldname;
|
||||
private final short[][] blockids; /* Block IDs, by section */
|
||||
private final byte[][] blockdata;
|
||||
private final byte[][] skylight;
|
||||
private final byte[][] emitlight;
|
||||
private final boolean[] empty;
|
||||
private final int[] hmap; // Height map
|
||||
private final long captureFulltime;
|
||||
private final net.minecraft.world.biome.BiomeGenBase[] biome;
|
||||
private final double[] biomeTemp;
|
||||
private final double[] biomeRain;
|
||||
|
||||
CraftChunkSnapshot(int x, int z, String wname, long wtime, short[][] sectionBlockIDs, byte[][] sectionBlockData, byte[][] sectionSkyLights, byte[][] sectionEmitLights, boolean[] sectionEmpty, int[] hmap, net.minecraft.world.biome.BiomeGenBase[] biome, double[] biomeTemp, double[] biomeRain) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.worldname = wname;
|
||||
this.captureFulltime = wtime;
|
||||
this.blockids = sectionBlockIDs;
|
||||
this.blockdata = sectionBlockData;
|
||||
this.skylight = sectionSkyLights;
|
||||
this.emitlight = sectionEmitLights;
|
||||
this.empty = sectionEmpty;
|
||||
this.hmap = hmap;
|
||||
this.biome = biome;
|
||||
this.biomeTemp = biomeTemp;
|
||||
this.biomeRain = biomeRain;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldname;
|
||||
}
|
||||
|
||||
public final int getBlockTypeId(int x, int y, int z) {
|
||||
return blockids[y >> 4][((y & 0xF) << 8) | (z << 4) | x];
|
||||
}
|
||||
|
||||
public final int getBlockData(int x, int y, int z) {
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
return (blockdata[y >> 4][off] >> ((x & 1) << 2)) & 0xF;
|
||||
}
|
||||
|
||||
public final int getBlockSkyLight(int x, int y, int z) {
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
return (skylight[y >> 4][off] >> ((x & 1) << 2)) & 0xF;
|
||||
}
|
||||
|
||||
public final int getBlockEmittedLight(int x, int y, int z) {
|
||||
int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1);
|
||||
return (emitlight[y >> 4][off] >> ((x & 1) << 2)) & 0xF;
|
||||
}
|
||||
|
||||
public final int getHighestBlockYAt(int x, int z) {
|
||||
return hmap[z << 4 | x];
|
||||
}
|
||||
|
||||
public final Biome getBiome(int x, int z) {
|
||||
return CraftBlock.biomeBaseToBiome(biome[z << 4 | x]);
|
||||
}
|
||||
|
||||
public final double getRawBiomeTemperature(int x, int z) {
|
||||
return biomeTemp[z << 4 | x];
|
||||
}
|
||||
|
||||
public final double getRawBiomeRainfall(int x, int z) {
|
||||
return biomeRain[z << 4 | x];
|
||||
}
|
||||
|
||||
public final long getCaptureFullTime() {
|
||||
return captureFulltime;
|
||||
}
|
||||
|
||||
public final boolean isSectionEmpty(int sy) {
|
||||
return empty[sy];
|
||||
}
|
||||
}
|
||||
40
src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
Normal file
40
src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
|
||||
|
||||
public class CraftCrashReport implements Callable<Object> {
|
||||
|
||||
public Object call() throws Exception {
|
||||
StringWriter value = new StringWriter();
|
||||
try {
|
||||
value.append("\n Running: ").append(Bukkit.getName()).append(" version ").append(Bukkit.getVersion()).append(" (Implementing API version ").append(Bukkit.getBukkitVersion()).append(") ").append(String.valueOf(net.minecraft.server.MinecraftServer.getServer().isServerInOnlineMode()));
|
||||
value.append("\n Plugins: {");
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
PluginDescriptionFile description = plugin.getDescription();
|
||||
value.append(' ').append(description.getFullName()).append(' ').append(description.getMain()).append(' ').append(Arrays.toString(description.getAuthors().toArray())).append(',');
|
||||
}
|
||||
value.append("}\n Warnings: ").append(Bukkit.getWarningState().name());
|
||||
value.append("\n Threads: {");
|
||||
for (Map.Entry<Thread, ? extends Object[]> entry : Thread.getAllStackTraces().entrySet()) {
|
||||
value.append(' ').append(entry.getKey().getState().name()).append(' ').append(entry.getKey().getName()).append(": ").append(Arrays.toString(entry.getValue())).append(',');
|
||||
}
|
||||
value.append("}\n ").append(Bukkit.getScheduler().toString());
|
||||
} catch (Throwable t) {
|
||||
value.append("\n Failed to handle CraftCrashReport:\n");
|
||||
PrintWriter writer = new PrintWriter(value);
|
||||
t.printStackTrace(writer);
|
||||
writer.flush();
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
}
|
||||
63
src/main/java/org/bukkit/craftbukkit/CraftEffect.java
Normal file
63
src/main/java/org/bukkit/craftbukkit/CraftEffect.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.potion.Potion;
|
||||
|
||||
public class CraftEffect {
|
||||
public static <T> int getDataValue(Effect effect, T data) {
|
||||
int datavalue;
|
||||
switch(effect) {
|
||||
case POTION_BREAK:
|
||||
datavalue = ((Potion) data).toDamageValue() & 0x3F;
|
||||
break;
|
||||
case RECORD_PLAY:
|
||||
Validate.isTrue(((Material) data).isRecord(), "Invalid record type!");
|
||||
datavalue = ((Material) data).getId();
|
||||
break;
|
||||
case SMOKE:
|
||||
switch((BlockFace) data) { // TODO: Verify (Where did these values come from...?)
|
||||
case SOUTH_EAST:
|
||||
datavalue = 0;
|
||||
break;
|
||||
case SOUTH:
|
||||
datavalue = 1;
|
||||
break;
|
||||
case SOUTH_WEST:
|
||||
datavalue = 2;
|
||||
break;
|
||||
case EAST:
|
||||
datavalue = 3;
|
||||
break;
|
||||
case UP:
|
||||
case SELF:
|
||||
datavalue = 4;
|
||||
break;
|
||||
case WEST:
|
||||
datavalue = 5;
|
||||
break;
|
||||
case NORTH_EAST:
|
||||
datavalue = 6;
|
||||
break;
|
||||
case NORTH:
|
||||
datavalue = 7;
|
||||
break;
|
||||
case NORTH_WEST:
|
||||
datavalue = 8;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad smoke direction!");
|
||||
}
|
||||
break;
|
||||
case STEP_SOUND:
|
||||
Validate.isTrue(((Material) data).isBlock(), "Material is not a block!");
|
||||
datavalue = ((Material) data).getId();
|
||||
break;
|
||||
default:
|
||||
datavalue = 0;
|
||||
}
|
||||
return datavalue;
|
||||
}
|
||||
}
|
||||
86
src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java
Normal file
86
src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import net.minecraft.server.management.IPBanEntry;
|
||||
import net.minecraft.server.management.BanList;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
public final class CraftIpBanEntry implements org.bukkit.BanEntry {
|
||||
private final BanList list;
|
||||
private final String target;
|
||||
private Date created;
|
||||
private String source;
|
||||
private Date expiration;
|
||||
private String reason;
|
||||
|
||||
public CraftIpBanEntry(String target, IPBanEntry entry, BanList list) {
|
||||
this.list = list;
|
||||
this.target = target;
|
||||
this.created = entry.getCreated() != null ? new Date(entry.getCreated().getTime()) : null;
|
||||
this.source = entry.getSource();
|
||||
this.expiration = entry.getBanEndDate() != null ? new Date(entry.getBanEndDate().getTime()) : null;
|
||||
this.reason = entry.getBanReason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreated() {
|
||||
return this.created == null ? null : (Date) this.created.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getExpiration() {
|
||||
return this.expiration == null ? null : (Date) this.expiration.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpiration(Date expiration) {
|
||||
if (expiration != null && expiration.getTime() == new Date(0, 0, 0, 0, 0, 0).getTime()) {
|
||||
expiration = null; // Forces "forever"
|
||||
}
|
||||
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReason() {
|
||||
return this.reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
IPBanEntry entry = new IPBanEntry(target, this.created, this.source, this.expiration, this.reason);
|
||||
this.list.func_152687_a(entry);
|
||||
try {
|
||||
this.list.func_152678_f();
|
||||
} catch (IOException ex) {
|
||||
MinecraftServer.getLogger().error("Failed to save banned-ips.json, " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
77
src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java
Normal file
77
src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.server.management.IPBanEntry;
|
||||
import net.minecraft.server.management.BanList;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class CraftIpBanList implements org.bukkit.BanList {
|
||||
private final BanList list;
|
||||
|
||||
public CraftIpBanList(BanList list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.BanEntry getBanEntry(String target) {
|
||||
Validate.notNull(target, "Target cannot be null");
|
||||
|
||||
IPBanEntry entry = (IPBanEntry) list.func_152683_b(target);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CraftIpBanEntry(target, entry, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.BanEntry addBan(String target, String reason, Date expires, String source) {
|
||||
Validate.notNull(target, "Ban target cannot be null");
|
||||
|
||||
IPBanEntry entry = new IPBanEntry(target, new Date(),
|
||||
StringUtils.isBlank(source) ? null : source, expires,
|
||||
StringUtils.isBlank(reason) ? null : reason);
|
||||
|
||||
list.func_152687_a(entry);
|
||||
|
||||
try {
|
||||
list.func_152678_f();
|
||||
} catch (IOException ex) {
|
||||
MinecraftServer.getLogger().error("Failed to save banned-ips.json, " + ex.getMessage());
|
||||
}
|
||||
|
||||
return new CraftIpBanEntry(target, entry, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<org.bukkit.BanEntry> getBanEntries() {
|
||||
ImmutableSet.Builder<org.bukkit.BanEntry> builder = ImmutableSet.builder();
|
||||
for (String target : list.func_152685_a()) {
|
||||
builder.add(new CraftIpBanEntry(target, (IPBanEntry) list.func_152683_b(target), list));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBanned(String target) {
|
||||
Validate.notNull(target, "Target cannot be null");
|
||||
|
||||
return list.func_152708_a(InetSocketAddress.createUnresolved(target, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pardon(String target) {
|
||||
Validate.notNull(target, "Target cannot be null");
|
||||
|
||||
list.func_152684_c(target);
|
||||
}
|
||||
}
|
||||
268
src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
Normal file
268
src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
Normal file
@@ -0,0 +1,268 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import org.bukkit.BanList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.SerializableAs;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
@SerializableAs("Player")
|
||||
public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable {
|
||||
private final GameProfile profile;
|
||||
private final CraftServer server;
|
||||
private final net.minecraft.world.storage.SaveHandler storage;
|
||||
|
||||
protected CraftOfflinePlayer(CraftServer server, GameProfile profile) {
|
||||
this.server = server;
|
||||
this.profile = profile;
|
||||
this.storage = (net.minecraft.world.storage.SaveHandler) (server.console.worlds.get(0).getSaveHandler());
|
||||
}
|
||||
|
||||
public GameProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return getPlayer() != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) {
|
||||
return player.getName();
|
||||
}
|
||||
|
||||
// This might not match lastKnownName but if not it should be more correct
|
||||
if (profile.getName() != null) {
|
||||
return profile.getName();
|
||||
}
|
||||
|
||||
NBTTagCompound data = getBukkitData();
|
||||
|
||||
if (data != null) {
|
||||
if (data.hasKey("lastKnownName")) {
|
||||
return data.getString("lastKnownName");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
return profile.getId();
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return server.getHandle().func_152596_g(profile);
|
||||
}
|
||||
|
||||
public void setOp(boolean value) {
|
||||
if (value == isOp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
server.getHandle().func_152605_a(profile);
|
||||
} else {
|
||||
server.getHandle().func_152610_b(profile);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBanned() {
|
||||
if (getName() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return server.getBanList(BanList.Type.NAME).isBanned(getName());
|
||||
}
|
||||
|
||||
public void setBanned(boolean value) {
|
||||
if (getName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
server.getBanList(BanList.Type.NAME).addBan(getName(), null, null, null);
|
||||
} else {
|
||||
server.getBanList(BanList.Type.NAME).pardon(getName());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWhitelisted() {
|
||||
return server.getHandle().func_152607_e(profile); // Cauldron
|
||||
}
|
||||
|
||||
public void setWhitelisted(boolean value) {
|
||||
if (value) {
|
||||
server.getHandle().func_152601_d(profile);
|
||||
} else {
|
||||
server.getHandle().func_152597_c(profile);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
|
||||
result.put("UUID", profile.getId().toString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static OfflinePlayer deserialize(Map<String, Object> args) {
|
||||
// Backwards comparability
|
||||
if (args.get("name") != null) {
|
||||
return Bukkit.getServer().getOfflinePlayer((String) args.get("name"));
|
||||
}
|
||||
|
||||
return Bukkit.getServer().getOfflinePlayer(UUID.fromString((String) args.get("UUID")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "[UUID=" + profile.getId() + "]";
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
for (Object obj : server.getHandle().playerEntityList) {
|
||||
EntityPlayerMP player = (EntityPlayerMP) obj;
|
||||
if (player.getUniqueID().equals(getUniqueId())) {
|
||||
return (player.playerNetServerHandler != null) ? player.playerNetServerHandler.getPlayerB() : null; // Cauldron
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof OfflinePlayer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OfflinePlayer other = (OfflinePlayer) obj;
|
||||
if ((this.getUniqueId() == null) || (other.getUniqueId() == null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getUniqueId().equals(other.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 97 * hash + (this.getUniqueId() != null ? this.getUniqueId().hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
private NBTTagCompound getData() {
|
||||
return storage.getPlayerData(getUniqueId().toString());
|
||||
}
|
||||
|
||||
private NBTTagCompound getBukkitData() {
|
||||
NBTTagCompound result = getData();
|
||||
|
||||
if (result != null) {
|
||||
if (!result.hasKey("bukkit")) {
|
||||
result.setTag("bukkit", new net.minecraft.nbt.NBTTagCompound());
|
||||
}
|
||||
result = result.getCompoundTag("bukkit");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private File getDataFile() {
|
||||
return new File(storage.getPlayerDir(), getUniqueId() + ".dat");
|
||||
}
|
||||
|
||||
public long getFirstPlayed() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) return player.getFirstPlayed();
|
||||
|
||||
net.minecraft.nbt.NBTTagCompound data = getBukkitData();
|
||||
|
||||
if (data != null) {
|
||||
if (data.hasKey("firstPlayed")) {
|
||||
return data.getLong("firstPlayed");
|
||||
} else {
|
||||
File file = getDataFile();
|
||||
return file.lastModified();
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public long getLastPlayed() {
|
||||
Player player = getPlayer();
|
||||
if (player != null) return player.getLastPlayed();
|
||||
|
||||
net.minecraft.nbt.NBTTagCompound data = getBukkitData();
|
||||
|
||||
if (data != null) {
|
||||
if (data.hasKey("lastPlayed")) {
|
||||
return data.getLong("lastPlayed");
|
||||
} else {
|
||||
File file = getDataFile();
|
||||
return file.lastModified();
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPlayedBefore() {
|
||||
return getData() != null;
|
||||
}
|
||||
|
||||
public Location getBedSpawnLocation() {
|
||||
net.minecraft.nbt.NBTTagCompound data = getData();
|
||||
if (data == null) return null;
|
||||
|
||||
if (data.hasKey("SpawnX") && data.hasKey("SpawnY") && data.hasKey("SpawnZ")) {
|
||||
String spawnWorld = data.getString("SpawnWorld");
|
||||
if (spawnWorld.equals("")) {
|
||||
spawnWorld = server.getWorlds().get(0).getName();
|
||||
}
|
||||
return new Location(server.getWorld(spawnWorld), data.getInteger("SpawnX"), data.getInteger("SpawnY"), data.getInteger("SpawnZ"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setMetadata(String metadataKey, MetadataValue metadataValue) {
|
||||
server.getPlayerMetadata().setMetadata(this, metadataKey, metadataValue);
|
||||
}
|
||||
|
||||
public List<MetadataValue> getMetadata(String metadataKey) {
|
||||
return server.getPlayerMetadata().getMetadata(this, metadataKey);
|
||||
}
|
||||
|
||||
public boolean hasMetadata(String metadataKey) {
|
||||
return server.getPlayerMetadata().hasMetadata(this, metadataKey);
|
||||
}
|
||||
|
||||
public void removeMetadata(String metadataKey, Plugin plugin) {
|
||||
server.getPlayerMetadata().removeMetadata(this, metadataKey, plugin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.management.UserListBans;
|
||||
import net.minecraft.server.management.UserListBansEntry;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
public final class CraftProfileBanEntry implements org.bukkit.BanEntry {
|
||||
private final UserListBans list;
|
||||
private final GameProfile profile;
|
||||
private Date created;
|
||||
private String source;
|
||||
private Date expiration;
|
||||
private String reason;
|
||||
|
||||
public CraftProfileBanEntry(GameProfile profile, UserListBansEntry entry, UserListBans list) {
|
||||
this.list = list;
|
||||
this.profile = profile;
|
||||
this.created = entry.getCreated() != null ? new Date(entry.getCreated().getTime()) : null;
|
||||
this.source = entry.getSource();
|
||||
this.expiration = entry.getBanEndDate() != null ? new Date(entry.getBanEndDate().getTime()) : null;
|
||||
this.reason = entry.getBanReason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTarget() {
|
||||
return this.profile.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreated() {
|
||||
return this.created == null ? null : (Date) this.created.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getExpiration() {
|
||||
return this.expiration == null ? null : (Date) this.expiration.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpiration(Date expiration) {
|
||||
if (expiration != null && expiration.getTime() == new Date(0, 0, 0, 0, 0, 0).getTime()) {
|
||||
expiration = null; // Forces "forever"
|
||||
}
|
||||
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReason() {
|
||||
return this.reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReason(String reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
UserListBansEntry entry = new UserListBansEntry(profile, this.created, this.source, this.expiration, this.reason);
|
||||
this.list.func_152687_a(entry);
|
||||
try {
|
||||
this.list.func_152678_f();
|
||||
} catch (IOException ex) {
|
||||
MinecraftServer.getLogger().error("Failed to save banned-players.json, " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.management.UserListBans;
|
||||
import net.minecraft.server.management.UserListBansEntry;
|
||||
import net.minecraft.server.management.UserListEntry;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class CraftProfileBanList implements org.bukkit.BanList {
|
||||
private final UserListBans list;
|
||||
|
||||
public CraftProfileBanList(UserListBans list){
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.BanEntry getBanEntry(String target) {
|
||||
Validate.notNull(target, "Target cannot be null");
|
||||
|
||||
GameProfile profile = MinecraftServer.getServer().func_152358_ax().func_152655_a(target);
|
||||
if (profile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserListBansEntry entry = (UserListBansEntry) list.func_152683_b(profile);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CraftProfileBanEntry(profile, entry, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.BanEntry addBan(String target, String reason, Date expires, String source) {
|
||||
Validate.notNull(target, "Ban target cannot be null");
|
||||
|
||||
GameProfile profile = MinecraftServer.getServer().func_152358_ax().func_152655_a(target);
|
||||
if (profile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserListBansEntry entry = new UserListBansEntry(profile, new Date(),
|
||||
StringUtils.isBlank(source) ? null : source, expires,
|
||||
StringUtils.isBlank(reason) ? null : reason);
|
||||
|
||||
list.func_152687_a(entry);
|
||||
|
||||
try {
|
||||
list.func_152678_f();
|
||||
} catch (IOException ex) {
|
||||
MinecraftServer.getLogger().error("Failed to save banned-players.json, " + ex.getMessage());
|
||||
}
|
||||
|
||||
return new CraftProfileBanEntry(profile, entry, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<org.bukkit.BanEntry> getBanEntries() {
|
||||
ImmutableSet.Builder<org.bukkit.BanEntry> builder = ImmutableSet.builder();
|
||||
for (UserListEntry entry : list.getValues()) {
|
||||
GameProfile profile = (GameProfile) entry.func_152640_f(); // Should be getKey
|
||||
builder.add(new CraftProfileBanEntry(profile, (UserListBansEntry) entry, list));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBanned(String target) {
|
||||
Validate.notNull(target, "Target cannot be null");
|
||||
|
||||
GameProfile profile = MinecraftServer.getServer().func_152358_ax().func_152655_a(target);
|
||||
if (profile == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return list.func_152702_a(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pardon(String target) {
|
||||
Validate.notNull(target, "Target cannot be null");
|
||||
|
||||
GameProfile profile = MinecraftServer.getServer().func_152358_ax().func_152655_a(target);
|
||||
list.func_152684_c(profile);
|
||||
}
|
||||
}
|
||||
1753
src/main/java/org/bukkit/craftbukkit/CraftServer.java
Normal file
1753
src/main/java/org/bukkit/craftbukkit/CraftServer.java
Normal file
File diff suppressed because it is too large
Load Diff
231
src/main/java/org/bukkit/craftbukkit/CraftSound.java
Normal file
231
src/main/java/org/bukkit/craftbukkit/CraftSound.java
Normal file
@@ -0,0 +1,231 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import static org.bukkit.Sound.*;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Sound;
|
||||
|
||||
public class CraftSound {
|
||||
private static final String[] sounds = new String[Sound.values().length];
|
||||
|
||||
static {
|
||||
// Ambient
|
||||
set(AMBIENCE_CAVE, "ambient.cave.cave");
|
||||
set(AMBIENCE_RAIN, "ambient.weather.rain");
|
||||
set(AMBIENCE_THUNDER, "ambient.weather.thunder");
|
||||
// Damage
|
||||
set(HURT_FLESH, "game.neutral.hurt");
|
||||
set(FALL_BIG, "game.neutral.hurt.fall.big");
|
||||
set(FALL_SMALL, "game.neutral.hurt.fall.small");
|
||||
// Dig Sounds
|
||||
set(DIG_WOOL, "dig.cloth");
|
||||
set(DIG_GRASS, "dig.grass");
|
||||
set(DIG_GRAVEL, "dig.gravel");
|
||||
set(DIG_SAND, "dig.sand");
|
||||
set(DIG_SNOW, "dig.snow");
|
||||
set(DIG_STONE, "dig.stone");
|
||||
set(DIG_WOOD, "dig.wood");
|
||||
// Fire
|
||||
set(FIRE, "fire.fire");
|
||||
set(FIRE_IGNITE, "fire.ignite");
|
||||
// Fireworks
|
||||
set(FIREWORK_BLAST, "fireworks.blast");
|
||||
set(FIREWORK_BLAST2, "fireworks.blast_far");
|
||||
set(FIREWORK_LARGE_BLAST, "fireworks.largeBlast");
|
||||
set(FIREWORK_LARGE_BLAST2, "fireworks.largeBlast_far");
|
||||
set(FIREWORK_TWINKLE, "fireworks.twinkle");
|
||||
set(FIREWORK_TWINKLE2, "fireworks.twinkle_far");
|
||||
set(FIREWORK_LAUNCH, "fireworks.launch");
|
||||
// Liquid
|
||||
set(SPLASH2, "game.neutral.swim.splash");
|
||||
set(SWIM, "game.neutral.swim");
|
||||
set(WATER, "liquid.water");
|
||||
set(LAVA, "liquid.lava");
|
||||
set(LAVA_POP, "liquid.lavapop");
|
||||
// Minecart
|
||||
set(MINECART_BASE, "minecart.base");
|
||||
set(MINECART_INSIDE, "minecart.inside");
|
||||
// Mob
|
||||
set(BAT_DEATH, "mob.bat.death");
|
||||
set(BAT_HURT, "mob.bat.hurt");
|
||||
set(BAT_IDLE, "mob.bat.idle");
|
||||
set(BAT_LOOP, "mob.bat.loop");
|
||||
set(BAT_TAKEOFF, "mob.bat.takeoff");
|
||||
set(BLAZE_BREATH, "mob.blaze.breathe");
|
||||
set(BLAZE_DEATH, "mob.blaze.death");
|
||||
set(BLAZE_HIT, "mob.blaze.hit");
|
||||
set(CAT_HISS, "mob.cat.hiss");
|
||||
set(CAT_HIT, "mob.cat.hitt");
|
||||
set(CAT_MEOW, "mob.cat.meow");
|
||||
set(CAT_PURR, "mob.cat.purr");
|
||||
set(CAT_PURREOW, "mob.cat.purreow");
|
||||
set(CHICKEN_IDLE, "mob.chicken.say");
|
||||
set(CHICKEN_HURT, "mob.chicken.hurt");
|
||||
set(CHICKEN_EGG_POP, "mob.chicken.plop");
|
||||
set(CHICKEN_WALK, "mob.chicken.step");
|
||||
set(COW_HURT, "mob.cow.hurt");
|
||||
set(COW_IDLE, "mob.cow.say");
|
||||
set(COW_WALK, "mob.cow.step");
|
||||
set(CREEPER_DEATH, "mob.creeper.death");
|
||||
set(CREEPER_HISS, "mob.creeper.say");
|
||||
set(ENDERDRAGON_DEATH, "mob.enderdragon.end");
|
||||
set(ENDERDRAGON_GROWL, "mob.enderdragon.growl");
|
||||
set(ENDERDRAGON_HIT, "mob.enderdragon.hit");
|
||||
set(ENDERDRAGON_WINGS, "mob.enderdragon.wings");
|
||||
set(ENDERMAN_DEATH, "mob.endermen.death");
|
||||
set(ENDERMAN_HIT, "mob.endermen.hit");
|
||||
set(ENDERMAN_IDLE, "mob.endermen.idle");
|
||||
set(ENDERMAN_TELEPORT, "mob.endermen.portal");
|
||||
set(ENDERMAN_SCREAM, "mob.endermen.scream");
|
||||
set(ENDERMAN_STARE, "mob.endermen.stare");
|
||||
set(GHAST_SCREAM2, "mob.ghast.affectionate_scream");
|
||||
set(GHAST_CHARGE, "mob.ghast.charge");
|
||||
set(GHAST_DEATH, "mob.ghast.death");
|
||||
set(GHAST_FIREBALL, "mob.ghast.fireball");
|
||||
set(GHAST_MOAN, "mob.ghast.moan");
|
||||
set(GHAST_SCREAM, "mob.ghast.scream");
|
||||
set(HORSE_ANGRY, "mob.horse.angry");
|
||||
set(HORSE_ARMOR, "mob.horse.armor");
|
||||
set(HORSE_BREATHE, "mob.horse.breathe");
|
||||
set(HORSE_DEATH, "mob.horse.death");
|
||||
set(HORSE_GALLOP, "mob.horse.gallop");
|
||||
set(HORSE_HIT, "mob.horse.hit");
|
||||
set(HORSE_IDLE, "mob.horse.idle");
|
||||
set(HORSE_JUMP, "mob.horse.jump");
|
||||
set(HORSE_LAND, "mob.horse.land");
|
||||
set(HORSE_SADDLE, "mob.horse.leather");
|
||||
set(HORSE_SOFT, "mob.horse.soft");
|
||||
set(HORSE_WOOD, "mob.horse.wood");
|
||||
set(DONKEY_ANGRY, "mob.horse.donkey.angry");
|
||||
set(DONKEY_DEATH, "mob.horse.donkey.death");
|
||||
set(DONKEY_HIT, "mob.horse.donkey.hit");
|
||||
set(DONKEY_IDLE, "mob.horse.donkey.idle");
|
||||
set(HORSE_SKELETON_DEATH, "mob.horse.skeleton.death");
|
||||
set(HORSE_SKELETON_HIT, "mob.horse.skeleton.hit");
|
||||
set(HORSE_SKELETON_IDLE, "mob.horse.skeleton.idle");
|
||||
set(HORSE_ZOMBIE_DEATH, "mob.horse.zombie.death");
|
||||
set(HORSE_ZOMBIE_HIT, "mob.horse.zombie.hit");
|
||||
set(HORSE_ZOMBIE_IDLE, "mob.horse.zombie.idle");
|
||||
set(IRONGOLEM_DEATH, "mob.irongolem.death");
|
||||
set(IRONGOLEM_HIT, "mob.irongolem.hit");
|
||||
set(IRONGOLEM_THROW, "mob.irongolem.throw");
|
||||
set(IRONGOLEM_WALK, "mob.irongolem.walk");
|
||||
set(MAGMACUBE_WALK, "mob.magmacube.small");
|
||||
set(MAGMACUBE_WALK2, "mob.magmacube.big");
|
||||
set(MAGMACUBE_JUMP, "mob.magmacube.jump");
|
||||
set(PIG_IDLE, "mob.pig.say");
|
||||
set(PIG_DEATH, "mob.pig.death");
|
||||
set(PIG_WALK, "mob.pig.step");
|
||||
set(SHEEP_IDLE, "mob.sheep.say");
|
||||
set(SHEEP_SHEAR, "mob.sheep.shear");
|
||||
set(SHEEP_WALK, "mob.sheep.step");
|
||||
set(SILVERFISH_HIT, "mob.silverfish.hit");
|
||||
set(SILVERFISH_KILL, "mob.silverfish.kill");
|
||||
set(SILVERFISH_IDLE, "mob.silverfish.say");
|
||||
set(SILVERFISH_WALK, "mob.silverfish.step");
|
||||
set(SKELETON_IDLE, "mob.skeleton.say");
|
||||
set(SKELETON_DEATH, "mob.skeleton.death");
|
||||
set(SKELETON_HURT, "mob.skeleton.hurt");
|
||||
set(SKELETON_WALK, "mob.skeleton.step");
|
||||
set(SLIME_ATTACK, "mob.slime.attack");
|
||||
set(SLIME_WALK, "mob.slime.small");
|
||||
set(SLIME_WALK2, "mob.slime.big");
|
||||
set(SPIDER_IDLE, "mob.spider.say");
|
||||
set(SPIDER_DEATH, "mob.spider.death");
|
||||
set(SPIDER_WALK, "mob.spider.step");
|
||||
set(VILLAGER_DEATH, "mob.villager.death");
|
||||
set(VILLAGER_HAGGLE, "mob.villager.haggle");
|
||||
set(VILLAGER_HIT, "mob.villager.hit");
|
||||
set(VILLAGER_IDLE, "mob.villager.idle");
|
||||
set(VILLAGER_NO, "mob.villager.no");
|
||||
set(VILLAGER_YES, "mob.villager.yes");
|
||||
set(WITHER_DEATH, "mob.wither.death");
|
||||
set(WITHER_HURT, "mob.wither.hurt");
|
||||
set(WITHER_IDLE, "mob.wither.idle");
|
||||
set(WITHER_SHOOT, "mob.wither.shoot");
|
||||
set(WITHER_SPAWN, "mob.wither.spawn");
|
||||
set(WOLF_BARK, "mob.wolf.bark");
|
||||
set(WOLF_DEATH, "mob.wolf.death");
|
||||
set(WOLF_GROWL, "mob.wolf.growl");
|
||||
set(WOLF_HOWL, "mob.wolf.howl");
|
||||
set(WOLF_HURT, "mob.wolf.hurt");
|
||||
set(WOLF_PANT, "mob.wolf.panting");
|
||||
set(WOLF_SHAKE, "mob.wolf.shake");
|
||||
set(WOLF_WALK, "mob.wolf.step");
|
||||
set(WOLF_WHINE, "mob.wolf.whine");
|
||||
set(ZOMBIE_METAL, "mob.zombie.metal");
|
||||
set(ZOMBIE_WOOD, "mob.zombie.wood");
|
||||
set(ZOMBIE_WOODBREAK, "mob.zombie.woodbreak");
|
||||
set(ZOMBIE_IDLE, "mob.zombie.say");
|
||||
set(ZOMBIE_DEATH, "mob.zombie.death");
|
||||
set(ZOMBIE_HURT, "mob.zombie.hurt");
|
||||
set(ZOMBIE_INFECT, "mob.zombie.infect");
|
||||
set(ZOMBIE_UNFECT, "mob.zombie.unfect");
|
||||
set(ZOMBIE_REMEDY, "mob.zombie.remedy");
|
||||
set(ZOMBIE_WALK, "mob.zombie.step");
|
||||
set(ZOMBIE_PIG_IDLE, "mob.zombiepig.zpig");
|
||||
set(ZOMBIE_PIG_ANGRY, "mob.zombiepig.zpigangry");
|
||||
set(ZOMBIE_PIG_DEATH, "mob.zombiepig.zpigdeath");
|
||||
set(ZOMBIE_PIG_HURT, "mob.zombiepig.zpighurt");
|
||||
// Note (blocks)
|
||||
set(NOTE_BASS_GUITAR, "note.bassattack");
|
||||
set(NOTE_SNARE_DRUM, "note.snare");
|
||||
set(NOTE_PLING, "note.pling");
|
||||
set(NOTE_BASS, "note.bass");
|
||||
set(NOTE_PIANO, "note.harp");
|
||||
set(NOTE_BASS_DRUM, "note.bd");
|
||||
set(NOTE_STICKS, "note.hat");
|
||||
// Portal
|
||||
set(PORTAL, "portal.portal");
|
||||
set(PORTAL_TRAVEL, "portal.travel");
|
||||
set(PORTAL_TRIGGER, "portal.trigger");
|
||||
// Random
|
||||
set(ANVIL_BREAK, "random.anvil_break");
|
||||
set(ANVIL_LAND, "random.anvil_land");
|
||||
set(ANVIL_USE, "random.anvil_use");
|
||||
set(SHOOT_ARROW, "random.bow");
|
||||
set(ARROW_HIT, "random.bowhit");
|
||||
set(ITEM_BREAK, "random.break");
|
||||
set(BURP, "random.burp");
|
||||
set(CHEST_CLOSE, "random.chestclosed");
|
||||
set(CHEST_OPEN, "random.chestopen");
|
||||
set(CLICK, "random.click");
|
||||
set(DOOR_CLOSE, "random.door_close");
|
||||
set(DOOR_OPEN, "random.door_open");
|
||||
set(DRINK, "random.drink");
|
||||
set(EAT, "random.eat");
|
||||
set(EXPLODE, "random.explode");
|
||||
set(FIZZ, "random.fizz");
|
||||
set(FUSE, "creeper.primed");
|
||||
set(GLASS, "dig.glass");
|
||||
set(LEVEL_UP, "random.levelup");
|
||||
set(ORB_PICKUP, "random.orb");
|
||||
set(ITEM_PICKUP, "random.pop");
|
||||
set(SPLASH, "random.splash");
|
||||
set(SUCCESSFUL_HIT, "random.successful_hit");
|
||||
set(WOOD_CLICK, "random.wood_click");
|
||||
// Step
|
||||
set(STEP_WOOL, "step.cloth");
|
||||
set(STEP_GRASS, "step.grass");
|
||||
set(STEP_GRAVEL, "step.gravel");
|
||||
set(STEP_LADDER, "step.ladder");
|
||||
set(STEP_SAND, "step.sand");
|
||||
set(STEP_SNOW, "step.snow");
|
||||
set(STEP_STONE, "step.stone");
|
||||
set(STEP_WOOD, "step.wood");
|
||||
// Tile
|
||||
set(PISTON_EXTEND, "tile.piston.out");
|
||||
set(PISTON_RETRACT, "tile.piston.in");
|
||||
}
|
||||
|
||||
private static void set(Sound sound, String key) {
|
||||
sounds[sound.ordinal()] = key;
|
||||
}
|
||||
|
||||
public static String getSound(final Sound sound) {
|
||||
Validate.notNull(sound, "Sound cannot be null");
|
||||
return sounds[sound.ordinal()];
|
||||
}
|
||||
|
||||
private CraftSound() {}
|
||||
}
|
||||
142
src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
Normal file
142
src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityList.EntityEggInfo;
|
||||
import net.minecraft.stats.StatList;
|
||||
|
||||
import org.bukkit.Achievement;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
public class CraftStatistic {
|
||||
private static final BiMap<String, org.bukkit.Statistic> statistics;
|
||||
private static final BiMap<String, org.bukkit.Achievement> achievements;
|
||||
|
||||
static {
|
||||
ImmutableMap<String, org.bukkit.Achievement> specialCases = ImmutableMap.<String, org.bukkit.Achievement> builder()
|
||||
.put("achievement.buildWorkBench", Achievement.BUILD_WORKBENCH)
|
||||
.put("achievement.diamonds", Achievement.GET_DIAMONDS)
|
||||
.put("achievement.portal", Achievement.NETHER_PORTAL)
|
||||
.put("achievement.ghast", Achievement.GHAST_RETURN)
|
||||
.put("achievement.theEnd", Achievement.END_PORTAL)
|
||||
.put("achievement.theEnd2", Achievement.THE_END)
|
||||
.put("achievement.blazeRod", Achievement.GET_BLAZE_ROD)
|
||||
.put("achievement.potion", Achievement.BREW_POTION)
|
||||
.build();
|
||||
ImmutableBiMap.Builder<String, org.bukkit.Statistic> statisticBuilder = ImmutableBiMap.<String, org.bukkit.Statistic>builder();
|
||||
ImmutableBiMap.Builder<String, org.bukkit.Achievement> achievementBuilder = ImmutableBiMap.<String, org.bukkit.Achievement>builder();
|
||||
for (Statistic statistic : Statistic.values()) {
|
||||
if (statistic == Statistic.PLAY_ONE_TICK) {
|
||||
statisticBuilder.put("stat.playOneMinute", statistic);
|
||||
} else {
|
||||
statisticBuilder.put("stat." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, statistic.name()), statistic);
|
||||
}
|
||||
}
|
||||
for (Achievement achievement : Achievement.values()) {
|
||||
if (specialCases.values().contains(achievement)) {
|
||||
continue;
|
||||
}
|
||||
achievementBuilder.put("achievement." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, achievement.name()), achievement);
|
||||
}
|
||||
|
||||
achievementBuilder.putAll(specialCases);
|
||||
|
||||
statistics = statisticBuilder.build();
|
||||
achievements = achievementBuilder.build();
|
||||
}
|
||||
|
||||
private CraftStatistic() {}
|
||||
|
||||
public static org.bukkit.Achievement getBukkitAchievement(net.minecraft.stats.Achievement achievement) {
|
||||
return getBukkitAchievementByName(achievement.statId);
|
||||
}
|
||||
|
||||
public static org.bukkit.Achievement getBukkitAchievementByName(String name) {
|
||||
return achievements.get(name);
|
||||
}
|
||||
|
||||
public static org.bukkit.Statistic getBukkitStatistic(net.minecraft.stats.StatBase statistic) {
|
||||
return getBukkitStatisticByName(statistic.statId);
|
||||
}
|
||||
|
||||
public static org.bukkit.Statistic getBukkitStatisticByName(String name) {
|
||||
if (name.startsWith("stat.killEntity")) {
|
||||
name = "stat.killEntity";
|
||||
}
|
||||
if (name.startsWith("stat.entityKilledBy")) {
|
||||
name = "stat.entityKilledBy";
|
||||
}
|
||||
if (name.startsWith("stat.breakItem")) {
|
||||
name = "stat.breakItem";
|
||||
}
|
||||
if (name.startsWith("stat.useItem")) {
|
||||
name = "stat.useItem";
|
||||
}
|
||||
if (name.startsWith("stat.mineBlock")) {
|
||||
name = "stat.mineBlock";
|
||||
}
|
||||
if (name.startsWith("stat.craftItem")) {
|
||||
name = "stat.craftItem";
|
||||
}
|
||||
return statistics.get(name);
|
||||
}
|
||||
|
||||
public static net.minecraft.stats.StatBase getNMSStatistic(org.bukkit.Statistic statistic) {
|
||||
return StatList.func_151177_a(statistics.inverse().get(statistic));
|
||||
}
|
||||
|
||||
public static net.minecraft.stats.Achievement getNMSAchievement(org.bukkit.Achievement achievement) {
|
||||
return (net.minecraft.stats.Achievement) StatList.func_151177_a(achievements.inverse().get(achievement));
|
||||
}
|
||||
|
||||
public static net.minecraft.stats.StatBase getMaterialStatistic(org.bukkit.Statistic stat, Material material) {
|
||||
try {
|
||||
if (stat == Statistic.MINE_BLOCK) {
|
||||
return StatList.mineBlockStatArray[material.getId()];
|
||||
}
|
||||
if (stat == Statistic.CRAFT_ITEM) {
|
||||
return StatList.objectCraftStats[material.getId()];
|
||||
}
|
||||
if (stat == Statistic.USE_ITEM) {
|
||||
return StatList.objectUseStats[material.getId()];
|
||||
}
|
||||
if (stat == Statistic.BREAK_ITEM) {
|
||||
return StatList.objectBreakStats[material.getId()];
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static net.minecraft.stats.StatBase getEntityStatistic(org.bukkit.Statistic stat, EntityType entity) {
|
||||
EntityEggInfo entityEggInfo = (EntityEggInfo) EntityList.entityEggs.get(Integer.valueOf(entity.getTypeId()));
|
||||
|
||||
if (entityEggInfo != null) {
|
||||
return entityEggInfo.field_151512_d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EntityType getEntityTypeFromStatistic(net.minecraft.stats.StatBase statistic) {
|
||||
String statisticString = statistic.statId;
|
||||
return EntityType.fromName(statisticString.substring(statisticString.lastIndexOf(".") + 1));
|
||||
}
|
||||
|
||||
public static Material getMaterialFromStatistic(net.minecraft.stats.StatBase statistic) {
|
||||
String statisticString = statistic.statId;
|
||||
int id;
|
||||
try {
|
||||
id = Integer.valueOf(statisticString.substring(statisticString.lastIndexOf(".") + 1));
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
return Material.getMaterial(id);
|
||||
}
|
||||
}
|
||||
76
src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java
Normal file
76
src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.TravelAgent;
|
||||
|
||||
public class CraftTravelAgent extends net.minecraft.world.Teleporter implements TravelAgent {
|
||||
|
||||
public static TravelAgent DEFAULT = null;
|
||||
|
||||
private int searchRadius = 128;
|
||||
private int creationRadius = 16;
|
||||
private boolean canCreatePortal = true;
|
||||
|
||||
public CraftTravelAgent(net.minecraft.world.WorldServer worldserver) {
|
||||
super(worldserver);
|
||||
if (DEFAULT == null && worldserver.provider.dimensionId == 0) { // Cauldron
|
||||
DEFAULT = this;
|
||||
}
|
||||
}
|
||||
|
||||
public Location findOrCreate(Location target) {
|
||||
net.minecraft.world.WorldServer worldServer = ((CraftWorld) target.getWorld()).getHandle();
|
||||
boolean before = worldServer.theChunkProviderServer.loadChunkOnProvideRequest;
|
||||
worldServer.theChunkProviderServer.loadChunkOnProvideRequest = true;
|
||||
|
||||
Location found = this.findPortal(target);
|
||||
if (found == null) {
|
||||
if (this.getCanCreatePortal() && this.createPortal(target)) {
|
||||
found = this.findPortal(target);
|
||||
} else {
|
||||
found = target; // fallback to original if unable to find or create
|
||||
}
|
||||
}
|
||||
|
||||
worldServer.theChunkProviderServer.loadChunkOnProvideRequest = before;
|
||||
return found;
|
||||
}
|
||||
|
||||
public Location findPortal(Location location) {
|
||||
net.minecraft.world.Teleporter pta = ((CraftWorld) location.getWorld()).getHandle().getDefaultTeleporter(); // Should be getTravelAgent
|
||||
net.minecraft.util.ChunkCoordinates found = pta.findPortal(location.getX(), location.getY(), location.getZ(), this.getSearchRadius());
|
||||
return found != null ? new Location(location.getWorld(), found.posX, found.posY, found.posZ, location.getYaw(), location.getPitch()) : null;
|
||||
}
|
||||
|
||||
public boolean createPortal(Location location) {
|
||||
net.minecraft.world.Teleporter pta = ((CraftWorld) location.getWorld()).getHandle().getDefaultTeleporter();
|
||||
return pta.createPortal(location.getX(), location.getY(), location.getZ(), this.getCreationRadius());
|
||||
}
|
||||
|
||||
public TravelAgent setSearchRadius(int radius) {
|
||||
this.searchRadius = radius;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getSearchRadius() {
|
||||
return this.searchRadius;
|
||||
}
|
||||
|
||||
public TravelAgent setCreationRadius(int radius) {
|
||||
this.creationRadius = radius < 2 ? 0 : radius;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getCreationRadius() {
|
||||
return this.creationRadius;
|
||||
}
|
||||
|
||||
public boolean getCanCreatePortal() {
|
||||
return this.canCreatePortal;
|
||||
}
|
||||
|
||||
public void setCanCreatePortal(boolean create) {
|
||||
this.canCreatePortal = create;
|
||||
}
|
||||
}
|
||||
1468
src/main/java/org/bukkit/craftbukkit/CraftWorld.java
Normal file
1468
src/main/java/org/bukkit/craftbukkit/CraftWorld.java
Normal file
File diff suppressed because it is too large
Load Diff
31
src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java
Normal file
31
src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class LoggerOutputStream extends ByteArrayOutputStream {
|
||||
private final String separator = System.getProperty("line.separator");
|
||||
private final Logger logger;
|
||||
private final Level level;
|
||||
|
||||
public LoggerOutputStream(Logger logger, Level level) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
synchronized (this) {
|
||||
super.flush();
|
||||
String record = this.toString();
|
||||
super.reset();
|
||||
|
||||
if ((record.length() > 0) && (!record.equals(separator))) {
|
||||
logger.log(level, record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/main/java/org/bukkit/craftbukkit/Overridden.java
Normal file
14
src/main/java/org/bukkit/craftbukkit/Overridden.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates a method needs to be overridden in sub classes
|
||||
*/
|
||||
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Overridden {
|
||||
}
|
||||
178
src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
Normal file
178
src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
Normal file
@@ -0,0 +1,178 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.*;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.spigotmc.CustomTimingsHandler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.craftbukkit.scheduler.CraftTask;
|
||||
|
||||
public class SpigotTimings {
|
||||
|
||||
public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick");
|
||||
public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List");
|
||||
public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler");
|
||||
public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables");
|
||||
public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler");
|
||||
public static final CustomTimingsHandler chunkIOTickTimer = new CustomTimingsHandler("ChunkIOTick");
|
||||
public static final CustomTimingsHandler timeUpdateTimer = new CustomTimingsHandler("Time Update");
|
||||
public static final CustomTimingsHandler serverCommandTimer = new CustomTimingsHandler("Server Command");
|
||||
public static final CustomTimingsHandler worldSaveTimer = new CustomTimingsHandler("World Save");
|
||||
|
||||
public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove");
|
||||
public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity");
|
||||
public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity");
|
||||
public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity");
|
||||
|
||||
public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick");
|
||||
public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI");
|
||||
public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision");
|
||||
public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove");
|
||||
public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest");
|
||||
|
||||
public static final CustomTimingsHandler processQueueTimer = new CustomTimingsHandler("processQueue");
|
||||
public static final CustomTimingsHandler schedulerSyncTimer = new CustomTimingsHandler("** Scheduler - Sync Tasks", JavaPluginLoader.pluginParentTimer);
|
||||
|
||||
public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand");
|
||||
|
||||
public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck");
|
||||
public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive");
|
||||
|
||||
public static final HashMap<String, CustomTimingsHandler> entityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
|
||||
public static final HashMap<String, CustomTimingsHandler> tileEntityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
|
||||
public static final HashMap<String, CustomTimingsHandler> pluginTaskTimingMap = new HashMap<String, CustomTimingsHandler>();
|
||||
|
||||
/**
|
||||
* Gets a timer associated with a plugins tasks.
|
||||
* @param task
|
||||
* @param period
|
||||
* @return
|
||||
*/
|
||||
public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) {
|
||||
if (!task.isSync()) {
|
||||
return null;
|
||||
}
|
||||
String plugin;
|
||||
final CraftTask ctask = (CraftTask) task;
|
||||
|
||||
if (task.getOwner() != null) {
|
||||
plugin = task.getOwner().getDescription().getFullName();
|
||||
} else if (ctask.timingName != null) {
|
||||
plugin = "CraftScheduler";
|
||||
} else {
|
||||
plugin = "Unknown";
|
||||
}
|
||||
String taskname = ctask.getTaskName();
|
||||
|
||||
String name = "Task: " + plugin + " Runnable: " + taskname;
|
||||
if (period > 0) {
|
||||
name += "(interval:" + period +")";
|
||||
} else {
|
||||
name += "(Single)";
|
||||
}
|
||||
CustomTimingsHandler result = pluginTaskTimingMap.get(name);
|
||||
if (result == null) {
|
||||
result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer);
|
||||
pluginTaskTimingMap.put(name, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a named timer for the specified entity type to track type specific timings.
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public static CustomTimingsHandler getEntityTimings(Entity entity) {
|
||||
String entityType = entity.getClass().getSimpleName();
|
||||
CustomTimingsHandler result = entityTypeTimingMap.get(entityType);
|
||||
if (result == null) {
|
||||
result = new CustomTimingsHandler("** tickEntity - " + entityType, activatedEntityTimer);
|
||||
entityTypeTimingMap.put(entityType, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a named timer for the specified tile entity type to track type specific timings.
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public static CustomTimingsHandler getTileEntityTimings(TileEntity entity) {
|
||||
String entityType = entity.getClass().getSimpleName();
|
||||
CustomTimingsHandler result = tileEntityTypeTimingMap.get(entityType);
|
||||
if (result == null) {
|
||||
result = new CustomTimingsHandler("** tickTileEntity - " + entityType, tickTileEntityTimer);
|
||||
tileEntityTypeTimingMap.put(entityType, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of timers per world, to track world specific timings.
|
||||
*/
|
||||
public static class WorldTimingsHandler {
|
||||
public final CustomTimingsHandler mobSpawn;
|
||||
public final CustomTimingsHandler doChunkUnload;
|
||||
public final CustomTimingsHandler doPortalForcer;
|
||||
public final CustomTimingsHandler doTickPending;
|
||||
public final CustomTimingsHandler doTickTiles;
|
||||
public final CustomTimingsHandler doVillages;
|
||||
public final CustomTimingsHandler doChunkMap;
|
||||
public final CustomTimingsHandler doChunkGC;
|
||||
public final CustomTimingsHandler doSounds;
|
||||
public final CustomTimingsHandler entityTick;
|
||||
public final CustomTimingsHandler tileEntityTick;
|
||||
public final CustomTimingsHandler tileEntityPending;
|
||||
public final CustomTimingsHandler tracker;
|
||||
public final CustomTimingsHandler doTick;
|
||||
public final CustomTimingsHandler tickEntities;
|
||||
|
||||
public final CustomTimingsHandler syncChunkLoadTimer;
|
||||
public final CustomTimingsHandler syncChunkLoadDataTimer;
|
||||
public final CustomTimingsHandler syncChunkLoadStructuresTimer;
|
||||
public final CustomTimingsHandler syncChunkLoadEntitiesTimer;
|
||||
public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer;
|
||||
public final CustomTimingsHandler syncChunkLoadTileTicksTimer;
|
||||
public final CustomTimingsHandler syncChunkLoadPostTimer;
|
||||
|
||||
public WorldTimingsHandler(World server) {
|
||||
String name = server.worldInfo.getWorldName() +" - ";
|
||||
|
||||
mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn");
|
||||
doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload");
|
||||
doTickPending = new CustomTimingsHandler("** " + name + "doTickPending");
|
||||
doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles");
|
||||
doVillages = new CustomTimingsHandler("** " + name + "doVillages");
|
||||
doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap");
|
||||
doSounds = new CustomTimingsHandler("** " + name + "doSounds");
|
||||
doChunkGC = new CustomTimingsHandler("** " + name + "doChunkGC");
|
||||
doPortalForcer = new CustomTimingsHandler("** " + name + "doPortalForcer");
|
||||
entityTick = new CustomTimingsHandler("** " + name + "entityTick");
|
||||
tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick");
|
||||
tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending");
|
||||
|
||||
syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad");
|
||||
syncChunkLoadDataTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad - Data");
|
||||
syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures");
|
||||
syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities");
|
||||
syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities");
|
||||
syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks");
|
||||
syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post");
|
||||
|
||||
|
||||
tracker = new CustomTimingsHandler(name + "tracker");
|
||||
doTick = new CustomTimingsHandler(name + "doTick");
|
||||
tickEntities = new CustomTimingsHandler(name + "tickEntities");
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/main/java/org/bukkit/craftbukkit/TrigMath.java
Normal file
47
src/main/java/org/bukkit/craftbukkit/TrigMath.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
/**
|
||||
* Credits for this class goes to user aioobe on stackoverflow.com
|
||||
* Source: http://stackoverflow.com/questions/4454630/j2me-calculate-the-the-distance-between-2-latitude-and-longitude
|
||||
*/
|
||||
public class TrigMath {
|
||||
|
||||
static final double sq2p1 = 2.414213562373095048802e0;
|
||||
static final double sq2m1 = .414213562373095048802e0;
|
||||
static final double p4 = .161536412982230228262e2;
|
||||
static final double p3 = .26842548195503973794141e3;
|
||||
static final double p2 = .11530293515404850115428136e4;
|
||||
static final double p1 = .178040631643319697105464587e4;
|
||||
static final double p0 = .89678597403663861959987488e3;
|
||||
static final double q4 = .5895697050844462222791e2;
|
||||
static final double q3 = .536265374031215315104235e3;
|
||||
static final double q2 = .16667838148816337184521798e4;
|
||||
static final double q1 = .207933497444540981287275926e4;
|
||||
static final double q0 = .89678597403663861962481162e3;
|
||||
static final double PIO2 = 1.5707963267948966135E0;
|
||||
|
||||
private static double mxatan(double arg) {
|
||||
double argsq = arg * arg, value;
|
||||
|
||||
value = ((((p4 * argsq + p3) * argsq + p2) * argsq + p1) * argsq + p0);
|
||||
value = value / (((((argsq + q4) * argsq + q3) * argsq + q2) * argsq + q1) * argsq + q0);
|
||||
return value * arg;
|
||||
}
|
||||
|
||||
private static double msatan(double arg) {
|
||||
return arg < sq2m1 ? mxatan(arg)
|
||||
: arg > sq2p1 ? PIO2 - mxatan(1 / arg)
|
||||
: PIO2 / 2 + mxatan((arg - 1) / (arg + 1));
|
||||
}
|
||||
|
||||
public static double atan(double arg) {
|
||||
return arg > 0 ? msatan(arg) : -msatan(-arg);
|
||||
}
|
||||
|
||||
public static double atan2(double arg1, double arg2) {
|
||||
if (arg1 + arg2 == arg1)
|
||||
return arg1 >= 0 ? PIO2 : -PIO2;
|
||||
arg1 = atan(arg1 / arg2);
|
||||
return arg2 < 0 ? arg1 <= 0 ? arg1 + Math.PI : arg1 - Math.PI : arg1;
|
||||
}
|
||||
}
|
||||
37
src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
Normal file
37
src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityBeacon;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Beacon;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryBeacon;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class CraftBeacon extends CraftBlockState implements Beacon {
|
||||
private final CraftWorld world;
|
||||
private final TileEntityBeacon beacon;
|
||||
|
||||
public CraftBeacon(final Block block) {
|
||||
super(block);
|
||||
|
||||
world = (CraftWorld) block.getWorld();
|
||||
beacon = (TileEntityBeacon) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return new CraftInventoryBeacon(beacon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
beacon.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
621
src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
Normal file
621
src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
Normal file
@@ -0,0 +1,621 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.world.EnumSkyBlock;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.block.BlockCocoa;
|
||||
import net.minecraft.block.BlockRedstoneWire;
|
||||
import net.minecraft.init.Blocks;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.tileentity.TileEntitySkull;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.PistonMoveReaction;
|
||||
import org.bukkit.craftbukkit.CraftChunk;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.BlockVector;
|
||||
// Cauldron start
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraftforge.cauldron.block.CraftCustomContainer;
|
||||
// Cauldron end
|
||||
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
public class CraftBlock implements Block {
|
||||
private final CraftChunk chunk;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
// Cauldron start - add support for custom biomes
|
||||
private static final Biome[] BIOME_MAPPING = new Biome[BiomeGenBase.getBiomeGenArray().length];
|
||||
private static final BiomeGenBase[] BIOMEBASE_MAPPING = new BiomeGenBase[BiomeGenBase.getBiomeGenArray().length];
|
||||
// Cauldron end
|
||||
|
||||
public CraftBlock(CraftChunk chunk, int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
private net.minecraft.block.Block getNMSBlock() {
|
||||
return CraftMagicNumbers.getBlock(this); // TODO: UPDATE THIS
|
||||
}
|
||||
|
||||
private static net.minecraft.block.Block getNMSBlock(int type) {
|
||||
return CraftMagicNumbers.getBlock(type);
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return chunk.getWorld();
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return new Location(getWorld(), x, y, z);
|
||||
}
|
||||
|
||||
public Location getLocation(Location loc) {
|
||||
if (loc != null) {
|
||||
loc.setWorld(getWorld());
|
||||
loc.setX(x);
|
||||
loc.setY(y);
|
||||
loc.setZ(z);
|
||||
loc.setYaw(0);
|
||||
loc.setPitch(0);
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
public BlockVector getVector() {
|
||||
return new BlockVector(x, y, z);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public void setData(final byte data) {
|
||||
chunk.getHandle().worldObj.setBlockMetadataWithNotify(x, y, z, data, 3);
|
||||
}
|
||||
|
||||
public void setData(final byte data, boolean applyPhysics) {
|
||||
if (applyPhysics) {
|
||||
chunk.getHandle().worldObj.setBlockMetadataWithNotify(x, y, z, data, 3);
|
||||
} else {
|
||||
chunk.getHandle().worldObj.setBlockMetadataWithNotify(x, y, z, data, 2);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getData() {
|
||||
return (byte) chunk.getHandle().getBlockMetadata(this.x & 0xF, this.y & 0xFF, this.z & 0xF);
|
||||
}
|
||||
|
||||
public void setType(final Material type) {
|
||||
setTypeId(type.getId());
|
||||
}
|
||||
|
||||
public boolean setTypeId(final int type) {
|
||||
return setTypeId(type, true);
|
||||
}
|
||||
|
||||
public boolean setTypeId(final int type, final boolean applyPhysics) {
|
||||
return setTypeIdAndData(type, getData(), applyPhysics);
|
||||
}
|
||||
|
||||
public boolean setTypeIdAndData(final int type, final byte data, final boolean applyPhysics) {
|
||||
if (applyPhysics) {
|
||||
return chunk.getHandle().worldObj.setBlock(x, y, z, getNMSBlock(type), data, 3);
|
||||
} else {
|
||||
boolean success = chunk.getHandle().worldObj.setBlock(x, y, z, getNMSBlock(type), data, 2);
|
||||
if (success) {
|
||||
chunk.getHandle().worldObj.markBlockForUpdate(x, y, z);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
public Material getType() {
|
||||
return Material.getMaterial(getTypeId());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public int getTypeId() {
|
||||
return CraftMagicNumbers.getId(chunk.getHandle().getBlock(this.x & 0xF, this.y & 0xFF, this.z & 0xF));
|
||||
}
|
||||
|
||||
public byte getLightLevel() {
|
||||
return (byte) chunk.getHandle().worldObj.getBlockLightValue(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
public byte getLightFromSky() {
|
||||
return (byte) chunk.getHandle().getSavedLightValue(EnumSkyBlock.Sky, this.x & 0xF, this.y & 0xFF, this.z & 0xF);
|
||||
}
|
||||
|
||||
public byte getLightFromBlocks() {
|
||||
return (byte) chunk.getHandle().getSavedLightValue(EnumSkyBlock.Block, this.x & 0xF, this.y & 0xFF, this.z & 0xF);
|
||||
}
|
||||
|
||||
|
||||
public Block getFace(final BlockFace face) {
|
||||
return getRelative(face, 1);
|
||||
}
|
||||
|
||||
public Block getFace(final BlockFace face, final int distance) {
|
||||
return getRelative(face, distance);
|
||||
}
|
||||
|
||||
public Block getRelative(final int modX, final int modY, final int modZ) {
|
||||
return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ);
|
||||
}
|
||||
|
||||
public Block getRelative(BlockFace face) {
|
||||
return getRelative(face, 1);
|
||||
}
|
||||
|
||||
public Block getRelative(BlockFace face, int distance) {
|
||||
return getRelative(face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
||||
}
|
||||
|
||||
public BlockFace getFace(final Block block) {
|
||||
BlockFace[] values = BlockFace.values();
|
||||
|
||||
for (BlockFace face : values) {
|
||||
if ((this.getX() + face.getModX() == block.getX()) &&
|
||||
(this.getY() + face.getModY() == block.getY()) &&
|
||||
(this.getZ() + face.getModZ() == block.getZ())
|
||||
) {
|
||||
return face;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftBlock{" + "chunk=" + chunk + ",x=" + x + ",y=" + y + ",z=" + z + ",type=" + getType() + ",data=" + getData() + '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notch uses a 0-5 to mean DOWN, UP, NORTH, SOUTH, WEST, EAST
|
||||
* in that order all over. This method is convenience to convert for us.
|
||||
*
|
||||
* @return BlockFace the BlockFace represented by this number
|
||||
*/
|
||||
public static BlockFace notchToBlockFace(int notch) {
|
||||
switch (notch) {
|
||||
case 0:
|
||||
return BlockFace.DOWN;
|
||||
case 1:
|
||||
return BlockFace.UP;
|
||||
case 2:
|
||||
return BlockFace.NORTH;
|
||||
case 3:
|
||||
return BlockFace.SOUTH;
|
||||
case 4:
|
||||
return BlockFace.WEST;
|
||||
case 5:
|
||||
return BlockFace.EAST;
|
||||
default:
|
||||
return BlockFace.SELF;
|
||||
}
|
||||
}
|
||||
|
||||
public static int blockFaceToNotch(BlockFace face) {
|
||||
switch (face) {
|
||||
case DOWN:
|
||||
return 0;
|
||||
case UP:
|
||||
return 1;
|
||||
case NORTH:
|
||||
return 2;
|
||||
case SOUTH:
|
||||
return 3;
|
||||
case WEST:
|
||||
return 4;
|
||||
case EAST:
|
||||
return 5;
|
||||
default:
|
||||
return 7; // Good as anything here, but technically invalid
|
||||
}
|
||||
}
|
||||
|
||||
public BlockState getState() {
|
||||
Material material = getType();
|
||||
// Cauldron start - if null, check for TE that implements IInventory
|
||||
if (material == null)
|
||||
{
|
||||
TileEntity te = ((CraftWorld)this.getWorld()).getHandle().getTileEntity(this.getX(), this.getY(), this.getZ());
|
||||
if (te != null && te instanceof IInventory)
|
||||
{
|
||||
// In order to allow plugins to properly grab the container location, we must pass a class that extends CraftBlockState and implements InventoryHolder.
|
||||
// Note: This will be returned when TileEntity.getOwner() is called
|
||||
return new CraftCustomContainer(this);
|
||||
}
|
||||
// pass default state
|
||||
return new CraftBlockState(this);
|
||||
}
|
||||
// Cauldron end
|
||||
switch (material) {
|
||||
case SIGN:
|
||||
case SIGN_POST:
|
||||
case WALL_SIGN:
|
||||
return new CraftSign(this);
|
||||
case CHEST:
|
||||
case TRAPPED_CHEST:
|
||||
return new CraftChest(this);
|
||||
case BURNING_FURNACE:
|
||||
case FURNACE:
|
||||
return new CraftFurnace(this);
|
||||
case DISPENSER:
|
||||
return new CraftDispenser(this);
|
||||
case DROPPER:
|
||||
return new CraftDropper(this);
|
||||
case HOPPER:
|
||||
return new CraftHopper(this);
|
||||
case MOB_SPAWNER:
|
||||
return new CraftCreatureSpawner(this);
|
||||
case NOTE_BLOCK:
|
||||
return new CraftNoteBlock(this);
|
||||
case JUKEBOX:
|
||||
return new CraftJukebox(this);
|
||||
case BREWING_STAND:
|
||||
return new CraftBrewingStand(this);
|
||||
case SKULL:
|
||||
return new CraftSkull(this);
|
||||
case COMMAND:
|
||||
return new CraftCommandBlock(this);
|
||||
case BEACON:
|
||||
return new CraftBeacon(this);
|
||||
default:
|
||||
// Cauldron start
|
||||
TileEntity te = ((CraftWorld)this.getWorld()).getHandle().getTileEntity(this.getX(), this.getY(), this.getZ());
|
||||
if (te != null && te instanceof IInventory)
|
||||
{
|
||||
// In order to allow plugins to properly grab the container location, we must pass a class that extends CraftBlockState and implements InventoryHolder.
|
||||
// Note: This will be returned when TileEntity.getOwner() is called
|
||||
return new CraftCustomContainer(this);
|
||||
}
|
||||
// pass default state
|
||||
// Cauldron end
|
||||
return new CraftBlockState(this);
|
||||
}
|
||||
}
|
||||
|
||||
public Biome getBiome() {
|
||||
return getWorld().getBiome(x, z);
|
||||
}
|
||||
|
||||
public void setBiome(Biome bio) {
|
||||
getWorld().setBiome(x, z, bio);
|
||||
}
|
||||
|
||||
public static Biome biomeBaseToBiome(BiomeGenBase base) {
|
||||
if (base == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return BIOME_MAPPING[base.biomeID];
|
||||
}
|
||||
|
||||
public static BiomeGenBase biomeToBiomeBase(Biome bio) {
|
||||
if (bio == null) {
|
||||
return null;
|
||||
}
|
||||
return BIOMEBASE_MAPPING[bio.ordinal()];
|
||||
}
|
||||
|
||||
public double getTemperature() {
|
||||
return getWorld().getTemperature(x, z);
|
||||
}
|
||||
|
||||
public double getHumidity() {
|
||||
return getWorld().getHumidity(x, z);
|
||||
}
|
||||
|
||||
public boolean isBlockPowered() {
|
||||
return chunk.getHandle().worldObj.getBlockPowerInput(x, y, z) > 0;
|
||||
}
|
||||
|
||||
public boolean isBlockIndirectlyPowered() {
|
||||
return chunk.getHandle().worldObj.isBlockIndirectlyGettingPowered(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof CraftBlock)) return false;
|
||||
CraftBlock other = (CraftBlock) o;
|
||||
|
||||
return this.x == other.x && this.y == other.y && this.z == other.z && this.getWorld().equals(other.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.y << 24 ^ this.x ^ this.z ^ this.getWorld().hashCode();
|
||||
}
|
||||
|
||||
public boolean isBlockFacePowered(BlockFace face) {
|
||||
return chunk.getHandle().worldObj.getIndirectPowerOutput(x, y, z, blockFaceToNotch(face));
|
||||
}
|
||||
|
||||
public boolean isBlockFaceIndirectlyPowered(BlockFace face) {
|
||||
int power = chunk.getHandle().worldObj.getIndirectPowerLevelTo(x, y, z, blockFaceToNotch(face));
|
||||
|
||||
Block relative = getRelative(face);
|
||||
if (relative.getType() == Material.REDSTONE_WIRE) {
|
||||
return Math.max(power, relative.getData()) > 0;
|
||||
}
|
||||
|
||||
return power > 0;
|
||||
}
|
||||
|
||||
public int getBlockPower(BlockFace face) {
|
||||
int power = 0;
|
||||
BlockRedstoneWire wire = Blocks.redstone_wire;
|
||||
net.minecraft.world.World world = chunk.getHandle().worldObj;
|
||||
if ((face == BlockFace.DOWN || face == BlockFace.SELF) && world.getIndirectPowerOutput(x, y - 1, z, 0)) power = wire.func_150178_a(world, x, y - 1, z, power);
|
||||
if ((face == BlockFace.UP || face == BlockFace.SELF) && world.getIndirectPowerOutput(x, y + 1, z, 1)) power = wire.func_150178_a(world, x, y + 1, z, power);
|
||||
if ((face == BlockFace.EAST || face == BlockFace.SELF) && world.getIndirectPowerOutput(x + 1, y, z, 2)) power = wire.func_150178_a(world, x + 1, y, z, power);
|
||||
if ((face == BlockFace.WEST || face == BlockFace.SELF) && world.getIndirectPowerOutput(x - 1, y, z, 3)) power = wire.func_150178_a(world, x - 1, y, z, power);
|
||||
if ((face == BlockFace.NORTH || face == BlockFace.SELF) && world.getIndirectPowerOutput(x, y, z - 1, 4)) power = wire.func_150178_a(world, x, y, z - 1, power);
|
||||
if ((face == BlockFace.SOUTH || face == BlockFace.SELF) && world.getIndirectPowerOutput(x, y, z + 1, 5)) power = wire.func_150178_a(world, x, y, z - 1, power);
|
||||
return power > 0 ? power : (face == BlockFace.SELF ? isBlockIndirectlyPowered() : isBlockFaceIndirectlyPowered(face)) ? 15 : 0;
|
||||
}
|
||||
|
||||
public int getBlockPower() {
|
||||
return getBlockPower(BlockFace.SELF);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
// Cauldron start - support custom air blocks (Railcraft player aura tracking block)
|
||||
//return getType() == Material.AIR;
|
||||
if (getType() == Material.AIR) return true;
|
||||
if (!(getWorld() instanceof CraftWorld)) return false;
|
||||
return ((CraftWorld) getWorld()).getHandle().isAirBlock(getX(), getY(), getZ());
|
||||
// Cauldron end
|
||||
}
|
||||
|
||||
public boolean isLiquid() {
|
||||
return (getType() == Material.WATER) || (getType() == Material.STATIONARY_WATER) || (getType() == Material.LAVA) || (getType() == Material.STATIONARY_LAVA);
|
||||
}
|
||||
|
||||
public PistonMoveReaction getPistonMoveReaction() {
|
||||
return PistonMoveReaction.getById(getNMSBlock().getMaterial().getMaterialMobility());
|
||||
}
|
||||
|
||||
private boolean itemCausesDrops(ItemStack item) {
|
||||
net.minecraft.block.Block block = this.getNMSBlock();
|
||||
net.minecraft.item.Item itemType = item != null ? net.minecraft.item.Item.getItemById(item.getTypeId()) : null;
|
||||
return block != null && (block.getMaterial().isToolNotRequired() || (itemType != null && itemType.func_150897_b(block)));
|
||||
}
|
||||
|
||||
public boolean breakNaturally() {
|
||||
// Order matters here, need to drop before setting to air so skulls can get their data
|
||||
net.minecraft.block.Block block = this.getNMSBlock();
|
||||
byte data = getData();
|
||||
boolean result = false;
|
||||
|
||||
if (block != null && block != Blocks.air) {
|
||||
block.dropBlockAsItemWithChance(chunk.getHandle().worldObj, x, y, z, data, 1.0F, 0);
|
||||
result = true;
|
||||
}
|
||||
|
||||
setTypeId(Material.AIR.getId());
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean breakNaturally(ItemStack item) {
|
||||
if (itemCausesDrops(item)) {
|
||||
return breakNaturally();
|
||||
} else {
|
||||
return setTypeId(Material.AIR.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<ItemStack> getDrops() {
|
||||
List<ItemStack> drops = new ArrayList<ItemStack>();
|
||||
|
||||
net.minecraft.block.Block block = this.getNMSBlock();
|
||||
if (block != Blocks.air) {
|
||||
byte data = getData();
|
||||
// based on nms.Block.dropNaturally
|
||||
int count = block.quantityDroppedWithBonus(0, chunk.getHandle().worldObj.rand);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Item item = block.getItemDropped(data, chunk.getHandle().worldObj.rand, 0);
|
||||
if (item != null) {
|
||||
// Skulls are special, their data is based on the tile entity
|
||||
if (Blocks.skull == block) {
|
||||
net.minecraft.item.ItemStack nmsStack = new net.minecraft.item.ItemStack(item, 1, block.getDamageValue(chunk.getHandle().worldObj, x, y, z));
|
||||
TileEntitySkull tileentityskull = (TileEntitySkull) chunk.getHandle().worldObj.getTileEntity(x, y, z);
|
||||
|
||||
if (tileentityskull.func_145904_a() == 3 && tileentityskull.func_152108_a() != null) {
|
||||
nmsStack.setTagCompound(new NBTTagCompound());
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
|
||||
NBTUtil.func_152460_a(nbttagcompound, tileentityskull.func_152108_a());
|
||||
nmsStack.getTagCompound().setTag("SkullOwner", nbttagcompound);
|
||||
}
|
||||
|
||||
drops.add(CraftItemStack.asBukkitCopy(nmsStack));
|
||||
// We don't want to drop cocoa blocks, we want to drop cocoa beans.
|
||||
} else if (Blocks.cocoa == block) {
|
||||
int dropAmount = (BlockCocoa.func_149987_c(data) >= 2 ? 3 : 1);
|
||||
for (int j = 0; j < dropAmount; ++j) {
|
||||
drops.add(new ItemStack(Material.INK_SACK, 1, (short) 3));
|
||||
}
|
||||
} else {
|
||||
drops.add(new ItemStack(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(item), 1, (short) block.damageDropped(data)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return drops;
|
||||
}
|
||||
|
||||
public Collection<ItemStack> getDrops(ItemStack item) {
|
||||
if (itemCausesDrops(item)) {
|
||||
return getDrops();
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/* Build biome index based lookup table for BiomeBase to Biome mapping */
|
||||
public static void initMappings() { // Cauldron - initializer to initMappings() method; called in CraftServer
|
||||
//BIOME_MAPPING = new Biome[BiomeGenBase.biomeList.length]; // Cauldron - move up
|
||||
//BIOMEBASE_MAPPING = new BiomeGenBase[Biome.values().length]; // Cauldron - move up
|
||||
BIOME_MAPPING[BiomeGenBase.swampland.biomeID] = Biome.SWAMPLAND;
|
||||
BIOME_MAPPING[BiomeGenBase.forest.biomeID] = Biome.FOREST;
|
||||
BIOME_MAPPING[BiomeGenBase.taiga.biomeID] = Biome.TAIGA;
|
||||
BIOME_MAPPING[BiomeGenBase.desert.biomeID] = Biome.DESERT;
|
||||
BIOME_MAPPING[BiomeGenBase.plains.biomeID] = Biome.PLAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.hell.biomeID] = Biome.HELL;
|
||||
BIOME_MAPPING[BiomeGenBase.sky.biomeID] = Biome.SKY;
|
||||
BIOME_MAPPING[BiomeGenBase.river.biomeID] = Biome.RIVER;
|
||||
BIOME_MAPPING[BiomeGenBase.extremeHills.biomeID] = Biome.EXTREME_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.ocean.biomeID] = Biome.OCEAN;
|
||||
BIOME_MAPPING[BiomeGenBase.frozenOcean.biomeID] = Biome.FROZEN_OCEAN;
|
||||
BIOME_MAPPING[BiomeGenBase.frozenRiver.biomeID] = Biome.FROZEN_RIVER;
|
||||
BIOME_MAPPING[BiomeGenBase.icePlains.biomeID] = Biome.ICE_PLAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.iceMountains.biomeID] = Biome.ICE_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.mushroomIsland.biomeID] = Biome.MUSHROOM_ISLAND;
|
||||
BIOME_MAPPING[BiomeGenBase.mushroomIslandShore.biomeID] = Biome.MUSHROOM_SHORE;
|
||||
BIOME_MAPPING[BiomeGenBase.beach.biomeID] = Biome.BEACH;
|
||||
BIOME_MAPPING[BiomeGenBase.desertHills.biomeID] = Biome.DESERT_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.forestHills.biomeID] = Biome.FOREST_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.taigaHills.biomeID] = Biome.TAIGA_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.extremeHillsEdge.biomeID] = Biome.SMALL_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.jungle.biomeID] = Biome.JUNGLE;
|
||||
BIOME_MAPPING[BiomeGenBase.jungleHills.biomeID] = Biome.JUNGLE_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.jungleEdge.biomeID] = Biome.JUNGLE_EDGE;
|
||||
BIOME_MAPPING[BiomeGenBase.deepOcean.biomeID] = Biome.DEEP_OCEAN;
|
||||
BIOME_MAPPING[BiomeGenBase.stoneBeach.biomeID] = Biome.STONE_BEACH;
|
||||
BIOME_MAPPING[BiomeGenBase.coldBeach.biomeID] = Biome.COLD_BEACH;
|
||||
BIOME_MAPPING[BiomeGenBase.birchForest.biomeID] = Biome.BIRCH_FOREST;
|
||||
BIOME_MAPPING[BiomeGenBase.birchForestHills.biomeID] = Biome.BIRCH_FOREST_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.roofedForest.biomeID] = Biome.ROOFED_FOREST;
|
||||
BIOME_MAPPING[BiomeGenBase.coldTaiga.biomeID] = Biome.COLD_TAIGA;
|
||||
BIOME_MAPPING[BiomeGenBase.coldTaigaHills.biomeID] = Biome.COLD_TAIGA_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.megaTaiga.biomeID] = Biome.MEGA_TAIGA;
|
||||
BIOME_MAPPING[BiomeGenBase.megaTaigaHills.biomeID] = Biome.MEGA_TAIGA_HILLS;
|
||||
BIOME_MAPPING[BiomeGenBase.extremeHillsPlus.biomeID] = Biome.EXTREME_HILLS_PLUS;
|
||||
BIOME_MAPPING[BiomeGenBase.savanna.biomeID] = Biome.SAVANNA;
|
||||
BIOME_MAPPING[BiomeGenBase.savannaPlateau.biomeID] = Biome.SAVANNA_PLATEAU;
|
||||
BIOME_MAPPING[BiomeGenBase.mesa.biomeID] = Biome.MESA;
|
||||
BIOME_MAPPING[BiomeGenBase.mesaPlateau_F.biomeID] = Biome.MESA_PLATEAU_FOREST;
|
||||
BIOME_MAPPING[BiomeGenBase.mesaPlateau.biomeID] = Biome.MESA_PLATEAU;
|
||||
|
||||
// Extended Biomes
|
||||
BIOME_MAPPING[BiomeGenBase.plains.biomeID + 128] = Biome.SUNFLOWER_PLAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.desert.biomeID + 128] = Biome.DESERT_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.forest.biomeID + 128] = Biome.FLOWER_FOREST;
|
||||
BIOME_MAPPING[BiomeGenBase.taiga.biomeID + 128] = Biome.TAIGA_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.swampland.biomeID + 128] = Biome.SWAMPLAND_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.icePlains.biomeID + 128] = Biome.ICE_PLAINS_SPIKES;
|
||||
BIOME_MAPPING[BiomeGenBase.jungle.biomeID + 128] = Biome.JUNGLE_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.jungleEdge.biomeID + 128] = Biome.JUNGLE_EDGE_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.coldTaiga.biomeID + 128] = Biome.COLD_TAIGA_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.savanna.biomeID + 128] = Biome.SAVANNA_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.savannaPlateau.biomeID + 128] = Biome.SAVANNA_PLATEAU_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.mesa.biomeID + 128] = Biome.MESA_BRYCE;
|
||||
BIOME_MAPPING[BiomeGenBase.mesaPlateau_F.biomeID + 128] = Biome.MESA_PLATEAU_FOREST_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.mesaPlateau.biomeID + 128] = Biome.MESA_PLATEAU_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.birchForest.biomeID + 128] = Biome.BIRCH_FOREST_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.birchForestHills.biomeID + 128] = Biome.BIRCH_FOREST_HILLS_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.roofedForest.biomeID + 128] = Biome.ROOFED_FOREST_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.megaTaiga.biomeID + 128] = Biome.MEGA_SPRUCE_TAIGA;
|
||||
BIOME_MAPPING[BiomeGenBase.extremeHills.biomeID + 128] = Biome.EXTREME_HILLS_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.extremeHillsPlus.biomeID + 128] = Biome.EXTREME_HILLS_PLUS_MOUNTAINS;
|
||||
BIOME_MAPPING[BiomeGenBase.megaTaigaHills.biomeID + 128] = Biome.MEGA_SPRUCE_TAIGA_HILLS;
|
||||
|
||||
/* Sanity check - we should have a record for each record in the BiomeBase.a table */
|
||||
/* Helps avoid missed biomes when we upgrade bukkit to new code with new biomes */
|
||||
for (int i = 0; i < BIOME_MAPPING.length; i++) {
|
||||
if ((BiomeGenBase.getBiome(i) != null) && (BIOME_MAPPING[i] == null)) {
|
||||
// Cauldron start - add support for mod biomes
|
||||
//throw new IllegalArgumentException("Missing Biome mapping for BiomeBase[" + i + "]");
|
||||
String name = BiomeGenBase.getBiome(i).biomeName;
|
||||
int id = BiomeGenBase.getBiome(i).biomeID;
|
||||
|
||||
System.out.println("Adding biome mapping " + BiomeGenBase.getBiome(i).biomeID + " " + name + " at BiomeBase[" + i + "]");
|
||||
net.minecraftforge.common.util.EnumHelper.addBukkitBiome(name); // Forge
|
||||
BIOME_MAPPING[BiomeGenBase.getBiome(i).biomeID] = ((Biome) Enum.valueOf(Biome.class, name));
|
||||
// Cauldron end
|
||||
}
|
||||
if (BIOME_MAPPING[i] != null) { /* Build reverse mapping for setBiome */
|
||||
BIOMEBASE_MAPPING[BIOME_MAPPING[i].ordinal()] = BiomeGenBase.getBiome(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cauldron start - if cauldron.dump-materials is true, dump all materials with their corresponding id's
|
||||
public static void dumpMaterials() {
|
||||
if (MinecraftServer.getServer().cauldronConfig.dumpMaterials.getValue())
|
||||
{
|
||||
FMLLog.info("Cauldron Dump Materials is ENABLED. Starting dump...");
|
||||
for (int i = 0; i < 32000; i++)
|
||||
{
|
||||
Material material = Material.getMaterial(i);
|
||||
if (material != null)
|
||||
{
|
||||
FMLLog.info("Found material " + material + " with ID " + i);
|
||||
}
|
||||
}
|
||||
FMLLog.info("Cauldron Dump Materials complete.");
|
||||
FMLLog.info("To disable these dumps, set cauldron.dump-materials to false in bukkit.yml.");
|
||||
}
|
||||
}
|
||||
// Cauldron end
|
||||
|
||||
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
|
||||
chunk.getCraftWorld().getBlockMetadata().setMetadata(this, metadataKey, newMetadataValue);
|
||||
}
|
||||
|
||||
public List<MetadataValue> getMetadata(String metadataKey) {
|
||||
return chunk.getCraftWorld().getBlockMetadata().getMetadata(this, metadataKey);
|
||||
}
|
||||
|
||||
public boolean hasMetadata(String metadataKey) {
|
||||
return chunk.getCraftWorld().getBlockMetadata().hasMetadata(this, metadataKey);
|
||||
}
|
||||
|
||||
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
|
||||
chunk.getCraftWorld().getBlockMetadata().removeMetadata(this, metadataKey, owningPlugin);
|
||||
}
|
||||
}
|
||||
284
src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
Normal file
284
src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
Normal file
@@ -0,0 +1,284 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.CraftChunk;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
// Cauldron start
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
// Cauldron end
|
||||
|
||||
public class CraftBlockState implements BlockState {
|
||||
private final CraftWorld world;
|
||||
private final CraftChunk chunk;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
private final NBTTagCompound nbt; // Cauldron
|
||||
protected int type;
|
||||
protected MaterialData data;
|
||||
protected int flag;
|
||||
protected final byte light;
|
||||
|
||||
public CraftBlockState(final Block block) {
|
||||
this.world = (CraftWorld) block.getWorld();
|
||||
this.x = block.getX();
|
||||
this.y = block.getY();
|
||||
this.z = block.getZ();
|
||||
this.type = block.getTypeId();
|
||||
this.light = block.getLightLevel();
|
||||
this.chunk = (CraftChunk) block.getChunk();
|
||||
this.flag = 3;
|
||||
// Cauldron start - save TE data
|
||||
TileEntity te = world.getHandle().getTileEntity(x, y, z);
|
||||
if (te != null)
|
||||
{
|
||||
nbt = new NBTTagCompound();
|
||||
te.writeToNBT(nbt);
|
||||
}
|
||||
else nbt = null;
|
||||
// Cauldron end
|
||||
|
||||
createData(block.getData());
|
||||
}
|
||||
|
||||
public CraftBlockState(final Block block, int flag) {
|
||||
this(block);
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public static CraftBlockState getBlockState(net.minecraft.world.World world, int x, int y, int z) {
|
||||
return new CraftBlockState(world.getWorld().getBlockAt(x, y, z));
|
||||
}
|
||||
|
||||
public static CraftBlockState getBlockState(net.minecraft.world.World world, int x, int y, int z, int flag) {
|
||||
return new CraftBlockState(world.getWorld().getBlockAt(x, y, z), flag);
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public void setData(final MaterialData data) {
|
||||
Material mat = getType();
|
||||
|
||||
if ((mat == null) || (mat.getData() == null)) {
|
||||
this.data = data;
|
||||
} else {
|
||||
if ((data.getClass() == mat.getData()) || (data.getClass() == MaterialData.class)) {
|
||||
this.data = data;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Provided data is not of type "
|
||||
+ mat.getData().getName() + ", found " + data.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setType(final Material type) {
|
||||
setTypeId(type.getId());
|
||||
}
|
||||
|
||||
public boolean setTypeId(final int type) {
|
||||
if (this.type != type) {
|
||||
this.type = type;
|
||||
|
||||
createData((byte) 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Material getType() {
|
||||
return Material.getMaterial(getTypeId());
|
||||
}
|
||||
|
||||
public void setFlag(int flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public int getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public int getTypeId() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public byte getLightLevel() {
|
||||
return light;
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
return world.getBlockAt(x, y, z);
|
||||
}
|
||||
|
||||
public boolean update() {
|
||||
return update(false);
|
||||
}
|
||||
|
||||
public boolean update(boolean force) {
|
||||
return update(force, true);
|
||||
}
|
||||
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() != getType()) {
|
||||
if (force) {
|
||||
block.setTypeId(getTypeId(), applyPhysics);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
block.setData(getRawData(), applyPhysics);
|
||||
world.getHandle().markBlockForUpdate(x, y, z);
|
||||
// Cauldron start - restore TE data from snapshot
|
||||
if (nbt != null)
|
||||
{
|
||||
TileEntity te = world.getHandle().getTileEntity(x, y, z);
|
||||
if (te != null)
|
||||
{
|
||||
te.readFromNBT(nbt);
|
||||
}
|
||||
}
|
||||
// Cauldron end
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void createData(final byte data) {
|
||||
Material mat = getType();
|
||||
if (mat == null || mat.getData() == null) {
|
||||
this.data = new MaterialData(type, data);
|
||||
} else {
|
||||
this.data = mat.getNewData(data);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getRawData() {
|
||||
return data.getData();
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
public Location getLocation(Location loc) {
|
||||
if (loc != null) {
|
||||
loc.setWorld(world);
|
||||
loc.setX(x);
|
||||
loc.setY(y);
|
||||
loc.setZ(z);
|
||||
loc.setYaw(0);
|
||||
loc.setPitch(0);
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
public void setRawData(byte data) {
|
||||
this.data.setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final CraftBlockState other = (CraftBlockState) obj;
|
||||
if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) {
|
||||
return false;
|
||||
}
|
||||
if (this.x != other.x) {
|
||||
return false;
|
||||
}
|
||||
if (this.y != other.y) {
|
||||
return false;
|
||||
}
|
||||
if (this.z != other.z) {
|
||||
return false;
|
||||
}
|
||||
if (this.type != other.type) {
|
||||
return false;
|
||||
}
|
||||
if (this.data != other.data && (this.data == null || !this.data.equals(other.data))) {
|
||||
return false;
|
||||
}
|
||||
// Cauldron start
|
||||
if (this.nbt != other.nbt && (this.nbt == null || !this.nbt.equals(other.nbt))) {
|
||||
return false;
|
||||
}
|
||||
// Cauldron end
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 73 * hash + (this.world != null ? this.world.hashCode() : 0);
|
||||
hash = 73 * hash + this.x;
|
||||
hash = 73 * hash + this.y;
|
||||
hash = 73 * hash + this.z;
|
||||
hash = 73 * hash + this.type;
|
||||
hash = 73 * hash + (this.data != null ? this.data.hashCode() : 0);
|
||||
hash = 73 * hash + (this.nbt != null ? this.nbt.hashCode() : 0); // Cauldron
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
|
||||
chunk.getCraftWorld().getBlockMetadata().setMetadata(getBlock(), metadataKey, newMetadataValue);
|
||||
}
|
||||
|
||||
public List<MetadataValue> getMetadata(String metadataKey) {
|
||||
return chunk.getCraftWorld().getBlockMetadata().getMetadata(getBlock(), metadataKey);
|
||||
}
|
||||
|
||||
public boolean hasMetadata(String metadataKey) {
|
||||
return chunk.getCraftWorld().getBlockMetadata().hasMetadata(getBlock(), metadataKey);
|
||||
}
|
||||
|
||||
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
|
||||
chunk.getCraftWorld().getBlockMetadata().removeMetadata(getBlock(), metadataKey, owningPlugin);
|
||||
}
|
||||
|
||||
// Cauldron start
|
||||
public TileEntity getTileEntity() {
|
||||
if (nbt != null)
|
||||
return TileEntity.createAndLoadEntity(nbt);
|
||||
else return null;
|
||||
}
|
||||
// Cauldron end
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityBrewingStand;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BrewingStand;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer;
|
||||
import org.bukkit.inventory.BrewerInventory;
|
||||
|
||||
public class CraftBrewingStand extends CraftBlockState implements BrewingStand {
|
||||
private final TileEntityBrewingStand brewingStand;
|
||||
|
||||
public CraftBrewingStand(Block block) {
|
||||
super(block);
|
||||
|
||||
brewingStand = (TileEntityBrewingStand) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public BrewerInventory getInventory() {
|
||||
return new CraftInventoryBrewer(brewingStand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
brewingStand.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getBrewingTime() {
|
||||
return brewingStand.brewTime;
|
||||
}
|
||||
|
||||
public void setBrewingTime(int brewTime) {
|
||||
brewingStand.brewTime = brewTime;
|
||||
}
|
||||
}
|
||||
72
src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
Normal file
72
src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityChest;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class CraftChest extends CraftBlockState implements Chest {
|
||||
private final CraftWorld world;
|
||||
private final TileEntityChest chest;
|
||||
|
||||
public CraftChest(final Block block) {
|
||||
super(block);
|
||||
|
||||
world = (CraftWorld) block.getWorld();
|
||||
chest = (TileEntityChest) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public Inventory getBlockInventory() {
|
||||
return new CraftInventory(chest);
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
int x = getX();
|
||||
int y = getY();
|
||||
int z = getZ();
|
||||
// The logic here is basically identical to the logic in BlockChest.interact
|
||||
CraftInventory inventory = new CraftInventory(chest);
|
||||
int id;
|
||||
if (world.getBlockTypeIdAt(x, y, z) == Material.CHEST.getId()) {
|
||||
id = Material.CHEST.getId();
|
||||
} else if (world.getBlockTypeIdAt(x, y, z) == Material.TRAPPED_CHEST.getId()) {
|
||||
id = Material.TRAPPED_CHEST.getId();
|
||||
} else {
|
||||
throw new IllegalStateException("CraftChest is not a chest but is instead " + world.getBlockAt(x, y, z));
|
||||
}
|
||||
|
||||
if (world.getBlockTypeIdAt(x - 1, y, z) == id) {
|
||||
CraftInventory left = new CraftInventory((TileEntityChest)world.getHandle().getTileEntity(x - 1, y, z));
|
||||
inventory = new CraftInventoryDoubleChest(left, inventory);
|
||||
}
|
||||
if (world.getBlockTypeIdAt(x + 1, y, z) == id) {
|
||||
CraftInventory right = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(x + 1, y, z));
|
||||
inventory = new CraftInventoryDoubleChest(inventory, right);
|
||||
}
|
||||
if (world.getBlockTypeIdAt(x, y, z - 1) == id) {
|
||||
CraftInventory left = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(x, y, z - 1));
|
||||
inventory = new CraftInventoryDoubleChest(left, inventory);
|
||||
}
|
||||
if (world.getBlockTypeIdAt(x, y, z + 1) == id) {
|
||||
CraftInventory right = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(x, y, z + 1));
|
||||
inventory = new CraftInventoryDoubleChest(inventory, right);
|
||||
}
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
chest.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityCommandBlock;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CommandBlock;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
public class CraftCommandBlock extends CraftBlockState implements CommandBlock {
|
||||
private final TileEntityCommandBlock commandBlock;
|
||||
private String command;
|
||||
private String name;
|
||||
|
||||
public CraftCommandBlock(Block block) {
|
||||
super(block);
|
||||
|
||||
CraftWorld world = (CraftWorld) block.getWorld();
|
||||
commandBlock = (TileEntityCommandBlock) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
command = commandBlock.func_145993_a().field_145763_e;
|
||||
name = commandBlock.func_145993_a().getCommandSenderName();
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public void setCommand(String command) {
|
||||
this.command = command != null ? command : "";
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name != null ? name : "@";
|
||||
}
|
||||
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
commandBlock.func_145993_a().func_145752_a(command);
|
||||
commandBlock.func_145993_a().func_145754_b(name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityMobSpawner;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.CreatureType;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftCreatureSpawner extends CraftBlockState implements CreatureSpawner {
|
||||
private final TileEntityMobSpawner spawner;
|
||||
|
||||
public CraftCreatureSpawner(final Block block) {
|
||||
super(block);
|
||||
|
||||
spawner = (TileEntityMobSpawner) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public CreatureType getCreatureType() {
|
||||
return CreatureType.fromName(spawner.func_145881_a().getEntityNameToSpawn());
|
||||
}
|
||||
|
||||
public EntityType getSpawnedType() {
|
||||
return EntityType.fromName(spawner.func_145881_a().getEntityNameToSpawn());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setCreatureType(CreatureType creatureType) {
|
||||
spawner.func_145881_a().setEntityName(creatureType.getName());
|
||||
}
|
||||
|
||||
public void setSpawnedType(EntityType entityType) {
|
||||
if (entityType == null || entityType.getName() == null) {
|
||||
throw new IllegalArgumentException("Can't spawn EntityType " + entityType + " from mobspawners!");
|
||||
}
|
||||
|
||||
spawner.func_145881_a().setEntityName(entityType.getName());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getCreatureTypeId() {
|
||||
return spawner.func_145881_a().getEntityNameToSpawn();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setCreatureTypeId(String creatureName) {
|
||||
setCreatureTypeByName(creatureName);
|
||||
}
|
||||
|
||||
public String getCreatureTypeName() {
|
||||
return spawner.func_145881_a().getEntityNameToSpawn();
|
||||
}
|
||||
|
||||
public void setCreatureTypeByName(String creatureType) {
|
||||
// Verify input
|
||||
EntityType type = EntityType.fromName(creatureType);
|
||||
if (type == null) {
|
||||
return;
|
||||
}
|
||||
setSpawnedType(type);
|
||||
}
|
||||
|
||||
public int getDelay() {
|
||||
return spawner.func_145881_a().spawnDelay;
|
||||
}
|
||||
|
||||
public void setDelay(int delay) {
|
||||
spawner.func_145881_a().spawnDelay = delay;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.block.BlockDispenser;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.tileentity.TileEntityDispenser;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Dispenser;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
|
||||
public class CraftDispenser extends CraftBlockState implements Dispenser {
|
||||
private final CraftWorld world;
|
||||
private final TileEntityDispenser dispenser;
|
||||
|
||||
public CraftDispenser(final Block block) {
|
||||
super(block);
|
||||
|
||||
world = (CraftWorld) block.getWorld();
|
||||
dispenser = (TileEntityDispenser) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return new CraftInventory(dispenser);
|
||||
}
|
||||
|
||||
public BlockProjectileSource getBlockProjectileSource() {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() != Material.DISPENSER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CraftBlockProjectileSource(dispenser);
|
||||
}
|
||||
|
||||
public boolean dispense() {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() == Material.DISPENSER) {
|
||||
BlockDispenser dispense = (BlockDispenser) Blocks.dispenser;
|
||||
|
||||
dispense.func_149941_e(world.getHandle(), getX(), getY(), getZ());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
dispenser.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
49
src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java
Normal file
49
src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.block.BlockDropper;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.tileentity.TileEntityDropper;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Dropper;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class CraftDropper extends CraftBlockState implements Dropper {
|
||||
private final CraftWorld world;
|
||||
private final TileEntityDropper dropper;
|
||||
|
||||
public CraftDropper(final Block block) {
|
||||
super(block);
|
||||
|
||||
world = (CraftWorld) block.getWorld();
|
||||
dropper = (TileEntityDropper) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return new CraftInventory(dropper);
|
||||
}
|
||||
|
||||
public void drop() {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() == Material.DROPPER) {
|
||||
BlockDropper drop = (BlockDropper) Blocks.dropper;
|
||||
|
||||
drop.func_149941_e(world.getHandle(), getX(), getY(), getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
dropper.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
49
src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
Normal file
49
src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityFurnace;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Furnace;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace;
|
||||
import org.bukkit.inventory.FurnaceInventory;
|
||||
|
||||
public class CraftFurnace extends CraftBlockState implements Furnace {
|
||||
private final TileEntityFurnace furnace;
|
||||
|
||||
public CraftFurnace(final Block block) {
|
||||
super(block);
|
||||
|
||||
furnace = (TileEntityFurnace) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public FurnaceInventory getInventory() {
|
||||
return new CraftInventoryFurnace(furnace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
furnace.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public short getBurnTime() {
|
||||
return (short) furnace.furnaceBurnTime;
|
||||
}
|
||||
|
||||
public void setBurnTime(short burnTime) {
|
||||
furnace.furnaceBurnTime = burnTime;
|
||||
}
|
||||
|
||||
public short getCookTime() {
|
||||
return (short) furnace.furnaceCookTime;
|
||||
}
|
||||
|
||||
public void setCookTime(short cookTime) {
|
||||
furnace.furnaceCookTime = cookTime;
|
||||
}
|
||||
}
|
||||
33
src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java
Normal file
33
src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityHopper;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Hopper;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class CraftHopper extends CraftBlockState implements Hopper {
|
||||
private final TileEntityHopper hopper;
|
||||
|
||||
public CraftHopper(final Block block) {
|
||||
super(block);
|
||||
|
||||
hopper = (TileEntityHopper) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return new CraftInventory(hopper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
hopper.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
60
src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java
Normal file
60
src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.block.BlockJukebox;
|
||||
import net.minecraft.block.BlockJukebox.TileEntityJukebox;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Jukebox;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
|
||||
public class CraftJukebox extends CraftBlockState implements Jukebox {
|
||||
private final CraftWorld world;
|
||||
private final TileEntityJukebox jukebox;
|
||||
|
||||
public CraftJukebox(final Block block) {
|
||||
super(block);
|
||||
|
||||
world = (CraftWorld) block.getWorld();
|
||||
jukebox = (TileEntityJukebox) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getPlaying() {
|
||||
ItemStack record = jukebox.func_145856_a();
|
||||
if (record == null) {
|
||||
return Material.AIR;
|
||||
}
|
||||
return CraftMagicNumbers.getMaterial(record.getItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaying(Material record) {
|
||||
if (record == null || CraftMagicNumbers.getItem(record) == null) {
|
||||
record = Material.AIR;
|
||||
jukebox.func_145857_a(null);
|
||||
} else {
|
||||
jukebox.func_145857_a(new ItemStack(CraftMagicNumbers.getItem(record), 1));
|
||||
}
|
||||
jukebox.markDirty();
|
||||
if (record == Material.AIR) {
|
||||
world.getHandle().setBlockMetadataWithNotify(getX(), getY(), getZ(), 0, 3);
|
||||
} else {
|
||||
world.getHandle().setBlockMetadataWithNotify(getX(), getY(), getZ(), 1, 3);
|
||||
}
|
||||
world.playEffect(getLocation(), Effect.RECORD_PLAY, record.getId());
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return getRawData() == 1;
|
||||
}
|
||||
|
||||
public boolean eject() {
|
||||
boolean result = isPlaying();
|
||||
((BlockJukebox) Blocks.jukebox).func_149925_e(world.getHandle(), getX(), getY(), getZ());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityNote;
|
||||
|
||||
import org.bukkit.Instrument;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Note;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.NoteBlock;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
|
||||
public class CraftNoteBlock extends CraftBlockState implements NoteBlock {
|
||||
private final CraftWorld world;
|
||||
private final TileEntityNote note;
|
||||
|
||||
public CraftNoteBlock(final Block block) {
|
||||
super(block);
|
||||
|
||||
world = (CraftWorld) block.getWorld();
|
||||
note = (TileEntityNote) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public Note getNote() {
|
||||
return new Note(note.note);
|
||||
}
|
||||
|
||||
public byte getRawNote() {
|
||||
return note.note;
|
||||
}
|
||||
|
||||
public void setNote(Note n) {
|
||||
note.note = n.getId();
|
||||
}
|
||||
|
||||
public void setRawNote(byte n) {
|
||||
note.note = n;
|
||||
}
|
||||
|
||||
public boolean play() {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
note.triggerNote(world.getHandle(), getX(), getY(), getZ());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean play(byte instrument, byte note) {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
world.getHandle().addBlockEvent(getX(), getY(), getZ(), CraftMagicNumbers.getBlock(block), instrument, note);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean play(Instrument instrument, Note note) {
|
||||
Block block = getBlock();
|
||||
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
world.getHandle().addBlockEvent(getX(), getY(), getZ(), CraftMagicNumbers.getBlock(block), instrument.getType(), note.getId());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
Normal file
64
src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntitySign;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
public class CraftSign extends CraftBlockState implements Sign {
|
||||
private final TileEntitySign sign;
|
||||
private final String[] lines;
|
||||
|
||||
public CraftSign(final Block block) {
|
||||
super(block);
|
||||
|
||||
CraftWorld world = (CraftWorld) block.getWorld();
|
||||
sign = (net.minecraft.tileentity.TileEntitySign) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
// Spigot start
|
||||
if (sign == null) {
|
||||
lines = new String[]{"", "", "", ""};
|
||||
return;
|
||||
}
|
||||
// Spigot end
|
||||
lines = new String[sign.signText.length];
|
||||
System.arraycopy(sign.signText, 0, lines, 0, lines.length);
|
||||
}
|
||||
|
||||
public String[] getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
public String getLine(int index) throws IndexOutOfBoundsException {
|
||||
return lines[index];
|
||||
}
|
||||
|
||||
public void setLine(int index, String line) throws IndexOutOfBoundsException {
|
||||
lines[index] = line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
sign.signText = sanitizeLines(lines);
|
||||
sign.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String[] sanitizeLines(String[] lines) {
|
||||
String[] astring = new String[4];
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if (i < lines.length && lines[i] != null) {
|
||||
astring[i] = lines[i];
|
||||
} else {
|
||||
astring[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
return TileEntitySign.sanitizeLines(astring);
|
||||
}
|
||||
}
|
||||
205
src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java
Normal file
205
src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java
Normal file
@@ -0,0 +1,205 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.tileentity.TileEntitySkull;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import org.bukkit.SkullType;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
public class CraftSkull extends CraftBlockState implements Skull {
|
||||
private static final int MAX_OWNER_LENGTH = 16;
|
||||
private final TileEntitySkull skull;
|
||||
private GameProfile profile;
|
||||
private SkullType skullType;
|
||||
private byte rotation;
|
||||
|
||||
public CraftSkull(final Block block) {
|
||||
super(block);
|
||||
|
||||
CraftWorld world = (CraftWorld) block.getWorld();
|
||||
skull = (TileEntitySkull) world.getTileEntityAt(getX(), getY(), getZ());
|
||||
profile = skull.func_152108_a();
|
||||
skullType = getSkullType(skull.func_145904_a());
|
||||
rotation = (byte) skull.getRotation();
|
||||
}
|
||||
|
||||
static SkullType getSkullType(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
return SkullType.SKELETON;
|
||||
case 1:
|
||||
return SkullType.WITHER;
|
||||
case 2:
|
||||
return SkullType.ZOMBIE;
|
||||
case 3:
|
||||
return SkullType.PLAYER;
|
||||
case 4:
|
||||
return SkullType.CREEPER;
|
||||
default:
|
||||
throw new AssertionError(id);
|
||||
}
|
||||
}
|
||||
|
||||
static int getSkullType(SkullType type) {
|
||||
switch(type) {
|
||||
case SKELETON:
|
||||
return 0;
|
||||
case WITHER:
|
||||
return 1;
|
||||
case ZOMBIE:
|
||||
return 2;
|
||||
case PLAYER:
|
||||
return 3;
|
||||
case CREEPER:
|
||||
return 4;
|
||||
default:
|
||||
throw new AssertionError(type);
|
||||
}
|
||||
}
|
||||
|
||||
static byte getBlockFace(BlockFace rotation) {
|
||||
switch (rotation) {
|
||||
case NORTH:
|
||||
return 0;
|
||||
case NORTH_NORTH_EAST:
|
||||
return 1;
|
||||
case NORTH_EAST:
|
||||
return 2;
|
||||
case EAST_NORTH_EAST:
|
||||
return 3;
|
||||
case EAST:
|
||||
return 4;
|
||||
case EAST_SOUTH_EAST:
|
||||
return 5;
|
||||
case SOUTH_EAST:
|
||||
return 6;
|
||||
case SOUTH_SOUTH_EAST:
|
||||
return 7;
|
||||
case SOUTH:
|
||||
return 8;
|
||||
case SOUTH_SOUTH_WEST:
|
||||
return 9;
|
||||
case SOUTH_WEST:
|
||||
return 10;
|
||||
case WEST_SOUTH_WEST:
|
||||
return 11;
|
||||
case WEST:
|
||||
return 12;
|
||||
case WEST_NORTH_WEST:
|
||||
return 13;
|
||||
case NORTH_WEST:
|
||||
return 14;
|
||||
case NORTH_NORTH_WEST:
|
||||
return 15;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid BlockFace rotation: " + rotation);
|
||||
}
|
||||
}
|
||||
|
||||
static BlockFace getBlockFace(byte rotation) {
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
return BlockFace.NORTH;
|
||||
case 1:
|
||||
return BlockFace.NORTH_NORTH_EAST;
|
||||
case 2:
|
||||
return BlockFace.NORTH_EAST;
|
||||
case 3:
|
||||
return BlockFace.EAST_NORTH_EAST;
|
||||
case 4:
|
||||
return BlockFace.EAST;
|
||||
case 5:
|
||||
return BlockFace.EAST_SOUTH_EAST;
|
||||
case 6:
|
||||
return BlockFace.SOUTH_EAST;
|
||||
case 7:
|
||||
return BlockFace.SOUTH_SOUTH_EAST;
|
||||
case 8:
|
||||
return BlockFace.SOUTH;
|
||||
case 9:
|
||||
return BlockFace.SOUTH_SOUTH_WEST;
|
||||
case 10:
|
||||
return BlockFace.SOUTH_WEST;
|
||||
case 11:
|
||||
return BlockFace.WEST_SOUTH_WEST;
|
||||
case 12:
|
||||
return BlockFace.WEST;
|
||||
case 13:
|
||||
return BlockFace.WEST_NORTH_WEST;
|
||||
case 14:
|
||||
return BlockFace.NORTH_WEST;
|
||||
case 15:
|
||||
return BlockFace.NORTH_NORTH_WEST;
|
||||
default:
|
||||
throw new AssertionError(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasOwner() {
|
||||
return profile != null;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return hasOwner() ? profile.getName() : null;
|
||||
}
|
||||
|
||||
public boolean setOwner(String name) {
|
||||
if (name == null || name.length() > MAX_OWNER_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GameProfile profile = MinecraftServer.getServer().func_152358_ax().func_152655_a (name);
|
||||
if (profile == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (skullType != SkullType.PLAYER) {
|
||||
skullType = SkullType.PLAYER;
|
||||
}
|
||||
|
||||
this.profile = profile;
|
||||
return true;
|
||||
}
|
||||
|
||||
public BlockFace getRotation() {
|
||||
return getBlockFace(rotation);
|
||||
}
|
||||
|
||||
public void setRotation(BlockFace rotation) {
|
||||
this.rotation = getBlockFace(rotation);
|
||||
}
|
||||
|
||||
public SkullType getSkullType() {
|
||||
return skullType;
|
||||
}
|
||||
|
||||
public void setSkullType(SkullType skullType) {
|
||||
this.skullType = skullType;
|
||||
|
||||
if (skullType != SkullType.PLAYER) {
|
||||
profile = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean force, boolean applyPhysics) {
|
||||
boolean result = super.update(force, applyPhysics);
|
||||
|
||||
if (result) {
|
||||
if (skullType == SkullType.PLAYER) {
|
||||
skull.func_152106_a(profile);
|
||||
} else {
|
||||
skull.func_152107_a(getSkullType(skullType));
|
||||
}
|
||||
|
||||
skull.func_145903_a(rotation);
|
||||
skull.markDirty();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.fusesource.jansi.Ansi;
|
||||
import org.fusesource.jansi.Ansi.Attribute;
|
||||
import jline.Terminal;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
|
||||
public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
||||
private final Terminal terminal;
|
||||
private final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
|
||||
private final ChatColor[] colors = ChatColor.values();
|
||||
|
||||
protected ColouredConsoleSender() {
|
||||
super();
|
||||
this.terminal = ((CraftServer) getServer()).getReader().getTerminal();
|
||||
|
||||
replacements.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString());
|
||||
replacements.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString());
|
||||
replacements.put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString());
|
||||
replacements.put(ChatColor.DARK_AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).boldOff().toString());
|
||||
replacements.put(ChatColor.DARK_RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).boldOff().toString());
|
||||
replacements.put(ChatColor.DARK_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).boldOff().toString());
|
||||
replacements.put(ChatColor.GOLD, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).boldOff().toString());
|
||||
replacements.put(ChatColor.GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).boldOff().toString());
|
||||
replacements.put(ChatColor.DARK_GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).bold().toString());
|
||||
replacements.put(ChatColor.BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).bold().toString());
|
||||
replacements.put(ChatColor.GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).bold().toString());
|
||||
replacements.put(ChatColor.AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).bold().toString());
|
||||
replacements.put(ChatColor.RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).bold().toString());
|
||||
replacements.put(ChatColor.LIGHT_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).bold().toString());
|
||||
replacements.put(ChatColor.YELLOW, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).bold().toString());
|
||||
replacements.put(ChatColor.WHITE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).bold().toString());
|
||||
replacements.put(ChatColor.MAGIC, Ansi.ansi().a(Attribute.BLINK_SLOW).toString());
|
||||
replacements.put(ChatColor.BOLD, Ansi.ansi().a(Attribute.UNDERLINE_DOUBLE).toString());
|
||||
replacements.put(ChatColor.STRIKETHROUGH, Ansi.ansi().a(Attribute.STRIKETHROUGH_ON).toString());
|
||||
replacements.put(ChatColor.UNDERLINE, Ansi.ansi().a(Attribute.UNDERLINE).toString());
|
||||
replacements.put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString());
|
||||
replacements.put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
if (terminal.isAnsiSupported()) {
|
||||
if (!conversationTracker.isConversingModaly()) {
|
||||
String result = message;
|
||||
for (ChatColor color : colors) {
|
||||
if (replacements.containsKey(color)) {
|
||||
result = result.replaceAll("(?i)" + color.toString(), replacements.get(color));
|
||||
} else {
|
||||
result = result.replaceAll("(?i)" + color.toString(), "");
|
||||
}
|
||||
}
|
||||
System.out.println(result + Ansi.ansi().reset().toString());
|
||||
}
|
||||
} else {
|
||||
super.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static ConsoleCommandSender getInstance() {
|
||||
if (Bukkit.getConsoleSender() != null) {
|
||||
return Bukkit.getConsoleSender();
|
||||
} else {
|
||||
return new ColouredConsoleSender();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.util.Waitable;
|
||||
|
||||
import jline.console.completer.Completer;
|
||||
|
||||
public class ConsoleCommandCompleter implements Completer {
|
||||
private final CraftServer server;
|
||||
|
||||
public ConsoleCommandCompleter(CraftServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
|
||||
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
||||
@Override
|
||||
protected List<String> evaluate() {
|
||||
return server.getCommandMap().tabComplete(server.getConsoleSender(), buffer);
|
||||
}
|
||||
};
|
||||
this.server.getServer().processQueue.add(waitable);
|
||||
try {
|
||||
List<String> offers = waitable.get();
|
||||
if (offers == null) {
|
||||
return cursor;
|
||||
}
|
||||
candidates.addAll(offers);
|
||||
|
||||
final int lastSpace = buffer.lastIndexOf(' ');
|
||||
if (lastSpace == -1) {
|
||||
return cursor - buffer.length();
|
||||
} else {
|
||||
return cursor - (buffer.length() - lastSpace - 1);
|
||||
}
|
||||
} catch (ExecutionException e) {
|
||||
this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.server.CommandBlockLogic;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
|
||||
/**
|
||||
* Represents input from a command block
|
||||
*/
|
||||
public class CraftBlockCommandSender extends ServerCommandSender implements BlockCommandSender {
|
||||
private final CommandBlockLogic commandBlock;
|
||||
|
||||
public CraftBlockCommandSender(CommandBlockLogic commandBlockListenerAbstract) {
|
||||
super();
|
||||
this.commandBlock = commandBlockListenerAbstract;
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
return commandBlock.getEntityWorld().getWorld().getBlockAt(commandBlock.getPlayerCoordinates().posX, commandBlock.getPlayerCoordinates().posY, commandBlock.getPlayerCoordinates().posZ);
|
||||
}
|
||||
|
||||
public void sendMessage(String message) {
|
||||
}
|
||||
|
||||
public void sendMessage(String[] messages) {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return commandBlock.getCommandSenderName();
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setOp(boolean value) {
|
||||
throw new UnsupportedOperationException("Cannot change operator status of a block");
|
||||
}
|
||||
|
||||
public ICommandSender getTileEntity() {
|
||||
return commandBlock;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.conversations.Conversation;
|
||||
import org.bukkit.conversations.ConversationAbandonedEvent;
|
||||
import org.bukkit.conversations.ManuallyAbandonedConversationCanceller;
|
||||
import org.bukkit.craftbukkit.conversations.ConversationTracker;
|
||||
|
||||
/**
|
||||
* Represents CLI input from a console
|
||||
*/
|
||||
public class CraftConsoleCommandSender extends ServerCommandSender implements ConsoleCommandSender {
|
||||
|
||||
protected final ConversationTracker conversationTracker = new ConversationTracker();
|
||||
|
||||
protected CraftConsoleCommandSender() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void sendMessage(String message) {
|
||||
sendRawMessage(message);
|
||||
}
|
||||
|
||||
public void sendRawMessage(String message) {
|
||||
System.out.println(ChatColor.stripColor(message));
|
||||
}
|
||||
|
||||
public void sendMessage(String[] messages) {
|
||||
for (String message : messages) {
|
||||
sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "CONSOLE";
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setOp(boolean value) {
|
||||
throw new UnsupportedOperationException("Cannot change operator status of server console");
|
||||
}
|
||||
|
||||
public boolean beginConversation(Conversation conversation) {
|
||||
return conversationTracker.beginConversation(conversation);
|
||||
}
|
||||
|
||||
public void abandonConversation(Conversation conversation) {
|
||||
conversationTracker.abandonConversation(conversation, new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller()));
|
||||
}
|
||||
|
||||
public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) {
|
||||
conversationTracker.abandonConversation(conversation, details);
|
||||
}
|
||||
|
||||
public void acceptConversationInput(String input) {
|
||||
conversationTracker.acceptConversationInput(input);
|
||||
}
|
||||
|
||||
public boolean isConversing() {
|
||||
return conversationTracker.isConversing();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import net.minecraft.network.rcon.RConConsoleSource;
|
||||
import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
|
||||
public class CraftRemoteConsoleCommandSender extends ServerCommandSender implements RemoteConsoleCommandSender {
|
||||
public CraftRemoteConsoleCommandSender() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
RConConsoleSource.instance.sendMessage(message + "\n"); // Send a newline after each message, to preserve formatting.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String[] messages) {
|
||||
for (String message : messages) {
|
||||
sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Rcon";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
throw new UnsupportedOperationException("Cannot change operator status of remote controller.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import static org.bukkit.util.Java15Compat.Arrays_copyOfRange;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandException;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
public class CraftSimpleCommandMap extends SimpleCommandMap {
|
||||
|
||||
private static final Pattern PATTERN_ON_SPACE = Pattern.compile(" ", Pattern.LITERAL);
|
||||
private ICommandSender vanillaConsoleSender; // Cauldron
|
||||
|
||||
public CraftSimpleCommandMap(Server server) {
|
||||
super(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean dispatch(CommandSender sender, String commandLine) throws CommandException {
|
||||
String[] args = PATTERN_ON_SPACE.split(commandLine);
|
||||
|
||||
if (args.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String sentCommandLabel = args[0].toLowerCase();
|
||||
Command target = getCommand(sentCommandLabel);
|
||||
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// Cauldron start - if command is a mod command, check permissions and route through vanilla
|
||||
if (target instanceof ModCustomCommand)
|
||||
{
|
||||
if (!target.testPermission(sender)) return true;
|
||||
if (sender instanceof ConsoleCommandSender)
|
||||
{
|
||||
FMLCommonHandler.instance().getMinecraftServerInstance().getCommandManager().executeCommand(this.vanillaConsoleSender, commandLine);
|
||||
}
|
||||
else FMLCommonHandler.instance().getMinecraftServerInstance().getCommandManager().executeCommand(((CraftPlayer)sender).getHandle(), commandLine);
|
||||
}
|
||||
else {
|
||||
// Cauldron end
|
||||
// Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
|
||||
target.execute(sender, sentCommandLabel, Arrays_copyOfRange(args, 1, args.length));
|
||||
}
|
||||
} catch (CommandException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
throw new CommandException("Unhandled exception executing '" + commandLine + "' in " + target, ex);
|
||||
}
|
||||
|
||||
// return true as command was handled
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cauldron start - sets the vanilla console sender
|
||||
public void setVanillaConsoleSender(ICommandSender console)
|
||||
{
|
||||
this.vanillaConsoleSender = console;
|
||||
}
|
||||
// Cauldron end
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
|
||||
public class ModCustomCommand extends Command {
|
||||
|
||||
public ModCustomCommand(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
public ModCustomCommand(String name, String description, String usageMessage, List<String> aliases)
|
||||
{
|
||||
super(name, description, usageMessage, aliases);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
||||
// Dummy method
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class ServerCommandSender implements CommandSender {
|
||||
private final PermissibleBase perm = new PermissibleBase(this);
|
||||
|
||||
public ServerCommandSender() {
|
||||
}
|
||||
|
||||
public boolean isPermissionSet(String name) {
|
||||
return perm.isPermissionSet(name);
|
||||
}
|
||||
|
||||
public boolean isPermissionSet(Permission perm) {
|
||||
return this.perm.isPermissionSet(perm);
|
||||
}
|
||||
|
||||
public boolean hasPermission(String name) {
|
||||
return perm.hasPermission(name);
|
||||
}
|
||||
|
||||
public boolean hasPermission(Permission perm) {
|
||||
return this.perm.hasPermission(perm);
|
||||
}
|
||||
|
||||
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
|
||||
return perm.addAttachment(plugin, name, value);
|
||||
}
|
||||
|
||||
public PermissionAttachment addAttachment(Plugin plugin) {
|
||||
return perm.addAttachment(plugin);
|
||||
}
|
||||
|
||||
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
|
||||
return perm.addAttachment(plugin, name, value, ticks);
|
||||
}
|
||||
|
||||
public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
|
||||
return perm.addAttachment(plugin, ticks);
|
||||
}
|
||||
|
||||
public void removeAttachment(PermissionAttachment attachment) {
|
||||
perm.removeAttachment(attachment);
|
||||
}
|
||||
|
||||
public void recalculatePermissions() {
|
||||
perm.recalculatePermissions();
|
||||
}
|
||||
|
||||
public Set<PermissionAttachmentInfo> getEffectivePermissions() {
|
||||
return perm.getEffectivePermissions();
|
||||
}
|
||||
|
||||
public boolean isPlayer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return Bukkit.getServer();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class TicksPerSecondCommand extends Command {
|
||||
|
||||
public TicksPerSecondCommand(String name) {
|
||||
super(name);
|
||||
this.description = "Gets the current ticks per second for the server";
|
||||
this.usageMessage = "/tps";
|
||||
this.setPermission("bukkit.command.tps");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
double tps = Math.min(20, Math.round(net.minecraft.server.MinecraftServer.currentTps * 10) / 10.0);
|
||||
ChatColor color;
|
||||
if (tps > 19.2D) {
|
||||
color = ChatColor.GREEN;
|
||||
} else if (tps > 17.4D) {
|
||||
color = ChatColor.YELLOW;
|
||||
} else {
|
||||
color = ChatColor.RED;
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.GOLD + "[TPS] " + color + tps);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package org.bukkit.craftbukkit.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import net.minecraft.entity.EntityMinecartCommandBlockListener;
|
||||
import net.minecraft.tileentity.TileEntityCommandBlockListener;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
import org.bukkit.command.defaults.*;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftMinecartCommand;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.minecart.CommandMinecart;
|
||||
|
||||
public final class VanillaCommandWrapper extends VanillaCommand {
|
||||
protected final net.minecraft.command.CommandBase vanillaCommand;
|
||||
|
||||
public VanillaCommandWrapper(net.minecraft.command.CommandBase vanillaCommand) {
|
||||
super(vanillaCommand.getCommandName());
|
||||
this.vanillaCommand = vanillaCommand;
|
||||
}
|
||||
|
||||
public VanillaCommandWrapper(net.minecraft.command.CommandBase vanillaCommand, String usage) {
|
||||
super(vanillaCommand.getCommandName());
|
||||
this.vanillaCommand = vanillaCommand;
|
||||
this.description = "A Mojang provided command.";
|
||||
this.usageMessage = usage;
|
||||
this.setPermission("minecraft.command." + vanillaCommand.getCommandName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
net.minecraft.command.ICommandSender icommandlistener = getListener(sender);
|
||||
// Some commands use the worldserver variable but we leave it full of null values,
|
||||
// so we must temporarily populate it with the world of the commandsender
|
||||
net.minecraft.world.WorldServer[] prev = net.minecraft.server.MinecraftServer.getServer().worldServers;
|
||||
net.minecraft.server.MinecraftServer.getServer().worldServers = new net.minecraft.world.WorldServer[]{(net.minecraft.world.WorldServer) icommandlistener.getEntityWorld()};
|
||||
try {
|
||||
vanillaCommand.processCommand(icommandlistener, args);
|
||||
} catch (net.minecraft.command.WrongUsageException exceptionusage) {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage = new net.minecraft.util.ChatComponentTranslation("commands.generic.usage", new Object[] {new net.minecraft.util.ChatComponentTranslation(exceptionusage.getMessage(), exceptionusage.getErrorOjbects())});
|
||||
chatmessage.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage);
|
||||
} catch (net.minecraft.command.CommandException commandexception) {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage = new net.minecraft.util.ChatComponentTranslation(commandexception.getMessage(), commandexception.getErrorOjbects());
|
||||
chatmessage.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage);
|
||||
} finally {
|
||||
net.minecraft.server.MinecraftServer.getServer().worldServers = prev;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
return (List<String>) vanillaCommand.addTabCompletionOptions(getListener(sender), args);
|
||||
}
|
||||
|
||||
public final int dispatchVanillaCommandBlock(net.minecraft.command.server.CommandBlockLogic icommandlistener, String s) {
|
||||
// Copied from net.minecraft.server.CommandHandler
|
||||
s = s.trim();
|
||||
if (s.startsWith("/")) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
String as[] = s.split(" ");
|
||||
as = dropFirstArgument(as);
|
||||
int i = getPlayerListSize(as);
|
||||
int j = 0;
|
||||
// Some commands use the worldserver variable but we leave it full of null values,
|
||||
// so we must temporarily populate it with the world of the commandsender
|
||||
net.minecraft.world.WorldServer[] prev = net.minecraft.server.MinecraftServer.getServer().worldServers;
|
||||
net.minecraft.server.MinecraftServer.getServer().worldServers = new net.minecraft.world.WorldServer[]{(net.minecraft.world.WorldServer) icommandlistener.getEntityWorld()};
|
||||
try {
|
||||
if (vanillaCommand.canCommandSenderUseCommand(icommandlistener)) {
|
||||
if (i > -1) {
|
||||
net.minecraft.entity.player.EntityPlayerMP aentityplayer[] = net.minecraft.command.PlayerSelector.matchPlayers(icommandlistener, as[i]);
|
||||
String s2 = as[i];
|
||||
net.minecraft.entity.player.EntityPlayerMP aentityplayer1[] = aentityplayer;
|
||||
int k = aentityplayer1.length;
|
||||
for (int l = 0; l < k;) {
|
||||
net.minecraft.entity.player.EntityPlayerMP entityplayer = aentityplayer1[l];
|
||||
as[i] = entityplayer.getCommandSenderName();
|
||||
try {
|
||||
vanillaCommand.processCommand(icommandlistener, as);
|
||||
j++;
|
||||
continue;
|
||||
} catch (net.minecraft.command.CommandException commandexception1) {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage4 = new net.minecraft.util.ChatComponentTranslation(commandexception1.getMessage(), commandexception1.getErrorOjbects());
|
||||
chatmessage4.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage4);
|
||||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
as[i] = s2;
|
||||
} else {
|
||||
vanillaCommand.processCommand(icommandlistener, as);
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage = new net.minecraft.util.ChatComponentTranslation("commands.generic.permission", new Object[0]);
|
||||
chatmessage.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage);
|
||||
}
|
||||
} catch (net.minecraft.command.WrongUsageException exceptionusage) {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage1 = new net.minecraft.util.ChatComponentTranslation("commands.generic.usage", new Object[] { new net.minecraft.util.ChatComponentTranslation(exceptionusage.getMessage(), exceptionusage.getErrorOjbects()) });
|
||||
chatmessage1.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage1);
|
||||
} catch (net.minecraft.command.CommandException commandexception) {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage2 = new net.minecraft.util.ChatComponentTranslation(commandexception.getMessage(), commandexception.getErrorOjbects());
|
||||
chatmessage2.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage2);
|
||||
} catch (Throwable throwable) {
|
||||
net.minecraft.util.ChatComponentTranslation chatmessage3 = new net.minecraft.util.ChatComponentTranslation("commands.generic.exception", new Object[0]);
|
||||
chatmessage3.getChatStyle().setColor(net.minecraft.util.EnumChatFormatting.RED);
|
||||
icommandlistener.addChatMessage(chatmessage3);
|
||||
if(icommandlistener instanceof TileEntityCommandBlockListener) {
|
||||
TileEntityCommandBlockListener listener = (TileEntityCommandBlockListener) icommandlistener;
|
||||
net.minecraft.server.MinecraftServer.getLogger().log(Level.WARN, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getPlayerCoordinates().posX, listener.getPlayerCoordinates().posY, listener.getPlayerCoordinates().posZ), throwable);
|
||||
} else if (icommandlistener instanceof EntityMinecartCommandBlockListener) {
|
||||
EntityMinecartCommandBlockListener listener = (EntityMinecartCommandBlockListener) icommandlistener;
|
||||
net.minecraft.server.MinecraftServer.getLogger().log(Level.WARN, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", listener.getPlayerCoordinates().posX, listener.getPlayerCoordinates().posY, listener.getPlayerCoordinates().posZ), throwable);
|
||||
} else {
|
||||
net.minecraft.server.MinecraftServer.getLogger().log(Level.WARN, String.format("Unknown CommandBlock failed to handle command"), throwable);
|
||||
}
|
||||
} finally {
|
||||
net.minecraft.server.MinecraftServer.getServer().worldServers = prev;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
private net.minecraft.command.ICommandSender getListener(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return ((CraftPlayer) sender).getHandle();
|
||||
}
|
||||
if (sender instanceof BlockCommandSender) {
|
||||
return ((CraftBlockCommandSender) sender).getTileEntity();
|
||||
}
|
||||
if (sender instanceof CommandMinecart) {
|
||||
return ((net.minecraft.entity.EntityMinecartCommandBlock) ((CraftMinecartCommand) sender).getHandle()).func_145822_e();
|
||||
}
|
||||
if (sender instanceof RemoteConsoleCommandSender) {
|
||||
return net.minecraft.network.rcon.RConConsoleSource.instance;
|
||||
}
|
||||
if (sender instanceof ConsoleCommandSender) {
|
||||
return ((CraftServer) sender.getServer()).getServer();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getPlayerListSize(String as[]) {
|
||||
for (int i = 0; i < as.length; i++) {
|
||||
if (vanillaCommand.isUsernameIndex(as, i) && net.minecraft.command.PlayerSelector.matchesMultiplePlayers(as[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private String[] dropFirstArgument(String as[]) {
|
||||
String as1[] = new String[as.length - 1];
|
||||
for (int i = 1; i < as.length; i++) {
|
||||
as1[i - 1] = as[i];
|
||||
}
|
||||
|
||||
return as1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.bukkit.craftbukkit.conversations;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.conversations.Conversation;
|
||||
import org.bukkit.conversations.ConversationAbandonedEvent;
|
||||
import org.bukkit.conversations.ManuallyAbandonedConversationCanceller;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ConversationTracker {
|
||||
|
||||
private LinkedList<Conversation> conversationQueue = new LinkedList<Conversation>();
|
||||
|
||||
public synchronized boolean beginConversation(Conversation conversation) {
|
||||
if (!conversationQueue.contains(conversation)) {
|
||||
conversationQueue.addLast(conversation);
|
||||
if (conversationQueue.getFirst() == conversation) {
|
||||
conversation.begin();
|
||||
conversation.outputNextPrompt();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) {
|
||||
if (!conversationQueue.isEmpty()) {
|
||||
if (conversationQueue.getFirst() == conversation) {
|
||||
conversation.abandon(details);
|
||||
}
|
||||
if (conversationQueue.contains(conversation)) {
|
||||
conversationQueue.remove(conversation);
|
||||
}
|
||||
if (!conversationQueue.isEmpty()) {
|
||||
conversationQueue.getFirst().outputNextPrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void abandonAllConversations() {
|
||||
|
||||
LinkedList<Conversation> oldQueue = conversationQueue;
|
||||
conversationQueue = new LinkedList<Conversation>();
|
||||
for(Conversation conversation : oldQueue) {
|
||||
try {
|
||||
conversation.abandon(new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller()));
|
||||
} catch (Throwable t) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unexpected exception while abandoning a conversation", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void acceptConversationInput(String input) {
|
||||
if (isConversing()) {
|
||||
conversationQueue.getFirst().acceptInput(input);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean isConversing() {
|
||||
return !conversationQueue.isEmpty();
|
||||
}
|
||||
|
||||
public synchronized boolean isConversingModaly() {
|
||||
return isConversing() && conversationQueue.getFirst().isModal();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package org.bukkit.craftbukkit.enchantments;
|
||||
|
||||
import org.apache.commons.lang.StringUtils; // Cauldron
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.enchantments.EnchantmentTarget;
|
||||
import org.bukkit.enchantments.EnchantmentWrapper;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CraftEnchantment extends Enchantment {
|
||||
private final net.minecraft.enchantment.Enchantment target;
|
||||
|
||||
public CraftEnchantment(net.minecraft.enchantment.Enchantment target) {
|
||||
super(target.effectId);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return target.getMaxLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartLevel() {
|
||||
return target.getMinLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnchantmentTarget getItemTarget() {
|
||||
switch (target.type) {
|
||||
case all:
|
||||
return EnchantmentTarget.ALL;
|
||||
case armor:
|
||||
return EnchantmentTarget.ARMOR;
|
||||
case armor_feet:
|
||||
return EnchantmentTarget.ARMOR_FEET;
|
||||
case armor_head:
|
||||
return EnchantmentTarget.ARMOR_HEAD;
|
||||
case armor_legs:
|
||||
return EnchantmentTarget.ARMOR_LEGS;
|
||||
case armor_torso:
|
||||
return EnchantmentTarget.ARMOR_TORSO;
|
||||
case digger:
|
||||
return EnchantmentTarget.TOOL;
|
||||
case weapon:
|
||||
return EnchantmentTarget.WEAPON;
|
||||
case bow:
|
||||
return EnchantmentTarget.BOW;
|
||||
case fishing_rod:
|
||||
return EnchantmentTarget.FISHING_ROD;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEnchantItem(ItemStack item) {
|
||||
return target.canApply(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
|
||||
private String generatedName;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
switch (target.effectId) {
|
||||
case 0:
|
||||
return "PROTECTION_ENVIRONMENTAL";
|
||||
case 1:
|
||||
return "PROTECTION_FIRE";
|
||||
case 2:
|
||||
return "PROTECTION_FALL";
|
||||
case 3:
|
||||
return "PROTECTION_EXPLOSIONS";
|
||||
case 4:
|
||||
return "PROTECTION_PROJECTILE";
|
||||
case 5:
|
||||
return "OXYGEN";
|
||||
case 6:
|
||||
return "WATER_WORKER";
|
||||
case 7:
|
||||
return "THORNS";
|
||||
case 16:
|
||||
return "DAMAGE_ALL";
|
||||
case 17:
|
||||
return "DAMAGE_UNDEAD";
|
||||
case 18:
|
||||
return "DAMAGE_ARTHROPODS";
|
||||
case 19:
|
||||
return "KNOCKBACK";
|
||||
case 20:
|
||||
return "FIRE_ASPECT";
|
||||
case 21:
|
||||
return "LOOT_BONUS_MOBS";
|
||||
case 32:
|
||||
return "DIG_SPEED";
|
||||
case 33:
|
||||
return "SILK_TOUCH";
|
||||
case 34:
|
||||
return "DURABILITY";
|
||||
case 35:
|
||||
return "LOOT_BONUS_BLOCKS";
|
||||
case 48:
|
||||
return "ARROW_DAMAGE";
|
||||
case 49:
|
||||
return "ARROW_KNOCKBACK";
|
||||
case 50:
|
||||
return "ARROW_FIRE";
|
||||
case 51:
|
||||
return "ARROW_INFINITE";
|
||||
case 61:
|
||||
return "LUCK";
|
||||
case 62:
|
||||
return "LURE";
|
||||
default:
|
||||
// Cauldron start - generate based on the class name
|
||||
if (generatedName != null) {
|
||||
return generatedName;
|
||||
}
|
||||
|
||||
generatedName = generateName(target);
|
||||
return generatedName;
|
||||
// Cauldron end
|
||||
}
|
||||
}
|
||||
|
||||
// Cauldron start - generate based on the class name
|
||||
private static String generateName(net.minecraft.enchantment.Enchantment target) {
|
||||
String candidate;
|
||||
Class<?> clz = target.getClass();
|
||||
if (clz.getName().startsWith("net.minecraft")) {
|
||||
// Keep pattern for vanilla
|
||||
candidate = "UNKNOWN_ENCHANT_" + target.effectId;
|
||||
return candidate;
|
||||
}
|
||||
candidate = clz.getSimpleName();
|
||||
// Make a nice name when it starts with Enchantment (e.g. EnchantmentSlowFall)
|
||||
if (StringUtils.containsIgnoreCase(candidate, "Enchantment")) {
|
||||
candidate = candidate.replaceFirst("[E|e]nchantment", "");
|
||||
// Add underscores at camelCase humps
|
||||
candidate = candidate.replaceAll("([a-z])([A-Z])", "\1_\2").toUpperCase();
|
||||
candidate = addSuffix(candidate.toUpperCase());
|
||||
return candidate;
|
||||
}
|
||||
// fall back to the FQN if naming pattern is broken
|
||||
candidate = clz.getName();
|
||||
candidate = candidate.replaceAll("([a-z])([A-Z])", "\1_\2");
|
||||
candidate = candidate.replaceAll("\\.", "_");
|
||||
candidate = addSuffix(candidate.toUpperCase());
|
||||
return candidate;
|
||||
}
|
||||
|
||||
private static String addSuffix(String enchName) {
|
||||
if (Enchantment.getByName(enchName) == null) {
|
||||
return enchName;
|
||||
}
|
||||
|
||||
int suffix = 2;
|
||||
while (Enchantment.getByName(enchName + "_" + suffix) != null) {
|
||||
suffix++;
|
||||
}
|
||||
return enchName + "_" + suffix;
|
||||
}
|
||||
// Cauldron end
|
||||
|
||||
public static net.minecraft.enchantment.Enchantment getRaw(Enchantment enchantment) {
|
||||
if (enchantment instanceof EnchantmentWrapper) {
|
||||
enchantment = ((EnchantmentWrapper) enchantment).getEnchantment();
|
||||
}
|
||||
|
||||
if (enchantment instanceof CraftEnchantment) {
|
||||
return ((CraftEnchantment) enchantment).target;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean conflictsWith(Enchantment other) {
|
||||
if (other instanceof EnchantmentWrapper) {
|
||||
other = ((EnchantmentWrapper) other).getEnchantment();
|
||||
}
|
||||
if (!(other instanceof CraftEnchantment)) {
|
||||
return false;
|
||||
}
|
||||
CraftEnchantment ench = (CraftEnchantment) other;
|
||||
return !target.canApplyTogether(ench.target);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Projectile;
|
||||
|
||||
public abstract class AbstractProjectile extends CraftEntity implements Projectile {
|
||||
|
||||
private boolean doesBounce;
|
||||
|
||||
public AbstractProjectile(CraftServer server, net.minecraft.entity.Entity entity) {
|
||||
super(server, entity);
|
||||
doesBounce = false;
|
||||
}
|
||||
|
||||
public boolean doesBounce() {
|
||||
return doesBounce;
|
||||
}
|
||||
|
||||
public void setBounce(boolean doesBounce) {
|
||||
this.doesBounce = doesBounce;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Ageable;
|
||||
|
||||
public class CraftAgeable extends CraftCreature implements Ageable {
|
||||
public CraftAgeable(CraftServer server, EntityAgeable entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return getHandle().getGrowingAge();
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
getHandle().setGrowingAge(age);
|
||||
}
|
||||
|
||||
public void setAgeLock(boolean lock) {
|
||||
getHandle().ageLocked = lock;
|
||||
}
|
||||
|
||||
public boolean getAgeLock() {
|
||||
return getHandle().ageLocked;
|
||||
}
|
||||
|
||||
public void setBaby() {
|
||||
if (isAdult()) {
|
||||
setAge(-24000);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAdult() {
|
||||
if (!isAdult()) {
|
||||
setAge(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAdult() {
|
||||
return getAge() >= 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean canBreed() {
|
||||
return getAge() == 0;
|
||||
}
|
||||
|
||||
public void setBreed(boolean breed) {
|
||||
if (breed) {
|
||||
setAge(0);
|
||||
} else if (isAdult()) {
|
||||
setAge(6000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAgeable getHandle() {
|
||||
return (EntityAgeable) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftAgeable";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.passive.EntityAmbientCreature;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Ambient;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftAmbient extends CraftLivingEntity implements Ambient {
|
||||
public CraftAmbient(CraftServer server, EntityAmbientCreature entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAmbientCreature getHandle() {
|
||||
return (EntityAmbientCreature) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.entityName; // Cauldron
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
// Cauldron start
|
||||
EntityType type = EntityType.fromName(this.entityName);
|
||||
if (type != null)
|
||||
return type;
|
||||
else return EntityType.UNKNOWN;
|
||||
// Cauldron end
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Animals;
|
||||
|
||||
public class CraftAnimals extends CraftAgeable implements Animals {
|
||||
|
||||
public CraftAnimals(CraftServer server, EntityAnimal entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAnimal getHandle() {
|
||||
return (EntityAnimal) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.entityName; // Cauldron
|
||||
}
|
||||
}
|
||||
96
src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
Normal file
96
src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
Normal file
@@ -0,0 +1,96 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
public class CraftArrow extends AbstractProjectile implements Arrow {
|
||||
|
||||
public CraftArrow(CraftServer server, EntityArrow entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
public void setKnockbackStrength(int knockbackStrength) {
|
||||
Validate.isTrue(knockbackStrength >= 0, "Knockback cannot be negative");
|
||||
getHandle().setKnockbackStrength(knockbackStrength);
|
||||
}
|
||||
|
||||
public int getKnockbackStrength() {
|
||||
return getHandle().knockbackStrength;
|
||||
}
|
||||
|
||||
public boolean isCritical() {
|
||||
return getHandle().getIsCritical();
|
||||
}
|
||||
|
||||
public void setCritical(boolean critical) {
|
||||
getHandle().setIsCritical(critical);
|
||||
}
|
||||
|
||||
public ProjectileSource getShooter() {
|
||||
return getHandle().projectileSource;
|
||||
}
|
||||
|
||||
public void setShooter(ProjectileSource shooter) {
|
||||
if (shooter instanceof LivingEntity) {
|
||||
getHandle().shootingEntity = ((CraftLivingEntity) shooter).getHandle();
|
||||
} else {
|
||||
getHandle().shootingEntity = null;
|
||||
}
|
||||
getHandle().projectileSource = shooter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityArrow getHandle() {
|
||||
return (EntityArrow) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftArrow";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.ARROW;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public LivingEntity _INVALID_getShooter() {
|
||||
if (getHandle().shootingEntity == null) {
|
||||
return null;
|
||||
}
|
||||
return (LivingEntity) getHandle().shootingEntity.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void _INVALID_setShooter(LivingEntity shooter) {
|
||||
getHandle().shootingEntity = ((CraftLivingEntity) shooter).getHandle();
|
||||
}
|
||||
|
||||
// Spigot start
|
||||
private final Arrow.Spigot spigot = new Arrow.Spigot()
|
||||
{
|
||||
@Override
|
||||
public double getDamage()
|
||||
{
|
||||
return getHandle().getDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDamage(double damage)
|
||||
{
|
||||
getHandle().setDamage( damage );
|
||||
}
|
||||
};
|
||||
|
||||
public Arrow.Spigot spigot()
|
||||
{
|
||||
return spigot;
|
||||
}
|
||||
// Spigot end
|
||||
}
|
||||
36
src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java
Normal file
36
src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.passive.EntityBat;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Bat;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftBat extends CraftAmbient implements Bat {
|
||||
public CraftBat(CraftServer server, EntityBat entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityBat getHandle() {
|
||||
return (EntityBat) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftBat";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.BAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAwake() {
|
||||
return !getHandle().getIsBatHanging();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAwake(boolean state) {
|
||||
getHandle().setIsBatHanging(!state);
|
||||
}
|
||||
}
|
||||
27
src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java
Normal file
27
src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.monster.EntityBlaze;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Blaze;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftBlaze extends CraftMonster implements Blaze {
|
||||
public CraftBlaze(CraftServer server, EntityBlaze entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityBlaze getHandle() {
|
||||
return (EntityBlaze) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftBlaze";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.BLAZE;
|
||||
}
|
||||
}
|
||||
63
src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
Normal file
63
src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.item.EntityBoat;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftBoat extends CraftVehicle implements Boat {
|
||||
|
||||
public CraftBoat(CraftServer server, EntityBoat entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
public double getMaxSpeed() {
|
||||
return getHandle().maxSpeed;
|
||||
}
|
||||
|
||||
public void setMaxSpeed(double speed) {
|
||||
if (speed >= 0D) {
|
||||
getHandle().maxSpeed = speed;
|
||||
}
|
||||
}
|
||||
|
||||
public double getOccupiedDeceleration() {
|
||||
return getHandle().occupiedDeceleration;
|
||||
}
|
||||
|
||||
public void setOccupiedDeceleration(double speed) {
|
||||
if (speed >= 0D) {
|
||||
getHandle().occupiedDeceleration = speed;
|
||||
}
|
||||
}
|
||||
|
||||
public double getUnoccupiedDeceleration() {
|
||||
return getHandle().unoccupiedDeceleration;
|
||||
}
|
||||
|
||||
public void setUnoccupiedDeceleration(double speed) {
|
||||
getHandle().unoccupiedDeceleration = speed;
|
||||
}
|
||||
|
||||
public boolean getWorkOnLand() {
|
||||
return getHandle().landBoats;
|
||||
}
|
||||
|
||||
public void setWorkOnLand(boolean workOnLand) {
|
||||
getHandle().landBoats = workOnLand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityBoat getHandle() {
|
||||
return (EntityBoat) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftBoat";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.BOAT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.monster.EntityCaveSpider;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.CaveSpider;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftCaveSpider extends CraftSpider implements CaveSpider {
|
||||
public CraftCaveSpider(CraftServer server, EntityCaveSpider entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityCaveSpider getHandle() {
|
||||
return (EntityCaveSpider) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftCaveSpider";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.CAVE_SPIDER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.passive.EntityChicken;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Chicken;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftChicken extends CraftAnimals implements Chicken {
|
||||
|
||||
public CraftChicken(CraftServer server, EntityChicken entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityChicken getHandle() {
|
||||
return (EntityChicken) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftChicken";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.CHICKEN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.ComplexLivingEntity;
|
||||
|
||||
public abstract class CraftComplexLivingEntity extends CraftLivingEntity implements ComplexLivingEntity {
|
||||
public CraftComplexLivingEntity(CraftServer server, EntityLivingBase entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityLivingBase getHandle() {
|
||||
return (EntityLivingBase) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftComplexLivingEntity";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.boss.EntityDragonPart;
|
||||
import net.minecraft.entity.boss.EntityDragon;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.ComplexEntityPart;
|
||||
import org.bukkit.entity.ComplexLivingEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
|
||||
public class CraftComplexPart extends CraftEntity implements ComplexEntityPart {
|
||||
public CraftComplexPart(CraftServer server, EntityDragonPart entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
public ComplexLivingEntity getParent() {
|
||||
// Cauldron start - Fix twilight Hydra crashes
|
||||
org.bukkit.entity.Entity result = getParentEntity();
|
||||
return (result instanceof ComplexLivingEntity) ? (ComplexLivingEntity)result : null;
|
||||
}
|
||||
|
||||
private org.bukkit.entity.Entity getParentEntity() {
|
||||
return ((net.minecraft.entity.Entity)getHandle().entityDragonObj).getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastDamageCause(EntityDamageEvent cause) {
|
||||
getParentEntity().setLastDamageCause(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDamageEvent getLastDamageCause() {
|
||||
return getParentEntity().getLastDamageCause();
|
||||
// Cauldron end
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDragonPart getHandle() {
|
||||
return (EntityDragonPart) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftComplexPart";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.COMPLEX_PART;
|
||||
}
|
||||
}
|
||||
28
src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java
Normal file
28
src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.passive.EntityCow;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Cow;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CraftCow extends CraftAnimals implements Cow {
|
||||
|
||||
public CraftCow(CraftServer server, EntityCow entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityCow getHandle() {
|
||||
return (EntityCow) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftCow";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.COW;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.EntityCreature;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public class CraftCreature extends CraftLivingEntity implements Creature {
|
||||
public CraftCreature(CraftServer server, EntityCreature entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
public void setTarget(LivingEntity target) {
|
||||
EntityCreature entity = getHandle();
|
||||
if (target == null) {
|
||||
entity.entityToAttack = null;
|
||||
} else if (target instanceof CraftLivingEntity) {
|
||||
entity.entityToAttack = ((CraftLivingEntity) target).getHandle();
|
||||
entity.pathToEntity = entity.worldObj.getPathEntityToEntity(entity, entity.entityToAttack, 16.0F, true, false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
public CraftLivingEntity getTarget() {
|
||||
if (getHandle().entityToAttack == null) return null;
|
||||
if (!(getHandle().entityToAttack instanceof EntityLivingBase)) return null;
|
||||
|
||||
return (CraftLivingEntity) getHandle().entityToAttack.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityCreature getHandle() {
|
||||
return (EntityCreature) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.entityName; // Cauldron
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.entity.CreeperPowerEvent;
|
||||
|
||||
public class CraftCreeper extends CraftMonster implements Creeper {
|
||||
|
||||
public CraftCreeper(CraftServer server, EntityCreeper entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
public boolean isPowered() {
|
||||
return getHandle().getPowered();
|
||||
}
|
||||
|
||||
public void setPowered(boolean powered) {
|
||||
CraftServer server = this.server;
|
||||
Creeper entity = (Creeper) this.getHandle().getBukkitEntity();
|
||||
|
||||
if (powered) {
|
||||
CreeperPowerEvent event = new CreeperPowerEvent(entity, CreeperPowerEvent.PowerCause.SET_ON);
|
||||
server.getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
getHandle().setPowered(true);
|
||||
}
|
||||
} else {
|
||||
CreeperPowerEvent event = new CreeperPowerEvent(entity, CreeperPowerEvent.PowerCause.SET_OFF);
|
||||
server.getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
getHandle().setPowered(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityCreeper getHandle() {
|
||||
return (EntityCreeper) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftCreeper";
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return EntityType.CREEPER;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user