Clout Gang ❤️

This commit is contained in:
disclearing 2019-06-30 23:06:59 +01:00
parent d8aeae8eb1
commit 69e542773e
2855 changed files with 215074 additions and 0 deletions

1
RageSpigot/.idea/.name Normal file
View File

@ -0,0 +1 @@
ragespigot-parent

View File

@ -0,0 +1,28 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<DBN-PSQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="false">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
</code_scheme>
</component>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="ragespigot" />
<module name="ragespigot-api" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="ragespigot" target="1.8" />
<module name="ragespigot-api" target="1.8" />
<module name="ragespigot-parent" target="1.5" />
</bytecodeTargetLevel>
</component>
</project>

View File

@ -0,0 +1,453 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DataExportManager">
<export-instructions>
<create-header value="true" />
<quote-values-containing-separator value="true" />
<quote-all-values value="false" />
<value-separator value="" />
<file-name value="" />
<file-location value="" />
<scope value="GLOBAL" />
<destination value="FILE" />
<format value="EXCEL" />
<charset value="windows-1252" />
</export-instructions>
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="true" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.EditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.MethodExecutionManager">
<method-browser />
<execution-history>
<group-entries value="true" />
<execution-inputs />
</execution-history>
<argument-values-cache />
</component>
<component name="DBNavigator.Project.ObjectDependencyManager">
<last-used-dependency-type value="INCOMING" />
</component>
<component name="DBNavigator.Project.ObjectQuickFilterManager">
<last-used-operator value="EQUAL" />
<filters />
</component>
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true">
<recently-used-interfaces />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="NESTED TABLE" enabled="false" />
<object-type name="COLUMN" enabled="false" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE ATTRIBUTE" enabled="false" />
<object-type name="ARGUMENT" enabled="false" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
<enable-column-tooltip value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<tracking-columns>
<columnNames value="" />
<visible value="true" />
<editable value="false" />
</tracking-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-list-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-list-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="Properties" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="Java" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="Groovy" enabled="true" />
<content-type name="AIDL" enabled="true" />
<content-type name="YAML" enabled="true" />
<content-type name="Manifest" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
<enable-spellchecking value="true" />
<enable-reference-spellchecking value="false" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
<debugger>
<debugger-type value="ASK" />
<use-generic-runners value="true" />
</debugger>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
<component name="DBNavigator.Project.StatementExecutionManager">
<execution-variables />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/RageSpigot-API" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/RageSpigot-Server" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.google.code.gson:gson:2.8.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.0/gson-2.8.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.0/gson-2.8.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.google.guava:guava:19.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/19.0/guava-19.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/19.0/guava-19.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/19.0/guava-19.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.googlecode.json-simple:json-simple:1.1.1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: commons-lang:commons-lang:2.6">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.6/commons-lang-2.6.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.6/commons-lang-2.6-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.6/commons-lang-2.6-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: javax.persistence:persistence-api:1.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/javax/persistence/persistence-api/1.0/persistence-api-1.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/javax/persistence/persistence-api/1.0/persistence-api-1.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: jline:jline:2.12">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/jline/jline/2.12/jline-2.12.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/jline/jline/2.12/jline-2.12-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/jline/jline/2.12/jline-2.12-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: junit:junit:4.11">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.11/junit-4.11-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: junit:junit:4.12">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.12/junit-4.12-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: mysql:mysql-connector-java:5.1.14">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/mysql/mysql-connector-java/5.1.14/mysql-connector-java-5.1.14.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/mysql/mysql-connector-java/5.1.14/mysql-connector-java-5.1.14-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/mysql/mysql-connector-java/5.1.14/mysql-connector-java-5.1.14-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: net.jafama:jafama:2.1.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/net/jafama/jafama/2.1.0/jafama-2.1.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/net/jafama/jafama/2.1.0/jafama-2.1.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/net/jafama/jafama/2.1.0/jafama-2.1.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: net.md-5:bungeecord-chat:1.8-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/net/md-5/bungeecord-chat/1.8-SNAPSHOT/bungeecord-chat-1.8-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/net/md-5/bungeecord-chat/1.8-SNAPSHOT/bungeecord-chat-1.8-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/net/md-5/bungeecord-chat/1.8-SNAPSHOT/bungeecord-chat-1.8-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: net.sf.jopt-simple:jopt-simple:3.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/net/sf/jopt-simple/jopt-simple/3.2/jopt-simple-3.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/net/sf/jopt-simple/jopt-simple/3.2/jopt-simple-3.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/net/sf/jopt-simple/jopt-simple/3.2/jopt-simple-3.2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: net.sf.trove4j:trove4j:3.0.3">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/net/sf/trove4j/trove4j/3.0.3/trove4j-3.0.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/net/sf/trove4j/trove4j/3.0.3/trove4j-3.0.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/net/sf/trove4j/trove4j/3.0.3/trove4j-3.0.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.avaje:ebean:2.8.1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/avaje/ebean/2.8.1/ebean-2.8.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/avaje/ebean/2.8.1/ebean-2.8.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/avaje/ebean/2.8.1/ebean-2.8.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.hamcrest:hamcrest-core:1.3">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.hamcrest:hamcrest-library:1.3">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-library/1.3/hamcrest-library-1.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-library/1.3/hamcrest-library-1.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-library/1.3/hamcrest-library-1.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.spigotmc:minecraft-server:1.8.8-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.xerial:sqlite-jdbc:3.7.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.7.2/sqlite-jdbc-3.7.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.7.2/sqlite-jdbc-3.7.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.7.2/sqlite-jdbc-3.7.2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.yaml:snakeyaml:1.15">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.15/snakeyaml-1.15.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.15/snakeyaml-1.15-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.15/snakeyaml-1.15-sources.jar!/" />
</SOURCES>
</library>
</component>

