The start of the spigot
This commit is contained in:
commit
cdffe91cc2
69
.gitignore
vendored
Normal file
69
.gitignore
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
<<<<<<< HEAD
|
||||
# Eclipse
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings
|
||||
|
||||
# Netbeans
|
||||
/nbproject
|
||||
|
||||
# We active maven!
|
||||
/build.xml
|
||||
|
||||
# Maven
|
||||
/target
|
||||
/dependency-reduced-pom.xml
|
||||
*/target
|
||||
*/dependency-reduced-pom.xml
|
||||
|
||||
# Vim
|
||||
.*.sw[a-p]
|
||||
|
||||
# Various other potential build files
|
||||
/build
|
||||
/bin
|
||||
/dist
|
||||
/manifest.mf
|
||||
/MANIFEST.MF
|
||||
/META-INF/MANIFEST.MF
|
||||
git.properties
|
||||
.ssh
|
||||
key
|
||||
key.pub
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# Mac Filesystem Dust
|
||||
.DS_Store
|
||||
|
||||
# IntelliJ IDEA
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
#Libraries jar files
|
||||
libraries/*.jar
|
||||
=======
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
>>>>>>> 354c5c7d98801e512c3da0913cd1824a9cf4b2cf
|
69
TacoSpigot-API/.gitignore
vendored
Normal file
69
TacoSpigot-API/.gitignore
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
<<<<<<< HEAD
|
||||
# Eclipse
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings
|
||||
|
||||
# Netbeans
|
||||
/nbproject
|
||||
|
||||
# We active maven!
|
||||
/build.xml
|
||||
|
||||
# Maven
|
||||
/target
|
||||
/dependency-reduced-pom.xml
|
||||
*/target
|
||||
*/dependency-reduced-pom.xml
|
||||
|
||||
# Vim
|
||||
.*.sw[a-p]
|
||||
|
||||
# Various other potential build files
|
||||
/build
|
||||
/bin
|
||||
/dist
|
||||
/manifest.mf
|
||||
/MANIFEST.MF
|
||||
/META-INF/MANIFEST.MF
|
||||
git.properties
|
||||
.ssh
|
||||
key
|
||||
key.pub
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# Mac Filesystem Dust
|
||||
.DS_Store
|
||||
|
||||
# IntelliJ IDEA
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
#Libraries jar files
|
||||
libraries/*.jar
|
||||
=======
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
>>>>>>> 354c5c7d98801e512c3da0913cd1824a9cf4b2cf
|
174
TacoSpigot-API/pom.xml
Normal file
174
TacoSpigot-API/pom.xml
Normal file
@ -0,0 +1,174 @@
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.techcable.tacospigot</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>net.techcable.tacospigot</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>1.8.8-R0.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>TacoSpigot-API</name>
|
||||
<url>https://github.com/TacoSpigot</url>
|
||||
<description>An enhanced plugin API for Minecraft servers.</description>
|
||||
|
||||
<properties>
|
||||
<!--PaperSpigot - Bump to 1.8 - This will haunt me -->
|
||||
<additionalparam>-Xdoclint:none</additionalparam>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<!-- just until we get deployment to central approved -->
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>destroystokyo-releases</id>
|
||||
<url>https://repo.destroystokyo.com/content/repositories/releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>destroystokyo-snapshots</id>
|
||||
<url>https://repo.destroystokyo.com/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<!-- required until fixed plexus-compiler-eclipse is deployed -->
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spigotmc-public</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sf.trove4j</groupId>
|
||||
<artifactId>trove4j</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<!-- Trove Provided by CraftBukkit -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- bundled with Minecraft, should be kept in sync -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>17.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- bundled with Minecraft, should be kept in sync -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.avaje</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>2.8.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.15</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-chat</artifactId>
|
||||
<version>1.8-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.20</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Thread Affinity -->
|
||||
<dependency>
|
||||
<groupId>net.openhft</groupId>
|
||||
<artifactId>affinity</artifactId>
|
||||
<version>3.20.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<!-- versions after this appear to be broken -->
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<!-- we use the Eclipse compiler as it doesn't need a JDK -->
|
||||
<compilerId>eclipse</compilerId>
|
||||
<!-- source and target are ignored if this isn't true -->
|
||||
<optimize>true</optimize>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<!-- we need our custom version as it fixes some bugs on case sensitive file systems -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-compiler-eclipse</artifactId>
|
||||
<version>2.5.0-spigotmc</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<!-- utterly useless artifact from shade 2.x -->
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<!-- when downloading via Maven we can pull depends individually -->
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,79 @@
|
||||
package co.aikar.timings;
|
||||
|
||||
import static co.aikar.timings.TimingsManager.*;
|
||||
|
||||
public class FullServerTickHandler extends TimingHandler {
|
||||
static final TimingIdentifier IDENTITY = new TimingIdentifier("Minecraft", "Full Server Tick", null, false);
|
||||
final TimingData minuteData;
|
||||
double avgFreeMemory = -1D;
|
||||
double avgUsedMemory = -1D;
|
||||
FullServerTickHandler() {
|
||||
super(IDENTITY);
|
||||
minuteData = new TimingData(id);
|
||||
|
||||
TIMING_MAP.put(IDENTITY, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTiming() {
|
||||
if (TimingsManager.needsFullReset) {
|
||||
TimingsManager.resetTimings();
|
||||
} else if (TimingsManager.needsRecheckEnabled) {
|
||||
TimingsManager.recheckEnabled();
|
||||
}
|
||||
super.startTiming();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTiming() {
|
||||
super.stopTiming();
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
if (TimingHistory.timedTicks % 20 == 0) {
|
||||
final Runtime runtime = Runtime.getRuntime();
|
||||
double usedMemory = runtime.totalMemory() - runtime.freeMemory();
|
||||
double freeMemory = runtime.maxMemory() - usedMemory;
|
||||
if (this.avgFreeMemory == -1) {
|
||||
this.avgFreeMemory = freeMemory;
|
||||
} else {
|
||||
this.avgFreeMemory = (this.avgFreeMemory * (59 / 60D)) + (freeMemory * (1 / 60D));
|
||||
}
|
||||
|
||||
if (this.avgUsedMemory == -1) {
|
||||
this.avgUsedMemory = usedMemory;
|
||||
} else {
|
||||
this.avgUsedMemory = (this.avgUsedMemory * (59 / 60D)) + (usedMemory * (1 / 60D));
|
||||
}
|
||||
}
|
||||
|
||||
long start = System.nanoTime();
|
||||
TimingsManager.tick();
|
||||
long diff = System.nanoTime() - start;
|
||||
CURRENT = TIMINGS_TICK;
|
||||
TIMINGS_TICK.addDiff(diff);
|
||||
// addDiff for TIMINGS_TICK incremented this, bring it back down to 1 per tick.
|
||||
record.curTickCount--;
|
||||
minuteData.curTickTotal = record.curTickTotal;
|
||||
minuteData.curTickCount = 1;
|
||||
boolean violated = isViolated();
|
||||
minuteData.processTick(violated);
|
||||
TIMINGS_TICK.processTick(violated);
|
||||
processTick(violated);
|
||||
|
||||
|
||||
if (TimingHistory.timedTicks % 1200 == 0) {
|
||||
MINUTE_REPORTS.add(new TimingHistory.MinuteReport());
|
||||
TimingHistory.resetTicks(false);
|
||||
minuteData.reset();
|
||||
}
|
||||
if (TimingHistory.timedTicks % Timings.getHistoryInterval() == 0) {
|
||||
TimingsManager.HISTORY.add(new TimingHistory());
|
||||
TimingsManager.resetTimings();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isViolated() {
|
||||
return record.curTickTotal > 50000000;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
public final class NullTimingHandler implements Timing {
|
||||
@Override
|
||||
public void startTiming() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTiming() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTimingIfSync() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTimingIfSync() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimingHandler getTimingHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class TimedEventExecutor implements EventExecutor {
|
||||
|
||||
private final EventExecutor executor;
|
||||
private final Timing timings;
|
||||
|
||||
/**
|
||||
* Wraps an event executor and associates a timing handler to it.
|
||||
*
|
||||
* @param executor
|
||||
* @param plugin
|
||||
* @param method
|
||||
* @param eventClass
|
||||
*/
|
||||
public TimedEventExecutor(EventExecutor executor, Plugin plugin, Method method, Class<? extends Event> eventClass) {
|
||||
this.executor = executor;
|
||||
String id;
|
||||
|
||||
if (method == null) {
|
||||
if (executor.getClass().getEnclosingClass() != null) { // Oh Skript, how we love you
|
||||
method = executor.getClass().getEnclosingMethod();
|
||||
}
|
||||
}
|
||||
|
||||
if (method != null) {
|
||||
id = method.getDeclaringClass().getName();
|
||||
} else {
|
||||
id = executor.getClass().getName();
|
||||
}
|
||||
|
||||
|
||||
final String eventName = eventClass.getSimpleName();
|
||||
boolean verbose = "BlockPhysicsEvent".equals(eventName) || "Drain".equals(eventName) || "Fill".equals(eventName);
|
||||
this.timings = Timings.ofSafe(plugin.getName(), (verbose ? "## " : "") +
|
||||
"Event: " + id + " (" + eventName + ")", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
if (event.isAsynchronous() || !Timings.timingsEnabled || !Bukkit.isPrimaryThread()) {
|
||||
executor.execute(listener, event);
|
||||
return;
|
||||
}
|
||||
timings.startTiming();
|
||||
executor.execute(listener, event);
|
||||
timings.stopTiming();
|
||||
}
|
||||
}
|
72
TacoSpigot-API/src/main/java/co/aikar/timings/Timing.java
Normal file
72
TacoSpigot-API/src/main/java/co/aikar/timings/Timing.java
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
/**
|
||||
* Provides an ability to time sections of code within the Minecraft Server
|
||||
*/
|
||||
public interface Timing extends AutoCloseable {
|
||||
/**
|
||||
* Starts timing the execution until {@link #stopTiming()} is called.
|
||||
*/
|
||||
public void startTiming();
|
||||
|
||||
/**
|
||||
* <p>Stops timing and records the data. Propagates the data up to group handlers.</p>
|
||||
*
|
||||
* Will automatically be called when this Timing is used with try-with-resources
|
||||
*/
|
||||
public void stopTiming();
|
||||
|
||||
/**
|
||||
* Starts timing the execution until {@link #stopTiming()} is called.
|
||||
*
|
||||
* But only if we are on the primary thread.
|
||||
*/
|
||||
public void startTimingIfSync();
|
||||
|
||||
/**
|
||||
* <p>Stops timing and records the data. Propagates the data up to group handlers.</p>
|
||||
*
|
||||
* <p>Will automatically be called when this Timing is used with try-with-resources</p>
|
||||
*
|
||||
* But only if we are on the primary thread.
|
||||
*/
|
||||
public void stopTimingIfSync();
|
||||
|
||||
/**
|
||||
* Stops timing and disregards current timing data.
|
||||
*/
|
||||
public void abort();
|
||||
|
||||
/**
|
||||
* Used internally to get the actual backing Handler in the case of delegated Handlers
|
||||
*
|
||||
* @return TimingHandler
|
||||
*/
|
||||
TimingHandler getTimingHandler();
|
||||
|
||||
@Override
|
||||
void close();
|
||||
}
|
105
TacoSpigot-API/src/main/java/co/aikar/timings/TimingData.java
Normal file
105
TacoSpigot-API/src/main/java/co/aikar/timings/TimingData.java
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static co.aikar.util.JSONUtil.toArray;
|
||||
|
||||
/**
|
||||
* <p>Lightweight object for tracking timing data</p>
|
||||
*
|
||||
* This is broken out to reduce memory usage
|
||||
*/
|
||||
class TimingData {
|
||||
static Function<Integer, TimingData> LOADER = new Function<Integer, TimingData>() {
|
||||
@Override
|
||||
public TimingData apply(Integer input) {
|
||||
return new TimingData(input);
|
||||
}
|
||||
};
|
||||
int id;
|
||||
int count = 0;
|
||||
int lagCount = 0;
|
||||
long totalTime = 0;
|
||||
long lagTotalTime = 0;
|
||||
|
||||
int curTickCount = 0;
|
||||
int curTickTotal = 0;
|
||||
|
||||
TimingData(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
TimingData(TimingData data) {
|
||||
this.id = data.id;
|
||||
this.totalTime = data.totalTime;
|
||||
this.lagTotalTime = data.lagTotalTime;
|
||||
this.count = data.count;
|
||||
this.lagCount = data.lagCount;
|
||||
}
|
||||
|
||||
void add(long diff) {
|
||||
++curTickCount;
|
||||
curTickTotal += diff;
|
||||
}
|
||||
|
||||
void processTick(boolean violated) {
|
||||
totalTime += curTickTotal;
|
||||
count += curTickCount;
|
||||
if (violated) {
|
||||
lagTotalTime += curTickTotal;
|
||||
lagCount += curTickCount;
|
||||
}
|
||||
curTickTotal = 0;
|
||||
curTickCount = 0;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
count = 0;
|
||||
lagCount = 0;
|
||||
curTickTotal = 0;
|
||||
curTickCount = 0;
|
||||
totalTime = 0;
|
||||
lagTotalTime = 0;
|
||||
}
|
||||
|
||||
protected TimingData clone() {
|
||||
return new TimingData(this);
|
||||
}
|
||||
|
||||
public List export() {
|
||||
List list = toArray(
|
||||
id,
|
||||
count,
|
||||
totalTime);
|
||||
if (lagCount > 0) {
|
||||
list.add(lagCount);
|
||||
list.add(lagTotalTime);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
193
TacoSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java
Normal file
193
TacoSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import co.aikar.util.LoadingIntMap;
|
||||
import co.aikar.util.LoadingMap;
|
||||
import co.aikar.util.MRUMapCache;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
class TimingHandler implements Timing {
|
||||
|
||||
private static int idPool = 1;
|
||||
final int id = idPool++;
|
||||
|
||||
final String name;
|
||||
final boolean verbose;
|
||||
|
||||
final TIntObjectHashMap<TimingData> children = new LoadingIntMap<TimingData>(TimingData.LOADER);
|
||||
|
||||
final TimingData record;
|
||||
final TimingHandler groupHandler;
|
||||
|
||||
long start = 0;
|
||||
int timingDepth = 0;
|
||||
boolean added;
|
||||
boolean timed;
|
||||
boolean enabled;
|
||||
TimingHandler parent;
|
||||
|
||||
TimingHandler(TimingIdentifier id) {
|
||||
if (id.name.startsWith("##")) {
|
||||
verbose = true;
|
||||
this.name = id.name.substring(3);
|
||||
} else {
|
||||
this.name = id.name;
|
||||
verbose = false;
|
||||
}
|
||||
|
||||
this.record = new TimingData(this.id);
|
||||
this.groupHandler = id.groupHandler;
|
||||
|
||||
TimingIdentifier.getGroup(id.group).handlers.add(this);
|
||||
checkEnabled();
|
||||
}
|
||||
|
||||
final void checkEnabled() {
|
||||
enabled = Timings.timingsEnabled && (!verbose || Timings.verboseEnabled);
|
||||
}
|
||||
|
||||
void processTick(boolean violated) {
|
||||
if (timingDepth != 0 || record.curTickCount == 0) {
|
||||
timingDepth = 0;
|
||||
start = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
record.processTick(violated);
|
||||
for (TimingData handler : children.valueCollection()) {
|
||||
handler.processTick(violated);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTimingIfSync() {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
startTiming();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTimingIfSync() {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
stopTiming();
|
||||
}
|
||||
}
|
||||
|
||||
public void startTiming() {
|
||||
if (enabled && ++timingDepth == 1) {
|
||||
start = System.nanoTime();
|
||||
parent = TimingsManager.CURRENT;
|
||||
TimingsManager.CURRENT = this;
|
||||
}
|
||||
}
|
||||
|
||||
public void stopTiming() {
|
||||
if (enabled && --timingDepth == 0 && start != 0) {
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "stopTiming called async for " + name);
|
||||
new Throwable().printStackTrace();
|
||||
start = 0;
|
||||
return;
|
||||
}
|
||||
addDiff(System.nanoTime() - start);
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
if (enabled && timingDepth > 0) {
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void addDiff(long diff) {
|
||||
if (TimingsManager.CURRENT == this) {
|
||||
TimingsManager.CURRENT = parent;
|
||||
if (parent != null) {
|
||||
parent.children.get(id).add(diff);
|
||||
}
|
||||
}
|
||||
record.add(diff);
|
||||
if (!added) {
|
||||
added = true;
|
||||
timed = true;
|
||||
TimingsManager.HANDLERS.add(this);
|
||||
}
|
||||
if (groupHandler != null) {
|
||||
groupHandler.addDiff(diff);
|
||||
groupHandler.children.get(id).add(diff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset this timer, setting all values to zero.
|
||||
*
|
||||
* @param full
|
||||
*/
|
||||
void reset(boolean full) {
|
||||
record.reset();
|
||||
if (full) {
|
||||
timed = false;
|
||||
}
|
||||
start = 0;
|
||||
timingDepth = 0;
|
||||
added = false;
|
||||
children.clear();
|
||||
checkEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimingHandler getTimingHandler() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return (this == o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is simply for the Closeable interface so it can be used with
|
||||
* try-with-resources ()
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
stopTimingIfSync();
|
||||
}
|
||||
|
||||
public boolean isSpecial() {
|
||||
return this == TimingsManager.FULL_SERVER_TICK || this == TimingsManager.TIMINGS_TICK;
|
||||
}
|
||||
}
|
276
TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistory.java
Normal file
276
TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistory.java
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import co.aikar.util.LoadingMap;
|
||||
import co.aikar.util.MRUMapCache;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static co.aikar.timings.TimingsManager.FULL_SERVER_TICK;
|
||||
import static co.aikar.timings.TimingsManager.MINUTE_REPORTS;
|
||||
import static co.aikar.util.JSONUtil.*;
|
||||
|
||||
@SuppressWarnings({"deprecation", "SuppressionAnnotation"})
|
||||
public class TimingHistory {
|
||||
public static long lastMinuteTime;
|
||||
public static long timedTicks;
|
||||
public static long playerTicks;
|
||||
public static long entityTicks;
|
||||
public static long tileEntityTicks;
|
||||
public static long activatedEntityTicks;
|
||||
static int worldIdPool = 1;
|
||||
static Map<String, Integer> worldMap = LoadingMap.newHashMap(new Function<String, Integer>() {
|
||||
@Override
|
||||
public Integer apply(String input) {
|
||||
return worldIdPool++;
|
||||
}
|
||||
});
|
||||
final long endTime;
|
||||
final long startTime;
|
||||
final long totalTicks;
|
||||
final long totalTime; // Represents all time spent running the server this history
|
||||
final MinuteReport[] minuteReports;
|
||||
|
||||
final TimingHistoryEntry[] entries;
|
||||
final Set<Material> tileEntityTypeSet = Sets.newHashSet();
|
||||
final Set<EntityType> entityTypeSet = Sets.newHashSet();
|
||||
final Map<Object, Object> worlds;
|
||||
|
||||
TimingHistory() {
|
||||
this.endTime = System.currentTimeMillis() / 1000;
|
||||
this.startTime = TimingsManager.historyStart / 1000;
|
||||
if (timedTicks % 1200 != 0 || MINUTE_REPORTS.isEmpty()) {
|
||||
this.minuteReports = MINUTE_REPORTS.toArray(new MinuteReport[MINUTE_REPORTS.size() + 1]);
|
||||
this.minuteReports[this.minuteReports.length - 1] = new MinuteReport();
|
||||
} else {
|
||||
this.minuteReports = MINUTE_REPORTS.toArray(new MinuteReport[MINUTE_REPORTS.size()]);
|
||||
}
|
||||
long ticks = 0;
|
||||
for (MinuteReport mp : this.minuteReports) {
|
||||
ticks += mp.ticksRecord.timed;
|
||||
}
|
||||
this.totalTicks = ticks;
|
||||
this.totalTime = FULL_SERVER_TICK.record.totalTime;
|
||||
this.entries = new TimingHistoryEntry[TimingsManager.HANDLERS.size()];
|
||||
|
||||
int i = 0;
|
||||
for (TimingHandler handler : TimingsManager.HANDLERS) {
|
||||
entries[i++] = new TimingHistoryEntry(handler);
|
||||
}
|
||||
|
||||
final Map<EntityType, Counter> entityCounts = MRUMapCache.of(LoadingMap.of(
|
||||
new EnumMap<EntityType, Counter>(EntityType.class), Counter.LOADER
|
||||
));
|
||||
final Map<Material, Counter> tileEntityCounts = MRUMapCache.of(LoadingMap.of(
|
||||
new EnumMap<Material, Counter>(Material.class), Counter.LOADER
|
||||
));
|
||||
// Information about all loaded chunks/entities
|
||||
this.worlds = toObjectMapper(Bukkit.getWorlds(), new Function<World, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(World world) {
|
||||
return pair(
|
||||
worldMap.get(world.getName()),
|
||||
toArrayMapper(world.getLoadedChunks(), new Function<Chunk, Object>() {
|
||||
@Override
|
||||
public Object apply(Chunk chunk) {
|
||||
entityCounts.clear();
|
||||
tileEntityCounts.clear();
|
||||
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
entityCounts.get(entity.getType()).increment();
|
||||
}
|
||||
|
||||
for (BlockState tileEntity : chunk.getTileEntities()) {
|
||||
tileEntityCounts.get(tileEntity.getBlock().getType()).increment();
|
||||
}
|
||||
|
||||
if (tileEntityCounts.isEmpty() && entityCounts.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return toArray(
|
||||
chunk.getX(),
|
||||
chunk.getZ(),
|
||||
toObjectMapper(entityCounts.entrySet(),
|
||||
new Function<Map.Entry<EntityType, Counter>, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(Map.Entry<EntityType, Counter> entry) {
|
||||
entityTypeSet.add(entry.getKey());
|
||||
return pair(
|
||||
String.valueOf(entry.getKey().getTypeId()),
|
||||
entry.getValue().count()
|
||||
);
|
||||
}
|
||||
}
|
||||
),
|
||||
toObjectMapper(tileEntityCounts.entrySet(),
|
||||
new Function<Map.Entry<Material, Counter>, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(Map.Entry<Material, Counter> entry) {
|
||||
tileEntityTypeSet.add(entry.getKey());
|
||||
return pair(
|
||||
String.valueOf(entry.getKey().getId()),
|
||||
entry.getValue().count()
|
||||
);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void resetTicks(boolean fullReset) {
|
||||
if (fullReset) {
|
||||
// Non full is simply for 1 minute reports
|
||||
timedTicks = 0;
|
||||
}
|
||||
lastMinuteTime = System.nanoTime();
|
||||
playerTicks = 0;
|
||||
tileEntityTicks = 0;
|
||||
entityTicks = 0;
|
||||
activatedEntityTicks = 0;
|
||||
}
|
||||
|
||||
Object export() {
|
||||
return createObject(
|
||||
pair("s", startTime),
|
||||
pair("e", endTime),
|
||||
pair("tk", totalTicks),
|
||||
pair("tm", totalTime),
|
||||
pair("w", worlds),
|
||||
pair("h", toArrayMapper(entries, new Function<TimingHistoryEntry, Object>() {
|
||||
@Override
|
||||
public Object apply(TimingHistoryEntry entry) {
|
||||
TimingData record = entry.data;
|
||||
if (record.count == 0) {
|
||||
return null;
|
||||
}
|
||||
return entry.export();
|
||||
}
|
||||
})),
|
||||
pair("mp", toArrayMapper(minuteReports, new Function<MinuteReport, Object>() {
|
||||
@Override
|
||||
public Object apply(MinuteReport input) {
|
||||
return input.export();
|
||||
}
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
static class MinuteReport {
|
||||
final long time = System.currentTimeMillis() / 1000;
|
||||
|
||||
final TicksRecord ticksRecord = new TicksRecord();
|
||||
final PingRecord pingRecord = new PingRecord();
|
||||
final TimingData fst = TimingsManager.FULL_SERVER_TICK.minuteData.clone();
|
||||
final double tps = 1E9 / ( System.nanoTime() - lastMinuteTime ) * ticksRecord.timed;
|
||||
final double usedMemory = TimingsManager.FULL_SERVER_TICK.avgUsedMemory;
|
||||
final double freeMemory = TimingsManager.FULL_SERVER_TICK.avgFreeMemory;
|
||||
final double loadAvg = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage();
|
||||
|
||||
public List export() {
|
||||
return toArray(
|
||||
time,
|
||||
Math.round(tps * 100D) / 100D,
|
||||
Math.round(pingRecord.avg * 100D) / 100D,
|
||||
fst.export(),
|
||||
toArray(ticksRecord.timed,
|
||||
ticksRecord.player,
|
||||
ticksRecord.entity,
|
||||
ticksRecord.activatedEntity,
|
||||
ticksRecord.tileEntity
|
||||
),
|
||||
usedMemory,
|
||||
freeMemory,
|
||||
loadAvg
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static class TicksRecord {
|
||||
final long timed;
|
||||
final long player;
|
||||
final long entity;
|
||||
final long tileEntity;
|
||||
final long activatedEntity;
|
||||
|
||||
TicksRecord() {
|
||||
timed = timedTicks - (TimingsManager.MINUTE_REPORTS.size() * 1200);
|
||||
player = playerTicks;
|
||||
entity = entityTicks;
|
||||
tileEntity = tileEntityTicks;
|
||||
activatedEntity = activatedEntityTicks;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class PingRecord {
|
||||
final double avg;
|
||||
|
||||
PingRecord() {
|
||||
final Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
int totalPing = 0;
|
||||
for (Player player : onlinePlayers) {
|
||||
totalPing += player.spigot().getPing();
|
||||
}
|
||||
avg = onlinePlayers.isEmpty() ? 0 : totalPing / onlinePlayers.size();
|
||||
}
|
||||
}
|
||||
|
||||
static class Counter {
|
||||
int count = 0;
|
||||
@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
|
||||
static Function LOADER = new LoadingMap.Feeder<Counter>() {
|
||||
@Override
|
||||
public Counter apply() {
|
||||
return new Counter();
|
||||
}
|
||||
};
|
||||
public int increment() {
|
||||
return ++count;
|
||||
}
|
||||
public int count() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static co.aikar.util.JSONUtil.toArrayMapper;
|
||||
|
||||
class TimingHistoryEntry {
|
||||
final TimingData data;
|
||||
final TimingData[] children;
|
||||
|
||||
TimingHistoryEntry(TimingHandler handler) {
|
||||
this.data = handler.record.clone();
|
||||
children = new TimingData[handler.children.size()];
|
||||
int i = 0;
|
||||
for (TimingData child : handler.children.valueCollection()) {
|
||||
children[i++] = child.clone();
|
||||
}
|
||||
}
|
||||
|
||||
List export() {
|
||||
List result = data.export();
|
||||
if (children.length > 0) {
|
||||
result.add(
|
||||
toArrayMapper(children, new Function<TimingData, Object>() {
|
||||
@Override
|
||||
public Object apply(TimingData child) {
|
||||
return child.export();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import co.aikar.util.LoadingMap;
|
||||
import co.aikar.util.MRUMapCache;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>Used as a basis for fast HashMap key comparisons for the Timing Map.</p>
|
||||
*
|
||||
* This class uses interned strings giving us the ability to do an identity check instead of equals() on the strings
|
||||
*/
|
||||
final class TimingIdentifier {
|
||||
/**
|
||||
* Holds all groups. Autoloads on request for a group by name.
|
||||
*/
|
||||
static final Map<String, TimingGroup> GROUP_MAP = MRUMapCache.of(
|
||||
LoadingMap.newIdentityHashMap(new Function<String, TimingGroup>() {
|
||||
@Override
|
||||
public TimingGroup apply(String group) {
|
||||
return new TimingGroup(group);
|
||||
}
|
||||
}, 64)
|
||||
);
|
||||
static final TimingGroup DEFAULT_GROUP = getGroup("Minecraft");
|
||||
final String group;
|
||||
final String name;
|
||||
final TimingHandler groupHandler;
|
||||
final boolean protect;
|
||||
private final int hashCode;
|
||||
|
||||
TimingIdentifier(String group, String name, Timing groupHandler, boolean protect) {
|
||||
this.group = group != null ? group.intern() : DEFAULT_GROUP.name;
|
||||
this.name = name.intern();
|
||||
this.groupHandler = groupHandler != null ? groupHandler.getTimingHandler() : null;
|
||||
this.protect = protect;
|
||||
this.hashCode = (31 * this.group.hashCode()) + this.name.hashCode();
|
||||
}
|
||||
|
||||
static TimingGroup getGroup(String groupName) {
|
||||
if (groupName == null) {
|
||||
return DEFAULT_GROUP;
|
||||
}
|
||||
|
||||
return GROUP_MAP.get(groupName.intern());
|
||||
}
|
||||
|
||||
// We are using .intern() on the strings so it is guaranteed to be an identity comparison.
|
||||
@SuppressWarnings("StringEquality")
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TimingIdentifier that = (TimingIdentifier) o;
|
||||
return group == that.group && name == that.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
static class TimingGroup {
|
||||
|
||||
private static int idPool = 1;
|
||||
final int id = idPool++;
|
||||
|
||||
final String name;
|
||||
ArrayDeque<TimingHandler> handlers = new ArrayDeque<TimingHandler>(64);
|
||||
|
||||
private TimingGroup(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
273
TacoSpigot-API/src/main/java/co/aikar/timings/Timings.java
Normal file
273
TacoSpigot-API/src/main/java/co/aikar/timings/Timings.java
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.EvictingQueue;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public final class Timings {
|
||||
|
||||
private static final int MAX_HISTORY_FRAMES = 12;
|
||||
public static final Timing NULL_HANDLER = new NullTimingHandler();
|
||||
static boolean timingsEnabled = false;
|
||||
static boolean verboseEnabled = false;
|
||||
private static int historyInterval = -1;
|
||||
private static int historyLength = -1;
|
||||
|
||||
private Timings() {}
|
||||
|
||||
/**
|
||||
* Returns a Timing for a plugin corresponding to a name.
|
||||
*
|
||||
* @param plugin Plugin to own the Timing
|
||||
* @param name Name of Timing
|
||||
* @return Handler
|
||||
*/
|
||||
public static Timing of(Plugin plugin, String name) {
|
||||
Timing pluginHandler = null;
|
||||
if (plugin != null) {
|
||||
pluginHandler = ofSafe(plugin.getName(), "Combined Total", TimingsManager.PLUGIN_GROUP_HANDLER);
|
||||
}
|
||||
return of(plugin, name, pluginHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns a handler that has a groupHandler timer handler. Parent timers should not have their
|
||||
* start/stop methods called directly, as the children will call it for you.</p>
|
||||
*
|
||||
* Parent Timers are used to group multiple subsections together and get a summary of them combined
|
||||
* Parent Handler can not be changed after first call
|
||||
*
|
||||
* @param plugin Plugin to own the Timing
|
||||
* @param name Name of Timing
|
||||
* @param groupHandler Parent handler to mirror .start/stop calls to
|
||||
* @return Timing Handler
|
||||
*/
|
||||
public static Timing of(Plugin plugin, String name, Timing groupHandler) {
|
||||
Preconditions.checkNotNull(plugin, "Plugin can not be null");
|
||||
return TimingsManager.getHandler(plugin.getName(), name, groupHandler, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Timing object after starting it, useful for Java7 try-with-resources.
|
||||
*
|
||||
* try (Timing ignored = Timings.ofStart(plugin, someName)) {
|
||||
* // timed section
|
||||
* }
|
||||
*
|
||||
* @param plugin Plugin to own the Timing
|
||||
* @param name Name of Timing
|
||||
* @return Timing Handler
|
||||
*/
|
||||
public static Timing ofStart(Plugin plugin, String name) {
|
||||
return ofStart(plugin, name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Timing object after starting it, useful for Java7 try-with-resources.
|
||||
*
|
||||
* try (Timing ignored = Timings.ofStart(plugin, someName, groupHandler)) {
|
||||
* // timed section
|
||||
* }
|
||||
*
|
||||
* @param plugin Plugin to own the Timing
|
||||
* @param name Name of Timing
|
||||
* @param groupHandler Parent handler to mirror .start/stop calls to
|
||||
* @return Timing Handler
|
||||
*/
|
||||
public static Timing ofStart(Plugin plugin, String name, Timing groupHandler) {
|
||||
Timing timing = of(plugin, name, groupHandler);
|
||||
timing.startTimingIfSync();
|
||||
return timing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not the Spigot Timings system is enabled
|
||||
*
|
||||
* @return Enabled or not
|
||||
*/
|
||||
public static boolean isTimingsEnabled() {
|
||||
return timingsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets whether or not the Spigot Timings system should be enabled</p>
|
||||
*
|
||||
* Calling this will reset timing data.
|
||||
*
|
||||
* @param enabled Should timings be reported
|
||||
*/
|
||||
public static void setTimingsEnabled(boolean enabled) {
|
||||
timingsEnabled = enabled;
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets whether or not the Timings should monitor at Verbose level.</p>
|
||||
*
|
||||
* <p>When Verbose is disabled, high-frequency timings will not be available.</p>
|
||||
*
|
||||
* @return Enabled or not
|
||||
*/
|
||||
public static boolean isVerboseTimingsEnabled() {
|
||||
return timingsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not the Timings should monitor at Verbose level.
|
||||
* <p/>
|
||||
* When Verbose is disabled, high-frequency timings will not be available.
|
||||
* Calling this will reset timing data.
|
||||
*
|
||||
* @param enabled Should high-frequency timings be reported
|
||||
*/
|
||||
public static void setVerboseTimingsEnabled(boolean enabled) {
|
||||
verboseEnabled = enabled;
|
||||
TimingsManager.needsRecheckEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets the interval between Timing History report generation.</p>
|
||||
*
|
||||
* Defaults to 5 minutes (6000 ticks)
|
||||
*
|
||||
* @return Interval in ticks
|
||||
*/
|
||||
public static int getHistoryInterval() {
|
||||
return historyInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the interval between Timing History report generations.</p>
|
||||
*
|
||||
* <p>Defaults to 5 minutes (6000 ticks)</p>
|
||||
*
|
||||
* This will recheck your history length, so lowering this value will lower your
|
||||
* history length if you need more than 60 history windows.
|
||||
*
|
||||
* @param interval Interval in ticks
|
||||
*/
|
||||
public static void setHistoryInterval(int interval) {
|
||||
historyInterval = Math.max(20*60, interval);
|
||||
// Recheck the history length with the new Interval
|
||||
if (historyLength != -1) {
|
||||
setHistoryLength(historyLength);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets how long in ticks Timings history is kept for the server.
|
||||
*
|
||||
* Defaults to 1 hour (72000 ticks)
|
||||
*
|
||||
* @return Duration in Ticks
|
||||
*/
|
||||
public static int getHistoryLength() {
|
||||
return historyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how long Timing History reports are kept for the server.
|
||||
*
|
||||
* Defaults to 1 hours(72000 ticks)
|
||||
*
|
||||
* This value is capped at a maximum of getHistoryInterval() * MAX_HISTORY_FRAMES (12)
|
||||
*
|
||||
* Will not reset Timing Data but may truncate old history if the new length is less than old length.
|
||||
*
|
||||
* @param length Duration in ticks
|
||||
*/
|
||||
public static void setHistoryLength(int length) {
|
||||
// Cap at 12 History Frames, 1 hour at 5 minute frames.
|
||||
int maxLength = historyInterval * MAX_HISTORY_FRAMES;
|
||||
// For special cases of servers with special permission to bypass the max.
|
||||
// This max helps keep data file sizes reasonable for processing on Aikar's Timing parser side.
|
||||
// Setting this will not help you bypass the max unless Aikar has added an exception on the API side.
|
||||
if (System.getProperty("timings.bypassMax") != null) {
|
||||
maxLength = Integer.MAX_VALUE;
|
||||
}
|
||||
historyLength = Math.max(Math.min(maxLength, length), historyInterval);
|
||||
Queue<TimingHistory> oldQueue = TimingsManager.HISTORY;
|
||||
int frames = (getHistoryLength() / getHistoryInterval());
|
||||
if (length > maxLength) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Timings Length too high. Requested " + length + ", max is " + maxLength + ". To get longer history, you must increase your interval. Set Interval to " + Math.ceil(length / MAX_HISTORY_FRAMES) + " to achieve this length.");
|
||||
}
|
||||
TimingsManager.HISTORY = EvictingQueue.create(frames);
|
||||
TimingsManager.HISTORY.addAll(oldQueue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all Timing Data
|
||||
*/
|
||||
public static void reset() {
|
||||
TimingsManager.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a report and sends it to the specified command sender.
|
||||
*
|
||||
* If sender is null, ConsoleCommandSender will be used.
|
||||
* @param sender The sender to send to, or null to use the ConsoleCommandSender
|
||||
*/
|
||||
public static void generateReport(CommandSender sender) {
|
||||
if (sender == null) {
|
||||
sender = Bukkit.getConsoleSender();
|
||||
}
|
||||
TimingsExport.reportTimings(sender);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Protected API: These are for internal use only in Bukkit/CraftBukkit
|
||||
These do not have isPrimaryThread() checks in the startTiming/stopTiming
|
||||
=================
|
||||
*/
|
||||
|
||||
static TimingHandler ofSafe(String name) {
|
||||
return ofSafe(null, name, null);
|
||||
}
|
||||
|
||||
static Timing ofSafe(Plugin plugin, String name) {
|
||||
Timing pluginHandler = null;
|
||||
if (plugin != null) {
|
||||
pluginHandler = ofSafe(plugin.getName(), "Combined Total", TimingsManager.PLUGIN_GROUP_HANDLER);
|
||||
}
|
||||
return ofSafe(plugin != null ? plugin.getName() : "Minecraft - Invalid Plugin", name, pluginHandler);
|
||||
}
|
||||
|
||||
static TimingHandler ofSafe(String name, Timing groupHandler) {
|
||||
return ofSafe(null, name, groupHandler);
|
||||
}
|
||||
|
||||
static TimingHandler ofSafe(String groupName, String name, Timing groupHandler) {
|
||||
return TimingsManager.getHandler(groupName, name, groupHandler, false);
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.defaults.BukkitCommand;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class TimingsCommand extends BukkitCommand {
|
||||
public static final List<String> TIMINGS_SUBCOMMANDS = ImmutableList.of("report", "reset", "on", "off", "paste", "verbon", "verboff");
|
||||
|
||||
public TimingsCommand(String name) {
|
||||
super(name);
|
||||
this.description = "Manages Spigot Timings data to see performance of the server.";
|
||||
this.usageMessage = "/timings <reset|report|on|off|verbon|verboff>";
|
||||
this.setPermission("bukkit.command.timings");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
|
||||
if (!testPermission(sender)) {
|
||||
return true;
|
||||
}
|
||||
if (args.length < 1) {
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
return true;
|
||||
}
|
||||
final String arg = args[0];
|
||||
if ("on".equalsIgnoreCase(arg)) {
|
||||
Timings.setTimingsEnabled(true);
|
||||
sender.sendMessage("Enabled Timings & Reset");
|
||||
return true;
|
||||
} else if ("off".equalsIgnoreCase(arg)) {
|
||||
Timings.setTimingsEnabled(false);
|
||||
sender.sendMessage("Disabled Timings");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Timings.isTimingsEnabled()) {
|
||||
sender.sendMessage("Please enable timings by typing /timings on");
|
||||
return true;
|
||||
}
|
||||
if ("verbon".equalsIgnoreCase(arg)) {
|
||||
Timings.setVerboseTimingsEnabled(true);
|
||||
sender.sendMessage("Enabled Verbose Timings");
|
||||
return true;
|
||||
} else if ("verboff".equalsIgnoreCase(arg)) {
|
||||
Timings.setVerboseTimingsEnabled(false);
|
||||
sender.sendMessage("Disabled Verbose Timings");
|
||||
return true;
|
||||
} else if ("reset".equalsIgnoreCase(arg)) {
|
||||
TimingsManager.reset();
|
||||
sender.sendMessage("Timings reset");
|
||||
} else if ("cost".equals(arg)) {
|
||||
sender.sendMessage("Timings cost: " + TimingsExport.getCost());
|
||||
} else if (
|
||||
"paste".equalsIgnoreCase(arg) ||
|
||||
"report".equalsIgnoreCase(arg) ||
|
||||
"get".equalsIgnoreCase(arg) ||
|
||||
"merged".equalsIgnoreCase(arg) ||
|
||||
"separate".equalsIgnoreCase(arg)
|
||||
) {
|
||||
TimingsExport.reportTimings(sender);
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
|
||||
}
|
||||
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], TIMINGS_SUBCOMMANDS,
|
||||
new ArrayList<String>(TIMINGS_SUBCOMMANDS.size()));
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
373
TacoSpigot-API/src/main/java/co/aikar/timings/TimingsExport.java
Normal file
373
TacoSpigot-API/src/main/java/co/aikar/timings/TimingsExport.java
Normal file
@ -0,0 +1,373 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.MemorySection;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import static co.aikar.timings.TimingsManager.HISTORY;
|
||||
import static co.aikar.util.JSONUtil.*;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
|
||||
class TimingsExport extends Thread {
|
||||
|
||||
private final CommandSender sender;
|
||||
private final Map out;
|
||||
private final TimingHistory[] history;
|
||||
|
||||
TimingsExport(CommandSender sender, Map out, TimingHistory[] history) {
|
||||
super("Timings paste thread");
|
||||
this.sender = sender;
|
||||
this.out = out;
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds an XML report of the timings to be uploaded for parsing.
|
||||
*
|
||||
* @param sender Who to report to
|
||||
*/
|
||||
static void reportTimings(CommandSender sender) {
|
||||
Map parent = createObject(
|
||||
// Get some basic system details about the server
|
||||
pair("version", Bukkit.getVersion()),
|
||||
pair("maxplayers", Bukkit.getMaxPlayers()),
|
||||
pair("start", TimingsManager.timingStart / 1000),
|
||||
pair("end", System.currentTimeMillis() / 1000),
|
||||
pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000)
|
||||
);
|
||||
if (!TimingsManager.privacy) {
|
||||
appendObjectData(parent,
|
||||
pair("server", Bukkit.getServerName()),
|
||||
pair("motd", Bukkit.getServer().getMotd()),
|
||||
pair("online-mode", Bukkit.getServer().getOnlineMode()),
|
||||
pair("icon", Bukkit.getServer().getServerIcon().getData())
|
||||
);
|
||||
}
|
||||
|
||||
final Runtime runtime = Runtime.getRuntime();
|
||||
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
parent.put("system", createObject(
|
||||
pair("timingcost", getCost()),
|
||||
pair("name", System.getProperty("os.name")),
|
||||
pair("version", System.getProperty("os.version")),
|
||||
pair("jvmversion", System.getProperty("java.version")),
|
||||
pair("arch", System.getProperty("os.arch")),
|
||||
pair("maxmem", runtime.maxMemory()),
|
||||
pair("cpu", runtime.availableProcessors()),
|
||||
pair("runtime", ManagementFactory.getRuntimeMXBean().getUptime()),
|
||||
pair("flags", StringUtils.join(runtimeBean.getInputArguments(), " ")),
|
||||
pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), new Function<GarbageCollectorMXBean, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(GarbageCollectorMXBean input) {
|
||||
return pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime()));
|
||||
}
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
||||
Set<Material> tileEntityTypeSet = Sets.newHashSet();
|
||||
Set<EntityType> entityTypeSet = Sets.newHashSet();
|
||||
|
||||
int size = HISTORY.size();
|
||||
TimingHistory[] history = new TimingHistory[size + 1];
|
||||
int i = 0;
|
||||
for (TimingHistory timingHistory : HISTORY) {
|
||||
tileEntityTypeSet.addAll(timingHistory.tileEntityTypeSet);
|
||||
entityTypeSet.addAll(timingHistory.entityTypeSet);
|
||||
history[i++] = timingHistory;
|
||||
}
|
||||
|
||||
history[i] = new TimingHistory(); // Current snapshot
|
||||
tileEntityTypeSet.addAll(history[i].tileEntityTypeSet);
|
||||
entityTypeSet.addAll(history[i].entityTypeSet);
|
||||
|
||||
|
||||
Map handlers = createObject();
|
||||
for (TimingIdentifier.TimingGroup group : TimingIdentifier.GROUP_MAP.values()) {
|
||||
for (TimingHandler id : group.handlers) {
|
||||
if (!id.timed && !id.isSpecial()) {
|
||||
continue;
|
||||
}
|
||||
handlers.put(id.id, toArray(
|
||||
group.id,
|
||||
id.name
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
parent.put("idmap", createObject(
|
||||
pair("groups", toObjectMapper(
|
||||
TimingIdentifier.GROUP_MAP.values(), new Function<TimingIdentifier.TimingGroup, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(TimingIdentifier.TimingGroup group) {
|
||||
return pair(group.id, group.name);
|
||||
}
|
||||
})),
|
||||
pair("handlers", handlers),
|
||||
pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), new Function<Map.Entry<String, Integer>, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(Map.Entry<String, Integer> input) {
|
||||
return pair(input.getValue(), input.getKey());
|
||||
}
|
||||
})),
|
||||
pair("tileentity",
|
||||
toObjectMapper(tileEntityTypeSet, new Function<Material, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(Material input) {
|
||||
return pair(input.getId(), input.name());
|
||||
}
|
||||
})),
|
||||
pair("entity",
|
||||
toObjectMapper(entityTypeSet, new Function<EntityType, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(EntityType input) {
|
||||
return pair(input.getTypeId(), input.name());
|
||||
}
|
||||
}))
|
||||
));
|
||||
|
||||
// Information about loaded plugins
|
||||
|
||||
parent.put("plugins", toObjectMapper(Bukkit.getPluginManager().getPlugins(),
|
||||
new Function<Plugin, JSONPair>() {
|
||||
@Override
|
||||
public JSONPair apply(Plugin plugin) {
|
||||
return pair(plugin.getName(), createObject(
|
||||
pair("version", plugin.getDescription().getVersion()),
|
||||
pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()),
|
||||
pair("website", plugin.getDescription().getWebsite()),
|
||||
pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", "))
|
||||
));
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
|
||||
// Information on the users Config
|
||||
|
||||
parent.put("config", createObject(
|
||||
pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
|
||||
pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
|
||||
pair("paperspigot", mapAsJSON(Bukkit.spigot().getPaperSpigotConfig(), null))
|
||||
));
|
||||
|
||||
new TimingsExport(sender, parent, history).start();
|
||||
}
|
||||
|
||||
static long getCost() {
|
||||
// Benchmark the users System.nanotime() for cost basis
|
||||
int passes = 100;
|
||||
TimingHandler SAMPLER1 = Timings.ofSafe("Timings Sampler 1");
|
||||
TimingHandler SAMPLER2 = Timings.ofSafe("Timings Sampler 2");
|
||||
TimingHandler SAMPLER3 = Timings.ofSafe("Timings Sampler 3");
|
||||
TimingHandler SAMPLER4 = Timings.ofSafe("Timings Sampler 4");
|
||||
TimingHandler SAMPLER5 = Timings.ofSafe("Timings Sampler 5");
|
||||
TimingHandler SAMPLER6 = Timings.ofSafe("Timings Sampler 6");
|
||||
|
||||
long start = System.nanoTime();
|
||||
for (int i = 0; i < passes; i++) {
|
||||
SAMPLER1.startTiming();
|
||||
SAMPLER2.startTiming();
|
||||
SAMPLER3.startTiming();
|
||||
SAMPLER3.stopTiming();
|
||||
SAMPLER4.startTiming();
|
||||
SAMPLER5.startTiming();
|
||||
SAMPLER6.startTiming();
|
||||
SAMPLER6.stopTiming();
|
||||
SAMPLER5.stopTiming();
|
||||
SAMPLER4.stopTiming();
|
||||
SAMPLER2.stopTiming();
|
||||
SAMPLER1.stopTiming();
|
||||
}
|
||||
long timingsCost = (System.nanoTime() - start) / passes / 6;
|
||||
SAMPLER1.reset(true);
|
||||
SAMPLER2.reset(true);
|
||||
SAMPLER3.reset(true);
|
||||
SAMPLER4.reset(true);
|
||||
SAMPLER5.reset(true);
|
||||
SAMPLER6.reset(true);
|
||||
return timingsCost;
|
||||
}
|
||||
|
||||
private static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) {
|
||||
|
||||
JSONObject object = new JSONObject();
|
||||
for (String key : config.getKeys(false)) {
|
||||
String fullKey = (parentKey != null ? parentKey + "." + key : key);
|
||||
if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey)) {
|
||||
continue;
|
||||
}
|
||||
final Object val = config.get(key);
|
||||
|
||||
object.put(key, valAsJSON(val, fullKey));
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private static Object valAsJSON(Object val, final String parentKey) {
|
||||
if (!(val instanceof MemorySection)) {
|
||||
if (val instanceof List) {
|
||||
Iterable<Object> v = (Iterable<Object>) val;
|
||||
return toArrayMapper(v, new Function<Object, Object>() {
|
||||
@Override
|
||||
public Object apply(Object input) {
|
||||
return valAsJSON(input, parentKey);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return val.toString();
|
||||
}
|
||||
} else {
|
||||
return mapAsJSON((ConfigurationSection) val, parentKey);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("CallToThreadRun")
|
||||
@Override
|
||||
public synchronized void start() {
|
||||
if (sender instanceof RemoteConsoleCommandSender) {
|
||||
sender.sendMessage(ChatColor.RED + "Warning: Timings report done over RCON will cause lag spikes.");
|
||||
sender.sendMessage(ChatColor.RED + "You should use " + ChatColor.YELLOW +
|
||||
"/timings report" + ChatColor.RED + " in game or console.");
|
||||
run();
|
||||
} else {
|
||||
super.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
sender.sendMessage(ChatColor.GREEN + "Preparing Timings Report...");
|
||||
|
||||
|
||||
out.put("data", toArrayMapper(history, new Function<TimingHistory, Object>() {
|
||||
@Override
|
||||
public Object apply(TimingHistory input) {
|
||||
return input.export();
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
String response = null;
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL("http://timings.aikar.co/post").openConnection();
|
||||
con.setDoOutput(true);
|
||||
con.setRequestProperty("User-Agent", "Spigot/" + Bukkit.getServerName() + "/" + InetAddress.getLocalHost().getHostName());
|
||||
con.setRequestMethod("POST");
|
||||
con.setInstanceFollowRedirects(false);
|
||||
|
||||
OutputStream request = new GZIPOutputStream(con.getOutputStream()) {{
|
||||
this.def.setLevel(7);
|
||||
}};
|
||||
|
||||
request.write(JSONValue.toJSONString(out).getBytes("UTF-8"));
|
||||
request.close();
|
||||
|
||||
response = getResponse(con);
|
||||
|
||||
if (con.getResponseCode() != 302) {
|
||||
sender.sendMessage(
|
||||
ChatColor.RED + "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage());
|
||||
sender.sendMessage(ChatColor.RED + "Check your logs for more information");
|
||||
if (response != null) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
String location = con.getHeaderField("Location");
|
||||
sender.sendMessage(ChatColor.GREEN + "View Timings Report: " + location);
|
||||
if (!(sender instanceof ConsoleCommandSender)) {
|
||||
Bukkit.getLogger().log(Level.INFO, "View Timings Report: " + location);
|
||||
}
|
||||
|
||||
if (response != null && !response.isEmpty()) {
|
||||
Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
|
||||
if (response != null) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, response);
|
||||
}
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String getResponse(HttpURLConnection con) throws IOException {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = con.getInputStream();
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
||||
byte[] b = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = is.read(b)) != -1) {
|
||||
bos.write(b, 0, bytesRead);
|
||||
}
|
||||
return bos.toString();
|
||||
|
||||
} catch (IOException ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information");
|
||||
Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex);
|
||||
return null;
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.EvictingQueue;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.PluginClassLoader;
|
||||
import co.aikar.util.LoadingMap;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public final class TimingsManager {
|
||||
static final Map<TimingIdentifier, TimingHandler> TIMING_MAP =
|
||||
Collections.synchronizedMap(LoadingMap.newHashMap(
|
||||
new Function<TimingIdentifier, TimingHandler>() {
|
||||
@Override
|
||||
public TimingHandler apply(TimingIdentifier id) {
|
||||
return (id.protect ?
|
||||
new UnsafeTimingHandler(id) :
|
||||
new TimingHandler(id)
|
||||
);
|
||||
}
|
||||
},
|
||||
256, .5F
|
||||
));
|
||||
public static final FullServerTickHandler FULL_SERVER_TICK = new FullServerTickHandler();
|
||||
public static final TimingHandler TIMINGS_TICK = Timings.ofSafe("Timings Tick", FULL_SERVER_TICK);
|
||||
public static final Timing PLUGIN_GROUP_HANDLER = Timings.ofSafe("Plugins");
|
||||
public static List<String> hiddenConfigs = new ArrayList<String>();
|
||||
public static boolean privacy = false;
|
||||
|
||||
static final Collection<TimingHandler> HANDLERS = new ArrayDeque<TimingHandler>();
|
||||
static final ArrayDeque<TimingHistory.MinuteReport> MINUTE_REPORTS = new ArrayDeque<TimingHistory.MinuteReport>();
|
||||
|
||||
static EvictingQueue<TimingHistory> HISTORY = EvictingQueue.create(12);
|
||||
static TimingHandler CURRENT;
|
||||
static long timingStart = 0;
|
||||
static long historyStart = 0;
|
||||
static boolean needsFullReset = false;
|
||||
static boolean needsRecheckEnabled = false;
|
||||
|
||||
private TimingsManager() {}
|
||||
|
||||
/**
|
||||
* Resets all timing data on the next tick
|
||||
*/
|
||||
static void reset() {
|
||||
needsFullReset = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ticked every tick by CraftBukkit to count the number of times a timer
|
||||
* caused TPS loss.
|
||||
*/
|
||||
static void tick() {
|
||||
if (Timings.timingsEnabled) {
|
||||
boolean violated = FULL_SERVER_TICK.isViolated();
|
||||
|
||||
for (TimingHandler handler : HANDLERS) {
|
||||
if (handler.isSpecial()) {
|
||||
// We manually call this
|
||||
continue;
|
||||
}
|
||||
handler.processTick(violated);
|
||||
}
|
||||
|
||||
TimingHistory.playerTicks += Bukkit.getOnlinePlayers().size();
|
||||
TimingHistory.timedTicks++;
|
||||
// Generate TPS/Ping/Tick reports every minute
|
||||
}
|
||||
}
|
||||
static void stopServer() {
|
||||
Timings.timingsEnabled = false;
|
||||
recheckEnabled();
|
||||
}
|
||||
static void recheckEnabled() {
|
||||
synchronized (TIMING_MAP) {
|
||||
for (TimingHandler timings : TIMING_MAP.values()) {
|
||||
timings.checkEnabled();
|
||||
}
|
||||
}
|
||||
needsRecheckEnabled = false;
|
||||
}
|
||||
static void resetTimings() {
|
||||
if (needsFullReset) {
|
||||
// Full resets need to re-check every handlers enabled state
|
||||
// Timing map can be modified from async so we must sync on it.
|
||||
synchronized (TIMING_MAP) {
|
||||
for (TimingHandler timings : TIMING_MAP.values()) {
|
||||
timings.reset(true);
|
||||
}
|
||||
}
|
||||
Bukkit.getLogger().log(Level.INFO, "Timings Reset");
|
||||
HISTORY.clear();
|
||||
needsFullReset = false;
|
||||
needsRecheckEnabled = false;
|
||||
timingStart = System.currentTimeMillis();
|
||||
} else {
|
||||
// Soft resets only need to act on timings that have done something
|
||||
// Handlers can only be modified on main thread.
|
||||
for (TimingHandler timings : HANDLERS) {
|
||||
timings.reset(false);
|
||||
}
|
||||
}
|
||||
|
||||
HANDLERS.clear();
|
||||
MINUTE_REPORTS.clear();
|
||||
|
||||
TimingHistory.resetTicks(true);
|
||||
historyStart = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
static TimingHandler getHandler(String group, String name, Timing parent, boolean protect) {
|
||||
return TIMING_MAP.get(new TimingIdentifier(group, name, parent, protect));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Due to access restrictions, we need a helper method to get a Command TimingHandler with String group</p>
|
||||
*
|
||||
* Plugins should never call this
|
||||
*
|
||||
* @param pluginName Plugin this command is associated with
|
||||
* @param command Command to get timings for
|
||||
* @return TimingHandler
|
||||
*/
|
||||
public static Timing getCommandTiming(String pluginName, Command command) {
|
||||
Plugin plugin = null;
|
||||
final Server server = Bukkit.getServer();
|
||||
if (!("minecraft".equals(pluginName) || "bukkit".equals(pluginName) || "Spigot".equals(pluginName) ||
|
||||
server == null)) {
|
||||
plugin = server.getPluginManager().getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
// Plugin is passing custom fallback prefix, try to look up by class loader
|
||||
plugin = getPluginByClassloader(command.getClass());
|
||||
}
|
||||
}
|
||||
if (plugin == null) {
|
||||
return Timings.ofSafe("Command: " + pluginName + ":" + command.getTimingName());
|
||||
}
|
||||
|
||||
return Timings.ofSafe(plugin, "Command: " + pluginName + ":" + command.getTimingName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the class loader for the specified class, and if it is a PluginClassLoader, return the
|
||||
* Plugin that created this class.
|
||||
*
|
||||
* @param clazz Class to check
|
||||
* @return Plugin if created by a plugin
|
||||
*/
|
||||
public static Plugin getPluginByClassloader(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
}
|
||||
final ClassLoader classLoader = clazz.getClassLoader();
|
||||
if (classLoader instanceof PluginClassLoader) {
|
||||
PluginClassLoader pluginClassLoader = (PluginClassLoader) classLoader;
|
||||
return pluginClassLoader.getPlugin();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.timings;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
class UnsafeTimingHandler extends TimingHandler {
|
||||
|
||||
UnsafeTimingHandler(TimingIdentifier id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
private static void checkThread() {
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalStateException("Calling Timings from Async Operation");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTiming() {
|
||||
checkThread();
|
||||
super.startTiming();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTiming() {
|
||||
checkThread();
|
||||
super.stopTiming();
|
||||
}
|
||||
}
|
123
TacoSpigot-API/src/main/java/co/aikar/util/JSONUtil.java
Normal file
123
TacoSpigot-API/src/main/java/co/aikar/util/JSONUtil.java
Normal file
@ -0,0 +1,123 @@
|
||||
package co.aikar.util;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides Utility methods that assist with generating JSON Objects
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "SuppressionAnnotation"})
|
||||
public final class JSONUtil {
|
||||
private JSONUtil() {}
|
||||
|
||||
/**
|
||||
* Creates a key/value "JSONPair" object
|
||||
* @param key
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public static JSONPair pair(String key, Object obj) {
|
||||
return new JSONPair(key, obj);
|
||||
}
|
||||
|
||||
public static JSONPair pair(long key, Object obj) {
|
||||
return new JSONPair(String.valueOf(key), obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new JSON object from multiple JsonPair key/value pairs
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Map createObject(JSONPair... data) {
|
||||
return appendObjectData(new LinkedHashMap(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* This appends multiple key/value Obj pairs into a JSON Object
|
||||
* @param parent
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Map appendObjectData(Map parent, JSONPair... data) {
|
||||
for (JSONPair JSONPair : data) {
|
||||
parent.put(JSONPair.key, JSONPair.val);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* This builds a JSON array from a set of data
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static List toArray(Object... data) {
|
||||
return Lists.newArrayList(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* These help build a single JSON array using a mapper function
|
||||
* @param collection
|
||||
* @param mapper
|
||||
* @param <E>
|
||||
* @return
|
||||
*/
|
||||
public static <E> List toArrayMapper(E[] collection, Function<E, Object> mapper) {
|
||||
return toArrayMapper(Lists.newArrayList(collection), mapper);
|
||||
}
|
||||
|
||||
public static <E> List toArrayMapper(Iterable<E> collection, Function<E, Object> mapper) {
|
||||
List array = Lists.newArrayList();
|
||||
for (E e : collection) {
|
||||
Object object = mapper.apply(e);
|
||||
if (object != null) {
|
||||
array.add(object);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* These help build a single JSON Object from a collection, using a mapper function
|
||||
* @param collection
|
||||
* @param mapper
|
||||
* @param <E>
|
||||
* @return
|
||||
*/
|
||||
public static <E> Map toObjectMapper(E[] collection, Function<E, JSONPair> mapper) {
|
||||
return toObjectMapper(Lists.newArrayList(collection), mapper);
|
||||
}
|
||||
|
||||
public static <E> Map toObjectMapper(Iterable<E> collection, Function<E, JSONPair> mapper) {
|
||||
Map object = Maps.newLinkedHashMap();
|
||||
for (E e : collection) {
|
||||
JSONPair JSONPair = mapper.apply(e);
|
||||
if (JSONPair != null) {
|
||||
object.put(JSONPair.key, JSONPair.val);
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply stores a key and a value, used internally by many methods below.
|
||||
*/
|
||||
@SuppressWarnings("PublicInnerClass")
|
||||
public static class JSONPair {
|
||||
final String key;
|
||||
final Object val;
|
||||
|
||||
JSONPair(String key, Object val) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2015. Starlis LLC / dba Empire Minecraft
|
||||
*
|
||||
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
|
||||
*
|
||||
*/
|
||||
package co.aikar.util;
|
||||
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
/**
|
||||
* Allows you to pass a Loader function that when a key is accessed that doesn't exist,
|
||||
* automatically loads the entry into the map by calling the loader Function.
|
||||
*
|
||||
* .get() Will only return null if the Loader can return null.
|
||||
*
|
||||
* You may pass any backing Map to use.
|
||||
*
|
||||
* This class is not thread safe and should be wrapped with Collections.synchronizedMap on the OUTSIDE of the LoadingMap if needed.
|
||||
*
|
||||
* Do not wrap the backing map with Collections.synchronizedMap.
|
||||
*
|
||||
* @param <V> Value
|
||||
*/
|
||||
public class LoadingIntMap<V> extends TIntObjectHashMap<V> {
|
||||
private final Function<Integer, V> loader;
|
||||
|
||||
/**
|
||||
* Initializes an auto loading map using specified loader and backing map
|
||||
* @param loader The loader
|
||||
*/
|
||||
public LoadingIntMap(Function<Integer, V> loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public V get(int key) {
|
||||
V res = super.get(key);
|
||||
if (res == null) {
|
||||
res = loader.apply(key);
|
||||
if (res != null) {
|
||||
put(key, res);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Due to java stuff, you will need to cast it to (Function) for some cases
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract static class Feeder <T> implements Function<T, T> {
|
||||
@Override
|
||||
public T apply(Object input) {
|
||||
return apply();
|
||||
}
|
||||
|
||||
public abstract T apply();
|
||||
}
|
||||
}
|
332
TacoSpigot-API/src/main/java/co/aikar/util/LoadingMap.java
Normal file
332
TacoSpigot-API/src/main/java/co/aikar/util/LoadingMap.java
Normal file
@ -0,0 +1,332 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.util;
|
||||
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.bukkit.Material;
|
||||
import co.aikar.timings.TimingHistory;
|
||||
import org.w3c.dom.css.Counter;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Allows you to pass a Loader function that when a key is accessed that doesn't exists,
|
||||
* automatically loads the entry into the map by calling the loader Function.
|
||||
*
|
||||
* .get() Will only return null if the Loader can return null.
|
||||
*
|
||||
* You may pass any backing Map to use.
|
||||
*
|
||||
* This class is not thread safe and should be wrapped with Collections.synchronizedMap on the OUTSIDE of the LoadingMap if needed.
|
||||
*
|
||||
* Do not wrap the backing map with Collections.synchronizedMap.
|
||||
*
|
||||
* @param <K> Key
|
||||
* @param <V> Value
|
||||
*/
|
||||
public class LoadingMap <K,V> extends AbstractMap<K, V> {
|
||||
private final Map<K, V> backingMap;
|
||||
private final Function<K, V> loader;
|
||||
|
||||
/**
|
||||
* Initializes an auto loading map using specified loader and backing map
|
||||
* @param backingMap
|
||||
* @param loader
|
||||
*/
|
||||
public LoadingMap(Map<K, V> backingMap, Function<K, V> loader) {
|
||||
this.backingMap = backingMap;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new LoadingMap with the specified map and loader
|
||||
* @param backingMap
|
||||
* @param loader
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> of(Map<K, V> backingMap, Function<K, V> loader) {
|
||||
return new LoadingMap<K, V>(backingMap, loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LoadingMap with an auto instantiating loader.
|
||||
*
|
||||
* Will auto construct class of of Value when not found
|
||||
*
|
||||
* Since this uses Reflection, It is more effecient to define your own static loader
|
||||
* than using this helper, but if performance is not critical, this is easier.
|
||||
*
|
||||
* @param backingMap Actual map being used.
|
||||
* @param keyClass Class used for the K generic
|
||||
* @param valueClass Class used for the V generic
|
||||
* @param <K> Key Type of the Map
|
||||
* @param <V> Value Type of the Map
|
||||
* @return Map that auto instantiates on .get()
|
||||
*/
|
||||
public static <K, V> Map<K, V> newAutoMap(Map<K, V> backingMap, final Class<? extends K> keyClass,
|
||||
final Class<? extends V> valueClass) {
|
||||
return new LoadingMap<K, V>(backingMap, new AutoInstantiatingLoader<K, V>(keyClass, valueClass));
|
||||
}
|
||||
/**
|
||||
* Creates a LoadingMap with an auto instantiating loader.
|
||||
*
|
||||
* Will auto construct class of of Value when not found
|
||||
*
|
||||
* Since this uses Reflection, It is more effecient to define your own static loader
|
||||
* than using this helper, but if performance is not critical, this is easier.
|
||||
*
|
||||
* @param backingMap Actual map being used.
|
||||
* @param valueClass Class used for the V generic
|
||||
* @param <K> Key Type of the Map
|
||||
* @param <V> Value Type of the Map
|
||||
* @return Map that auto instantiates on .get()
|
||||
*/
|
||||
public static <K, V> Map<K, V> newAutoMap(Map<K, V> backingMap,
|
||||
final Class<? extends V> valueClass) {
|
||||
return newAutoMap(backingMap, null, valueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #newAutoMap
|
||||
*
|
||||
* new Auto initializing map using a HashMap.
|
||||
* @param keyClass
|
||||
* @param valueClass
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newHashAutoMap(final Class<? extends K> keyClass, final Class<? extends V> valueClass) {
|
||||
return newAutoMap(new HashMap<K, V>(), keyClass, valueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #newAutoMap
|
||||
*
|
||||
* new Auto initializing map using a HashMap.
|
||||
* @param valueClass
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newHashAutoMap(final Class<? extends V> valueClass) {
|
||||
return newHashAutoMap(null, valueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #newAutoMap
|
||||
*
|
||||
* new Auto initializing map using a HashMap.
|
||||
*
|
||||
* @param keyClass
|
||||
* @param valueClass
|
||||
* @param initialCapacity
|
||||
* @param loadFactor
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newHashAutoMap(final Class<? extends K> keyClass, final Class<? extends V> valueClass, int initialCapacity, float loadFactor) {
|
||||
return newAutoMap(new HashMap<K, V>(initialCapacity, loadFactor), keyClass, valueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #newAutoMap
|
||||
*
|
||||
* new Auto initializing map using a HashMap.
|
||||
*
|
||||
* @param valueClass
|
||||
* @param initialCapacity
|
||||
* @param loadFactor
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newHashAutoMap(final Class<? extends V> valueClass, int initialCapacity, float loadFactor) {
|
||||
return newHashAutoMap(null, valueClass, initialCapacity, loadFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an auto loading map using a HashMap
|
||||
* @param loader
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newHashMap(Function<K, V> loader) {
|
||||
return new LoadingMap<K, V>(new HashMap<K, V>(), loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an auto loading map using a HashMap
|
||||
* @param loader
|
||||
* @param initialCapacity
|
||||
* @param loadFactor
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newHashMap(Function<K, V> loader, int initialCapacity, float loadFactor) {
|
||||
return new LoadingMap<K, V>(new HashMap<K, V>(initialCapacity, loadFactor), loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an auto loading map using an Identity HashMap
|
||||
* @param loader
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newIdentityHashMap(Function<K, V> loader) {
|
||||
return new LoadingMap<K, V>(new IdentityHashMap<K, V>(), loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an auto loading map using an Identity HashMap
|
||||
* @param loader
|
||||
* @param initialCapacity
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> newIdentityHashMap(Function<K, V> loader, int initialCapacity) {
|
||||
return new LoadingMap<K, V>(new IdentityHashMap<K, V>(initialCapacity), loader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {return backingMap.size();}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {return backingMap.isEmpty();}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {return backingMap.containsKey(key);}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {return backingMap.containsValue(value);}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
V res = backingMap.get(key);
|
||||
if (res == null && key != null) {
|
||||
res = loader.apply((K) key);
|
||||
if (res != null) {
|
||||
backingMap.put((K) key, res);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public V put(K key, V value) {return backingMap.put(key, value);}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {return backingMap.remove(key);}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends V> m) {backingMap.putAll(m);}
|
||||
|
||||
@Override
|
||||
public void clear() {backingMap.clear();}
|
||||
|
||||
@Override
|
||||
public Set<K> keySet() {return backingMap.keySet();}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {return backingMap.values();}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {return backingMap.equals(o);}
|
||||
|
||||
@Override
|
||||
public int hashCode() {return backingMap.hashCode();}
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return backingMap.entrySet();
|
||||
}
|
||||
|
||||
public LoadingMap<K, V> clone() {
|
||||
return new LoadingMap<K, V>(backingMap, loader);
|
||||
}
|
||||
|
||||
private static class AutoInstantiatingLoader<K, V> implements Function<K, V> {
|
||||
final Constructor<? extends V> constructor;
|
||||
private final Class<? extends V> valueClass;
|
||||
|
||||
AutoInstantiatingLoader(Class<? extends K> keyClass, Class<? extends V> valueClass) {
|
||||
try {
|
||||
this.valueClass = valueClass;
|
||||
if (keyClass != null) {
|
||||
constructor = valueClass.getConstructor(keyClass);
|
||||
} else {
|
||||
constructor = null;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalStateException(
|
||||
valueClass.getName() + " does not have a constructor for " + (keyClass != null ? keyClass.getName() : null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public V apply(K input) {
|
||||
try {
|
||||
return (constructor != null ? constructor.newInstance(input) : valueClass.newInstance());
|
||||
} catch (Exception e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Due to java stuff, you will need to cast it to (Function) for some cases
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract static class Feeder <T> implements Function<T, T> {
|
||||
@Override
|
||||
public T apply(Object input) {
|
||||
return apply();
|
||||
}
|
||||
|
||||
public abstract T apply();
|
||||
}
|
||||
}
|
100
TacoSpigot-API/src/main/java/co/aikar/util/MRUMapCache.java
Normal file
100
TacoSpigot-API/src/main/java/co/aikar/util/MRUMapCache.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package co.aikar.util;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Implements a Most Recently Used cache in front of a backing map, to quickly access the last accessed result.
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
*/
|
||||
public class MRUMapCache<K, V> extends AbstractMap<K, V> {
|
||||
final Map<K, V> backingMap;
|
||||
Object cacheKey;
|
||||
V cacheValue;
|
||||
public MRUMapCache(final Map<K, V> backingMap) {
|
||||
this.backingMap = backingMap;
|
||||
}
|
||||
|
||||
public int size() {return backingMap.size();}
|
||||
|
||||
public boolean isEmpty() {return backingMap.isEmpty();}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return key != null && key.equals(cacheKey) || backingMap.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return value != null && value == cacheValue || backingMap.containsValue(value);
|
||||
}
|
||||
|
||||
public V get(Object key) {
|
||||
if (cacheKey != null && cacheKey.equals(key)) {
|
||||
return cacheValue;
|
||||
}
|
||||
cacheKey = key;
|
||||
return cacheValue = backingMap.get(key);
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
cacheKey = key;
|
||||
return cacheValue = backingMap.put(key, value);
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
if (key != null && key.equals(cacheKey)) {
|
||||
cacheKey = null;
|
||||
}
|
||||
return backingMap.remove(key);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends V> m) {backingMap.putAll(m);}
|
||||
|
||||
public void clear() {
|
||||
cacheKey = null;
|
||||
cacheValue = null;
|
||||
backingMap.clear();
|
||||
}
|
||||
|
||||
public Set<K> keySet() {return backingMap.keySet();}
|
||||
|
||||
public Collection<V> values() {return backingMap.values();}
|
||||
|
||||
public Set<Map.Entry<K, V>> entrySet() {return backingMap.entrySet();}
|
||||
|
||||
/**
|
||||
* Wraps the specified map with a most recently used cache
|
||||
* @param map
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> of(Map<K, V> map) {
|
||||
return new MRUMapCache<K, V>(map);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package net.techcable.tacospigot.event.entity;
|
||||
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.entity.EntityEvent;
|
||||
|
||||
/**
|
||||
* Called when an arrow collides with an entity
|
||||
* <p>
|
||||
* This event is called <b>before</b> {@link org.bukkit.event.entity.EntityDamageByEntityEvent}, and cancelling it will allow the arrow to continue flying
|
||||
*/
|
||||
public class ArrowCollideEvent extends EntityEvent implements Cancellable {
|
||||
private final Entity collidedWith;
|
||||
|
||||
/**
|
||||
* Get the entity the arrow collided wit
|
||||
*
|
||||
* @return the entity
|
||||
*/
|
||||
public Entity getCollidedWith() {
|
||||
return collidedWith;
|
||||
}
|
||||
|
||||
public ArrowCollideEvent(Arrow what, Entity collidedWith) {
|
||||
super(what);
|
||||
this.collidedWith = collidedWith;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the arrow that collided
|
||||
*
|
||||
* @return the arrow that collided
|
||||
*/
|
||||
public Arrow getEntity() {
|
||||
return (Arrow) super.getEntity();
|
||||
}
|
||||
|
||||
private static final HandlerList handlerList = new HandlerList();
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
private boolean cancelled = false;
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package net.techcable.tacospigot.event.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
|
||||
/**
|
||||
* Fired before a mob spawns and entity data as calculated.
|
||||
* <p>This is a more preformat alternative to {@link org.bukkit.event.entity.SpawnerSpawnEvent}</p>
|
||||
*/
|
||||
public class SpawnerPreSpawnEvent extends Event implements Cancellable {
|
||||
|
||||
private final Location location;
|
||||
private final EntityType spawnedType;
|
||||
|
||||
public SpawnerPreSpawnEvent(Location location, EntityType spawnedType) {
|
||||
this.location = checkNotNull(location, "Null location").clone(); // Defensive copy
|
||||
this.spawnedType = checkNotNull(spawnedType, "Null spawned type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of the spawner where the entity is being spawned
|
||||
*
|
||||
* @return the spawner's location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location.clone(); // Defensive copy
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of entity being spawned
|
||||
*
|
||||
* @return the type being spawned
|
||||
*/
|
||||
public EntityType getSpawnedType() {
|
||||
return spawnedType;
|
||||
}
|
||||
|
||||
// Cancellable
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
// handlers
|
||||
|
||||
private static final HandlerList handlerList = new HandlerList();
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlerList;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlerList;
|
||||
}
|
||||
}
|
70
TacoSpigot-API/src/main/java/org/bukkit/Achievement.java
Normal file
70
TacoSpigot-API/src/main/java/org/bukkit/Achievement.java
Normal file
@ -0,0 +1,70 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* Represents an achievement, which may be given to players.
|
||||
*/
|
||||
public enum Achievement {
|
||||
OPEN_INVENTORY,
|
||||
MINE_WOOD (OPEN_INVENTORY),
|
||||
BUILD_WORKBENCH (MINE_WOOD),
|
||||
BUILD_PICKAXE (BUILD_WORKBENCH),
|
||||
BUILD_FURNACE (BUILD_PICKAXE),
|
||||
ACQUIRE_IRON (BUILD_FURNACE),
|
||||
BUILD_HOE (BUILD_WORKBENCH),
|
||||
MAKE_BREAD (BUILD_HOE),
|
||||
BAKE_CAKE (BUILD_HOE),
|
||||
BUILD_BETTER_PICKAXE (BUILD_PICKAXE),
|
||||
COOK_FISH (BUILD_FURNACE),
|
||||
ON_A_RAIL (ACQUIRE_IRON),
|
||||
BUILD_SWORD (BUILD_WORKBENCH),
|
||||
KILL_ENEMY (BUILD_SWORD),
|
||||
KILL_COW (BUILD_SWORD),
|
||||
FLY_PIG (KILL_COW),
|
||||
SNIPE_SKELETON (KILL_ENEMY),
|
||||
GET_DIAMONDS (ACQUIRE_IRON),
|
||||
NETHER_PORTAL (GET_DIAMONDS),
|
||||
GHAST_RETURN (NETHER_PORTAL),
|
||||
GET_BLAZE_ROD (NETHER_PORTAL),
|
||||
BREW_POTION (GET_BLAZE_ROD),
|
||||
END_PORTAL (GET_BLAZE_ROD),
|
||||
THE_END (END_PORTAL),
|
||||
ENCHANTMENTS (GET_DIAMONDS),
|
||||
OVERKILL (ENCHANTMENTS),
|
||||
BOOKCASE (ENCHANTMENTS),
|
||||
EXPLORE_ALL_BIOMES (END_PORTAL),
|
||||
SPAWN_WITHER (THE_END),
|
||||
KILL_WITHER (SPAWN_WITHER),
|
||||
FULL_BEACON (KILL_WITHER),
|
||||
BREED_COW (KILL_COW),
|
||||
DIAMONDS_TO_YOU (GET_DIAMONDS),
|
||||
OVERPOWERED (BUILD_BETTER_PICKAXE)
|
||||
;
|
||||
|
||||
private final Achievement parent;
|
||||
|
||||
private Achievement() {
|
||||
parent = null;
|
||||
}
|
||||
|
||||
private Achievement(Achievement parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this achievement has a parent achievement.
|
||||
*
|
||||
* @return whether the achievement has a parent achievement
|
||||
*/
|
||||
public boolean hasParent() {
|
||||
return parent != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent achievement of this achievement, or null if none.
|
||||
*
|
||||
* @return the parent achievement or null
|
||||
*/
|
||||
public Achievement getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
111
TacoSpigot-API/src/main/java/org/bukkit/Art.java
Normal file
111
TacoSpigot-API/src/main/java/org/bukkit/Art.java
Normal file
@ -0,0 +1,111 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the art on a painting
|
||||
*/
|
||||
public enum Art {
|
||||
KEBAB(0, 1, 1),
|
||||
AZTEC(1, 1, 1),
|
||||
ALBAN(2, 1, 1),
|
||||
AZTEC2(3, 1, 1),
|
||||
BOMB(4, 1, 1),
|
||||
PLANT(5, 1, 1),
|
||||
WASTELAND(6, 1, 1),
|
||||
POOL(7, 2, 1),
|
||||
COURBET(8, 2, 1),
|
||||
SEA(9, 2, 1),
|
||||
SUNSET(10, 2, 1),
|
||||
CREEBET(11, 2, 1),
|
||||
WANDERER(12, 1, 2),
|
||||
GRAHAM(13, 1, 2),
|
||||
MATCH(14, 2, 2),
|
||||
BUST(15, 2, 2),
|
||||
STAGE(16, 2, 2),
|
||||
VOID(17, 2, 2),
|
||||
SKULL_AND_ROSES(18, 2, 2),
|
||||
WITHER(19, 2, 2),
|
||||
FIGHTERS(20, 4, 2),
|
||||
POINTER(21, 4, 4),
|
||||
PIGSCENE(22, 4, 4),
|
||||
BURNINGSKULL(23, 4, 4),
|
||||
SKELETON(24, 4, 3),
|
||||
DONKEYKONG(25, 4, 3);
|
||||
|
||||
private int id, width, height;
|
||||
private static final HashMap<String, Art> BY_NAME = Maps.newHashMap();
|
||||
private static final HashMap<Integer, Art> BY_ID = Maps.newHashMap();
|
||||
|
||||
private Art(int id, int width, int height) {
|
||||
this.id = id;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the painting, in blocks
|
||||
*
|
||||
* @return The width of the painting, in blocks
|
||||
*/
|
||||
public int getBlockWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the painting, in blocks
|
||||
*
|
||||
* @return The height of the painting, in blocks
|
||||
*/
|
||||
public int getBlockHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of this painting.
|
||||
*
|
||||
* @return The ID of this painting
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a painting by its numeric ID
|
||||
*
|
||||
* @param id The ID
|
||||
* @return The painting
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static Art getById(int id) {
|
||||
return BY_ID.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a painting by its unique name
|
||||
* <p>
|
||||
* This ignores underscores and capitalization
|
||||
*
|
||||
* @param name The name
|
||||
* @return The painting
|
||||
*/
|
||||
public static Art getByName(String name) {
|
||||
Validate.notNull(name, "Name cannot be null");
|
||||
|
||||
return BY_NAME.get(name.toLowerCase().replaceAll("_", ""));
|
||||
}
|
||||
|
||||
static {
|
||||
for (Art art : values()) {
|
||||
BY_ID.put(art.id, art);
|
||||
BY_NAME.put(art.toString().toLowerCase().replaceAll("_", ""), art);
|
||||
}
|
||||
}
|
||||
}
|
128
TacoSpigot-API/src/main/java/org/bukkit/BanEntry.java
Normal file
128
TacoSpigot-API/src/main/java/org/bukkit/BanEntry.java
Normal file
@ -0,0 +1,128 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A single entry from a ban list. This may represent either a player ban or
|
||||
* an IP ban.
|
||||
* <p>
|
||||
* Ban entries include the following properties:
|
||||
* <table border=1>
|
||||
* <caption>Property information</caption>
|
||||
* <tr>
|
||||
* <th>Property</th>
|
||||
* <th>Description</th>
|
||||
* </tr><tr>
|
||||
* <td>Target Name / IP Address</td>
|
||||
* <td>The target name or IP address</td>
|
||||
* </tr><tr>
|
||||
* <td>Creation Date</td>
|
||||
* <td>The creation date of the ban</td>
|
||||
* </tr><tr>
|
||||
* <td>Source</td>
|
||||
* <td>The source of the ban, such as a player, console, plugin, etc</td>
|
||||
* </tr><tr>
|
||||
* <td>Expiration Date</td>
|
||||
* <td>The expiration date of the ban</td>
|
||||
* </tr><tr>
|
||||
* <td>Reason</td>
|
||||
* <td>The reason for the ban</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* <p>
|
||||
* Unsaved information is not automatically written to the implementation's
|
||||
* ban list, instead, the {@link #save()} method must be called to write the
|
||||
* changes to the ban list. If this ban entry has expired (such as from an
|
||||
* unban) and is no longer found in the list, the {@link #save()} call will
|
||||
* re-add it to the list, therefore banning the victim specified.
|
||||
* <p>
|
||||
* Likewise, changes to the associated {@link BanList} or other entries may or
|
||||
* may not be reflected in this entry.
|
||||
*/
|
||||
public interface BanEntry {
|
||||
|
||||
/**
|
||||
* Gets the target involved. This may be in the form of an IP or a player
|
||||
* name.
|
||||
*
|
||||
* @return the target name or IP address
|
||||
*/
|
||||
public String getTarget();
|
||||
|
||||
/**
|
||||
* Gets the date this ban entry was created.
|
||||
*
|
||||
* @return the creation date
|
||||
*/
|
||||
public Date getCreated();
|
||||
|
||||
/**
|
||||
* Sets the date this ban entry was created.
|
||||
*
|
||||
* @param created the new created date, cannot be null
|
||||
* @see #save() saving changes
|
||||
*/
|
||||
public void setCreated(Date created);
|
||||
|
||||
/**
|
||||
* Gets the source of this ban.
|
||||
* <p>
|
||||
* Note: A source is considered any String, although this is generally a
|
||||
* player name.
|
||||
*
|
||||
* @return the source of the ban
|
||||
*/
|
||||
public String getSource();
|
||||
|
||||
/**
|
||||
* Sets the source of this ban.
|
||||
* <p>
|
||||
* Note: A source is considered any String, although this is generally a
|
||||
* player name.
|
||||
*
|
||||
* @param source the new source where null values become empty strings
|
||||
* @see #save() saving changes
|
||||
*/
|
||||
public void setSource(String source);
|
||||
|
||||
/**
|
||||
* Gets the date this ban expires on, or null for no defined end date.
|
||||
*
|
||||
* @return the expiration date
|
||||
*/
|
||||
public Date getExpiration();
|
||||
|
||||
/**
|
||||
* Sets the date this ban expires on. Null values are considered
|
||||
* "infinite" bans.
|
||||
*
|
||||
* @param expiration the new expiration date, or null to indicate an
|
||||
* eternity
|
||||
* @see #save() saving changes
|
||||
*/
|
||||
public void setExpiration(Date expiration);
|
||||
|
||||
/**
|
||||
* Gets the reason for this ban.
|
||||
*
|
||||
* @return the ban reason, or null if not set
|
||||
*/
|
||||
public String getReason();
|
||||
|
||||
/**
|
||||
* Sets the reason for this ban. Reasons must not be null.
|
||||
*
|
||||
* @param reason the new reason, null values assume the implementation
|
||||
* default
|
||||
* @see #save() saving changes
|
||||
*/
|
||||
public void setReason(String reason);
|
||||
|
||||
/**
|
||||
* Saves the ban entry, overwriting any previous data in the ban list.
|
||||
* <p>
|
||||
* Saving the ban entry of an unbanned player will cause the player to be
|
||||
* banned once again.
|
||||
*/
|
||||
public void save();
|
||||
}
|
72
TacoSpigot-API/src/main/java/org/bukkit/BanList.java
Normal file
72
TacoSpigot-API/src/main/java/org/bukkit/BanList.java
Normal file
@ -0,0 +1,72 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A ban list, containing bans of some {@link Type}.
|
||||
*/
|
||||
public interface BanList {
|
||||
|
||||
/**
|
||||
* Represents a ban-type that a {@link BanList} may track.
|
||||
*/
|
||||
public enum Type {
|
||||
/**
|
||||
* Banned player names
|
||||
*/
|
||||
NAME,
|
||||
/**
|
||||
* Banned player IP addresses
|
||||
*/
|
||||
IP,
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link BanEntry} by target.
|
||||
*
|
||||
* @param target entry parameter to search for
|
||||
* @return the corresponding entry, or null if none found
|
||||
*/
|
||||
public BanEntry getBanEntry(String target);
|
||||
|
||||
/**
|
||||
* Adds a ban to the this list. If a previous ban exists, this will
|
||||
* update the previous entry.
|
||||
*
|
||||
* @param target the target of the ban
|
||||
* @param reason reason for the ban, null indicates implementation default
|
||||
* @param expires date for the ban's expiration (unban), or null to imply
|
||||
* forever
|
||||
* @param source source of the ban, null indicates implementation default
|
||||
* @return the entry for the newly created ban, or the entry for the
|
||||
* (updated) previous ban
|
||||
*/
|
||||
public BanEntry addBan(String target, String reason, Date expires, String source);
|
||||
|
||||
/**
|
||||
* Gets a set containing every {@link BanEntry} in this list.
|
||||
*
|
||||
* @return an immutable set containing every entry tracked by this list
|
||||
*/
|
||||
public Set<BanEntry> getBanEntries();
|
||||
|
||||
/**
|
||||
* Gets if a {@link BanEntry} exists for the target, indicating an active
|
||||
* ban status.
|
||||
*
|
||||
* @param target the target to find
|
||||
* @return true if a {@link BanEntry} exists for the name, indicating an
|
||||
* active ban status, false otherwise
|
||||
*/
|
||||
public boolean isBanned(String target);
|
||||
|
||||
/**
|
||||
* Removes the specified target from this list, therefore indicating a
|
||||
* "not banned" status.
|
||||
*
|
||||
* @param target the target to remove from this list
|
||||
*/
|
||||
public void pardon(String target);
|
||||
}
|
104
TacoSpigot-API/src/main/java/org/bukkit/BlockChangeDelegate.java
Normal file
104
TacoSpigot-API/src/main/java/org/bukkit/BlockChangeDelegate.java
Normal file
@ -0,0 +1,104 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* A delegate for handling block changes. This serves as a direct interface
|
||||
* between generation algorithms in the server implementation and utilizing
|
||||
* code.
|
||||
*/
|
||||
public interface BlockChangeDelegate {
|
||||
|
||||
/**
|
||||
* Set a block type at the specified coordinates without doing all world
|
||||
* updates and notifications.
|
||||
* <p>
|
||||
* It is safe to have this call World.setTypeId, but it may be slower than
|
||||
* World.setRawTypeId.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @param typeId New block ID
|
||||
* @return true if the block was set successfully
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setRawTypeId(int x, int y, int z, int typeId);
|
||||
|
||||
/**
|
||||
* Set a block type and data at the specified coordinates without doing
|
||||
* all world updates and notifications.
|
||||
* <p>
|
||||
* It is safe to have this call World.setTypeId, but it may be slower than
|
||||
* World.setRawTypeId.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @param typeId New block ID
|
||||
* @param data Block data
|
||||
* @return true if the block was set successfully
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data);
|
||||
|
||||
/**
|
||||
* Set a block type at the specified coordinates.
|
||||
* <p>
|
||||
* This method cannot call World.setRawTypeId, a full update is needed.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @param typeId New block ID
|
||||
* @return true if the block was set successfully
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setTypeId(int x, int y, int z, int typeId);
|
||||
|
||||
/**
|
||||
* Set a block type and data at the specified coordinates.
|
||||
* <p>
|
||||
* This method cannot call World.setRawTypeId, a full update is needed.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @param typeId New block ID
|
||||
* @param data Block data
|
||||
* @return true if the block was set successfully
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data);
|
||||
|
||||
/**
|
||||
* Get the block type at the location.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return The block ID
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTypeId(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Gets the height of the world.
|
||||
*
|
||||
* @return Height of the world
|
||||
*/
|
||||
public int getHeight();
|
||||
|
||||
/**
|
||||
* Checks if the specified block is empty (air) or not.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return True if the block is considered empty.
|
||||
*/
|
||||
public boolean isEmpty(int x, int y, int z);
|
||||
}
|
1169
TacoSpigot-API/src/main/java/org/bukkit/Bukkit.java
Normal file
1169
TacoSpigot-API/src/main/java/org/bukkit/Bukkit.java
Normal file
File diff suppressed because it is too large
Load Diff
371
TacoSpigot-API/src/main/java/org/bukkit/ChatColor.java
Normal file
371
TacoSpigot-API/src/main/java/org/bukkit/ChatColor.java
Normal file
@ -0,0 +1,371 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* All supported color values for chat
|
||||
*/
|
||||
public enum ChatColor{
|
||||
/**
|
||||
* Represents black
|
||||
*/
|
||||
BLACK('0', 0x00) {
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.BLACK;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents dark blue
|
||||
*/
|
||||
DARK_BLUE('1', 0x1){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.DARK_BLUE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents dark green
|
||||
*/
|
||||
DARK_GREEN('2', 0x2){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.DARK_GREEN;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents dark blue (aqua)
|
||||
*/
|
||||
DARK_AQUA('3', 0x3){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.DARK_AQUA;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents dark red
|
||||
*/
|
||||
DARK_RED('4', 0x4){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.DARK_RED;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents dark purple
|
||||
*/
|
||||
DARK_PURPLE('5', 0x5){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.DARK_PURPLE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents gold
|
||||
*/
|
||||
GOLD('6', 0x6){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.GOLD;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents gray
|
||||
*/
|
||||
GRAY('7', 0x7){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.GRAY;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents dark gray
|
||||
*/
|
||||
DARK_GRAY('8', 0x8){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.DARK_GRAY;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents blue
|
||||
*/
|
||||
BLUE('9', 0x9){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.BLUE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents green
|
||||
*/
|
||||
GREEN('a', 0xA){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.GREEN;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents aqua
|
||||
*/
|
||||
AQUA('b', 0xB){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.AQUA;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents red
|
||||
*/
|
||||
RED('c', 0xC){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.RED;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents light purple
|
||||
*/
|
||||
LIGHT_PURPLE('d', 0xD){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.LIGHT_PURPLE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents yellow
|
||||
*/
|
||||
YELLOW('e', 0xE){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.YELLOW;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents white
|
||||
*/
|
||||
WHITE('f', 0xF){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.WHITE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Represents magical characters that change around randomly
|
||||
*/
|
||||
MAGIC('k', 0x10, true){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.MAGIC;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes the text bold.
|
||||
*/
|
||||
BOLD('l', 0x11, true){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.BOLD;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes a line appear through the text.
|
||||
*/
|
||||
STRIKETHROUGH('m', 0x12, true){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.STRIKETHROUGH;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes the text appear underlined.
|
||||
*/
|
||||
UNDERLINE('n', 0x13, true){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.UNDERLINE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes the text italic.
|
||||
*/
|
||||
ITALIC('o', 0x14, true){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.ITALIC;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Resets all previous chat colors or formats.
|
||||
*/
|
||||
RESET('r', 0x15){
|
||||
@Override
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.RESET;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The special character which prefixes all chat colour codes. Use this if
|
||||
* you need to dynamically convert colour codes from your custom format.
|
||||
*/
|
||||
public static final char COLOR_CHAR = '\u00A7';
|
||||
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]");
|
||||
|
||||
private final int intCode;
|
||||
private final char code;
|
||||
private final boolean isFormat;
|
||||
private final String toString;
|
||||
private final static Map<Integer, ChatColor> BY_ID = Maps.newHashMap();
|
||||
private final static Map<Character, ChatColor> BY_CHAR = Maps.newHashMap();
|
||||
|
||||
private ChatColor(char code, int intCode) {
|
||||
this(code, intCode, false);
|
||||
}
|
||||
|
||||
private ChatColor(char code, int intCode, boolean isFormat) {
|
||||
this.code = code;
|
||||
this.intCode = intCode;
|
||||
this.isFormat = isFormat;
|
||||
this.toString = new String(new char[] {COLOR_CHAR, code});
|
||||
}
|
||||
|
||||
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||
return net.md_5.bungee.api.ChatColor.RESET;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the char value associated with this color
|
||||
*
|
||||
* @return A char value of this color code
|
||||
*/
|
||||
public char getChar() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this code is a format code as opposed to a color code.
|
||||
*
|
||||
* @return whether this ChatColor is a format code
|
||||
*/
|
||||
public boolean isFormat() {
|
||||
return isFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this code is a color code as opposed to a format code.
|
||||
*
|
||||
* @return whether this ChatColor is a color code
|
||||
*/
|
||||
public boolean isColor() {
|
||||
return !isFormat && this != RESET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color represented by the specified color code
|
||||
*
|
||||
* @param code Code to check
|
||||
* @return Associative {@link org.bukkit.ChatColor} with the given code,
|
||||
* or null if it doesn't exist
|
||||
*/
|
||||
public static ChatColor getByChar(char code) {
|
||||
return BY_CHAR.get(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color represented by the specified color code
|
||||
*
|
||||
* @param code Code to check
|
||||
* @return Associative {@link org.bukkit.ChatColor} with the given code,
|
||||
* or null if it doesn't exist
|
||||
*/
|
||||
public static ChatColor getByChar(String code) {
|
||||
Validate.notNull(code, "Code cannot be null");
|
||||
Validate.isTrue(code.length() > 0, "Code must have at least one char");
|
||||
|
||||
return BY_CHAR.get(code.charAt(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the given message of all color codes
|
||||
*
|
||||
* @param input String to strip of color
|
||||
* @return A copy of the input string, without any coloring
|
||||
*/
|
||||
public static String stripColor(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return STRIP_COLOR_PATTERN.matcher(input).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a string using an alternate color code character into a
|
||||
* string that uses the internal ChatColor.COLOR_CODE color code
|
||||
* character. The alternate color code character will only be replaced if
|
||||
* it is immediately followed by 0-9, A-F, a-f, K-O, k-o, R or r.
|
||||
*
|
||||
* @param altColorChar The alternate color code character to replace. Ex: {@literal &}
|
||||
* @param textToTranslate Text containing the alternate color code character.
|
||||
* @return Text containing the ChatColor.COLOR_CODE color code character.
|
||||
*/
|
||||
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) {
|
||||
char[] b = textToTranslate.toCharArray();
|
||||
for (int i = 0; i < b.length - 1; i++) {
|
||||
if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i+1]) > -1) {
|
||||
b[i] = ChatColor.COLOR_CHAR;
|
||||
b[i+1] = Character.toLowerCase(b[i+1]);
|
||||
}
|
||||
}
|
||||
return new String(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ChatColors used at the end of the given input string.
|
||||
*
|
||||
* @param input Input string to retrieve the colors from.
|
||||
* @return Any remaining ChatColors to pass onto the next line.
|
||||
*/
|
||||
public static String getLastColors(String input) {
|
||||
String result = "";
|
||||
int length = input.length();
|
||||
|
||||
// Search backwards from the end as it is faster
|
||||
for (int index = length - 1; index > -1; index--) {
|
||||
char section = input.charAt(index);
|
||||
if (section == COLOR_CHAR && index < length - 1) {
|
||||
char c = input.charAt(index + 1);
|
||||
ChatColor color = getByChar(c);
|
||||
|
||||
if (color != null) {
|
||||
result = color.toString() + result;
|
||||
|
||||
// Once we find a color or reset we can stop searching
|
||||
if (color.isColor() || color.equals(RESET)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
for (ChatColor color : values()) {
|
||||
BY_ID.put(color.intCode, color);
|
||||
BY_CHAR.put(color.code, color);
|
||||
}
|
||||
}
|
||||
}
|
124
TacoSpigot-API/src/main/java/org/bukkit/Chunk.java
Normal file
124
TacoSpigot-API/src/main/java/org/bukkit/Chunk.java
Normal file
@ -0,0 +1,124 @@
|
||||
package org.bukkit;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
/**
|
||||
* Represents a chunk of blocks
|
||||
*/
|
||||
public interface Chunk {
|
||||
|
||||
/**
|
||||
* Gets the X-coordinate of this chunk
|
||||
*
|
||||
* @return X-coordinate
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Gets the Z-coordinate of this chunk
|
||||
*
|
||||
* @return Z-coordinate
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* Gets the world containing this chunk
|
||||
*
|
||||
* @return Parent World
|
||||
*/
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Gets a block from this chunk
|
||||
*
|
||||
* @param x 0-15
|
||||
* @param y 0-127
|
||||
* @param z 0-15
|
||||
* @return the Block
|
||||
*/
|
||||
Block getBlock(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Capture thread-safe read-only snapshot of chunk data
|
||||
*
|
||||
* @return ChunkSnapshot
|
||||
*/
|
||||
ChunkSnapshot getChunkSnapshot();
|
||||
|
||||
/**
|
||||
* Capture thread-safe read-only snapshot of chunk data
|
||||
*
|
||||
* @param includeMaxblocky - if true, snapshot includes per-coordinate
|
||||
* maximum Y values
|
||||
* @param includeBiome - if true, snapshot includes per-coordinate biome
|
||||
* type
|
||||
* @param includeBiomeTempRain - if true, snapshot includes per-coordinate
|
||||
* raw biome temperature and rainfall
|
||||
* @return ChunkSnapshot
|
||||
*/
|
||||
ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain);
|
||||
|
||||
/**
|
||||
* Get a list of all entities in the chunk.
|
||||
*
|
||||
* @return The entities.
|
||||
*/
|
||||
Entity[] getEntities();
|
||||
|
||||
/**
|
||||
* Get a list of all tile entities in the chunk.
|
||||
*
|
||||
* @return The tile entities.
|
||||
*/
|
||||
BlockState[] getTileEntities();
|
||||
|
||||
/**
|
||||
* Checks if the chunk is loaded.
|
||||
*
|
||||
* @return True if it is loaded.
|
||||
*/
|
||||
boolean isLoaded();
|
||||
|
||||
/**
|
||||
* Loads the chunk.
|
||||
*
|
||||
* @param generate Whether or not to generate a chunk if it doesn't
|
||||
* already exist
|
||||
* @return true if the chunk has loaded successfully, otherwise false
|
||||
*/
|
||||
boolean load(boolean generate);
|
||||
|
||||
/**
|
||||
* Loads the chunk.
|
||||
*
|
||||
* @return true if the chunk has loaded successfully, otherwise false
|
||||
*/
|
||||
boolean load();
|
||||
|
||||
/**
|
||||
* Unloads and optionally saves the Chunk
|
||||
*
|
||||
* @param save Controls whether the chunk is saved
|
||||
* @param safe Controls whether to unload the chunk when players are
|
||||
* nearby
|
||||
* @return true if the chunk has unloaded successfully, otherwise false
|
||||
*/
|
||||
boolean unload(boolean save, boolean safe);
|
||||
|
||||
/**
|
||||
* Unloads and optionally saves the Chunk
|
||||
*
|
||||
* @param save Controls whether the chunk is saved
|
||||
* @return true if the chunk has unloaded successfully, otherwise false
|
||||
*/
|
||||
boolean unload(boolean save);
|
||||
|
||||
/**
|
||||
* Unloads and optionally saves the Chunk
|
||||
*
|
||||
* @return true if the chunk has unloaded successfully, otherwise false
|
||||
*/
|
||||
boolean unload();
|
||||
}
|
129
TacoSpigot-API/src/main/java/org/bukkit/ChunkSnapshot.java
Normal file
129
TacoSpigot-API/src/main/java/org/bukkit/ChunkSnapshot.java
Normal file
@ -0,0 +1,129 @@
|
||||
package org.bukkit;
|
||||
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
/**
|
||||
* Represents a static, thread-safe snapshot of chunk of blocks.
|
||||
* <p>
|
||||
* 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 interface ChunkSnapshot {
|
||||
|
||||
/**
|
||||
* Gets the X-coordinate of this chunk
|
||||
*
|
||||
* @return X-coordinate
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Gets the Z-coordinate of this chunk
|
||||
*
|
||||
* @return Z-coordinate
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* Gets name of the world containing this chunk
|
||||
*
|
||||
* @return Parent World Name
|
||||
*/
|
||||
String getWorldName();
|
||||
|
||||
/**
|
||||
* Get block type for block at corresponding coordinate in the chunk
|
||||
*
|
||||
* @param x 0-15
|
||||
* @param y 0-127
|
||||
* @param z 0-15
|
||||
* @return 0-255
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
int getBlockTypeId(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Get block data for block at corresponding coordinate in the chunk
|
||||
*
|
||||
* @param x 0-15
|
||||
* @param y 0-127
|
||||
* @param z 0-15
|
||||
* @return 0-15
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
int getBlockData(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Get sky light level for block at corresponding coordinate in the chunk
|
||||
*
|
||||
* @param x 0-15
|
||||
* @param y 0-127
|
||||
* @param z 0-15
|
||||
* @return 0-15
|
||||
*/
|
||||
int getBlockSkyLight(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Get light level emitted by block at corresponding coordinate in the
|
||||
* chunk
|
||||
*
|
||||
* @param x 0-15
|
||||
* @param y 0-127
|
||||
* @param z 0-15
|
||||
* @return 0-15
|
||||
*/
|
||||
int getBlockEmittedLight(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Gets the highest non-air coordinate at the given coordinates
|
||||
*
|
||||
* @param x X-coordinate of the blocks
|
||||
* @param z Z-coordinate of the blocks
|
||||
* @return Y-coordinate of the highest non-air block
|
||||
*/
|
||||
int getHighestBlockYAt(int x, int z);
|
||||
|
||||
/**
|
||||
* Get biome at given coordinates
|
||||
*
|
||||
* @param x X-coordinate
|
||||
* @param z Z-coordinate
|
||||
* @return Biome at given coordinate
|
||||
*/
|
||||
Biome getBiome(int x, int z);
|
||||
|
||||
/**
|
||||
* Get raw biome temperature (0.0-1.0) at given coordinate
|
||||
*
|
||||
* @param x X-coordinate
|
||||
* @param z Z-coordinate
|
||||
* @return temperature at given coordinate
|
||||
*/
|
||||
double getRawBiomeTemperature(int x, int z);
|
||||
|
||||
/**
|
||||
* Get raw biome rainfall (0.0-1.0) at given coordinate
|
||||
*
|
||||
* @param x X-coordinate
|
||||
* @param z Z-coordinate
|
||||
* @return rainfall at given coordinate
|
||||
*/
|
||||
double getRawBiomeRainfall(int x, int z);
|
||||
|
||||
/**
|
||||
* Get world full time when chunk snapshot was captured
|
||||
*
|
||||
* @return time in ticks
|
||||
*/
|
||||
long getCaptureFullTime();
|
||||
|
||||
/**
|
||||
* Test if section is empty
|
||||
*
|
||||
* @param sy - section Y coordinate (block Y / 16)
|
||||
* @return true if empty, false if not
|
||||
*/
|
||||
boolean isSectionEmpty(int sy);
|
||||
}
|
50
TacoSpigot-API/src/main/java/org/bukkit/CoalType.java
Normal file
50
TacoSpigot-API/src/main/java/org/bukkit/CoalType.java
Normal file
@ -0,0 +1,50 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the two types of coal
|
||||
*/
|
||||
public enum CoalType {
|
||||
COAL(0x0),
|
||||
CHARCOAL(0x1);
|
||||
|
||||
private final byte data;
|
||||
private final static Map<Byte, CoalType> BY_DATA = Maps.newHashMap();
|
||||
|
||||
private CoalType(final int data) {
|
||||
this.data = (byte) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated data value representing this type of coal
|
||||
*
|
||||
* @return A byte containing the data value of this coal type
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of coal with the given data value
|
||||
*
|
||||
* @param data Data value to fetch
|
||||
* @return The {@link CoalType} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static CoalType getByData(final byte data) {
|
||||
return BY_DATA.get(data);
|
||||
}
|
||||
|
||||
static {
|
||||
for (CoalType type : values()) {
|
||||
BY_DATA.put(type.data, type);
|
||||
}
|
||||
}
|
||||
}
|
344
TacoSpigot-API/src/main/java/org/bukkit/Color.java
Normal file
344
TacoSpigot-API/src/main/java/org/bukkit/Color.java
Normal file
@ -0,0 +1,344 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.SerializableAs;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* A container for a color palette. This class is immutable; the set methods
|
||||
* return a new color. The color names listed as fields are HTML4 standards,
|
||||
* but subject to change.
|
||||
*/
|
||||
@SerializableAs("Color")
|
||||
public final class Color implements ConfigurationSerializable {
|
||||
private static final int BIT_MASK = 0xff;
|
||||
|
||||
/**
|
||||
* White, or (0xFF,0xFF,0xFF) in (R,G,B)
|
||||
*/
|
||||
public static final Color WHITE = fromRGB(0xFFFFFF);
|
||||
|
||||
/**
|
||||
* Silver, or (0xC0,0xC0,0xC0) in (R,G,B)
|
||||
*/
|
||||
public static final Color SILVER = fromRGB(0xC0C0C0);
|
||||
|
||||
/**
|
||||
* Gray, or (0x80,0x80,0x80) in (R,G,B)
|
||||
*/
|
||||
public static final Color GRAY = fromRGB(0x808080);
|
||||
|
||||
/**
|
||||
* Black, or (0x00,0x00,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color BLACK = fromRGB(0x000000);
|
||||
|
||||
/**
|
||||
* Red, or (0xFF,0x00,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color RED = fromRGB(0xFF0000);
|
||||
|
||||
/**
|
||||
* Maroon, or (0x80,0x00,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color MAROON = fromRGB(0x800000);
|
||||
|
||||
/**
|
||||
* Yellow, or (0xFF,0xFF,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color YELLOW = fromRGB(0xFFFF00);
|
||||
|
||||
/**
|
||||
* Olive, or (0x80,0x80,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color OLIVE = fromRGB(0x808000);
|
||||
|
||||
/**
|
||||
* Lime, or (0x00,0xFF,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color LIME = fromRGB(0x00FF00);
|
||||
|
||||
/**
|
||||
* Green, or (0x00,0x80,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color GREEN = fromRGB(0x008000);
|
||||
|
||||
/**
|
||||
* Aqua, or (0x00,0xFF,0xFF) in (R,G,B)
|
||||
*/
|
||||
public static final Color AQUA = fromRGB(0x00FFFF);
|
||||
|
||||
/**
|
||||
* Teal, or (0x00,0x80,0x80) in (R,G,B)
|
||||
*/
|
||||
public static final Color TEAL = fromRGB(0x008080);
|
||||
|
||||
/**
|
||||
* Blue, or (0x00,0x00,0xFF) in (R,G,B)
|
||||
*/
|
||||
public static final Color BLUE = fromRGB(0x0000FF);
|
||||
|
||||
/**
|
||||
* Navy, or (0x00,0x00,0x80) in (R,G,B)
|
||||
*/
|
||||
public static final Color NAVY = fromRGB(0x000080);
|
||||
|
||||
/**
|
||||
* Fuchsia, or (0xFF,0x00,0xFF) in (R,G,B)
|
||||
*/
|
||||
public static final Color FUCHSIA = fromRGB(0xFF00FF);
|
||||
|
||||
/**
|
||||
* Purple, or (0x80,0x00,0x80) in (R,G,B)
|
||||
*/
|
||||
public static final Color PURPLE = fromRGB(0x800080);
|
||||
|
||||
/**
|
||||
* Orange, or (0xFF,0xA5,0x00) in (R,G,B)
|
||||
*/
|
||||
public static final Color ORANGE = fromRGB(0xFFA500);
|
||||
|
||||
private final byte red;
|
||||
private final byte green;
|
||||
private final byte blue;
|
||||
|
||||
/**
|
||||
* Creates a new Color object from a red, green, and blue
|
||||
*
|
||||
* @param red integer from 0-255
|
||||
* @param green integer from 0-255
|
||||
* @param blue integer from 0-255
|
||||
* @return a new Color object for the red, green, blue
|
||||
* @throws IllegalArgumentException if any value is strictly {@literal >255 or <0}
|
||||
*/
|
||||
public static Color fromRGB(int red, int green, int blue) throws IllegalArgumentException {
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Color object from a blue, green, and red
|
||||
*
|
||||
* @param blue integer from 0-255
|
||||
* @param green integer from 0-255
|
||||
* @param red integer from 0-255
|
||||
* @return a new Color object for the red, green, blue
|
||||
* @throws IllegalArgumentException if any value is strictly {@literal >255 or <0}
|
||||
*/
|
||||
public static Color fromBGR(int blue, int green, int red) throws IllegalArgumentException {
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new color object from an integer that contains the red,
|
||||
* green, and blue bytes in the lowest order 24 bits.
|
||||
*
|
||||
* @param rgb the integer storing the red, green, and blue values
|
||||
* @return a new color object for specified values
|
||||
* @throws IllegalArgumentException if any data is in the highest order 8
|
||||
* bits
|
||||
*/
|
||||
public static Color fromRGB(int rgb) throws IllegalArgumentException {
|
||||
Validate.isTrue((rgb >> 24) == 0, "Extrenuous data in: ", rgb);
|
||||
return fromRGB(rgb >> 16 & BIT_MASK, rgb >> 8 & BIT_MASK, rgb >> 0 & BIT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new color object from an integer that contains the blue,
|
||||
* green, and red bytes in the lowest order 24 bits.
|
||||
*
|
||||
* @param bgr the integer storing the blue, green, and red values
|
||||
* @return a new color object for specified values
|
||||
* @throws IllegalArgumentException if any data is in the highest order 8
|
||||
* bits
|
||||
*/
|
||||
public static Color fromBGR(int bgr) throws IllegalArgumentException {
|
||||
Validate.isTrue((bgr >> 24) == 0, "Extrenuous data in: ", bgr);
|
||||
return fromBGR(bgr >> 16 & BIT_MASK, bgr >> 8 & BIT_MASK, bgr >> 0 & BIT_MASK);
|
||||
}
|
||||
|
||||
private Color(int red, int green, int blue) {
|
||||
Validate.isTrue(red >= 0 && red <= BIT_MASK, "Red is not between 0-255: ", red);
|
||||
Validate.isTrue(green >= 0 && green <= BIT_MASK, "Green is not between 0-255: ", green);
|
||||
Validate.isTrue(blue >= 0 && blue <= BIT_MASK, "Blue is not between 0-255: ", blue);
|
||||
|
||||
this.red = (byte) red;
|
||||
this.green = (byte) green;
|
||||
this.blue = (byte) blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the red component
|
||||
*
|
||||
* @return red component, from 0 to 255
|
||||
*/
|
||||
public int getRed() {
|
||||
return BIT_MASK & red;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Color object with specified component
|
||||
*
|
||||
* @param red the red component, from 0 to 255
|
||||
* @return a new color object with the red component
|
||||
*/
|
||||
public Color setRed(int red) {
|
||||
return fromRGB(red, getGreen(), getBlue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the green component
|
||||
*
|
||||
* @return green component, from 0 to 255
|
||||
*/
|
||||
public int getGreen() {
|
||||
return BIT_MASK & green;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Color object with specified component
|
||||
*
|
||||
* @param green the red component, from 0 to 255
|
||||
* @return a new color object with the red component
|
||||
*/
|
||||
public Color setGreen(int green) {
|
||||
return fromRGB(getRed(), green, getBlue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blue component
|
||||
*
|
||||
* @return blue component, from 0 to 255
|
||||
*/
|
||||
public int getBlue() {
|
||||
return BIT_MASK & blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Color object with specified component
|
||||
*
|
||||
* @param blue the red component, from 0 to 255
|
||||
* @return a new color object with the red component
|
||||
*/
|
||||
public Color setBlue(int blue) {
|
||||
return fromRGB(getRed(), getGreen(), blue);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return An integer representation of this color, as 0xRRGGBB
|
||||
*/
|
||||
public int asRGB() {
|
||||
return getRed() << 16 | getGreen() << 8 | getBlue() << 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return An integer representation of this color, as 0xBBGGRR
|
||||
*/
|
||||
public int asBGR() {
|
||||
return getBlue() << 16 | getGreen() << 8 | getRed() << 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new color with its RGB components changed as if it was dyed
|
||||
* with the colors passed in, replicating vanilla workbench dyeing
|
||||
*
|
||||
* @param colors The DyeColors to dye with
|
||||
* @return A new color with the changed rgb components
|
||||
*/
|
||||
// TODO: Javadoc what this method does, not what it mimics. API != Implementation
|
||||
public Color mixDyes(DyeColor... colors) {
|
||||
Validate.noNullElements(colors, "Colors cannot be null");
|
||||
|
||||
Color[] toPass = new Color[colors.length];
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
toPass[i] = colors[i].getColor();
|
||||
}
|
||||
|
||||
return mixColors(toPass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new color with its RGB components changed as if it was dyed
|
||||
* with the colors passed in, replicating vanilla workbench dyeing
|
||||
*
|
||||
* @param colors The colors to dye with
|
||||
* @return A new color with the changed rgb components
|
||||
*/
|
||||
// TODO: Javadoc what this method does, not what it mimics. API != Implementation
|
||||
public Color mixColors(Color... colors) {
|
||||
Validate.noNullElements(colors, "Colors cannot be null");
|
||||
|
||||
int totalRed = this.getRed();
|
||||
int totalGreen = this.getGreen();
|
||||
int totalBlue = this.getBlue();
|
||||
int totalMax = Math.max(Math.max(totalRed, totalGreen), totalBlue);
|
||||
for (Color color : colors) {
|
||||
totalRed += color.getRed();
|
||||
totalGreen += color.getGreen();
|
||||
totalBlue += color.getBlue();
|
||||
totalMax += Math.max(Math.max(color.getRed(), color.getGreen()), color.getBlue());
|
||||
}
|
||||
|
||||
float averageRed = totalRed / (colors.length + 1);
|
||||
float averageGreen = totalGreen / (colors.length + 1);
|
||||
float averageBlue = totalBlue / (colors.length + 1);
|
||||
float averageMax = totalMax / (colors.length + 1);
|
||||
|
||||
float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue);
|
||||
float gainFactor = averageMax / maximumOfAverages;
|
||||
|
||||
return Color.fromRGB((int) (averageRed * gainFactor), (int) (averageGreen * gainFactor), (int) (averageBlue * gainFactor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Color)) {
|
||||
return false;
|
||||
}
|
||||
final Color that = (Color) o;
|
||||
return this.blue == that.blue && this.green == that.green && this.red == that.red;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return asRGB() ^ Color.class.hashCode();
|
||||
}
|
||||
|
||||
public Map<String, Object> serialize() {
|
||||
return ImmutableMap.<String, Object>of(
|
||||
"RED", getRed(),
|
||||
"BLUE", getBlue(),
|
||||
"GREEN", getGreen()
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("javadoc")
|
||||
public static Color deserialize(Map<String, Object> map) {
|
||||
return fromRGB(
|
||||
asInt("RED", map),
|
||||
asInt("GREEN", map),
|
||||
asInt("BLUE", map)
|
||||
);
|
||||
}
|
||||
|
||||
private static int asInt(String string, Map<String, Object> map) {
|
||||
Object value = map.get(string);
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException(string + " not in map " + map);
|
||||
}
|
||||
if (!(value instanceof Number)) {
|
||||
throw new IllegalArgumentException(string + '(' + value + ") is not a number");
|
||||
}
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Color:[rgb0x" + Integer.toHexString(getRed()).toUpperCase() + Integer.toHexString(getGreen()).toUpperCase() + Integer.toHexString(getBlue()).toUpperCase() + "]";
|
||||
}
|
||||
}
|
81
TacoSpigot-API/src/main/java/org/bukkit/CropState.java
Normal file
81
TacoSpigot-API/src/main/java/org/bukkit/CropState.java
Normal file
@ -0,0 +1,81 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the different growth states of crops
|
||||
*/
|
||||
public enum CropState {
|
||||
|
||||
/**
|
||||
* State when first seeded
|
||||
*/
|
||||
SEEDED(0x0),
|
||||
/**
|
||||
* First growth stage
|
||||
*/
|
||||
GERMINATED(0x1),
|
||||
/**
|
||||
* Second growth stage
|
||||
*/
|
||||
VERY_SMALL(0x2),
|
||||
/**
|
||||
* Third growth stage
|
||||
*/
|
||||
SMALL(0x3),
|
||||
/**
|
||||
* Fourth growth stage
|
||||
*/
|
||||
MEDIUM(0x4),
|
||||
/**
|
||||
* Fifth growth stage
|
||||
*/
|
||||
TALL(0x5),
|
||||
/**
|
||||
* Almost ripe stage
|
||||
*/
|
||||
VERY_TALL(0x6),
|
||||
/**
|
||||
* Ripe stage
|
||||
*/
|
||||
RIPE(0x7);
|
||||
|
||||
private final byte data;
|
||||
private final static Map<Byte, CropState> BY_DATA = Maps.newHashMap();
|
||||
|
||||
private CropState(final int data) {
|
||||
this.data = (byte) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated data value representing this growth state
|
||||
*
|
||||
* @return A byte containing the data value of this growth state
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CropState with the given data value
|
||||
*
|
||||
* @param data Data value to fetch
|
||||
* @return The {@link CropState} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static CropState getByData(final byte data) {
|
||||
return BY_DATA.get(data);
|
||||
}
|
||||
|
||||
static {
|
||||
for (CropState cropState : values()) {
|
||||
BY_DATA.put(cropState.getData(), cropState);
|
||||
}
|
||||
}
|
||||
}
|
72
TacoSpigot-API/src/main/java/org/bukkit/Difficulty.java
Normal file
72
TacoSpigot-API/src/main/java/org/bukkit/Difficulty.java
Normal file
@ -0,0 +1,72 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the various difficulty levels that are available.
|
||||
*/
|
||||
public enum Difficulty {
|
||||
/**
|
||||
* Players regain health over time, hostile mobs don't spawn, the hunger
|
||||
* bar does not deplete.
|
||||
*/
|
||||
PEACEFUL(0),
|
||||
|
||||
/**
|
||||
* Hostile mobs spawn, enemies deal less damage than on normal difficulty,
|
||||
* the hunger bar does deplete and starving deals up to 5 hearts of
|
||||
* damage. (Default value)
|
||||
*/
|
||||
EASY(1),
|
||||
|
||||
/**
|
||||
* Hostile mobs spawn, enemies deal normal amounts of damage, the hunger
|
||||
* bar does deplete and starving deals up to 9.5 hearts of damage.
|
||||
*/
|
||||
NORMAL(2),
|
||||
|
||||
/**
|
||||
* Hostile mobs spawn, enemies deal greater damage than on normal
|
||||
* difficulty, the hunger bar does deplete and starving can kill players.
|
||||
*/
|
||||
HARD(3);
|
||||
|
||||
private final int value;
|
||||
private final static Map<Integer, Difficulty> BY_ID = Maps.newHashMap();
|
||||
|
||||
private Difficulty(final int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the difficulty value associated with this Difficulty.
|
||||
*
|
||||
* @return An integer value of this difficulty
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Difficulty represented by the specified value
|
||||
*
|
||||
* @param value Value to check
|
||||
* @return Associative {@link Difficulty} with the given value, or null if
|
||||
* it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static Difficulty getByValue(final int value) {
|
||||
return BY_ID.get(value);
|
||||
}
|
||||
|
||||
static {
|
||||
for (Difficulty diff : values()) {
|
||||
BY_ID.put(diff.value, diff);
|
||||
}
|
||||
}
|
||||
}
|
239
TacoSpigot-API/src/main/java/org/bukkit/DyeColor.java
Normal file
239
TacoSpigot-API/src/main/java/org/bukkit/DyeColor.java
Normal file
@ -0,0 +1,239 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* All supported color values for dyes and cloth
|
||||
*/
|
||||
public enum DyeColor {
|
||||
|
||||
/**
|
||||
* Represents white dye.
|
||||
*/
|
||||
WHITE(0x0, 0xF, Color.WHITE, Color.fromRGB(0xF0F0F0)),
|
||||
/**
|
||||
* Represents orange dye.
|
||||
*/
|
||||
ORANGE(0x1, 0xE, Color.fromRGB(0xD87F33), Color.fromRGB(0xEB8844)),
|
||||
/**
|
||||
* Represents magenta dye.
|
||||
*/
|
||||
MAGENTA(0x2, 0xD, Color.fromRGB(0xB24CD8), Color.fromRGB(0xC354CD)),
|
||||
/**
|
||||
* Represents light blue dye.
|
||||
*/
|
||||
LIGHT_BLUE(0x3, 0xC, Color.fromRGB(0x6699D8), Color.fromRGB(0x6689D3)),
|
||||
/**
|
||||
* Represents yellow dye.
|
||||
*/
|
||||
YELLOW(0x4, 0xB, Color.fromRGB(0xE5E533), Color.fromRGB(0xDECF2A)),
|
||||
/**
|
||||
* Represents lime dye.
|
||||
*/
|
||||
LIME(0x5, 0xA, Color.fromRGB(0x7FCC19), Color.fromRGB(0x41CD34)),
|
||||
/**
|
||||
* Represents pink dye.
|
||||
*/
|
||||
PINK(0x6, 0x9, Color.fromRGB(0xF27FA5), Color.fromRGB(0xD88198)),
|
||||
/**
|
||||
* Represents gray dye.
|
||||
*/
|
||||
GRAY(0x7, 0x8, Color.fromRGB(0x4C4C4C), Color.fromRGB(0x434343)),
|
||||
/**
|
||||
* Represents silver dye.
|
||||
*/
|
||||
SILVER(0x8, 0x7, Color.fromRGB(0x999999), Color.fromRGB(0xABABAB)),
|
||||
/**
|
||||
* Represents cyan dye.
|
||||
*/
|
||||
CYAN(0x9, 0x6, Color.fromRGB(0x4C7F99), Color.fromRGB(0x287697)),
|
||||
/**
|
||||
* Represents purple dye.
|
||||
*/
|
||||
PURPLE(0xA, 0x5, Color.fromRGB(0x7F3FB2), Color.fromRGB(0x7B2FBE)),
|
||||
/**
|
||||
* Represents blue dye.
|
||||
*/
|
||||
BLUE(0xB, 0x4, Color.fromRGB(0x334CB2), Color.fromRGB(0x253192)),
|
||||
/**
|
||||
* Represents brown dye.
|
||||
*/
|
||||
BROWN(0xC, 0x3, Color.fromRGB(0x664C33), Color.fromRGB(0x51301A)),
|
||||
/**
|
||||
* Represents green dye.
|
||||
*/
|
||||
GREEN(0xD, 0x2, Color.fromRGB(0x667F33), Color.fromRGB(0x3B511A)),
|
||||
/**
|
||||
* Represents red dye.
|
||||
*/
|
||||
RED(0xE, 0x1, Color.fromRGB(0x993333), Color.fromRGB(0xB3312C)),
|
||||
/**
|
||||
* Represents black dye.
|
||||
*/
|
||||
BLACK(0xF, 0x0, Color.fromRGB(0x191919), Color.fromRGB(0x1E1B1B));
|
||||
|
||||
private final byte woolData;
|
||||
private final byte dyeData;
|
||||
private final Color color;
|
||||
private final Color firework;
|
||||
private final static DyeColor[] BY_WOOL_DATA;
|
||||
private final static DyeColor[] BY_DYE_DATA;
|
||||
private final static Map<Color, DyeColor> BY_COLOR;
|
||||
private final static Map<Color, DyeColor> BY_FIREWORK;
|
||||
|
||||
private DyeColor(final int woolData, final int dyeData, Color color, Color firework) {
|
||||
this.woolData = (byte) woolData;
|
||||
this.dyeData = (byte) dyeData;
|
||||
this.color = color;
|
||||
this.firework = firework;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated (wool) data value representing this color.
|
||||
*
|
||||
* @return A byte containing the (wool) data value of this color
|
||||
* @deprecated The name is misleading. It would imply {@link
|
||||
* Material#INK_SACK} but uses {@link Material#WOOL}
|
||||
* @see #getWoolData()
|
||||
* @see #getDyeData()
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return getWoolData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated wool data value representing this color.
|
||||
*
|
||||
* @return A byte containing the wool data value of this color
|
||||
* @see #getDyeData()
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getWoolData() {
|
||||
return woolData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated dye data value representing this color.
|
||||
*
|
||||
* @return A byte containing the dye data value of this color
|
||||
* @see #getWoolData()
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getDyeData() {
|
||||
return dyeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the color that this dye represents.
|
||||
*
|
||||
* @return The {@link Color} that this dye represents
|
||||
*/
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the firework color that this dye represents.
|
||||
*
|
||||
* @return The {@link Color} that this dye represents
|
||||
*/
|
||||
public Color getFireworkColor() {
|
||||
return firework;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DyeColor with the given (wool) data value.
|
||||
*
|
||||
* @param data (wool) data value to fetch
|
||||
* @return The {@link DyeColor} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
* @deprecated The name is misleading. It would imply {@link
|
||||
* Material#INK_SACK} but uses {@link Material#WOOL}
|
||||
* @see #getByDyeData(byte)
|
||||
* @see #getByWoolData(byte)
|
||||
*/
|
||||
@Deprecated
|
||||
public static DyeColor getByData(final byte data) {
|
||||
return getByWoolData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DyeColor with the given wool data value.
|
||||
*
|
||||
* @param data Wool data value to fetch
|
||||
* @return The {@link DyeColor} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
* @see #getByDyeData(byte)
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static DyeColor getByWoolData(final byte data) {
|
||||
int i = 0xff & data;
|
||||
if (i >= BY_WOOL_DATA.length) {
|
||||
return null;
|
||||
}
|
||||
return BY_WOOL_DATA[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DyeColor with the given dye data value.
|
||||
*
|
||||
* @param data Dye data value to fetch
|
||||
* @return The {@link DyeColor} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
* @see #getByWoolData(byte)
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static DyeColor getByDyeData(final byte data) {
|
||||
int i = 0xff & data;
|
||||
if (i >= BY_DYE_DATA.length) {
|
||||
return null;
|
||||
}
|
||||
return BY_DYE_DATA[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DyeColor with the given color value.
|
||||
*
|
||||
* @param color Color value to get the dye by
|
||||
* @return The {@link DyeColor} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
*/
|
||||
public static DyeColor getByColor(final Color color) {
|
||||
return BY_COLOR.get(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DyeColor with the given firework color value.
|
||||
*
|
||||
* @param color Color value to get dye by
|
||||
* @return The {@link DyeColor} representing the given value, or null if
|
||||
* it doesn't exist
|
||||
*/
|
||||
public static DyeColor getByFireworkColor(final Color color) {
|
||||
return BY_FIREWORK.get(color);
|
||||
}
|
||||
|
||||
static {
|
||||
BY_WOOL_DATA = values();
|
||||
BY_DYE_DATA = values();
|
||||
ImmutableMap.Builder<Color, DyeColor> byColor = ImmutableMap.builder();
|
||||
ImmutableMap.Builder<Color, DyeColor> byFirework = ImmutableMap.builder();
|
||||
|
||||
for (DyeColor color : values()) {
|
||||
BY_WOOL_DATA[color.woolData & 0xff] = color;
|
||||
BY_DYE_DATA[color.dyeData & 0xff] = color;
|
||||
byColor.put(color.getColor(), color);
|
||||
byFirework.put(color.getFireworkColor(), color);
|
||||
}
|
||||
|
||||
BY_COLOR = byColor.build();
|
||||
BY_FIREWORK = byFirework.build();
|
||||
}
|
||||
}
|
337
TacoSpigot-API/src/main/java/org/bukkit/Effect.java
Normal file
337
TacoSpigot-API/src/main/java/org/bukkit/Effect.java
Normal file
@ -0,0 +1,337 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.potion.Potion;
|
||||
|
||||
/**
|
||||
* A list of effects that the server is able to send to players.
|
||||
*/
|
||||
public enum Effect {
|
||||
/**
|
||||
* An alternate click sound.
|
||||
*/
|
||||
CLICK2(1000, Type.SOUND),
|
||||
/**
|
||||
* A click sound.
|
||||
*/
|
||||
CLICK1(1001, Type.SOUND),
|
||||
/**
|
||||
* Sound of a bow firing.
|
||||
*/
|
||||
BOW_FIRE(1002, Type.SOUND),
|
||||
/**
|
||||
* Sound of a door opening/closing.
|
||||
*/
|
||||
DOOR_TOGGLE(1003, Type.SOUND),
|
||||
/**
|
||||
* Sound of fire being extinguished.
|
||||
*/
|
||||
EXTINGUISH(1004, Type.SOUND),
|
||||
/**
|
||||
* A song from a record. Needs the record item ID as additional info
|
||||
*/
|
||||
RECORD_PLAY(1005, Type.SOUND, Material.class),
|
||||
/**
|
||||
* Sound of ghast shrieking.
|
||||
*/
|
||||
GHAST_SHRIEK(1007, Type.SOUND),
|
||||
/**
|
||||
* Sound of ghast firing.
|
||||
*/
|
||||
GHAST_SHOOT(1008, Type.SOUND),
|
||||
/**
|
||||
* Sound of blaze firing.
|
||||
*/
|
||||
BLAZE_SHOOT(1009, Type.SOUND),
|
||||
/**
|
||||
* Sound of zombies chewing on wooden doors.
|
||||
*/
|
||||
ZOMBIE_CHEW_WOODEN_DOOR(1010, Type.SOUND),
|
||||
/**
|
||||
* Sound of zombies chewing on iron doors.
|
||||
*/
|
||||
ZOMBIE_CHEW_IRON_DOOR(1011, Type.SOUND),
|
||||
/**
|
||||
* Sound of zombies destroying a door.
|
||||
*/
|
||||
ZOMBIE_DESTROY_DOOR(1012, Type.SOUND),
|
||||
/**
|
||||
* A visual smoke effect. Needs direction as additional info.
|
||||
*/
|
||||
SMOKE(2000, Type.VISUAL, BlockFace.class),
|
||||
/**
|
||||
* Sound of a block breaking. Needs block ID as additional info.
|
||||
*/
|
||||
STEP_SOUND(2001, Type.SOUND, Material.class),
|
||||
/**
|
||||
* Visual effect of a splash potion breaking. Needs potion data value as
|
||||
* additional info.
|
||||
*/
|
||||
POTION_BREAK(2002, Type.VISUAL, Potion.class),
|
||||
/**
|
||||
* An ender eye signal; a visual effect.
|
||||
*/
|
||||
ENDER_SIGNAL(2003, Type.VISUAL),
|
||||
/**
|
||||
* The flames seen on a mobspawner; a visual effect.
|
||||
*/
|
||||
MOBSPAWNER_FLAMES(2004, Type.VISUAL),
|
||||
/**
|
||||
* The spark that comes off a fireworks
|
||||
*/
|
||||
FIREWORKS_SPARK("fireworksSpark", Type.PARTICLE),
|
||||
/**
|
||||
* Critical hit particles
|
||||
*/
|
||||
CRIT("crit", Type.PARTICLE),
|
||||
/**
|
||||
* Blue critical hit particles
|
||||
*/
|
||||
MAGIC_CRIT("magicCrit", Type.PARTICLE),
|
||||
/**
|
||||
* Multicolored potion effect particles
|
||||
*/
|
||||
POTION_SWIRL("mobSpell", Type.PARTICLE),
|
||||
/**
|
||||
* Multicolored potion effect particles that are slightly transparent
|
||||
*/
|
||||
POTION_SWIRL_TRANSPARENT("mobSpellAmbient", Type.PARTICLE),
|
||||
/**
|
||||
* A puff of white potion swirls
|
||||
*/
|
||||
SPELL("spell", Type.PARTICLE),
|
||||
/**
|
||||
* A puff of white stars
|
||||
*/
|
||||
INSTANT_SPELL("instantSpell", Type.PARTICLE),
|
||||
/**
|
||||
* A puff of purple particles
|
||||
*/
|
||||
WITCH_MAGIC("witchMagic", Type.PARTICLE),
|
||||
/**
|
||||
* The note that appears above note blocks
|
||||
*/
|
||||
NOTE("note", Type.PARTICLE),
|
||||
/**
|
||||
* The particles shown at nether portals
|
||||
*/
|
||||
PORTAL("portal", Type.PARTICLE),
|
||||
/**
|
||||
* The symbols that fly towards the enchantment table
|
||||
*/
|
||||
FLYING_GLYPH("enchantmenttable", Type.PARTICLE),
|
||||
/**
|
||||
* Fire particles
|
||||
*/
|
||||
FLAME("flame", Type.PARTICLE),
|
||||
/**
|
||||
* The particles that pop out of lava
|
||||
*/
|
||||
LAVA_POP("lava", Type.PARTICLE),
|
||||
/**
|
||||
* A small gray square
|
||||
*/
|
||||
FOOTSTEP("footstep", Type.PARTICLE),
|
||||
/**
|
||||
* Water particles
|
||||
*/
|
||||
SPLASH("splash", Type.PARTICLE),
|
||||
/**
|
||||
* Smoke particles
|
||||
*/
|
||||
PARTICLE_SMOKE("smoke", Type.PARTICLE),
|
||||
/**
|
||||
* The biggest explosion particle effect
|
||||
*/
|
||||
EXPLOSION_HUGE("hugeexplosion", Type.PARTICLE),
|
||||
/**
|
||||
* A larger version of the explode particle
|
||||
*/
|
||||
EXPLOSION_LARGE("largeexplode", Type.PARTICLE),
|
||||
/**
|
||||
* Explosion particles
|
||||
*/
|
||||
EXPLOSION("explode", Type.PARTICLE),
|
||||
/**
|
||||
* Small gray particles
|
||||
*/
|
||||
VOID_FOG("depthsuspend", Type.PARTICLE),
|
||||
/**
|
||||
* Small gray particles
|
||||
*/
|
||||
SMALL_SMOKE("townaura", Type.PARTICLE),
|
||||
/**
|
||||
* A puff of white smoke
|
||||
*/
|
||||
CLOUD("cloud", Type.PARTICLE),
|
||||
/**
|
||||
* Multicolored dust particles
|
||||
*/
|
||||
COLOURED_DUST("reddust", Type.PARTICLE),
|
||||
/**
|
||||
* Snowball breaking
|
||||
*/
|
||||
SNOWBALL_BREAK("snowballpoof", Type.PARTICLE),
|
||||
/**
|
||||
* The water drip particle that appears on blocks under water
|
||||
*/
|
||||
WATERDRIP("dripWater", Type.PARTICLE),
|
||||
/**
|
||||
* The lava drip particle that appears on blocks under lava
|
||||
*/
|
||||
LAVADRIP("dripLava", Type.PARTICLE),
|
||||
/**
|
||||
* White particles
|
||||
*/
|
||||
SNOW_SHOVEL("snowshovel", Type.PARTICLE),
|
||||
/**
|
||||
* The particle shown when a slime jumps
|
||||
*/
|
||||
SLIME("slime", Type.PARTICLE),
|
||||
/**
|
||||
* The particle that appears when breading animals
|
||||
*/
|
||||
HEART("heart", Type.PARTICLE),
|
||||
/**
|
||||
* The particle that appears when hitting a villager
|
||||
*/
|
||||
VILLAGER_THUNDERCLOUD("angryVillager", Type.PARTICLE),
|
||||
/**
|
||||
* The particle that appears when trading with a villager
|
||||
*/
|
||||
HAPPY_VILLAGER("happyVillager", Type.PARTICLE),
|
||||
/**
|
||||
* The smoke particles that appears on blazes, minecarts
|
||||
* with furnaces and fire
|
||||
*/
|
||||
LARGE_SMOKE("largesmoke", Type.PARTICLE),
|
||||
/**
|
||||
* The particles generated when a tool breaks.
|
||||
* This particle requires a Material so that the client can select the correct texture.
|
||||
*/
|
||||
ITEM_BREAK("iconcrack", Type.PARTICLE, Material.class),
|
||||
/**
|
||||
* The particles generated while breaking a block.
|
||||
* This particle requires a Material and data value so that the client can select the correct texture.
|
||||
*/
|
||||
TILE_BREAK("blockcrack", Type.PARTICLE, MaterialData.class),
|
||||
/**
|
||||
* The particles generated while sprinting a block
|
||||
* This particle requires a Material and data value so that the client can select the correct texture.
|
||||
*/
|
||||
TILE_DUST("blockdust", Type.PARTICLE, MaterialData.class);
|
||||
|
||||
private final int id;
|
||||
private final Type type;
|
||||
private final Class<?> data;
|
||||
private static final Map<Integer, Effect> BY_ID = Maps.newHashMap();
|
||||
private static final Map<String, Effect> BY_NAME = Maps.newHashMap();
|
||||
private final String particleName;
|
||||
|
||||
private Effect(int id, Type type) {
|
||||
this(id,type,null);
|
||||
}
|
||||
|
||||
private Effect(int id, Type type, Class<?> data) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
particleName = null;
|
||||
}
|
||||
|
||||
private Effect(String particleName, Type type, Class<?> data) {
|
||||
this.particleName = particleName;
|
||||
this.type = type;
|
||||
id = 0;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
private Effect(String particleName, Type type) {
|
||||
this.particleName = particleName;
|
||||
this.type = type;
|
||||
id = 0;
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ID for this effect.
|
||||
*
|
||||
* @return if this Effect isn't of type PARTICLE it returns ID of this effect
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effect's name. This returns null if the effect is not a particle
|
||||
*
|
||||
* @return The effect's name
|
||||
*/
|
||||
public String getName() {
|
||||
return particleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type of the effect.
|
||||
*/
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if this Effect isn't of type PARTICLE it returns the class which represents data for this effect, or null if none
|
||||
*/
|
||||
public Class<?> getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Effect associated with the given ID.
|
||||
*
|
||||
* @param id ID of the Effect to return
|
||||
* @return Effect with the given ID
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static Effect getById(int id) {
|
||||
return BY_ID.get(id);
|
||||
}
|
||||
|
||||
static {
|
||||
for (Effect effect : values()) {
|
||||
if (effect.type != Type.PARTICLE) {
|
||||
BY_ID.put(effect.id, effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Effect associated with the given name.
|
||||
*
|
||||
* @param name name of the Effect to return
|
||||
* @return Effect with the given name
|
||||
*/
|
||||
public static Effect getByName(String name) {
|
||||
return BY_NAME.get(name);
|
||||
}
|
||||
|
||||
static {
|
||||
for (Effect effect : values()) {
|
||||
if (effect.type == Type.PARTICLE) {
|
||||
BY_NAME.put(effect.particleName, effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the type of an effect.
|
||||
*/
|
||||
public enum Type {SOUND, VISUAL, PARTICLE}
|
||||
}
|
136
TacoSpigot-API/src/main/java/org/bukkit/EntityEffect.java
Normal file
136
TacoSpigot-API/src/main/java/org/bukkit/EntityEffect.java
Normal file
@ -0,0 +1,136 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* A list of all Effects that can happen to entities.
|
||||
*/
|
||||
public enum EntityEffect {
|
||||
|
||||
/**
|
||||
* When mobs get hurt.
|
||||
*/
|
||||
HURT(2),
|
||||
|
||||
/**
|
||||
* When a mob dies.
|
||||
* <p>
|
||||
* <b>This will cause client-glitches!</b>
|
||||
*/
|
||||
DEATH(3),
|
||||
|
||||
/**
|
||||
* The smoke when taming a wolf fails.
|
||||
* <p>
|
||||
* Without client-mods this will be ignored if the entity is not a wolf.
|
||||
*/
|
||||
WOLF_SMOKE(6),
|
||||
|
||||
/**
|
||||
* The hearts when taming a wolf succeeds.
|
||||
* <p>
|
||||
* Without client-mods this will be ignored if the entity is not a wolf.
|
||||
*/
|
||||
WOLF_HEARTS(7),
|
||||
|
||||
/**
|
||||
* When a wolf shakes (after being wet).
|
||||
* <p>
|
||||
* Without client-mods this will be ignored if the entity is not a wolf.
|
||||
*/
|
||||
WOLF_SHAKE(8),
|
||||
|
||||
/**
|
||||
* When a sheep eats a LONG_GRASS block.
|
||||
*/
|
||||
SHEEP_EAT(10),
|
||||
|
||||
/**
|
||||
* When an Iron Golem gives a rose.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not an iron golem.
|
||||
*/
|
||||
IRON_GOLEM_ROSE(11),
|
||||
|
||||
/**
|
||||
* Hearts from a villager.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not a villager.
|
||||
*/
|
||||
VILLAGER_HEART(12),
|
||||
|
||||
/**
|
||||
* When a villager is angry.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not a villager.
|
||||
*/
|
||||
VILLAGER_ANGRY(13),
|
||||
|
||||
/**
|
||||
* Happy particles from a villager.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not a villager.
|
||||
*/
|
||||
VILLAGER_HAPPY(14),
|
||||
|
||||
/**
|
||||
* Magic particles from a witch.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not a witch.
|
||||
*/
|
||||
WITCH_MAGIC(15),
|
||||
|
||||
/**
|
||||
* When a zombie transforms into a villager by shaking violently.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not a zombie.
|
||||
*/
|
||||
ZOMBIE_TRANSFORM(16),
|
||||
|
||||
/**
|
||||
* When a firework explodes.
|
||||
* <p>
|
||||
* This will not play an effect if the entity is not a firework.
|
||||
*/
|
||||
FIREWORK_EXPLODE(17);
|
||||
|
||||
private final byte data;
|
||||
private final static Map<Byte, EntityEffect> BY_DATA = Maps.newHashMap();
|
||||
|
||||
EntityEffect(final int data) {
|
||||
this.data = (byte) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data value of this EntityEffect
|
||||
*
|
||||
* @return The data value
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the EntityEffect with the given data value
|
||||
*
|
||||
* @param data Data value to fetch
|
||||
* @return The {@link EntityEffect} representing the given value, or null
|
||||
* if it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static EntityEffect getByData(final byte data) {
|
||||
return BY_DATA.get(data);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
for (EntityEffect entityEffect : values()) {
|
||||
BY_DATA.put(entityEffect.data, entityEffect);
|
||||
}
|
||||
}
|
||||
}
|
424
TacoSpigot-API/src/main/java/org/bukkit/FireworkEffect.java
Normal file
424
TacoSpigot-API/src/main/java/org/bukkit/FireworkEffect.java
Normal file
@ -0,0 +1,424 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.SerializableAs;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Represents a single firework effect.
|
||||
*/
|
||||
@SerializableAs("Firework")
|
||||
public final class FireworkEffect implements ConfigurationSerializable {
|
||||
|
||||
/**
|
||||
* The type or shape of the effect.
|
||||
*/
|
||||
public enum Type {
|
||||
/**
|
||||
* A small ball effect.
|
||||
*/
|
||||
BALL,
|
||||
/**
|
||||
* A large ball effect.
|
||||
*/
|
||||
BALL_LARGE,
|
||||
/**
|
||||
* A star-shaped effect.
|
||||
*/
|
||||
STAR,
|
||||
/**
|
||||
* A burst effect.
|
||||
*/
|
||||
BURST,
|
||||
/**
|
||||
* A creeper-face effect.
|
||||
*/
|
||||
CREEPER,
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a firework effect.
|
||||
*
|
||||
* @return A utility object for building a firework effect
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a builder for FireworkEffects.
|
||||
*
|
||||
* @see FireworkEffect#builder()
|
||||
*/
|
||||
public static final class Builder {
|
||||
boolean flicker = false;
|
||||
boolean trail = false;
|
||||
final ImmutableList.Builder<Color> colors = ImmutableList.builder();
|
||||
ImmutableList.Builder<Color> fadeColors = null;
|
||||
Type type = Type.BALL;
|
||||
|
||||
Builder() {}
|
||||
|
||||
/**
|
||||
* Specify the type of the firework effect.
|
||||
*
|
||||
* @param type The effect type
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If type is null
|
||||
*/
|
||||
public Builder with(Type type) throws IllegalArgumentException {
|
||||
Validate.notNull(type, "Cannot have null type");
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a flicker to the firework effect.
|
||||
*
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public Builder withFlicker() {
|
||||
flicker = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the firework effect should flicker.
|
||||
*
|
||||
* @param flicker true if it should flicker, false if not
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public Builder flicker(boolean flicker) {
|
||||
this.flicker = flicker;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a trail to the firework effect.
|
||||
*
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public Builder withTrail() {
|
||||
trail = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the firework effect should have a trail.
|
||||
*
|
||||
* @param trail true if it should have a trail, false for no trail
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public Builder trail(boolean trail) {
|
||||
this.trail = trail;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a primary color to the firework effect.
|
||||
*
|
||||
* @param color The color to add
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If color is null
|
||||
*/
|
||||
public Builder withColor(Color color) throws IllegalArgumentException {
|
||||
Validate.notNull(color, "Cannot have null color");
|
||||
|
||||
colors.add(color);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add several primary colors to the firework effect.
|
||||
*
|
||||
* @param colors The colors to add
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If colors is null
|
||||
* @throws IllegalArgumentException If any color is null (may be
|
||||
* thrown after changes have occurred)
|
||||
*/
|
||||
public Builder withColor(Color...colors) throws IllegalArgumentException {
|
||||
Validate.notNull(colors, "Cannot have null colors");
|
||||
if (colors.length == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
ImmutableList.Builder<Color> list = this.colors;
|
||||
for (Color color : colors) {
|
||||
Validate.notNull(color, "Color cannot be null");
|
||||
list.add(color);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add several primary colors to the firework effect.
|
||||
*
|
||||
* @param colors An iterable object whose iterator yields the desired
|
||||
* colors
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If colors is null
|
||||
* @throws IllegalArgumentException If any color is null (may be
|
||||
* thrown after changes have occurred)
|
||||
*/
|
||||
public Builder withColor(Iterable<?> colors) throws IllegalArgumentException {
|
||||
Validate.notNull(colors, "Cannot have null colors");
|
||||
|
||||
ImmutableList.Builder<Color> list = this.colors;
|
||||
for (Object color : colors) {
|
||||
if (!(color instanceof Color)) {
|
||||
throw new IllegalArgumentException(color + " is not a Color in " + colors);
|
||||
}
|
||||
list.add((Color) color);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a fade color to the firework effect.
|
||||
*
|
||||
* @param color The color to add
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If colors is null
|
||||
* @throws IllegalArgumentException If any color is null (may be
|
||||
* thrown after changes have occurred)
|
||||
*/
|
||||
public Builder withFade(Color color) throws IllegalArgumentException {
|
||||
Validate.notNull(color, "Cannot have null color");
|
||||
|
||||
if (fadeColors == null) {
|
||||
fadeColors = ImmutableList.builder();
|
||||
}
|
||||
|
||||
fadeColors.add(color);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add several fade colors to the firework effect.
|
||||
*
|
||||
* @param colors The colors to add
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If colors is null
|
||||
* @throws IllegalArgumentException If any color is null (may be
|
||||
* thrown after changes have occurred)
|
||||
*/
|
||||
public Builder withFade(Color...colors) throws IllegalArgumentException {
|
||||
Validate.notNull(colors, "Cannot have null colors");
|
||||
if (colors.length == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
ImmutableList.Builder<Color> list = this.fadeColors;
|
||||
if (list == null) {
|
||||
list = this.fadeColors = ImmutableList.builder();
|
||||
}
|
||||
|
||||
for (Color color : colors) {
|
||||
Validate.notNull(color, "Color cannot be null");
|
||||
list.add(color);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add several fade colors to the firework effect.
|
||||
*
|
||||
* @param colors An iterable object whose iterator yields the desired
|
||||
* colors
|
||||
* @return This object, for chaining
|
||||
* @throws IllegalArgumentException If colors is null
|
||||
* @throws IllegalArgumentException If any color is null (may be
|
||||
* thrown after changes have occurred)
|
||||
*/
|
||||
public Builder withFade(Iterable<?> colors) throws IllegalArgumentException {
|
||||
Validate.notNull(colors, "Cannot have null colors");
|
||||
|
||||
ImmutableList.Builder<Color> list = this.fadeColors;
|
||||
if (list == null) {
|
||||
list = this.fadeColors = ImmutableList.builder();
|
||||
}
|
||||
|
||||
for (Object color : colors) {
|
||||
if (!(color instanceof Color)) {
|
||||
throw new IllegalArgumentException(color + " is not a Color in " + colors);
|
||||
}
|
||||
list.add((Color) color);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link FireworkEffect} from the current contents of this
|
||||
* builder.
|
||||
* <p>
|
||||
* To successfully build, you must have specified at least one color.
|
||||
*
|
||||
* @return The representative firework effect
|
||||
*/
|
||||
public FireworkEffect build() {
|
||||
return new FireworkEffect(
|
||||
flicker,
|
||||
trail,
|
||||
colors.build(),
|
||||
fadeColors == null ? ImmutableList.<Color>of() : fadeColors.build(),
|
||||
type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String FLICKER = "flicker";
|
||||
private static final String TRAIL = "trail";
|
||||
private static final String COLORS = "colors";
|
||||
private static final String FADE_COLORS = "fade-colors";
|
||||
private static final String TYPE = "type";
|
||||
|
||||
private final boolean flicker;
|
||||
private final boolean trail;
|
||||
private final ImmutableList<Color> colors;
|
||||
private final ImmutableList<Color> fadeColors;
|
||||
private final Type type;
|
||||
private String string = null;
|
||||
|
||||
FireworkEffect(boolean flicker, boolean trail, ImmutableList<Color> colors, ImmutableList<Color> fadeColors, Type type) {
|
||||
if (colors.isEmpty()) {
|
||||
throw new IllegalStateException("Cannot make FireworkEffect without any color");
|
||||
}
|
||||
this.flicker = flicker;
|
||||
this.trail = trail;
|
||||
this.colors = colors;
|
||||
this.fadeColors = fadeColors;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the firework effect flickers.
|
||||
*
|
||||
* @return true if it flickers, false if not
|
||||
*/
|
||||
public boolean hasFlicker() {
|
||||
return flicker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the firework effect has a trail.
|
||||
*
|
||||
* @return true if it has a trail, false if not
|
||||
*/
|
||||
public boolean hasTrail() {
|
||||
return trail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary colors of the firework effect.
|
||||
*
|
||||
* @return An immutable list of the primary colors
|
||||
*/
|
||||
public List<Color> getColors() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fade colors of the firework effect.
|
||||
*
|
||||
* @return An immutable list of the fade colors
|
||||
*/
|
||||
public List<Color> getFadeColors() {
|
||||
return fadeColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the firework effect.
|
||||
*
|
||||
* @return The effect type
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ConfigurationSerializable
|
||||
* @param map the map to deserialize
|
||||
* @return the resulting serializable
|
||||
*/
|
||||
public static ConfigurationSerializable deserialize(Map<String, Object> map) {
|
||||
Type type = Type.valueOf((String) map.get(TYPE));
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException(map.get(TYPE) + " is not a valid Type");
|
||||
}
|
||||
|
||||
return builder()
|
||||
.flicker((Boolean) map.get(FLICKER))
|
||||
.trail((Boolean) map.get(TRAIL))
|
||||
.withColor((Iterable<?>) map.get(COLORS))
|
||||
.withFade((Iterable<?>) map.get(FADE_COLORS))
|
||||
.with(type)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
return ImmutableMap.<String, Object>of(
|
||||
FLICKER, flicker,
|
||||
TRAIL, trail,
|
||||
COLORS, colors,
|
||||
FADE_COLORS, fadeColors,
|
||||
TYPE, type.name()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final String string = this.string;
|
||||
if (string == null) {
|
||||
return this.string = "FireworkEffect:" + serialize();
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
/**
|
||||
* TRUE and FALSE as per boolean.hashCode()
|
||||
*/
|
||||
final int PRIME = 31, TRUE = 1231, FALSE = 1237;
|
||||
int hash = 1;
|
||||
hash = hash * PRIME + (flicker ? TRUE : FALSE);
|
||||
hash = hash * PRIME + (trail ? TRUE : FALSE);
|
||||
hash = hash * PRIME + type.hashCode();
|
||||
hash = hash * PRIME + colors.hashCode();
|
||||
hash = hash * PRIME + fadeColors.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof FireworkEffect)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FireworkEffect that = (FireworkEffect) obj;
|
||||
return this.flicker == that.flicker
|
||||
&& this.trail == that.trail
|
||||
&& this.type == that.type
|
||||
&& this.colors.equals(that.colors)
|
||||
&& this.fadeColors.equals(that.fadeColors);
|
||||
}
|
||||
}
|
73
TacoSpigot-API/src/main/java/org/bukkit/GameMode.java
Normal file
73
TacoSpigot-API/src/main/java/org/bukkit/GameMode.java
Normal file
@ -0,0 +1,73 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the various type of game modes that {@link HumanEntity}s may
|
||||
* have
|
||||
*/
|
||||
public enum GameMode {
|
||||
/**
|
||||
* Creative mode may fly, build instantly, become invulnerable and create
|
||||
* free items.
|
||||
*/
|
||||
CREATIVE(1),
|
||||
|
||||
/**
|
||||
* Survival mode is the "normal" gameplay type, with no special features.
|
||||
*/
|
||||
SURVIVAL(0),
|
||||
|
||||
/**
|
||||
* Adventure mode cannot break blocks without the correct tools.
|
||||
*/
|
||||
ADVENTURE(2),
|
||||
|
||||
/**
|
||||
* Spectator mode cannot interact with the world in anyway and is
|
||||
* invisible to normal players. This grants the player the
|
||||
* ability to no-clip through the world.
|
||||
*/
|
||||
SPECTATOR(3);
|
||||
|
||||
private final int value;
|
||||
private final static Map<Integer, GameMode> BY_ID = Maps.newHashMap();
|
||||
|
||||
private GameMode(final int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mode value associated with this GameMode
|
||||
*
|
||||
* @return An integer value of this gamemode
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GameMode represented by the specified value
|
||||
*
|
||||
* @param value Value to check
|
||||
* @return Associative {@link GameMode} with the given value, or null if
|
||||
* it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static GameMode getByValue(final int value) {
|
||||
return BY_ID.get(value);
|
||||
}
|
||||
|
||||
static {
|
||||
for (GameMode mode : values()) {
|
||||
BY_ID.put(mode.getValue(), mode);
|
||||
}
|
||||
}
|
||||
}
|
61
TacoSpigot-API/src/main/java/org/bukkit/GrassSpecies.java
Normal file
61
TacoSpigot-API/src/main/java/org/bukkit/GrassSpecies.java
Normal file
@ -0,0 +1,61 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the different types of grass.
|
||||
*/
|
||||
public enum GrassSpecies {
|
||||
|
||||
/**
|
||||
* Represents the dead looking grass.
|
||||
*/
|
||||
DEAD(0x0),
|
||||
/**
|
||||
* Represents the normal grass species.
|
||||
*/
|
||||
NORMAL(0x1),
|
||||
/**
|
||||
* Represents the fern-looking grass species.
|
||||
*/
|
||||
FERN_LIKE(0x2);
|
||||
|
||||
private final byte data;
|
||||
private final static Map<Byte, GrassSpecies> BY_DATA = Maps.newHashMap();
|
||||
|
||||
private GrassSpecies(final int data) {
|
||||
this.data = (byte) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated data value representing this species
|
||||
*
|
||||
* @return A byte containing the data value of this grass species
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GrassSpecies with the given data value
|
||||
*
|
||||
* @param data Data value to fetch
|
||||
* @return The {@link GrassSpecies} representing the given value, or null
|
||||
* if it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static GrassSpecies getByData(final byte data) {
|
||||
return BY_DATA.get(data);
|
||||
}
|
||||
|
||||
static {
|
||||
for (GrassSpecies grassSpecies : values()) {
|
||||
BY_DATA.put(grassSpecies.getData(), grassSpecies);
|
||||
}
|
||||
}
|
||||
}
|
67
TacoSpigot-API/src/main/java/org/bukkit/Instrument.java
Normal file
67
TacoSpigot-API/src/main/java/org/bukkit/Instrument.java
Normal file
@ -0,0 +1,67 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public enum Instrument {
|
||||
|
||||
/**
|
||||
* Piano is the standard instrument for a note block.
|
||||
*/
|
||||
PIANO(0x0),
|
||||
/**
|
||||
* Bass drum is normally played when a note block is on top of a
|
||||
* stone-like block
|
||||
*/
|
||||
BASS_DRUM(0x1),
|
||||
/**
|
||||
* Snare drum is normally played when a note block is on top of a sandy
|
||||
* block.
|
||||
*/
|
||||
SNARE_DRUM(0x2),
|
||||
/**
|
||||
* Sticks are normally played when a note block is on top of a glass
|
||||
* block.
|
||||
*/
|
||||
STICKS(0x3),
|
||||
/**
|
||||
* Bass guitar is normally played when a note block is on top of a wooden
|
||||
* block.
|
||||
*/
|
||||
BASS_GUITAR(0x4);
|
||||
|
||||
private final byte type;
|
||||
private final static Map<Byte, Instrument> BY_DATA = Maps.newHashMap();
|
||||
|
||||
private Instrument(final int type) {
|
||||
this.type = (byte) type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type ID of this instrument.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instrument by its type ID.
|
||||
*
|
||||
* @param type The type ID
|
||||
* @return The instrument
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static Instrument getByType(final byte type) {
|
||||
return BY_DATA.get(type);
|
||||
}
|
||||
|
||||
static {
|
||||
for (Instrument instrument : Instrument.values()) {
|
||||
BY_DATA.put(instrument.getType(), instrument);
|
||||
}
|
||||
}
|
||||
}
|
600
TacoSpigot-API/src/main/java/org/bukkit/Location.java
Normal file
600
TacoSpigot-API/src/main/java/org/bukkit/Location.java
Normal file
@ -0,0 +1,600 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
import static org.bukkit.util.NumberConversions.checkFinite;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Represents a 3-dimensional position in a world
|
||||
*/
|
||||
public class Location implements Cloneable, ConfigurationSerializable {
|
||||
private World world;
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float pitch;
|
||||
private float yaw;
|
||||
|
||||
/**
|
||||
* Constructs a new Location with the given coordinates
|
||||
*
|
||||
* @param world The world in which this location resides
|
||||
* @param x The x-coordinate of this new location
|
||||
* @param y The y-coordinate of this new location
|
||||
* @param z The z-coordinate of this new location
|
||||
*/
|
||||
public Location(final World world, final double x, final double y, final double z) {
|
||||
this(world, x, y, z, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Location with the given coordinates and direction
|
||||
*
|
||||
* @param world The world in which this location resides
|
||||
* @param x The x-coordinate of this new location
|
||||
* @param y The y-coordinate of this new location
|
||||
* @param z The z-coordinate of this new location
|
||||
* @param yaw The absolute rotation on the x-plane, in degrees
|
||||
* @param pitch The absolute rotation on the y-plane, in degrees
|
||||
*/
|
||||
public Location(final World world, final double x, final double y, final double z, final float yaw, final float pitch) {
|
||||
this.world = world;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.pitch = pitch;
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the world that this location resides in
|
||||
*
|
||||
* @param world New world that this location resides in
|
||||
*/
|
||||
public void setWorld(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world that this location resides in
|
||||
*
|
||||
* @return World that contains this location
|
||||
*/
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunk at the represented location
|
||||
*
|
||||
* @return Chunk at the represented location
|
||||
*/
|
||||
public Chunk getChunk() {
|
||||
return world.getChunkAt(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block at the represented location
|
||||
*
|
||||
* @return Block at the represented location
|
||||
*/
|
||||
public Block getBlock() {
|
||||
return world.getBlockAt(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the x-coordinate of this location
|
||||
*
|
||||
* @param x X-coordinate
|
||||
*/
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the x-coordinate of this location
|
||||
*
|
||||
* @return x-coordinate
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the floored value of the X component, indicating the block that
|
||||
* this location is contained with.
|
||||
*
|
||||
* @return block X
|
||||
*/
|
||||
public int getBlockX() {
|
||||
return locToBlock(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the y-coordinate of this location
|
||||
*
|
||||
* @param y y-coordinate
|
||||
*/
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y-coordinate of this location
|
||||
*
|
||||
* @return y-coordinate
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the floored value of the Y component, indicating the block that
|
||||
* this location is contained with.
|
||||
*
|
||||
* @return block y
|
||||
*/
|
||||
public int getBlockY() {
|
||||
return locToBlock(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the z-coordinate of this location
|
||||
*
|
||||
* @param z z-coordinate
|
||||
*/
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the z-coordinate of this location
|
||||
*
|
||||
* @return z-coordinate
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the floored value of the Z component, indicating the block that
|
||||
* this location is contained with.
|
||||
*
|
||||
* @return block z
|
||||
*/
|
||||
public int getBlockZ() {
|
||||
return locToBlock(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the yaw of this location, measured in degrees.
|
||||
* <ul>
|
||||
* <li>A yaw of 0 or 360 represents the positive z direction.
|
||||
* <li>A yaw of 180 represents the negative z direction.
|
||||
* <li>A yaw of 90 represents the negative x direction.
|
||||
* <li>A yaw of 270 represents the positive x direction.
|
||||
* </ul>
|
||||
* Increasing yaw values are the equivalent of turning to your
|
||||
* right-facing, increasing the scale of the next respective axis, and
|
||||
* decreasing the scale of the previous axis.
|
||||
*
|
||||
* @param yaw new rotation's yaw
|
||||
*/
|
||||
public void setYaw(float yaw) {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the yaw of this location, measured in degrees.
|
||||
* <ul>
|
||||
* <li>A yaw of 0 or 360 represents the positive z direction.
|
||||
* <li>A yaw of 180 represents the negative z direction.
|
||||
* <li>A yaw of 90 represents the negative x direction.
|
||||
* <li>A yaw of 270 represents the positive x direction.
|
||||
* </ul>
|
||||
* Increasing yaw values are the equivalent of turning to your
|
||||
* right-facing, increasing the scale of the next respective axis, and
|
||||
* decreasing the scale of the previous axis.
|
||||
*
|
||||
* @return the rotation's yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pitch of this location, measured in degrees.
|
||||
* <ul>
|
||||
* <li>A pitch of 0 represents level forward facing.
|
||||
* <li>A pitch of 90 represents downward facing, or negative y
|
||||
* direction.
|
||||
* <li>A pitch of -90 represents upward facing, or positive y direction.
|
||||
* </ul>
|
||||
* Increasing pitch values the equivalent of looking down.
|
||||
*
|
||||
* @param pitch new incline's pitch
|
||||
*/
|
||||
public void setPitch(float pitch) {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pitch of this location, measured in degrees.
|
||||
* <ul>
|
||||
* <li>A pitch of 0 represents level forward facing.
|
||||
* <li>A pitch of 90 represents downward facing, or negative y
|
||||
* direction.
|
||||
* <li>A pitch of -90 represents upward facing, or positive y direction.
|
||||
* </ul>
|
||||
* Increasing pitch values the equivalent of looking down.
|
||||
*
|
||||
* @return the incline's pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a unit-vector pointing in the direction that this Location is
|
||||
* facing.
|
||||
*
|
||||
* @return a vector pointing the direction of this location's {@link
|
||||
* #getPitch() pitch} and {@link #getYaw() yaw}
|
||||
*/
|
||||
public Vector getDirection() {
|
||||
Vector vector = new Vector();
|
||||
|
||||
double rotX = this.getYaw();
|
||||
double rotY = this.getPitch();
|
||||
|
||||
vector.setY(-Math.sin(Math.toRadians(rotY)));
|
||||
|
||||
double xz = Math.cos(Math.toRadians(rotY));
|
||||
|
||||
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
|
||||
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link #getYaw() yaw} and {@link #getPitch() pitch} to point
|
||||
* in the direction of the vector.
|
||||
*
|
||||
* @param vector the direction vector
|
||||
* @return the same location
|
||||
*/
|
||||
public Location setDirection(Vector vector) {
|
||||
/*
|
||||
* Sin = Opp / Hyp
|
||||
* Cos = Adj / Hyp
|
||||
* Tan = Opp / Adj
|
||||
*
|
||||
* x = -Opp
|
||||
* z = Adj
|
||||
*/
|
||||
final double _2PI = 2 * Math.PI;
|
||||
final double x = vector.getX();
|
||||
final double z = vector.getZ();
|
||||
|
||||
if (x == 0 && z == 0) {
|
||||
pitch = vector.getY() > 0 ? -90 : 90;
|
||||
return this;
|
||||
}
|
||||
|
||||
double theta = Math.atan2(-x, z);
|
||||
yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
|
||||
|
||||
double x2 = NumberConversions.square(x);
|
||||
double z2 = NumberConversions.square(z);
|
||||
double xz = Math.sqrt(x2 + z2);
|
||||
pitch = (float) Math.toDegrees(Math.atan(-vector.getY() / xz));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the location by another.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec The other location
|
||||
* @return the same location
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
*/
|
||||
public Location add(Location vec) {
|
||||
if (vec == null || vec.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot add Locations of differing worlds");
|
||||
}
|
||||
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
z += vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the location by a vector.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec Vector to use
|
||||
* @return the same location
|
||||
*/
|
||||
public Location add(Vector vec) {
|
||||
this.x += vec.getX();
|
||||
this.y += vec.getY();
|
||||
this.z += vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the location by another. Not world-aware.
|
||||
*
|
||||
* @see Vector
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return the same location
|
||||
*/
|
||||
public Location add(double x, double y, double z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the location by another.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec The other location
|
||||
* @return the same location
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
*/
|
||||
public Location subtract(Location vec) {
|
||||
if (vec == null || vec.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot add Locations of differing worlds");
|
||||
}
|
||||
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
z -= vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the location by a vector.
|
||||
*
|
||||
* @see Vector
|
||||
* @param vec The vector to use
|
||||
* @return the same location
|
||||
*/
|
||||
public Location subtract(Vector vec) {
|
||||
this.x -= vec.getX();
|
||||
this.y -= vec.getY();
|
||||
this.z -= vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the location by another. Not world-aware and
|
||||
* orientation independent.
|
||||
*
|
||||
* @see Vector
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @return the same location
|
||||
*/
|
||||
public Location subtract(double x, double y, double z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The
|
||||
* value of this method is not cached and uses a costly square-root
|
||||
* function, so do not repeatedly call this method to get the location's
|
||||
* magnitude. NaN will be returned if the inner result of the sqrt()
|
||||
* function overflows, which will be caused if the length is too long. Not
|
||||
* world-aware and orientation independent.
|
||||
*
|
||||
* @see Vector
|
||||
* @return the magnitude
|
||||
*/
|
||||
public double length() {
|
||||
return Math.sqrt(NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the magnitude of the location squared. Not world-aware and
|
||||
* orientation independent.
|
||||
*
|
||||
* @see Vector
|
||||
* @return the magnitude
|
||||
*/
|
||||
public double lengthSquared() {
|
||||
return NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance between this location and another. The value of this
|
||||
* method is not cached and uses a costly square-root function, so do not
|
||||
* repeatedly call this method to get the location's magnitude. NaN will
|
||||
* be returned if the inner result of the sqrt() function overflows, which
|
||||
* will be caused if the distance is too long.
|
||||
*
|
||||
* @see Vector
|
||||
* @param o The other location
|
||||
* @return the distance
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
*/
|
||||
public double distance(Location o) {
|
||||
return Math.sqrt(distanceSquared(o));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the squared distance between this location and another.
|
||||
*
|
||||
* @see Vector
|
||||
* @param o The other location
|
||||
* @return the distance
|
||||
* @throws IllegalArgumentException for differing worlds
|
||||
*/
|
||||
public double distanceSquared(Location o) {
|
||||
if (o == null) {
|
||||
throw new IllegalArgumentException("Cannot measure distance to a null location");
|
||||
} else if (o.getWorld() == null || getWorld() == null) {
|
||||
throw new IllegalArgumentException("Cannot measure distance to a null world");
|
||||
} else if (o.getWorld() != getWorld()) {
|
||||
throw new IllegalArgumentException("Cannot measure distance between " + getWorld().getName() + " and " + o.getWorld().getName());
|
||||
}
|
||||
|
||||
return NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs scalar multiplication, multiplying all components with a
|
||||
* scalar. Not world-aware.
|
||||
*
|
||||
* @param m The factor
|
||||
* @see Vector
|
||||
* @return the same location
|
||||
*/
|
||||
public Location multiply(double m) {
|
||||
x *= m;
|
||||
y *= m;
|
||||
z *= m;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero this location's components. Not world-aware.
|
||||
*
|
||||
* @see Vector
|
||||
* @return the same location
|
||||
*/
|
||||
public Location zero() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Location other = (Location) obj;
|
||||
|
||||
if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(this.y) != Double.doubleToLongBits(other.y)) {
|
||||
return false;
|
||||
}
|
||||
if (Double.doubleToLongBits(this.z) != Double.doubleToLongBits(other.z)) {
|
||||
return false;
|
||||
}
|
||||
if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) {
|
||||
return false;
|
||||
}
|
||||
if (Float.floatToIntBits(this.yaw) != Float.floatToIntBits(other.yaw)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
|
||||
hash = 19 * hash + (this.world != null ? this.world.hashCode() : 0);
|
||||
hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
|
||||
hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
|
||||
hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
|
||||
hash = 19 * hash + Float.floatToIntBits(this.pitch);
|
||||
hash = 19 * hash + Float.floatToIntBits(this.yaw);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Vector} based on this Location
|
||||
*
|
||||
* @return New Vector containing the coordinates represented by this
|
||||
* Location
|
||||
*/
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location clone() {
|
||||
try {
|
||||
return (Location) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely converts a double (location coordinate) to an int (block
|
||||
* coordinate)
|
||||
*
|
||||
* @param loc Precise coordinate
|
||||
* @return Block coordinate
|
||||
*/
|
||||
public static int locToBlock(double loc) {
|
||||
return NumberConversions.floor(loc);
|
||||
}
|
||||
|
||||
@Utility
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
data.put("world", this.world.getName());
|
||||
|
||||
data.put("x", this.x);
|
||||
data.put("y", this.y);
|
||||
data.put("z", this.z);
|
||||
|
||||
data.put("yaw", this.yaw);
|
||||
data.put("pitch", this.pitch);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required method for deserialization
|
||||
*
|
||||
* @param args map to deserialize
|
||||
* @return deserialized location
|
||||
* @throws IllegalArgumentException if the world don't exists
|
||||
* @see ConfigurationSerializable
|
||||
*/
|
||||
public static Location deserialize(Map<String, Object> args) {
|
||||
World world = Bukkit.getWorld((String) args.get("world"));
|
||||
if (world == null) {
|
||||
throw new IllegalArgumentException("unknown world");
|
||||
}
|
||||
|
||||
return new Location(world, NumberConversions.toDouble(args.get("x")), NumberConversions.toDouble(args.get("y")), NumberConversions.toDouble(args.get("z")), NumberConversions.toFloat(args.get("yaw")), NumberConversions.toFloat(args.get("pitch")));
|
||||
}
|
||||
}
|
1143
TacoSpigot-API/src/main/java/org/bukkit/Material.java
Normal file
1143
TacoSpigot-API/src/main/java/org/bukkit/Material.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
|
||||
package org.bukkit;
|
||||
|
||||
public enum NetherWartsState {
|
||||
|
||||
/**
|
||||
* State when first seeded
|
||||
*/
|
||||
SEEDED,
|
||||
/**
|
||||
* First growth stage
|
||||
*/
|
||||
STAGE_ONE,
|
||||
/**
|
||||
* Second growth stage
|
||||
*/
|
||||
STAGE_TWO,
|
||||
/**
|
||||
* Ready to harvest
|
||||
*/
|
||||
RIPE;
|
||||
}
|
276
TacoSpigot-API/src/main/java/org/bukkit/Note.java
Normal file
276
TacoSpigot-API/src/main/java/org/bukkit/Note.java
Normal file
@ -0,0 +1,276 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* A note class to store a specific note.
|
||||
*/
|
||||
public class Note {
|
||||
|
||||
/**
|
||||
* An enum holding tones.
|
||||
*/
|
||||
public enum Tone {
|
||||
G(0x1, true),
|
||||
A(0x3, true),
|
||||
B(0x5, false),
|
||||
C(0x6, true),
|
||||
D(0x8, true),
|
||||
E(0xA, false),
|
||||
F(0xB, true);
|
||||
|
||||
private final boolean sharpable;
|
||||
private final byte id;
|
||||
|
||||
private static final Map<Byte, Note.Tone> BY_DATA = Maps.newHashMap();
|
||||
/** The number of tones including sharped tones. */
|
||||
public static final byte TONES_COUNT = 12;
|
||||
|
||||
private Tone(int id, boolean sharpable) {
|
||||
this.id = (byte) (id % TONES_COUNT);
|
||||
this.sharpable = sharpable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the not sharped id of this tone.
|
||||
*
|
||||
* @return the not sharped id of this tone.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getId() {
|
||||
return getId(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of this tone. These method allows to return the
|
||||
* sharped id of the tone. If the tone couldn't be sharped it always
|
||||
* return the not sharped id of this tone.
|
||||
*
|
||||
* @param sharped Set to true to return the sharped id.
|
||||
* @return the id of this tone.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getId(boolean sharped) {
|
||||
byte id = (byte) (sharped && sharpable ? this.id + 1 : this.id);
|
||||
|
||||
return (byte) (id % TONES_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if this tone could be sharped.
|
||||
*
|
||||
* @return if this tone could be sharped.
|
||||
*/
|
||||
public boolean isSharpable() {
|
||||
return sharpable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if this tone id is the sharped id of the tone.
|
||||
*
|
||||
* @param id the id of the tone.
|
||||
* @return if the tone id is the sharped id of the tone.
|
||||
* @throws IllegalArgumentException if neither the tone nor the
|
||||
* semitone have the id.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isSharped(byte id) {
|
||||
if (id == getId(false)) {
|
||||
return false;
|
||||
} else if (id == getId(true)) {
|
||||
return true;
|
||||
} else {
|
||||
// The id isn't matching to the tone!
|
||||
throw new IllegalArgumentException("The id isn't matching to the tone.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tone to id. Also returning the semitones.
|
||||
*
|
||||
* @param id the id of the tone.
|
||||
* @return the tone to id.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static Tone getById(byte id) {
|
||||
return BY_DATA.get(id);
|
||||
}
|
||||
|
||||
static {
|
||||
for (Tone tone : values()) {
|
||||
int id = tone.id % TONES_COUNT;
|
||||
BY_DATA.put((byte) id, tone);
|
||||
|
||||
if (tone.isSharpable()) {
|
||||
id = (id + 1) % TONES_COUNT;
|
||||
BY_DATA.put((byte) id, tone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final byte note;
|
||||
|
||||
/**
|
||||
* Creates a new note.
|
||||
*
|
||||
* @param note Internal note id. {@link #getId()} always return this
|
||||
* value. The value has to be in the interval [0; 24].
|
||||
*/
|
||||
public Note(int note) {
|
||||
Validate.isTrue(note >= 0 && note <= 24, "The note value has to be between 0 and 24.");
|
||||
|
||||
this.note = (byte) note;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new note.
|
||||
*
|
||||
* @param octave The octave where the note is in. Has to be 0 - 2.
|
||||
* @param tone The tone within the octave. If the octave is 2 the note has
|
||||
* to be F#.
|
||||
* @param sharped Set if the tone is sharped (e.g. for F#).
|
||||
*/
|
||||
public Note(int octave, Tone tone, boolean sharped) {
|
||||
if (sharped && !tone.isSharpable()) {
|
||||
tone = Tone.values()[tone.ordinal() + 1];
|
||||
sharped = false;
|
||||
}
|
||||
if (octave < 0 || octave > 2 || (octave == 2 && !(tone == Tone.F && sharped))) {
|
||||
throw new IllegalArgumentException("Tone and octave have to be between F#0 and F#2");
|
||||
}
|
||||
|
||||
this.note = (byte) (octave * Tone.TONES_COUNT + tone.getId(sharped));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new note for a flat tone, such as A-flat.
|
||||
*
|
||||
* @param octave The octave where the note is in. Has to be 0 - 1.
|
||||
* @param tone The tone within the octave.
|
||||
* @return The new note.
|
||||
*/
|
||||
public static Note flat(int octave, Tone tone) {
|
||||
Validate.isTrue(octave != 2, "Octave cannot be 2 for flats");
|
||||
tone = tone == Tone.G ? Tone.F : Tone.values()[tone.ordinal() - 1];
|
||||
return new Note(octave, tone, tone.isSharpable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new note for a sharp tone, such as A-sharp.
|
||||
*
|
||||
* @param octave The octave where the note is in. Has to be 0 - 2.
|
||||
* @param tone The tone within the octave. If the octave is 2 the note has
|
||||
* to be F#.
|
||||
* @return The new note.
|
||||
*/
|
||||
public static Note sharp(int octave, Tone tone) {
|
||||
return new Note(octave, tone, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new note for a natural tone, such as A-natural.
|
||||
*
|
||||
* @param octave The octave where the note is in. Has to be 0 - 1.
|
||||
* @param tone The tone within the octave.
|
||||
* @return The new note.
|
||||
*/
|
||||
public static Note natural(int octave, Tone tone) {
|
||||
Validate.isTrue(octave != 2, "Octave cannot be 2 for naturals");
|
||||
return new Note(octave, tone, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The note a semitone above this one.
|
||||
*/
|
||||
public Note sharped() {
|
||||
Validate.isTrue(note < 24, "This note cannot be sharped because it is the highest known note!");
|
||||
return new Note(note + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The note a semitone below this one.
|
||||
*/
|
||||
public Note flattened() {
|
||||
Validate.isTrue(note > 0, "This note cannot be flattened because it is the lowest known note!");
|
||||
return new Note(note - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal id of this note.
|
||||
*
|
||||
* @return the internal id of this note.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getId() {
|
||||
return note;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the octave of this note.
|
||||
*
|
||||
* @return the octave of this note.
|
||||
*/
|
||||
public int getOctave() {
|
||||
return note / Tone.TONES_COUNT;
|
||||
}
|
||||
|
||||
private byte getToneByte() {
|
||||
return (byte) (note % Tone.TONES_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tone of this note.
|
||||
*
|
||||
* @return the tone of this note.
|
||||
*/
|
||||
public Tone getTone() {
|
||||
return Tone.getById(getToneByte());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if this note is sharped.
|
||||
*
|
||||
* @return if this note is sharped.
|
||||
*/
|
||||
public boolean isSharped() {
|
||||
byte note = getToneByte();
|
||||
return Tone.getById(note).isSharped(note);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + note;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Note other = (Note) obj;
|
||||
if (note != other.note)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Note{" + getTone().toString() + (isSharped() ? "#" : "") + "}";
|
||||
}
|
||||
}
|
118
TacoSpigot-API/src/main/java/org/bukkit/OfflinePlayer.java
Normal file
118
TacoSpigot-API/src/main/java/org/bukkit/OfflinePlayer.java
Normal file
@ -0,0 +1,118 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.ServerOperator;
|
||||
|
||||
public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable {
|
||||
|
||||
/**
|
||||
* Checks if this player is currently online
|
||||
*
|
||||
* @return true if they are online
|
||||
*/
|
||||
public boolean isOnline();
|
||||
|
||||
/**
|
||||
* Returns the name of this player
|
||||
* <p>
|
||||
* Names are no longer unique past a single game session. For persistent storage
|
||||
* it is recommended that you use {@link #getUniqueId()} instead.
|
||||
*
|
||||
* @return Player name or null if we have not seen a name for this player yet
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns the UUID of this player
|
||||
*
|
||||
* @return Player UUID
|
||||
*/
|
||||
public UUID getUniqueId();
|
||||
|
||||
/**
|
||||
* Checks if this player is banned or not
|
||||
*
|
||||
* @return true if banned, otherwise false
|
||||
*/
|
||||
public boolean isBanned();
|
||||
|
||||
/**
|
||||
* Bans or unbans this player
|
||||
*
|
||||
* @param banned true if banned
|
||||
* @deprecated Use {@link org.bukkit.BanList#addBan(String, String, Date,
|
||||
* String)} or {@link org.bukkit.BanList#pardon(String)} to enhance
|
||||
* functionality
|
||||
*/
|
||||
@Deprecated
|
||||
public void setBanned(boolean banned);
|
||||
|
||||
/**
|
||||
* Checks if this player is whitelisted or not
|
||||
*
|
||||
* @return true if whitelisted
|
||||
*/
|
||||
public boolean isWhitelisted();
|
||||
|
||||
/**
|
||||
* Sets if this player is whitelisted or not
|
||||
*
|
||||
* @param value true if whitelisted
|
||||
*/
|
||||
public void setWhitelisted(boolean value);
|
||||
|
||||
/**
|
||||
* Gets a {@link Player} object that this represents, if there is one
|
||||
* <p>
|
||||
* If the player is online, this will return that player. Otherwise,
|
||||
* it will return null.
|
||||
*
|
||||
* @return Online player
|
||||
*/
|
||||
public Player getPlayer();
|
||||
|
||||
/**
|
||||
* Gets the first date and time that this player was witnessed on this
|
||||
* server.
|
||||
* <p>
|
||||
* If the player has never played before, this will return 0. Otherwise,
|
||||
* it will be the amount of milliseconds since midnight, January 1, 1970
|
||||
* UTC.
|
||||
*
|
||||
* @return Date of first log-in for this player, or 0
|
||||
*/
|
||||
public long getFirstPlayed();
|
||||
|
||||
/**
|
||||
* Gets the last date and time that this player was witnessed on this
|
||||
* server.
|
||||
* <p>
|
||||
* If the player has never played before, this will return 0. Otherwise,
|
||||
* it will be the amount of milliseconds since midnight, January 1, 1970
|
||||
* UTC.
|
||||
*
|
||||
* @return Date of last log-in for this player, or 0
|
||||
*/
|
||||
public long getLastPlayed();
|
||||
|
||||
/**
|
||||
* Checks if this player has played on this server before.
|
||||
*
|
||||
* @return True if the player has played before, otherwise false
|
||||
*/
|
||||
public boolean hasPlayedBefore();
|
||||
|
||||
/**
|
||||
* Gets the Location where the player will spawn at their bed, null if
|
||||
* they have not slept in one or their current bed spawn is invalid.
|
||||
*
|
||||
* @return Bed Spawn Location if bed exists, otherwise null.
|
||||
*/
|
||||
public Location getBedSpawnLocation();
|
||||
|
||||
}
|
22
TacoSpigot-API/src/main/java/org/bukkit/PortalType.java
Normal file
22
TacoSpigot-API/src/main/java/org/bukkit/PortalType.java
Normal file
@ -0,0 +1,22 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* Represents various types of portals that can be made in a world.
|
||||
*/
|
||||
public enum PortalType {
|
||||
|
||||
/**
|
||||
* This is a Nether portal, made of obsidian.
|
||||
*/
|
||||
NETHER,
|
||||
|
||||
/**
|
||||
* This is an Ender portal.
|
||||
*/
|
||||
ENDER,
|
||||
|
||||
/**
|
||||
* This is a custom Plugin portal.
|
||||
*/
|
||||
CUSTOM;
|
||||
}
|
63
TacoSpigot-API/src/main/java/org/bukkit/Rotation.java
Normal file
63
TacoSpigot-API/src/main/java/org/bukkit/Rotation.java
Normal file
@ -0,0 +1,63 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* An enum to specify a rotation based orientation, like that on a clock.
|
||||
* <p>
|
||||
* It represents how something is viewed, as opposed to cardinal directions.
|
||||
*/
|
||||
public enum Rotation {
|
||||
|
||||
/**
|
||||
* No rotation
|
||||
*/
|
||||
NONE,
|
||||
/**
|
||||
* Rotated clockwise by 45 degrees
|
||||
*/
|
||||
CLOCKWISE_45,
|
||||
/**
|
||||
* Rotated clockwise by 90 degrees
|
||||
*/
|
||||
CLOCKWISE,
|
||||
/**
|
||||
* Rotated clockwise by 135 degrees
|
||||
*/
|
||||
CLOCKWISE_135,
|
||||
/**
|
||||
* Flipped upside-down, a 180 degree rotation
|
||||
*/
|
||||
FLIPPED,
|
||||
/**
|
||||
* Flipped upside-down + 45 degree rotation
|
||||
*/
|
||||
FLIPPED_45,
|
||||
/**
|
||||
* Rotated counter-clockwise by 90 degrees
|
||||
*/
|
||||
COUNTER_CLOCKWISE,
|
||||
/**
|
||||
* Rotated counter-clockwise by 45 degrees
|
||||
*/
|
||||
COUNTER_CLOCKWISE_45
|
||||
;
|
||||
|
||||
private static final Rotation [] rotations = values();
|
||||
|
||||
/**
|
||||
* Rotate clockwise by 90 degrees.
|
||||
*
|
||||
* @return the relative rotation
|
||||
*/
|
||||
public Rotation rotateClockwise() {
|
||||
return rotations[(this.ordinal() + 1) & 0x7];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate counter-clockwise by 90 degrees.
|
||||
*
|
||||
* @return the relative rotation
|
||||
*/
|
||||
public Rotation rotateCounterClockwise() {
|
||||
return rotations[(this.ordinal() - 1) & 0x7];
|
||||
}
|
||||
}
|
51
TacoSpigot-API/src/main/java/org/bukkit/SandstoneType.java
Normal file
51
TacoSpigot-API/src/main/java/org/bukkit/SandstoneType.java
Normal file
@ -0,0 +1,51 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the three different types of Sandstone
|
||||
*/
|
||||
public enum SandstoneType {
|
||||
CRACKED(0x0),
|
||||
GLYPHED(0x1),
|
||||
SMOOTH(0x2);
|
||||
|
||||
private final byte data;
|
||||
private final static Map<Byte, SandstoneType> BY_DATA = Maps.newHashMap();
|
||||
|
||||
private SandstoneType(final int data) {
|
||||
this.data = (byte) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated data value representing this type of sandstone
|
||||
*
|
||||
* @return A byte containing the data value of this sandstone type
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of sandstone with the given data value
|
||||
*
|
||||
* @param data Data value to fetch
|
||||
* @return The {@link SandstoneType} representing the given value, or null
|
||||
* if it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static SandstoneType getByData(final byte data) {
|
||||
return BY_DATA.get(data);
|
||||
}
|
||||
|
||||
static {
|
||||
for (SandstoneType type : values()) {
|
||||
BY_DATA.put(type.data, type);
|
||||
}
|
||||
}
|
||||
}
|
1010
TacoSpigot-API/src/main/java/org/bukkit/Server.java
Normal file
1010
TacoSpigot-API/src/main/java/org/bukkit/Server.java
Normal file
File diff suppressed because it is too large
Load Diff
12
TacoSpigot-API/src/main/java/org/bukkit/SkullType.java
Normal file
12
TacoSpigot-API/src/main/java/org/bukkit/SkullType.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* Represents the different types of skulls.
|
||||
*/
|
||||
public enum SkullType {
|
||||
SKELETON,
|
||||
WITHER,
|
||||
ZOMBIE,
|
||||
PLAYER,
|
||||
CREEPER;
|
||||
}
|
211
TacoSpigot-API/src/main/java/org/bukkit/Sound.java
Normal file
211
TacoSpigot-API/src/main/java/org/bukkit/Sound.java
Normal file
@ -0,0 +1,211 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* An Enum of Sounds the server is able to send to players.
|
||||
* <p>
|
||||
* WARNING: At any time, sounds may be added/removed from this Enum or even
|
||||
* MineCraft itself! There is no guarantee the sounds will play. There is no
|
||||
* guarantee values will not be removed from this Enum. As such, you should
|
||||
* not depend on the ordinal values of this class.
|
||||
*/
|
||||
public enum Sound {
|
||||
AMBIENCE_CAVE,
|
||||
AMBIENCE_RAIN,
|
||||
AMBIENCE_THUNDER,
|
||||
ANVIL_BREAK,
|
||||
ANVIL_LAND,
|
||||
ANVIL_USE,
|
||||
ARROW_HIT,
|
||||
BURP,
|
||||
CHEST_CLOSE,
|
||||
CHEST_OPEN,
|
||||
CLICK,
|
||||
DOOR_CLOSE,
|
||||
DOOR_OPEN,
|
||||
DRINK,
|
||||
EAT,
|
||||
EXPLODE,
|
||||
FALL_BIG,
|
||||
FALL_SMALL,
|
||||
FIRE,
|
||||
FIRE_IGNITE,
|
||||
FIZZ,
|
||||
FUSE,
|
||||
GLASS,
|
||||
HURT_FLESH,
|
||||
ITEM_BREAK,
|
||||
ITEM_PICKUP,
|
||||
LAVA,
|
||||
LAVA_POP,
|
||||
LEVEL_UP,
|
||||
MINECART_BASE,
|
||||
MINECART_INSIDE,
|
||||
NOTE_BASS,
|
||||
NOTE_PIANO,
|
||||
NOTE_BASS_DRUM,
|
||||
NOTE_STICKS,
|
||||
NOTE_BASS_GUITAR,
|
||||
NOTE_SNARE_DRUM,
|
||||
NOTE_PLING,
|
||||
ORB_PICKUP,
|
||||
PISTON_EXTEND,
|
||||
PISTON_RETRACT,
|
||||
PORTAL,
|
||||
PORTAL_TRAVEL,
|
||||
PORTAL_TRIGGER,
|
||||
SHOOT_ARROW,
|
||||
SPLASH,
|
||||
SPLASH2,
|
||||
STEP_GRASS,
|
||||
STEP_GRAVEL,
|
||||
STEP_LADDER,
|
||||
STEP_SAND,
|
||||
STEP_SNOW,
|
||||
STEP_STONE,
|
||||
STEP_WOOD,
|
||||
STEP_WOOL,
|
||||
SWIM,
|
||||
WATER,
|
||||
WOOD_CLICK,
|
||||
// Mob sounds
|
||||
BAT_DEATH,
|
||||
BAT_HURT,
|
||||
BAT_IDLE,
|
||||
BAT_LOOP,
|
||||
BAT_TAKEOFF,
|
||||
BLAZE_BREATH,
|
||||
BLAZE_DEATH,
|
||||
BLAZE_HIT,
|
||||
CAT_HISS,
|
||||
CAT_HIT,
|
||||
CAT_MEOW,
|
||||
CAT_PURR,
|
||||
CAT_PURREOW,
|
||||
CHICKEN_IDLE,
|
||||
CHICKEN_HURT,
|
||||
CHICKEN_EGG_POP,
|
||||
CHICKEN_WALK,
|
||||
COW_IDLE,
|
||||
COW_HURT,
|
||||
COW_WALK,
|
||||
CREEPER_HISS,
|
||||
CREEPER_DEATH,
|
||||
ENDERDRAGON_DEATH,
|
||||
ENDERDRAGON_GROWL,
|
||||
ENDERDRAGON_HIT,
|
||||
ENDERDRAGON_WINGS,
|
||||
ENDERMAN_DEATH,
|
||||
ENDERMAN_HIT,
|
||||
ENDERMAN_IDLE,
|
||||
ENDERMAN_TELEPORT,
|
||||
ENDERMAN_SCREAM,
|
||||
ENDERMAN_STARE,
|
||||
GHAST_SCREAM,
|
||||
GHAST_SCREAM2,
|
||||
GHAST_CHARGE,
|
||||
GHAST_DEATH,
|
||||
GHAST_FIREBALL,
|
||||
GHAST_MOAN,
|
||||
IRONGOLEM_DEATH,
|
||||
IRONGOLEM_HIT,
|
||||
IRONGOLEM_THROW,
|
||||
IRONGOLEM_WALK,
|
||||
MAGMACUBE_WALK,
|
||||
MAGMACUBE_WALK2,
|
||||
MAGMACUBE_JUMP,
|
||||
PIG_IDLE,
|
||||
PIG_DEATH,
|
||||
PIG_WALK,
|
||||
SHEEP_IDLE,
|
||||
SHEEP_SHEAR,
|
||||
SHEEP_WALK,
|
||||
SILVERFISH_HIT,
|
||||
SILVERFISH_KILL,
|
||||
SILVERFISH_IDLE,
|
||||
SILVERFISH_WALK,
|
||||
SKELETON_IDLE,
|
||||
SKELETON_DEATH,
|
||||
SKELETON_HURT,
|
||||
SKELETON_WALK,
|
||||
SLIME_ATTACK,
|
||||
SLIME_WALK,
|
||||
SLIME_WALK2,
|
||||
SPIDER_IDLE,
|
||||
SPIDER_DEATH,
|
||||
SPIDER_WALK,
|
||||
WITHER_DEATH,
|
||||
WITHER_HURT,
|
||||
WITHER_IDLE,
|
||||
WITHER_SHOOT,
|
||||
WITHER_SPAWN,
|
||||
WOLF_BARK,
|
||||
WOLF_DEATH,
|
||||
WOLF_GROWL,
|
||||
WOLF_HOWL,
|
||||
WOLF_HURT,
|
||||
WOLF_PANT,
|
||||
WOLF_SHAKE,
|
||||
WOLF_WALK,
|
||||
WOLF_WHINE,
|
||||
ZOMBIE_METAL,
|
||||
ZOMBIE_WOOD,
|
||||
ZOMBIE_WOODBREAK,
|
||||
ZOMBIE_IDLE,
|
||||
ZOMBIE_DEATH,
|
||||
ZOMBIE_HURT,
|
||||
ZOMBIE_INFECT,
|
||||
ZOMBIE_UNFECT,
|
||||
ZOMBIE_REMEDY,
|
||||
ZOMBIE_WALK,
|
||||
ZOMBIE_PIG_IDLE,
|
||||
ZOMBIE_PIG_ANGRY,
|
||||
ZOMBIE_PIG_DEATH,
|
||||
ZOMBIE_PIG_HURT,
|
||||
// Dig Sounds
|
||||
DIG_WOOL,
|
||||
DIG_GRASS,
|
||||
DIG_GRAVEL,
|
||||
DIG_SAND,
|
||||
DIG_SNOW,
|
||||
DIG_STONE,
|
||||
DIG_WOOD,
|
||||
// Fireworks
|
||||
FIREWORK_BLAST,
|
||||
FIREWORK_BLAST2,
|
||||
FIREWORK_LARGE_BLAST,
|
||||
FIREWORK_LARGE_BLAST2,
|
||||
FIREWORK_TWINKLE,
|
||||
FIREWORK_TWINKLE2,
|
||||
FIREWORK_LAUNCH,
|
||||
SUCCESSFUL_HIT,
|
||||
// Horses
|
||||
HORSE_ANGRY,
|
||||
HORSE_ARMOR,
|
||||
HORSE_BREATHE,
|
||||
HORSE_DEATH,
|
||||
HORSE_GALLOP,
|
||||
HORSE_HIT,
|
||||
HORSE_IDLE,
|
||||
HORSE_JUMP,
|
||||
HORSE_LAND,
|
||||
HORSE_SADDLE,
|
||||
HORSE_SOFT,
|
||||
HORSE_WOOD,
|
||||
DONKEY_ANGRY,
|
||||
DONKEY_DEATH,
|
||||
DONKEY_HIT,
|
||||
DONKEY_IDLE,
|
||||
HORSE_SKELETON_DEATH,
|
||||
HORSE_SKELETON_HIT,
|
||||
HORSE_SKELETON_IDLE,
|
||||
HORSE_ZOMBIE_DEATH,
|
||||
HORSE_ZOMBIE_HIT,
|
||||
HORSE_ZOMBIE_IDLE,
|
||||
// Villager
|
||||
VILLAGER_DEATH,
|
||||
VILLAGER_HAGGLE,
|
||||
VILLAGER_HIT,
|
||||
VILLAGER_IDLE,
|
||||
VILLAGER_NO,
|
||||
VILLAGER_YES,
|
||||
}
|
133
TacoSpigot-API/src/main/java/org/bukkit/Statistic.java
Normal file
133
TacoSpigot-API/src/main/java/org/bukkit/Statistic.java
Normal file
@ -0,0 +1,133 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* Represents a countable statistic, which is tracked by the server.
|
||||
*/
|
||||
public enum Statistic {
|
||||
DAMAGE_DEALT,
|
||||
DAMAGE_TAKEN,
|
||||
DEATHS,
|
||||
MOB_KILLS,
|
||||
PLAYER_KILLS,
|
||||
FISH_CAUGHT,
|
||||
ANIMALS_BRED,
|
||||
TREASURE_FISHED,
|
||||
JUNK_FISHED,
|
||||
LEAVE_GAME,
|
||||
JUMP,
|
||||
DROP,
|
||||
PLAY_ONE_TICK,
|
||||
WALK_ONE_CM,
|
||||
SWIM_ONE_CM,
|
||||
FALL_ONE_CM,
|
||||
CLIMB_ONE_CM,
|
||||
FLY_ONE_CM,
|
||||
DIVE_ONE_CM,
|
||||
MINECART_ONE_CM,
|
||||
BOAT_ONE_CM,
|
||||
PIG_ONE_CM,
|
||||
HORSE_ONE_CM,
|
||||
SPRINT_ONE_CM,
|
||||
CROUCH_ONE_CM,
|
||||
MINE_BLOCK(Type.BLOCK),
|
||||
USE_ITEM(Type.ITEM),
|
||||
BREAK_ITEM(Type.ITEM),
|
||||
CRAFT_ITEM(Type.ITEM),
|
||||
KILL_ENTITY(Type.ENTITY),
|
||||
ENTITY_KILLED_BY(Type.ENTITY),
|
||||
TIME_SINCE_DEATH,
|
||||
TALKED_TO_VILLAGER,
|
||||
TRADED_WITH_VILLAGER,
|
||||
CAKE_SLICES_EATEN,
|
||||
CAULDRON_FILLED,
|
||||
CAULDRON_USED,
|
||||
ARMOR_CLEANED,
|
||||
BANNER_CLEANED,
|
||||
BREWINGSTAND_INTERACTION,
|
||||
BEACON_INTERACTION,
|
||||
DROPPER_INSPECTED,
|
||||
HOPPER_INSPECTED,
|
||||
DISPENSER_INSPECTED,
|
||||
NOTEBLOCK_PLAYED,
|
||||
NOTEBLOCK_TUNED,
|
||||
FLOWER_POTTED,
|
||||
TRAPPED_CHEST_TRIGGERED,
|
||||
ENDERCHEST_OPENED,
|
||||
ITEM_ENCHANTED,
|
||||
RECORD_PLAYED,
|
||||
FURNACE_INTERACTION,
|
||||
CRAFTING_TABLE_INTERACTION,
|
||||
CHEST_OPENED;
|
||||
|
||||
private final Type type;
|
||||
|
||||
private Statistic() {
|
||||
this(Type.UNTYPED);
|
||||
}
|
||||
|
||||
private Statistic(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of this statistic.
|
||||
*
|
||||
* @return the type of this statistic
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a substatistic.
|
||||
* <p>
|
||||
* A substatistic exists en masse for each block, item, or entitytype, depending on
|
||||
* {@link #getType()}.
|
||||
* <p>
|
||||
* This is a redundant method and equivalent to checking
|
||||
* <code>getType() != Type.UNTYPED</code>
|
||||
*
|
||||
* @return true if this is a substatistic
|
||||
*/
|
||||
public boolean isSubstatistic() {
|
||||
return type != Type.UNTYPED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a substatistic dealing with blocks.
|
||||
* <p>
|
||||
* This is a redundant method and equivalent to checking
|
||||
* <code>getType() == Type.BLOCK</code>
|
||||
*
|
||||
* @return true if this deals with blocks
|
||||
*/
|
||||
public boolean isBlock() {
|
||||
return type == Type.BLOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of statistic.
|
||||
*
|
||||
*/
|
||||
public enum Type {
|
||||
/**
|
||||
* Statistics of this type do not require a qualifier.
|
||||
*/
|
||||
UNTYPED,
|
||||
|
||||
/**
|
||||
* Statistics of this type require an Item Material qualifier.
|
||||
*/
|
||||
ITEM,
|
||||
|
||||
/**
|
||||
* Statistics of this type require a Block Material qualifier.
|
||||
*/
|
||||
BLOCK,
|
||||
|
||||
/**
|
||||
* Statistics of this type require an EntityType qualifier.
|
||||
*/
|
||||
ENTITY;
|
||||
}
|
||||
}
|
94
TacoSpigot-API/src/main/java/org/bukkit/TravelAgent.java
Normal file
94
TacoSpigot-API/src/main/java/org/bukkit/TravelAgent.java
Normal file
@ -0,0 +1,94 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* The Travel Agent handles the creation and the research of Nether and End
|
||||
* portals when Entities try to use one.
|
||||
* <p>
|
||||
* It is used in {@link org.bukkit.event.entity.EntityPortalEvent} and in
|
||||
* {@link org.bukkit.event.player.PlayerPortalEvent} to help developers
|
||||
* reproduce and/or modify Vanilla behaviour.
|
||||
*/
|
||||
public interface TravelAgent {
|
||||
|
||||
/**
|
||||
* Set the Block radius to search in for available portals.
|
||||
*
|
||||
* @param radius the radius in which to search for a portal from the
|
||||
* location
|
||||
* @return this travel agent
|
||||
*/
|
||||
public TravelAgent setSearchRadius(int radius);
|
||||
|
||||
/**
|
||||
* Gets the search radius value for finding an available portal.
|
||||
*
|
||||
* @return the currently set search radius
|
||||
*/
|
||||
public int getSearchRadius();
|
||||
|
||||
/**
|
||||
* Sets the maximum radius from the given location to create a portal.
|
||||
*
|
||||
* @param radius the radius in which to create a portal from the location
|
||||
* @return this travel agent
|
||||
*/
|
||||
public TravelAgent setCreationRadius(int radius);
|
||||
|
||||
/**
|
||||
* Gets the maximum radius from the given location to create a portal.
|
||||
*
|
||||
* @return the currently set creation radius
|
||||
*/
|
||||
public int getCreationRadius();
|
||||
|
||||
/**
|
||||
* Returns whether the TravelAgent will attempt to create a destination
|
||||
* portal or not.
|
||||
*
|
||||
* @return whether the TravelAgent should create a destination portal or
|
||||
* not
|
||||
*/
|
||||
public boolean getCanCreatePortal();
|
||||
|
||||
/**
|
||||
* Sets whether the TravelAgent should attempt to create a destination
|
||||
* portal or not.
|
||||
*
|
||||
* @param create Sets whether the TravelAgent should create a destination
|
||||
* portal or not
|
||||
*/
|
||||
public void setCanCreatePortal(boolean create);
|
||||
|
||||
/**
|
||||
* Attempt to find a portal near the given location, if a portal is not
|
||||
* found it will attempt to create one.
|
||||
*
|
||||
* @param location the location where the search for a portal should begin
|
||||
* @return the location of a portal which has been found or returns the
|
||||
* location passed to the method if unsuccessful
|
||||
* @see #createPortal(Location)
|
||||
*/
|
||||
public Location findOrCreate(Location location);
|
||||
|
||||
/**
|
||||
* Attempt to find a portal near the given location.
|
||||
*
|
||||
* @param location the desired location of the portal
|
||||
* @return the location of the nearest portal to the location
|
||||
*/
|
||||
public Location findPortal(Location location);
|
||||
|
||||
/**
|
||||
* Attempt to create a portal near the given location.
|
||||
* <p>
|
||||
* In the case of a Nether portal teleportation, this will attempt to
|
||||
* create a Nether portal.
|
||||
* <p>
|
||||
* In the case of an Ender portal teleportation, this will (re-)create the
|
||||
* obsidian platform and clean blocks above it.
|
||||
*
|
||||
* @param location the desired location of the portal
|
||||
* @return true if a portal was successfully created
|
||||
*/
|
||||
public boolean createPortal(Location location);
|
||||
}
|
74
TacoSpigot-API/src/main/java/org/bukkit/TreeSpecies.java
Normal file
74
TacoSpigot-API/src/main/java/org/bukkit/TreeSpecies.java
Normal file
@ -0,0 +1,74 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Represents the different species of trees regardless of size.
|
||||
*/
|
||||
public enum TreeSpecies {
|
||||
|
||||
/**
|
||||
* Represents the common tree species.
|
||||
*/
|
||||
GENERIC(0x0),
|
||||
/**
|
||||
* Represents the darker barked/leaved tree species.
|
||||
*/
|
||||
REDWOOD(0x1),
|
||||
/**
|
||||
* Represents birches.
|
||||
*/
|
||||
BIRCH(0x2),
|
||||
/**
|
||||
* Represents jungle trees.
|
||||
*/
|
||||
JUNGLE(0x3),
|
||||
/**
|
||||
* Represents acacia trees.
|
||||
*/
|
||||
ACACIA(0x4),
|
||||
/**
|
||||
* Represents dark oak trees.
|
||||
*/
|
||||
DARK_OAK(0x5),
|
||||
;
|
||||
|
||||
private final byte data;
|
||||
private final static Map<Byte, TreeSpecies> BY_DATA = Maps.newHashMap();
|
||||
|
||||
private TreeSpecies(final int data) {
|
||||
this.data = (byte) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated data value representing this species
|
||||
*
|
||||
* @return A byte containing the data value of this tree species
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TreeSpecies with the given data value
|
||||
*
|
||||
* @param data Data value to fetch
|
||||
* @return The {@link TreeSpecies} representing the given value, or null
|
||||
* if it doesn't exist
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static TreeSpecies getByData(final byte data) {
|
||||
return BY_DATA.get(data);
|
||||
}
|
||||
|
||||
static {
|
||||
for (TreeSpecies species : values()) {
|
||||
BY_DATA.put(species.data, species);
|
||||
}
|
||||
}
|
||||
}
|
72
TacoSpigot-API/src/main/java/org/bukkit/TreeType.java
Normal file
72
TacoSpigot-API/src/main/java/org/bukkit/TreeType.java
Normal file
@ -0,0 +1,72 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* Tree and organic structure types.
|
||||
*/
|
||||
public enum TreeType {
|
||||
|
||||
/**
|
||||
* Regular tree, no branches
|
||||
*/
|
||||
TREE,
|
||||
/**
|
||||
* Regular tree, extra tall with branches
|
||||
*/
|
||||
BIG_TREE,
|
||||
/**
|
||||
* Redwood tree, shaped like a pine tree
|
||||
*/
|
||||
REDWOOD,
|
||||
/**
|
||||
* Tall redwood tree with just a few leaves at the top
|
||||
*/
|
||||
TALL_REDWOOD,
|
||||
/**
|
||||
* Birch tree
|
||||
*/
|
||||
BIRCH,
|
||||
/**
|
||||
* Standard jungle tree; 4 blocks wide and tall
|
||||
*/
|
||||
JUNGLE,
|
||||
/**
|
||||
* Smaller jungle tree; 1 block wide
|
||||
*/
|
||||
SMALL_JUNGLE,
|
||||
/**
|
||||
* Jungle tree with cocoa plants; 1 block wide
|
||||
*/
|
||||
COCOA_TREE,
|
||||
/**
|
||||
* Small bush that grows in the jungle
|
||||
*/
|
||||
JUNGLE_BUSH,
|
||||
/**
|
||||
* Big red mushroom; short and fat
|
||||
*/
|
||||
RED_MUSHROOM,
|
||||
/**
|
||||
* Big brown mushroom; tall and umbrella-like
|
||||
*/
|
||||
BROWN_MUSHROOM,
|
||||
/**
|
||||
* Swamp tree (regular with vines on the side)
|
||||
*/
|
||||
SWAMP,
|
||||
/**
|
||||
* Acacia tree.
|
||||
*/
|
||||
ACACIA,
|
||||
/**
|
||||
* Dark Oak tree.
|
||||
*/
|
||||
DARK_OAK,
|
||||
/**
|
||||
* Mega redwood tree; 4 blocks wide and tall
|
||||
*/
|
||||
MEGA_REDWOOD,
|
||||
/**
|
||||
* Tall birch tree
|
||||
*/
|
||||
TALL_BIRCH,
|
||||
}
|
33
TacoSpigot-API/src/main/java/org/bukkit/UnsafeValues.java
Normal file
33
TacoSpigot-API/src/main/java/org/bukkit/UnsafeValues.java
Normal file
@ -0,0 +1,33 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* This interface provides value conversions that may be specific to a
|
||||
* runtime, or have arbitrary meaning (read: magic values).
|
||||
* <p>
|
||||
* Their existence and behavior is not guaranteed across future versions. They
|
||||
* may be poorly named, throw exceptions, have misleading parameters, or any
|
||||
* other bad programming practice.
|
||||
* <p>
|
||||
* This interface is unsupported and only for internal use.
|
||||
*
|
||||
* @deprecated Unsupported {@literal &} internal use only
|
||||
*/
|
||||
@Deprecated
|
||||
public interface UnsafeValues {
|
||||
|
||||
Material getMaterialFromInternalName(String name);
|
||||
|
||||
List<String> tabCompleteInternalMaterialName(String token, List<String> completions);
|
||||
|
||||
ItemStack modifyItemStack(ItemStack stack, String arguments);
|
||||
|
||||
Statistic getStatisticFromInternalName(String name);
|
||||
|
||||
Achievement getAchievementFromInternalName(String name);
|
||||
|
||||
List<String> tabCompleteInternalStatisticOrAchievementName(String token, List<String> completions);
|
||||
}
|
18
TacoSpigot-API/src/main/java/org/bukkit/Utility.java
Normal file
18
TacoSpigot-API/src/main/java/org/bukkit/Utility.java
Normal file
@ -0,0 +1,18 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation indicates a method (and sometimes constructor) will chain
|
||||
* its internal operations.
|
||||
* <p>
|
||||
* This is solely meant for identifying methods that don't need to be
|
||||
* overridden / handled manually.
|
||||
*/
|
||||
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Utility {
|
||||
}
|
109
TacoSpigot-API/src/main/java/org/bukkit/Warning.java
Normal file
109
TacoSpigot-API/src/main/java/org/bukkit/Warning.java
Normal file
@ -0,0 +1,109 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* This designates the warning state for a specific item.
|
||||
* <p>
|
||||
* When the server settings dictate 'default' warnings, warnings are printed
|
||||
* if the {@link #value()} is true.
|
||||
*/
|
||||
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Warning {
|
||||
|
||||
/**
|
||||
* This represents the states that server verbose for warnings may be.
|
||||
*/
|
||||
public enum WarningState {
|
||||
|
||||
/**
|
||||
* Indicates all warnings should be printed for deprecated items.
|
||||
*/
|
||||
ON,
|
||||
/**
|
||||
* Indicates no warnings should be printed for deprecated items.
|
||||
*/
|
||||
OFF,
|
||||
/**
|
||||
* Indicates each warning would default to the configured {@link
|
||||
* Warning} annotation, or always if annotation not found.
|
||||
*/
|
||||
DEFAULT;
|
||||
|
||||
private static final Map<String, WarningState> values = ImmutableMap.<String,WarningState>builder()
|
||||
.put("off", OFF)
|
||||
.put("false", OFF)
|
||||
.put("f", OFF)
|
||||
.put("no", OFF)
|
||||
.put("n", OFF)
|
||||
.put("on", ON)
|
||||
.put("true", ON)
|
||||
.put("t", ON)
|
||||
.put("yes", ON)
|
||||
.put("y", ON)
|
||||
.put("", DEFAULT)
|
||||
.put("d", DEFAULT)
|
||||
.put("default", DEFAULT)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* This method checks the provided warning should be printed for this
|
||||
* state
|
||||
*
|
||||
* @param warning The warning annotation added to a deprecated item
|
||||
* @return <ul>
|
||||
* <li>ON is always True
|
||||
* <li>OFF is always false
|
||||
* <li>DEFAULT is false if and only if annotation is not null and
|
||||
* specifies false for {@link Warning#value()}, true otherwise.
|
||||
* </ul>
|
||||
*/
|
||||
public boolean printFor(Warning warning) {
|
||||
if (this == DEFAULT) {
|
||||
return warning == null || warning.value();
|
||||
}
|
||||
return this == ON;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the corresponding warning state for the given
|
||||
* string value.
|
||||
*
|
||||
* @param value The string value to check
|
||||
* @return {@link #DEFAULT} if not found, or the respective
|
||||
* WarningState
|
||||
*/
|
||||
public static WarningState value(final String value) {
|
||||
if (value == null) {
|
||||
return DEFAULT;
|
||||
}
|
||||
WarningState state = values.get(value.toLowerCase());
|
||||
if (state == null) {
|
||||
return DEFAULT;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets if the deprecation warnings when registering events gets
|
||||
* printed when the setting is in the default state.
|
||||
*
|
||||
* @return false normally, or true to encourage warning printout
|
||||
*/
|
||||
boolean value() default false;
|
||||
|
||||
/**
|
||||
* This can provide detailed information on why the event is deprecated.
|
||||
*
|
||||
* @return The reason an event is deprecated
|
||||
*/
|
||||
String reason() default "";
|
||||
}
|
17
TacoSpigot-API/src/main/java/org/bukkit/WeatherType.java
Normal file
17
TacoSpigot-API/src/main/java/org/bukkit/WeatherType.java
Normal file
@ -0,0 +1,17 @@
|
||||
package org.bukkit;
|
||||
|
||||
/**
|
||||
* An enum of all current weather types
|
||||
*/
|
||||
public enum WeatherType {
|
||||
|
||||
/**
|
||||
* Raining or snowing depending on biome.
|
||||
*/
|
||||
DOWNFALL,
|
||||
/**
|
||||
* Clear weather, clouds but no rain.
|
||||
*/
|
||||
CLEAR,
|
||||
;
|
||||
}
|
1330
TacoSpigot-API/src/main/java/org/bukkit/World.java
Normal file
1330
TacoSpigot-API/src/main/java/org/bukkit/World.java
Normal file
File diff suppressed because it is too large
Load Diff
109
TacoSpigot-API/src/main/java/org/bukkit/WorldBorder.java
Normal file
109
TacoSpigot-API/src/main/java/org/bukkit/WorldBorder.java
Normal file
@ -0,0 +1,109 @@
|
||||
package org.bukkit;
|
||||
|
||||
public interface WorldBorder {
|
||||
|
||||
/**
|
||||
* Resets the border to default values.
|
||||
*/
|
||||
public void reset();
|
||||
|
||||
/**
|
||||
* Gets the current side length of the border.
|
||||
*
|
||||
* @return The current side length of the border.
|
||||
*/
|
||||
public double getSize();
|
||||
|
||||
/**
|
||||
* Sets the border to a square region with the specified side length in blocks.
|
||||
*
|
||||
* @param newSize The new size of the border.
|
||||
*/
|
||||
public void setSize(double newSize);
|
||||
|
||||
/**
|
||||
* Sets the border to a square region with the specified side length in blocks.
|
||||
*
|
||||
* @param newSize The new side length of the border.
|
||||
* @param seconds The time in seconds in which the border grows or shrinks from the previous size to that being set.
|
||||
*/
|
||||
public void setSize(double newSize, long seconds);
|
||||
|
||||
/**
|
||||
* Gets the current border center.
|
||||
*
|
||||
* @return The current border center.
|
||||
*/
|
||||
public Location getCenter();
|
||||
|
||||
/**
|
||||
* Sets the new border center.
|
||||
*
|
||||
* @param x The new center x-coordinate.
|
||||
* @param z The new center z-coordinate.
|
||||
*/
|
||||
public void setCenter(double x, double z);
|
||||
|
||||
/**
|
||||
* Sets the new border center.
|
||||
*
|
||||
* @param location The new location of the border center. (Only x/z used)
|
||||
*/
|
||||
public void setCenter(Location location);
|
||||
|
||||
/**
|
||||
* Gets the current border damage buffer.
|
||||
*
|
||||
* @return The current border damage buffer.
|
||||
*/
|
||||
public double getDamageBuffer();
|
||||
|
||||
/**
|
||||
* Sets the amount of blocks a player may safely be outside the border before taking damage.
|
||||
*
|
||||
* @param blocks The amount of blocks. (The default is 5 blocks.)
|
||||
*/
|
||||
public void setDamageBuffer(double blocks);
|
||||
|
||||
/**
|
||||
* Gets the current border damage amount.
|
||||
*
|
||||
* @return The current border damage amount.
|
||||
*/
|
||||
public double getDamageAmount();
|
||||
|
||||
/**
|
||||
* Sets the amount of damage a player takes when outside the border plus the border buffer.
|
||||
*
|
||||
* @param damage The amount of damage. (The default is 0.2 damage per second per block.)
|
||||
*/
|
||||
public void setDamageAmount(double damage);
|
||||
|
||||
/**
|
||||
* Gets the current border warning time in seconds.
|
||||
*
|
||||
* @return The current border warning time in seconds.
|
||||
*/
|
||||
public int getWarningTime();
|
||||
|
||||
/**
|
||||
* Sets the warning time that causes the screen to be tinted red when a contracting border will reach the player within the specified time.
|
||||
*
|
||||
* @param seconds The amount of time in seconds. (The default is 15 seconds.)
|
||||
*/
|
||||
public void setWarningTime(int seconds);
|
||||
|
||||
/**
|
||||
* Gets the current border warning distance.
|
||||
*
|
||||
* @return The current border warning distance.
|
||||
*/
|
||||
public int getWarningDistance();
|
||||
|
||||
/**
|
||||
* Sets the warning distance that causes the screen to be tinted red when the player is within the specified number of blocks from the border.
|
||||
*
|
||||
* @param distance The distance in blocks. (The default is 5 blocks.)
|
||||
*/
|
||||
public void setWarningDistance(int distance);
|
||||
}
|
317
TacoSpigot-API/src/main/java/org/bukkit/WorldCreator.java
Normal file
317
TacoSpigot-API/src/main/java/org/bukkit/WorldCreator.java
Normal file
@ -0,0 +1,317 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.util.Random;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents various types of options that may be used to create a world.
|
||||
*/
|
||||
public class WorldCreator {
|
||||
private final String name;
|
||||
private long seed;
|
||||
private World.Environment environment = World.Environment.NORMAL;
|
||||
private ChunkGenerator generator = null;
|
||||
private WorldType type = WorldType.NORMAL;
|
||||
private boolean generateStructures = true;
|
||||
private String generatorSettings = "";
|
||||
|
||||
/**
|
||||
* Creates an empty WorldCreationOptions for the given world name
|
||||
*
|
||||
* @param name Name of the world that will be created
|
||||
*/
|
||||
public WorldCreator(String name) {
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("World name cannot be null");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
this.seed = (new Random()).nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the options from the specified world
|
||||
*
|
||||
* @param world World to copy options from
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator copy(World world) {
|
||||
if (world == null) {
|
||||
throw new IllegalArgumentException("World cannot be null");
|
||||
}
|
||||
|
||||
seed = world.getSeed();
|
||||
environment = world.getEnvironment();
|
||||
generator = world.getGenerator();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the options from the specified {@link WorldCreator}
|
||||
*
|
||||
* @param creator World creator to copy options from
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator copy(WorldCreator creator) {
|
||||
if (creator == null) {
|
||||
throw new IllegalArgumentException("Creator cannot be null");
|
||||
}
|
||||
|
||||
seed = creator.seed();
|
||||
environment = creator.environment();
|
||||
generator = creator.generator();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the world that is to be loaded or created.
|
||||
*
|
||||
* @return World name
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the seed that will be used to create this world
|
||||
*
|
||||
* @return World seed
|
||||
*/
|
||||
public long seed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the seed that will be used to create this world
|
||||
*
|
||||
* @param seed World seed
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator seed(long seed) {
|
||||
this.seed = seed;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the environment that will be used to create or load the world
|
||||
*
|
||||
* @return World environment
|
||||
*/
|
||||
public World.Environment environment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the environment that will be used to create or load the world
|
||||
*
|
||||
* @param env World environment
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator environment(World.Environment env) {
|
||||
this.environment = env;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the world that will be created or loaded
|
||||
*
|
||||
* @return World type
|
||||
*/
|
||||
public WorldType type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of the world that will be created or loaded
|
||||
*
|
||||
* @param type World type
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator type(WorldType type) {
|
||||
this.type = type;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the generator that will be used to create or load the world.
|
||||
* <p>
|
||||
* This may be null, in which case the "natural" generator for this
|
||||
* environment will be used.
|
||||
*
|
||||
* @return Chunk generator
|
||||
*/
|
||||
public ChunkGenerator generator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the generator that will be used to create or load the world.
|
||||
* <p>
|
||||
* This may be null, in which case the "natural" generator for this
|
||||
* environment will be used.
|
||||
*
|
||||
* @param generator Chunk generator
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator generator(ChunkGenerator generator) {
|
||||
this.generator = generator;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the generator that will be used to create or load the world.
|
||||
* <p>
|
||||
* This may be null, in which case the "natural" generator for this
|
||||
* environment will be used.
|
||||
* <p>
|
||||
* If the generator cannot be found for the given name, the natural
|
||||
* environment generator will be used instead and a warning will be
|
||||
* printed to the console.
|
||||
*
|
||||
* @param generator Name of the generator to use, in "plugin:id" notation
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator generator(String generator) {
|
||||
this.generator = getGeneratorForName(name, generator, Bukkit.getConsoleSender());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the generator that will be used to create or load the world.
|
||||
* <p>
|
||||
* This may be null, in which case the "natural" generator for this
|
||||
* environment will be used.
|
||||
* <p>
|
||||
* If the generator cannot be found for the given name, the natural
|
||||
* environment generator will be used instead and a warning will be
|
||||
* printed to the specified output
|
||||
*
|
||||
* @param generator Name of the generator to use, in "plugin:id" notation
|
||||
* @param output {@link CommandSender} that will receive any error
|
||||
* messages
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator generator(String generator, CommandSender output) {
|
||||
this.generator = getGeneratorForName(name, generator, output);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the generator settings of the world that will be created or loaded
|
||||
*
|
||||
* @param generatorSettings The settings that should be used by the generator
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator generatorSettings(String generatorSettings) {
|
||||
this.generatorSettings = generatorSettings;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the generator settings of the world that will be created or loaded
|
||||
*
|
||||
* @return The settings that should be used by the generator
|
||||
*/
|
||||
public String generatorSettings() {
|
||||
return generatorSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not worlds created or loaded with this creator will
|
||||
* have structures.
|
||||
*
|
||||
* @param generate Whether to generate structures
|
||||
* @return This object, for chaining
|
||||
*/
|
||||
public WorldCreator generateStructures(boolean generate) {
|
||||
this.generateStructures = generate;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not structures will be generated in the world.
|
||||
*
|
||||
* @return True if structures will be generated
|
||||
*/
|
||||
public boolean generateStructures() {
|
||||
return generateStructures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a world with the specified options.
|
||||
* <p>
|
||||
* If the world already exists, it will be loaded from disk and some
|
||||
* options may be ignored.
|
||||
*
|
||||
* @return Newly created or loaded world
|
||||
*/
|
||||
public World createWorld() {
|
||||
return Bukkit.createWorld(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link WorldCreator} for the given world name
|
||||
*
|
||||
* @param name Name of the world to load or create
|
||||
* @return Resulting WorldCreator
|
||||
*/
|
||||
public static WorldCreator name(String name) {
|
||||
return new WorldCreator(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get the {@link ChunkGenerator} with the given name.
|
||||
* <p>
|
||||
* If the generator is not found, null will be returned and a message will
|
||||
* be printed to the specified {@link CommandSender} explaining why.
|
||||
* <p>
|
||||
* The name must be in the "plugin:id" notation, or optionally just
|
||||
* "plugin", where "plugin" is the safe-name of a plugin and "id" is an
|
||||
* optional unique identifier for the generator you wish to request from
|
||||
* the plugin.
|
||||
*
|
||||
* @param world Name of the world this will be used for
|
||||
* @param name Name of the generator to retrieve
|
||||
* @param output Where to output if errors are present
|
||||
* @return Resulting generator, or null
|
||||
*/
|
||||
public static ChunkGenerator getGeneratorForName(String world, String name, CommandSender output) {
|
||||
ChunkGenerator result = null;
|
||||
|
||||
if (world == null) {
|
||||
throw new IllegalArgumentException("World name must be specified");
|
||||
}
|
||||
|
||||
if (output == null) {
|
||||
output = Bukkit.getConsoleSender();
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
String[] split = name.split(":", 2);
|
||||
String id = (split.length > 1) ? split[1] : null;
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(split[0]);
|
||||
|
||||
if (plugin == null) {
|
||||
output.sendMessage("Could not set generator for world '" + world + "': Plugin '" + split[0] + "' does not exist");
|
||||
} else if (!plugin.isEnabled()) {
|
||||
output.sendMessage("Could not set generator for world '" + world + "': Plugin '" + plugin.getDescription().getFullName() + "' is not enabled");
|
||||
} else {
|
||||
result = plugin.getDefaultWorldGenerator(world, id);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
48
TacoSpigot-API/src/main/java/org/bukkit/WorldType.java
Normal file
48
TacoSpigot-API/src/main/java/org/bukkit/WorldType.java
Normal file
@ -0,0 +1,48 @@
|
||||
package org.bukkit;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents various types of worlds that may exist
|
||||
*/
|
||||
public enum WorldType {
|
||||
NORMAL("DEFAULT"),
|
||||
FLAT("FLAT"),
|
||||
VERSION_1_1("DEFAULT_1_1"),
|
||||
LARGE_BIOMES("LARGEBIOMES"),
|
||||
AMPLIFIED("AMPLIFIED"),
|
||||
CUSTOMIZED("CUSTOMIZED");
|
||||
|
||||
private final static Map<String, WorldType> BY_NAME = Maps.newHashMap();
|
||||
private final String name;
|
||||
|
||||
private WorldType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this WorldType
|
||||
*
|
||||
* @return Name of this type
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Worldtype by its name
|
||||
*
|
||||
* @param name Name of the WorldType to get
|
||||
* @return Requested WorldType, or null if not found
|
||||
*/
|
||||
public static WorldType getByName(String name) {
|
||||
return BY_NAME.get(name.toUpperCase());
|
||||
}
|
||||
|
||||
static {
|
||||
for (WorldType type : values()) {
|
||||
BY_NAME.put(type.name, type);
|
||||
}
|
||||
}
|
||||
}
|
77
TacoSpigot-API/src/main/java/org/bukkit/block/Banner.java
Normal file
77
TacoSpigot-API/src/main/java/org/bukkit/block/Banner.java
Normal file
@ -0,0 +1,77 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.block.banner.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Banner extends BlockState {
|
||||
|
||||
/**
|
||||
* Returns the base color for this banner
|
||||
*
|
||||
* @return the base color
|
||||
*/
|
||||
DyeColor getBaseColor();
|
||||
|
||||
/**
|
||||
* Sets the base color for this banner
|
||||
*
|
||||
* @param color the base color
|
||||
*/
|
||||
void setBaseColor(DyeColor color);
|
||||
|
||||
/**
|
||||
* Returns a list of patterns on this banner
|
||||
*
|
||||
* @return the patterns
|
||||
*/
|
||||
List<Pattern> getPatterns();
|
||||
|
||||
/**
|
||||
* Sets the patterns used on this banner
|
||||
*
|
||||
* @param patterns the new list of patterns
|
||||
*/
|
||||
void setPatterns(List<Pattern> patterns);
|
||||
|
||||
/**
|
||||
* Adds a new pattern on top of the existing
|
||||
* patterns
|
||||
*
|
||||
* @param pattern the new pattern to add
|
||||
*/
|
||||
void addPattern(Pattern pattern);
|
||||
|
||||
/**
|
||||
* Returns the pattern at the specified index
|
||||
*
|
||||
* @param i the index
|
||||
* @return the pattern
|
||||
*/
|
||||
Pattern getPattern(int i);
|
||||
|
||||
/**
|
||||
* Removes the pattern at the specified index
|
||||
*
|
||||
* @param i the index
|
||||
* @return the removed pattern
|
||||
*/
|
||||
Pattern removePattern(int i);
|
||||
|
||||
/**
|
||||
* Sets the pattern at the specified index
|
||||
*
|
||||
* @param i the index
|
||||
* @param pattern the new pattern
|
||||
*/
|
||||
void setPattern(int i, Pattern pattern);
|
||||
|
||||
/**
|
||||
* Returns the number of patterns on this
|
||||
* banner
|
||||
*
|
||||
* @return the number of patterns
|
||||
*/
|
||||
int numberOfPatterns();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Represents a beacon.
|
||||
*/
|
||||
public interface Beacon extends BlockState, InventoryHolder {
|
||||
}
|
68
TacoSpigot-API/src/main/java/org/bukkit/block/Biome.java
Normal file
68
TacoSpigot-API/src/main/java/org/bukkit/block/Biome.java
Normal file
@ -0,0 +1,68 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
/**
|
||||
* Holds all accepted Biomes in the default server
|
||||
*/
|
||||
public enum Biome {
|
||||
SWAMPLAND,
|
||||
FOREST,
|
||||
TAIGA,
|
||||
DESERT,
|
||||
PLAINS,
|
||||
HELL,
|
||||
SKY,
|
||||
OCEAN,
|
||||
RIVER,
|
||||
EXTREME_HILLS,
|
||||
FROZEN_OCEAN,
|
||||
FROZEN_RIVER,
|
||||
ICE_PLAINS,
|
||||
ICE_MOUNTAINS,
|
||||
MUSHROOM_ISLAND,
|
||||
MUSHROOM_SHORE,
|
||||
BEACH,
|
||||
DESERT_HILLS,
|
||||
FOREST_HILLS,
|
||||
TAIGA_HILLS,
|
||||
SMALL_MOUNTAINS,
|
||||
JUNGLE,
|
||||
JUNGLE_HILLS,
|
||||
JUNGLE_EDGE,
|
||||
DEEP_OCEAN,
|
||||
STONE_BEACH,
|
||||
COLD_BEACH,
|
||||
BIRCH_FOREST,
|
||||
BIRCH_FOREST_HILLS,
|
||||
ROOFED_FOREST,
|
||||
COLD_TAIGA,
|
||||
COLD_TAIGA_HILLS,
|
||||
MEGA_TAIGA,
|
||||
MEGA_TAIGA_HILLS,
|
||||
EXTREME_HILLS_PLUS,
|
||||
SAVANNA,
|
||||
SAVANNA_PLATEAU,
|
||||
MESA,
|
||||
MESA_PLATEAU_FOREST,
|
||||
MESA_PLATEAU,
|
||||
SUNFLOWER_PLAINS,
|
||||
DESERT_MOUNTAINS,
|
||||
FLOWER_FOREST,
|
||||
TAIGA_MOUNTAINS,
|
||||
SWAMPLAND_MOUNTAINS,
|
||||
ICE_PLAINS_SPIKES,
|
||||
JUNGLE_MOUNTAINS,
|
||||
JUNGLE_EDGE_MOUNTAINS,
|
||||
COLD_TAIGA_MOUNTAINS,
|
||||
SAVANNA_MOUNTAINS,
|
||||
SAVANNA_PLATEAU_MOUNTAINS,
|
||||
MESA_BRYCE,
|
||||
MESA_PLATEAU_FOREST_MOUNTAINS,
|
||||
MESA_PLATEAU_MOUNTAINS,
|
||||
BIRCH_FOREST_MOUNTAINS,
|
||||
BIRCH_FOREST_HILLS_MOUNTAINS,
|
||||
ROOFED_FOREST_MOUNTAINS,
|
||||
MEGA_SPRUCE_TAIGA,
|
||||
EXTREME_HILLS_MOUNTAINS,
|
||||
EXTREME_HILLS_PLUS_MOUNTAINS,
|
||||
MEGA_SPRUCE_TAIGA_HILLS,
|
||||
}
|
393
TacoSpigot-API/src/main/java/org/bukkit/block/Block.java
Normal file
393
TacoSpigot-API/src/main/java/org/bukkit/block/Block.java
Normal file
@ -0,0 +1,393 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.Metadatable;
|
||||
|
||||
/**
|
||||
* Represents a block. This is a live object, and only one Block may exist for
|
||||
* any given location in a world. The state of the block may change
|
||||
* concurrently to your own handling of it; use block.getState() to get a
|
||||
* snapshot state of a block which will not be modified.
|
||||
*/
|
||||
public interface Block extends Metadatable {
|
||||
|
||||
/**
|
||||
* Gets the metadata for this block
|
||||
*
|
||||
* @return block specific metadata
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
byte getData();
|
||||
|
||||
/**
|
||||
* Gets the block at the given offsets
|
||||
*
|
||||
* @param modX X-coordinate offset
|
||||
* @param modY Y-coordinate offset
|
||||
* @param modZ Z-coordinate offset
|
||||
* @return Block at the given offsets
|
||||
*/
|
||||
Block getRelative(int modX, int modY, int modZ);
|
||||
|
||||
/**
|
||||
* Gets the block at the given face
|
||||
* <p>
|
||||
* This method is equal to getRelative(face, 1)
|
||||
*
|
||||
* @param face Face of this block to return
|
||||
* @return Block at the given face
|
||||
* @see #getRelative(BlockFace, int)
|
||||
*/
|
||||
Block getRelative(BlockFace face);
|
||||
|
||||
/**
|
||||
* Gets the block at the given distance of the given face
|
||||
* <p>
|
||||
* For example, the following method places water at 100,102,100; two
|
||||
* blocks above 100,100,100.
|
||||
*
|
||||
* <pre>
|
||||
* Block block = world.getBlockAt(100, 100, 100);
|
||||
* Block shower = block.getRelative(BlockFace.UP, 2);
|
||||
* shower.setType(Material.WATER);
|
||||
* </pre>
|
||||
*
|
||||
* @param face Face of this block to return
|
||||
* @param distance Distance to get the block at
|
||||
* @return Block at the given face
|
||||
*/
|
||||
Block getRelative(BlockFace face, int distance);
|
||||
|
||||
/**
|
||||
* Gets the type of this block
|
||||
*
|
||||
* @return block type
|
||||
*/
|
||||
Material getType();
|
||||
|
||||
/**
|
||||
* Gets the type-id of this block
|
||||
*
|
||||
* @return block type-id
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
int getTypeId();
|
||||
|
||||
/**
|
||||
* Gets the light level between 0-15
|
||||
*
|
||||
* @return light level
|
||||
*/
|
||||
byte getLightLevel();
|
||||
|
||||
/**
|
||||
* Get the amount of light at this block from the sky.
|
||||
* <p>
|
||||
* Any light given from other sources (such as blocks like torches) will
|
||||
* be ignored.
|
||||
*
|
||||
* @return Sky light level
|
||||
*/
|
||||
byte getLightFromSky();
|
||||
|
||||
/**
|
||||
* Get the amount of light at this block from nearby blocks.
|
||||
* <p>
|
||||
* Any light given from other sources (such as the sun) will be ignored.
|
||||
*
|
||||
* @return Block light level
|
||||
*/
|
||||
byte getLightFromBlocks();
|
||||
|
||||
/**
|
||||
* Gets the world which contains this Block
|
||||
*
|
||||
* @return World containing this block
|
||||
*/
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Gets the x-coordinate of this block
|
||||
*
|
||||
* @return x-coordinate
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Gets the y-coordinate of this block
|
||||
*
|
||||
* @return y-coordinate
|
||||
*/
|
||||
int getY();
|
||||
|
||||
/**
|
||||
* Gets the z-coordinate of this block
|
||||
*
|
||||
* @return z-coordinate
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* Gets the Location of the block
|
||||
*
|
||||
* @return Location of block
|
||||
*/
|
||||
Location getLocation();
|
||||
|
||||
/**
|
||||
* Stores the location of the block in the provided Location object.
|
||||
* <p>
|
||||
* If the provided Location is null this method does nothing and returns
|
||||
* null.
|
||||
*
|
||||
* @param loc the location to copy into
|
||||
* @return The Location object provided or null
|
||||
*/
|
||||
Location getLocation(Location loc);
|
||||
|
||||
/**
|
||||
* Gets the chunk which contains this block
|
||||
*
|
||||
* @return Containing Chunk
|
||||
*/
|
||||
Chunk getChunk();
|
||||
|
||||
/**
|
||||
* Sets the metadata for this block
|
||||
*
|
||||
* @param data New block specific metadata
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
void setData(byte data);
|
||||
|
||||
/**
|
||||
* Sets the metadata for this block
|
||||
*
|
||||
* @param data New block specific metadata
|
||||
* @param applyPhysics False to cancel physics from the changed block.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
void setData(byte data, boolean applyPhysics);
|
||||
|
||||
/**
|
||||
* Sets the type of this block
|
||||
*
|
||||
* @param type Material to change this block to
|
||||
*/
|
||||
void setType(Material type);
|
||||
|
||||
/**
|
||||
* Sets the type of this block
|
||||
*
|
||||
* @param type Material to change this block to
|
||||
* @param applyPhysics False to cancel physics on the changed block.
|
||||
*/
|
||||
void setType(Material type, boolean applyPhysics);
|
||||
|
||||
/**
|
||||
* Sets the type-id of this block
|
||||
*
|
||||
* @param type Type-Id to change this block to
|
||||
* @return whether the block was changed
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
boolean setTypeId(int type);
|
||||
|
||||
/**
|
||||
* Sets the type-id of this block
|
||||
*
|
||||
* @param type Type-Id to change this block to
|
||||
* @param applyPhysics False to cancel physics on the changed block.
|
||||
* @return whether the block was changed
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
boolean setTypeId(int type, boolean applyPhysics);
|
||||
|
||||
/**
|
||||
* Sets the type-id of this block
|
||||
*
|
||||
* @param type Type-Id to change this block to
|
||||
* @param data The data value to change this block to
|
||||
* @param applyPhysics False to cancel physics on the changed block
|
||||
* @return whether the block was changed
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
boolean setTypeIdAndData(int type, byte data, boolean applyPhysics);
|
||||
|
||||
/**
|
||||
* Gets the face relation of this block compared to the given block.
|
||||
* <p>
|
||||
* For example:
|
||||
* <pre>{@code
|
||||
* Block current = world.getBlockAt(100, 100, 100);
|
||||
* Block target = world.getBlockAt(100, 101, 100);
|
||||
*
|
||||
* current.getFace(target) == BlockFace.Up;
|
||||
* }</pre>
|
||||
* <br>
|
||||
* If the given block is not connected to this block, null may be returned
|
||||
*
|
||||
* @param block Block to compare against this block
|
||||
* @return BlockFace of this block which has the requested block, or null
|
||||
*/
|
||||
BlockFace getFace(Block block);
|
||||
|
||||
/**
|
||||
* Captures the current state of this block. You may then cast that state
|
||||
* into any accepted type, such as Furnace or Sign.
|
||||
* <p>
|
||||
* The returned object will never be updated, and you are not guaranteed
|
||||
* that (for example) a sign is still a sign after you capture its state.
|
||||
*
|
||||
* @return BlockState with the current state of this block.
|
||||
*/
|
||||
BlockState getState();
|
||||
|
||||
/**
|
||||
* Returns the biome that this block resides in
|
||||
*
|
||||
* @return Biome type containing this block
|
||||
*/
|
||||
Biome getBiome();
|
||||
|
||||
/**
|
||||
* Sets the biome that this block resides in
|
||||
*
|
||||
* @param bio new Biome type for this block
|
||||
*/
|
||||
void setBiome(Biome bio);
|
||||
|
||||
/**
|
||||
* Returns true if the block is being powered by Redstone.
|
||||
*
|
||||
* @return True if the block is powered.
|
||||
*/
|
||||
boolean isBlockPowered();
|
||||
|
||||
/**
|
||||
* Returns true if the block is being indirectly powered by Redstone.
|
||||
*
|
||||
* @return True if the block is indirectly powered.
|
||||
*/
|
||||
boolean isBlockIndirectlyPowered();
|
||||
|
||||
/**
|
||||
* Returns true if the block face is being powered by Redstone.
|
||||
*
|
||||
* @param face The block face
|
||||
* @return True if the block face is powered.
|
||||
*/
|
||||
boolean isBlockFacePowered(BlockFace face);
|
||||
|
||||
/**
|
||||
* Returns true if the block face is being indirectly powered by Redstone.
|
||||
*
|
||||
* @param face The block face
|
||||
* @return True if the block face is indirectly powered.
|
||||
*/
|
||||
boolean isBlockFaceIndirectlyPowered(BlockFace face);
|
||||
|
||||
/**
|
||||
* Returns the redstone power being provided to this block face
|
||||
*
|
||||
* @param face the face of the block to query or BlockFace.SELF for the
|
||||
* block itself
|
||||
* @return The power level.
|
||||
*/
|
||||
int getBlockPower(BlockFace face);
|
||||
|
||||
/**
|
||||
* Returns the redstone power being provided to this block
|
||||
*
|
||||
* @return The power level.
|
||||
*/
|
||||
int getBlockPower();
|
||||
|
||||
/**
|
||||
* Checks if this block is empty.
|
||||
* <p>
|
||||
* A block is considered empty when {@link #getType()} returns {@link
|
||||
* Material#AIR}.
|
||||
*
|
||||
* @return true if this block is empty
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Checks if this block is liquid.
|
||||
* <p>
|
||||
* A block is considered liquid when {@link #getType()} returns {@link
|
||||
* Material#WATER}, {@link Material#STATIONARY_WATER}, {@link
|
||||
* Material#LAVA} or {@link Material#STATIONARY_LAVA}.
|
||||
*
|
||||
* @return true if this block is liquid
|
||||
*/
|
||||
boolean isLiquid();
|
||||
|
||||
/**
|
||||
* Gets the temperature of the biome of this block
|
||||
*
|
||||
* @return Temperature of this block
|
||||
*/
|
||||
double getTemperature();
|
||||
|
||||
/**
|
||||
* Gets the humidity of the biome of this block
|
||||
*
|
||||
* @return Humidity of this block
|
||||
*/
|
||||
double getHumidity();
|
||||
|
||||
/**
|
||||
* Returns the reaction of the block when moved by a piston
|
||||
*
|
||||
* @return reaction
|
||||
*/
|
||||
PistonMoveReaction getPistonMoveReaction();
|
||||
|
||||
/**
|
||||
* Breaks the block and spawns items as if a player had digged it
|
||||
*
|
||||
* @return true if the block was destroyed
|
||||
*/
|
||||
boolean breakNaturally();
|
||||
|
||||
/**
|
||||
* Breaks the block and spawns items as if a player had digged it with a
|
||||
* specific tool
|
||||
*
|
||||
* @param tool The tool or item in hand used for digging
|
||||
* @return true if the block was destroyed
|
||||
*/
|
||||
boolean breakNaturally(ItemStack tool);
|
||||
|
||||
/**
|
||||
* Returns a list of items which would drop by destroying this block
|
||||
*
|
||||
* @return a list of dropped items for this type of block
|
||||
*/
|
||||
Collection<ItemStack> getDrops();
|
||||
|
||||
/**
|
||||
* Returns a list of items which would drop by destroying this block with
|
||||
* a specific tool
|
||||
*
|
||||
* @param tool The tool or item in hand used for digging
|
||||
* @return a list of dropped items for this type of block
|
||||
*/
|
||||
Collection<ItemStack> getDrops(ItemStack tool);
|
||||
|
||||
}
|
132
TacoSpigot-API/src/main/java/org/bukkit/block/BlockFace.java
Normal file
132
TacoSpigot-API/src/main/java/org/bukkit/block/BlockFace.java
Normal file
@ -0,0 +1,132 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
/**
|
||||
* Represents the face of a block
|
||||
*/
|
||||
public enum BlockFace {
|
||||
NORTH(0, 0, -1),
|
||||
EAST(1, 0, 0),
|
||||
SOUTH(0, 0, 1),
|
||||
WEST(-1, 0, 0),
|
||||
UP(0, 1, 0),
|
||||
DOWN(0, -1, 0),
|
||||
NORTH_EAST(NORTH, EAST),
|
||||
NORTH_WEST(NORTH, WEST),
|
||||
SOUTH_EAST(SOUTH, EAST),
|
||||
SOUTH_WEST(SOUTH, WEST),
|
||||
WEST_NORTH_WEST(WEST, NORTH_WEST),
|
||||
NORTH_NORTH_WEST(NORTH, NORTH_WEST),
|
||||
NORTH_NORTH_EAST(NORTH, NORTH_EAST),
|
||||
EAST_NORTH_EAST(EAST, NORTH_EAST),
|
||||
EAST_SOUTH_EAST(EAST, SOUTH_EAST),
|
||||
SOUTH_SOUTH_EAST(SOUTH, SOUTH_EAST),
|
||||
SOUTH_SOUTH_WEST(SOUTH, SOUTH_WEST),
|
||||
WEST_SOUTH_WEST(WEST, SOUTH_WEST),
|
||||
SELF(0, 0, 0);
|
||||
|
||||
private final int modX;
|
||||
private final int modY;
|
||||
private final int modZ;
|
||||
|
||||
private BlockFace(final int modX, final int modY, final int modZ) {
|
||||
this.modX = modX;
|
||||
this.modY = modY;
|
||||
this.modZ = modZ;
|
||||
}
|
||||
|
||||
private BlockFace(final BlockFace face1, final BlockFace face2) {
|
||||
this.modX = face1.getModX() + face2.getModX();
|
||||
this.modY = face1.getModY() + face2.getModY();
|
||||
this.modZ = face1.getModZ() + face2.getModZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of X-coordinates to modify to get the represented block
|
||||
*
|
||||
* @return Amount of X-coordinates to modify
|
||||
*/
|
||||
public int getModX() {
|
||||
return modX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of Y-coordinates to modify to get the represented block
|
||||
*
|
||||
* @return Amount of Y-coordinates to modify
|
||||
*/
|
||||
public int getModY() {
|
||||
return modY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of Z-coordinates to modify to get the represented block
|
||||
*
|
||||
* @return Amount of Z-coordinates to modify
|
||||
*/
|
||||
public int getModZ() {
|
||||
return modZ;
|
||||
}
|
||||
|
||||
public BlockFace getOppositeFace() {
|
||||
switch (this) {
|
||||
case NORTH:
|
||||
return BlockFace.SOUTH;
|
||||
|
||||
case SOUTH:
|
||||
return BlockFace.NORTH;
|
||||
|
||||
case EAST:
|
||||
return BlockFace.WEST;
|
||||
|
||||
case WEST:
|
||||
return BlockFace.EAST;
|
||||
|
||||
case UP:
|
||||
return BlockFace.DOWN;
|
||||
|
||||
case DOWN:
|
||||
return BlockFace.UP;
|
||||
|
||||
case NORTH_EAST:
|
||||
return BlockFace.SOUTH_WEST;
|
||||
|
||||
case NORTH_WEST:
|
||||
return BlockFace.SOUTH_EAST;
|
||||
|
||||
case SOUTH_EAST:
|
||||
return BlockFace.NORTH_WEST;
|
||||
|
||||
case SOUTH_WEST:
|
||||
return BlockFace.NORTH_EAST;
|
||||
|
||||
case WEST_NORTH_WEST:
|
||||
return BlockFace.EAST_SOUTH_EAST;
|
||||
|
||||
case NORTH_NORTH_WEST:
|
||||
return BlockFace.SOUTH_SOUTH_EAST;
|
||||
|
||||
case NORTH_NORTH_EAST:
|
||||
return BlockFace.SOUTH_SOUTH_WEST;
|
||||
|
||||
case EAST_NORTH_EAST:
|
||||
return BlockFace.WEST_SOUTH_WEST;
|
||||
|
||||
case EAST_SOUTH_EAST:
|
||||
return BlockFace.WEST_NORTH_WEST;
|
||||
|
||||
case SOUTH_SOUTH_EAST:
|
||||
return BlockFace.NORTH_NORTH_WEST;
|
||||
|
||||
case SOUTH_SOUTH_WEST:
|
||||
return BlockFace.NORTH_NORTH_EAST;
|
||||
|
||||
case WEST_SOUTH_WEST:
|
||||
return BlockFace.EAST_NORTH_EAST;
|
||||
|
||||
case SELF:
|
||||
return BlockFace.SELF;
|
||||
}
|
||||
|
||||
return BlockFace.SELF;
|
||||
}
|
||||
}
|
206
TacoSpigot-API/src/main/java/org/bukkit/block/BlockState.java
Normal file
206
TacoSpigot-API/src/main/java/org/bukkit/block/BlockState.java
Normal file
@ -0,0 +1,206 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.metadata.Metadatable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a block, which will not change
|
||||
* automatically.
|
||||
* <p>
|
||||
* Unlike Block, which only one object can exist per coordinate, BlockState
|
||||
* can exist multiple times for any given Block. Note that another plugin may
|
||||
* change the state of the block and you will not know, or they may change the
|
||||
* block to another type entirely, causing your BlockState to become invalid.
|
||||
*/
|
||||
public interface BlockState extends Metadatable {
|
||||
|
||||
/**
|
||||
* Gets the block represented by this BlockState
|
||||
*
|
||||
* @return Block that this BlockState represents
|
||||
*/
|
||||
Block getBlock();
|
||||
|
||||
/**
|
||||
* Gets the metadata for this block
|
||||
*
|
||||
* @return block specific metadata
|
||||
*/
|
||||
MaterialData getData();
|
||||
|
||||
/**
|
||||
* Gets the type of this block
|
||||
*
|
||||
* @return block type
|
||||
*/
|
||||
Material getType();
|
||||
|
||||
/**
|
||||
* Gets the type-id of this block
|
||||
*
|
||||
* @return block type-id
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
int getTypeId();
|
||||
|
||||
/**
|
||||
* Gets the light level between 0-15
|
||||
*
|
||||
* @return light level
|
||||
*/
|
||||
byte getLightLevel();
|
||||
|
||||
/**
|
||||
* Gets the world which contains this Block
|
||||
*
|
||||
* @return World containing this block
|
||||
*/
|
||||
World getWorld();
|
||||
|
||||
/**
|
||||
* Gets the x-coordinate of this block
|
||||
*
|
||||
* @return x-coordinate
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* Gets the y-coordinate of this block
|
||||
*
|
||||
* @return y-coordinate
|
||||
*/
|
||||
int getY();
|
||||
|
||||
/**
|
||||
* Gets the z-coordinate of this block
|
||||
*
|
||||
* @return z-coordinate
|
||||
*/
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* Gets the location of this block
|
||||
*
|
||||
* @return location
|
||||
*/
|
||||
Location getLocation();
|
||||
|
||||
/**
|
||||
* Stores the location of this block in the provided Location object.
|
||||
* <p>
|
||||
* If the provided Location is null this method does nothing and returns
|
||||
* null.
|
||||
*
|
||||
* @param loc the location to copy into
|
||||
* @return The Location object provided or null
|
||||
*/
|
||||
Location getLocation(Location loc);
|
||||
|
||||
/**
|
||||
* Gets the chunk which contains this block
|
||||
*
|
||||
* @return Containing Chunk
|
||||
*/
|
||||
Chunk getChunk();
|
||||
|
||||
/**
|
||||
* Sets the metadata for this block
|
||||
*
|
||||
* @param data New block specific metadata
|
||||
*/
|
||||
void setData(MaterialData data);
|
||||
|
||||
/**
|
||||
* Sets the type of this block
|
||||
*
|
||||
* @param type Material to change this block to
|
||||
*/
|
||||
void setType(Material type);
|
||||
|
||||
/**
|
||||
* Sets the type-id of this block
|
||||
*
|
||||
* @param type Type-Id to change this block to
|
||||
* @return Whether it worked?
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
boolean setTypeId(int type);
|
||||
|
||||
/**
|
||||
* Attempts to update the block represented by this state, setting it to
|
||||
* the new values as defined by this state.
|
||||
* <p>
|
||||
* This has the same effect as calling update(false). That is to say,
|
||||
* this will not modify the state of a block if it is no longer the same
|
||||
* type as it was when this state was taken. It will return false in this
|
||||
* eventuality.
|
||||
*
|
||||
* @return true if the update was successful, otherwise false
|
||||
* @see #update(boolean)
|
||||
*/
|
||||
boolean update();
|
||||
|
||||
/**
|
||||
* Attempts to update the block represented by this state, setting it to
|
||||
* the new values as defined by this state.
|
||||
* <p>
|
||||
* This has the same effect as calling update(force, true). That is to
|
||||
* say, this will trigger a physics update to surrounding blocks.
|
||||
*
|
||||
* @param force true to forcefully set the state
|
||||
* @return true if the update was successful, otherwise false
|
||||
*/
|
||||
boolean update(boolean force);
|
||||
|
||||
/**
|
||||
* Attempts to update the block represented by this state, setting it to
|
||||
* the new values as defined by this state.
|
||||
* <p>
|
||||
* Unless force is true, this will not modify the state of a block if it
|
||||
* is no longer the same type as it was when this state was taken. It will
|
||||
* return false in this eventuality.
|
||||
* <p>
|
||||
* If force is true, it will set the type of the block to match the new
|
||||
* state, set the state data and then return true.
|
||||
* <p>
|
||||
* If applyPhysics is true, it will trigger a physics update on
|
||||
* surrounding blocks which could cause them to update or disappear.
|
||||
*
|
||||
* @param force true to forcefully set the state
|
||||
* @param applyPhysics false to cancel updating physics on surrounding
|
||||
* blocks
|
||||
* @return true if the update was successful, otherwise false
|
||||
*/
|
||||
boolean update(boolean force, boolean applyPhysics);
|
||||
|
||||
/**
|
||||
* @return The data as a raw byte.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getRawData();
|
||||
|
||||
/**
|
||||
* @param data The new data value for the block.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public void setRawData(byte data);
|
||||
|
||||
/**
|
||||
* Returns whether this state is placed in the world.
|
||||
*
|
||||
* Some methods will not work if the blockState isn't
|
||||
* placed in the world.
|
||||
*
|
||||
* @return whether the state is placed in the world
|
||||
* or 'virtual' (e.g. on an itemstack)
|
||||
*/
|
||||
boolean isPlaced();
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.BrewerInventory;
|
||||
|
||||
/**
|
||||
* Represents a brewing stand.
|
||||
*/
|
||||
public interface BrewingStand extends BlockState, ContainerBlock {
|
||||
|
||||
/**
|
||||
* How much time is left in the brewing cycle
|
||||
*
|
||||
* @return Brew Time
|
||||
*/
|
||||
int getBrewingTime();
|
||||
|
||||
/**
|
||||
* Set the time left before brewing completes.
|
||||
*
|
||||
* @param brewTime Brewing time
|
||||
*/
|
||||
void setBrewingTime(int brewTime);
|
||||
|
||||
public BrewerInventory getInventory();
|
||||
}
|
17
TacoSpigot-API/src/main/java/org/bukkit/block/Chest.java
Normal file
17
TacoSpigot-API/src/main/java/org/bukkit/block/Chest.java
Normal file
@ -0,0 +1,17 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
/**
|
||||
* Represents a chest.
|
||||
*/
|
||||
public interface Chest extends BlockState, ContainerBlock {
|
||||
|
||||
/**
|
||||
* Returns the chest's inventory. If this is a double chest, it returns
|
||||
* just the portion of the inventory linked to this half of the chest.
|
||||
*
|
||||
* @return The inventory.
|
||||
*/
|
||||
Inventory getBlockInventory();
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
public interface CommandBlock extends BlockState {
|
||||
|
||||
/**
|
||||
* Gets the command that this CommandBlock will run when powered.
|
||||
* This will never return null. If the CommandBlock does not have a
|
||||
* command, an empty String will be returned instead.
|
||||
*
|
||||
* @return Command that this CommandBlock will run when powered.
|
||||
*/
|
||||
public String getCommand();
|
||||
|
||||
/**
|
||||
* Sets the command that this CommandBlock will run when powered.
|
||||
* Setting the command to null is the same as setting it to an empty
|
||||
* String.
|
||||
*
|
||||
* @param command Command that this CommandBlock will run when powered.
|
||||
*/
|
||||
public void setCommand(String command);
|
||||
|
||||
/**
|
||||
* Gets the name of this CommandBlock. The name is used with commands
|
||||
* that this CommandBlock executes. This name will never be null, and
|
||||
* by default is "@".
|
||||
*
|
||||
* @return Name of this CommandBlock.
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Sets the name of this CommandBlock. The name is used with commands
|
||||
* that this CommandBlock executes. Setting the name to null is the
|
||||
* same as setting it to "@".
|
||||
*
|
||||
* @param name New name for this CommandBlock.
|
||||
*/
|
||||
public void setName(String name);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Indicates a block type that has inventory.
|
||||
*
|
||||
* @deprecated in favour of {@link InventoryHolder}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ContainerBlock extends InventoryHolder {}
|
@ -0,0 +1,88 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.entity.CreatureType;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
/**
|
||||
* Represents a creature spawner.
|
||||
*/
|
||||
public interface CreatureSpawner extends BlockState {
|
||||
|
||||
/**
|
||||
* Get the spawner's creature type.
|
||||
*
|
||||
* @return The creature type.
|
||||
* @deprecated In favour of {@link #getSpawnedType()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public CreatureType getCreatureType();
|
||||
|
||||
/**
|
||||
* Get the spawner's creature type.
|
||||
*
|
||||
* @return The creature type.
|
||||
*/
|
||||
public EntityType getSpawnedType();
|
||||
|
||||
/**
|
||||
* Set the spawner's creature type.
|
||||
*
|
||||
* @param creatureType The creature type.
|
||||
*/
|
||||
public void setSpawnedType(EntityType creatureType);
|
||||
|
||||
/**
|
||||
* Set the spawner creature type.
|
||||
*
|
||||
* @param creatureType The creature type.
|
||||
* @deprecated In favour of {@link #setSpawnedType(EntityType)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setCreatureType(CreatureType creatureType);
|
||||
|
||||
/**
|
||||
* Get the spawner's creature type.
|
||||
*
|
||||
* @return The creature type's name.
|
||||
* @deprecated Use {@link #getCreatureTypeName()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getCreatureTypeId();
|
||||
|
||||
/**
|
||||
* Set the spawner mob type.
|
||||
*
|
||||
* @param creatureType The creature type's name.
|
||||
*/
|
||||
public void setCreatureTypeByName(String creatureType);
|
||||
|
||||
/**
|
||||
* Get the spawner's creature type.
|
||||
*
|
||||
* @return The creature type's name.
|
||||
*/
|
||||
public String getCreatureTypeName();
|
||||
|
||||
/**
|
||||
* Set the spawner mob type.
|
||||
*
|
||||
* @param creatureType The creature type's name.
|
||||
* @deprecated Use {@link #setCreatureTypeByName(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setCreatureTypeId(String creatureType);
|
||||
|
||||
/**
|
||||
* Get the spawner's delay.
|
||||
*
|
||||
* @return The delay.
|
||||
*/
|
||||
public int getDelay();
|
||||
|
||||
/**
|
||||
* Set the spawner's delay.
|
||||
*
|
||||
* @param delay The delay.
|
||||
*/
|
||||
public void setDelay(int delay);
|
||||
}
|
27
TacoSpigot-API/src/main/java/org/bukkit/block/Dispenser.java
Normal file
27
TacoSpigot-API/src/main/java/org/bukkit/block/Dispenser.java
Normal file
@ -0,0 +1,27 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
|
||||
/**
|
||||
* Represents a dispenser.
|
||||
*/
|
||||
public interface Dispenser extends BlockState, ContainerBlock {
|
||||
|
||||
/**
|
||||
* Gets the BlockProjectileSource object for this dispenser.
|
||||
* <p>
|
||||
* If the block is no longer a dispenser, this will return null.
|
||||
*
|
||||
* @return a BlockProjectileSource if valid, otherwise null
|
||||
*/
|
||||
public BlockProjectileSource getBlockProjectileSource();
|
||||
|
||||
/**
|
||||
* Attempts to dispense the contents of this block.
|
||||
* <p>
|
||||
* If the block is no longer a dispenser, this will return false.
|
||||
*
|
||||
* @return true if successful, otherwise false
|
||||
*/
|
||||
public boolean dispense();
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.DoubleChestInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Represents a double chest.
|
||||
*/
|
||||
public class DoubleChest implements InventoryHolder {
|
||||
private DoubleChestInventory inventory;
|
||||
|
||||
public DoubleChest(DoubleChestInventory chest) {
|
||||
inventory = chest;
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public InventoryHolder getLeftSide() {
|
||||
return inventory.getLeftSide().getHolder();
|
||||
}
|
||||
|
||||
public InventoryHolder getRightSide() {
|
||||
return inventory.getRightSide().getHolder();
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return new Location(getWorld(), getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return ((Chest)getLeftSide()).getWorld();
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return 0.5 * (((Chest)getLeftSide()).getX() + ((Chest)getRightSide()).getX());
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return 0.5 * (((Chest)getLeftSide()).getY() + ((Chest)getRightSide()).getY());
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return 0.5 * (((Chest)getLeftSide()).getZ() + ((Chest)getRightSide()).getZ());
|
||||
}
|
||||
}
|
25
TacoSpigot-API/src/main/java/org/bukkit/block/Dropper.java
Normal file
25
TacoSpigot-API/src/main/java/org/bukkit/block/Dropper.java
Normal file
@ -0,0 +1,25 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Represents a dropper.
|
||||
*/
|
||||
public interface Dropper extends BlockState, InventoryHolder {
|
||||
/**
|
||||
* Tries to drop a randomly selected item from the Dropper's inventory,
|
||||
* following the normal behavior of a Dropper.
|
||||
* <p>
|
||||
* Normal behavior of a Dropper is as follows:
|
||||
* <p>
|
||||
* If the block that the Dropper is facing is an InventoryHolder or
|
||||
* ContainerBlock the randomly selected ItemStack is placed within that
|
||||
* Inventory in the first slot that's available, starting with 0 and
|
||||
* counting up. If the inventory is full, nothing happens.
|
||||
* <p>
|
||||
* If the block that the Dropper is facing is not an InventoryHolder or
|
||||
* ContainerBlock, the randomly selected ItemStack is dropped on
|
||||
* the ground in the form of an {@link org.bukkit.entity.Item Item}.
|
||||
*/
|
||||
public void drop();
|
||||
}
|
39
TacoSpigot-API/src/main/java/org/bukkit/block/Furnace.java
Normal file
39
TacoSpigot-API/src/main/java/org/bukkit/block/Furnace.java
Normal file
@ -0,0 +1,39 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.FurnaceInventory;
|
||||
|
||||
/**
|
||||
* Represents a furnace.
|
||||
*/
|
||||
public interface Furnace extends BlockState, ContainerBlock {
|
||||
|
||||
/**
|
||||
* Get burn time.
|
||||
*
|
||||
* @return Burn time
|
||||
*/
|
||||
public short getBurnTime();
|
||||
|
||||
/**
|
||||
* Set burn time.
|
||||
*
|
||||
* @param burnTime Burn time
|
||||
*/
|
||||
public void setBurnTime(short burnTime);
|
||||
|
||||
/**
|
||||
* Get cook time.
|
||||
*
|
||||
* @return Cook time
|
||||
*/
|
||||
public short getCookTime();
|
||||
|
||||
/**
|
||||
* Set cook time.
|
||||
*
|
||||
* @param cookTime Cook time
|
||||
*/
|
||||
public void setCookTime(short cookTime);
|
||||
|
||||
public FurnaceInventory getInventory();
|
||||
}
|
10
TacoSpigot-API/src/main/java/org/bukkit/block/Hopper.java
Normal file
10
TacoSpigot-API/src/main/java/org/bukkit/block/Hopper.java
Normal file
@ -0,0 +1,10 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Represents a hopper.
|
||||
*/
|
||||
public interface Hopper extends BlockState, InventoryHolder {
|
||||
|
||||
}
|
36
TacoSpigot-API/src/main/java/org/bukkit/block/Jukebox.java
Normal file
36
TacoSpigot-API/src/main/java/org/bukkit/block/Jukebox.java
Normal file
@ -0,0 +1,36 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
/**
|
||||
* Represents a Jukebox
|
||||
*/
|
||||
public interface Jukebox extends BlockState {
|
||||
/**
|
||||
* Get the record currently playing
|
||||
*
|
||||
* @return The record Material, or AIR if none is playing
|
||||
*/
|
||||
public Material getPlaying();
|
||||
|
||||
/**
|
||||
* Set the record currently playing
|
||||
*
|
||||
* @param record The record Material, or null/AIR to stop playing
|
||||
*/
|
||||
public void setPlaying(Material record);
|
||||
|
||||
/**
|
||||
* Check if the jukebox is currently playing a record
|
||||
*
|
||||
* @return True if there is a record playing
|
||||
*/
|
||||
public boolean isPlaying();
|
||||
|
||||
/**
|
||||
* Stop the jukebox playing and eject the current record
|
||||
*
|
||||
* @return True if a record was ejected; false if there was none playing
|
||||
*/
|
||||
public boolean eject();
|
||||
}
|
72
TacoSpigot-API/src/main/java/org/bukkit/block/NoteBlock.java
Normal file
72
TacoSpigot-API/src/main/java/org/bukkit/block/NoteBlock.java
Normal file
@ -0,0 +1,72 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.Instrument;
|
||||
import org.bukkit.Note;
|
||||
|
||||
/**
|
||||
* Represents a note.
|
||||
*/
|
||||
public interface NoteBlock extends BlockState {
|
||||
|
||||
/**
|
||||
* Gets the note.
|
||||
*
|
||||
* @return The note.
|
||||
*/
|
||||
public Note getNote();
|
||||
|
||||
/**
|
||||
* Gets the note.
|
||||
*
|
||||
* @return The note ID.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public byte getRawNote();
|
||||
|
||||
/**
|
||||
* Set the note.
|
||||
*
|
||||
* @param note The note.
|
||||
*/
|
||||
public void setNote(Note note);
|
||||
|
||||
/**
|
||||
* Set the note.
|
||||
*
|
||||
* @param note The note ID.
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public void setRawNote(byte note);
|
||||
|
||||
/**
|
||||
* Attempts to play the note at block
|
||||
* <p>
|
||||
* If the block is no longer a note block, this will return false
|
||||
*
|
||||
* @return true if successful, otherwise false
|
||||
*/
|
||||
public boolean play();
|
||||
|
||||
/**
|
||||
* Plays an arbitrary note with an arbitrary instrument
|
||||
*
|
||||
* @param instrument Instrument ID
|
||||
* @param note Note ID
|
||||
* @return true if successful, otherwise false
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean play(byte instrument, byte note);
|
||||
|
||||
/**
|
||||
* Plays an arbitrary note with an arbitrary instrument
|
||||
*
|
||||
* @param instrument The instrument
|
||||
* @param note The note
|
||||
* @return true if successful, otherwise false
|
||||
* @see Instrument Note
|
||||
*/
|
||||
public boolean play(Instrument instrument, Note note);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum PistonMoveReaction {
|
||||
|
||||
/**
|
||||
* Indicates that the block can be pushed or pulled.
|
||||
*/
|
||||
MOVE(0),
|
||||
/**
|
||||
* Indicates the block is fragile and will break if pushed on.
|
||||
*/
|
||||
BREAK(1),
|
||||
/**
|
||||
* Indicates that the block will resist being pushed or pulled.
|
||||
*/
|
||||
BLOCK(2);
|
||||
|
||||
private int id;
|
||||
private static Map<Integer, PistonMoveReaction> byId = new HashMap<Integer, PistonMoveReaction>();
|
||||
static {
|
||||
for (PistonMoveReaction reaction : PistonMoveReaction.values()) {
|
||||
byId.put(reaction.id, reaction);
|
||||
}
|
||||
}
|
||||
|
||||
private PistonMoveReaction(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ID of the move reaction
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id An ID
|
||||
* @return The move reaction with that ID
|
||||
* @deprecated Magic value
|
||||
*/
|
||||
@Deprecated
|
||||
public static PistonMoveReaction getById(int id) {
|
||||
return byId.get(id);
|
||||
}
|
||||
}
|
37
TacoSpigot-API/src/main/java/org/bukkit/block/Sign.java
Normal file
37
TacoSpigot-API/src/main/java/org/bukkit/block/Sign.java
Normal file
@ -0,0 +1,37 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
/**
|
||||
* Represents either a SignPost or a WallSign
|
||||
*/
|
||||
public interface Sign extends BlockState {
|
||||
|
||||
/**
|
||||
* Gets all the lines of text currently on this sign.
|
||||
*
|
||||
* @return Array of Strings containing each line of text
|
||||
*/
|
||||
public String[] getLines();
|
||||
|
||||
/**
|
||||
* Gets the line of text at the specified index.
|
||||
* <p>
|
||||
* For example, getLine(0) will return the first line of text.
|
||||
*
|
||||
* @param index Line number to get the text from, starting at 0
|
||||
* @throws IndexOutOfBoundsException Thrown when the line does not exist
|
||||
* @return Text on the given line
|
||||
*/
|
||||
public String getLine(int index) throws IndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the line of text at the specified index.
|
||||
* <p>
|
||||
* For example, setLine(0, "Line One") will set the first line of text to
|
||||
* "Line One".
|
||||
*
|
||||
* @param index Line number to set the text at, starting from 0
|
||||
* @param line New text to set at the specified index
|
||||
* @throws IndexOutOfBoundsException If the index is out of the range 0..3
|
||||
*/
|
||||
public void setLine(int index, String line) throws IndexOutOfBoundsException;
|
||||
}
|
62
TacoSpigot-API/src/main/java/org/bukkit/block/Skull.java
Normal file
62
TacoSpigot-API/src/main/java/org/bukkit/block/Skull.java
Normal file
@ -0,0 +1,62 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
import org.bukkit.SkullType;
|
||||
|
||||
/**
|
||||
* Represents a Skull
|
||||
*/
|
||||
public interface Skull extends BlockState {
|
||||
|
||||
/**
|
||||
* Checks to see if the skull has an owner
|
||||
*
|
||||
* @return true if the skull has an owner
|
||||
*/
|
||||
public boolean hasOwner();
|
||||
|
||||
/**
|
||||
* Gets the owner of the skull, if one exists
|
||||
*
|
||||
* @return the owner of the skull or null if the skull does not have an owner
|
||||
*/
|
||||
public String getOwner();
|
||||
|
||||
/**
|
||||
* Sets the owner of the skull
|
||||
* <p>
|
||||
* Involves a potentially blocking web request to acquire the profile data for
|
||||
* the provided name.
|
||||
*
|
||||
* @param name the new owner of the skull
|
||||
* @return true if the owner was successfully set
|
||||
*/
|
||||
public boolean setOwner(String name);
|
||||
|
||||
/**
|
||||
* Gets the rotation of the skull in the world
|
||||
*
|
||||
* @return the rotation of the skull
|
||||
*/
|
||||
public BlockFace getRotation();
|
||||
|
||||
/**
|
||||
* Sets the rotation of the skull in the world
|
||||
*
|
||||
* @param rotation the rotation of the skull
|
||||
*/
|
||||
public void setRotation(BlockFace rotation);
|
||||
|
||||
/**
|
||||
* Gets the type of skull
|
||||
*
|
||||
* @return the type of skull
|
||||
*/
|
||||
public SkullType getSkullType();
|
||||
|
||||
/**
|
||||
* Sets the type of skull
|
||||
*
|
||||
* @param skullType the type of skull
|
||||
*/
|
||||
public void setSkullType(SkullType skullType);
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package org.bukkit.block.banner;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.SerializableAs;
|
||||
|
||||
@SerializableAs("Pattern")
|
||||
public class Pattern implements ConfigurationSerializable {
|
||||
|
||||
private static final String COLOR = "color";
|
||||
private static final String PATTERN = "pattern";
|
||||
|
||||
private final DyeColor color;
|
||||
private final PatternType pattern;
|
||||
|
||||
/**
|
||||
* Creates a new pattern from the specified color and
|
||||
* pattern type
|
||||
*
|
||||
* @param color the pattern color
|
||||
* @param pattern the pattern type
|
||||
*/
|
||||
public Pattern(DyeColor color, PatternType pattern) {
|
||||
this.color = color;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for deserialization.
|
||||
*
|
||||
* @param map the map to deserialize from
|
||||
*/
|
||||
public Pattern(Map<String, Object> map) {
|
||||
color = DyeColor.valueOf(getString(map, COLOR));
|
||||
pattern = PatternType.getByIdentifier(getString(map, PATTERN));
|
||||
}
|
||||
|
||||
private static String getString(Map<?,?> map, Object key) {
|
||||
Object str = map.get(key);
|
||||
if (str instanceof String) {
|
||||
return (String) str;
|
||||
}
|
||||
throw new NoSuchElementException(map + " does not contain " + key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
return ImmutableMap.<String, Object>of(
|
||||
COLOR, color.toString(),
|
||||
PATTERN, pattern.getIdentifier()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of the pattern
|
||||
*
|
||||
* @return the color of the pattern
|
||||
*/
|
||||
public DyeColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of pattern
|
||||
*
|
||||
* @return the pattern type
|
||||
*/
|
||||
public PatternType getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 97 * hash + (this.color != null ? this.color.hashCode() : 0);
|
||||
hash = 97 * hash + (this.pattern != null ? this.pattern.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Pattern other = (Pattern) obj;
|
||||
return this.color == other.color && this.pattern == other.pattern;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package org.bukkit.block.banner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum PatternType {
|
||||
BASE("b"),
|
||||
SQUARE_BOTTOM_LEFT("bl"),
|
||||
SQUARE_BOTTOM_RIGHT("br"),
|
||||
SQUARE_TOP_LEFT("tl"),
|
||||
SQUARE_TOP_RIGHT("tr"),
|
||||
STRIPE_BOTTOM("bs"),
|
||||
STRIPE_TOP("ts"),
|
||||
STRIPE_LEFT("ls"),
|
||||
STRIPE_RIGHT("rs"),
|
||||
STRIPE_CENTER("cs"),
|
||||
STRIPE_MIDDLE("ms"),
|
||||
STRIPE_DOWNRIGHT("drs"),
|
||||
STRIPE_DOWNLEFT("dls"),
|
||||
STRIPE_SMALL("ss"),
|
||||
CROSS("cr"),
|
||||
STRAIGHT_CROSS("sc"),
|
||||
TRIANGLE_BOTTOM("bt"),
|
||||
TRIANGLE_TOP("tt"),
|
||||
TRIANGLES_BOTTOM("bts"),
|
||||
TRIANGLES_TOP("tts"),
|
||||
DIAGONAL_LEFT("ld"),
|
||||
DIAGONAL_RIGHT("rd"),
|
||||
DIAGONAL_LEFT_MIRROR("lud"),
|
||||
DIAGONAL_RIGHT_MIRROR("rud"),
|
||||
CIRCLE_MIDDLE("mc"),
|
||||
RHOMBUS_MIDDLE("mr"),
|
||||
HALF_VERTICAL("vh"),
|
||||
HALF_HORIZONTAL("hh"),
|
||||
HALF_VERTICAL_MIRROR("vhr"),
|
||||
HALF_HORIZONTAL_MIRROR("hhb"),
|
||||
BORDER("bo"),
|
||||
CURLY_BORDER("cbo"),
|
||||
CREEPER("cre"),
|
||||
GRADIENT("gra"),
|
||||
GRADIENT_UP("gru"),
|
||||
BRICKS("bri"),
|
||||
SKULL("sku"),
|
||||
FLOWER("flo"),
|
||||
MOJANG("moj");
|
||||
|
||||
private final String identifier;
|
||||
private static final Map<String, PatternType> byString = new HashMap<String, PatternType>();
|
||||
|
||||
static {
|
||||
for (PatternType p : values()) {
|
||||
byString.put(p.identifier, p);
|
||||
}
|
||||
}
|
||||
|
||||
private PatternType(String key) {
|
||||
this.identifier = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier used to represent
|
||||
* this pattern type
|
||||
*
|
||||
* @return the pattern's identifier
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern type which matches the passed
|
||||
* identifier or null if no matches are found
|
||||
*
|
||||
* @param identifier the identifier
|
||||
* @return the matched pattern type or null
|
||||
*/
|
||||
public static PatternType getByIdentifier(String identifier) {
|
||||
return byString.get(identifier);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public interface BlockCommandSender extends CommandSender {
|
||||
|
||||
/**
|
||||
* Returns the block this command sender belongs to
|
||||
*
|
||||
* @return Block for the command sender
|
||||
*/
|
||||
public Block getBlock();
|
||||
}
|
450
TacoSpigot-API/src/main/java/org/bukkit/command/Command.java
Normal file
450
TacoSpigot-API/src/main/java/org/bukkit/command/Command.java
Normal file
@ -0,0 +1,450 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.minecart.CommandMinecart;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Represents a Command, which executes various tasks upon user input
|
||||
*/
|
||||
public abstract class Command {
|
||||
private String name;
|
||||
private String nextLabel;
|
||||
private String label;
|
||||
private List<String> aliases;
|
||||
private List<String> activeAliases;
|
||||
private CommandMap commandMap = null;
|
||||
protected String description = "";
|
||||
protected String usageMessage;
|
||||
private String permission;
|
||||
private String permissionMessage;
|
||||
public co.aikar.timings.Timing timings; // Spigot
|
||||
public String getTimingName() {return getName();} // Spigot
|
||||
|
||||
protected Command(String name) {
|
||||
this(name, "", "/" + name, new ArrayList<String>());
|
||||
}
|
||||
|
||||
protected Command(String name, String description, String usageMessage, List<String> aliases) {
|
||||
this.name = name;
|
||||
this.nextLabel = name;
|
||||
this.label = name;
|
||||
this.description = description;
|
||||
this.usageMessage = usageMessage;
|
||||
this.aliases = aliases;
|
||||
this.activeAliases = new ArrayList<String>(aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the command, returning its success
|
||||
*
|
||||
* @param sender Source object which is executing this command
|
||||
* @param commandLabel The alias of the command used
|
||||
* @param args All arguments passed to the command, split via ' '
|
||||
* @return true if the command was successful, otherwise false
|
||||
*/
|
||||
public abstract boolean execute(CommandSender sender, String commandLabel, String[] args);
|
||||
|
||||
/**
|
||||
* Executed on tab completion for this command, returning a list of
|
||||
* options the player can tab through.
|
||||
*
|
||||
* @deprecated This method is not supported and returns null
|
||||
* @param sender Source object which is executing this command
|
||||
* @param args All arguments passed to the command, split via ' '
|
||||
* @return a list of tab-completions for the specified arguments. This
|
||||
* will never be null. List may be immutable.
|
||||
*/
|
||||
@Deprecated
|
||||
public List<String> tabComplete(CommandSender sender, String[] args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed on tab completion for this command, returning a list of
|
||||
* options the player can tab through.
|
||||
*
|
||||
* @param sender Source object which is executing this command
|
||||
* @param alias the alias being used
|
||||
* @param args All arguments passed to the command, split via ' '
|
||||
* @return a list of tab-completions for the specified arguments. This
|
||||
* will never be null. List may be immutable.
|
||||
* @throws IllegalArgumentException if sender, alias, or args is null
|
||||
*/
|
||||
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");
|
||||
|
||||
if (args.length == 0) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
String lastWord = args[args.length - 1];
|
||||
|
||||
Player senderPlayer = sender instanceof Player ? (Player) sender : null;
|
||||
|
||||
ArrayList<String> matchedPlayers = new ArrayList<String>();
|
||||
for (Player player : sender.getServer().getOnlinePlayers()) {
|
||||
String name = player.getName();
|
||||
if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
|
||||
matchedPlayers.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER);
|
||||
return matchedPlayers;
|
||||
}
|
||||
|
||||
// PaperSpigot start - location tab-completes
|
||||
/**
|
||||
* Executed on tab completion for this command, returning a list of options the player can tab through. This method
|
||||
* returns the {@link Location} of the block the player is looking at at the time of the tab complete.
|
||||
* <p>
|
||||
* Commands that want to use the Location information in their tab-complete implementations need to override this
|
||||
* method. The Location provided by this method is the block that the player is currently looking at when the player
|
||||
* attempts the tab complete. For this to be valid, the block must be highlighted by the player (i.e. the player is
|
||||
* close enough to interact with the block).
|
||||
*
|
||||
* @param sender Source object which is executing this command
|
||||
* @param alias the alias being used
|
||||
* @param args All arguments passed to the command, split via ' '
|
||||
* @param location the location of the block the player is looking at
|
||||
* @return a list of tab-completions for the specified arguments. This
|
||||
* will never be null. List may be immutable.
|
||||
* @throws IllegalArgumentException if sender, alias, or args is null
|
||||
*/
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
|
||||
// Simply default to the standard tab-complete, subclasses can override this if needed
|
||||
return tabComplete(sender, alias, args);
|
||||
}
|
||||
// PaperSpigot end
|
||||
|
||||
/**
|
||||
* Returns the name of this command
|
||||
*
|
||||
* @return Name of this command
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of this command.
|
||||
* <p>
|
||||
* May only be used before registering the command.
|
||||
* Will return true if the new name is set, and false
|
||||
* if the command has already been registered.
|
||||
*
|
||||
* @param name New command name
|
||||
* @return returns true if the name change happened instantly or false if
|
||||
* the command was already registered
|
||||
*/
|
||||
public boolean setName(String name) {
|
||||
if (!isRegistered()) {
|
||||
this.name = name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permission required by users to be able to perform this
|
||||
* command
|
||||
*
|
||||
* @return Permission name, or null if none
|
||||
*/
|
||||
public String getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the permission required by users to be able to perform this
|
||||
* command
|
||||
*
|
||||
* @param permission Permission name or null
|
||||
*/
|
||||
public void setPermission(String permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the given {@link CommandSender} to see if they can perform this
|
||||
* command.
|
||||
* <p>
|
||||
* If they do not have permission, they will be informed that they cannot
|
||||
* do this.
|
||||
*
|
||||
* @param target User to test
|
||||
* @return true if they can use it, otherwise false
|
||||
*/
|
||||
public boolean testPermission(CommandSender target) {
|
||||
if (testPermissionSilent(target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (permissionMessage == null) {
|
||||
target.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.");
|
||||
} else if (permissionMessage.length() != 0) {
|
||||
for (String line : permissionMessage.replace("<permission>", permission).split("\n")) {
|
||||
target.sendMessage(line);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the given {@link CommandSender} to see if they can perform this
|
||||
* command.
|
||||
* <p>
|
||||
* No error is sent to the sender.
|
||||
*
|
||||
* @param target User to test
|
||||
* @return true if they can use it, otherwise false
|
||||
*/
|
||||
public boolean testPermissionSilent(CommandSender target) {
|
||||
if ((permission == null) || (permission.length() == 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String p : permission.split(";")) {
|
||||
if (target.hasPermission(p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label for this command
|
||||
*
|
||||
* @return Label of this command
|
||||
*/
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the label of this command.
|
||||
* <p>
|
||||
* May only be used before registering the command.
|
||||
* Will return true if the new name is set, and false
|
||||
* if the command has already been registered.
|
||||
*
|
||||
* @param name The command's name
|
||||
* @return returns true if the name change happened instantly or false if
|
||||
* the command was already registered
|
||||
*/
|
||||
public boolean setLabel(String name) {
|
||||
this.nextLabel = name;
|
||||
if (!isRegistered()) {
|
||||
this.label = name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this command to a CommandMap.
|
||||
* Once called it only allows changes the registered CommandMap
|
||||
*
|
||||
* @param commandMap the CommandMap to register this command to
|
||||
* @return true if the registration was successful (the current registered
|
||||
* CommandMap was the passed CommandMap or null) false otherwise
|
||||
*/
|
||||
public boolean register(CommandMap commandMap) {
|
||||
if (allowChangesFrom(commandMap)) {
|
||||
this.commandMap = commandMap;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this command from the passed CommandMap applying any
|
||||
* outstanding changes
|
||||
*
|
||||
* @param commandMap the CommandMap to unregister
|
||||
* @return true if the unregistration was successfull (the current
|
||||
* registered CommandMap was the passed CommandMap or null) false
|
||||
* otherwise
|
||||
*/
|
||||
public boolean unregister(CommandMap commandMap) {
|
||||
if (allowChangesFrom(commandMap)) {
|
||||
this.commandMap = null;
|
||||
this.activeAliases = new ArrayList<String>(this.aliases);
|
||||
this.label = this.nextLabel;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allowChangesFrom(CommandMap commandMap) {
|
||||
return (null == this.commandMap || this.commandMap == commandMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current registered state of this command
|
||||
*
|
||||
* @return true if this command is currently registered false otherwise
|
||||
*/
|
||||
public boolean isRegistered() {
|
||||
return (null != this.commandMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of active aliases of this command
|
||||
*
|
||||
* @return List of aliases
|
||||
*/
|
||||
public List<String> getAliases() {
|
||||
return activeAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a message to be displayed on a failed permission check for this
|
||||
* command
|
||||
*
|
||||
* @return Permission check failed message
|
||||
*/
|
||||
public String getPermissionMessage() {
|
||||
return permissionMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a brief description of this command
|
||||
*
|
||||
* @return Description of this command
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an example usage of this command
|
||||
*
|
||||
* @return One or more example usages
|
||||
*/
|
||||
public String getUsage() {
|
||||
return usageMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of aliases to request on registration for this command.
|
||||
* This is not effective outside of defining aliases in the {@link
|
||||
* PluginDescriptionFile#getCommands()} (under the
|
||||
* `<code>aliases</code>' node) is equivalent to this method.
|
||||
*
|
||||
* @param aliases aliases to register to this command
|
||||
* @return this command object, for chaining
|
||||
*/
|
||||
public Command setAliases(List<String> aliases) {
|
||||
this.aliases = aliases;
|
||||
if (!isRegistered()) {
|
||||
this.activeAliases = new ArrayList<String>(aliases);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a brief description of this command. Defining a description in the
|
||||
* {@link PluginDescriptionFile#getCommands()} (under the
|
||||
* `<code>description</code>' node) is equivalent to this method.
|
||||
*
|
||||
* @param description new command description
|
||||
* @return this command object, for chaining
|
||||
*/
|
||||
public Command setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message sent when a permission check fails
|
||||
*
|
||||
* @param permissionMessage new permission message, null to indicate
|
||||
* default message, or an empty string to indicate no message
|
||||
* @return this command object, for chaining
|
||||
*/
|
||||
public Command setPermissionMessage(String permissionMessage) {
|
||||
this.permissionMessage = permissionMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the example usage of this command
|
||||
*
|
||||
* @param usage new example usage
|
||||
* @return this command object, for chaining
|
||||
*/
|
||||
public Command setUsage(String usage) {
|
||||
this.usageMessage = usage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static void broadcastCommandMessage(CommandSender source, String message) {
|
||||
broadcastCommandMessage(source, message, true);
|
||||
}
|
||||
|
||||
public static void broadcastCommandMessage(CommandSender source, String message, boolean sendToSource) {
|
||||
String result = source.getName() + ": " + message;
|
||||
|
||||
if (source instanceof BlockCommandSender) {
|
||||
BlockCommandSender blockCommandSender = (BlockCommandSender) source;
|
||||
|
||||
if (blockCommandSender.getBlock().getWorld().getGameRuleValue("commandBlockOutput").equalsIgnoreCase("false")) {
|
||||
Bukkit.getConsoleSender().sendMessage(result);
|
||||
return;
|
||||
}
|
||||
} else if (source instanceof CommandMinecart) {
|
||||
CommandMinecart commandMinecart = (CommandMinecart) source;
|
||||
|
||||
if (commandMinecart.getWorld().getGameRuleValue("commandBlockOutput").equalsIgnoreCase("false")) {
|
||||
Bukkit.getConsoleSender().sendMessage(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Set<Permissible> users = Bukkit.getPluginManager().getPermissionSubscriptions(Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
||||
String colored = ChatColor.GRAY + "" + ChatColor.ITALIC + "[" + result + ChatColor.GRAY + ChatColor.ITALIC + "]";
|
||||
|
||||
if (sendToSource && !(source instanceof ConsoleCommandSender)) {
|
||||
source.sendMessage(message);
|
||||
}
|
||||
|
||||
for (Permissible user : users) {
|
||||
if (user instanceof CommandSender) {
|
||||
CommandSender target = (CommandSender) user;
|
||||
|
||||
if (target instanceof ConsoleCommandSender) {
|
||||
target.sendMessage(result);
|
||||
} else if (target != source) {
|
||||
target.sendMessage(colored);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + '(' + name + ')';
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
/**
|
||||
* Thrown when an unhandled exception occurs during the execution of a Command
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CommandException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>CommandException</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public CommandException() {}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>CommandException</code> with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public CommandException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CommandException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
/**
|
||||
* Represents a class which contains a single method for executing commands
|
||||
*/
|
||||
public interface CommandExecutor {
|
||||
|
||||
/**
|
||||
* Executes the given command, returning its success
|
||||
*
|
||||
* @param sender Source of the command
|
||||
* @param command Command which was executed
|
||||
* @param label Alias of the command which was used
|
||||
* @param args Passed command arguments
|
||||
* @return true if a valid command, otherwise false
|
||||
*/
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args);
|
||||
}
|
109
TacoSpigot-API/src/main/java/org/bukkit/command/CommandMap.java
Normal file
109
TacoSpigot-API/src/main/java/org/bukkit/command/CommandMap.java
Normal file
@ -0,0 +1,109 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CommandMap {
|
||||
|
||||
/**
|
||||
* Registers all the commands belonging to a certain plugin.
|
||||
* <p>
|
||||
* Caller can use:-
|
||||
* <ul>
|
||||
* <li>command.getName() to determine the label registered for this
|
||||
* command
|
||||
* <li>command.getAliases() to determine the aliases which where
|
||||
* registered
|
||||
* </ul>
|
||||
*
|
||||
* @param fallbackPrefix a prefix which is prepended to each command with
|
||||
* a ':' one or more times to make the command unique
|
||||
* @param commands a list of commands to register
|
||||
*/
|
||||
public void registerAll(String fallbackPrefix, List<Command> commands);
|
||||
|
||||
/**
|
||||
* Registers a command. Returns true on success; false if name is already
|
||||
* taken and fallback had to be used.
|
||||
* <p>
|
||||
* Caller can use:-
|
||||
* <ul>
|
||||
* <li>command.getName() to determine the label registered for this
|
||||
* command
|
||||
* <li>command.getAliases() to determine the aliases which where
|
||||
* registered
|
||||
* </ul>
|
||||
*
|
||||
* @param label the label of the command, without the '/'-prefix.
|
||||
* @param fallbackPrefix a prefix which is prepended to the command with a
|
||||
* ':' one or more times to make the command unique
|
||||
* @param command the command to register
|
||||
* @return true if command was registered with the passed in label, false
|
||||
* otherwise, which indicates the fallbackPrefix was used one or more
|
||||
* times
|
||||
*/
|
||||
public boolean register(String label, String fallbackPrefix, Command command);
|
||||
|
||||
/**
|
||||
* Registers a command. Returns true on success; false if name is already
|
||||
* taken and fallback had to be used.
|
||||
* <p>
|
||||
* Caller can use:-
|
||||
* <ul>
|
||||
* <li>command.getName() to determine the label registered for this
|
||||
* command
|
||||
* <li>command.getAliases() to determine the aliases which where
|
||||
* registered
|
||||
* </ul>
|
||||
*
|
||||
* @param fallbackPrefix a prefix which is prepended to the command with a
|
||||
* ':' one or more times to make the command unique
|
||||
* @param command the command to register, from which label is determined
|
||||
* from the command name
|
||||
* @return true if command was registered with the passed in label, false
|
||||
* otherwise, which indicates the fallbackPrefix was used one or more
|
||||
* times
|
||||
*/
|
||||
public boolean register(String fallbackPrefix, Command command);
|
||||
|
||||
/**
|
||||
* Looks for the requested command and executes it if found.
|
||||
*
|
||||
* @param sender The command's sender
|
||||
* @param cmdLine command + arguments. Example: "/test abc 123"
|
||||
* @return returns false if no target is found, true otherwise.
|
||||
* @throws CommandException Thrown when the executor for the given command
|
||||
* fails with an unhandled exception
|
||||
*/
|
||||
public boolean dispatch(CommandSender sender, String cmdLine) throws CommandException;
|
||||
|
||||
/**
|
||||
* Clears all registered commands.
|
||||
*/
|
||||
public void clearCommands();
|
||||
|
||||
/**
|
||||
* Gets the command registered to the specified name
|
||||
*
|
||||
* @param name Name of the command to retrieve
|
||||
* @return Command with the specified name or null if a command with that
|
||||
* label doesn't exist
|
||||
*/
|
||||
public Command getCommand(String name);
|
||||
|
||||
|
||||
/**
|
||||
* Looks for the requested command and executes an appropriate
|
||||
* tab-completer if found. This method will also tab-complete partial
|
||||
* commands.
|
||||
*
|
||||
* @param sender The command's sender.
|
||||
* @param cmdLine The entire command string to tab-complete, excluding
|
||||
* initial slash.
|
||||
* @return a list of possible tab-completions. This list may be immutable.
|
||||
* Will be null if no matching command of which sender has permission.
|
||||
* @throws CommandException Thrown when the tab-completer for the given
|
||||
* command fails with an unhandled exception
|
||||
* @throws IllegalArgumentException if either sender or cmdLine are null
|
||||
*/
|
||||
public List<String> tabComplete(CommandSender sender, String cmdLine) throws IllegalArgumentException;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
|
||||
public interface CommandSender extends Permissible {
|
||||
|
||||
/**
|
||||
* Sends this sender a message
|
||||
*
|
||||
* @param message Message to be displayed
|
||||
*/
|
||||
public void sendMessage(String message);
|
||||
|
||||
/**
|
||||
* Sends this sender multiple messages
|
||||
*
|
||||
* @param messages An array of messages to be displayed
|
||||
*/
|
||||
public void sendMessage(String[] messages);
|
||||
|
||||
/**
|
||||
* Returns the server instance that this command is running on
|
||||
*
|
||||
* @return Server instance
|
||||
*/
|
||||
public Server getServer();
|
||||
|
||||
/**
|
||||
* Gets the name of this command sender
|
||||
*
|
||||
* @return Name of the sender
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
// Paper start
|
||||
/**
|
||||
* Sends the component to the sender
|
||||
*
|
||||
* <p>If this sender does not support sending full components then
|
||||
* the component will be sent as legacy text.</p>
|
||||
*
|
||||
* @param component the component to send
|
||||
*/
|
||||
default void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
this.sendMessage(component.toLegacyText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an array of components as a single message to the sender
|
||||
*
|
||||
* <p>If this sender does not support sending full components then
|
||||
* the components will be sent as legacy text.</p>
|
||||
*
|
||||
* @param components the components to send
|
||||
*/
|
||||
default void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
this.sendMessage(new net.md_5.bungee.api.chat.TextComponent(components).toLegacyText());
|
||||
}
|
||||
// Paper end
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import org.bukkit.conversations.Conversable;
|
||||
|
||||
public interface ConsoleCommandSender extends CommandSender, Conversable {
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.server.RemoteServerCommandEvent;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
|
||||
public class FormattedCommandAlias extends Command {
|
||||
private final String[] formatStrings;
|
||||
|
||||
public FormattedCommandAlias(String alias, String[] formatStrings) {
|
||||
super(alias);
|
||||
timings = co.aikar.timings.TimingsManager.getCommandTiming("minecraft", this); // Spigot
|
||||
this.formatStrings = formatStrings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
||||
boolean result = false;
|
||||
ArrayList<String> commands = new ArrayList<String>();
|
||||
for (String formatString : formatStrings) {
|
||||
try {
|
||||
commands.add(buildCommand(formatString, args));
|
||||
} catch (Throwable throwable) {
|
||||
if (throwable instanceof IllegalArgumentException) {
|
||||
sender.sendMessage(throwable.getMessage());
|
||||
} else {
|
||||
sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (String command : commands) {
|
||||
result |= Bukkit.dispatchCommand(sender, command);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildCommand(String formatString, String[] args) {
|
||||
int index = formatString.indexOf("$");
|
||||
while (index != -1) {
|
||||
int start = index;
|
||||
|
||||
if (index > 0 && formatString.charAt(start - 1) == '\\') {
|
||||
formatString = formatString.substring(0, start - 1) + formatString.substring(start);
|
||||
index = formatString.indexOf("$", index);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean required = false;
|
||||
if (formatString.charAt(index + 1) == '$') {
|
||||
required = true;
|
||||
// Move index past the second $
|
||||
index++;
|
||||
}
|
||||
|
||||
// Move index past the $
|
||||
index++;
|
||||
int argStart = index;
|
||||
while (index < formatString.length() && inRange(((int) formatString.charAt(index)) - 48, 0, 9)) {
|
||||
// Move index past current digit
|
||||
index++;
|
||||
}
|
||||
|
||||
// No numbers found
|
||||
if (argStart == index) {
|
||||
throw new IllegalArgumentException("Invalid replacement token");
|
||||
}
|
||||
|
||||
int position = Integer.valueOf(formatString.substring(argStart, index));
|
||||
|
||||
// Arguments are not 0 indexed
|
||||
if (position == 0) {
|
||||
throw new IllegalArgumentException("Invalid replacement token");
|
||||
}
|
||||
|
||||
// Convert position to 0 index
|
||||
position--;
|
||||
|
||||
boolean rest = false;
|
||||
if (index < formatString.length() && formatString.charAt(index) == '-') {
|
||||
rest = true;
|
||||
// Move index past the -
|
||||
index++;
|
||||
}
|
||||
|
||||
int end = index;
|
||||
|
||||
if (required && position >= args.length) {
|
||||
throw new IllegalArgumentException("Missing required argument " + (position + 1));
|
||||
}
|
||||
|
||||
StringBuilder replacement = new StringBuilder();
|
||||
if (rest && position < args.length) {
|
||||
for (int i = position; i < args.length; i++) {
|
||||
if (i != position) {
|
||||
replacement.append(' ');
|
||||
}
|
||||
replacement.append(args[i]);
|
||||
}
|
||||
} else if (position < args.length) {
|
||||
replacement.append(args[position]);
|
||||
}
|
||||
|
||||
formatString = formatString.substring(0, start) + replacement.toString() + formatString.substring(end);
|
||||
// Move index past the replaced data so we don't process it again
|
||||
index = start + replacement.length();
|
||||
|
||||
// Move to the next replacement token
|
||||
index = formatString.indexOf("$", index);
|
||||
}
|
||||
|
||||
return formatString;
|
||||
}
|
||||
|
||||
@Override // Spigot
|
||||
public String getTimingName() {return "Command Forwarder - " + super.getTimingName();} // Spigot
|
||||
|
||||
private static boolean inRange(int i, int j, int k) {
|
||||
return i >= j && i <= k;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
/**
|
||||
* Represents a command that delegates to one or more other commands
|
||||
*/
|
||||
public class MultipleCommandAlias extends Command {
|
||||
private Command[] commands;
|
||||
|
||||
public MultipleCommandAlias(String name, Command[] commands) {
|
||||
super(name);
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the commands associated with the multi-command alias.
|
||||
*
|
||||
* @return commands associated with alias
|
||||
*/
|
||||
public Command[] getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
||||
boolean result = false;
|
||||
|
||||
for (Command command : commands) {
|
||||
result |= command.execute(sender, commandLabel, args);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a {@link Command} belonging to a plugin
|
||||
*/
|
||||
public final class PluginCommand extends Command implements PluginIdentifiableCommand {
|
||||
private final Plugin owningPlugin;
|
||||
private CommandExecutor executor;
|
||||
private TabCompleter completer;
|
||||
|
||||
protected PluginCommand(String name, Plugin owner) {
|
||||
super(name);
|
||||
this.executor = owner;
|
||||
this.owningPlugin = owner;
|
||||
this.usageMessage = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the command, returning its success
|
||||
*
|
||||
* @param sender Source object which is executing this command
|
||||
* @param commandLabel The alias of the command used
|
||||
* @param args All arguments passed to the command, split via ' '
|
||||
* @return true if the command was successful, otherwise false
|
||||
*/
|
||||
@Override
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
|
||||
boolean success = false;
|
||||
|
||||
if (!owningPlugin.isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!testPermission(sender)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
success = executor.onCommand(sender, this, commandLabel, args);
|
||||
} catch (Throwable ex) {
|
||||
throw new CommandException("Unhandled exception executing command '" + commandLabel + "' in plugin " + owningPlugin.getDescription().getFullName(), ex);
|
||||
}
|
||||
|
||||
if (!success && usageMessage.length() > 0) {
|
||||
for (String line : usageMessage.replace("<command>", commandLabel).split("\n")) {
|
||||
sender.sendMessage(line);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link CommandExecutor} to run when parsing this command
|
||||
*
|
||||
* @param executor New executor to run
|
||||
*/
|
||||
public void setExecutor(CommandExecutor executor) {
|
||||
this.executor = executor == null ? owningPlugin : executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link CommandExecutor} associated with this command
|
||||
*
|
||||
* @return CommandExecutor object linked to this command
|
||||
*/
|
||||
public CommandExecutor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TabCompleter} to run when tab-completing this command.
|
||||
* <p>
|
||||
* If no TabCompleter is specified, and the command's executor implements
|
||||
* TabCompleter, then the executor will be used for tab completion.
|
||||
*
|
||||
* @param completer New tab completer
|
||||
*/
|
||||
public void setTabCompleter(TabCompleter completer) {
|
||||
this.completer = completer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link TabCompleter} associated with this command.
|
||||
*
|
||||
* @return TabCompleter object linked to this command
|
||||
*/
|
||||
public TabCompleter getTabCompleter() {
|
||||
return completer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owner of this PluginCommand
|
||||
*
|
||||
* @return Plugin that owns this command
|
||||
*/
|
||||
public Plugin getPlugin() {
|
||||
return owningPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* Delegates to the tab completer if present.
|
||||
* <p>
|
||||
* If it is not present or returns null, will delegate to the current
|
||||
* command executor if it implements {@link TabCompleter}. If a non-null
|
||||
* list has not been found, will default to standard player name
|
||||
* completion in {@link
|
||||
* Command#tabComplete(CommandSender, String, String[])}.
|
||||
* <p>
|
||||
* This method does not consider permissions.
|
||||
*
|
||||
* @throws CommandException if the completer or executor throw an
|
||||
* exception during the process of tab-completing.
|
||||
* @throws IllegalArgumentException if sender, alias, or args is null
|
||||
*/
|
||||
@Override
|
||||
public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException {
|
||||
return tabComplete(sender, alias, args, null); // PaperSpigot - The code from this method has been (slightly modified) moved to the Location method.
|
||||
}
|
||||
|
||||
// PaperSpigot start - location tab-completes
|
||||
/**
|
||||
* This code was copied from tabComplete(CommandSender sender, String alias, String[] args)
|
||||
*/
|
||||
@Override
|
||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws CommandException, IllegalArgumentException {
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
|
||||
List<String> completions = null;
|
||||
try {
|
||||
if (completer != null) {
|
||||
completions = completer.onTabComplete(sender, this, alias, args, location); // PaperSpigot - add location argument
|
||||
}
|
||||
if (completions == null && executor instanceof TabCompleter) {
|
||||
completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args, location); // PaperSpigot - add location argument
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("Unhandled exception during tab completion for command '/").append(alias).append(' ');
|
||||
for (String arg : args) {
|
||||
message.append(arg).append(' ');
|
||||
}
|
||||
message.deleteCharAt(message.length() - 1).append("' in plugin ").append(owningPlugin.getDescription().getFullName());
|
||||
throw new CommandException(message.toString(), ex);
|
||||
}
|
||||
|
||||
if (completions == null) {
|
||||
return super.tabComplete(sender, alias, args);
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
// PaperSpigot end
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder(super.toString());
|
||||
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
|
||||
stringBuilder.append(", ").append(owningPlugin.getDescription().getFullName()).append(')');
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class PluginCommandYamlParser {
|
||||
|
||||
public static List<Command> parse(Plugin plugin) {
|
||||
List<Command> pluginCmds = new ArrayList<Command>();
|
||||
|
||||
Map<String, Map<String, Object>> map = plugin.getDescription().getCommands();
|
||||
|
||||
if (map == null) {
|
||||
return pluginCmds;
|
||||
}
|
||||
|
||||
for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
|
||||
if (entry.getKey().contains(":")) {
|
||||
Bukkit.getServer().getLogger().severe("Could not load command " + entry.getKey() + " for plugin " + plugin.getName() + ": Illegal Characters");
|
||||
continue;
|
||||
}
|
||||
Command newCmd = new PluginCommand(entry.getKey(), plugin);
|
||||
Object description = entry.getValue().get("description");
|
||||
Object usage = entry.getValue().get("usage");
|
||||
Object aliases = entry.getValue().get("aliases");
|
||||
Object permission = entry.getValue().get("permission");
|
||||
Object permissionMessage = entry.getValue().get("permission-message");
|
||||
|
||||
if (description != null) {
|
||||
newCmd.setDescription(description.toString());
|
||||
}
|
||||
|
||||
if (usage != null) {
|
||||
newCmd.setUsage(usage.toString());
|
||||
}
|
||||
|
||||
if (aliases != null) {
|
||||
List<String> aliasList = new ArrayList<String>();
|
||||
|
||||
if (aliases instanceof List) {
|
||||
for (Object o : (List<?>) aliases) {
|
||||
if (o.toString().contains(":")) {
|
||||
Bukkit.getServer().getLogger().severe("Could not load alias " + o.toString() + " for plugin " + plugin.getName() + ": Illegal Characters");
|
||||
continue;
|
||||
}
|
||||
aliasList.add(o.toString());
|
||||
}
|
||||
} else {
|
||||
if (aliases.toString().contains(":")) {
|
||||
Bukkit.getServer().getLogger().severe("Could not load alias " + aliases.toString() + " for plugin " + plugin.getName() + ": Illegal Characters");
|
||||
} else {
|
||||
aliasList.add(aliases.toString());
|
||||
}
|
||||
}
|
||||
|
||||
newCmd.setAliases(aliasList);
|
||||
}
|
||||
|
||||
if (permission != null) {
|
||||
newCmd.setPermission(permission.toString());
|
||||
}
|
||||
|
||||
if (permissionMessage != null) {
|
||||
newCmd.setPermissionMessage(permissionMessage.toString());
|
||||
}
|
||||
|
||||
pluginCmds.add(newCmd);
|
||||
}
|
||||
return pluginCmds;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user