13
RageSpigot/.idea/misc.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/classes" />
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/RageSpigot-Server/ragespigot.iml" filepath="$PROJECT_DIR$/RageSpigot-Server/ragespigot.iml" />
<module fileurl="file://$PROJECT_DIR$/RageSpigot-API/ragespigot-api.iml" filepath="$PROJECT_DIR$/RageSpigot-API/ragespigot-api.iml" />
<module fileurl="file://$PROJECT_DIR$/ragespigot-parent.iml" filepath="$PROJECT_DIR$/ragespigot-parent.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
RageSpigot/.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,929 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="00715986-1d73-4946-bb49-f74a2b8611b1" name="Default" comment="">
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigot.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigot.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigotConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigotConfig.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/command/KnockbackCommand.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/knockback/CraftKnockbackProfile.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/World.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/World.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java" afterDir="false" />
</list>
<ignored path="$PROJECT_DIR$/RageSpigot-Server/target/" />
<ignored path="$PROJECT_DIR$/target/" />
<ignored path="$PROJECT_DIR$/RageSpigot-API/target/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FUSProjectUsageTrigger">
<session id="2046823959">
<usages-collector id="statistics.lifecycle.project">
<counts>
<entry key="project.closed" value="7" />
<entry key="project.open.time.12" value="1" />
<entry key="project.open.time.35" value="2" />
<entry key="project.open.time.51" value="1" />
<entry key="project.open.time.66" value="1" />
<entry key="project.open.time.7" value="1" />
<entry key="project.open.time.9" value="1" />
<entry key="project.opened" value="7" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.open">
<counts>
<entry key="class" value="2" />
<entry key="java" value="35" />
<entry key="md" value="1" />
<entry key="xml" value="2" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.open">
<counts>
<entry key="CLASS" value="2" />
<entry key="JAVA" value="35" />
<entry key="PLAIN_TEXT" value="1" />
<entry key="XML" value="2" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.edit">
<counts>
<entry key="java" value="233" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.edit">
<counts>
<entry key="JAVA" value="233" />
</counts>
</usages-collector>
<usages-collector id="statistics.vcs.git.usages" />
</session>
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="RageSpigotConfig.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigotConfig.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="13" column="13" selection-start-line="13" selection-start-column="13" selection-end-line="13" selection-end-column="13" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="RageSpigot.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigot.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="21" column="36" selection-start-line="21" selection-start-column="36" selection-end-line="21" selection-end-column="36" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="MovementHandler.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/handler/MovementHandler.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="6" column="17" selection-start-line="6" selection-start-column="17" selection-end-line="6" selection-end-column="17" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="PacketHandler.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/handler/PacketHandler.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="9" column="19" selection-start-line="9" selection-start-column="19" selection-end-line="9" selection-end-column="19" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="CraftFakeMultiBlockChange.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/chunk/CraftFakeMultiBlockChange.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="EntityHuman.java" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3341">
<caret line="1028" lean-forward="true" selection-start-line="1028" selection-end-line="1028" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="help.yml" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/configurations/help.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file leaf-file-name="commands.yml" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/configurations/commands.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file leaf-file-name="bukkit.yml" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/configurations/bukkit.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file leaf-file-name="log4j2.xml" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/log4j2.xml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
<option value="Interface" />
</list>
</option>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>pipeline</find>
<find>channelRead0</find>
<find>moveToWorld</find>
<find>packetHandler</find>
<find>DedicatedServer</find>
<find>PacketPlayOutSpawnEntity</find>
<find>PacketPlayOutNamedEntity</find>
<find>new PacketPlayOutNamedEntity</find>
<find>setCustomName</find>
<find>PacketPlayOutPlayer</find>
<find>PacketPlayOutPlayerInf</find>
<find>Rotation</find>
<find>EntityLiving</find>
<find>PacketPlayOutAnimation</find>
<find>PacketPlayOutEntity</find>
<find>PacketPlayOutEntityLook</find>
<find>Pac</find>
<find>PacketPlayOutEntityHead</find>
<find>PacketPlayOutRel</find>
<find>protocol version</find>
<find>Unsupported</find>
<find>PacketPlayOutNamed</find>
<find>PacketPlayOutEntityMet</find>
<find>save</find>
<find>Stopping server</find>
<find>boolean flag2 = entity.damageEntity(DamageSource.playerAttack(this), f);</find>
<find>setVelocity</find>
<find>+</find>
<find>setVel</find>
<find>a(Entity entity, float f, double d0, double d1) {</find>
</findStrings>
<replaceStrings>
<replace>FastMath.</replace>
<replace>MathHelper.clamp</replace>
<replace>MathHelper.floor</replace>
<replace>MathHelper.g</replace>
<replace>MathHelper.b</replace>
<replace>MathHelper.c</replace>
<replace>MathHelper.a</replace>
<replace>MathHelper.f</replace>
<replace>MathHelper.d</replace>
<replace>MathHelper.nextInt</replace>
</replaceStrings>
<dirStrings>
<dir>C:\Users\skruf\Documents\RageMC\RageSpigot\RageSpigot-Server</dir>
<dir>C:\Users\skruf\Documents\RageMC\RageSpigot</dir>
<dir>C:\Users\skruf\Documents\RageMC\RageSpigot\RageSpigot-Server\src\main\java\gg\ragemc\spigot\handler</dir>
<dir>C:\Users\skruf\Documents\Projects\RageMC\RageSpigot\RageSpigot-API</dir>
<dir>C:\Users\skruf\Documents\Projects\RageMC\RageSpigot</dir>
<dir>C:\Users\david\IdeaProjects\RageSpigot\RageSpigot-Server\src\main\java</dir>
</dirStrings>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityHorse.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartAbstract.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/spigotmc/ActivationRange.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityChicken.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntitySnowman.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/BlockPiston.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityMonster.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/VillageSiege.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/CraftingManager.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/CommandSpreadPlayers.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityGhast.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSelector.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/NavigationAbstract.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/spigotmc/TicksPerSecondCommand.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/command/SetTPSCommand.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityItem.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/command/SetTicksPerSecondCommand.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/command/SetNoDamageTicksCommand.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/knockback/KnockbackProfile.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/LoginListener.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java" />
<option value="$PROJECT_DIR$/RageSpigot-API/src/main/java/gg/ragemc/spigot/knockback/KnockbackProfile.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/knockback/CraftKnockbackProfile.java" />
<option value="$PROJECT_DIR$/RageSpigot-API/src/main/java/org/bukkit/entity/Player.java" />
<option value="$PROJECT_DIR$/RageSpigot-API/src/main/java/org/bukkit/entity/LivingEntity.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/Entity.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/chunk/CraftFakeMultiBlockChange.java" />
<option value="$PROJECT_DIR$/RageSpigot-API/src/main/java/org/bukkit/Chunk.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunk.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/command/KnockbackCommand.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigotConfig.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigot.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityEnderPearl.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java" />
<option value="$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/World.java" />
</list>
</option>
</component>
<component name="MavenImportPreferences">
<option name="importingSettings">
<MavenImportingSettings>
<option name="importAutomatically" value="true" />
</MavenImportingSettings>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="14" />
<option name="y" value="14" />
<option name="width" value="1278" />
<option name="height" value="678" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="ragespigot-parent" type="b2602c69:ProjectViewProjectNode" />
<item name="RageSpigot" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="ragespigot-parent" type="b2602c69:ProjectViewProjectNode" />
<item name="RageSpigot" type="462c0819:PsiDirectoryNode" />
<item name="RageSpigot-Server" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="ragespigot-parent" type="b2602c69:ProjectViewProjectNode" />
<item name="RageSpigot" type="462c0819:PsiDirectoryNode" />
<item name="RageSpigot-Server" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="ragespigot-parent" type="b2602c69:ProjectViewProjectNode" />
<item name="RageSpigot" type="462c0819:PsiDirectoryNode" />
<item name="RageSpigot-Server" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="main" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="ragespigot-parent" type="b2602c69:ProjectViewProjectNode" />
<item name="RageSpigot" type="462c0819:PsiDirectoryNode" />
<item name="RageSpigot-Server" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="main" type="462c0819:PsiDirectoryNode" />
<item name="java" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="ragespigot-parent" type="b2602c69:ProjectViewProjectNode" />
<item name="RageSpigot" type="462c0819:PsiDirectoryNode" />
<item name="RageSpigot-Server" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="main" type="462c0819:PsiDirectoryNode" />
<item name="java" type="462c0819:PsiDirectoryNode" />
<item name="server" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
<pane id="AndroidView" />
<pane id="PackagesPane" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1539962232423" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="project.structure.last.edited" value="Modules" />
<property name="project.structure.proportion" value="0.15" />
<property name="project.structure.side.proportion" value="0.2" />
</component>
<component name="RecentsManager">
<key name="CopyClassDialog.RECENTS_KEY">
<recent name="gg.ragemc.spigot.command" />
<recent name="gg.ragemc.spigot.knockback" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration default="true" type="Applet" factoryName="Applet">
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<method>
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method>
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<patterns />
<method>
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="Unnamed" type="MavenRunConfiguration" factoryName="Maven">
<MavenSettings>
<option name="myGeneralSettings" />
<option name="myRunnerSettings" />
<option name="myRunnerParameters">
<MavenRunnerParameters>
<option name="profiles">
<set />
</option>
<option name="goals">
<list>
<option value="clean" />
<option value="install" />
</list>
</option>
<option name="pomFileName" />
<option name="profilesMap">
<map />
</option>
<option name="resolveToWorkspace" value="false" />
<option name="workingDirPath" value="$PROJECT_DIR$" />
</MavenRunnerParameters>
</option>
</MavenSettings>
</configuration>
<configuration default="true" type="TestNG" factoryName="TestNG">
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="SUITE_NAME" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="GROUP_NAME" />
<option name="TEST_OBJECT" value="CLASS" />
<option name="VM_PARAMETERS" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<option name="OUTPUT_DIRECTORY" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<option name="USE_DEFAULT_REPORTERS" value="false" />
<option name="PROPERTIES_FILE" />
<properties />
<listeners />
<method>
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
<module name="" />
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
<option name="PROGRAM_PARAMETERS" />
<predefined_log_file id="idea.log" enabled="true" />
<method>
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="00715986-1d73-4946-bb49-f74a2b8611b1" name="Default" comment="" />
<created>1524308330911</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1524308330911</updated>
</task>
<servers />
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="1936" height="1056" extended-state="6" />
<editor active="true" />
<layout>
<window_info anchor="right" id="Palette" order="3" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="right" id="Palette&#9;" order="7" />
<window_info id="Image Layers" order="6" />
<window_info anchor="right" id="Capture Analysis" order="5" />
<window_info anchor="bottom" id="Event Log" order="7" side_tool="true" />
<window_info anchor="right" id="Maven Projects" order="4" />
<window_info anchor="bottom" id="Version Control" order="10" />
<window_info anchor="bottom" id="Run" order="2" weight="0.32934782" />
<window_info anchor="bottom" id="Terminal" order="9" weight="0.32837406" />
<window_info id="Capture Tool" order="2" />
<window_info id="Designer" order="3" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.22760417" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info id="UI Designer" order="4" />
<window_info anchor="right" id="Theme Preview" order="6" />
<window_info id="Favorites" order="5" side_tool="true" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="DB Execution Console" order="11" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
<window_info anchor="bottom" id="Floobits" order="8" />
<window_info anchor="bottom" id="Find" order="1" weight="0.32934782" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info id="Project Explorer" order="8" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info id="DB Browser" order="7" />
<window_info id="Job Explorer" order="9" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="bottom" id="Console" order="12" />
</layout>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="antWorkspaceConfiguration">
<option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
<option name="FILTER_TARGETS" value="false" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/DataWatcher.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="298">
<caret line="116" column="20" selection-start-line="116" selection-start-column="20" selection-end-line="116" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/DataWatcher.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="102">
<caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/PacketPlayOutPlayerInfo.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="811">
<caret line="171" column="28" selection-start-line="171" selection-start-column="28" selection-end-line="171" selection-end-column="28" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/PacketDataSerializer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="281">
<caret line="129" lean-forward="true" selection-start-line="129" selection-end-line="129" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/PacketPlayOutAnimation.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="15" selection-start-line="15" selection-end-line="15" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutEntity.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="51">
<caret line="60" lean-forward="true" selection-start-line="60" selection-end-line="60" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/Entity.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="281">
<caret line="133" lean-forward="true" selection-start-line="133" selection-end-line="133" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/PacketPlayOutNamedEntitySpawn.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="281">
<caret line="26" selection-start-line="26" selection-end-line="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3162">
<caret line="199" column="16" selection-start-line="199" selection-start-column="16" selection-end-line="199" selection-end-column="16" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="6392">
<caret line="452" column="32" selection-start-line="452" selection-start-column="32" selection-end-line="452" selection-end-column="32" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/Entity.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="33541">
<caret line="2129" selection-start-line="2129" selection-end-line="2129" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/PacketPlayOutEntityMetadata.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="357">
<caret line="26" column="5" lean-forward="true" selection-start-line="26" selection-start-column="5" selection-end-line="26" selection-end-column="5" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="289" column="39" selection-start-line="289" selection-start-column="39" selection-end-line="289" selection-end-column="39" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/EnumDirection.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="205">
<caret line="97" column="15" selection-start-line="97" selection-start-column="15" selection-end-line="97" selection-end-column="15" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="184" column="46" selection-start-line="184" selection-start-column="46" selection-end-line="184" selection-end-column="46" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPlugin.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="171">
<caret line="227" column="20" lean-forward="true" selection-start-line="227" selection-start-column="20" selection-end-line="227" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfiguration.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="205">
<caret line="97" column="19" selection-start-line="97" selection-start-column="19" selection-end-line="97" selection-end-column="19" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/MojangStatisticsGenerator.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1768">
<caret line="122" column="16" selection-start-line="122" selection-start-column="16" selection-end-line="122" selection-end-column="16" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="157" column="49" selection-start-line="157" selection-start-column="49" selection-end-line="157" selection-end-column="49" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-API/src/main/java/co/aikar/timings/TimingsManager.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-16">
<caret line="89" column="52" lean-forward="true" selection-start-line="89" selection-start-column="52" selection-end-line="89" selection-end-column="52" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/co/aikar/timings/SpigotTimings.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1632">
<caret line="104" column="27" selection-start-line="104" selection-start-column="27" selection-end-line="104" selection-end-column="27" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="260">
<caret line="450" column="30" lean-forward="true" selection-start-line="450" selection-start-column="30" selection-end-line="450" selection-end-column="30" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="144">
<caret line="24" column="31" selection-start-line="24" selection-start-column="31" selection-end-line="24" selection-end-column="31" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/pom.xml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1020">
<caret line="3" column="33" selection-start-line="3" selection-start-column="13" selection-end-line="3" selection-end-column="33" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pom.xml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/command/KnockbackCommand.java" />
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="4046">
<caret line="310" column="43" selection-start-line="310" selection-start-column="43" selection-end-line="310" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-API/src/main/java/org/bukkit/entity/Player.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="28" column="17" selection-start-line="28" selection-start-column="17" selection-end-line="28" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450">
<caret line="1234" column="23" selection-start-line="1234" selection-start-column="23" selection-end-line="1234" selection-end-column="23" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="340">
<caret line="1615" column="33" selection-start-line="1615" selection-start-column="16" selection-end-line="1615" selection-end-column="33" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="442">
<caret line="981" column="9" lean-forward="true" selection-start-line="981" selection-start-column="9" selection-end-line="981" selection-end-column="9" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/knockback/CraftKnockbackProfile.java" />
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="240">
<caret line="417" column="80" lean-forward="true" selection-start-line="417" selection-start-column="80" selection-end-line="417" selection-end-column="80" />
</state>
</provider>
</entry>
<entry file="jar://$MAVEN_REPOSITORY$/org/spigotmc/minecraft-server/1.8.8-SNAPSHOT/minecraft-server-1.8.8-SNAPSHOT.jar!/net/minecraft/server/IBlockAccess.class">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="9" column="36" selection-start-line="9" selection-start-column="36" selection-end-line="9" selection-end-column="36" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityEnderPearl.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="510">
<caret line="32" column="9" selection-start-line="32" selection-start-column="9" selection-end-line="32" selection-end-column="9" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="4743">
<caret line="291" column="1" selection-start-line="291" selection-start-column="1" selection-end-line="291" selection-end-column="1" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/World.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="26571">
<caret line="1631" column="22" selection-start-line="1631" selection-start-column="22" selection-end-line="1631" selection-end-column="22" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3281">
<caret line="218" column="22" selection-start-line="218" selection-start-column="22" selection-end-line="218" selection-end-column="22" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/util/BooleanUtil.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="2" column="13" selection-start-line="2" selection-start-column="13" selection-end-line="2" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/util/CraftPotionUtil.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/util/OptimizedRemoveUtil.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="5" column="13" selection-start-line="5" selection-start-column="13" selection-end-line="5" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/handler/MovementHandler.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="6" column="17" selection-start-line="6" selection-start-column="17" selection-end-line="6" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/handler/PacketHandler.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="9" column="19" selection-start-line="9" selection-start-column="19" selection-end-line="9" selection-end-column="19" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/chunk/CraftFakeMultiBlockChange.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigotConfig.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="13" column="13" selection-start-line="13" selection-start-column="13" selection-end-line="13" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/gg/ragemc/spigot/RageSpigot.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="21" column="36" selection-start-line="21" selection-start-column="36" selection-end-line="21" selection-end-column="36" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/configurations/help.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/configurations/commands.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/configurations/bukkit.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/resources/log4j2.xml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/RageSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3341">
<caret line="1028" lean-forward="true" selection-start-line="1028" selection-end-line="1028" />
</state>
</provider>
</entry>
</component>
<component name="masterDetails">
<states>
<state key="ArtifactsStructureConfigurable.UI">
<settings>
<artifact-editor />
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="FacetStructureConfigurable.UI">
<settings>
<last-edited>No facets are configured</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="GlobalLibrariesConfigurable.UI">
<settings>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="JdkListConfigurable.UI">
<settings>
<last-edited>1.8</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="ModuleStructureConfigurable.UI">
<settings>
<last-edited>ragespigot</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>1.8</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
<state key="ProjectLibrariesConfigurable.UI">
<settings>
<last-edited>Maven: com.google.code.gson:gson:2.8.0</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>

32
RageSpigot/README.md Normal file
View File

@ -0,0 +1,32 @@
PaperSpigot [![CI Status](http://ci.destroystokyo.com/buildStatus/icon?job=PaperSpigot)](http://ci.destroystokyo.com/job/PaperSpigot/)
===========
High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies.
[IRC Support and Project Discussion](http://irc.spi.gt/iris/?channels=PaperSpigot)
How To (Server Admins)
------
Download a copy of Paperclip.jar from our buildserver here:
https://ci.destroystokyo.com/job/PaperSpigot/
Run the PaperClip jar directly from your server. Just like old times
PaperSpigot requires **JRE 8** or above.
How To (Compiling From Source)
------
To compile PaperSpigot, you need JDK8, maven, and an internet connection.
Clone this repo, run ./build.sh from *bash*, get files.
Special Thanks To:
-------------
![YourKit-Logo](https://www.yourkit.com/images/yklogo.png)
[YourKit](http://www.yourkit.com/), makers of the outstanding java profiler, support open source projects of all kinds with their full featured [Java](https://www.yourkit.com/java/profiler/index.jsp) and [.NET](https://www.yourkit.com/.net/profiler/index.jsp) application profilers. We thank them for granting PaperSpigot an OSS license so that we can make our software the best it can be.

31
RageSpigot/RageSpigot-API/.gitignore vendored Normal file
View File

@ -0,0 +1,31 @@
# Eclipse stuff
/.classpath
/.project
/.settings
# netbeans
/nbproject
# we use maven!
/build.xml
# maven
/target
# vim
.*.sw[a-p]
# various other potential build files
/build
/bin
/dist
/manifest.mf
# Mac filesystem dust
.DS_Store
# intellij
*.iml
*.ipr
*.iws
.idea/

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -0,0 +1,27 @@
Bukkit
======
A plugin API for [Minecraft](https://minecraft.net/) servers, currently maintained by [SpigotMC](http://www.spigotmc.org/).
Bug Reporting
-------------
The development team is very open to both bug and feature requests / suggestions. You can submit these on the [JIRA Issue Tracker](http://hub.spigotmc.org/jira/).
Compilation
-----------
Bukkit is a Java program which uses [Maven 3](http://maven.apache.org/) for compilation. To compile fresh from Git, simply perform the following steps:
* Install Maven and Git using your preferred installation methods.
* `git clone https://hub.spigotmc.org/stash/scm/spigot/bukkit.git`.
* `mvn clean install`.
Some IDEs such as [NetBeans](https://netbeans.org/) can perform these steps for you. Any Maven capable Java IDE can be used to develop with Bukkit, however the current team's personal preference is to use NetBeans.
Contributing
------------
Contributions of all sorts are welcome. To manage community contributions, we use the pull request functionality of Stash. In to gain access to Stash and create a pull request, you will first need to perform the following steps:
* Create an account on [JIRA](http://hub.spigotmc.org/jira/).
* Fill in the [SpigotMC CLA](http://www.spigotmc.org/go/cla) and wait up to 24 hours for your Stash account to be activated. Please ensure that your username and email addresses match.
* Log into Stash using your JIRA credentials.
Once you have performed these steps you can create a fork, push your code changes, and then submit it for review.

View 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>gg.ragemc.ragespigot</groupId>
<artifactId>ragespigot-parent</artifactId>
<version>dev-SNAPSHOT</version>
</parent>
<artifactId>ragespigot-api</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>RageSpigot-API</name>
<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>
<!-- 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>
<repositories>
<repository>
<id>mc-repo</id>
<url>http://maven.elmakers.com/repository/</url>
</repository>
</repositories>
<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>19.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- bundled with Minecraft, should be kept in sync -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</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>
<!-- 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>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.0-beta-3</version>
<configuration>
<reportPlugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jxr-maven-plugin</artifactId>
<version>2.0-beta-1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<configuration>
<linksource>true</linksource>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -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;
}
}

View File

@ -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() {
}
}

View File

@ -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();
}
}

View 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();
}

View 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;
}
}

View 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;
}
}

View 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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View 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);
}
}

View File

@ -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();
}
}

View 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();
}
}
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View 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;
}
}
}

View File

@ -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();
}
}

View 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();
}
}

View 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);
}
}

View File

@ -0,0 +1,9 @@
package gg.ragemc.spigot.chunk;
import org.bukkit.entity.Player;
public interface FakeMultiBlockChange {
void sendTo(Player player);
}

View File

@ -0,0 +1,78 @@
package gg.ragemc.spigot.event.inventory;
import org.bukkit.block.Block;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
/**
* @since 11/20/2017
*/
public class PrepareAnvilRepairEvent extends InventoryEvent implements Cancellable {
private static final HandlerList handlers;
static {
handlers = new HandlerList();
}
private final ItemStack first;
private final ItemStack second;
private final HumanEntity repairer;
private final Block anvil;
private boolean cancelled;
private ItemStack result;
public PrepareAnvilRepairEvent(final HumanEntity repairer, final InventoryView view, final Block anvil,
final ItemStack first, final ItemStack second, final ItemStack result) {
super(view);
this.first = first;
this.second = second;
this.anvil = anvil;
this.result = result;
this.repairer = repairer;
}
public static HandlerList getHandlerList() {
return PrepareAnvilRepairEvent.handlers;
}
public ItemStack getFirst() {
return this.first;
}
public ItemStack getSecond() {
return this.second;
}
public HumanEntity getRepairer() {
return this.repairer;
}
public Block getAnvil() {
return this.anvil;
}
public ItemStack getResult() {
return this.result;
}
public void setResult(final ItemStack result) {
this.result = result;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
public HandlerList getHandlers() {
return PrepareAnvilRepairEvent.handlers;
}
}

View File

@ -0,0 +1,34 @@
package gg.ragemc.spigot.event.potion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.potion.PotionEffect;
/**
* Called when a potion effect is applied to an entity, or an existing effect is extended or upgraded
*/
public class PotionEffectAddEvent extends PotionEffectEvent implements Cancellable {
private boolean cancelled;
private static final HandlerList HANDLER_LIST = new HandlerList();
public PotionEffectAddEvent(LivingEntity entity, PotionEffect effect) {
super(entity, effect);
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override public HandlerList getHandlers() { return PotionEffectAddEvent.HANDLER_LIST; }
public static HandlerList getHandlerList() { return PotionEffectAddEvent.HANDLER_LIST; }
}

View File

@ -0,0 +1,24 @@
package gg.ragemc.spigot.event.potion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.potion.PotionEffect;
public abstract class PotionEffectEvent extends EntityEvent {
private final PotionEffect effect;
public PotionEffectEvent(LivingEntity what, PotionEffect effect) {
super(what);
this.effect = effect;
}
@Override
public LivingEntity getEntity() {
return (LivingEntity) super.getEntity();
}
public PotionEffect getEffect() {
return this.effect;
}
}

View File

@ -0,0 +1,45 @@
package gg.ragemc.spigot.event.potion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
/**
* Called when a potion effect on an entity runs out. Cancelling the event extends
* the effect with a practically infinite duration. The new duration can also be set
* explicitly by calling {@link #setDuration}.
*
* Handlers of {@link PotionEffectRemoveEvent} will also receive this event.
*/
public class PotionEffectExpireEvent extends PotionEffectRemoveEvent {
private int duration = 0;
public PotionEffectExpireEvent(LivingEntity entity, PotionEffect effect) {
super(entity, effect);
}
/**
* Get the new duration for the potion effect. This is initially 0.
*/
public int getDuration() {
return this.duration;
}
/**
* Set a new duration for the potion effect. Passing 0 to this method un-cancels
* the event, and passing anything above 0 cancels it.
*/
public void setDuration(int duration) {
this.duration = Math.max(0, duration);
}
@Override
public boolean isCancelled() {
return this.duration > 0;
}
@Override
public void setCancelled(boolean cancel) {
this.duration = cancel ? Integer.MAX_VALUE : 0;
}
}

View File

@ -0,0 +1,26 @@
package gg.ragemc.spigot.event.potion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.potion.PotionEffect;
/**
* Called when an entity's active potion effect is extended or upgraded.
*
* Handlers of {@link PotionEffectAddEvent} will also receive this event.
*/
public class PotionEffectExtendEvent extends PotionEffectAddEvent {
private final PotionEffect oldEffect;
public PotionEffectExtendEvent(LivingEntity entity, PotionEffect effect, PotionEffect oldEffect) {
super(entity, effect);
this.oldEffect = oldEffect;
}
/**
* Get the state of the potion effect prior to the change
*/
public PotionEffect getOldEffect() {
return this.oldEffect;
}
}

View File

@ -0,0 +1,35 @@
package gg.ragemc.spigot.event.potion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.potion.PotionEffect;
/**
* Called when a potion effect is removed from an entity for whatever reason
*/
public class PotionEffectRemoveEvent extends PotionEffectEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled = false;
public PotionEffectRemoveEvent(LivingEntity entity, PotionEffect effect) {
super(entity, effect);
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Override public HandlerList getHandlers() { return PotionEffectRemoveEvent.HANDLER_LIST; }
public static HandlerList getHandlerList() { return PotionEffectRemoveEvent.HANDLER_LIST; }
}

View File

@ -0,0 +1,19 @@
package gg.ragemc.spigot.knockback;
public interface KnockbackProfile {
public String getName();
public boolean isFriction();
public void setFriction(boolean friction);
public double getHorizontal();
public void setHorizontal(double horizontal);
public double getVertical();
public void setVertical(double vertical);
}

View File

@ -0,0 +1,68 @@
package gg.ragemc.spigot.util;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateUtil {
private static final int MAX_YEARS = 100000;
private DateUtil() {
}
private static int dateDiff(int type, Calendar fromDate, Calendar toDate, boolean future) {
int year = Calendar.YEAR;
int fromYear = fromDate.get(year);
int toYear = toDate.get(year);
if (Math.abs(fromYear - toYear) > DateUtil.MAX_YEARS) {
toDate.set(year, fromYear +
(future ? DateUtil.MAX_YEARS : -DateUtil.MAX_YEARS));
}
int diff = 0;
long savedDate = fromDate.getTimeInMillis();
while ((future && !fromDate.after(toDate)) || (!future && !fromDate.before(toDate))) {
savedDate = fromDate.getTimeInMillis();
fromDate.add(type, future ? 1 : -1);
diff++;
}
diff--;
fromDate.setTimeInMillis(savedDate);
return diff;
}
public static String formatDateDiff(long date) {
Calendar c = new GregorianCalendar();
c.setTimeInMillis(date);
Calendar now = new GregorianCalendar();
return DateUtil.formatDateDiff(now, c);
}
private static String formatDateDiff(Calendar fromDate, Calendar toDate) {
boolean future = false;
if (toDate.equals(fromDate)) {
return "now";
}
if (toDate.after(fromDate)) {
future = true;
}
StringBuilder sb = new StringBuilder();
int[] types = new int[]{Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND};
String[] names = new String[]{"year", "years", "month", "months", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds"};
int accuracy = 0;
for (int i = 0; i < types.length; i++) {
if (accuracy > 2) {
break;
}
int diff = dateDiff(types[i], fromDate, toDate, future);
if (diff > 0) {
accuracy++;
sb.append(" ").append(diff).append(" ").append(names[i * 2 + (diff > 1 ? 1 : 0)]);
}
}
if (sb.length() == 0) {
return "now";
}
return sb.toString().trim();
}
}

View 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;
}
}

View 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);
}
}
}

View 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();
}

View 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);
}

View 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);
}

File diff suppressed because it is too large Load Diff

View 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);
}
}
}

View File

@ -0,0 +1,129 @@
package org.bukkit;
import gg.ragemc.spigot.chunk.FakeMultiBlockChange;
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();
// RageSpigot start
FakeMultiBlockChange createFakeBlockUpdate(final Location[] locations, final int[] ids, final int[] datas);
// RageSpigot end
}

View 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);
}

View 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);
}
}
}

View 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() + "]";
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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();
}
}

View 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}
}

View 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);
}
}
}

View 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);
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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")));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View 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;&nbsp;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() ? "#" : "") + "}";
}
}

View 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();
}

View 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;
}

View 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];
}
}

View 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);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
package org.bukkit;
/**
* Represents the different types of skulls.
*/
public enum SkullType {
SKELETON,
WITHER,
ZOMBIE,
PLAYER,
CREEPER;
}

View 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,
}

View 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;
}
}

View 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);
}

View 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);
}
}
}

View 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,
}

View 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);
}

View 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 {
}

View 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 "";
}

View 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,
;
}

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