Merge branch 'development'

This commit is contained in:
Christian Koop 2021-07-08 17:50:27 +02:00
commit e65dcc67cb
No known key found for this signature in database
GPG Key ID: 89A8181384E010A3
350 changed files with 15595 additions and 15446 deletions

311
.editorconfig Normal file
View File

@ -0,0 +1,311 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
# max_line_length = 120
tab_width = 4
trim_trailing_whitespace = true
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false
ij_smart_tabs = false
ij_visual_guides = none
ij_wrap_on_typing = false
[*.java]
ij_smart_tabs = true
ij_java_align_consecutive_assignments = false
ij_java_align_consecutive_variable_declarations = false
ij_java_align_group_field_declarations = false
ij_java_align_multiline_annotation_parameters = false
ij_java_align_multiline_array_initializer_expression = false
ij_java_align_multiline_assignment = false
ij_java_align_multiline_binary_operation = false
ij_java_align_multiline_chained_methods = false
ij_java_align_multiline_extends_list = false
ij_java_align_multiline_for = true
ij_java_align_multiline_method_parentheses = false
ij_java_align_multiline_parameters = true
ij_java_align_multiline_parameters_in_calls = false
ij_java_align_multiline_parenthesized_expression = false
ij_java_align_multiline_records = true
ij_java_align_multiline_resources = true
ij_java_align_multiline_ternary_operation = false
ij_java_align_multiline_text_blocks = false
ij_java_align_multiline_throws_list = false
ij_java_align_subsequent_simple_methods = false
ij_java_align_throws_keyword = false
ij_java_annotation_parameter_wrap = off
ij_java_array_initializer_new_line_after_left_brace = false
ij_java_array_initializer_right_brace_on_new_line = false
ij_java_array_initializer_wrap = off
ij_java_assert_statement_colon_on_next_line = false
ij_java_assert_statement_wrap = off
ij_java_assignment_wrap = off
ij_java_binary_operation_sign_on_next_line = false
ij_java_binary_operation_wrap = off
ij_java_blank_lines_after_anonymous_class_header = 0
ij_java_blank_lines_after_class_header = 0
ij_java_blank_lines_after_imports = 1
ij_java_blank_lines_after_package = 1
ij_java_blank_lines_around_class = 1
ij_java_blank_lines_around_field = 0
ij_java_blank_lines_around_field_in_interface = 0
ij_java_blank_lines_around_initializer = 1
ij_java_blank_lines_around_method = 1
ij_java_blank_lines_around_method_in_interface = 1
ij_java_blank_lines_before_class_end = 0
ij_java_blank_lines_before_imports = 1
ij_java_blank_lines_before_method_body = 0
ij_java_blank_lines_before_package = 0
ij_java_block_brace_style = end_of_line
ij_java_block_comment_at_first_column = true
ij_java_builder_methods = none
ij_java_call_parameters_new_line_after_left_paren = false
ij_java_call_parameters_right_paren_on_new_line = false
ij_java_call_parameters_wrap = off
ij_java_case_statement_on_separate_line = true
ij_java_catch_on_new_line = false
ij_java_class_annotation_wrap = split_into_lines
ij_java_class_brace_style = end_of_line
ij_java_class_count_to_use_import_on_demand = 15
ij_java_class_names_in_javadoc = 1
ij_java_do_not_indent_top_level_class_members = false
ij_java_do_not_wrap_after_single_annotation = false
ij_java_do_while_brace_force = never
ij_java_doc_add_blank_line_after_description = true
ij_java_doc_add_blank_line_after_param_comments = true
ij_java_doc_add_blank_line_after_return = true
ij_java_doc_add_p_tag_on_empty_lines = true
ij_java_doc_align_exception_comments = true
ij_java_doc_align_param_comments = true
ij_java_doc_do_not_wrap_if_one_line = true
ij_java_doc_enable_formatting = true
ij_java_doc_enable_leading_asterisks = true
ij_java_doc_indent_on_continuation = true
ij_java_doc_keep_empty_lines = true
ij_java_doc_keep_empty_parameter_tag = true
ij_java_doc_keep_empty_return_tag = true
ij_java_doc_keep_empty_throws_tag = true
ij_java_doc_keep_invalid_tags = true
ij_java_doc_param_description_on_new_line = false
ij_java_doc_preserve_line_breaks = false
ij_java_doc_use_throws_not_exception_tag = true
ij_java_else_on_new_line = false
ij_java_enum_constants_wrap = off
ij_java_extends_keyword_wrap = off
ij_java_extends_list_wrap = off
ij_java_field_annotation_wrap = split_into_lines
ij_java_finally_on_new_line = false
ij_java_for_brace_force = never
ij_java_for_statement_new_line_after_left_paren = false
ij_java_for_statement_right_paren_on_new_line = false
ij_java_for_statement_wrap = off
ij_java_generate_final_locals = false
ij_java_generate_final_parameters = false
ij_java_if_brace_force = never
ij_java_imports_layout = *, |, javax.**, java.**, |, $*
ij_java_indent_case_from_switch = true
ij_java_insert_inner_class_imports = false
ij_java_insert_override_annotation = true
ij_java_keep_blank_lines_before_right_brace = 0
ij_java_keep_blank_lines_between_package_declaration_and_header = 0
ij_java_keep_blank_lines_in_code = 1
ij_java_keep_blank_lines_in_declarations = 1
ij_java_keep_builder_methods_indents = false
ij_java_keep_control_statement_in_one_line = true
ij_java_keep_first_column_comment = true
ij_java_keep_indents_on_empty_lines = false
ij_java_keep_line_breaks = true
ij_java_keep_multiple_expressions_in_one_line = false
ij_java_keep_simple_blocks_in_one_line = false
ij_java_keep_simple_classes_in_one_line = true
ij_java_keep_simple_lambdas_in_one_line = true
ij_java_keep_simple_methods_in_one_line = true
ij_java_label_indent_absolute = false
ij_java_label_indent_size = 0
ij_java_lambda_brace_style = end_of_line
ij_java_layout_static_imports_separately = true
ij_java_line_comment_add_space = false
ij_java_line_comment_at_first_column = true
ij_java_method_annotation_wrap = split_into_lines
ij_java_method_brace_style = end_of_line
ij_java_method_call_chain_wrap = off
ij_java_method_parameters_new_line_after_left_paren = false
ij_java_method_parameters_right_paren_on_new_line = false
ij_java_method_parameters_wrap = off
ij_java_modifier_list_wrap = false
ij_java_names_count_to_use_import_on_demand = 9
ij_java_new_line_after_lparen_in_record_header = false
ij_java_packages_to_use_import_on_demand = _java.awt.*, _javax.swing.*
ij_java_parameter_annotation_wrap = off
ij_java_parentheses_expression_new_line_after_left_paren = false
ij_java_parentheses_expression_right_paren_on_new_line = false
ij_java_place_assignment_sign_on_next_line = false
ij_java_prefer_longer_names = true
ij_java_prefer_parameters_wrap = false
ij_java_record_components_wrap = normal
ij_java_repeat_synchronized = true
ij_java_replace_instanceof_and_cast = true
ij_java_replace_null_check = true
ij_java_replace_sum_lambda_with_method_ref = true
ij_java_resource_list_new_line_after_left_paren = false
ij_java_resource_list_right_paren_on_new_line = false
ij_java_resource_list_wrap = off
ij_java_rparen_on_new_line_in_record_header = false
ij_java_space_after_closing_angle_bracket_in_type_argument = false
ij_java_space_after_colon = true
ij_java_space_after_comma = true
ij_java_space_after_comma_in_type_arguments = true
ij_java_space_after_for_semicolon = true
ij_java_space_after_quest = true
ij_java_space_after_type_cast = true
ij_java_space_before_annotation_array_initializer_left_brace = false
ij_java_space_before_annotation_parameter_list = false
ij_java_space_before_array_initializer_left_brace = true
ij_java_space_before_catch_keyword = true
ij_java_space_before_catch_left_brace = true
ij_java_space_before_catch_parentheses = true
ij_java_space_before_class_left_brace = true
ij_java_space_before_colon = true
ij_java_space_before_colon_in_foreach = true
ij_java_space_before_comma = false
ij_java_space_before_do_left_brace = true
ij_java_space_before_else_keyword = true
ij_java_space_before_else_left_brace = true
ij_java_space_before_finally_keyword = true
ij_java_space_before_finally_left_brace = true
ij_java_space_before_for_left_brace = true
ij_java_space_before_for_parentheses = true
ij_java_space_before_for_semicolon = false
ij_java_space_before_if_left_brace = true
ij_java_space_before_if_parentheses = true
ij_java_space_before_method_call_parentheses = false
ij_java_space_before_method_left_brace = true
ij_java_space_before_method_parentheses = false
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
ij_java_space_before_quest = true
ij_java_space_before_switch_left_brace = true
ij_java_space_before_switch_parentheses = true
ij_java_space_before_synchronized_left_brace = true
ij_java_space_before_synchronized_parentheses = true
ij_java_space_before_try_left_brace = true
ij_java_space_before_try_parentheses = true
ij_java_space_before_type_parameter_list = false
ij_java_space_before_while_keyword = true
ij_java_space_before_while_left_brace = true
ij_java_space_before_while_parentheses = true
ij_java_space_inside_one_line_enum_braces = false
ij_java_space_within_empty_array_initializer_braces = true
ij_java_space_within_empty_method_call_parentheses = false
ij_java_space_within_empty_method_parentheses = false
ij_java_spaces_around_additive_operators = true
ij_java_spaces_around_assignment_operators = true
ij_java_spaces_around_bitwise_operators = true
ij_java_spaces_around_equality_operators = true
ij_java_spaces_around_lambda_arrow = true
ij_java_spaces_around_logical_operators = true
ij_java_spaces_around_method_ref_dbl_colon = false
ij_java_spaces_around_multiplicative_operators = true
ij_java_spaces_around_relational_operators = true
ij_java_spaces_around_shift_operators = true
ij_java_spaces_around_type_bounds_in_type_parameters = true
ij_java_spaces_around_unary_operator = false
ij_java_spaces_within_angle_brackets = false
ij_java_spaces_within_annotation_parentheses = false
ij_java_spaces_within_array_initializer_braces = false
ij_java_spaces_within_braces = true
ij_java_spaces_within_brackets = false
ij_java_spaces_within_cast_parentheses = false
ij_java_spaces_within_catch_parentheses = false
ij_java_spaces_within_for_parentheses = false
ij_java_spaces_within_if_parentheses = false
ij_java_spaces_within_method_call_parentheses = false
ij_java_spaces_within_method_parentheses = false
ij_java_spaces_within_parentheses = false
ij_java_spaces_within_record_header = false
ij_java_spaces_within_switch_parentheses = false
ij_java_spaces_within_synchronized_parentheses = false
ij_java_spaces_within_try_parentheses = false
ij_java_spaces_within_while_parentheses = false
ij_java_special_else_if_treatment = true
ij_java_subclass_name_suffix = Impl
ij_java_ternary_operation_signs_on_next_line = false
ij_java_ternary_operation_wrap = off
ij_java_test_name_suffix = Test
ij_java_throws_keyword_wrap = off
ij_java_throws_list_wrap = off
ij_java_use_external_annotations = false
ij_java_use_fq_class_names = false
ij_java_use_relative_indents = false
ij_java_use_single_class_imports = true
ij_java_variable_annotation_wrap = off
ij_java_visibility = public
ij_java_while_brace_force = never
ij_java_while_on_new_line = false
ij_java_wrap_comments = false
ij_java_wrap_first_method_in_call_chain = false
ij_java_wrap_long_lines = false
[*.properties]
ij_properties_align_group_field_declarations = false
ij_properties_keep_blank_lines = false
ij_properties_key_value_delimiter = equals
ij_properties_spaces_around_key_value_delimiter = false
[.editorconfig]
ij_editorconfig_align_group_field_declarations = false
ij_editorconfig_space_after_colon = false
ij_editorconfig_space_after_comma = true
ij_editorconfig_space_before_colon = false
ij_editorconfig_space_before_comma = false
ij_editorconfig_spaces_around_assignment_operators = true
[{*.ant, *.fxml, *.jhm, *.jnlp, *.jrxml, *.pom, *.rng, *.tld, *.wsdl, *.xml, *.xsd, *.xsl, *.xslt, *.xul}]
ij_xml_align_attributes = true
ij_xml_align_text = false
ij_xml_attribute_wrap = normal
ij_xml_block_comment_at_first_column = true
ij_xml_keep_blank_lines = 2
ij_xml_keep_indents_on_empty_lines = false
ij_xml_keep_line_breaks = true
ij_xml_keep_line_breaks_in_text = true
ij_xml_keep_whitespaces = false
ij_xml_keep_whitespaces_around_cdata = preserve
ij_xml_keep_whitespaces_inside_cdata = false
ij_xml_line_comment_at_first_column = true
ij_xml_space_after_tag_name = false
ij_xml_space_around_equals_in_attribute = false
ij_xml_space_inside_empty_tag = false
ij_xml_text_wrap = normal
[{*.markdown, *.md}]
indent_size = 2
tab_width = 2
ij_markdown_force_one_space_after_blockquote_symbol = true
ij_markdown_force_one_space_after_header_symbol = true
ij_markdown_force_one_space_after_list_bullet = true
ij_markdown_force_one_space_between_words = true
ij_markdown_keep_indents_on_empty_lines = false
ij_markdown_max_lines_around_block_elements = 1
ij_markdown_max_lines_around_header = 1
ij_markdown_max_lines_between_paragraphs = 1
ij_markdown_min_lines_around_block_elements = 1
ij_markdown_min_lines_around_header = 1
ij_markdown_min_lines_between_paragraphs = 1
[{*.yaml, *.yml, *.lang}]
indent_size = 2
ij_yaml_align_values_properties = do_not_align
ij_yaml_autoinsert_sequence_marker = true
ij_yaml_block_mapping_on_new_line = false
ij_yaml_indent_sequence_value = true
ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true
ij_yaml_sequence_on_new_line = false
ij_yaml_space_before_colon = false
ij_yaml_spaces_within_braces = true
ij_yaml_spaces_within_brackets = true

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: songoda
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "maven" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"

View File

@ -5,20 +5,39 @@ name: Build SongodaCore
on:
push:
branches: [ master ]
branches: [ master, development ]
pull_request:
branches: [ master ]
types: [ opened, synchronize, reopened ]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 16
uses: actions/setup-java@v1
with:
java-version: 16
- name: Build with Maven
run: mvn -B package --file pom.xml
# Setup Java
- uses: actions/setup-java@v2
with:
java-version: 16
distribution: adopt
# Checkout project files
- uses: actions/checkout@v2
# Caches
- name: 'Cache: Maven'
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
# Build project
- name: Build with Maven
run: 'mvn -B -Duser.name="GitHub Runner on $GITHUB_REPOSITORY (id=$GITHUB_RUN_ID)" clean package'
# Upload build artifacts
- name: 'Upload Build Artifact: SongodaCore-*.jar'
uses: actions/upload-artifact@v2
with:
name: SongodaCore-artifacts
path: ./Core/target/SongodaCore-*.jar

226
.gitignore vendored
View File

@ -1,214 +1,24 @@
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
##
# JetBrains IDEs
##
/.idea/
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
### Eclipse Patch ###
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Annotation Processing
.apt_generated
.sts4-cache/
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
auto-import.
.idea/modules.xml
.idea/*.iml
.idea/modules
# Don't exclude files that might not be related to the IDE
*.iml
*.ipr
/*/*.iml
/NMS/*/*.iml
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
##
# Maven
##
# Don't exclude a 'target' package by accident
/target/
/*/target/
/NMS/*/target/
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
*.iml
modules.xml
.idea/misc.xml
*.ipr
.idea/compiler.xml
# Sonarlint plugin
.idea/**/sonarlint/
# SonarQube Plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml
### NetBeans ###
**/nbproject/private/
**/nbproject/Makefile-*.mk
**/nbproject/Package-*.bash
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
### Gradle ###
.gradle
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Cache of project
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
### Gradle Patch ###
**/build/
.DS_Store
##
# Misc.
##
.DS_Store

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/Compatibility/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/Core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-API/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_10_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_11_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_12_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_13_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_13_R2/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_14_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_15_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_16_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_16_R2/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_16_R3/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_17_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_8_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_8_R2/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_8_R3/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_9_R1/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/NMS/NMS-v1_9_R2/src" charset="UTF-8" />
</component>
</project>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="spigot-repo" />
<option name="name" value="spigot-repo" />
<option name="url" value="https://hub.spigotmc.org/nexus/content/repositories/snapshots/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jitpack.io" />
<option name="name" value="jitpack.io" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="CodeMC" />
<option name="name" value="CodeMC" />
<option name="url" value="https://repo.codemc.org/repository/maven-public" />
</remote-repository>
<remote-repository>
<option name="id" value="public" />
<option name="name" value="public" />
<option name="url" value="https://repo.songoda.com/repository/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

View File

@ -1,29 +1,33 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<?xml version="1.0" encoding="UTF-8"?>
<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>com.songoda</groupId>
<artifactId>SongodaCore-Modules</artifactId>
<version>2.5.7</version>
<relativePath>../</relativePath>
<version>2.5.8</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>SongodaCore-Compatibility</artifactId>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>us.myles.viaversion-bukkit</groupId>
<artifactId>ViaVersion</artifactId>
<version>2.1.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>protocolsupport</groupId>
<artifactId>ProtocolSupport</artifactId>
@ -31,4 +35,4 @@
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,114 +1,115 @@
package com.songoda.core.compatibility;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.HashMap;
import java.util.UUID;
/**
* Handy reference for checking a connected client's Minecraft version<br>
* NOTE: this is automatically initialized through SongodaCore
*/
public class ClientVersion {
static HashMap<UUID, ServerVersion> players = new HashMap();
/**
* Check to see what client version this player is connected to the server
* with. Note that if a player is connecting with a newer client than the server,
* this value will simply be the server version.
*
* @param player Player to check
* @return ServerVersion that matches this player's Minecraft version
*/
public static ServerVersion getClientVersion(Player player) {
if (player == null || !players.containsKey(player.getUniqueId())) {
return ServerVersion.getServerVersion();
}
return players.get(player.getUniqueId());
}
/**
* Do Not Use: This is handled by SongodaCore.
*/
@Deprecated
public static void onLoginProtocol(Player p, JavaPlugin plugin) {
Bukkit.getScheduler().runTaskLater(plugin, () -> {
if (p.isOnline()) {
final int version = protocolsupport.api.ProtocolSupportAPI.getProtocolVersion(p).getId();
players.put(p.getUniqueId(), protocolToVersion(version));
}
}, 20);
}
/**
* Do Not Use: This is handled by SongodaCore.
*/
@Deprecated
public static void onLoginVia(Player p, JavaPlugin plugin) {
Bukkit.getScheduler().runTaskLater(plugin, () -> {
if (p.isOnline()) {
final int version = us.myles.ViaVersion.api.Via.getAPI().getPlayerVersion(p.getUniqueId());
players.put(p.getUniqueId(), protocolToVersion(version));
}
}, 20);
}
private static ServerVersion protocolToVersion(int version) {
// https://github.com/ViaVersion/ViaVersion/blob/master/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
// https://github.com/ProtocolSupport/ProtocolSupport/blob/master/src/protocolsupport/api/ProtocolVersion.java
switch (version) {
case 4:
case 5:
return ServerVersion.V1_7;
case 47:
return ServerVersion.V1_8;
case 107:
case 108:
case 109:
case 110:
return ServerVersion.V1_9;
case 210:
return ServerVersion.V1_10;
case 315:
case 316:
return ServerVersion.V1_11;
case 335:
case 338:
case 340:
return ServerVersion.V1_12;
case 393:
case 401:
case 404:
return ServerVersion.V1_13;
case 477:
case 485:
case 490:
case 498:
return ServerVersion.V1_14;
case 573:
case 575:
case 578:
return ServerVersion.V1_15;
case 735:
case 736:
case 751:
case 753:
case 754:
return ServerVersion.V1_16;
case 755:
return ServerVersion.V1_17;
}
return version > 498 ? ServerVersion.getServerVersion() : ServerVersion.UNKNOWN;
}
/**
* Do Not Use: This is handled by SongodaCore.
*/
@Deprecated
public static void onLogout(Player p) {
players.remove(p.getUniqueId());
}
}
package com.songoda.core.compatibility;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.HashMap;
import java.util.UUID;
/**
* Handy reference for checking a connected client's Minecraft version<br>
* NOTE: this is automatically initialized through SongodaCore
*/
public class ClientVersion {
static HashMap<UUID, ServerVersion> players = new HashMap();
/**
* Check to see what client version this player is connected to the server
* with. Note that if a player is connecting with a newer client than the server,
* this value will simply be the server version.
*
* @param player Player to check
*
* @return ServerVersion that matches this player's Minecraft version
*/
public static ServerVersion getClientVersion(Player player) {
if (player == null || !players.containsKey(player.getUniqueId())) {
return ServerVersion.getServerVersion();
}
return players.get(player.getUniqueId());
}
/**
* Do Not Use: This is handled by SongodaCore.
*/
@Deprecated
public static void onLoginProtocol(Player p, JavaPlugin plugin) {
Bukkit.getScheduler().runTaskLater(plugin, () -> {
if (p.isOnline()) {
final int version = protocolsupport.api.ProtocolSupportAPI.getProtocolVersion(p).getId();
players.put(p.getUniqueId(), protocolToVersion(version));
}
}, 20);
}
/**
* Do Not Use: This is handled by SongodaCore.
*/
@Deprecated
public static void onLoginVia(Player p, JavaPlugin plugin) {
Bukkit.getScheduler().runTaskLater(plugin, () -> {
if (p.isOnline()) {
final int version = us.myles.ViaVersion.api.Via.getAPI().getPlayerVersion(p.getUniqueId());
players.put(p.getUniqueId(), protocolToVersion(version));
}
}, 20);
}
private static ServerVersion protocolToVersion(int version) {
// https://github.com/ViaVersion/ViaVersion/blob/master/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
// https://github.com/ProtocolSupport/ProtocolSupport/blob/master/src/protocolsupport/api/ProtocolVersion.java
switch (version) {
case 4:
case 5:
return ServerVersion.V1_7;
case 47:
return ServerVersion.V1_8;
case 107:
case 108:
case 109:
case 110:
return ServerVersion.V1_9;
case 210:
return ServerVersion.V1_10;
case 315:
case 316:
return ServerVersion.V1_11;
case 335:
case 338:
case 340:
return ServerVersion.V1_12;
case 393:
case 401:
case 404:
return ServerVersion.V1_13;
case 477:
case 485:
case 490:
case 498:
return ServerVersion.V1_14;
case 573:
case 575:
case 578:
return ServerVersion.V1_15;
case 735:
case 736:
case 751:
case 753:
case 754:
return ServerVersion.V1_16;
case 755:
return ServerVersion.V1_17;
}
return version > 498 ? ServerVersion.getServerVersion() : ServerVersion.UNKNOWN;
}
/**
* Do Not Use: This is handled by SongodaCore.
*/
@Deprecated
public static void onLogout(Player p) {
players.remove(p.getUniqueId());
}
}

View File

@ -131,12 +131,12 @@ public enum CompatibleBiome {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
try {
Class<?> classBiomeBase = ClassMapping.BIOME_BASE.getClazz(),
classCraftChunk = ClassMapping.CRAFT_CHUNK.getClazz(),
classCraftBlock = ClassMapping.CRAFT_BLOCK.getClazz(),
classChunk = ClassMapping.CHUNK.getClazz(),
classBiomeStorage = ClassMapping.BIOME_STORAGE.getClazz(),
classIRegistry = ClassMapping.I_REGISTRY.getClazz();
Class<?> classBiomeBase = ClassMapping.BIOME_BASE.getClazz(),
classCraftChunk = ClassMapping.CRAFT_CHUNK.getClazz(),
classCraftBlock = ClassMapping.CRAFT_BLOCK.getClazz(),
classChunk = ClassMapping.CHUNK.getClazz(),
classBiomeStorage = ClassMapping.BIOME_STORAGE.getClazz(),
classIRegistry = ClassMapping.I_REGISTRY.getClazz();
methodBiomeToBiomeBase = isAbove1_16_R1 ? classCraftBlock.getMethod("biomeToBiomeBase", classIRegistry, Biome.class)
: classCraftBlock.getMethod("biomeToBiomeBase", Biome.class);
@ -189,7 +189,6 @@ public enum CompatibleBiome {
return compatibleBiomes;
}
public static CompatibleBiome getBiome(Biome biome) {
return biome == null ? null : lookupMap.get(biome.name());
}
@ -252,6 +251,5 @@ public enum CompatibleBiome {
this.version = version;
this.biome = biome;
}
}
}

View File

@ -75,6 +75,7 @@ public enum CompatibleHand {
* Get item in the selected hand
*
* @param player the player to get the item from
*
* @return the item
*/
public ItemStack getItem(Player player) {

View File

@ -1,129 +1,128 @@
package com.songoda.core.compatibility;
import org.bukkit.Material;
import java.util.HashMap;
import java.util.Map;
/**
* Starting in Minecraft 1.13, separate materials for blocks and items were
* phased out. This provides a translation for those values.
*
* @author jascotty2
* @since 2019-09-12
*/
public enum LegacyMaterialBlockType {
OAK_LEAVES("LEAVES", (byte)8, true),
SPRUCE_LEAVES("LEAVES", (byte)9, true),
BIRCH_LEAVES("LEAVES", (byte)10, true),
JUNGLE_LEAVES("LEAVES", (byte)11, true),
ACACIA_LEAVES("LEAVES_2", (byte)8, true),
DARK_OAK_LEAVES("LEAVES_2", (byte)9, true),
ACACIA_DOOR("ACACIA_DOOR", true),
BED("BED_BLOCK", true),
BIRCH_DOOR("BIRCH_DOOR", true),
FURNACE("FURNACE", "BURNING_FURNACE"),
CAKE("CAKE_BLOCK"),
CARROTS("CARROT"), // totally makes sense, lol
CAULDRON("CAULDRON_BLOCK"),
COMPARATOR("REDSTONE_COMPARATOR_OFF", "REDSTONE_COMPARATOR_ON"),
DARK_OAK_DOOR("DARK_OAK_DOOR", true),
DAYLIGHT_DETECTOR("DAYLIGHT_DETECTOR", "DAYLIGHT_DETECTOR_INVERTED"),
/*
< DOUBLE_STEP,
< DOUBLE_STONE_SLAB2,
*/
FLOWER_POT("FLOWER_POT"),
IRON_DOOR("IRON_DOOR_BLOCK", true),
JUNGLE_DOOR("JUNGLE_DOOR", true),
LAVA("STATIONARY_LAVA"),
NETHER_WART("NETHER_WARTS"),
/*
< PURPUR_DOUBLE_SLAB
*/
POTATOES("POTATO"),
REDSTONE_LAMP("REDSTONE_LAMP_OFF", "REDSTONE_LAMP_ON"),
REDSTONE_ORE("REDSTONE_ORE", "GLOWING_REDSTONE_ORE"),
REDSTONE_TORCH("REDSTONE_TORCH_ON", "REDSTONE_TORCH_OFF"),
SPRUCE_DOOR("SPRUCE_DOOR"),
SUGAR_CANE("SUGAR_CANE_BLOCK"),
WATER("STATIONARY_WATER"),
WHEAT("CROPS");
final String blockMaterialName;
final byte blockData;
final String alternateBlockMaterialName;
final Material blockMaterial, alternateBlockMaterial;
final boolean requiresData; // some blocks require data to render properly (double blocks)
final static Map<String, LegacyMaterialBlockType> lookupTable = new HashMap();
final static Map<String, LegacyMaterialBlockType> reverseLookupTable = new HashMap();
static {
for (LegacyMaterialBlockType t : values()) {
lookupTable.put(t.name(), t);
reverseLookupTable.put(t.blockMaterialName + ":" + t.blockData, t);
if (t.alternateBlockMaterialName != null) {
reverseLookupTable.put(t.alternateBlockMaterialName, t);
}
}
}
private LegacyMaterialBlockType(String blockMaterial) {
this(blockMaterial, (byte)-1, null,false);
}
private LegacyMaterialBlockType(String blockMaterial, boolean requiresData) {
this(blockMaterial, (byte)-1, null, requiresData);
}
private LegacyMaterialBlockType(String blockMaterial, byte data, boolean requiresData) {
this(blockMaterial, data, null, requiresData);
}
private LegacyMaterialBlockType(String blockMaterial, String alternateMaterial) {
this(blockMaterial, (byte)-1, alternateMaterial, false);
}
private LegacyMaterialBlockType(String blockMaterial, byte data, String alternateMaterial, boolean requiresData) {
this.blockMaterialName = blockMaterial;
this.alternateBlockMaterialName = alternateMaterial;
this.requiresData = requiresData;
this.blockMaterial = Material.getMaterial(blockMaterialName);
this.alternateBlockMaterial = Material.getMaterial(alternateBlockMaterialName);
this.blockData = data;
}
public String getBlockMaterialName() {
return blockMaterialName;
}
public String getAlternateMaterialName() {
return alternateBlockMaterialName;
}
public Material getBlockMaterial() {
return blockMaterial;
}
public Material getAlternateBlockMaterial() {
return alternateBlockMaterial;
}
public boolean requiresData() {
return requiresData;
}
public static LegacyMaterialBlockType getMaterial(String lookup) {
return lookupTable.get(lookup);
}
public static LegacyMaterialBlockType getFromLegacy(String lookup, byte data) {
return reverseLookupTable.get(lookup + ":" + data);
}
public static LegacyMaterialBlockType getFromLegacy(String lookup) {
return getFromLegacy(lookup, (byte)-1);
}
}
package com.songoda.core.compatibility;
import org.bukkit.Material;
import java.util.HashMap;
import java.util.Map;
/**
* Starting in Minecraft 1.13, separate materials for blocks and items were
* phased out. This provides a translation for those values.
*
* @author jascotty2
* @since 2019-09-12
*/
public enum LegacyMaterialBlockType {
OAK_LEAVES("LEAVES", (byte) 8, true),
SPRUCE_LEAVES("LEAVES", (byte) 9, true),
BIRCH_LEAVES("LEAVES", (byte) 10, true),
JUNGLE_LEAVES("LEAVES", (byte) 11, true),
ACACIA_LEAVES("LEAVES_2", (byte) 8, true),
DARK_OAK_LEAVES("LEAVES_2", (byte) 9, true),
ACACIA_DOOR("ACACIA_DOOR", true),
BED("BED_BLOCK", true),
BIRCH_DOOR("BIRCH_DOOR", true),
FURNACE("FURNACE", "BURNING_FURNACE"),
CAKE("CAKE_BLOCK"),
CARROTS("CARROT"), // totally makes sense, lol
CAULDRON("CAULDRON_BLOCK"),
COMPARATOR("REDSTONE_COMPARATOR_OFF", "REDSTONE_COMPARATOR_ON"),
DARK_OAK_DOOR("DARK_OAK_DOOR", true),
DAYLIGHT_DETECTOR("DAYLIGHT_DETECTOR", "DAYLIGHT_DETECTOR_INVERTED"),
/*
< DOUBLE_STEP,
< DOUBLE_STONE_SLAB2,
*/
FLOWER_POT("FLOWER_POT"),
IRON_DOOR("IRON_DOOR_BLOCK", true),
JUNGLE_DOOR("JUNGLE_DOOR", true),
LAVA("STATIONARY_LAVA"),
NETHER_WART("NETHER_WARTS"),
/*
< PURPUR_DOUBLE_SLAB
*/
POTATOES("POTATO"),
REDSTONE_LAMP("REDSTONE_LAMP_OFF", "REDSTONE_LAMP_ON"),
REDSTONE_ORE("REDSTONE_ORE", "GLOWING_REDSTONE_ORE"),
REDSTONE_TORCH("REDSTONE_TORCH_ON", "REDSTONE_TORCH_OFF"),
SPRUCE_DOOR("SPRUCE_DOOR"),
SUGAR_CANE("SUGAR_CANE_BLOCK"),
WATER("STATIONARY_WATER"),
WHEAT("CROPS");
final String blockMaterialName;
final byte blockData;
final String alternateBlockMaterialName;
final Material blockMaterial, alternateBlockMaterial;
final boolean requiresData; // some blocks require data to render properly (double blocks)
final static Map<String, LegacyMaterialBlockType> lookupTable = new HashMap();
final static Map<String, LegacyMaterialBlockType> reverseLookupTable = new HashMap();
static {
for (LegacyMaterialBlockType t : values()) {
lookupTable.put(t.name(), t);
reverseLookupTable.put(t.blockMaterialName + ":" + t.blockData, t);
if (t.alternateBlockMaterialName != null) {
reverseLookupTable.put(t.alternateBlockMaterialName, t);
}
}
}
private LegacyMaterialBlockType(String blockMaterial) {
this(blockMaterial, (byte) -1, null, false);
}
private LegacyMaterialBlockType(String blockMaterial, boolean requiresData) {
this(blockMaterial, (byte) -1, null, requiresData);
}
private LegacyMaterialBlockType(String blockMaterial, byte data, boolean requiresData) {
this(blockMaterial, data, null, requiresData);
}
private LegacyMaterialBlockType(String blockMaterial, String alternateMaterial) {
this(blockMaterial, (byte) -1, alternateMaterial, false);
}
private LegacyMaterialBlockType(String blockMaterial, byte data, String alternateMaterial, boolean requiresData) {
this.blockMaterialName = blockMaterial;
this.alternateBlockMaterialName = alternateMaterial;
this.requiresData = requiresData;
this.blockMaterial = Material.getMaterial(blockMaterialName);
this.alternateBlockMaterial = Material.getMaterial(alternateBlockMaterialName);
this.blockData = data;
}
public String getBlockMaterialName() {
return blockMaterialName;
}
public String getAlternateMaterialName() {
return alternateBlockMaterialName;
}
public Material getBlockMaterial() {
return blockMaterial;
}
public Material getAlternateBlockMaterial() {
return alternateBlockMaterial;
}
public boolean requiresData() {
return requiresData;
}
public static LegacyMaterialBlockType getMaterial(String lookup) {
return lookupTable.get(lookup);
}
public static LegacyMaterialBlockType getFromLegacy(String lookup, byte data) {
return reverseLookupTable.get(lookup + ":" + data);
}
public static LegacyMaterialBlockType getFromLegacy(String lookup) {
return getFromLegacy(lookup, (byte) -1);
}
}

View File

@ -1,54 +1,53 @@
package com.songoda.core.compatibility;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Bukkit;
public enum ServerProject {
UNKNOWN, CRAFTBUKKIT, SPIGOT, PAPER, TACO, GLOWSTONE;
private final static ServerProject serverProject = checkProject();
private static ServerProject checkProject() {
String serverPath = Bukkit.getServer().getClass().getName();
if (serverPath.contains("glowstone")) {
return GLOWSTONE;
}
// taco is pretty easy to check. it uses paper stuff, though, so should be checked first
try {
Class.forName("net.techcable.tacospigot.TacoSpigotConfig");
return TACO;
} catch (ClassNotFoundException ex) {
}
// paper used to be called "paperclip"
try {
Class.forName("com.destroystokyo.paperclip.Paperclip");
return PAPER;
} catch (ClassNotFoundException ex) {
}
try {
Class.forName("com.destroystokyo.paper.PaperConfig");
return PAPER;
} catch (ClassNotFoundException ex) {
}
// spigot is the fork that pretty much all builds are based on anymore
try {
Class.forName("org.spigotmc.SpigotConfig");
return SPIGOT;
} catch (ClassNotFoundException ex) {
}
return serverPath.contains("craftbukkit") ? CRAFTBUKKIT : UNKNOWN;
}
public static ServerProject getServerVersion() {
return serverProject;
}
public static boolean isServer(ServerProject version) {
return serverProject == version;
}
public static boolean isServer(ServerProject... versions) {
return ArrayUtils.contains(versions, serverProject);
}
}
package com.songoda.core.compatibility;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Bukkit;
public enum ServerProject {
UNKNOWN, CRAFTBUKKIT, SPIGOT, PAPER, TACO, GLOWSTONE;
private final static ServerProject serverProject = checkProject();
private static ServerProject checkProject() {
String serverPath = Bukkit.getServer().getClass().getName();
if (serverPath.contains("glowstone")) {
return GLOWSTONE;
}
// taco is pretty easy to check. it uses paper stuff, though, so should be checked first
try {
Class.forName("net.techcable.tacospigot.TacoSpigotConfig");
return TACO;
} catch (ClassNotFoundException ex) {
}
// paper used to be called "paperclip"
try {
Class.forName("com.destroystokyo.paperclip.Paperclip");
return PAPER;
} catch (ClassNotFoundException ex) {
}
try {
Class.forName("com.destroystokyo.paper.PaperConfig");
return PAPER;
} catch (ClassNotFoundException ex) {
}
// spigot is the fork that pretty much all builds are based on anymore
try {
Class.forName("org.spigotmc.SpigotConfig");
return SPIGOT;
} catch (ClassNotFoundException ex) {
}
return serverPath.contains("craftbukkit") ? CRAFTBUKKIT : UNKNOWN;
}
public static ServerProject getServerVersion() {
return serverProject;
}
public static boolean isServer(ServerProject version) {
return serverProject == version;
}
public static boolean isServer(ServerProject... versions) {
return ArrayUtils.contains(versions, serverProject);
}
}

View File

@ -1,27 +1,28 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<?xml version="1.0" encoding="UTF-8"?>
<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>com.songoda</groupId>
<artifactId>SongodaCore-Modules</artifactId>
<version>2.5.7</version>
<relativePath>../</relativePath>
<version>2.5.8</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<defaultGoal>clean install</defaultGoal>
<finalName>SongodaCore-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
@ -29,42 +30,52 @@
<release>${java.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>shaded</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>true</createDependencyReducedPom>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<includes>
<include>com.songoda:*</include>
<include>com.zaxxer:HikariCP</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<includes>
<include>com/</include>
<include>META-INF/MANIFEST.MF</include>
@ -76,30 +87,9 @@
</execution>
</executions>
</plugin>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>../assembly.xml</descriptor>
</descriptors>
<finalName>SongodaCore-${project.version}</finalName>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
@ -107,135 +97,121 @@
<version>1.17</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-Compatibility</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Need to include all NMS modules here -->
<!-- Note when adding a new module: include the class in NmsManager -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-API</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_8_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_8_R2</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_8_R3</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_9_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_9_R2</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_10_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_11_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_12_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_13_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_13_R2</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_14_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_15_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_16_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_16_R2</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_16_R3</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS-v1_17_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- End NMS -->
<!-- Start Plugin Hooks -->
<dependency>
<groupId>com.gmail.filoghost.holographicdisplays</groupId>
@ -243,152 +219,171 @@
<version>2.3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sainttx</groupId>
<artifactId>Holograms</artifactId>
<version>2.13</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.Zrips</groupId>
<artifactId>CMI-API</artifactId>
<version>7.6.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.tnemc</groupId>
<artifactId>Reserve</artifactId>
<version>0.1.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.black_ixx</groupId>
<artifactId>PlayerPoints</artifactId>
<version>2.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.milkbowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>UltimateStacker</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.bgsoftware</groupId>
<artifactId>wildstacker</artifactId>
<version>3.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>uk.antiperson</groupId>
<artifactId>stackmob</artifactId>
<version>4-0-2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.Zrips</groupId>
<artifactId>Jobs</artifactId>
<version>LATEST</version>
<version>v4.17.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.50</version>
<version>2.1.200</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net</groupId>
<artifactId>coreprotect</artifactId>
<version>2.17.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.ryanhamshire</groupId>
<artifactId>GriefPrevention</artifactId>
<version>16.16.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.angeschossen</groupId>
<artifactId>LandsAPI</artifactId>
<version>4.12.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>br.net.fabiozumbi12</groupId>
<artifactId>RedProtect</artifactId>
<version>7.7.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>UltimateClaims</artifactId>
<version>1.3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.palmergames</groupId>
<artifactId>Towny</artifactId>
<version>0.96.5.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>world.bentobox</groupId>
<artifactId>bentobox</artifactId>
<version>1.15.5</version>
<scope>provided</scope>
</dependency>
<!-- End Plugin Hooks -->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>

View File

@ -9,8 +9,6 @@ import com.songoda.core.core.PluginInfoModule;
import com.songoda.core.core.SongodaCoreCommand;
import com.songoda.core.core.SongodaCoreDiagCommand;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
@ -22,7 +20,6 @@ import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
@ -56,7 +53,7 @@ public class SongodaCore {
/**
* This has been added as of Rev 6
*/
private final static String coreVersion = "2.5.7";
private final static String coreVersion = "2.5.8";
/**
* This is specific to the website api
@ -73,7 +70,7 @@ public class SongodaCore {
public static boolean hasShading() {
// sneaky hack to check the package name since maven tries to re-shade all references to the package string
return !SongodaCore.class.getPackage().getName().equals(new String(new char[]{'c', 'o', 'm', '.', 's', 'o', 'n', 'g', 'o', 'd', 'a', '.', 'c', 'o', 'r', 'e'}));
return !SongodaCore.class.getPackage().getName().equals(new String(new char[] {'c', 'o', 'm', '.', 's', 'o', 'n', 'g', 'o', 'd', 'a', '.', 'c', 'o', 'r', 'e'}));
}
public static void registerPlugin(JavaPlugin plugin, int pluginID, CompatibleMaterial icon) {
@ -315,7 +312,7 @@ public class SongodaCore {
if (!via && (via = event.getPlugin().getName().equals("ViaVersion"))) {
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginVia(p, getHijackedPlugin()));
} else if (!proto && (proto = event.getPlugin().getName().equals("ProtocolSupport"))) {
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginProtocol(p, getHijackedPlugin()));
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginProtocol(p, getHijackedPlugin()));
}
}
}

View File

@ -1,177 +1,178 @@
package com.songoda.core;
import com.songoda.core.configuration.Config;
import com.songoda.core.locale.Locale;
import com.songoda.core.utils.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.List;
import java.util.logging.Level;
/**
* REMINDER: When converting plugins to use this, REMOVE METRICS <br>
* Must not have two instances of Metrics enabled!
*
* @author jascotty2
*/
public abstract class SongodaPlugin extends JavaPlugin {
protected Locale locale;
protected Config config = new Config(this);
protected long dataLoadDelay = 20L;
protected ConsoleCommandSender console = Bukkit.getConsoleSender();
private boolean emergencyStop = false;
public abstract void onPluginLoad();
public abstract void onPluginEnable();
public abstract void onPluginDisable();
public abstract void onDataLoad();
/**
* Called after reloadConfig() is called
*/
public abstract void onConfigReload();
/**
* Any other plugin configuration files used by the plugin.
*
* @return a list of Configs that are used in addition to the main config.
*/
public abstract List<Config> getExtraConfig();
@Override
public FileConfiguration getConfig() {
return config.getFileConfig();
}
public Config getCoreConfig() {
return config;
}
@Override
public void reloadConfig() {
config.load();
onConfigReload();
}
@Override
public void saveConfig() {
config.save();
}
@Override
public final void onLoad() {
try {
onPluginLoad();
} catch (Throwable t) {
Bukkit.getLogger().log(Level.SEVERE,
"Unexpected error while loading " + getDescription().getName()
+ " v" + getDescription().getVersion()
+ " c" + SongodaCore.getCoreLibraryVersion()
+ ": Disabling plugin!", t);
emergencyStop = true;
}
}
@Override
public final void onEnable() {
if (emergencyStop) {
setEnabled(false);
return;
}
console.sendMessage(" "); // blank line to separate chatter
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
ChatColor.GREEN.toString(), "Enabling", ChatColor.GRAY.toString()));
try {
locale = Locale.loadDefaultLocale(this, "en_US");
// plugin setup
onPluginEnable();
// Load Data.
Bukkit.getScheduler().runTaskLater(this, this::onDataLoad, dataLoadDelay);
if (emergencyStop) {
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.sendMessage(" ");
return;
}
// Start Metrics
Metrics.start(this);
} catch (Throwable t) {
Bukkit.getLogger().log(Level.SEVERE,
"Unexpected error while loading " + getDescription().getName()
+ " v" + getDescription().getVersion()
+ " c" + SongodaCore.getCoreLibraryVersion()
+ ": Disabling plugin!", t);
emergencyStop();
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.sendMessage(" ");
return;
}
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(" "); // blank line to separate chatter
}
protected void emergencyStop() {
emergencyStop = true;
Bukkit.getPluginManager().disablePlugin(this);
}
@Override
public final void onDisable() {
if (emergencyStop) {
return;
}
console.sendMessage(" "); // blank line to speparate chatter
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
ChatColor.RED.toString(), "Disabling", ChatColor.GRAY.toString()));
onPluginDisable();
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(" "); // blank line to speparate chatter
}
public ConsoleCommandSender getConsole() {
return console;
}
public Locale getLocale() {
return locale;
}
/**
* Set the plugin's locale to a specific language
*
* @param localeName locale to use, eg "en_US"
* @param reload optionally reload the loaded locale if the locale didn't
* change
* @return true if the locale exists and was loaded successfully
*/
public boolean setLocale(String localeName, boolean reload) {
if (locale != null && locale.getName().equals(localeName)) {
return !reload || locale.reloadMessages();
} else {
Locale l = Locale.loadLocale(this, localeName);
if (l != null) {
locale = l;
return true;
} else {
return false;
}
}
}
}
package com.songoda.core;
import com.songoda.core.configuration.Config;
import com.songoda.core.locale.Locale;
import com.songoda.core.utils.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.List;
import java.util.logging.Level;
/**
* REMINDER: When converting plugins to use this, REMOVE METRICS <br>
* Must not have two instances of Metrics enabled!
*
* @author jascotty2
*/
public abstract class SongodaPlugin extends JavaPlugin {
protected Locale locale;
protected Config config = new Config(this);
protected long dataLoadDelay = 20L;
protected ConsoleCommandSender console = Bukkit.getConsoleSender();
private boolean emergencyStop = false;
public abstract void onPluginLoad();
public abstract void onPluginEnable();
public abstract void onPluginDisable();
public abstract void onDataLoad();
/**
* Called after reloadConfig() is called
*/
public abstract void onConfigReload();
/**
* Any other plugin configuration files used by the plugin.
*
* @return a list of Configs that are used in addition to the main config.
*/
public abstract List<Config> getExtraConfig();
@Override
public FileConfiguration getConfig() {
return config.getFileConfig();
}
public Config getCoreConfig() {
return config;
}
@Override
public void reloadConfig() {
config.load();
onConfigReload();
}
@Override
public void saveConfig() {
config.save();
}
@Override
public final void onLoad() {
try {
onPluginLoad();
} catch (Throwable t) {
Bukkit.getLogger().log(Level.SEVERE,
"Unexpected error while loading " + getDescription().getName()
+ " v" + getDescription().getVersion()
+ " c" + SongodaCore.getCoreLibraryVersion()
+ ": Disabling plugin!", t);
emergencyStop = true;
}
}
@Override
public final void onEnable() {
if (emergencyStop) {
setEnabled(false);
return;
}
console.sendMessage(" "); // blank line to separate chatter
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
ChatColor.GREEN.toString(), "Enabling", ChatColor.GRAY.toString()));
try {
locale = Locale.loadDefaultLocale(this, "en_US");
// plugin setup
onPluginEnable();
// Load Data.
Bukkit.getScheduler().runTaskLater(this, this::onDataLoad, dataLoadDelay);
if (emergencyStop) {
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.sendMessage(" ");
return;
}
// Start Metrics
Metrics.start(this);
} catch (Throwable t) {
Bukkit.getLogger().log(Level.SEVERE,
"Unexpected error while loading " + getDescription().getName()
+ " v" + getDescription().getVersion()
+ " c" + SongodaCore.getCoreLibraryVersion()
+ ": Disabling plugin!", t);
emergencyStop();
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
console.sendMessage(" ");
return;
}
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(" "); // blank line to separate chatter
}
protected void emergencyStop() {
emergencyStop = true;
Bukkit.getPluginManager().disablePlugin(this);
}
@Override
public final void onDisable() {
if (emergencyStop) {
return;
}
console.sendMessage(" "); // blank line to speparate chatter
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
ChatColor.RED.toString(), "Disabling", ChatColor.GRAY.toString()));
onPluginDisable();
console.sendMessage(ChatColor.GREEN + "=============================");
console.sendMessage(" "); // blank line to speparate chatter
}
public ConsoleCommandSender getConsole() {
return console;
}
public Locale getLocale() {
return locale;
}
/**
* Set the plugin's locale to a specific language
*
* @param localeName locale to use, eg "en_US"
* @param reload optionally reload the loaded locale if the locale didn't
* change
*
* @return true if the locale exists and was loaded successfully
*/
public boolean setLocale(String localeName, boolean reload) {
if (locale != null && locale.getName().equals(localeName)) {
return !reload || locale.reloadMessages();
} else {
Locale l = Locale.loadLocale(this, localeName);
if (l != null) {
locale = l;
return true;
} else {
return false;
}
}
}
}

View File

@ -1,274 +1,273 @@
package com.songoda.core.chat;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.utils.TextUtils;
import net.minecraft.network.chat.IChatBaseComponent;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatMessage {
private static final Gson gson = new GsonBuilder().create();
private final List<JsonObject> textList = new ArrayList<>();
public void clear() {
textList.clear();
}
public ChatMessage fromText(String text) {
return fromText(text, false);
}
public ChatMessage fromText(String text, boolean noHex) {
Pattern pattern = Pattern.compile("(.*?)(?!&([omnlk]))(?=(&([123456789abcdefr#])|$)|#([a-f]|[A-F]|[0-9]){6})",
Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
ColorContainer color = null;
String match1 = matcher.group(1);
if (matcher.groupCount() == 0 || match1.length() == 0) continue;
char colorChar = '-';
if (matcher.start() != 0)
colorChar = text.substring(matcher.start() - 1, matcher.start()).charAt(0);
if (colorChar != '-') {
if (colorChar == '#') {
color = new ColorContainer(match1.substring(0, 6), noHex);
match1 = match1.substring(5);
} else if (colorChar == '&') {
color = new ColorContainer(ColorCode.getByChar(Character.toLowerCase(match1.charAt(0))));
}
}
Pattern subPattern = Pattern.compile("(.*?)(?=&([omnlk])|$)");
Matcher subMatcher = subPattern.matcher(match1);
List<ColorCode> stackedCodes = new ArrayList<>();
while (subMatcher.find()) {
String match2 = subMatcher.group(1);
if (match2.length() == 0) continue;
ColorCode code = ColorCode.getByChar(Character.toLowerCase(match2.charAt(0)));
if (code != null && code != ColorCode.RESET)
stackedCodes.add(code);
if (color != null)
match2 = match2.substring(1);
if (match2.length() == 0) continue;
addMessage(match2, color, stackedCodes);
}
}
return this;
}
public String toText() {
return toText(false);
}
public String toText(boolean noHex) {
StringBuilder text = new StringBuilder();
for (JsonObject object : textList) {
if (object.has("color")) {
String color = object.get("color").getAsString();
text.append("&");
if (color.length() == 7) {
text.append(new ColorContainer(color, noHex).getColor().getCode());
} else {
text.append(ColorCode.valueOf(color.toUpperCase()).getCode());
}
}
for (ColorCode code : ColorCode.values()) {
if (code.isColor()) continue;
String c = code.name().toLowerCase();
if (object.has(c) && object.get(c).getAsBoolean())
text.append("&").append(code.getCode());
}
text.append(object.get("text").getAsString());
}
return text.toString();
}
public ChatMessage addMessage(String s) {
JsonObject txt = new JsonObject();
txt.addProperty("text", s);
textList.add(txt);
return this;
}
public ChatMessage addMessage(String text, ColorContainer color) {
return addMessage(text, color, Collections.emptyList());
}
public ChatMessage addMessage(String text, ColorContainer color, List<ColorCode> colorCodes) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
if (color != null)
txt.addProperty("color", color.getHexCode() != null ? "#" + color.getHexCode() : color.getColorCode().name().toLowerCase());
for (ColorCode code : ColorCode.values()) {
if (!code.isColor())
txt.addProperty(code.name().toLowerCase(), colorCodes.contains(code));
}
textList.add(txt);
return this;
}
public ChatMessage addRunCommand(String text, String hoverText, String cmd) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_text");
hover.addProperty("value", hoverText);
txt.add("hoverEvent", hover);
JsonObject click = new JsonObject();
click.addProperty("action", "run_command");
click.addProperty("value", cmd);
txt.add("clickEvent", click);
textList.add(txt);
return this;
}
public ChatMessage addPromptCommand(String text, String hoverText, String cmd) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_text");
hover.addProperty("value", hoverText);
txt.add("hoverEvent", hover);
JsonObject click = new JsonObject();
click.addProperty("action", "suggest_command");
click.addProperty("value", cmd);
txt.add("clickEvent", click);
textList.add(txt);
return this;
}
public ChatMessage addURL(String text, String hoverText, String url) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_text");
hover.addProperty("value", hoverText);
txt.add("hoverEvent", hover);
JsonObject click = new JsonObject();
click.addProperty("action", "open_url");
click.addProperty("value", url);
txt.add("clickEvent", hover);
textList.add(txt);
return this;
}
@Override
public String toString() {
return gson.toJson(textList);
}
public void sendTo(CommandSender sender) {
sendTo(null, sender);
}
public void sendTo(ChatMessage prefix, CommandSender sender) {
if (sender instanceof Player && enabled) {
try {
List<JsonObject> textList = prefix == null ? new ArrayList<>() : new ArrayList<>(prefix.textList);
textList.addAll(this.textList);
Object packet;
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)) {
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)), mc_chatMessageType_Chat.get(null), ((Player) sender).getUniqueId());
} else {
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)));
}
Object cbPlayer = cb_craftPlayer_getHandle.invoke(sender);
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
enabled = false;
}
} else {
sender.sendMessage(TextUtils.formatText((prefix == null ? "" : prefix.toText(true) + " ") + toText(true)));
}
}
private static boolean enabled = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_8);
private static Class<?> mc_ChatMessageType;
private static Method mc_IChatBaseComponent_ChatSerializer_a, cb_craftPlayer_getHandle, mc_playerConnection_sendPacket;
private static Constructor mc_PacketPlayOutChat_new;
private static Field mc_entityPlayer_playerConnection, mc_chatMessageType_Chat;
static {
init();
}
static void init() {
if (enabled) {
try {
final String version = ServerVersion.getServerVersionString();
Class<?> cb_craftPlayerClazz, mc_entityPlayerClazz, mc_playerConnectionClazz, mc_PacketInterface,
mc_IChatBaseComponent, mc_IChatBaseComponent_ChatSerializer, mc_PacketPlayOutChat;
cb_craftPlayerClazz = ClassMapping.CRAFT_PLAYER.getClazz();
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
mc_entityPlayerClazz = ClassMapping.ENTITY_PLAYER.getClazz();
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) ? "b" : "playerConnection");
mc_playerConnectionClazz = ClassMapping.PLAYER_CONNECTION.getClazz();
mc_PacketInterface = ClassMapping.PACKET.getClazz();
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
mc_IChatBaseComponent = ClassMapping.I_CHAT_BASE_COMPONENT.getClazz();
mc_IChatBaseComponent_ChatSerializer = ClassMapping.I_CHAT_BASE_COMPONENT.getClazz("ChatSerializer");
mc_IChatBaseComponent_ChatSerializer_a = mc_IChatBaseComponent_ChatSerializer.getMethod("a", String.class);
mc_PacketPlayOutChat = ClassMapping.PACKET_PLAY_OUT_CHAT.getClazz();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)) {
mc_ChatMessageType = ClassMapping.CHAT_MESSAGE_TYPE.getClazz();
mc_chatMessageType_Chat = mc_ChatMessageType.getField(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) ? "a" : "CHAT");
mc_PacketPlayOutChat_new = mc_PacketPlayOutChat.getConstructor(mc_IChatBaseComponent, mc_ChatMessageType, UUID.class);
} else {
mc_PacketPlayOutChat_new = mc_PacketPlayOutChat.getConstructor(mc_IChatBaseComponent);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
enabled = false;
}
}
}
public ChatMessage replaceAll(String toReplace, String replaceWith) {
for (JsonObject object : textList) {
String text = object.get("text").getAsString()
.replaceAll(toReplace, replaceWith);
object.remove("text");
object.addProperty("text", text);
}
return this;
}
}
package com.songoda.core.chat;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatMessage {
private static final Gson gson = new GsonBuilder().create();
private final List<JsonObject> textList = new ArrayList<>();
public void clear() {
textList.clear();
}
public ChatMessage fromText(String text) {
return fromText(text, false);
}
public ChatMessage fromText(String text, boolean noHex) {
Pattern pattern = Pattern.compile("(.*?)(?!&([omnlk]))(?=(&([123456789abcdefr#])|$)|#([a-f]|[A-F]|[0-9]){6})",
Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
ColorContainer color = null;
String match1 = matcher.group(1);
if (matcher.groupCount() == 0 || match1.length() == 0) continue;
char colorChar = '-';
if (matcher.start() != 0)
colorChar = text.substring(matcher.start() - 1, matcher.start()).charAt(0);
if (colorChar != '-') {
if (colorChar == '#') {
color = new ColorContainer(match1.substring(0, 6), noHex);
match1 = match1.substring(5);
} else if (colorChar == '&') {
color = new ColorContainer(ColorCode.getByChar(Character.toLowerCase(match1.charAt(0))));
}
}
Pattern subPattern = Pattern.compile("(.*?)(?=&([omnlk])|$)");
Matcher subMatcher = subPattern.matcher(match1);
List<ColorCode> stackedCodes = new ArrayList<>();
while (subMatcher.find()) {
String match2 = subMatcher.group(1);
if (match2.length() == 0) continue;
ColorCode code = ColorCode.getByChar(Character.toLowerCase(match2.charAt(0)));
if (code != null && code != ColorCode.RESET)
stackedCodes.add(code);
if (color != null)
match2 = match2.substring(1);
if (match2.length() == 0) continue;
addMessage(match2, color, stackedCodes);
}
}
return this;
}
public String toText() {
return toText(false);
}
public String toText(boolean noHex) {
StringBuilder text = new StringBuilder();
for (JsonObject object : textList) {
if (object.has("color")) {
String color = object.get("color").getAsString();
text.append("&");
if (color.length() == 7) {
text.append(new ColorContainer(color, noHex).getColor().getCode());
} else {
text.append(ColorCode.valueOf(color.toUpperCase()).getCode());
}
}
for (ColorCode code : ColorCode.values()) {
if (code.isColor()) continue;
String c = code.name().toLowerCase();
if (object.has(c) && object.get(c).getAsBoolean())
text.append("&").append(code.getCode());
}
text.append(object.get("text").getAsString());
}
return text.toString();
}
public ChatMessage addMessage(String s) {
JsonObject txt = new JsonObject();
txt.addProperty("text", s);
textList.add(txt);
return this;
}
public ChatMessage addMessage(String text, ColorContainer color) {
return addMessage(text, color, Collections.emptyList());
}
public ChatMessage addMessage(String text, ColorContainer color, List<ColorCode> colorCodes) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
if (color != null)
txt.addProperty("color", color.getHexCode() != null ? "#" + color.getHexCode() : color.getColorCode().name().toLowerCase());
for (ColorCode code : ColorCode.values()) {
if (!code.isColor())
txt.addProperty(code.name().toLowerCase(), colorCodes.contains(code));
}
textList.add(txt);
return this;
}
public ChatMessage addRunCommand(String text, String hoverText, String cmd) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_text");
hover.addProperty("value", hoverText);
txt.add("hoverEvent", hover);
JsonObject click = new JsonObject();
click.addProperty("action", "run_command");
click.addProperty("value", cmd);
txt.add("clickEvent", click);
textList.add(txt);
return this;
}
public ChatMessage addPromptCommand(String text, String hoverText, String cmd) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_text");
hover.addProperty("value", hoverText);
txt.add("hoverEvent", hover);
JsonObject click = new JsonObject();
click.addProperty("action", "suggest_command");
click.addProperty("value", cmd);
txt.add("clickEvent", click);
textList.add(txt);
return this;
}
public ChatMessage addURL(String text, String hoverText, String url) {
JsonObject txt = new JsonObject();
txt.addProperty("text", text);
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_text");
hover.addProperty("value", hoverText);
txt.add("hoverEvent", hover);
JsonObject click = new JsonObject();
click.addProperty("action", "open_url");
click.addProperty("value", url);
txt.add("clickEvent", hover);
textList.add(txt);
return this;
}
@Override
public String toString() {
return gson.toJson(textList);
}
public void sendTo(CommandSender sender) {
sendTo(null, sender);
}
public void sendTo(ChatMessage prefix, CommandSender sender) {
if (sender instanceof Player && enabled) {
try {
List<JsonObject> textList = prefix == null ? new ArrayList<>() : new ArrayList<>(prefix.textList);
textList.addAll(this.textList);
Object packet;
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)) {
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)), mc_chatMessageType_Chat.get(null), ((Player) sender).getUniqueId());
} else {
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)));
}
Object cbPlayer = cb_craftPlayer_getHandle.invoke(sender);
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
enabled = false;
}
} else {
sender.sendMessage(TextUtils.formatText((prefix == null ? "" : prefix.toText(true) + " ") + toText(true)));
}
}
private static boolean enabled = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_8);
private static Class<?> mc_ChatMessageType;
private static Method mc_IChatBaseComponent_ChatSerializer_a, cb_craftPlayer_getHandle, mc_playerConnection_sendPacket;
private static Constructor mc_PacketPlayOutChat_new;
private static Field mc_entityPlayer_playerConnection, mc_chatMessageType_Chat;
static {
init();
}
static void init() {
if (enabled) {
try {
final String version = ServerVersion.getServerVersionString();
Class<?> cb_craftPlayerClazz, mc_entityPlayerClazz, mc_playerConnectionClazz, mc_PacketInterface,
mc_IChatBaseComponent, mc_IChatBaseComponent_ChatSerializer, mc_PacketPlayOutChat;
cb_craftPlayerClazz = ClassMapping.CRAFT_PLAYER.getClazz();
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
mc_entityPlayerClazz = ClassMapping.ENTITY_PLAYER.getClazz();
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) ? "b" : "playerConnection");
mc_playerConnectionClazz = ClassMapping.PLAYER_CONNECTION.getClazz();
mc_PacketInterface = ClassMapping.PACKET.getClazz();
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
mc_IChatBaseComponent = ClassMapping.I_CHAT_BASE_COMPONENT.getClazz();
mc_IChatBaseComponent_ChatSerializer = ClassMapping.I_CHAT_BASE_COMPONENT.getClazz("ChatSerializer");
mc_IChatBaseComponent_ChatSerializer_a = mc_IChatBaseComponent_ChatSerializer.getMethod("a", String.class);
mc_PacketPlayOutChat = ClassMapping.PACKET_PLAY_OUT_CHAT.getClazz();
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)) {
mc_ChatMessageType = ClassMapping.CHAT_MESSAGE_TYPE.getClazz();
mc_chatMessageType_Chat = mc_ChatMessageType.getField(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) ? "a" : "CHAT");
mc_PacketPlayOutChat_new = mc_PacketPlayOutChat.getConstructor(mc_IChatBaseComponent, mc_ChatMessageType, UUID.class);
} else {
mc_PacketPlayOutChat_new = mc_PacketPlayOutChat.getConstructor(mc_IChatBaseComponent);
}
} catch (Throwable ex) {
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
enabled = false;
}
}
}
public ChatMessage replaceAll(String toReplace, String replaceWith) {
for (JsonObject object : textList) {
String text = object.get("text").getAsString()
.replaceAll(toReplace, replaceWith);
object.remove("text");
object.addProperty("text", text);
}
return this;
}
}

View File

@ -50,7 +50,6 @@ public enum ColorCode {
ColorCode color = var0[i];
BY_CHAR.put(color.code, color);
}
}
public static ColorCode getByChar(char code) {
@ -68,4 +67,4 @@ public enum ColorCode {
public boolean isColor() {
return this.isColor;
}
}
}

View File

@ -3,7 +3,7 @@ package com.songoda.core.chat;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.utils.ColorUtils;
import java.awt.*;
import java.awt.Color;
public class ColorContainer {
@ -40,4 +40,4 @@ public class ColorContainer {
Integer.valueOf(hexCode.substring(4, 6), 16));
return ColorUtils.fromRGB(jColor.getRed(), jColor.getGreen(), jColor.getBlue());
}
}
}

View File

@ -10,11 +10,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.command.TabCompleter;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

View File

@ -1,120 +1,119 @@
package com.songoda.core.commands;
import com.songoda.core.chat.ChatMessage;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class MainCommand extends AbstractCommand {
String header = null;
String description;
boolean sortHelp = false;
final String command;
final Plugin plugin;
protected final SimpleNestedCommand nestedCommands;
public MainCommand(Plugin plugin, String command) {
super(CommandType.CONSOLE_OK, command);
this.command = command;
this.plugin = plugin;
this.description = "Shows the command help page for /" + command;
this.nestedCommands = new SimpleNestedCommand(this);
}
public MainCommand setHeader(String header) {
this.header = header;
return this;
}
public MainCommand setDescription(String description) {
this.description = description;
return this;
}
public MainCommand setSortHelp(boolean sortHelp) {
this.sortHelp = sortHelp;
return this;
}
public MainCommand addSubCommand(AbstractCommand command) {
nestedCommands.addSubCommand(command);
return this;
}
public MainCommand addSubCommands(AbstractCommand... commands) {
nestedCommands.addSubCommands(commands);
return this;
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
sender.sendMessage("");
if (header != null) {
sender.sendMessage(header);
} else {
new ChatMessage().fromText(String.format("#ff8080&l%s &8» &7Version %s Created with <3 by #ec4e74&l&oS#fa5b65&l&oo#ff6c55&l&on#ff7f44&l&og#ff9432&l&oo#ffaa1e&l&od#f4c009&l&oa",
plugin.getDescription().getName(), plugin.getDescription().getVersion()), sender instanceof ConsoleCommandSender)
.sendTo(sender);
}
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + "/songoda" + ChatColor.GRAY + " - Opens the Songoda plugin GUI");
sender.sendMessage("");
if (nestedCommands != null) {
List<String> commands = nestedCommands.children.values().stream().distinct().map(c -> c.getCommands().get(0)).collect(Collectors.toList());
if (sortHelp) {
Collections.sort(commands);
}
boolean isPlayer = sender instanceof Player;
// todo? pagation if commands.size is too large? (player-only)
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + getSyntax() + ChatColor.GRAY + " - " + getDescription());
for (String cmdStr : commands) {
final AbstractCommand cmd = nestedCommands.children.get(cmdStr);
if (cmd == null) continue;
if (!isPlayer) {
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + cmd.getSyntax() + ChatColor.GRAY + " - " + cmd.getDescription());
} else if (cmd.getPermissionNode() == null || sender.hasPermission(cmd.getPermissionNode())) {
ChatMessage chatMessage = new ChatMessage();
final String c = "/" + command + " ";
chatMessage.addMessage(ChatColor.DARK_GRAY + "- ")
.addPromptCommand(ChatColor.YELLOW + c + cmd.getSyntax(), ChatColor.YELLOW + c + cmdStr, c + cmdStr)
.addMessage(ChatColor.GRAY + " - " + cmd.getDescription());
chatMessage.sendTo((Player) sender);
}
}
}
sender.sendMessage("");
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
// don't need to worry about tab for a root command - handled by the manager
return null;
}
@Override
public String getPermissionNode() {
// permissions for a root command should be handled in the plugin.yml
return null;
}
@Override
public String getSyntax() {
return "/" + command;
}
@Override
public String getDescription() {
return description;
}
}
package com.songoda.core.commands;
import com.songoda.core.chat.ChatMessage;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class MainCommand extends AbstractCommand {
String header = null;
String description;
boolean sortHelp = false;
final String command;
final Plugin plugin;
protected final SimpleNestedCommand nestedCommands;
public MainCommand(Plugin plugin, String command) {
super(CommandType.CONSOLE_OK, command);
this.command = command;
this.plugin = plugin;
this.description = "Shows the command help page for /" + command;
this.nestedCommands = new SimpleNestedCommand(this);
}
public MainCommand setHeader(String header) {
this.header = header;
return this;
}
public MainCommand setDescription(String description) {
this.description = description;
return this;
}
public MainCommand setSortHelp(boolean sortHelp) {
this.sortHelp = sortHelp;
return this;
}
public MainCommand addSubCommand(AbstractCommand command) {
nestedCommands.addSubCommand(command);
return this;
}
public MainCommand addSubCommands(AbstractCommand... commands) {
nestedCommands.addSubCommands(commands);
return this;
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
sender.sendMessage("");
if (header != null) {
sender.sendMessage(header);
} else {
new ChatMessage().fromText(String.format("#ff8080&l%s &8» &7Version %s Created with <3 by #ec4e74&l&oS#fa5b65&l&oo#ff6c55&l&on#ff7f44&l&og#ff9432&l&oo#ffaa1e&l&od#f4c009&l&oa",
plugin.getDescription().getName(), plugin.getDescription().getVersion()), sender instanceof ConsoleCommandSender)
.sendTo(sender);
}
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + "/songoda" + ChatColor.GRAY + " - Opens the Songoda plugin GUI");
sender.sendMessage("");
if (nestedCommands != null) {
List<String> commands = nestedCommands.children.values().stream().distinct().map(c -> c.getCommands().get(0)).collect(Collectors.toList());
if (sortHelp) {
Collections.sort(commands);
}
boolean isPlayer = sender instanceof Player;
// todo? pagation if commands.size is too large? (player-only)
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + getSyntax() + ChatColor.GRAY + " - " + getDescription());
for (String cmdStr : commands) {
final AbstractCommand cmd = nestedCommands.children.get(cmdStr);
if (cmd == null) continue;
if (!isPlayer) {
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + cmd.getSyntax() + ChatColor.GRAY + " - " + cmd.getDescription());
} else if (cmd.getPermissionNode() == null || sender.hasPermission(cmd.getPermissionNode())) {
ChatMessage chatMessage = new ChatMessage();
final String c = "/" + command + " ";
chatMessage.addMessage(ChatColor.DARK_GRAY + "- ")
.addPromptCommand(ChatColor.YELLOW + c + cmd.getSyntax(), ChatColor.YELLOW + c + cmdStr, c + cmdStr)
.addMessage(ChatColor.GRAY + " - " + cmd.getDescription());
chatMessage.sendTo((Player) sender);
}
}
}
sender.sendMessage("");
return ReturnType.SUCCESS;
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
// don't need to worry about tab for a root command - handled by the manager
return null;
}
@Override
public String getPermissionNode() {
// permissions for a root command should be handled in the plugin.yml
return null;
}
@Override
public String getSyntax() {
return "/" + command;
}
@Override
public String getDescription() {
return description;
}
}

View File

@ -1,193 +1,194 @@
package com.songoda.core.commands;
import com.songoda.core.compatibility.EntityNamespace;
import org.bukkit.Location;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SelectorArguments {
static Pattern selectorPattern = Pattern.compile("^(@[apers])(\\[(.*?)\\])?$");
static Pattern selectorRangePattern = Pattern.compile("^([0-9]{1,9}(\\.[0-9]{1,9})?)?(\\.\\.)?([0-9]{1,9}(\\.[0-9]{1,9})?)?$");
/**
* Parse a command selector using Minecraft's selector format. <br>
* Currently only supports distance and entity type
*
* @param sender CommandBlock or Player running the command
* @param argument argument with the selector to parse
* @return SelectorArguments Object for grabbing the list of entities, or null if the selector is invalid
*/
@Nullable
public static SelectorArguments parseSelector(@NotNull CommandSender sender, @NotNull String argument) {
if (!(sender instanceof BlockCommandSender || sender instanceof Player)) {
return null;
}
Matcher m = selectorPattern.matcher(argument);
if (!m.find()) {
return null;
}
SelectorType type = SelectorType.getType(m.group(1));
if (type == null) {
return null;
}
SelectorArguments selector = new SelectorArguments(sender, type);
if (m.group(3) != null) {
selector.parseArguments(m.group(3));
}
return selector;
}
protected final CommandSender sender;
protected final SelectorType selector;
protected double rangeMin = 0, rangeMax = Double.POSITIVE_INFINITY;
protected EntityType entityType;
public SelectorArguments(CommandSender sender, SelectorType type) {
this.sender = sender;
this.selector = type;
}
private void parseArguments(String selectorArgs) {
String[] args = selectorArgs.split(",");
for (String s : args) {
if (s.contains("=")) {
String[] v = s.split("=");
if (v[0].equals("distance")) {
// 10 = d == 10
// 10..12 = d > 10 && d <= 12
// 5.. = d >= 5
// ..5 = d <= 15
Matcher distGroup = selectorRangePattern.matcher(v[1]);
if (distGroup.find()) {
if (distGroup.group(1) != null) {
rangeMin = Double.parseDouble(distGroup.group(1));
}
if (distGroup.group(3) == null) {
rangeMax = rangeMin;
} else if (distGroup.group(4) != null) {
rangeMax = Double.parseDouble(distGroup.group(4));
}
}
} else if (v[0].equals("type")) {
entityType = EntityNamespace.minecraftToBukkit(v[1]);
}
// more arguments can be parsed here (TODO)
}
}
/*
advancements Advancement earned by entity.
distance Distance to entity.
dx Entities between x and x + dx.
dy Entities between y and y + dy.
dz Entities between z and z + dz.
gamemode Players with gamemode. It can be one of the following values: adventure, creative, spectator, survival, !adventure, !creative, !spectator, !survival
level Experience level. It must be an integer value that is 0 or greater.
limit Maximum number of entities to target. It must be an integer value that is 1 or greater.
name Entity name.
nbt NBT tag.
scores Score.
sort Sort the entities. It must be one of the following values: arbitrary, furthest, nearest, random
tag Scoreboard tag.
team Entities on team.
type Entity type (target must be the specified entity type - https://www.digminecraft.com/lists/entity_list_pc.php ).
x Entity's x-coordinate position.
x_rotation Entity's x rotation (vertical rotation).
y Entity's y-coordinate position.
y_rotation Entity's y rotation (horizontal rotation).
z Entity's z-coordinate position.
target selector arguments are case-sensitive
@e[type=cow,limit=5]
*/
}
public Collection<Entity> getSelection() {
final Location location = sender instanceof Player ? ((Player) sender).getLocation() : ((BlockCommandSender) sender).getBlock().getLocation();
Collection<Entity> list = preSelect(location);
if (list.isEmpty()) {
return list;
}
List<Entity> list2 = filter(location, list);
if (list2.isEmpty()) {
return list2;
}
switch (selector) {
case PLAYER:
Collections.sort(list2, (o1, o2) -> (int) (o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location)));
return Arrays.asList(list2.get(0));
case RANDOM_PLAYER:
Collections.shuffle(list2);
return Arrays.asList(list2.get(0));
case ALL_PLAYER:
case ALL_ENTITIES:
case SELF:
return list2;
}
return list2;
}
protected Collection<Entity> preSelect(Location location) {
switch (selector) {
case PLAYER:
case RANDOM_PLAYER:
case ALL_PLAYER:
return rangeMax == Double.POSITIVE_INFINITY
? location.getWorld().getEntitiesByClasses(Player.class)
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2).stream()
.filter(e -> e instanceof Player).collect(Collectors.toSet());
case ALL_ENTITIES:
return rangeMax == Double.POSITIVE_INFINITY
? location.getWorld().getEntities()
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2);
case SELF:
return sender instanceof Entity ? Arrays.asList((Entity) sender) : Collections.EMPTY_LIST;
}
return Collections.EMPTY_LIST;
}
protected List<Entity> filter(Location location, Collection<Entity> list) {
Stream<Entity> stream = list.stream()
.filter(p -> rangeMin == 0 || p.getLocation().distance(location) > rangeMin)
.filter(e -> entityType == null || e.getType() == entityType);
return stream.collect(Collectors.toList());
}
public static enum SelectorType {
PLAYER, RANDOM_PLAYER, ALL_PLAYER, ALL_ENTITIES, SELF;
public static SelectorType getType(String str) {
if (str != null) {
switch (str.toLowerCase()) {
case "@p":
return PLAYER;
case "@r":
return RANDOM_PLAYER;
case "@a":
return ALL_PLAYER;
case "@e":
return ALL_ENTITIES;
case "@s":
return SELF;
}
}
return null;
}
}
}
package com.songoda.core.commands;
import com.songoda.core.compatibility.EntityNamespace;
import org.bukkit.Location;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SelectorArguments {
static Pattern selectorPattern = Pattern.compile("^(@[apers])(\\[(.*?)\\])?$");
static Pattern selectorRangePattern = Pattern.compile("^([0-9]{1,9}(\\.[0-9]{1,9})?)?(\\.\\.)?([0-9]{1,9}(\\.[0-9]{1,9})?)?$");
/**
* Parse a command selector using Minecraft's selector format. <br>
* Currently only supports distance and entity type
*
* @param sender CommandBlock or Player running the command
* @param argument argument with the selector to parse
*
* @return SelectorArguments Object for grabbing the list of entities, or null if the selector is invalid
*/
@Nullable
public static SelectorArguments parseSelector(@NotNull CommandSender sender, @NotNull String argument) {
if (!(sender instanceof BlockCommandSender || sender instanceof Player)) {
return null;
}
Matcher m = selectorPattern.matcher(argument);
if (!m.find()) {
return null;
}
SelectorType type = SelectorType.getType(m.group(1));
if (type == null) {
return null;
}
SelectorArguments selector = new SelectorArguments(sender, type);
if (m.group(3) != null) {
selector.parseArguments(m.group(3));
}
return selector;
}
protected final CommandSender sender;
protected final SelectorType selector;
protected double rangeMin = 0, rangeMax = Double.POSITIVE_INFINITY;
protected EntityType entityType;
public SelectorArguments(CommandSender sender, SelectorType type) {
this.sender = sender;
this.selector = type;
}
private void parseArguments(String selectorArgs) {
String[] args = selectorArgs.split(",");
for (String s : args) {
if (s.contains("=")) {
String[] v = s.split("=");
if (v[0].equals("distance")) {
// 10 = d == 10
// 10..12 = d > 10 && d <= 12
// 5.. = d >= 5
// ..5 = d <= 15
Matcher distGroup = selectorRangePattern.matcher(v[1]);
if (distGroup.find()) {
if (distGroup.group(1) != null) {
rangeMin = Double.parseDouble(distGroup.group(1));
}
if (distGroup.group(3) == null) {
rangeMax = rangeMin;
} else if (distGroup.group(4) != null) {
rangeMax = Double.parseDouble(distGroup.group(4));
}
}
} else if (v[0].equals("type")) {
entityType = EntityNamespace.minecraftToBukkit(v[1]);
}
// more arguments can be parsed here (TODO)
}
}
/*
advancements Advancement earned by entity.
distance Distance to entity.
dx Entities between x and x + dx.
dy Entities between y and y + dy.
dz Entities between z and z + dz.
gamemode Players with gamemode. It can be one of the following values: adventure, creative, spectator, survival, !adventure, !creative, !spectator, !survival
level Experience level. It must be an integer value that is 0 or greater.
limit Maximum number of entities to target. It must be an integer value that is 1 or greater.
name Entity name.
nbt NBT tag.
scores Score.
sort Sort the entities. It must be one of the following values: arbitrary, furthest, nearest, random
tag Scoreboard tag.
team Entities on team.
type Entity type (target must be the specified entity type - https://www.digminecraft.com/lists/entity_list_pc.php ).
x Entity's x-coordinate position.
x_rotation Entity's x rotation (vertical rotation).
y Entity's y-coordinate position.
y_rotation Entity's y rotation (horizontal rotation).
z Entity's z-coordinate position.
target selector arguments are case-sensitive
@e[type=cow,limit=5]
*/
}
public Collection<Entity> getSelection() {
final Location location = sender instanceof Player ? ((Player) sender).getLocation() : ((BlockCommandSender) sender).getBlock().getLocation();
Collection<Entity> list = preSelect(location);
if (list.isEmpty()) {
return list;
}
List<Entity> list2 = filter(location, list);
if (list2.isEmpty()) {
return list2;
}
switch (selector) {
case PLAYER:
Collections.sort(list2, (o1, o2) -> (int) (o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location)));
return Arrays.asList(list2.get(0));
case RANDOM_PLAYER:
Collections.shuffle(list2);
return Arrays.asList(list2.get(0));
case ALL_PLAYER:
case ALL_ENTITIES:
case SELF:
return list2;
}
return list2;
}
protected Collection<Entity> preSelect(Location location) {
switch (selector) {
case PLAYER:
case RANDOM_PLAYER:
case ALL_PLAYER:
return rangeMax == Double.POSITIVE_INFINITY
? location.getWorld().getEntitiesByClasses(Player.class)
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2).stream()
.filter(e -> e instanceof Player).collect(Collectors.toSet());
case ALL_ENTITIES:
return rangeMax == Double.POSITIVE_INFINITY
? location.getWorld().getEntities()
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2);
case SELF:
return sender instanceof Entity ? Arrays.asList((Entity) sender) : Collections.EMPTY_LIST;
}
return Collections.EMPTY_LIST;
}
protected List<Entity> filter(Location location, Collection<Entity> list) {
Stream<Entity> stream = list.stream()
.filter(p -> rangeMin == 0 || p.getLocation().distance(location) > rangeMin)
.filter(e -> entityType == null || e.getType() == entityType);
return stream.collect(Collectors.toList());
}
public static enum SelectorType {
PLAYER, RANDOM_PLAYER, ALL_PLAYER, ALL_ENTITIES, SELF;
public static SelectorType getType(String str) {
if (str != null) {
switch (str.toLowerCase()) {
case "@p":
return PLAYER;
case "@r":
return RANDOM_PLAYER;
case "@a":
return ALL_PLAYER;
case "@e":
return ALL_ENTITIES;
case "@s":
return SELF;
}
}
return null;
}
}
}

View File

@ -1,25 +1,24 @@
package com.songoda.core.commands;
import java.util.LinkedHashMap;
import java.util.stream.Stream;
public class SimpleNestedCommand {
final AbstractCommand parent;
final LinkedHashMap<String, AbstractCommand> children = new LinkedHashMap<>();
protected SimpleNestedCommand(AbstractCommand parent) {
this.parent = parent;
}
public SimpleNestedCommand addSubCommand(AbstractCommand command) {
command.getCommands().forEach(cmd -> children.put(cmd.toLowerCase(), command));
return this;
}
public SimpleNestedCommand addSubCommands(AbstractCommand... commands) {
Stream.of(commands).forEach(command -> command.getCommands().forEach(cmd -> children.put(cmd.toLowerCase(), command)));
return this;
}
}
package com.songoda.core.commands;
import java.util.LinkedHashMap;
import java.util.stream.Stream;
public class SimpleNestedCommand {
final AbstractCommand parent;
final LinkedHashMap<String, AbstractCommand> children = new LinkedHashMap<>();
protected SimpleNestedCommand(AbstractCommand parent) {
this.parent = parent;
}
public SimpleNestedCommand addSubCommand(AbstractCommand command) {
command.getCommands().forEach(cmd -> children.put(cmd.toLowerCase(), command));
return this;
}
public SimpleNestedCommand addSubCommands(AbstractCommand... commands) {
Stream.of(commands).forEach(command -> command.getCommands().forEach(cmd -> children.put(cmd.toLowerCase(), command)));
return this;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +1,93 @@
package com.songoda.core.configuration;
import java.util.List;
public class ConfigFormattingRules {
int spacesBetweenMainCategories;
int spacesBetweenValues;
CommentStyle rootCommentStyle = CommentStyle.BLOCKSPACED;
CommentStyle mainCategoryCommentStyle = CommentStyle.SPACED;
public static enum CommentStyle {
/**
* # Comment
*/
SIMPLE(false, false, " ", ""),
/**
* # <br />
* # Comment <br />
* # <br />
*/
SPACED(false, true, " ", ""),
/**
* ########### <br />
* # Comment # <br />
* ########### <br />
*/
BLOCKED(true, false, " ", " "),
/**
* ############# <br />
* #|¯¯¯¯¯¯¯¯¯|# <br />
* #| Comment |# <br />
* #|_________|# <br />
* ############# <br />
*/
BLOCKSPACED(true, true, "|\u00AF", '\u00AF', "\u00AF|", "| ", " |", "|_", '_', "_|");
final boolean drawBorder, drawSpace;
final String commentPrefix, spacePrefixTop, spacePrefixBottom;
final String commentSuffix, spaceSuffixTop, spaceSuffixBottom;
final char spaceCharTop, spaceCharBottom;
private CommentStyle(boolean drawBorder, boolean drawSpace,
String spacePrefixTop, char spaceCharTop, String spaceSuffixTop,
String commentPrefix, String commentSuffix,
String spacePrefixBottom, char spaceCharBottom, String spaceSuffixBottom) {
this.drawBorder = drawBorder;
this.drawSpace = drawSpace;
this.commentPrefix = commentPrefix;
this.spacePrefixTop = spacePrefixTop;
this.spacePrefixBottom = spacePrefixBottom;
this.commentSuffix = commentSuffix;
this.spaceSuffixTop = spaceSuffixTop;
this.spaceSuffixBottom = spaceSuffixBottom;
this.spaceCharTop = spaceCharTop;
this.spaceCharBottom = spaceCharBottom;
}
private CommentStyle(boolean drawBorder, boolean drawSpace, String commentPrefix, String commentSuffix) {
this.drawBorder = drawBorder;
this.drawSpace = drawSpace;
this.commentPrefix = commentPrefix;
this.commentSuffix = commentSuffix;
this.spacePrefixTop = this.spacePrefixBottom = "";
this.spaceCharTop = this.spaceCharBottom = ' ';
this.spaceSuffixTop = this.spaceSuffixBottom = "";
}
}
public static CommentStyle parseStyle(List<String> lines) {
if (lines == null || lines.size() <= 2) {
return CommentStyle.SIMPLE;
} else if (lines.size() > 2 && lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
return CommentStyle.SPACED;
}
boolean hasBorders = lines.size() > 2 && lines.get(0).trim().matches("^##+$") && lines.get(lines.size() - 1).trim().matches("^##+$");
if (!hasBorders) {
// default return
return CommentStyle.SIMPLE;
}
// now need to figure out if this is blocked or not
if (lines.size() > 4 && lines.get(1).trim().matches(("^#"
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))
&& lines.get(1).trim().matches(("^#"
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))) {
return CommentStyle.BLOCKSPACED;
}
return CommentStyle.BLOCKED;
}
}
package com.songoda.core.configuration;
import java.util.List;
public class ConfigFormattingRules {
int spacesBetweenMainCategories;
int spacesBetweenValues;
CommentStyle rootCommentStyle = CommentStyle.BLOCKSPACED;
CommentStyle mainCategoryCommentStyle = CommentStyle.SPACED;
public static enum CommentStyle {
/**
* # Comment
*/
SIMPLE(false, false, " ", ""),
/**
* # <br />
* # Comment <br />
* # <br />
*/
SPACED(false, true, " ", ""),
/**
* ########### <br />
* # Comment # <br />
* ########### <br />
*/
BLOCKED(true, false, " ", " "),
/**
* ############# <br />
* #|¯¯¯¯¯¯¯¯¯|# <br />
* #| Comment |# <br />
* #|_________|# <br />
* ############# <br />
*/
BLOCKSPACED(true, true, "|\u00AF", '\u00AF', "\u00AF|", "| ", " |", "|_", '_', "_|");
final boolean drawBorder, drawSpace;
final String commentPrefix, spacePrefixTop, spacePrefixBottom;
final String commentSuffix, spaceSuffixTop, spaceSuffixBottom;
final char spaceCharTop, spaceCharBottom;
private CommentStyle(boolean drawBorder, boolean drawSpace,
String spacePrefixTop, char spaceCharTop, String spaceSuffixTop,
String commentPrefix, String commentSuffix,
String spacePrefixBottom, char spaceCharBottom, String spaceSuffixBottom) {
this.drawBorder = drawBorder;
this.drawSpace = drawSpace;
this.commentPrefix = commentPrefix;
this.spacePrefixTop = spacePrefixTop;
this.spacePrefixBottom = spacePrefixBottom;
this.commentSuffix = commentSuffix;
this.spaceSuffixTop = spaceSuffixTop;
this.spaceSuffixBottom = spaceSuffixBottom;
this.spaceCharTop = spaceCharTop;
this.spaceCharBottom = spaceCharBottom;
}
private CommentStyle(boolean drawBorder, boolean drawSpace, String commentPrefix, String commentSuffix) {
this.drawBorder = drawBorder;
this.drawSpace = drawSpace;
this.commentPrefix = commentPrefix;
this.commentSuffix = commentSuffix;
this.spacePrefixTop = this.spacePrefixBottom = "";
this.spaceCharTop = this.spaceCharBottom = ' ';
this.spaceSuffixTop = this.spaceSuffixBottom = "";
}
}
public static CommentStyle parseStyle(List<String> lines) {
if (lines == null || lines.size() <= 2) {
return CommentStyle.SIMPLE;
} else if (lines.size() > 2 && lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
return CommentStyle.SPACED;
}
boolean hasBorders = lines.size() > 2 && lines.get(0).trim().matches("^##+$") && lines.get(lines.size() - 1).trim().matches("^##+$");
if (!hasBorders) {
// default return
return CommentStyle.SIMPLE;
}
// now need to figure out if this is blocked or not
if (lines.size() > 4 && lines.get(1).trim().matches(("^#"
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))
&& lines.get(1).trim().matches(("^#"
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))) {
return CommentStyle.BLOCKSPACED;
}
return CommentStyle.BLOCKED;
}
}

View File

@ -129,5 +129,4 @@ public class ConfigSetting {
return mat != null ? mat : def;
}
}

View File

@ -1,265 +1,270 @@
package com.songoda.core.configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Function;
import java.util.logging.Level;
/**
* Used to easily store a set of one data value
*
* @param <T> DataObject class that is used to store the data
* @author jascotty2
* @since 2019-09-06
*/
public class SimpleDataStore<T extends DataStoreObject> {
protected final Plugin plugin;
protected final String filename, dirName;
private final Function<ConfigurationSection, T> getFromSection;
protected final HashMap<Object, T> data = new HashMap();
private File file;
private final Object lock = new Object();
SaveTask saveTask;
Timer autosaveTimer;
/**
* time in seconds to start a save after a change is made
*/
int autosaveInterval = 60;
public SimpleDataStore(@NotNull Plugin plugin, @NotNull String filename, @NotNull Function<ConfigurationSection, T> loadFunction) {
this.plugin = plugin;
this.filename = filename;
dirName = null;
this.getFromSection = loadFunction;
}
public SimpleDataStore(@NotNull Plugin plugin, @Nullable String directory, @NotNull String filename, @NotNull Function<ConfigurationSection, T> loadFunction) {
this.plugin = plugin;
this.filename = filename;
this.dirName = directory;
this.getFromSection = loadFunction;
}
@NotNull
public File getFile() {
if (file == null) {
if (dirName != null) {
this.file = new File(plugin.getDataFolder() + dirName, filename != null ? filename : "data.yml");
} else {
this.file = new File(plugin.getDataFolder(), filename != null ? filename : "data.yml");
}
}
return file;
}
/**
* @return a directly-modifiable instance of the data mapping for this
* storage
*/
public Map<Object, T> getData() {
return data;
}
/**
* Returns the value to which the specified key is mapped, or {@code null}
* if this map contains no mapping for the key.
*
* @param key key whose mapping is to be retrieved from this storage
* @return the value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
*/
@Nullable
public T get(Object key) {
return data.get(key);
}
/**
* Removes the mapping for the specified key from this storage if present.
*
* @param key key whose mapping is to be removed from this storage
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
*/
@Nullable
public T remove(@NotNull Object key) {
T temp;
synchronized (lock) {
temp = data.remove(key);
}
save();
return temp;
}
/**
* Removes the mapping for the specified key from this storage if present.
*
* @param value value whose mapping is to be removed from this storage
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
*/
@Nullable
public T remove(@NotNull T value) {
if (value == null) {
return null;
}
T temp;
synchronized (lock) {
temp = data.remove(value.getKey());
}
save();
return temp;
}
/**
* Adds the specified value in this storage. If the map previously contained
* a mapping for the key, the old value is replaced.
*
* @param value value to be added
* @return the previous value associated with <tt>value.getKey()</tt>, or
* <tt>null</tt> if there was no mapping for <tt>value.getKey()</tt>.
*/
@Nullable
public T add(@NotNull T value) {
if (value == null) {
return null;
}
T temp;
synchronized (lock) {
temp = data.put(value.getKey(), value);
}
save();
return temp;
}
/**
* Adds the specified value in this storage. If the map previously contained
* a mapping for the key, the old value is replaced.
*
* @param value values to be added
*/
@Nullable
public void addAll(@NotNull T[] value) {
if (value == null) {
return;
}
synchronized (lock) {
for (int i = 0; i < value.length; ++i) {
if (value[i] != null) {
data.put(value[i].getKey(), value[i]);
}
}
}
save();
}
/**
* Adds the specified value in this storage. If the map previously contained
* a mapping for the key, the old value is replaced.
*
* @param value values to be added
*/
@Nullable
public void addAll(@NotNull Collection<T> value) {
if (value == null) {
return;
}
synchronized (lock) {
for (T v : value) {
if (v != null) {
data.put(v.getKey(), v);
}
}
}
save();
}
/**
* Load data from the associated file
*/
public void load() {
if (!getFile().exists()) {
return;
}
try {
YamlConfiguration f = new YamlConfiguration();
f.options().pathSeparator('\0');
f.load(file);
synchronized (lock) {
data.clear();
f.getValues(false).entrySet().stream()
.filter(d -> d.getValue() instanceof ConfigurationSection)
.map(Map.Entry::getValue)
.map(v -> getFromSection.apply((ConfigurationSection) v))
.forEach(v -> data.put(v.getKey(), v));
}
} catch (IOException | InvalidConfigurationException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to load data from " + file.getName(), ex);
}
}
/**
* Optionally save this storage's data to file if there have been changes
* made
*/
public void saveChanges() {
if (saveTask != null || data.values().stream().anyMatch(v -> v.hasChanged())) {
flushSave();
}
}
/**
* Save this file data. This saves later asynchronously.
*/
public void save() {
// save async even if no plugin or if plugin disabled
if (saveTask == null) {
autosaveTimer = new Timer((plugin != null ? plugin.getName() + "-DataStoreSave-" : "DataStoreSave-") + getFile().getName());
autosaveTimer.schedule(saveTask = new SaveTask(), autosaveInterval * 1000L);
}
}
/**
* Force a new save of this storage's data
*/
public void flushSave() {
if (saveTask != null) {
//Close Threads
saveTask.cancel();
autosaveTimer.cancel();
saveTask = null;
autosaveTimer = null;
}
YamlConfiguration f = new YamlConfiguration();
synchronized (lock) {
data.values().stream().forEach(e -> e.saveToSection(f.createSection(e.getConfigKey())));
}
try {
f.save(getFile());
data.values().stream().forEach(e -> e.setChanged(false));
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to save data to " + file.getName(), ex);
}
}
class SaveTask extends TimerTask {
@Override
public void run() {
flushSave();
}
}
}
package com.songoda.core.configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Function;
import java.util.logging.Level;
/**
* Used to easily store a set of one data value
*
* @param <T> DataObject class that is used to store the data
*
* @author jascotty2
* @since 2019-09-06
*/
public class SimpleDataStore<T extends DataStoreObject> {
protected final Plugin plugin;
protected final String filename, dirName;
private final Function<ConfigurationSection, T> getFromSection;
protected final HashMap<Object, T> data = new HashMap();
private File file;
private final Object lock = new Object();
SaveTask saveTask;
Timer autosaveTimer;
/**
* time in seconds to start a save after a change is made
*/
int autosaveInterval = 60;
public SimpleDataStore(@NotNull Plugin plugin, @NotNull String filename, @NotNull Function<ConfigurationSection, T> loadFunction) {
this.plugin = plugin;
this.filename = filename;
dirName = null;
this.getFromSection = loadFunction;
}
public SimpleDataStore(@NotNull Plugin plugin, @Nullable String directory, @NotNull String filename, @NotNull Function<ConfigurationSection, T> loadFunction) {
this.plugin = plugin;
this.filename = filename;
this.dirName = directory;
this.getFromSection = loadFunction;
}
@NotNull
public File getFile() {
if (file == null) {
if (dirName != null) {
this.file = new File(plugin.getDataFolder() + dirName, filename != null ? filename : "data.yml");
} else {
this.file = new File(plugin.getDataFolder(), filename != null ? filename : "data.yml");
}
}
return file;
}
/**
* @return a directly-modifiable instance of the data mapping for this
* storage
*/
public Map<Object, T> getData() {
return data;
}
/**
* Returns the value to which the specified key is mapped, or {@code null}
* if this map contains no mapping for the key.
*
* @param key key whose mapping is to be retrieved from this storage
*
* @return the value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
*/
@Nullable
public T get(Object key) {
return data.get(key);
}
/**
* Removes the mapping for the specified key from this storage if present.
*
* @param key key whose mapping is to be removed from this storage
*
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
*/
@Nullable
public T remove(@NotNull Object key) {
T temp;
synchronized (lock) {
temp = data.remove(key);
}
save();
return temp;
}
/**
* Removes the mapping for the specified key from this storage if present.
*
* @param value value whose mapping is to be removed from this storage
*
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
*/
@Nullable
public T remove(@NotNull T value) {
if (value == null) {
return null;
}
T temp;
synchronized (lock) {
temp = data.remove(value.getKey());
}
save();
return temp;
}
/**
* Adds the specified value in this storage. If the map previously contained
* a mapping for the key, the old value is replaced.
*
* @param value value to be added
*
* @return the previous value associated with <tt>value.getKey()</tt>, or
* <tt>null</tt> if there was no mapping for <tt>value.getKey()</tt>.
*/
@Nullable
public T add(@NotNull T value) {
if (value == null) {
return null;
}
T temp;
synchronized (lock) {
temp = data.put(value.getKey(), value);
}
save();
return temp;
}
/**
* Adds the specified value in this storage. If the map previously contained
* a mapping for the key, the old value is replaced.
*
* @param value values to be added
*/
@Nullable
public void addAll(@NotNull T[] value) {
if (value == null) {
return;
}
synchronized (lock) {
for (int i = 0; i < value.length; ++i) {
if (value[i] != null) {
data.put(value[i].getKey(), value[i]);
}
}
}
save();
}
/**
* Adds the specified value in this storage. If the map previously contained
* a mapping for the key, the old value is replaced.
*
* @param value values to be added
*/
@Nullable
public void addAll(@NotNull Collection<T> value) {
if (value == null) {
return;
}
synchronized (lock) {
for (T v : value) {
if (v != null) {
data.put(v.getKey(), v);
}
}
}
save();
}
/**
* Load data from the associated file
*/
public void load() {
if (!getFile().exists()) {
return;
}
try {
YamlConfiguration f = new YamlConfiguration();
f.options().pathSeparator('\0');
f.load(file);
synchronized (lock) {
data.clear();
f.getValues(false).entrySet().stream()
.filter(d -> d.getValue() instanceof ConfigurationSection)
.map(Map.Entry::getValue)
.map(v -> getFromSection.apply((ConfigurationSection) v))
.forEach(v -> data.put(v.getKey(), v));
}
} catch (IOException | InvalidConfigurationException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to load data from " + file.getName(), ex);
}
}
/**
* Optionally save this storage's data to file if there have been changes
* made
*/
public void saveChanges() {
if (saveTask != null || data.values().stream().anyMatch(v -> v.hasChanged())) {
flushSave();
}
}
/**
* Save this file data. This saves later asynchronously.
*/
public void save() {
// save async even if no plugin or if plugin disabled
if (saveTask == null) {
autosaveTimer = new Timer((plugin != null ? plugin.getName() + "-DataStoreSave-" : "DataStoreSave-") + getFile().getName());
autosaveTimer.schedule(saveTask = new SaveTask(), autosaveInterval * 1000L);
}
}
/**
* Force a new save of this storage's data
*/
public void flushSave() {
if (saveTask != null) {
//Close Threads
saveTask.cancel();
autosaveTimer.cancel();
saveTask = null;
autosaveTimer = null;
}
YamlConfiguration f = new YamlConfiguration();
synchronized (lock) {
data.values().stream().forEach(e -> e.saveToSection(f.createSection(e.getConfigKey())));
}
try {
f.save(getFile());
data.values().stream().forEach(e -> e.setChanged(false));
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to save data to " + file.getName(), ex);
}
}
class SaveTask extends TimerTask {
@Override
public void run() {
flushSave();
}
}
}

View File

@ -1,308 +1,306 @@
package com.songoda.core.configuration.editor;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import com.songoda.core.input.ChatPrompt;
import com.songoda.core.utils.ItemUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
/**
* Edit a configuration file for a specific plugin
*
* @author jascotty2
* @since 2019-08-31
*/
public class ConfigEditorGui extends SimplePagedGui {
final JavaPlugin plugin;
final String file;
final MemoryConfiguration config;
final ConfigurationSection node;
final Player player;
Method configSection_getCommentString = null;
boolean edits = false;
List<String> sections = new ArrayList();
List<String> settings = new ArrayList();
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config) {
this(player, plugin, parent, file, config, config);
}
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config, ConfigurationSection node) {
super(parent);
this.player = player;
this.plugin = plugin;
this.file = file;
this.config = config;
this.node = node;
this.blankItem = GuiUtils.getBorderItem(CompatibleMaterial.LIGHT_GRAY_STAINED_GLASS_PANE);
if (!(parent instanceof ConfigEditorGui)) {
setOnClose((gui) -> save());
} else {
setOnClose((gui) -> ((ConfigEditorGui) parent).edits |= edits);
}
// if we have a ConfigSection, we can also grab comments
try {
configSection_getCommentString = node.getClass().getDeclaredMethod("getCommentString", String.class);
} catch (Exception ex) {
}
// decorate header
this.setTitle(ChatColor.DARK_BLUE + file);
this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(CompatibleMaterial.GRAY_STAINED_GLASS_PANE.getItem());
final String path = node.getCurrentPath();
this.setItem(4, configItem(CompatibleMaterial.FILLED_MAP, !path.isEmpty() ? path : file, config, !path.isEmpty() ? path : null, ChatColor.BLACK.toString()));
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// compile list of settings
for (String key : node.getKeys(false)) {
if (node.isConfigurationSection(key)) {
sections.add(key);
} else {
settings.add(key);
}
}
// next we need to display the config settings
int index = 9;
for (final String sectionKey : sections) {
setButton(index++, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + sectionKey, node, sectionKey, "Click to open this section"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(player, plugin, this, file, config, node.getConfigurationSection(sectionKey))));
}
// now display individual settings
for (final String settingKey : settings) {
final Object val = node.get(settingKey);
if (val == null) continue;
else if (val instanceof Boolean) {
// toggle switch
setButton(index, configItem(CompatibleMaterial.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Boolean) val), "Click to toggle this setting"),
(event) -> this.toggle(event.slot, settingKey));
if ((Boolean) val) {
highlightItem(index);
}
} else if (isNumber(val)) {
// number dial
this.setButton(index, configItem(CompatibleMaterial.CLOCK, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Number) val), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new number value for " + settingKey + ":", response -> {
if (!setNumber(event.slot, settingKey, response.getMessage().trim())) {
event.player.sendMessage(ChatColor.RED + "Error: \"" + response.getMessage().trim() + "\" is not a number!");
}
}).setOnClose(() -> event.manager.showGUI(event.player, this))
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
} else if (isMaterial(val)) {
// changing a block
// isMaterial is more of a guess, to be honest.
setButton(index, configItem(CompatibleMaterial.STONE, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> {
SimplePagedGui paged = new SimplePagedGui(this);
paged.setTitle(ChatColor.BLUE + settingKey);
paged.setHeaderBackItem(headerBackItem).setFooterBackItem(footerBackItem).setDefaultItem(blankItem);
paged.setItem(4, configItem(CompatibleMaterial.FILLED_MAP, settingKey, node, settingKey, "Choose an item to change this value to"));
int i = 9;
for (CompatibleMaterial mat : CompatibleMaterial.getAllValidItemMaterials()) {
paged.setButton(i++, GuiUtils.createButtonItem(mat, mat.name()), ClickType.LEFT, (matEvent) -> {
setMaterial(event.slot, settingKey, matEvent.clickedItem);
matEvent.player.closeInventory();
});
}
event.manager.showGUI(event.player, paged);
});
} else if (val instanceof String) {
// changing a "string" value (or change to a feather for writing quill)
setButton(index, configItem(CompatibleMaterial.STRING, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new value for " + settingKey + ":", response -> {
node.set(settingKey, response.getMessage().trim());
updateValue(event.slot, settingKey);
}).setOnClose(() -> event.manager.showGUI(event.player, this))
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
} else if (val instanceof List) {
setButton(index, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List) val).size()), "Click to edit this setting"),
(event) -> {
event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> {
if (((ConfigEditorListEditorGui) gui.gui).saveChanges) {
setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).values);
}
}));
});
} else {
// idk. should we display uneditable values?
}
++index;
}
}
public ConfigurationSection getCurrentNode() {
return node;
}
protected void updateValue(int clickCell, String path) {
ItemStack item = inventory.getItem(clickCell);
if (item == null || item == AIR) return;
ItemMeta meta = item.getItemMeta();
Object val = node.get(path);
if (meta != null && val != null) {
String valStr;
if (val instanceof List) {
valStr = String.format("(%d values)", ((List) val).size());
} else {
valStr = val.toString();
}
List<String> lore = meta.getLore();
if (lore == null || lore.isEmpty()) {
meta.setLore(Arrays.asList(valStr));
} else {
lore.set(0, valStr);
meta.setLore(lore);
}
item.setItemMeta(meta);
setItem(clickCell, item);
}
edits = true;
}
void toggle(int clickCell, String path) {
boolean val = !node.getBoolean(path);
node.set(path, val);
if (val) {
setItem(clickCell, ItemUtils.addGlow(inventory.getItem(clickCell)));
} else {
setItem(clickCell, ItemUtils.removeGlow(inventory.getItem(clickCell)));
}
updateValue(clickCell, path);
}
boolean setNumber(int clickCell, String path, String input) {
try {
if (node.isInt(path)) {
node.set(path, Integer.parseInt(input));
} else if (node.isDouble(path)) {
node.set(path, Double.parseDouble(input));
} else if (node.isLong(path)) {
node.set(path, Long.parseLong(input));
}
updateValue(clickCell, path);
} catch (NumberFormatException e) {
return false;
}
return true;
}
void setMaterial(int clickCell, String path, ItemStack item) {
CompatibleMaterial mat = CompatibleMaterial.getMaterial(item);
if (mat == null) {
node.set(path, CompatibleMaterial.STONE.name());
} else {
node.set(path, mat.name());
}
updateValue(clickCell, path);
}
void setList(int clickCell, String path, List<String> list) {
node.set(path, list);
updateValue(clickCell, path);
}
void save() {
if (!edits) {
return;
}
// could also check and call saveChanges()
if (config instanceof FileConfiguration) {
try {
((FileConfiguration) config).save(new File(plugin.getDataFolder(), file));
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to save config changes to " + file, ex);
return;
}
} else if (config instanceof Config) {
((Config) config).save();
} else {
player.sendMessage(ChatColor.RED + "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
plugin.getLogger().log(Level.WARNING, "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
return;
}
plugin.reloadConfig();
player.sendMessage(ChatColor.GREEN + "Config " + file + " saved!");
}
private boolean isNumber(Object value) {
return value != null && (
value instanceof Long
|| value instanceof Integer
|| value instanceof Float
|| value instanceof Double);
}
private boolean isMaterial(Object value) {
CompatibleMaterial m;
return value instanceof String && value.toString().equals(value.toString().toUpperCase())
&& (m = CompatibleMaterial.getMaterial(value.toString())) != null && m.isValidItem();
}
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String def) {
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(node, path);
if (comment != null) {
info = comment.toString().split("\n");
}
} catch (Exception ex) {
}
}
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? def.split("\n") : null));
}
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String value, String def) {
if (value == null) value = "";
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(node, path);
if (comment != null) {
info = (value + "\n" + comment.toString()).split("\n");
}
} catch (Exception ex) {
}
}
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? (value + "\n" + def).split("\n") : null));
}
}
package com.songoda.core.configuration.editor;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import com.songoda.core.input.ChatPrompt;
import com.songoda.core.utils.ItemUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
/**
* Edit a configuration file for a specific plugin
*
* @author jascotty2
* @since 2019-08-31
*/
public class ConfigEditorGui extends SimplePagedGui {
final JavaPlugin plugin;
final String file;
final MemoryConfiguration config;
final ConfigurationSection node;
final Player player;
Method configSection_getCommentString = null;
boolean edits = false;
List<String> sections = new ArrayList();
List<String> settings = new ArrayList();
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config) {
this(player, plugin, parent, file, config, config);
}
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config, ConfigurationSection node) {
super(parent);
this.player = player;
this.plugin = plugin;
this.file = file;
this.config = config;
this.node = node;
this.blankItem = GuiUtils.getBorderItem(CompatibleMaterial.LIGHT_GRAY_STAINED_GLASS_PANE);
if (!(parent instanceof ConfigEditorGui)) {
setOnClose((gui) -> save());
} else {
setOnClose((gui) -> ((ConfigEditorGui) parent).edits |= edits);
}
// if we have a ConfigSection, we can also grab comments
try {
configSection_getCommentString = node.getClass().getDeclaredMethod("getCommentString", String.class);
} catch (Exception ex) {
}
// decorate header
this.setTitle(ChatColor.DARK_BLUE + file);
this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(CompatibleMaterial.GRAY_STAINED_GLASS_PANE.getItem());
final String path = node.getCurrentPath();
this.setItem(4, configItem(CompatibleMaterial.FILLED_MAP, !path.isEmpty() ? path : file, config, !path.isEmpty() ? path : null, ChatColor.BLACK.toString()));
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// compile list of settings
for (String key : node.getKeys(false)) {
if (node.isConfigurationSection(key)) {
sections.add(key);
} else {
settings.add(key);
}
}
// next we need to display the config settings
int index = 9;
for (final String sectionKey : sections) {
setButton(index++, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + sectionKey, node, sectionKey, "Click to open this section"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(player, plugin, this, file, config, node.getConfigurationSection(sectionKey))));
}
// now display individual settings
for (final String settingKey : settings) {
final Object val = node.get(settingKey);
if (val == null) continue;
else if (val instanceof Boolean) {
// toggle switch
setButton(index, configItem(CompatibleMaterial.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Boolean) val), "Click to toggle this setting"),
(event) -> this.toggle(event.slot, settingKey));
if ((Boolean) val) {
highlightItem(index);
}
} else if (isNumber(val)) {
// number dial
this.setButton(index, configItem(CompatibleMaterial.CLOCK, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Number) val), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new number value for " + settingKey + ":", response -> {
if (!setNumber(event.slot, settingKey, response.getMessage().trim())) {
event.player.sendMessage(ChatColor.RED + "Error: \"" + response.getMessage().trim() + "\" is not a number!");
}
}).setOnClose(() -> event.manager.showGUI(event.player, this))
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
} else if (isMaterial(val)) {
// changing a block
// isMaterial is more of a guess, to be honest.
setButton(index, configItem(CompatibleMaterial.STONE, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> {
SimplePagedGui paged = new SimplePagedGui(this);
paged.setTitle(ChatColor.BLUE + settingKey);
paged.setHeaderBackItem(headerBackItem).setFooterBackItem(footerBackItem).setDefaultItem(blankItem);
paged.setItem(4, configItem(CompatibleMaterial.FILLED_MAP, settingKey, node, settingKey, "Choose an item to change this value to"));
int i = 9;
for (CompatibleMaterial mat : CompatibleMaterial.getAllValidItemMaterials()) {
paged.setButton(i++, GuiUtils.createButtonItem(mat, mat.name()), ClickType.LEFT, (matEvent) -> {
setMaterial(event.slot, settingKey, matEvent.clickedItem);
matEvent.player.closeInventory();
});
}
event.manager.showGUI(event.player, paged);
});
} else if (val instanceof String) {
// changing a "string" value (or change to a feather for writing quill)
setButton(index, configItem(CompatibleMaterial.STRING, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new value for " + settingKey + ":", response -> {
node.set(settingKey, response.getMessage().trim());
updateValue(event.slot, settingKey);
}).setOnClose(() -> event.manager.showGUI(event.player, this))
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
} else if (val instanceof List) {
setButton(index, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List) val).size()), "Click to edit this setting"),
(event) -> {
event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> {
if (((ConfigEditorListEditorGui) gui.gui).saveChanges) {
setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).values);
}
}));
});
} else {
// idk. should we display uneditable values?
}
++index;
}
}
public ConfigurationSection getCurrentNode() {
return node;
}
protected void updateValue(int clickCell, String path) {
ItemStack item = inventory.getItem(clickCell);
if (item == null || item == AIR) return;
ItemMeta meta = item.getItemMeta();
Object val = node.get(path);
if (meta != null && val != null) {
String valStr;
if (val instanceof List) {
valStr = String.format("(%d values)", ((List) val).size());
} else {
valStr = val.toString();
}
List<String> lore = meta.getLore();
if (lore == null || lore.isEmpty()) {
meta.setLore(Arrays.asList(valStr));
} else {
lore.set(0, valStr);
meta.setLore(lore);
}
item.setItemMeta(meta);
setItem(clickCell, item);
}
edits = true;
}
void toggle(int clickCell, String path) {
boolean val = !node.getBoolean(path);
node.set(path, val);
if (val) {
setItem(clickCell, ItemUtils.addGlow(inventory.getItem(clickCell)));
} else {
setItem(clickCell, ItemUtils.removeGlow(inventory.getItem(clickCell)));
}
updateValue(clickCell, path);
}
boolean setNumber(int clickCell, String path, String input) {
try {
if (node.isInt(path)) {
node.set(path, Integer.parseInt(input));
} else if (node.isDouble(path)) {
node.set(path, Double.parseDouble(input));
} else if (node.isLong(path)) {
node.set(path, Long.parseLong(input));
}
updateValue(clickCell, path);
} catch (NumberFormatException e) {
return false;
}
return true;
}
void setMaterial(int clickCell, String path, ItemStack item) {
CompatibleMaterial mat = CompatibleMaterial.getMaterial(item);
if (mat == null) {
node.set(path, CompatibleMaterial.STONE.name());
} else {
node.set(path, mat.name());
}
updateValue(clickCell, path);
}
void setList(int clickCell, String path, List<String> list) {
node.set(path, list);
updateValue(clickCell, path);
}
void save() {
if (!edits) {
return;
}
// could also check and call saveChanges()
if (config instanceof FileConfiguration) {
try {
((FileConfiguration) config).save(new File(plugin.getDataFolder(), file));
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to save config changes to " + file, ex);
return;
}
} else if (config instanceof Config) {
((Config) config).save();
} else {
player.sendMessage(ChatColor.RED + "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
plugin.getLogger().log(Level.WARNING, "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
return;
}
plugin.reloadConfig();
player.sendMessage(ChatColor.GREEN + "Config " + file + " saved!");
}
private boolean isNumber(Object value) {
return value != null && (
value instanceof Long
|| value instanceof Integer
|| value instanceof Float
|| value instanceof Double);
}
private boolean isMaterial(Object value) {
CompatibleMaterial m;
return value instanceof String && value.toString().equals(value.toString().toUpperCase())
&& (m = CompatibleMaterial.getMaterial(value.toString())) != null && m.isValidItem();
}
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String def) {
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(node, path);
if (comment != null) {
info = comment.toString().split("\n");
}
} catch (Exception ex) {
}
}
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? def.split("\n") : null));
}
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String value, String def) {
if (value == null) value = "";
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(node, path);
if (comment != null) {
info = (value + "\n" + comment.toString()).split("\n");
}
} catch (Exception ex) {
}
}
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? (value + "\n" + def).split("\n") : null));
}
}

View File

@ -1,85 +1,84 @@
package com.songoda.core.configuration.editor;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import com.songoda.core.input.ChatPrompt;
import org.bukkit.ChatColor;
import org.bukkit.event.inventory.ClickType;
import java.util.ArrayList;
import java.util.List;
/**
* Edit a string list
*
* @author jascotty2
* @since 2019-08-31
*/
public class ConfigEditorListEditorGui extends SimplePagedGui {
final ConfigEditorGui current;
public boolean saveChanges = false;
public List<String> values;
public ConfigEditorListEditorGui(ConfigEditorGui current, String key, List<String> val) {
super(current);
this.current = current;
this.blankItem = current.getDefaultItem();
headerBackItem = footerBackItem = current.getHeaderBackItem();
setTitle(ChatColor.DARK_BLUE + "String List Editor");
this.setUseHeader(true);
this.setItem(4, current.configItem(CompatibleMaterial.FILLED_MAP, key, current.getCurrentNode(), key, null));
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
this.values = new ArrayList(val);
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.LAVA_BUCKET, ChatColor.RED + "Discard Changes"), (event) -> event.player.closeInventory());
this.setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE, ChatColor.GREEN + "Save"), (event) -> {
saveChanges = true;
event.player.closeInventory();
});
this.setButton(1, GuiUtils.createButtonItem(CompatibleMaterial.CHEST, ChatColor.BLUE + "Add Item"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(event.manager.getPlugin(), event.player, "Enter a new value to add:", response -> {
values.add(response.getMessage().trim());
redraw();
}).setOnClose(() -> {
event.manager.showGUI(event.player, this);
})
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
redraw();
}
void redraw() {
page = 1;
// clear old display
if (inventory != null) {
for (Integer i : cellItems.keySet().toArray(new Integer[0])) {
if (i > 8) {
cellItems.remove(i);
conditionalButtons.remove(i);
}
}
}
// update items
int i = 9;
for (String item : values) {
final int index = i - 9;
setButton(i++, GuiUtils.createButtonItem(CompatibleMaterial.PAPER, item, "Right-click to remove"), ClickType.RIGHT, (event) -> {
values.remove(index);
redraw();
});
}
// update display
update();
}
}
package com.songoda.core.configuration.editor;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import com.songoda.core.input.ChatPrompt;
import org.bukkit.ChatColor;
import org.bukkit.event.inventory.ClickType;
import java.util.ArrayList;
import java.util.List;
/**
* Edit a string list
*
* @author jascotty2
* @since 2019-08-31
*/
public class ConfigEditorListEditorGui extends SimplePagedGui {
final ConfigEditorGui current;
public boolean saveChanges = false;
public List<String> values;
public ConfigEditorListEditorGui(ConfigEditorGui current, String key, List<String> val) {
super(current);
this.current = current;
this.blankItem = current.getDefaultItem();
headerBackItem = footerBackItem = current.getHeaderBackItem();
setTitle(ChatColor.DARK_BLUE + "String List Editor");
this.setUseHeader(true);
this.setItem(4, current.configItem(CompatibleMaterial.FILLED_MAP, key, current.getCurrentNode(), key, null));
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
this.values = new ArrayList(val);
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.LAVA_BUCKET, ChatColor.RED + "Discard Changes"), (event) -> event.player.closeInventory());
this.setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE, ChatColor.GREEN + "Save"), (event) -> {
saveChanges = true;
event.player.closeInventory();
});
this.setButton(1, GuiUtils.createButtonItem(CompatibleMaterial.CHEST, ChatColor.BLUE + "Add Item"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(event.manager.getPlugin(), event.player, "Enter a new value to add:", response -> {
values.add(response.getMessage().trim());
redraw();
}).setOnClose(() -> {
event.manager.showGUI(event.player, this);
})
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
redraw();
}
void redraw() {
page = 1;
// clear old display
if (inventory != null) {
for (Integer i : cellItems.keySet().toArray(new Integer[0])) {
if (i > 8) {
cellItems.remove(i);
conditionalButtons.remove(i);
}
}
}
// update items
int i = 9;
for (String item : values) {
final int index = i - 9;
setButton(i++, GuiUtils.createButtonItem(CompatibleMaterial.PAPER, item, "Right-click to remove"), ClickType.RIGHT, (event) -> {
values.remove(index);
redraw();
});
}
// update display
update();
}
}

View File

@ -1,99 +1,98 @@
package com.songoda.core.configuration.editor;
import com.songoda.core.SongodaPlugin;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import org.bukkit.ChatColor;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Edit all configuration files for a specific plugin
*
* @author jascotty2
* @since 2019-08-31
*/
public class PluginConfigGui extends SimplePagedGui {
final JavaPlugin plugin;
LinkedHashMap<String, MemoryConfiguration> configs = new LinkedHashMap();
public PluginConfigGui(SongodaPlugin plugin) {
this(plugin, null);
}
public PluginConfigGui(SongodaPlugin plugin, Gui parent) {
super(parent);
this.plugin = plugin;
// collect list of plugins
configs.put(plugin.getCoreConfig().getFile().getName(), plugin.getCoreConfig());
List<Config> more = plugin.getExtraConfig();
if (more != null && !more.isEmpty()) {
for (Config cfg : more) {
configs.put(cfg.getFile().getName(), cfg);
}
}
init();
}
public PluginConfigGui(JavaPlugin plugin) {
this(plugin, null);
}
public PluginConfigGui(JavaPlugin plugin, Gui parent) {
super(parent);
this.plugin = plugin;
// collect list of plugins
configs.put("config.yml", plugin.getConfig());
try {
// can we also grab extra config from this mysterious plugin?
Object more = plugin.getClass().getDeclaredMethod("getExtraConfig").invoke(plugin);
if (more != null && more instanceof List && !((List) more).isEmpty()) {
try {
// if we have the getExtraConfig function, we should also be able to get the file
Method method_Config_getFile = ((List) more).get(0).getClass().getDeclaredMethod("getFile");
for (Object cfg : ((List) more)) {
configs.put(((File) method_Config_getFile.invoke(cfg)).getName(), (MemoryConfiguration) cfg);
}
} catch (Exception ex) {
// include a failsafe, I guess
((List) more).forEach(cfg -> configs.put("(File " + configs.size() + ")", (MemoryConfiguration) cfg));
}
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
// I guess not!
}
init();
}
private void init() {
this.blankItem = GuiUtils.getBorderItem(CompatibleMaterial.LIGHT_GRAY_STAINED_GLASS_PANE);
// decorate header
this.setTitle(ChatColor.DARK_BLUE + plugin.getName() + " Plugin Config");
this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(CompatibleMaterial.GRAY_STAINED_GLASS_PANE.getItem());
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// List out all config files that this plugin has
int i = 9;
for (Map.Entry<String, MemoryConfiguration> config : configs.entrySet()) {
this.setButton(i++, GuiUtils.createButtonItem(CompatibleMaterial.BOOK, ChatColor.YELLOW + config.getKey(), "Click to edit this config"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(event.player, plugin, this, config.getKey(), config.getValue())));
}
}
}
package com.songoda.core.configuration.editor;
import com.songoda.core.SongodaPlugin;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.configuration.Config;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import org.bukkit.ChatColor;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Edit all configuration files for a specific plugin
*
* @author jascotty2
* @since 2019-08-31
*/
public class PluginConfigGui extends SimplePagedGui {
final JavaPlugin plugin;
LinkedHashMap<String, MemoryConfiguration> configs = new LinkedHashMap();
public PluginConfigGui(SongodaPlugin plugin) {
this(plugin, null);
}
public PluginConfigGui(SongodaPlugin plugin, Gui parent) {
super(parent);
this.plugin = plugin;
// collect list of plugins
configs.put(plugin.getCoreConfig().getFile().getName(), plugin.getCoreConfig());
List<Config> more = plugin.getExtraConfig();
if (more != null && !more.isEmpty()) {
for (Config cfg : more) {
configs.put(cfg.getFile().getName(), cfg);
}
}
init();
}
public PluginConfigGui(JavaPlugin plugin) {
this(plugin, null);
}
public PluginConfigGui(JavaPlugin plugin, Gui parent) {
super(parent);
this.plugin = plugin;
// collect list of plugins
configs.put("config.yml", plugin.getConfig());
try {
// can we also grab extra config from this mysterious plugin?
Object more = plugin.getClass().getDeclaredMethod("getExtraConfig").invoke(plugin);
if (more != null && more instanceof List && !((List) more).isEmpty()) {
try {
// if we have the getExtraConfig function, we should also be able to get the file
Method method_Config_getFile = ((List) more).get(0).getClass().getDeclaredMethod("getFile");
for (Object cfg : ((List) more)) {
configs.put(((File) method_Config_getFile.invoke(cfg)).getName(), (MemoryConfiguration) cfg);
}
} catch (Exception ex) {
// include a failsafe, I guess
((List) more).forEach(cfg -> configs.put("(File " + configs.size() + ")", (MemoryConfiguration) cfg));
}
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
// I guess not!
}
init();
}
private void init() {
this.blankItem = GuiUtils.getBorderItem(CompatibleMaterial.LIGHT_GRAY_STAINED_GLASS_PANE);
// decorate header
this.setTitle(ChatColor.DARK_BLUE + plugin.getName() + " Plugin Config");
this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(CompatibleMaterial.GRAY_STAINED_GLASS_PANE.getItem());
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// List out all config files that this plugin has
int i = 9;
for (Map.Entry<String, MemoryConfiguration> config : configs.entrySet()) {
this.setButton(i++, GuiUtils.createButtonItem(CompatibleMaterial.BOOK, ChatColor.YELLOW + config.getKey(), "Click to edit this config"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(event.player, plugin, this, config.getKey(), config.getValue())));
}
}
}

View File

@ -3,5 +3,4 @@ package com.songoda.core.core;
public interface PluginInfoModule {
void run(PluginInfo plugin);
}

View File

@ -1,52 +1,51 @@
package com.songoda.core.core;
import com.songoda.core.SongodaCore;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.gui.GuiManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
public class SongodaCoreCommand extends AbstractCommand {
protected GuiManager guiManager;
public SongodaCoreCommand() {
super(false, "songoda");
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
if (sender instanceof Player) {
if (guiManager == null || guiManager.isClosed()) {
guiManager = new GuiManager(SongodaCore.getHijackedPlugin());
}
guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI());
} else {
sender.sendMessage("/songoda diag");
}
return ReturnType.SUCCESS;
}
@Override
public String getPermissionNode() {
return "songoda.admin";
}
@Override
public String getSyntax() {
return "/songoda";
}
@Override
public String getDescription() {
return "Displays this interface.";
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}
}
package com.songoda.core.core;
import com.songoda.core.SongodaCore;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.gui.GuiManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
public class SongodaCoreCommand extends AbstractCommand {
protected GuiManager guiManager;
public SongodaCoreCommand() {
super(false, "songoda");
}
@Override
protected ReturnType runCommand(CommandSender sender, String... args) {
if (sender instanceof Player) {
if (guiManager == null || guiManager.isClosed()) {
guiManager = new GuiManager(SongodaCore.getHijackedPlugin());
}
guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI());
} else {
sender.sendMessage("/songoda diag");
}
return ReturnType.SUCCESS;
}
@Override
public String getPermissionNode() {
return "songoda.admin";
}
@Override
public String getSyntax() {
return "/songoda";
}
@Override
public String getDescription() {
return "Displays this interface.";
}
@Override
protected List<String> onTab(CommandSender sender, String... args) {
return null;
}
}

View File

@ -2,9 +2,9 @@ package com.songoda.core.core;
import com.songoda.core.SongodaCore;
import com.songoda.core.commands.AbstractCommand;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.ServerProject;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.compatibility.ClassMapping;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;

View File

@ -25,26 +25,26 @@ final class SongodaCoreOverviewGUI extends Gui {
final PluginInfo plugin = plugins.get(i);
if (plugin.hasUpdate()) {
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Latest Version: " + plugin.getLatestVersion(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
"Change log:",
plugin.getChangeLog(),
"",
ChatColor.GOLD + "Click for the marketplace page link.",
ChatColor.GOLD + "Right Click to edit plugin settings."
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Latest Version: " + plugin.getLatestVersion(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
"Change log:",
plugin.getChangeLog(),
"",
ChatColor.GOLD + "Click for the marketplace page link.",
ChatColor.GOLD + "Right Click to edit plugin settings."
),
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
highlightItem(i);
} else {
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
ChatColor.GOLD + "Click for the marketplace page link.",
ChatColor.GOLD + "Right Click to edit plugin settings."
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
ChatColor.GOLD + "Click for the marketplace page link.",
ChatColor.GOLD + "Right Click to edit plugin settings."
),
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));

View File

@ -19,5 +19,4 @@ public abstract class DataMigration {
public int getRevision() {
return this.revision;
}
}

View File

@ -100,5 +100,4 @@ public class DataMigrationManager {
private String getMigrationsTableName() {
return this.dataManagerAbstract.getTablePrefix() + "migrations";
}
}

View File

@ -30,5 +30,4 @@ public interface DatabaseConnector {
interface ConnectionCallback {
void accept(Connection connection) throws SQLException;
}
}

View File

@ -51,5 +51,4 @@ public class MySQLConnector implements DatabaseConnector {
ex.printStackTrace();
}
}
}

View File

@ -57,5 +57,4 @@ public class SQLiteConnector implements DatabaseConnector {
ex.printStackTrace();
}
}
}

View File

@ -10,5 +10,4 @@ public enum BackgroundType {
private BackgroundType() {
this.key = "minecraft:textures/gui/advancements/backgrounds/" + name().toLowerCase() + ".png";
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,20 @@
package com.songoda.core.gui;
import org.bukkit.event.inventory.InventoryType;
public enum GuiType {
STANDARD(InventoryType.CHEST, 6, 9),
DISPENSER(InventoryType.DISPENSER, 9, 3),
HOPPER(InventoryType.HOPPER, 5, 1);
protected final InventoryType type;
protected final int rows;
protected final int columns;
private GuiType(InventoryType type, int rows, int columns) {
this.type = type;
this.rows = rows;
this.columns = columns;
}
}
package com.songoda.core.gui;
import org.bukkit.event.inventory.InventoryType;
public enum GuiType {
STANDARD(InventoryType.CHEST, 6, 9),
DISPENSER(InventoryType.DISPENSER, 9, 3),
HOPPER(InventoryType.HOPPER, 5, 1);
protected final InventoryType type;
protected final int rows;
protected final int columns;
private GuiType(InventoryType type, int rows, int columns) {
this.type = type;
this.rows = rows;
this.columns = columns;
}
}

View File

@ -1,412 +1,413 @@
package com.songoda.core.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @author jascotty2
* @since 2019-08-25
*/
public class GuiUtils {
public static ItemStack getBorderGlassItem() {
ItemStack glass = CompatibleMaterial.LIGHT_BLUE_STAINED_GLASS_PANE.getItem();
ItemMeta glassmeta = glass.getItemMeta();
glassmeta.setDisplayName(ChatColor.BLACK.toString());
glass.setItemMeta(glassmeta);
return glass;
}
public static ItemStack getBorderItem(ItemStack item) {
ItemMeta glassmeta = item.getItemMeta();
glassmeta.setDisplayName(ChatColor.BLACK.toString());
item.setItemMeta(glassmeta);
return item;
}
public static ItemStack getBorderItem(CompatibleMaterial mat) {
ItemStack item = mat.getItem();
ItemMeta glassmeta = item.getItemMeta();
glassmeta.setDisplayName(ChatColor.BLACK.toString());
item.setItemMeta(glassmeta);
return item;
}
public static List<String> getSafeLore(String... lines) {
return getSafeLore(Arrays.asList(lines));
}
/**
* Get a lore value that will display fine on clients using auto gui scaling
*
* @param lines lines to format
* @return newline and length-corrected item lore
*/
public static List<String> getSafeLore(List<String> lines) {
// fix newlines
ArrayList<String> newLore = new ArrayList();
for (String l : lines) {
for (String l2 : l.split("\n")) {
if (l2.length() < 54) {
newLore.add(l2);
} else {
// try to shorten the string
String shorterString = l2;
ChatColor lastColor = null; // todo? probably should also track formatting codes..
int line = 0;
while (shorterString.length() > 50) {
int breakingSpace = -1;
for (int i = 0; i < 50; ++i) {
if (shorterString.charAt(i) == ChatColor.COLOR_CHAR) {
lastColor = ChatColor.getByChar(shorterString.charAt(++i));
} else if (shorterString.charAt(i) == ' ' || shorterString.charAt(i) == '-') {
breakingSpace = i;
}
}
if (breakingSpace == -1) {
breakingSpace = Math.max(50, shorterString.length());
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
} else {
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace));
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
}
++line;
}
if (!shorterString.isEmpty()) {
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + " " + shorterString);
}
}
}
}
return newLore;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, String... lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, String... lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, String title, String... lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, List<String> lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, List<String> lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, String title, List<String> lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, String[] lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String[] lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, String[] lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, List<String> lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && !lore.isEmpty()) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, List<String> lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && !lore.isEmpty()) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, List<String> lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && !lore.isEmpty()) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, String title, String... lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItemName(ItemStack item, String title) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItemLore(ItemStack item, String... lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItemLore(ItemStack item, List<String> lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, CompatibleMaterial matTo, String title, String... lore) {
if (!matTo.matches(item)) {
item = matTo.getItem();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, ItemStack to, String title, String... lore) {
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
item = to.clone();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, String title, List<String> lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, CompatibleMaterial matTo, String title, List<String> lore) {
if (!matTo.matches(item)) {
item = matTo.getItem();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, ItemStack to, String title, List<String> lore) {
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
item = to.clone();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
}
package com.songoda.core.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @author jascotty2
* @since 2019-08-25
*/
public class GuiUtils {
public static ItemStack getBorderGlassItem() {
ItemStack glass = CompatibleMaterial.LIGHT_BLUE_STAINED_GLASS_PANE.getItem();
ItemMeta glassmeta = glass.getItemMeta();
glassmeta.setDisplayName(ChatColor.BLACK.toString());
glass.setItemMeta(glassmeta);
return glass;
}
public static ItemStack getBorderItem(ItemStack item) {
ItemMeta glassmeta = item.getItemMeta();
glassmeta.setDisplayName(ChatColor.BLACK.toString());
item.setItemMeta(glassmeta);
return item;
}
public static ItemStack getBorderItem(CompatibleMaterial mat) {
ItemStack item = mat.getItem();
ItemMeta glassmeta = item.getItemMeta();
glassmeta.setDisplayName(ChatColor.BLACK.toString());
item.setItemMeta(glassmeta);
return item;
}
public static List<String> getSafeLore(String... lines) {
return getSafeLore(Arrays.asList(lines));
}
/**
* Get a lore value that will display fine on clients using auto gui scaling
*
* @param lines lines to format
*
* @return newline and length-corrected item lore
*/
public static List<String> getSafeLore(List<String> lines) {
// fix newlines
ArrayList<String> newLore = new ArrayList();
for (String l : lines) {
for (String l2 : l.split("\n")) {
if (l2.length() < 54) {
newLore.add(l2);
} else {
// try to shorten the string
String shorterString = l2;
ChatColor lastColor = null; // todo? probably should also track formatting codes..
int line = 0;
while (shorterString.length() > 50) {
int breakingSpace = -1;
for (int i = 0; i < 50; ++i) {
if (shorterString.charAt(i) == ChatColor.COLOR_CHAR) {
lastColor = ChatColor.getByChar(shorterString.charAt(++i));
} else if (shorterString.charAt(i) == ' ' || shorterString.charAt(i) == '-') {
breakingSpace = i;
}
}
if (breakingSpace == -1) {
breakingSpace = Math.max(50, shorterString.length());
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
} else {
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace));
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
}
++line;
}
if (!shorterString.isEmpty()) {
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + " " + shorterString);
}
}
}
}
return newLore;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, String... lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, String... lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, String title, String... lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, List<String> lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, List<String> lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, String title, List<String> lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, String[] lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String[] lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, String[] lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, List<String> lore) {
ItemStack item = mat.getItem();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && !lore.isEmpty()) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, List<String> lore) {
ItemStack item = mat.getItem();
item.setAmount(amount);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && !lore.isEmpty()) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack createButtonItem(ItemStack from, List<String> lore) {
ItemStack item = from.clone();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && !lore.isEmpty()) {
List<String> safe = getSafeLore(lore);
meta.setDisplayName(safe.get(0));
meta.setLore(safe.subList(1, safe.size()));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, String title, String... lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItemName(ItemStack item, String title) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItemLore(ItemStack item, String... lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null && lore.length != 0) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItemLore(ItemStack item, List<String> lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, CompatibleMaterial matTo, String title, String... lore) {
if (!matTo.matches(item)) {
item = matTo.getItem();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, ItemStack to, String title, String... lore) {
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
item = to.clone();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, String title, List<String> lore) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, CompatibleMaterial matTo, String title, List<String> lore) {
if (!matTo.matches(item)) {
item = matTo.getItem();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
public static ItemStack updateItem(ItemStack item, ItemStack to, String title, List<String> lore) {
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
item = to.clone();
}
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName(title);
if (lore != null) {
meta.setLore(getSafeLore(lore));
} else {
meta.setLore(Collections.EMPTY_LIST);
}
item.setItemMeta(meta);
}
return item;
}
}

View File

@ -1,187 +1,186 @@
package com.songoda.core.gui;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.HashSet;
import java.util.UUID;
/**
* Instance of a popup message that can be sent to a player <br>
* Popup toast messages only work on Minecraft 1.12+ <br>
* Calling this class on anything below 1.12 will cause ClassLoader Exceptions!
*/
class PopupMessage {
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final HashSet<UUID> registeredMessages = new HashSet();
final UUID id = UUID.randomUUID();
private final NamespacedKey key;
private final TextComponent title;
CompatibleMaterial icon;
TriggerType trigger = TriggerType.IMPOSSIBLE;
FrameType frame = FrameType.GOAL; // TASK is the default
BackgroundType background = BackgroundType.ADVENTURE;
PopupMessage(Plugin source, CompatibleMaterial icon, String title) {
this.key = new NamespacedKey(source, "popup/" + id);
this.title = new TextComponent(title.length() < 74 ? title : (title.substring(0, 72) + "..."));
this.icon = icon;
}
PopupMessage(Plugin source, CompatibleMaterial icon, String title, BackgroundType background) {
this.key = new NamespacedKey(source, "popup/" + id);
this.title = new TextComponent(title.length() < 74 ? title : (title.substring(0, 72) + "..."));
this.icon = icon;
this.background = background;
}
private String getJSON() {
JsonObject json = new JsonObject();
JsonObject advDisplay = new JsonObject();
if (this.icon != null) {
JsonObject displayIcon = new JsonObject();
displayIcon.addProperty("item", "minecraft:" + this.icon.getMaterial().name().toLowerCase());
if (this.icon.usesData()) {
displayIcon.addProperty("data", this.icon.getData());
}
advDisplay.add("icon", displayIcon);
}
advDisplay.add("title", gson.fromJson(ComponentSerializer.toString(this.title), JsonElement.class));
advDisplay.addProperty("background", background.key);
advDisplay.addProperty("description", "");
advDisplay.addProperty("frame", this.frame.id);
advDisplay.addProperty("announce_to_chat", false);
advDisplay.addProperty("show_toast", true);
advDisplay.addProperty("hidden", true);
json.add("display", advDisplay);
JsonObject advCriteria = new JsonObject();
json.add("criteria", advCriteria);
JsonObject advTrigger = new JsonObject();
advTrigger.addProperty("trigger", this.trigger.getKey());
/*if() {
JsonObject advConditions = new JsonObject();
// can add items to this list with [item,amount,data]
advTrigger.add("conditions", advConditions);
}*/
advCriteria.add("mentioned", advTrigger);
return gson.toJson(json);
}
protected void grant(final Player pl) {
final Advancement adv = getAdvancement();
final AdvancementProgress progress = pl.getAdvancementProgress(adv);
if (!progress.isDone())
progress.getRemainingCriteria().forEach((crit) -> progress.awardCriteria(crit));
}
protected void revoke(final Player pl) {
final Advancement adv = getAdvancement();
final AdvancementProgress prog = pl.getAdvancementProgress(adv);
if (prog.isDone())
prog.getAwardedCriteria().forEach((crit) -> prog.revokeCriteria(crit));
}
protected void add() {
if (!registeredMessages.contains(id)) {
registeredMessages.add(id);
try {
Bukkit.getUnsafe().loadAdvancement(key, getJSON());
} catch (IllegalArgumentException e) {
Bukkit.getLogger().warning("Failed to create popup advancement!");
}
}
}
protected void remove() {
if (registeredMessages.contains(id)) {
registeredMessages.remove(id);
Bukkit.getUnsafe().removeAdvancement(key);
}
}
public Advancement getAdvancement() {
return Bukkit.getAdvancement(key);
}
public static enum FrameType {
TASK,
CHALLENGE,
GOAL;
final String id;
private FrameType() {
id = name().toLowerCase();
}
}
public static enum TriggerType {
ARBITRARY_PLAYER_TICK(ServerVersion.V1_13, "TICK"),
BRED_ANIMALS,
BREWED_POTION,
CHANGED_DIMENSION,
CONSTRUCT_BEACON,
CONSUME_ITEM,
CURED_ZOMBIE_VILLAGER,
EFFECTS_CHANGED,
ENCHANTED_ITEM,
ENTER_BLOCK,
ENTITY_HURT_PLAYER,
ENTITY_KILLED_PLAYER,
IMPOSSIBLE,
INVENTORY_CHANGED,
ITEM_DURABILITY_CHANGED,
LEVITATION,
LOCATION,
NETHER_TRAVEL,
PLACED_BLOCK,
PLAYER_HURT_ENTITY,
PLAYER_KILL_ENTITY,
RECIPE_UNLOCKED,
SLEPT_IN_BED,
SUMMONED_ENTITY,
TAME_ANIMAL,
TICK,
USED_ENDER_EYE,
USED_TOTEM,
VILLAGER_TRADE;
final ServerVersion minVersion;
final String compatible;
final String key;
private TriggerType() {
this.minVersion = ServerVersion.UNKNOWN;
this.compatible = "";
this.key = "minecraft:" + name().toLowerCase();
}
private TriggerType(ServerVersion minVersion, String compatible) {
this.minVersion = minVersion;
this.compatible = compatible;
this.key = "minecraft:" + (ServerVersion.isServerVersionAtLeast(minVersion) ? name() : compatible).toLowerCase();
}
public String getKey() {
return key;
}
}
}
package com.songoda.core.gui;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.HashSet;
import java.util.UUID;
/**
* Instance of a popup message that can be sent to a player <br>
* Popup toast messages only work on Minecraft 1.12+ <br>
* Calling this class on anything below 1.12 will cause ClassLoader Exceptions!
*/
class PopupMessage {
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final HashSet<UUID> registeredMessages = new HashSet();
final UUID id = UUID.randomUUID();
private final NamespacedKey key;
private final TextComponent title;
CompatibleMaterial icon;
TriggerType trigger = TriggerType.IMPOSSIBLE;
FrameType frame = FrameType.GOAL; // TASK is the default
BackgroundType background = BackgroundType.ADVENTURE;
PopupMessage(Plugin source, CompatibleMaterial icon, String title) {
this.key = new NamespacedKey(source, "popup/" + id);
this.title = new TextComponent(title.length() < 74 ? title : (title.substring(0, 72) + "..."));
this.icon = icon;
}
PopupMessage(Plugin source, CompatibleMaterial icon, String title, BackgroundType background) {
this.key = new NamespacedKey(source, "popup/" + id);
this.title = new TextComponent(title.length() < 74 ? title : (title.substring(0, 72) + "..."));
this.icon = icon;
this.background = background;
}
private String getJSON() {
JsonObject json = new JsonObject();
JsonObject advDisplay = new JsonObject();
if (this.icon != null) {
JsonObject displayIcon = new JsonObject();
displayIcon.addProperty("item", "minecraft:" + this.icon.getMaterial().name().toLowerCase());
if (this.icon.usesData()) {
displayIcon.addProperty("data", this.icon.getData());
}
advDisplay.add("icon", displayIcon);
}
advDisplay.add("title", gson.fromJson(ComponentSerializer.toString(this.title), JsonElement.class));
advDisplay.addProperty("background", background.key);
advDisplay.addProperty("description", "");
advDisplay.addProperty("frame", this.frame.id);
advDisplay.addProperty("announce_to_chat", false);
advDisplay.addProperty("show_toast", true);
advDisplay.addProperty("hidden", true);
json.add("display", advDisplay);
JsonObject advCriteria = new JsonObject();
json.add("criteria", advCriteria);
JsonObject advTrigger = new JsonObject();
advTrigger.addProperty("trigger", this.trigger.getKey());
/*if() {
JsonObject advConditions = new JsonObject();
// can add items to this list with [item,amount,data]
advTrigger.add("conditions", advConditions);
}*/
advCriteria.add("mentioned", advTrigger);
return gson.toJson(json);
}
protected void grant(final Player pl) {
final Advancement adv = getAdvancement();
final AdvancementProgress progress = pl.getAdvancementProgress(adv);
if (!progress.isDone())
progress.getRemainingCriteria().forEach((crit) -> progress.awardCriteria(crit));
}
protected void revoke(final Player pl) {
final Advancement adv = getAdvancement();
final AdvancementProgress prog = pl.getAdvancementProgress(adv);
if (prog.isDone())
prog.getAwardedCriteria().forEach((crit) -> prog.revokeCriteria(crit));
}
protected void add() {
if (!registeredMessages.contains(id)) {
registeredMessages.add(id);
try {
Bukkit.getUnsafe().loadAdvancement(key, getJSON());
} catch (IllegalArgumentException e) {
Bukkit.getLogger().warning("Failed to create popup advancement!");
}
}
}
protected void remove() {
if (registeredMessages.contains(id)) {
registeredMessages.remove(id);
Bukkit.getUnsafe().removeAdvancement(key);
}
}
public Advancement getAdvancement() {
return Bukkit.getAdvancement(key);
}
public static enum FrameType {
TASK,
CHALLENGE,
GOAL;
final String id;
private FrameType() {
id = name().toLowerCase();
}
}
public static enum TriggerType {
ARBITRARY_PLAYER_TICK(ServerVersion.V1_13, "TICK"),
BRED_ANIMALS,
BREWED_POTION,
CHANGED_DIMENSION,
CONSTRUCT_BEACON,
CONSUME_ITEM,
CURED_ZOMBIE_VILLAGER,
EFFECTS_CHANGED,
ENCHANTED_ITEM,
ENTER_BLOCK,
ENTITY_HURT_PLAYER,
ENTITY_KILLED_PLAYER,
IMPOSSIBLE,
INVENTORY_CHANGED,
ITEM_DURABILITY_CHANGED,
LEVITATION,
LOCATION,
NETHER_TRAVEL,
PLACED_BLOCK,
PLAYER_HURT_ENTITY,
PLAYER_KILL_ENTITY,
RECIPE_UNLOCKED,
SLEPT_IN_BED,
SUMMONED_ENTITY,
TAME_ANIMAL,
TICK,
USED_ENDER_EYE,
USED_TOTEM,
VILLAGER_TRADE;
final ServerVersion minVersion;
final String compatible;
final String key;
private TriggerType() {
this.minVersion = ServerVersion.UNKNOWN;
this.compatible = "";
this.key = "minecraft:" + name().toLowerCase();
}
private TriggerType(ServerVersion minVersion, String compatible) {
this.minVersion = minVersion;
this.compatible = compatible;
this.key = "minecraft:" + (ServerVersion.isServerVersionAtLeast(minVersion) ? name() : compatible).toLowerCase();
}
public String getKey() {
return key;
}
}
}

View File

@ -1,29 +1,28 @@
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public class GuiClickEvent extends GuiEvent {
public final int slot;
public final boolean guiClicked;
public final ItemStack cursor, clickedItem;
public final ClickType clickType;
public final InventoryClickEvent event;
public GuiClickEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event, int slot, boolean guiClicked) {
super(manager, gui, player);
this.slot = slot;
this.guiClicked = guiClicked;
this.cursor = event.getCursor();
Inventory clicked = event.getClickedInventory();
this.clickedItem = clicked == null ? null : clicked.getItem(event.getSlot());
this.clickType = event.getClick();
this.event = event;
}
}
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public class GuiClickEvent extends GuiEvent {
public final int slot;
public final boolean guiClicked;
public final ItemStack cursor, clickedItem;
public final ClickType clickType;
public final InventoryClickEvent event;
public GuiClickEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event, int slot, boolean guiClicked) {
super(manager, gui, player);
this.slot = slot;
this.guiClicked = guiClicked;
this.cursor = event.getCursor();
Inventory clicked = event.getClickedInventory();
this.clickedItem = clicked == null ? null : clicked.getItem(event.getSlot());
this.clickType = event.getClick();
this.event = event;
}
}

View File

@ -1,13 +1,12 @@
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
public class GuiCloseEvent extends GuiEvent {
public GuiCloseEvent(GuiManager manager, Gui gui, Player player) {
super(manager, gui, player);
}
}
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
public class GuiCloseEvent extends GuiEvent {
public GuiCloseEvent(GuiManager manager, Gui gui, Player player) {
super(manager, gui, player);
}
}

View File

@ -1,22 +1,21 @@
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class GuiDropItemEvent extends GuiEvent {
public final ItemStack cursor;
public final ClickType clickType;
public final InventoryClickEvent event;
public GuiDropItemEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event) {
super(manager, gui, player);
this.cursor = event.getCursor();
this.clickType = event.getClick();
this.event = event;
}
}
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class GuiDropItemEvent extends GuiEvent {
public final ItemStack cursor;
public final ClickType clickType;
public final InventoryClickEvent event;
public GuiDropItemEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event) {
super(manager, gui, player);
this.cursor = event.getCursor();
this.clickType = event.getClick();
this.event = event;
}
}

View File

@ -1,19 +1,18 @@
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
public abstract class GuiEvent {
public final GuiManager manager;
public final Gui gui;
public final Player player;
public GuiEvent(GuiManager manager, Gui gui, Player player) {
this.manager = manager;
this.gui = gui;
this.player = player;
}
}
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
public abstract class GuiEvent {
public final GuiManager manager;
public final Gui gui;
public final Player player;
public GuiEvent(GuiManager manager, Gui gui, Player player) {
this.manager = manager;
this.gui = gui;
this.player = player;
}
}

View File

@ -1,13 +1,12 @@
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
public class GuiOpenEvent extends GuiEvent {
public GuiOpenEvent(GuiManager manager, Gui gui, Player player) {
super(manager, gui, player);
}
}
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
import org.bukkit.entity.Player;
public class GuiOpenEvent extends GuiEvent {
public GuiOpenEvent(GuiManager manager, Gui gui, Player player) {
super(manager, gui, player);
}
}

View File

@ -1,20 +1,19 @@
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
public class GuiPageEvent {
final Gui gui;
final GuiManager manager;
final int lastPage;
final int page;
public GuiPageEvent(Gui gui, GuiManager manager, int lastPage, int page) {
this.gui = gui;
this.manager = manager;
this.lastPage = lastPage;
this.page = page;
}
}
package com.songoda.core.gui.events;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiManager;
public class GuiPageEvent {
final Gui gui;
final GuiManager manager;
final int lastPage;
final int page;
public GuiPageEvent(Gui gui, GuiManager manager, int lastPage, int page) {
this.gui = gui;
this.manager = manager;
this.lastPage = lastPage;
this.page = page;
}
}

View File

@ -4,8 +4,6 @@ import com.songoda.core.hooks.economies.Economy;
import com.songoda.core.utils.NumberUtils;
import org.bukkit.OfflinePlayer;
import java.text.DecimalFormat;
/**
* A convenience class for static access to an Economy HookManager
*/
@ -61,6 +59,7 @@ public class EconomyManager {
* Format the given amount to a human-readable string in this currency
*
* @param amt amount to display
*
* @return a currency string as formatted by the economy plugin
*/
public static String formatEconomy(double amt) {
@ -71,13 +70,13 @@ public class EconomyManager {
* Get the players available balance
*
* @param player player
*
* @return the amount of available balance
*/
public static double getBalance(OfflinePlayer player) {
if (!manager.isEnabled())
return 0;
return manager.getCurrentHook().getBalance(player);
}
/**
@ -86,6 +85,7 @@ public class EconomyManager {
*
* @param player player to check
* @param cost minimum amount this player should have
*
* @return true if this player can have this amount withdrawn
*/
public static boolean hasBalance(OfflinePlayer player, double cost) {
@ -98,6 +98,7 @@ public class EconomyManager {
*
* @param player player to check
* @param cost amount to remove from this player
*
* @return true if the total amount was withdrawn successfully
*/
public static boolean withdrawBalance(OfflinePlayer player, double cost) {
@ -110,6 +111,7 @@ public class EconomyManager {
*
* @param player player to check
* @param amount amount to add to this player
*
* @return true if the total amount was added successfully
*/
public static boolean deposit(OfflinePlayer player, double amount) {

View File

@ -1,184 +1,189 @@
package com.songoda.core.hooks;
import org.bukkit.plugin.Plugin;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class HookManager<T extends Hook> {
private final Class typeClass;
private T defaultHook = null;
private boolean loaded = false;
private final Map<PluginHook, T> registeredHooks = new HashMap<>();
public HookManager(Class typeClass) {
this.typeClass = typeClass;
}
/**
* Load all supported plugins.
*/
public void load() {
load(null);
}
/**
* Load all supported plugins.
*
* @param hookingPlugin plugin to pass to the hook handler
*/
public void load(Plugin hookingPlugin) {
if (!loaded) {
registeredHooks.putAll(PluginHook.loadHooks(typeClass, hookingPlugin).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (T) e.getValue())));
if (!registeredHooks.isEmpty()) {
defaultHook = (T) registeredHooks.values().iterator().next();
}
loaded = true;
}
}
/**
* Get the currently selected plugin hook. <br>
* If none were set, then the first one found is used.
*
* @return The instance of T that was created, or null if none available.
*/
public T getCurrentHook() {
return defaultHook;
}
/**
* Set the default hook to a different plugin, if that plugin exists. <br>
* If the plugin is not loaded or supported,
* the previously defined default will be used.
*
* @param name name of the plugin to use
* @return true if the default was set to this plugin
*/
public boolean setPreferredHook(String name) {
T hook = getHook(name);
if (hook != null) {
defaultHook = hook;
return true;
}
return false;
}
/**
* Set the default hook to a different plugin, if that plugin exists. <br />
* If the plugin is not loaded or supported,
* the previously defined default will be used.
*
* @param plugin plugin to use
* @return true if the default was set to this plugin
*/
public boolean setPreferredHook(PluginHook plugin) {
T hook = getHook(plugin);
if (hook != null) {
defaultHook = hook;
return true;
}
return false;
}
/**
* Try to grab the handler for this specific plugin hook.
*
* @param name plugin to use
* @return returns null if plugin is not enabled
*/
public T getHook(String name) {
if (name == null)
return null;
final String plugin = name.trim();
return (T) registeredHooks.get(registeredHooks.keySet().stream()
.filter(type -> type.plugin.equalsIgnoreCase(plugin))
.findFirst().orElse(null));
}
/**
* Try to grab the handler for this specific plugin hook.
*
* @param hook plugin to use
* @return returns null if plugin is not enabled
*/
public T getHook(PluginHook hook) {
return registeredHooks.get(hook);
}
/**
* Grab a list of all supported and loaded plugin hooks.
*
* @return an immutable collection of the loaded handler instances
*/
public Collection<T> getRegisteredHooks() {
return Collections.unmodifiableCollection(registeredHooks.values());
}
/**
* Grab a list of all supported and loaded plugin hooks.
*
* @return an immutable collection of plugin names that are loaded.
*/
public List<String> getRegisteredPlugins() {
return registeredHooks.keySet().stream()
.map(v -> v.plugin)
.collect(Collectors.toList());
}
/**
* Get a list of all supported plugins that we can hook into.
*
* @return an immutable collection of plugin names that can be used.
*/
public List<String> getPossiblePlugins() {
return PluginHook.getHooks(typeClass).stream()
.map(v -> v.plugin)
.collect(Collectors.toList());
}
/**
* Check to see if a specific plugin hook is enabled.
*
* @param name plugin to check
* @return true if this plugin is supported and loaded
*/
public boolean isEnabled(String name) {
return getHook(name) != null;
}
/**
* Check to see if a specific plugin hook is enabled.
*
* @param hook plugin to check
* @return true if this plugin is supported and loaded
*/
public boolean isEnabled(PluginHook hook) {
return registeredHooks.containsKey(hook);
}
/**
* Check to see if there is a default hook loaded.
*
* @return returns false if there are no supported plugins loaded
*/
public boolean isEnabled() {
return defaultHook != null;
}
/**
* Get the name of the default plugin being hooked into.
*
* @return plugin name, or null if none enabled.
*/
public String getName() {
return defaultHook != null ? defaultHook.getName() : null;
}
}
package com.songoda.core.hooks;
import org.bukkit.plugin.Plugin;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class HookManager<T extends Hook> {
private final Class typeClass;
private T defaultHook = null;
private boolean loaded = false;
private final Map<PluginHook, T> registeredHooks = new HashMap<>();
public HookManager(Class typeClass) {
this.typeClass = typeClass;
}
/**
* Load all supported plugins.
*/
public void load() {
load(null);
}
/**
* Load all supported plugins.
*
* @param hookingPlugin plugin to pass to the hook handler
*/
public void load(Plugin hookingPlugin) {
if (!loaded) {
registeredHooks.putAll(PluginHook.loadHooks(typeClass, hookingPlugin).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (T) e.getValue())));
if (!registeredHooks.isEmpty()) {
defaultHook = (T) registeredHooks.values().iterator().next();
}
loaded = true;
}
}
/**
* Get the currently selected plugin hook. <br>
* If none were set, then the first one found is used.
*
* @return The instance of T that was created, or null if none available.
*/
public T getCurrentHook() {
return defaultHook;
}
/**
* Set the default hook to a different plugin, if that plugin exists. <br>
* If the plugin is not loaded or supported,
* the previously defined default will be used.
*
* @param name name of the plugin to use
*
* @return true if the default was set to this plugin
*/
public boolean setPreferredHook(String name) {
T hook = getHook(name);
if (hook != null) {
defaultHook = hook;
return true;
}
return false;
}
/**
* Set the default hook to a different plugin, if that plugin exists. <br />
* If the plugin is not loaded or supported,
* the previously defined default will be used.
*
* @param plugin plugin to use
*
* @return true if the default was set to this plugin
*/
public boolean setPreferredHook(PluginHook plugin) {
T hook = getHook(plugin);
if (hook != null) {
defaultHook = hook;
return true;
}
return false;
}
/**
* Try to grab the handler for this specific plugin hook.
*
* @param name plugin to use
*
* @return returns null if plugin is not enabled
*/
public T getHook(String name) {
if (name == null)
return null;
final String plugin = name.trim();
return (T) registeredHooks.get(registeredHooks.keySet().stream()
.filter(type -> type.plugin.equalsIgnoreCase(plugin))
.findFirst().orElse(null));
}
/**
* Try to grab the handler for this specific plugin hook.
*
* @param hook plugin to use
*
* @return returns null if plugin is not enabled
*/
public T getHook(PluginHook hook) {
return registeredHooks.get(hook);
}
/**
* Grab a list of all supported and loaded plugin hooks.
*
* @return an immutable collection of the loaded handler instances
*/
public Collection<T> getRegisteredHooks() {
return Collections.unmodifiableCollection(registeredHooks.values());
}
/**
* Grab a list of all supported and loaded plugin hooks.
*
* @return an immutable collection of plugin names that are loaded.
*/
public List<String> getRegisteredPlugins() {
return registeredHooks.keySet().stream()
.map(v -> v.plugin)
.collect(Collectors.toList());
}
/**
* Get a list of all supported plugins that we can hook into.
*
* @return an immutable collection of plugin names that can be used.
*/
public List<String> getPossiblePlugins() {
return PluginHook.getHooks(typeClass).stream()
.map(v -> v.plugin)
.collect(Collectors.toList());
}
/**
* Check to see if a specific plugin hook is enabled.
*
* @param name plugin to check
*
* @return true if this plugin is supported and loaded
*/
public boolean isEnabled(String name) {
return getHook(name) != null;
}
/**
* Check to see if a specific plugin hook is enabled.
*
* @param hook plugin to check
*
* @return true if this plugin is supported and loaded
*/
public boolean isEnabled(PluginHook hook) {
return registeredHooks.containsKey(hook);
}
/**
* Check to see if there is a default hook loaded.
*
* @return returns false if there are no supported plugins loaded
*/
public boolean isEnabled() {
return defaultHook != null;
}
/**
* Get the name of the default plugin being hooked into.
*
* @return plugin name, or null if none enabled.
*/
public String getName() {
return defaultHook != null ? defaultHook.getName() : null;
}
}

View File

@ -88,5 +88,4 @@ public class LogManager {
if (manager.isEnabled())
manager.getCurrentHook().logInteraction(player, location);
}
}

View File

@ -1,231 +1,230 @@
package com.songoda.core.hooks;
import com.songoda.core.hooks.mcmmo.McMMOHandler;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.util.Collection;
public class McMMOHook {
static boolean canHook = false;
static {
try {
// if this class exists, we're good to use McMMO
Class.forName("com.gmail.nossr50.api.AbilityAPI");
canHook = true;
} catch (ClassNotFoundException ex) {
}
}
public static void addMining(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addMining(player, blocks);
}
}
public static void addExcavation(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addExcavation(player, blocks);
}
}
public static void addHerbalism(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addHerbalism(player, blocks);
}
}
public static void addWoodcutting(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addWoodcutting(player, blocks);
}
}
public static int getAcrobaticsSkill(Player player) {
return canHook ? McMMOHandler.getAcrobaticsSkill(player) : -1;
}
public static int getAlchemySkill(Player player) {
return canHook ? McMMOHandler.getAlchemySkill(player) : -1;
}
public static int getArcherySkill(Player player) {
return canHook ? McMMOHandler.getArcherySkill(player) : -1;
}
public static int getAxesSkill(Player player) {
return canHook ? McMMOHandler.getAxesSkill(player) : -1;
}
public static int getExcavationSkill(Player player) {
return canHook ? McMMOHandler.getExcavationSkill(player) : -1;
}
public static int getFishingSkill(Player player) {
return canHook ? McMMOHandler.getFishingSkill(player) : -1;
}
public static int getHerbalismSkill(Player player) {
return canHook ? McMMOHandler.getHerbalismSkill(player) : -1;
}
public static int getMiningSkill(Player player) {
return canHook ? McMMOHandler.getMiningSkill(player) : -1;
}
public static int getRepairSkill(Player player) {
return canHook ? McMMOHandler.getRepairSkill(player) : -1;
}
public static int getSmeltingSkill(Player player) {
return canHook ? McMMOHandler.getSmeltingSkill(player) : -1;
}
public static int getSwordsSkill(Player player) {
return canHook ? McMMOHandler.getSwordsSkill(player) : -1;
}
public static int getTamingSkill(Player player) {
return canHook ? McMMOHandler.getTamingSkill(player) : -1;
}
public static int getUnarmedSkill(Player player) {
return canHook ? McMMOHandler.getUnarmedSkill(player) : -1;
}
public static int getWoodcuttingSkill(Player player) {
return canHook ? McMMOHandler.getWoodcuttingSkill(player) : -1;
}
public static void addAcrobatics(Player player, int xp) {
if (canHook) {
McMMOHandler.addAcrobatics(player, xp);
}
}
public static void addAlchemy(Player player, int xp) {
if (canHook) {
McMMOHandler.addAlchemy(player, xp);
}
}
public static void addArchery(Player player, int xp) {
if (canHook) {
McMMOHandler.addArchery(player, xp);
}
}
public static void addAxes(Player player, int xp) {
if (canHook) {
McMMOHandler.addAxes(player, xp);
}
}
public static void addExcavation(Player player, int xp) {
if (canHook) {
McMMOHandler.addExcavation(player, xp);
}
}
public static void addFishing(Player player, int xp) {
if (canHook) {
McMMOHandler.addFishing(player, xp);
}
}
public static void addHerbalism(Player player, int xp) {
if (canHook) {
McMMOHandler.addHerbalism(player, xp);
}
}
public static void addMining(Player player, int xp) {
if (canHook) {
McMMOHandler.addMining(player, xp);
}
}
public static void addRepair(Player player, int xp) {
if (canHook) {
McMMOHandler.addRepair(player, xp);
}
}
public static void addSmelting(Player player, int xp) {
if (canHook) {
McMMOHandler.addSmelting(player, xp);
}
}
public static void addSwords(Player player, int xp) {
if (canHook) {
McMMOHandler.addSwords(player, xp);
}
}
public static void addTaming(Player player, int xp) {
if (canHook) {
McMMOHandler.addTaming(player, xp);
}
}
public static void addUnarmed(Player player, int xp) {
if (canHook) {
McMMOHandler.addUnarmed(player, xp);
}
}
public static void addWoodcutting(Player player, int xp) {
if (canHook) {
McMMOHandler.addWoodcutting(player, xp);
}
}
public static boolean hasHerbalismDoubleDrops(Player player) {
return canHook ? McMMOHandler.hasHerbalismDoubleDrops(player) : false;
}
public static boolean hasMiningDoubleDrops(Player player) {
return canHook ? McMMOHandler.hasMiningDoubleDrops(player) : false;
}
public static boolean hasWoodcuttingDoubleDrops(Player player) {
return canHook ? McMMOHandler.hasWoodcuttingDoubleDrops(player) : false;
}
public static boolean isUsingBerserk(Player player) {
return canHook ? McMMOHandler.isUsingBerserk(player) : false;
}
public static boolean isUsingGigaDrill(Player player) {
return canHook ? McMMOHandler.isUsingGigaDrill(player) : false;
}
public static boolean isUsingGreenTerra(Player player) {
return canHook ? McMMOHandler.isUsingGreenTerra(player) : false;
}
public static boolean isUsingSerratedStrikes(Player player) {
return canHook ? McMMOHandler.isUsingSerratedStrikes(player) : false;
}
public static boolean isUsingSkullSplitter(Player player) {
return canHook ? McMMOHandler.isUsingSkullSplitter(player) : false;
}
public static boolean isUsingSuperBreaker(Player player) {
return canHook ? McMMOHandler.isUsingSuperBreaker(player) : false;
}
public static boolean isUsingTreeFeller(Player player) {
return canHook ? McMMOHandler.isUsingTreeFeller(player) : false;
}
public static boolean isBleeding(LivingEntity victim) {
return canHook ? McMMOHandler.isBleeding(victim) : false;
}
}
package com.songoda.core.hooks;
import com.songoda.core.hooks.mcmmo.McMMOHandler;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.util.Collection;
public class McMMOHook {
static boolean canHook = false;
static {
try {
// if this class exists, we're good to use McMMO
Class.forName("com.gmail.nossr50.api.AbilityAPI");
canHook = true;
} catch (ClassNotFoundException ex) {
}
}
public static void addMining(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addMining(player, blocks);
}
}
public static void addExcavation(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addExcavation(player, blocks);
}
}
public static void addHerbalism(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addHerbalism(player, blocks);
}
}
public static void addWoodcutting(Player player, Collection<Block> blocks) {
if (canHook) {
McMMOHandler.addWoodcutting(player, blocks);
}
}
public static int getAcrobaticsSkill(Player player) {
return canHook ? McMMOHandler.getAcrobaticsSkill(player) : -1;
}
public static int getAlchemySkill(Player player) {
return canHook ? McMMOHandler.getAlchemySkill(player) : -1;
}
public static int getArcherySkill(Player player) {
return canHook ? McMMOHandler.getArcherySkill(player) : -1;
}
public static int getAxesSkill(Player player) {
return canHook ? McMMOHandler.getAxesSkill(player) : -1;
}
public static int getExcavationSkill(Player player) {
return canHook ? McMMOHandler.getExcavationSkill(player) : -1;
}
public static int getFishingSkill(Player player) {
return canHook ? McMMOHandler.getFishingSkill(player) : -1;
}
public static int getHerbalismSkill(Player player) {
return canHook ? McMMOHandler.getHerbalismSkill(player) : -1;
}
public static int getMiningSkill(Player player) {
return canHook ? McMMOHandler.getMiningSkill(player) : -1;
}
public static int getRepairSkill(Player player) {
return canHook ? McMMOHandler.getRepairSkill(player) : -1;
}
public static int getSmeltingSkill(Player player) {
return canHook ? McMMOHandler.getSmeltingSkill(player) : -1;
}
public static int getSwordsSkill(Player player) {
return canHook ? McMMOHandler.getSwordsSkill(player) : -1;
}
public static int getTamingSkill(Player player) {
return canHook ? McMMOHandler.getTamingSkill(player) : -1;
}
public static int getUnarmedSkill(Player player) {
return canHook ? McMMOHandler.getUnarmedSkill(player) : -1;
}
public static int getWoodcuttingSkill(Player player) {
return canHook ? McMMOHandler.getWoodcuttingSkill(player) : -1;
}
public static void addAcrobatics(Player player, int xp) {
if (canHook) {
McMMOHandler.addAcrobatics(player, xp);
}
}
public static void addAlchemy(Player player, int xp) {
if (canHook) {
McMMOHandler.addAlchemy(player, xp);
}
}
public static void addArchery(Player player, int xp) {
if (canHook) {
McMMOHandler.addArchery(player, xp);
}
}
public static void addAxes(Player player, int xp) {
if (canHook) {
McMMOHandler.addAxes(player, xp);
}
}
public static void addExcavation(Player player, int xp) {
if (canHook) {
McMMOHandler.addExcavation(player, xp);
}
}
public static void addFishing(Player player, int xp) {
if (canHook) {
McMMOHandler.addFishing(player, xp);
}
}
public static void addHerbalism(Player player, int xp) {
if (canHook) {
McMMOHandler.addHerbalism(player, xp);
}
}
public static void addMining(Player player, int xp) {
if (canHook) {
McMMOHandler.addMining(player, xp);
}
}
public static void addRepair(Player player, int xp) {
if (canHook) {
McMMOHandler.addRepair(player, xp);
}
}
public static void addSmelting(Player player, int xp) {
if (canHook) {
McMMOHandler.addSmelting(player, xp);
}
}
public static void addSwords(Player player, int xp) {
if (canHook) {
McMMOHandler.addSwords(player, xp);
}
}
public static void addTaming(Player player, int xp) {
if (canHook) {
McMMOHandler.addTaming(player, xp);
}
}
public static void addUnarmed(Player player, int xp) {
if (canHook) {
McMMOHandler.addUnarmed(player, xp);
}
}
public static void addWoodcutting(Player player, int xp) {
if (canHook) {
McMMOHandler.addWoodcutting(player, xp);
}
}
public static boolean hasHerbalismDoubleDrops(Player player) {
return canHook ? McMMOHandler.hasHerbalismDoubleDrops(player) : false;
}
public static boolean hasMiningDoubleDrops(Player player) {
return canHook ? McMMOHandler.hasMiningDoubleDrops(player) : false;
}
public static boolean hasWoodcuttingDoubleDrops(Player player) {
return canHook ? McMMOHandler.hasWoodcuttingDoubleDrops(player) : false;
}
public static boolean isUsingBerserk(Player player) {
return canHook ? McMMOHandler.isUsingBerserk(player) : false;
}
public static boolean isUsingGigaDrill(Player player) {
return canHook ? McMMOHandler.isUsingGigaDrill(player) : false;
}
public static boolean isUsingGreenTerra(Player player) {
return canHook ? McMMOHandler.isUsingGreenTerra(player) : false;
}
public static boolean isUsingSerratedStrikes(Player player) {
return canHook ? McMMOHandler.isUsingSerratedStrikes(player) : false;
}
public static boolean isUsingSkullSplitter(Player player) {
return canHook ? McMMOHandler.isUsingSkullSplitter(player) : false;
}
public static boolean isUsingSuperBreaker(Player player) {
return canHook ? McMMOHandler.isUsingSuperBreaker(player) : false;
}
public static boolean isUsingTreeFeller(Player player) {
return canHook ? McMMOHandler.isUsingTreeFeller(player) : false;
}
public static boolean isBleeding(LivingEntity victim) {
return canHook ? McMMOHandler.isBleeding(victim) : false;
}
}

View File

@ -1,163 +1,169 @@
package com.songoda.core.hooks;
import com.songoda.core.hooks.economies.Economy;
import com.songoda.core.hooks.economies.PlayerPointsEconomy;
import com.songoda.core.hooks.economies.ReserveEconomy;
import com.songoda.core.hooks.economies.VaultEconomy;
import com.songoda.core.hooks.holograms.CMIHolograms;
import com.songoda.core.hooks.holograms.Holograms;
import com.songoda.core.hooks.holograms.HologramsHolograms;
import com.songoda.core.hooks.holograms.HolographicDisplaysHolograms;
import com.songoda.core.hooks.log.CoreProtectLog;
import com.songoda.core.hooks.log.Log;
import com.songoda.core.hooks.protection.*;
import com.songoda.core.hooks.stackers.StackMob;
import com.songoda.core.hooks.stackers.Stacker;
import com.songoda.core.hooks.stackers.UltimateStacker;
import com.songoda.core.hooks.stackers.WildStacker;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.stream.Collectors;
public final class PluginHook<T extends Class> {
public static final PluginHook ECO_VAULT = new PluginHook(Economy.class, "Vault", VaultEconomy.class);
public static final PluginHook ECO_PLAYER_POINTS = new PluginHook(Economy.class, "PlayerPoints", PlayerPointsEconomy.class);
public static final PluginHook ECO_RESERVE = new PluginHook(Economy.class, "Reserve", ReserveEconomy.class);
public static final PluginHook STACKER_ULTIMATE = new PluginHook(Stacker.class, "UltimateStacker", UltimateStacker.class);
public static final PluginHook STACKER_WILD = new PluginHook(Stacker.class, "WildStacker", WildStacker.class);
public static final PluginHook STACKER_STACK_MOB = new PluginHook(Stacker.class, "StackMob", StackMob.class);
public static final PluginHook HOLO_DISPLAYS = new PluginHook(Holograms.class, "HolographicDisplays", HolographicDisplaysHolograms.class);
public static final PluginHook HOLO_HOLOGRAMS = new PluginHook(Holograms.class, "Holograms", HologramsHolograms.class);
public static final PluginHook HOLO_CMI = new PluginHook(Holograms.class, "CMI", CMIHolograms.class);
public static final PluginHook LOG_CORE_PROTECT = new PluginHook(Log.class, "CoreProtect", CoreProtectLog.class);
public static final PluginHook PROTECTION_GRIEFPREVENTION = new PluginHook(Protection.class, "GriefPrevention", GriefPreventionProtection.class);
public static final PluginHook PROTECTION_LANDS = new PluginHook(Protection.class, "Lands", LandsProtection.class);
public static final PluginHook PROTECTION_REDPROTECT = new PluginHook(Protection.class, "RedProtect", RedProtectProtection.class);
public static final PluginHook PROTECTION_ULTIMATECLAIMS = new PluginHook(Protection.class, "UltimateClaims", UltimateClaimsProtection.class);
public static final PluginHook PROTECTION_BENTOBOX = new PluginHook(Protection.class, "BentoBox", BentoBoxProtection.class);
/******* Start Manager stuff *******/
protected final T hookGeneric;
protected final String plugin;
protected final Class managerClass;
protected static Map<Class, PluginHook> hooks;
protected Constructor pluginConstructor; // for passing the plugin loading the hook to the plugin hook
private PluginHook(T type, String pluginName, Class handler) {
if (!Hook.class.isAssignableFrom(handler)) {
throw new RuntimeException("Tried to register a non-Hook plugin hook! " + pluginName + " -> " + handler.getName());
}
this.hookGeneric = type;
this.plugin = pluginName;
this.managerClass = handler;
if (hooks == null) {
hooks = new LinkedHashMap();
}
hooks.put(handler, this);
// Does this class have a plugin constructor?
try {
pluginConstructor = handler.getDeclaredConstructor(Plugin.class);
} catch (NoSuchMethodException | SecurityException ex) {
// nope!
} catch (Throwable t) {
// (can also reach here if there is a class loader exception)
hooks.remove(handler);
}
}
/**
* Add a hook handler for us to use later. <br>
* NOTE: The class passed MUST extend Hook. <br>
* Permissible constructors are empty () or (org.bukkit.plugin.Plugin) <br>
* Each plugin defined must use a different handler class.
*
* @param <T>
* @param type Generic hook type for this plugin
* @param pluginName Plugin name
* @param handler Specific class that will handle this plugin, if enabled.
* @return instance of the PluginHook that was added
*/
public static <T extends Class> PluginHook addHook(T type, String pluginName, Class handler) {
return new PluginHook(type, pluginName, handler);
}
protected static Map<PluginHook, Hook> loadHooks(Class type, Plugin plugin) {
Map<PluginHook, Hook> loaded = new LinkedHashMap<>();
PluginManager pluginManager = Bukkit.getPluginManager();
for (PluginHook hook : getHooks(type)) {
if (pluginManager.isPluginEnabled(hook.plugin)) {
Hook handler = (Hook) (plugin != null ? hook.load(plugin) : hook.load());
if (handler != null && handler.isEnabled()) {
loaded.put(hook, handler);
}
}
}
return loaded;
}
protected static List<PluginHook> getHooks(Class type) {
return hooks.entrySet().parallelStream()
.filter(e -> e.getKey() == type || e.getValue().managerClass == type || type.isAssignableFrom(e.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}
public String getPluginName() {
return plugin;
}
protected Object load() {
try {
return managerClass.cast(
pluginConstructor != null
? pluginConstructor.newInstance((Plugin) null)
: managerClass.getConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
}
return null;
}
protected Object load(Plugin hookingPlugin) {
try {
return managerClass.cast(
pluginConstructor != null
? pluginConstructor.newInstance(hookingPlugin)
: managerClass.getConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
}
return null;
}
@Override
public int hashCode() {
int hash = 3;
hash = 37 * hash + Objects.hashCode(this.plugin);
hash = 37 * hash + Objects.hashCode(this.managerClass);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final PluginHook<?> other = (PluginHook<?>) obj;
return Objects.equals(this.plugin, other.plugin)
&& Objects.equals(this.managerClass, other.managerClass);
}
}
package com.songoda.core.hooks;
import com.songoda.core.hooks.economies.Economy;
import com.songoda.core.hooks.economies.PlayerPointsEconomy;
import com.songoda.core.hooks.economies.ReserveEconomy;
import com.songoda.core.hooks.economies.VaultEconomy;
import com.songoda.core.hooks.holograms.CMIHolograms;
import com.songoda.core.hooks.holograms.Holograms;
import com.songoda.core.hooks.holograms.HologramsHolograms;
import com.songoda.core.hooks.holograms.HolographicDisplaysHolograms;
import com.songoda.core.hooks.log.CoreProtectLog;
import com.songoda.core.hooks.log.Log;
import com.songoda.core.hooks.protection.BentoBoxProtection;
import com.songoda.core.hooks.protection.GriefPreventionProtection;
import com.songoda.core.hooks.protection.LandsProtection;
import com.songoda.core.hooks.protection.Protection;
import com.songoda.core.hooks.protection.RedProtectProtection;
import com.songoda.core.hooks.protection.UltimateClaimsProtection;
import com.songoda.core.hooks.stackers.StackMob;
import com.songoda.core.hooks.stackers.Stacker;
import com.songoda.core.hooks.stackers.UltimateStacker;
import com.songoda.core.hooks.stackers.WildStacker;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.stream.Collectors;
public final class PluginHook<T extends Class> {
public static final PluginHook ECO_VAULT = new PluginHook(Economy.class, "Vault", VaultEconomy.class);
public static final PluginHook ECO_PLAYER_POINTS = new PluginHook(Economy.class, "PlayerPoints", PlayerPointsEconomy.class);
public static final PluginHook ECO_RESERVE = new PluginHook(Economy.class, "Reserve", ReserveEconomy.class);
public static final PluginHook STACKER_ULTIMATE = new PluginHook(Stacker.class, "UltimateStacker", UltimateStacker.class);
public static final PluginHook STACKER_WILD = new PluginHook(Stacker.class, "WildStacker", WildStacker.class);
public static final PluginHook STACKER_STACK_MOB = new PluginHook(Stacker.class, "StackMob", StackMob.class);
public static final PluginHook HOLO_DISPLAYS = new PluginHook(Holograms.class, "HolographicDisplays", HolographicDisplaysHolograms.class);
public static final PluginHook HOLO_HOLOGRAMS = new PluginHook(Holograms.class, "Holograms", HologramsHolograms.class);
public static final PluginHook HOLO_CMI = new PluginHook(Holograms.class, "CMI", CMIHolograms.class);
public static final PluginHook LOG_CORE_PROTECT = new PluginHook(Log.class, "CoreProtect", CoreProtectLog.class);
public static final PluginHook PROTECTION_GRIEFPREVENTION = new PluginHook(Protection.class, "GriefPrevention", GriefPreventionProtection.class);
public static final PluginHook PROTECTION_LANDS = new PluginHook(Protection.class, "Lands", LandsProtection.class);
public static final PluginHook PROTECTION_REDPROTECT = new PluginHook(Protection.class, "RedProtect", RedProtectProtection.class);
public static final PluginHook PROTECTION_ULTIMATECLAIMS = new PluginHook(Protection.class, "UltimateClaims", UltimateClaimsProtection.class);
public static final PluginHook PROTECTION_BENTOBOX = new PluginHook(Protection.class, "BentoBox", BentoBoxProtection.class);
/******* Start Manager stuff *******/
protected final T hookGeneric;
protected final String plugin;
protected final Class managerClass;
protected static Map<Class, PluginHook> hooks;
protected Constructor pluginConstructor; // for passing the plugin loading the hook to the plugin hook
private PluginHook(T type, String pluginName, Class handler) {
if (!Hook.class.isAssignableFrom(handler)) {
throw new RuntimeException("Tried to register a non-Hook plugin hook! " + pluginName + " -> " + handler.getName());
}
this.hookGeneric = type;
this.plugin = pluginName;
this.managerClass = handler;
if (hooks == null) {
hooks = new LinkedHashMap();
}
hooks.put(handler, this);
// Does this class have a plugin constructor?
try {
pluginConstructor = handler.getDeclaredConstructor(Plugin.class);
} catch (NoSuchMethodException | SecurityException ex) {
// nope!
} catch (Throwable t) {
// (can also reach here if there is a class loader exception)
hooks.remove(handler);
}
}
/**
* Add a hook handler for us to use later. <br>
* NOTE: The class passed MUST extend Hook. <br>
* Permissible constructors are empty () or (org.bukkit.plugin.Plugin) <br>
* Each plugin defined must use a different handler class.
*
* @param <T>
* @param type Generic hook type for this plugin
* @param pluginName Plugin name
* @param handler Specific class that will handle this plugin, if enabled.
*
* @return instance of the PluginHook that was added
*/
public static <T extends Class> PluginHook addHook(T type, String pluginName, Class handler) {
return new PluginHook(type, pluginName, handler);
}
protected static Map<PluginHook, Hook> loadHooks(Class type, Plugin plugin) {
Map<PluginHook, Hook> loaded = new LinkedHashMap<>();
PluginManager pluginManager = Bukkit.getPluginManager();
for (PluginHook hook : getHooks(type)) {
if (pluginManager.isPluginEnabled(hook.plugin)) {
Hook handler = (Hook) (plugin != null ? hook.load(plugin) : hook.load());
if (handler != null && handler.isEnabled()) {
loaded.put(hook, handler);
}
}
}
return loaded;
}
protected static List<PluginHook> getHooks(Class type) {
return hooks.entrySet().parallelStream()
.filter(e -> e.getKey() == type || e.getValue().managerClass == type || type.isAssignableFrom(e.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}
public String getPluginName() {
return plugin;
}
protected Object load() {
try {
return managerClass.cast(
pluginConstructor != null
? pluginConstructor.newInstance((Plugin) null)
: managerClass.getConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
}
return null;
}
protected Object load(Plugin hookingPlugin) {
try {
return managerClass.cast(
pluginConstructor != null
? pluginConstructor.newInstance(hookingPlugin)
: managerClass.getConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
}
return null;
}
@Override
public int hashCode() {
int hash = 3;
hash = 37 * hash + Objects.hashCode(this.plugin);
hash = 37 * hash + Objects.hashCode(this.managerClass);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final PluginHook<?> other = (PluginHook<?>) obj;
return Objects.equals(this.plugin, other.plugin)
&& Objects.equals(this.managerClass, other.managerClass);
}
}

View File

@ -1,152 +1,162 @@
package com.songoda.core.hooks;
import com.songoda.core.hooks.worldguard.WorldGuardFlagHandler;
import com.songoda.core.hooks.worldguard.WorldGuardRegionHandler;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class WorldGuardHook {
static boolean canHook = false;
static {
try {
// if this class exists, we're good to use WG classes
Class.forName("com.sk89q.worldguard.protection.flags.Flag");
canHook = true;
} catch (ClassNotFoundException ex) {
}
}
/**
* Attempt to register a worldGuard flag (ALLOW/DENY) <br />
* Note: This must be called before WorldGuard loads, or it will fail.
*
* @param flag name of the flag to set
* @param state default value of the flag
*/
public static void addHook(@NotNull String flag, boolean state) {
if (canHook) {
WorldGuardFlagHandler.addHook(flag, state);
}
}
/**
* Check to see if WorldGuard is installed and hooked
*
* @return true if and only if WorldGuard exists and addHook() has been
* called and added successfully
*/
public static boolean isEnabled() {
return canHook && WorldGuardFlagHandler.isEnabled();
}
/**
* Checks this location to see what this flag is set to
*
* @param l location to check
* @param flag ALLOW/DENY flag to check
* @return flag state, or null if undefined
*/
@Nullable
public static Boolean getBooleanFlag(@NotNull Location l, @NotNull String flag) {
return canHook ? WorldGuardFlagHandler.getBooleanFlag(l, flag) : null;
}
/**
* Query all regions that are in or intersect this chunk
*
* @param c chunk to check for regions in
* @param flag ALLOW/DENY flag to check
* @return flag state, or null if undefined
*/
@Nullable
public static Boolean getBooleanFlag(@NotNull Chunk c, @NotNull String flag) {
return canHook ? WorldGuardFlagHandler.getBooleanFlag(c, flag) : null;
}
/**
* Check to see if the pvp flag is set and is set to ALLOW
*
* @param loc Location to check
* @return false if the pvp flag is not set for this region, or is set to DENY
*/
public static boolean isPvpAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "pvp"), Boolean.TRUE);
}
/**
* Check to see if the block-break flag is set and is set to ALLOW
*
* @param loc Location to check
* @return false if the block-break flag is not set for this region, or is set to DENY
*/
public static boolean isBreakAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "block-break"), Boolean.TRUE);
}
/**
* Check to see if the build flag is set and is set to ALLOW
*
* @param loc Location to check
* @return false if the build flag is not set for this region, or is set to DENY
*/
public static boolean isBuildAllowed(@NotNull Player player, @NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "build", player), Boolean.TRUE);
}
/**
* Check to see if the use flag is set and is set to ALLOW
*
* @param loc Location to check
* @return false if the use flag is not set for this region, or is set to DENY
*/
public static boolean isInteractAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "use"), Boolean.TRUE);
}
/**
* Check to see if the other-explosion flag is set and is set to ALLOW
*
* @param loc Location to check
* @return false if the other-explosion flag is not set for this region, or is set to DENY
*/
public static boolean isExplosionsAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "other-explosion"), Boolean.TRUE);
}
/**
* Check to see if the mob-spawning flag is set and is set to ALLOW
*
* @param loc Location to check
* @return false if the mob-spawning flag is not set for this region, or is set to DENY
*/
public static boolean isMobSpawningAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "mob-spawning"), Boolean.TRUE);
}
/**
* @param loc Location to check
* @return A list of regions that contain this location.
*/
@NotNull
public static List<String> getRegionNames(@NotNull Location loc) {
return canHook ? WorldGuardRegionHandler.getRegionNames(loc) : Collections.EMPTY_LIST;
}
/**
* @param c Chunk to check
* @return A list of regions that contain any part of this chunk.
*/
@NotNull
public static List<String> getRegionNames(@NotNull Chunk c) {
return canHook ? WorldGuardRegionHandler.getRegionNames(c) : Collections.EMPTY_LIST;
}
}
package com.songoda.core.hooks;
import com.songoda.core.hooks.worldguard.WorldGuardFlagHandler;
import com.songoda.core.hooks.worldguard.WorldGuardRegionHandler;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class WorldGuardHook {
static boolean canHook = false;
static {
try {
// if this class exists, we're good to use WG classes
Class.forName("com.sk89q.worldguard.protection.flags.Flag");
canHook = true;
} catch (ClassNotFoundException ex) {
}
}
/**
* Attempt to register a worldGuard flag (ALLOW/DENY) <br />
* Note: This must be called before WorldGuard loads, or it will fail.
*
* @param flag name of the flag to set
* @param state default value of the flag
*/
public static void addHook(@NotNull String flag, boolean state) {
if (canHook) {
WorldGuardFlagHandler.addHook(flag, state);
}
}
/**
* Check to see if WorldGuard is installed and hooked
*
* @return true if and only if WorldGuard exists and addHook() has been
* called and added successfully
*/
public static boolean isEnabled() {
return canHook && WorldGuardFlagHandler.isEnabled();
}
/**
* Checks this location to see what this flag is set to
*
* @param l location to check
* @param flag ALLOW/DENY flag to check
*
* @return flag state, or null if undefined
*/
@Nullable
public static Boolean getBooleanFlag(@NotNull Location l, @NotNull String flag) {
return canHook ? WorldGuardFlagHandler.getBooleanFlag(l, flag) : null;
}
/**
* Query all regions that are in or intersect this chunk
*
* @param c chunk to check for regions in
* @param flag ALLOW/DENY flag to check
*
* @return flag state, or null if undefined
*/
@Nullable
public static Boolean getBooleanFlag(@NotNull Chunk c, @NotNull String flag) {
return canHook ? WorldGuardFlagHandler.getBooleanFlag(c, flag) : null;
}
/**
* Check to see if the pvp flag is set and is set to ALLOW
*
* @param loc Location to check
*
* @return false if the pvp flag is not set for this region, or is set to DENY
*/
public static boolean isPvpAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "pvp"), Boolean.TRUE);
}
/**
* Check to see if the block-break flag is set and is set to ALLOW
*
* @param loc Location to check
*
* @return false if the block-break flag is not set for this region, or is set to DENY
*/
public static boolean isBreakAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "block-break"), Boolean.TRUE);
}
/**
* Check to see if the build flag is set and is set to ALLOW
*
* @param loc Location to check
*
* @return false if the build flag is not set for this region, or is set to DENY
*/
public static boolean isBuildAllowed(@NotNull Player player, @NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "build", player), Boolean.TRUE);
}
/**
* Check to see if the use flag is set and is set to ALLOW
*
* @param loc Location to check
*
* @return false if the use flag is not set for this region, or is set to DENY
*/
public static boolean isInteractAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "use"), Boolean.TRUE);
}
/**
* Check to see if the other-explosion flag is set and is set to ALLOW
*
* @param loc Location to check
*
* @return false if the other-explosion flag is not set for this region, or is set to DENY
*/
public static boolean isExplosionsAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "other-explosion"), Boolean.TRUE);
}
/**
* Check to see if the mob-spawning flag is set and is set to ALLOW
*
* @param loc Location to check
*
* @return false if the mob-spawning flag is not set for this region, or is set to DENY
*/
public static boolean isMobSpawningAllowed(@NotNull Location loc) {
return canHook && Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "mob-spawning"), Boolean.TRUE);
}
/**
* @param loc Location to check
*
* @return A list of regions that contain this location.
*/
@NotNull
public static List<String> getRegionNames(@NotNull Location loc) {
return canHook ? WorldGuardRegionHandler.getRegionNames(loc) : Collections.EMPTY_LIST;
}
/**
* @param c Chunk to check
*
* @return A list of regions that contain any part of this chunk.
*/
@NotNull
public static List<String> getRegionNames(@NotNull Chunk c) {
return canHook ? WorldGuardRegionHandler.getRegionNames(c) : Collections.EMPTY_LIST;
}
}

View File

@ -3,14 +3,13 @@ package com.songoda.core.hooks.economies;
import com.songoda.core.hooks.Hook;
import org.bukkit.OfflinePlayer;
import java.text.DecimalFormat;
public abstract class Economy implements Hook {
/**
* Get the players available balance
*
* @param player player
*
* @return the amount of available balance
*/
public abstract double getBalance(OfflinePlayer player);
@ -20,6 +19,7 @@ public abstract class Economy implements Hook {
*
* @param player player to check
* @param cost minimum amount this player should have
*
* @return true if this player can have this amount withdrawn
*/
public abstract boolean hasBalance(OfflinePlayer player, double cost);
@ -29,6 +29,7 @@ public abstract class Economy implements Hook {
*
* @param player player to check
* @param cost amount to remove from this player
*
* @return true if the total amount was withdrawn successfully
*/
public abstract boolean withdrawBalance(OfflinePlayer player, double cost);
@ -38,6 +39,7 @@ public abstract class Economy implements Hook {
*
* @param player player to check
* @param amount amount to add to this player
*
* @return true if the total amount was added successfully
*/
public abstract boolean deposit(OfflinePlayer player, double amount);

View File

@ -35,14 +35,12 @@ public class PlayerPointsEconomy extends Economy {
public boolean hasBalance(OfflinePlayer player, double cost) {
int amount = convertAmount(cost);
return playerPoints.getAPI().look(player.getUniqueId()) >= amount;
}
@Override
public boolean withdrawBalance(OfflinePlayer player, double cost) {
int amount = convertAmount(cost);
return playerPoints.getAPI().take(player.getUniqueId(), amount);
}
@Override

View File

@ -31,6 +31,7 @@ public abstract class Holograms implements Hook {
* Center and offset this location
*
* @param location location to offset
*
* @return copy-safe location with the applied offset.
*/
protected final Location fixLocation(Location location) {

View File

@ -2,7 +2,6 @@ package com.songoda.core.hooks.holograms;
import com.gmail.filoghost.holographicdisplays.api.Hologram;
import com.gmail.filoghost.holographicdisplays.api.HologramsAPI;
import com.gmail.filoghost.holographicdisplays.api.line.TextLine;
import org.bukkit.Location;
import org.bukkit.plugin.Plugin;

View File

@ -18,5 +18,4 @@ public abstract class Protection implements Hook {
public abstract boolean canBreak(Player player, Location location);
public abstract boolean canInteract(Player player, Location location);
}

View File

@ -78,5 +78,4 @@ public class StackMob extends Stacker {
public int getMinStackSize(EntityType type) {
return 0;
}
}

View File

@ -32,5 +32,4 @@ public abstract class Stacker implements Hook {
public abstract void add(LivingEntity entity, int amount);
public abstract int getMinStackSize(EntityType type);
}

View File

@ -1,7 +1,6 @@
package com.songoda.core.hooks.stackers;
import com.songoda.ultimatestacker.stackable.entity.EntityStack;
import com.songoda.ultimatestacker.stackable.entity.EntityStackManager;
import com.songoda.ultimatestacker.utils.Methods;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;

View File

@ -75,5 +75,4 @@ public class WildStacker extends Stacker {
}
return min == -1 ? 0 : min;
}
}

View File

@ -1,414 +1,413 @@
package com.songoda.core.hooks.worldguard;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitPlayer;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.RegionQuery;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.stream.Stream;
/**
* Hooks for adding a custom WorldGuard flag
* <p>
* Note: Hooks must be added before WG loads!
*/
public class WorldGuardFlagHandler {
static boolean wgPlugin;
static Object worldGuardPlugin;
static boolean wg_v7 = false;
static boolean legacy_v60 = false;
static boolean legacy_v62 = false;
static boolean legacy_v5 = false;
static boolean hooksInstalled = false;
static Map<String, Object> flags = new HashMap();
static {
if ((wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) {
// a number of flags were introduced in 7.x that aren't in 5 or 6
try {
// if this class exists, we're on 7.x
Class.forName("com.sk89q.worldguard.protection.flags.WeatherTypeFlag");
wg_v7 = true;
} catch (ClassNotFoundException ex) {
try {
// if this class exists, we're on 6.2
Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_v62 = true;
} catch (ClassNotFoundException ex2) {
try {
// if this class exists, we're on 6.0
Class.forName("com.sk89q.worldguard.protection.flags.BuildFlag");
legacy_v60 = true;
} catch (ClassNotFoundException ex3) {
try {
// if this class exists, we're on 5.x
Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
legacy_v5 = true;
} catch (ClassNotFoundException ex4) {
// ¯\_()_/¯
wgPlugin = false;
}
}
}
}
}
}
/**
* Attempt to register a worldGuard flag (ALLOW/DENY) <br />
* Note: This must be called before WorldGuard loads, or it will fail.
*
* @param flag name of the flag to set
* @param state default value of the flag
*/
public static void addHook(String flag, boolean state) {
if (!wgPlugin) {
return;
}
if (legacy_v62 || legacy_v60 || legacy_v5) {
addLegacyHook(flag, state);
return;
}
StateFlag addFlag = new StateFlag(flag, state);
try {
WorldGuard.getInstance().getFlagRegistry().register(addFlag);
flags.put(flag, addFlag);
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add flag {0} to WorldGuard", addFlag.getName());
Object wgFlag = WorldGuard.getInstance().getFlagRegistry().get(addFlag.getName());
if (wgFlag == null || !(wgFlag instanceof StateFlag)) {
wgPlugin = false;
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not hook WorldGuard");
} else {
flags.put(flag, wgFlag);
Bukkit.getServer().getLogger().log(Level.WARNING, "Loaded existing {1} {0}", new Object[]{((Flag) wgFlag).getName(), wgFlag.getClass().getSimpleName()});
}
}
}
// reflection to add hooks
private static void addLegacyHook(String flag, boolean state) {
try {
// 6.0 has the same classpath for StateFlag as the current version does
// does this flag exist already?
Class defaultFlagClazz = Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
Field flagField = defaultFlagClazz.getField("flagsList");
Flag<?>[] flagsOld = (Flag<?>[]) flagField.get(null);
Flag wgFlag = Stream.of(flagsOld)
.filter(f -> ((Flag<?>) f).getName().equalsIgnoreCase(flag))
.findFirst().orElse(null);
if (wgFlag != null) {
// we already have one
flags.put(flag, wgFlag);
Bukkit.getServer().getLogger().log(Level.WARNING, "Loaded existing {1} {0}", new Object[]{wgFlag.getName(), wgFlag.getClass().getSimpleName()});
return;
}
// if not, we need to add one
wgFlag = new StateFlag(flag, state);
// we need to sneak our flag into the array
// make a copy first
Flag<?>[] flagsNew = new Flag<?>[flagsOld.length + 1];
System.arraycopy(flagsOld, 0, flagsNew, 0, flagsOld.length);
// add ours
flagsNew[flagsNew.length - 1] = wgFlag;
// and put the new list into place
setStaticField(flagField, flagsNew);
if (legacy_v62) { // SimpleFlagRegistry is NOT in 6.0 or 6.1
// register this flag in the registry
if (legacy_simpleFlagRegistryClazz == null) {
legacy_worldGuardPlugin_flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry");
legacy_simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_simpleFlagRegistry_get = legacy_simpleFlagRegistryClazz.getDeclaredMethod("get", String.class);
}
legacy_simpleFlagRegistryClazz.getDeclaredMethod("register", Flag.class).invoke(legacy_worldGuardPlugin_flagRegistry, wgFlag);
}
// all good!
flags.put(flag, wgFlag);
} catch (Exception ex) {
//Bukkit.getServer().getLogger().log(Level.WARNING, "Failed to set legacy WorldGuard Flags", ex);
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add flag {0} to WorldGuard " + (legacy_v62 ? "6.2" : (legacy_v60 ? "6.0" : "5")), flag);
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not hook WorldGuard");
wgPlugin = false;
}
}
private static Object getPrivateField(Class<?> c, Object handle, String fieldName) throws Exception {
Field field = c.getDeclaredField(fieldName);
field.setAccessible(true); // This should be okay since it only runs on older versions.
return field.get(handle);
}
private static void setStaticField(Field field, Object value) throws Exception {
field.setAccessible(true); // This should be okay since it only runs on older versions.
Field modifier = Field.class.getDeclaredField("modifiers");
modifier.setAccessible(true); // This should be okay since it only runs on older versions.
modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, value);
}
public static boolean isEnabled() {
return wgPlugin;
}
public static Object getFlag(String flag) {
Object flagObj = flags.get(flag);
// load a flag if we don't know it
if (flagObj == null) {
if (wg_v7) {
flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag));
} else if (legacy_v62) {
try {
if (legacy_simpleFlagRegistryClazz == null) {
legacy_worldGuardPlugin_flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry");
legacy_simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_simpleFlagRegistry_get = legacy_simpleFlagRegistryClazz.getDeclaredMethod("get", String.class);
}
flags.put(flag, flagObj = legacy_simpleFlagRegistry_get.invoke(legacy_worldGuardPlugin_flagRegistry, flag));
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
} else if (!legacy_loadedFlags && (legacy_v60 || legacy_v5)) {
try {
Class defaultFlagClazz = Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
Field flagField = defaultFlagClazz.getField("flagsList");
Flag<?>[] flagsOld = (Flag<?>[]) flagField.get(null);
Stream.of(flagsOld).forEach(f -> flags.put(f.getName(), f));
flagObj = flags.get(flag);
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
legacy_loadedFlags = true;
}
}
return flagObj;
}
public static Boolean getBooleanFlag(Location loc, String flag) {
return getBooleanFlag(loc, flag, null);
}
/**
* Checks this location to see what this flag is set to
*
* @param loc location to check
* @param flag ALLOW/DENY flag to check
* @return flag state, or null if undefined
*/
public static Boolean getBooleanFlag(Location loc, String flag, Player optionalPlayer) {
if (!wgPlugin) {
return null;
}
LocalPlayer player = optionalPlayer != null ? WorldGuardPlugin.inst().wrapPlayer(optionalPlayer) : null;
Object flagObj = getFlag(flag);
// There's a different way to get this in the old version
if (legacy_v62 || legacy_v60 || legacy_v5) {
return flagObj == null ? null : getBooleanFlagLegacy(loc, flagObj);
}
// so, what's up?
if (flagObj instanceof StateFlag) {
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
State result = query.getApplicableRegions(BukkitAdapter.adapt(loc)).queryState(player, (StateFlag) flagObj);
return result != null ? result == State.ALLOW : null;
}
return null;
}
/**
* Query all regions that are in or intersect this chunk
*
* @param c chunk to check for regions in
* @param flag ALLOW/DENY flag to check
* @return flag state, or null if undefined
*/
public static Boolean getBooleanFlag(Chunk c, String flag) {
if (!wgPlugin) {
return null;
}
Object flagObj = getFlag(flag);
// There's a different way to get this in the old version
if (legacy_v62 || legacy_v60 || legacy_v5) {
return flagObj == null ? null : getBooleanFlagLegacy(c, flagObj);
}
// so, what's up?
if (flagObj instanceof StateFlag) {
RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld()));
if (worldManager == null) {
return null;
}
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("__TEST__",
BlockVector3.at(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
BlockVector3.at((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
ApplicableRegionSet set = worldManager.getApplicableRegions(chunkRegion);
State result = set.queryState((RegionAssociable) null, (StateFlag) flagObj);
if (result == null && set.size() == 0) {
return null;
}
return result == State.ALLOW;
}
return null;
}
static Method legacy_getRegionManager = null;
static Method legacy_getApplicableRegions_Region = null;
static Method legacy_getApplicableRegions_Location = null;
static Method legacy5_applicableRegionSet_getFlag = null;
static Constructor legacy_newProtectedCuboidRegion;
static Class legacy_blockVectorClazz;
static Constructor legacy_newblockVector;
static Class legacy_VectorClazz;
static Constructor legacy_newVectorClazz;
static Method legacy_getApplicableRegions_Vector = null;
static Class legacy_simpleFlagRegistryClazz = null; // only used for 6.2
static Method legacy_simpleFlagRegistry_get = null; // only used for 6.2
static Object legacy_worldGuardPlugin_flagRegistry = null; // only used for 6.2
static boolean legacy_loadedFlags = false;
private static Boolean getBooleanFlagLegacy(Location l, Object flag) {
try {
// cache reflection methods
if (legacy_getRegionManager == null) {
legacy_getRegionManager = worldGuardPlugin.getClass()
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Location.class);
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector");
legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class);
legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz);
}
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, l.getWorld());
if (worldManager == null) {
return null;
}
// create a vector object
Object vec = legacy_newVectorClazz.newInstance(l.getBlockX(), l.getBlockY(), l.getBlockZ());
// now look for any intersecting regions
Object set = legacy_getApplicableRegions_Vector.invoke(worldManager, legacy_VectorClazz.cast(vec));
// so what's the verdict?
State result;
if (legacy_v62 || legacy_v60) {
result = (State) ((ApplicableRegionSet) set).queryState((RegionAssociable) null, (StateFlag) flag);
} else {
// v5 has a different class signature for ApplicableRegionSet
// also doesn't have a "queryState" function
//getFlag(T flag)
if (legacy5_applicableRegionSet_getFlag == null) {
legacy5_applicableRegionSet_getFlag = Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").getMethod("getFlag", Flag.class);
}
result = (State) legacy5_applicableRegionSet_getFlag.invoke(set, flag);
}
if (result == null && set != null && ((Iterable) set).iterator().hasNext()) {
return null;
}
return result == State.ALLOW;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
return null;
}
private static Boolean getBooleanFlagLegacy(Chunk c, Object flag) {
// ApplicableRegionSet and RegionManager have the same classpath as the current version
// ProtectedCuboidRegion uses a different constructor, though
try {
// cache reflection methods
if (legacy_getRegionManager == null) {
legacy_getRegionManager = worldGuardPlugin.getClass()
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Location.class);
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector");
legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class);
legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz);
}
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, c.getWorld());
if (worldManager == null) {
return null;
}
// Create a legacy ProtectedCuboidRegion
Object chunkRegion = legacy_newProtectedCuboidRegion.newInstance("__TEST__",
legacy_newblockVector.newInstance(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
legacy_newblockVector.newInstance((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
// now look for any intersecting regions
Object set = legacy_getApplicableRegions_Region.invoke(worldManager, chunkRegion);
// so what's the verdict?
State result;
if (legacy_v62 || legacy_v60) {
result = (State) ((ApplicableRegionSet) set).queryState((RegionAssociable) null, (StateFlag) flag);
} else {
// v5 has a different class signature for ApplicableRegionSet
// also doesn't have a "queryState" function
//getFlag(T flag)
if (legacy5_applicableRegionSet_getFlag == null) {
legacy5_applicableRegionSet_getFlag = Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").getMethod("getFlag", Flag.class);
}
result = (State) legacy5_applicableRegionSet_getFlag.invoke(set, flag);
}
if (result == null && set != null && ((Iterable) set).iterator().hasNext()) {
return null;
}
return result == State.ALLOW;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
return null;
}
}
package com.songoda.core.hooks.worldguard;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.association.RegionAssociable;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.RegionQuery;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.stream.Stream;
/**
* Hooks for adding a custom WorldGuard flag
* <p>
* Note: Hooks must be added before WG loads!
*/
public class WorldGuardFlagHandler {
static boolean wgPlugin;
static Object worldGuardPlugin;
static boolean wg_v7 = false;
static boolean legacy_v60 = false;
static boolean legacy_v62 = false;
static boolean legacy_v5 = false;
static boolean hooksInstalled = false;
static Map<String, Object> flags = new HashMap();
static {
if ((wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) {
// a number of flags were introduced in 7.x that aren't in 5 or 6
try {
// if this class exists, we're on 7.x
Class.forName("com.sk89q.worldguard.protection.flags.WeatherTypeFlag");
wg_v7 = true;
} catch (ClassNotFoundException ex) {
try {
// if this class exists, we're on 6.2
Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_v62 = true;
} catch (ClassNotFoundException ex2) {
try {
// if this class exists, we're on 6.0
Class.forName("com.sk89q.worldguard.protection.flags.BuildFlag");
legacy_v60 = true;
} catch (ClassNotFoundException ex3) {
try {
// if this class exists, we're on 5.x
Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
legacy_v5 = true;
} catch (ClassNotFoundException ex4) {
// ¯\_()_/¯
wgPlugin = false;
}
}
}
}
}
}
/**
* Attempt to register a worldGuard flag (ALLOW/DENY) <br />
* Note: This must be called before WorldGuard loads, or it will fail.
*
* @param flag name of the flag to set
* @param state default value of the flag
*/
public static void addHook(String flag, boolean state) {
if (!wgPlugin) {
return;
}
if (legacy_v62 || legacy_v60 || legacy_v5) {
addLegacyHook(flag, state);
return;
}
StateFlag addFlag = new StateFlag(flag, state);
try {
WorldGuard.getInstance().getFlagRegistry().register(addFlag);
flags.put(flag, addFlag);
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add flag {0} to WorldGuard", addFlag.getName());
Object wgFlag = WorldGuard.getInstance().getFlagRegistry().get(addFlag.getName());
if (wgFlag == null || !(wgFlag instanceof StateFlag)) {
wgPlugin = false;
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not hook WorldGuard");
} else {
flags.put(flag, wgFlag);
Bukkit.getServer().getLogger().log(Level.WARNING, "Loaded existing {1} {0}", new Object[] {((Flag) wgFlag).getName(), wgFlag.getClass().getSimpleName()});
}
}
}
// reflection to add hooks
private static void addLegacyHook(String flag, boolean state) {
try {
// 6.0 has the same classpath for StateFlag as the current version does
// does this flag exist already?
Class defaultFlagClazz = Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
Field flagField = defaultFlagClazz.getField("flagsList");
Flag<?>[] flagsOld = (Flag<?>[]) flagField.get(null);
Flag wgFlag = Stream.of(flagsOld)
.filter(f -> ((Flag<?>) f).getName().equalsIgnoreCase(flag))
.findFirst().orElse(null);
if (wgFlag != null) {
// we already have one
flags.put(flag, wgFlag);
Bukkit.getServer().getLogger().log(Level.WARNING, "Loaded existing {1} {0}", new Object[] {wgFlag.getName(), wgFlag.getClass().getSimpleName()});
return;
}
// if not, we need to add one
wgFlag = new StateFlag(flag, state);
// we need to sneak our flag into the array
// make a copy first
Flag<?>[] flagsNew = new Flag<?>[flagsOld.length + 1];
System.arraycopy(flagsOld, 0, flagsNew, 0, flagsOld.length);
// add ours
flagsNew[flagsNew.length - 1] = wgFlag;
// and put the new list into place
setStaticField(flagField, flagsNew);
if (legacy_v62) { // SimpleFlagRegistry is NOT in 6.0 or 6.1
// register this flag in the registry
if (legacy_simpleFlagRegistryClazz == null) {
legacy_worldGuardPlugin_flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry");
legacy_simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_simpleFlagRegistry_get = legacy_simpleFlagRegistryClazz.getDeclaredMethod("get", String.class);
}
legacy_simpleFlagRegistryClazz.getDeclaredMethod("register", Flag.class).invoke(legacy_worldGuardPlugin_flagRegistry, wgFlag);
}
// all good!
flags.put(flag, wgFlag);
} catch (Exception ex) {
//Bukkit.getServer().getLogger().log(Level.WARNING, "Failed to set legacy WorldGuard Flags", ex);
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add flag {0} to WorldGuard " + (legacy_v62 ? "6.2" : (legacy_v60 ? "6.0" : "5")), flag);
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not hook WorldGuard");
wgPlugin = false;
}
}
private static Object getPrivateField(Class<?> c, Object handle, String fieldName) throws Exception {
Field field = c.getDeclaredField(fieldName);
field.setAccessible(true); // This should be okay since it only runs on older versions.
return field.get(handle);
}
private static void setStaticField(Field field, Object value) throws Exception {
field.setAccessible(true); // This should be okay since it only runs on older versions.
Field modifier = Field.class.getDeclaredField("modifiers");
modifier.setAccessible(true); // This should be okay since it only runs on older versions.
modifier.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, value);
}
public static boolean isEnabled() {
return wgPlugin;
}
public static Object getFlag(String flag) {
Object flagObj = flags.get(flag);
// load a flag if we don't know it
if (flagObj == null) {
if (wg_v7) {
flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag));
} else if (legacy_v62) {
try {
if (legacy_simpleFlagRegistryClazz == null) {
legacy_worldGuardPlugin_flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry");
legacy_simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_simpleFlagRegistry_get = legacy_simpleFlagRegistryClazz.getDeclaredMethod("get", String.class);
}
flags.put(flag, flagObj = legacy_simpleFlagRegistry_get.invoke(legacy_worldGuardPlugin_flagRegistry, flag));
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
} else if (!legacy_loadedFlags && (legacy_v60 || legacy_v5)) {
try {
Class defaultFlagClazz = Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
Field flagField = defaultFlagClazz.getField("flagsList");
Flag<?>[] flagsOld = (Flag<?>[]) flagField.get(null);
Stream.of(flagsOld).forEach(f -> flags.put(f.getName(), f));
flagObj = flags.get(flag);
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
legacy_loadedFlags = true;
}
}
return flagObj;
}
public static Boolean getBooleanFlag(Location loc, String flag) {
return getBooleanFlag(loc, flag, null);
}
/**
* Checks this location to see what this flag is set to
*
* @param loc location to check
* @param flag ALLOW/DENY flag to check
*
* @return flag state, or null if undefined
*/
public static Boolean getBooleanFlag(Location loc, String flag, Player optionalPlayer) {
if (!wgPlugin) {
return null;
}
LocalPlayer player = optionalPlayer != null ? WorldGuardPlugin.inst().wrapPlayer(optionalPlayer) : null;
Object flagObj = getFlag(flag);
// There's a different way to get this in the old version
if (legacy_v62 || legacy_v60 || legacy_v5) {
return flagObj == null ? null : getBooleanFlagLegacy(loc, flagObj);
}
// so, what's up?
if (flagObj instanceof StateFlag) {
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
State result = query.getApplicableRegions(BukkitAdapter.adapt(loc)).queryState(player, (StateFlag) flagObj);
return result != null ? result == State.ALLOW : null;
}
return null;
}
/**
* Query all regions that are in or intersect this chunk
*
* @param c chunk to check for regions in
* @param flag ALLOW/DENY flag to check
*
* @return flag state, or null if undefined
*/
public static Boolean getBooleanFlag(Chunk c, String flag) {
if (!wgPlugin) {
return null;
}
Object flagObj = getFlag(flag);
// There's a different way to get this in the old version
if (legacy_v62 || legacy_v60 || legacy_v5) {
return flagObj == null ? null : getBooleanFlagLegacy(c, flagObj);
}
// so, what's up?
if (flagObj instanceof StateFlag) {
RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld()));
if (worldManager == null) {
return null;
}
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("__TEST__",
BlockVector3.at(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
BlockVector3.at((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
ApplicableRegionSet set = worldManager.getApplicableRegions(chunkRegion);
State result = set.queryState((RegionAssociable) null, (StateFlag) flagObj);
if (result == null && set.size() == 0) {
return null;
}
return result == State.ALLOW;
}
return null;
}
static Method legacy_getRegionManager = null;
static Method legacy_getApplicableRegions_Region = null;
static Method legacy_getApplicableRegions_Location = null;
static Method legacy5_applicableRegionSet_getFlag = null;
static Constructor legacy_newProtectedCuboidRegion;
static Class legacy_blockVectorClazz;
static Constructor legacy_newblockVector;
static Class legacy_VectorClazz;
static Constructor legacy_newVectorClazz;
static Method legacy_getApplicableRegions_Vector = null;
static Class legacy_simpleFlagRegistryClazz = null; // only used for 6.2
static Method legacy_simpleFlagRegistry_get = null; // only used for 6.2
static Object legacy_worldGuardPlugin_flagRegistry = null; // only used for 6.2
static boolean legacy_loadedFlags = false;
private static Boolean getBooleanFlagLegacy(Location l, Object flag) {
try {
// cache reflection methods
if (legacy_getRegionManager == null) {
legacy_getRegionManager = worldGuardPlugin.getClass()
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Location.class);
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector");
legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class);
legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz);
}
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, l.getWorld());
if (worldManager == null) {
return null;
}
// create a vector object
Object vec = legacy_newVectorClazz.newInstance(l.getBlockX(), l.getBlockY(), l.getBlockZ());
// now look for any intersecting regions
Object set = legacy_getApplicableRegions_Vector.invoke(worldManager, legacy_VectorClazz.cast(vec));
// so what's the verdict?
State result;
if (legacy_v62 || legacy_v60) {
result = (State) ((ApplicableRegionSet) set).queryState((RegionAssociable) null, (StateFlag) flag);
} else {
// v5 has a different class signature for ApplicableRegionSet
// also doesn't have a "queryState" function
//getFlag(T flag)
if (legacy5_applicableRegionSet_getFlag == null) {
legacy5_applicableRegionSet_getFlag = Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").getMethod("getFlag", Flag.class);
}
result = (State) legacy5_applicableRegionSet_getFlag.invoke(set, flag);
}
if (result == null && set != null && ((Iterable) set).iterator().hasNext()) {
return null;
}
return result == State.ALLOW;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
return null;
}
private static Boolean getBooleanFlagLegacy(Chunk c, Object flag) {
// ApplicableRegionSet and RegionManager have the same classpath as the current version
// ProtectedCuboidRegion uses a different constructor, though
try {
// cache reflection methods
if (legacy_getRegionManager == null) {
legacy_getRegionManager = worldGuardPlugin.getClass()
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Location.class);
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector");
legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class);
legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz);
}
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, c.getWorld());
if (worldManager == null) {
return null;
}
// Create a legacy ProtectedCuboidRegion
Object chunkRegion = legacy_newProtectedCuboidRegion.newInstance("__TEST__",
legacy_newblockVector.newInstance(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
legacy_newblockVector.newInstance((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
// now look for any intersecting regions
Object set = legacy_getApplicableRegions_Region.invoke(worldManager, chunkRegion);
// so what's the verdict?
State result;
if (legacy_v62 || legacy_v60) {
result = (State) ((ApplicableRegionSet) set).queryState((RegionAssociable) null, (StateFlag) flag);
} else {
// v5 has a different class signature for ApplicableRegionSet
// also doesn't have a "queryState" function
//getFlag(T flag)
if (legacy5_applicableRegionSet_getFlag == null) {
legacy5_applicableRegionSet_getFlag = Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").getMethod("getFlag", Flag.class);
}
result = (State) legacy5_applicableRegionSet_getFlag.invoke(set, flag);
}
if (result == null && set != null && ((Iterable) set).iterator().hasNext()) {
return null;
}
return result == State.ALLOW;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex);
}
return null;
}
}

View File

@ -1,249 +1,248 @@
package com.songoda.core.hooks.worldguard;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
public class WorldGuardRegionHandler {
static boolean wgPlugin;
static Object worldGuardPlugin;
static boolean wg_v7 = false;
static boolean legacy_v60 = false;
static boolean legacy_v62 = false;
static boolean legacy_v5 = false;
static Method legacy_getRegionManager = null;
static Method legacy_getApplicableRegions_Region = null;
static Method legacy_getApplicableRegions_Location = null;
static Constructor legacy_newProtectedCuboidRegion;
static Class legacy_blockVectorClazz;
static Constructor legacy_newblockVector;
static Class legacy_VectorClazz;
static Constructor legacy_newVectorClazz;
static Method legacy_getApplicableRegions_Vector = null;
static void init() {
if ((wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) {
// a number of flags were introduced in 7.x that aren't in 5 or 6
try {
// if this class exists, we're on 7.x
Class.forName("com.sk89q.worldguard.protection.flags.WeatherTypeFlag");
wg_v7 = true;
} catch (ClassNotFoundException ex) {
try {
// if this class exists, we're on 6.2
Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_v62 = true;
} catch (ClassNotFoundException ex2) {
try {
// if this class exists, we're on 6.0
Class.forName("com.sk89q.worldguard.protection.flags.BuildFlag");
legacy_v60 = true;
} catch (ClassNotFoundException ex3) {
try {
// if this class exists, we're on 5.x
Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
legacy_v5 = true;
} catch (ClassNotFoundException ex4) {
// ¯\_()_/¯
wgPlugin = false;
}
}
}
}
}
if (wgPlugin && (legacy_v62 || legacy_v60 || legacy_v5)) {
try {
// cache reflection methods
if (legacy_getRegionManager == null) {
legacy_getRegionManager = worldGuardPlugin.getClass()
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Location.class);
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector");
legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class);
legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz);
}
} catch (Exception ex) {
//Bukkit.getServer().getLogger().log(Level.WARNING, "Failed to set legacy WorldGuard Flags", ex);
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not load WorldGuard methods for " + (legacy_v62 ? "6.2" : (legacy_v60 ? "6.0" : "5")));
wgPlugin = false;
}
}
}
public static List<String> getRegionNames(Chunk c) {
if (worldGuardPlugin == null) {
init();
}
if (!wgPlugin || c == null) {
return Collections.EMPTY_LIST;
} else if (legacy_v62 || legacy_v60 || legacy_v5) {
return getRegionNamesLegacy(c);
}
RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld()));
if (worldManager == null) {
return Collections.EMPTY_LIST;
}
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("__TEST__",
BlockVector3.at(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
BlockVector3.at((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
ApplicableRegionSet set = worldManager.getApplicableRegions(chunkRegion);
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
}
private static List<String> getRegionNamesLegacy(Chunk c) {
try {
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, c.getWorld());
if (worldManager == null) {
return null;
}
// Create a legacy ProtectedCuboidRegion
Object chunkRegion = legacy_newProtectedCuboidRegion.newInstance("__TEST__",
legacy_newblockVector.newInstance(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
legacy_newblockVector.newInstance((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
// now look for any intersecting regions
// ApplicableRegionSet's prototype is different from v5 to v6, but they're both Iterable
Iterable<ProtectedRegion> set = (Iterable<ProtectedRegion>) legacy_getApplicableRegions_Region.invoke(worldManager, chunkRegion);
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab regions from WorldGuard", ex);
}
return Collections.EMPTY_LIST;
}
public static List<String> getRegionNames(Location loc) {
if (worldGuardPlugin == null) {
init();
}
if (!wgPlugin || loc == null) {
return Collections.EMPTY_LIST;
} else if (legacy_v62 || legacy_v60 || legacy_v5) {
return getRegionNamesLegacy(loc);
}
RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
if (regionManager == null) {
return Collections.EMPTY_LIST;
}
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
ApplicableRegionSet set = regionManager.getApplicableRegions(BukkitAdapter.asBlockVector(loc));
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
}
private static List<String> getRegionNamesLegacy(Location loc) {
try {
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, loc.getWorld());
if (worldManager == null) {
return Collections.EMPTY_LIST;
}
// create a vector object
Object vec = legacy_newVectorClazz.newInstance(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
// now look for any intersecting regions
// ApplicableRegionSet's prototype is different from v5 to v6, but they're both Iterable
Iterable<ProtectedRegion> set = (Iterable<ProtectedRegion>) legacy_getApplicableRegions_Vector.invoke(worldManager, legacy_VectorClazz.cast(vec));
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab regions from WorldGuard", ex);
}
return Collections.EMPTY_LIST;
}
}
package com.songoda.core.hooks.worldguard;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
public class WorldGuardRegionHandler {
static boolean wgPlugin;
static Object worldGuardPlugin;
static boolean wg_v7 = false;
static boolean legacy_v60 = false;
static boolean legacy_v62 = false;
static boolean legacy_v5 = false;
static Method legacy_getRegionManager = null;
static Method legacy_getApplicableRegions_Region = null;
static Method legacy_getApplicableRegions_Location = null;
static Constructor legacy_newProtectedCuboidRegion;
static Class legacy_blockVectorClazz;
static Constructor legacy_newblockVector;
static Class legacy_VectorClazz;
static Constructor legacy_newVectorClazz;
static Method legacy_getApplicableRegions_Vector = null;
static void init() {
if ((wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) {
// a number of flags were introduced in 7.x that aren't in 5 or 6
try {
// if this class exists, we're on 7.x
Class.forName("com.sk89q.worldguard.protection.flags.WeatherTypeFlag");
wg_v7 = true;
} catch (ClassNotFoundException ex) {
try {
// if this class exists, we're on 6.2
Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry");
legacy_v62 = true;
} catch (ClassNotFoundException ex2) {
try {
// if this class exists, we're on 6.0
Class.forName("com.sk89q.worldguard.protection.flags.BuildFlag");
legacy_v60 = true;
} catch (ClassNotFoundException ex3) {
try {
// if this class exists, we're on 5.x
Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag");
legacy_v5 = true;
} catch (ClassNotFoundException ex4) {
// ¯\_()_/¯
wgPlugin = false;
}
}
}
}
}
if (wgPlugin && (legacy_v62 || legacy_v60 || legacy_v5)) {
try {
// cache reflection methods
if (legacy_getRegionManager == null) {
legacy_getRegionManager = worldGuardPlugin.getClass()
.getDeclaredMethod("getRegionManager", org.bukkit.World.class);
legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion"));
legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions",
Location.class);
legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector");
legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class);
legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion")
.getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz);
legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector");
legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class);
legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz);
}
} catch (Exception ex) {
//Bukkit.getServer().getLogger().log(Level.WARNING, "Failed to set legacy WorldGuard Flags", ex);
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not load WorldGuard methods for " + (legacy_v62 ? "6.2" : (legacy_v60 ? "6.0" : "5")));
wgPlugin = false;
}
}
}
public static List<String> getRegionNames(Chunk c) {
if (worldGuardPlugin == null) {
init();
}
if (!wgPlugin || c == null) {
return Collections.EMPTY_LIST;
} else if (legacy_v62 || legacy_v60 || legacy_v5) {
return getRegionNamesLegacy(c);
}
RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld()));
if (worldManager == null) {
return Collections.EMPTY_LIST;
}
ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("__TEST__",
BlockVector3.at(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
BlockVector3.at((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
ApplicableRegionSet set = worldManager.getApplicableRegions(chunkRegion);
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
}
private static List<String> getRegionNamesLegacy(Chunk c) {
try {
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, c.getWorld());
if (worldManager == null) {
return null;
}
// Create a legacy ProtectedCuboidRegion
Object chunkRegion = legacy_newProtectedCuboidRegion.newInstance("__TEST__",
legacy_newblockVector.newInstance(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4),
legacy_newblockVector.newInstance((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15));
// now look for any intersecting regions
// ApplicableRegionSet's prototype is different from v5 to v6, but they're both Iterable
Iterable<ProtectedRegion> set = (Iterable<ProtectedRegion>) legacy_getApplicableRegions_Region.invoke(worldManager, chunkRegion);
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab regions from WorldGuard", ex);
}
return Collections.EMPTY_LIST;
}
public static List<String> getRegionNames(Location loc) {
if (worldGuardPlugin == null) {
init();
}
if (!wgPlugin || loc == null) {
return Collections.EMPTY_LIST;
} else if (legacy_v62 || legacy_v60 || legacy_v5) {
return getRegionNamesLegacy(loc);
}
RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld()));
if (regionManager == null) {
return Collections.EMPTY_LIST;
}
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
ApplicableRegionSet set = regionManager.getApplicableRegions(BukkitAdapter.asBlockVector(loc));
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
}
private static List<String> getRegionNamesLegacy(Location loc) {
try {
// grab the applicable manager for this world
Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, loc.getWorld());
if (worldManager == null) {
return Collections.EMPTY_LIST;
}
// create a vector object
Object vec = legacy_newVectorClazz.newInstance(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
// now look for any intersecting regions
// ApplicableRegionSet's prototype is different from v5 to v6, but they're both Iterable
Iterable<ProtectedRegion> set = (Iterable<ProtectedRegion>) legacy_getApplicableRegions_Vector.invoke(worldManager, legacy_VectorClazz.cast(vec));
List<String> regions = new ArrayList<>();
List<String> parentNames = new ArrayList<>();
for (ProtectedRegion region : set) {
String id = region.getId();
regions.add(id);
ProtectedRegion parent = region.getParent();
while (parent != null) {
parentNames.add(parent.getId());
parent = parent.getParent();
}
}
regions.removeAll(parentNames);
return regions;
} catch (Exception ex) {
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab regions from WorldGuard", ex);
}
return Collections.EMPTY_LIST;
}
}

View File

@ -157,5 +157,4 @@ public class ChatPrompt implements Listener {
return message;
}
}
}

View File

@ -7,7 +7,16 @@ import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -55,6 +64,7 @@ public class Locale {
*
* @param plugin plugin to load from
* @param name name of the default locale, eg "en_US"
*
* @return returns the loaded Locale, or null if there was an error
*/
public static Locale loadDefaultLocale(JavaPlugin plugin, String name) {
@ -67,6 +77,7 @@ public class Locale {
*
* @param plugin plugin to load from
* @param name name of the locale, eg "en_US"
*
* @return returns the loaded Locale, or null if there was an error
*/
public static Locale loadLocale(JavaPlugin plugin, String name) {
@ -85,6 +96,7 @@ public class Locale {
* Load all locales from this plugin's locale directory
*
* @param plugin plugin to load from
*
* @return returns the loaded Locales
*/
public static List<Locale> loadAllLocales(JavaPlugin plugin) {
@ -130,6 +142,7 @@ public class Locale {
* @param plugin plugin owning the locale file
* @param locale the specific locale file to save
* @param fileName where to save the file
*
* @return true if the operation was successful, false otherwise
*/
public static boolean saveDefaultLocale(JavaPlugin plugin, String locale, String fileName) {
@ -142,6 +155,7 @@ public class Locale {
* @param plugin plugin owning the locale file
* @param in file to save
* @param fileName the name of the file to save
*
* @return true if the operation was successful, false otherwise
*/
public static boolean saveLocale(Plugin plugin, InputStream in, String fileName) {
@ -369,6 +383,7 @@ public class Locale {
* Supply the Message object with the plugins prefix.
*
* @param message message to be applied
*
* @return applied message
*/
private Message supplyPrefix(Message message) {
@ -379,6 +394,7 @@ public class Locale {
* Create a new unsaved Message
*
* @param message the message to create
*
* @return the created message
*/
public Message newMessage(String message) {
@ -389,6 +405,7 @@ public class Locale {
* Get a message set for a specific node.
*
* @param node the node to get
*
* @return the message for the specified node
*/
public Message getMessage(String node) {
@ -403,6 +420,7 @@ public class Locale {
*
* @param node the node to get
* @param defaultValue the default value given that a value for the node was not found
*
* @return the message for the specified node. Default if none found
*/
public Message getMessageOrDefault(String node, String defaultValue) {

View File

@ -157,6 +157,7 @@ public class Message {
*
* @param placeholder the placeholder to replace
* @param replacement the replacement object
*
* @return the modified Message
*/
public Message processPlaceholder(String placeholder, Object replacement) {
@ -179,4 +180,4 @@ public class Message {
public String toText() {
return this.message.toText();
}
}
}

View File

@ -4,8 +4,8 @@ import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.AnvilGui;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.core.lootables.loot.Loot;
import com.songoda.core.utils.TextUtils;
import java.util.ArrayList;
import java.util.Collections;
@ -16,7 +16,7 @@ public abstract class AbstractGuiListEditor extends Gui {
protected final Loot loot;
private final Gui returnGui;
public AbstractGuiListEditor(Loot loot ,Gui returnGui) {
public AbstractGuiListEditor(Loot loot, Gui returnGui) {
super(1, returnGui);
this.returnGui = returnGui;
this.loot = loot;
@ -27,19 +27,19 @@ public abstract class AbstractGuiListEditor extends Gui {
public void paint() {
List<String> lore = getData() == null ? new ArrayList<>() : getData();
setButton(2, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
TextUtils.formatText("&cBack")),
TextUtils.formatText("&cBack")),
(event) -> {
guiManager.showGUI(event.player, returnGui);
((GuiLootEditor) returnGui).paint();
});
setButton(6, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
TextUtils.formatText("&cBack")),
TextUtils.formatText("&cBack")),
(event) -> {
guiManager.showGUI(event.player, returnGui);
((GuiLootEditor) returnGui).paint();
});
setButton(3, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
TextUtils.formatText("&aAdd new line")),
TextUtils.formatText("&aAdd new line")),
(event -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e -> {
@ -62,7 +62,7 @@ public abstract class AbstractGuiListEditor extends Gui {
: TextUtils.formatText(lore)));
setButton(5, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
TextUtils.formatText("&cRemove the last line")),
TextUtils.formatText("&cRemove the last line")),
(event -> {
lore.remove(lore.size() - 1);
updateData(lore);

View File

@ -6,7 +6,6 @@ import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.lootables.loot.Loot;
import com.songoda.core.utils.TextUtils;
import com.songoda.core.lootables.loot.Loot;
import org.bukkit.enchantments.Enchantment;
import java.util.ArrayList;
@ -32,19 +31,19 @@ public class GuiEnchantEditor extends Gui {
public void paint() {
Map<String, Integer> lore = loot.getEnchants() == null ? new HashMap<>() : new HashMap<>(loot.getEnchants());
setButton(2, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
TextUtils.formatText("&cBack")),
TextUtils.formatText("&cBack")),
(event) -> {
guiManager.showGUI(event.player, returnGui);
((GuiLootEditor) returnGui).paint();
});
setButton(6, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
TextUtils.formatText("&cBack")),
TextUtils.formatText("&cBack")),
(event) -> {
guiManager.showGUI(event.player, returnGui);
((GuiLootEditor) returnGui).paint();
});
setButton(3, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
TextUtils.formatText("&aAdd new line")),
TextUtils.formatText("&aAdd new line")),
(event -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e -> {
@ -84,9 +83,9 @@ public class GuiEnchantEditor extends Gui {
? TextUtils.formatText(Collections.singletonList("&cNo enchantments set..."))
: TextUtils.formatText(enchantments)));
String lastFinal = last;
String lastFinal = last;
setButton(5, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
TextUtils.formatText("&cRemove the last line")),
TextUtils.formatText("&cRemove the last line")),
(event -> {
lore.remove(lastFinal);
loot.setEnchants(lore);

View File

@ -4,10 +4,10 @@ import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.AnvilGui;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.core.lootables.loot.Loot;
import com.songoda.core.lootables.loot.LootBuilder;
import com.songoda.core.lootables.loot.LootManager;
import com.songoda.core.utils.TextUtils;
import org.bukkit.entity.EntityType;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
@ -42,7 +42,7 @@ public class GuiLootEditor extends Gui {
setActionForRange(0, 0, 5, 9, null);
setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR,
TextUtils.formatText("&cBack")),
TextUtils.formatText("&cBack")),
(event) -> {
guiManager.showGUI(event.player, returnGui);
});
@ -60,7 +60,7 @@ public class GuiLootEditor extends Gui {
});
setButton(10, GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
TextUtils.formatText("&7Name Override: &6" + (loot.getName() == null ? "None set" : loot.getName()))),
TextUtils.formatText("&7Name Override: &6" + (loot.getName() == null ? "None set" : loot.getName()))),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e -> {
@ -73,8 +73,8 @@ public class GuiLootEditor extends Gui {
});
setButton(11, GuiUtils.createButtonItem(CompatibleMaterial.WRITABLE_BOOK,
TextUtils.formatText("&7Lore Override:"),
TextUtils.formatText(loot.getLore() == null ? Collections.singletonList("&6None set") : loot.getLore())),
TextUtils.formatText("&7Lore Override:"),
TextUtils.formatText(loot.getLore() == null ? Collections.singletonList("&6None set") : loot.getLore())),
(event) -> guiManager.showGUI(event.player, new GuiLoreEditor(loot, this)));
List<String> enchantments = new ArrayList<>();
@ -84,22 +84,22 @@ public class GuiLootEditor extends Gui {
enchantments.add("&6" + entry.getKey() + " " + entry.getValue());
setButton(12, GuiUtils.createButtonItem(CompatibleMaterial.ENCHANTED_BOOK,
TextUtils.formatText("&7Enchantments:"),
TextUtils.formatText(enchantments.isEmpty() ? Collections.singletonList("&6None set") : enchantments)),
TextUtils.formatText("&7Enchantments:"),
TextUtils.formatText(enchantments.isEmpty() ? Collections.singletonList("&6None set") : enchantments)),
(event) -> guiManager.showGUI(event.player, new GuiEnchantEditor(loot, this)));
setButton(13, GuiUtils.createButtonItem(
loot.getBurnedMaterial() == null
? CompatibleMaterial.FIRE_CHARGE
: loot.getBurnedMaterial(),
TextUtils.formatText("&7Current Burned Material: &6"
+ (loot.getBurnedMaterial() == null
? "None"
: loot.getBurnedMaterial().name())), TextUtils.formatText(
Arrays.asList("",
"&8Click to set the burned material to",
"&8the material in your hand.")
)),
loot.getBurnedMaterial() == null
? CompatibleMaterial.FIRE_CHARGE
: loot.getBurnedMaterial(),
TextUtils.formatText("&7Current Burned Material: &6"
+ (loot.getBurnedMaterial() == null
? "None"
: loot.getBurnedMaterial().name())), TextUtils.formatText(
Arrays.asList("",
"&8Click to set the burned material to",
"&8the material in your hand.")
)),
(event) -> {
ItemStack stack = event.player.getInventory().getItemInMainHand();
loot.setBurnedMaterial(CompatibleMaterial.getMaterial(stack));
@ -107,12 +107,12 @@ public class GuiLootEditor extends Gui {
});
setButton(14, GuiUtils.createButtonItem(CompatibleMaterial.CLOCK,
TextUtils.formatText("&7Chance: &6" + loot.getChance()),
TextUtils.formatText(
Arrays.asList("",
"&8Click to edit this loots",
"&8drop chance.")
)),
TextUtils.formatText("&7Chance: &6" + loot.getChance()),
TextUtils.formatText(
Arrays.asList("",
"&8Click to edit this loots",
"&8drop chance.")
)),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -126,7 +126,7 @@ public class GuiLootEditor extends Gui {
});
setButton(15, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE,
TextUtils.formatText("&7Min Drop Amount: &6" + loot.getMin())),
TextUtils.formatText("&7Min Drop Amount: &6" + loot.getMin())),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -140,7 +140,7 @@ public class GuiLootEditor extends Gui {
});
setButton(16, GuiUtils.createButtonItem(CompatibleMaterial.GLOWSTONE_DUST,
TextUtils.formatText("&7Max Drop Amount: &6" + loot.getMax())),
TextUtils.formatText("&7Max Drop Amount: &6" + loot.getMax())),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -154,7 +154,7 @@ public class GuiLootEditor extends Gui {
});
setButton(17, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE,
TextUtils.formatText("&7Min Item Damage: &6" + loot.getDamageMin())),
TextUtils.formatText("&7Min Item Damage: &6" + loot.getDamageMin())),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -168,7 +168,7 @@ public class GuiLootEditor extends Gui {
});
setButton(18, GuiUtils.createButtonItem(CompatibleMaterial.GLOWSTONE_DUST,
TextUtils.formatText("&7Max Item Damage: &6" + loot.getDamageMax())),
TextUtils.formatText("&7Max Item Damage: &6" + loot.getDamageMax())),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -182,7 +182,7 @@ public class GuiLootEditor extends Gui {
});
setButton(19, GuiUtils.createButtonItem(CompatibleMaterial.CHEST,
TextUtils.formatText("&7Allow Looting Enchantment?: &6" + loot.isAllowLootingEnchant())),
TextUtils.formatText("&7Allow Looting Enchantment?: &6" + loot.isAllowLootingEnchant())),
(event) -> {
loot.setAllowLootingEnchant(!loot.isAllowLootingEnchant());
paint();
@ -190,7 +190,7 @@ public class GuiLootEditor extends Gui {
});
setButton(20, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE,
TextUtils.formatText("&7Min Child Loot Min: &6" + loot.getChildDropCountMin())),
TextUtils.formatText("&7Min Child Loot Min: &6" + loot.getChildDropCountMin())),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -204,7 +204,7 @@ public class GuiLootEditor extends Gui {
});
setButton(21, GuiUtils.createButtonItem(CompatibleMaterial.GLOWSTONE_DUST,
TextUtils.formatText("&7Min Child Loot Max: &6" + loot.getChildDropCountMax())),
TextUtils.formatText("&7Min Child Loot Max: &6" + loot.getChildDropCountMax())),
(event) -> {
AnvilGui gui = new AnvilGui(event.player, this);
gui.setAction((e) -> {
@ -224,8 +224,8 @@ public class GuiLootEditor extends Gui {
entities.add("&6" + entity.name());
setButton(22, GuiUtils.createButtonItem(CompatibleMaterial.ENCHANTED_BOOK,
TextUtils.formatText("&7Only Drop For:"),
TextUtils.formatText(entities)),
TextUtils.formatText("&7Only Drop For:"),
TextUtils.formatText(entities)),
(event) -> guiManager.showGUI(event.player, new GuiEntityEditor(loot, this)));
setButton(4, 0, GuiUtils.createButtonItem(CompatibleMaterial.LIME_DYE, TextUtils.formatText("&aCreate new Child Loot")),

View File

@ -4,11 +4,11 @@ import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.AnvilGui;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.utils.TextUtils;
import com.songoda.core.lootables.loot.Loot;
import com.songoda.core.lootables.loot.LootBuilder;
import com.songoda.core.lootables.loot.LootManager;
import com.songoda.core.lootables.loot.Lootable;
import com.songoda.core.utils.TextUtils;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;

View File

@ -37,7 +37,7 @@ public class DropUtils {
commands.add(drop.getCommand());
if (drop.getXp() != 0)
xp.add(drop.getXp());
xp.add(drop.getXp());
}
event.getDrops().clear();
@ -65,5 +65,4 @@ public class DropUtils {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
}
}
}

View File

@ -161,7 +161,6 @@ public class Loot {
this.enchants = enchants;
}
public void setEnchantChances(Map<String, Double> enchants) {
this.enchantChances = enchants;
}

View File

@ -1,6 +1,5 @@
package com.songoda.core.lootables.loot;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.lootables.loot.objects.EnchantChance;
import org.bukkit.entity.EntityType;
@ -35,7 +34,7 @@ public final class LootBuilder {
public LootBuilder addEnchants(Tuple... tuples) {
Map<String, Integer> enchants = new HashMap<>();
for (Tuple tuple : tuples)
enchants.put((String)tuple.getKey(), (int)tuple.getValue());
enchants.put((String) tuple.getKey(), (int) tuple.getValue());
this.loot.setEnchants(enchants);
return this;
}
@ -118,7 +117,7 @@ public final class LootBuilder {
this.loot.setRequireCharged(require);
return this;
}
public Loot build() {
return this.loot;
}
@ -140,4 +139,4 @@ public final class LootBuilder {
return this.y;
}
}
}
}

View File

@ -140,7 +140,6 @@ public class LootManager {
addLootable(lootable);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
@ -164,7 +163,6 @@ public class LootManager {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(lootable, writer);
}
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -27,7 +27,7 @@ public class Eval {
public double parse() {
nextChar();
double x = parseExpression();
if (pos < toParse.length()) throw new RuntimeException(warningMessage + "Unexpected: " + (char)ch);
if (pos < toParse.length()) throw new RuntimeException(warningMessage + "Unexpected: " + (char) ch);
return x;
}
@ -39,8 +39,8 @@ public class Eval {
private double parseExpression() {
double x = parseTerm();
for (;;) {
if (eat('+')) x += parseTerm(); // addition
for (; ; ) {
if (eat('+')) x += parseTerm(); // addition
else if (eat('-')) x -= parseTerm(); // subtraction
else return x;
}
@ -48,8 +48,8 @@ public class Eval {
private double parseTerm() {
double x = parseFactor();
for (;;) {
if (eat('*')) x *= parseFactor(); // multiplication
for (; ; ) {
if (eat('*')) x *= parseFactor(); // multiplication
else if (eat('/')) x /= parseFactor(); // division
else return x;
}
@ -77,7 +77,7 @@ public class Eval {
else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
else throw new RuntimeException(warningMessage + "Unknown function: " + func);
} else {
throw new RuntimeException(warningMessage + "Unexpected: " + (char)ch);
throw new RuntimeException(warningMessage + "Unexpected: " + (char) ch);
}
if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation

File diff suppressed because it is too large Load Diff

View File

@ -1,341 +1,340 @@
package com.songoda.core.utils;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.AnaloguePowerable;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Powerable;
import org.bukkit.block.data.type.Door;
import org.bukkit.block.data.type.Gate;
import org.bukkit.block.data.type.Switch;
import org.bukkit.block.data.type.TrapDoor;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
public class BlockUtilsModern {
protected static void _updatePressurePlateModern(Block plate, int power) {
BlockData blockData = plate.getBlockData();
boolean update = false;
if (blockData instanceof AnaloguePowerable) {
AnaloguePowerable a = (AnaloguePowerable) blockData;
int toPower = Math.min(a.getMaximumPower(), power);
if ((update = toPower != a.getPower())) {
a.setPower(toPower);
plate.setBlockData(a);
}
} else if (blockData instanceof Powerable) {
Powerable p = (Powerable) blockData;
if ((update = p.isPowered() != (power != 0))) {
p.setPowered(power != 0);
plate.setBlockData(p);
}
}
if (update) {
_updateRedstoneNeighbours(plate);
}
}
protected static void _toggleLeverModern(Block lever) {
BlockData blockData = lever.getBlockData();
if (blockData instanceof Switch) {
Switch s = (Switch) blockData;
s.setPowered(!s.isPowered());
lever.setBlockData(s);
_updateRedstoneNeighbours(lever);
}
}
protected static void _pressButtonModern(Block button) {
BlockData blockData = button.getBlockData();
if (blockData instanceof Switch) {
Switch s = (Switch) blockData;
s.setPowered(true);
button.setBlockData(s);
_updateRedstoneNeighbours(button);
}
}
static void _releaseButtonModern(Block button) {
BlockData blockData = button.getBlockData();
if (blockData instanceof Switch) {
Switch s = (Switch) blockData;
s.setPowered(false);
button.setBlockData(s);
_updateRedstoneNeighbours(button);
}
}
private static Class<?> clazzCraftWorld;
private static Class<?> clazzCraftBlock;
private static Class<?> clazzLeverBlock;
private static Class<?> clazzButtonBlock;
private static Class<?> clazzPressurePlateBlock;
private static Method craftWorld_getHandle, craftBlock_getNMS, craftBlock_getPostition, craftBlockData_getState,
nmsLever_updateNeighbours, nmsButton_updateNeighbours, nmsPlate_updateNeighbours, nmsBlockData_getBlock;
static {
try {
// Cache reflection.
clazzCraftWorld = ClassMapping.CRAFT_WORLD.getClazz();
clazzCraftBlock = ClassMapping.CRAFT_BLOCK.getClazz();
craftWorld_getHandle = clazzCraftWorld.getMethod("getHandle");
craftBlock_getPostition = clazzCraftBlock.getDeclaredMethod("getPosition");
craftBlock_getNMS = clazzCraftBlock.getDeclaredMethod("getNMS");
Class<?> clazzBlockData = ClassMapping.BLOCK_BASE.getClazz("BlockData");
nmsBlockData_getBlock = clazzBlockData.getDeclaredMethod("getBlock");
Class<?> clazzCraftBlockData = ClassMapping.CRAFT_BLOCK_DATA.getClazz();
craftBlockData_getState = clazzCraftBlockData.getDeclaredMethod("getState");
Class<?> clazzWorld = ClassMapping.WORLD.getClazz();
Class<?> clazzBlockState = ClassMapping.I_BLOCK_DATA.getClazz();
Class<?> clazzBlockPos = ClassMapping.BLOCK_POSITION.getClazz();
clazzLeverBlock = ClassMapping.BLOCK_LEVER.getClazz();
clazzButtonBlock = ClassMapping.BLOCK_BUTTON_ABSTRACT.getClazz();
clazzPressurePlateBlock = ClassMapping.BLOCK_PRESSURE_PLATE_ABSTRACT.getClazz();
// nmsLever_updateNeighbours, nmsButton_updateNeighbours, nmsPlate_updateNeighbours
nmsLever_updateNeighbours = clazzLeverBlock.getDeclaredMethod(ServerVersion.isServerVersionAbove(ServerVersion.V1_13)
? "e" : "b", clazzBlockState, clazzWorld, clazzBlockPos);
nmsLever_updateNeighbours.setAccessible(true);
nmsButton_updateNeighbours = clazzButtonBlock.getDeclaredMethod(ServerVersion.isServerVersionAbove(ServerVersion.V1_13)
? "f" : "c", clazzBlockState, clazzWorld, clazzBlockPos);
nmsButton_updateNeighbours.setAccessible(true);
nmsPlate_updateNeighbours = clazzPressurePlateBlock.getDeclaredMethod("a", clazzWorld, clazzBlockPos);
nmsPlate_updateNeighbours.setAccessible(true);
} catch (Throwable ex) {
Logger.getLogger(BlockUtilsModern.class.getName()).log(Level.SEVERE, null, ex);
}
}
static void _updateRedstoneNeighbours(Block block) {
try {
// spigot made some changes to how data updates work in 1.13+
// updating the data value of a redstone power source
// does NOT update attatched block power,
// even if you update the block state. (Still broken last I checked in 1.15.2)
// so now we're going to manually call the updateNeighbours block method
// invoke and cast objects.
Object cworld = clazzCraftWorld.cast(block.getWorld());
Object mworld = craftWorld_getHandle.invoke(cworld);
Object cblock = clazzCraftBlock.cast(block);
Object mblock = nmsBlockData_getBlock.invoke(craftBlock_getNMS.invoke(cblock));
Object mpos = craftBlock_getPostition.invoke(cblock);
//System.out.println(mblock.getClass());
// now for testing stuff
if (clazzLeverBlock.isAssignableFrom(mblock.getClass())) {
final Object mstate = craftBlockData_getState.invoke(block.getBlockData());
nmsLever_updateNeighbours.invoke(mblock, mstate, mworld, mpos);
} else if (clazzButtonBlock.isAssignableFrom(mblock.getClass())) {
final Object mstate = craftBlockData_getState.invoke(block.getBlockData());
nmsButton_updateNeighbours.invoke(mblock, mstate, mworld, mpos);
} else if (clazzPressurePlateBlock.isAssignableFrom(mblock.getClass())) {
nmsPlate_updateNeighbours.invoke(mblock, mworld, mpos);
} else {
System.out.println("Unknown redstone: " + mblock.getClass().getName());
}
//
// if(mblock instanceof net.minecraft.server.v1_15_R1.BlockLever) {
// Method updateNeighbours = net.minecraft.server.v1_15_R1.BlockLever.class.getDeclaredMethod("e", net.minecraft.server.v1_15_R1.IBlockData.class, net.minecraft.server.v1_15_R1.World.class, net.minecraft.server.v1_15_R1.BlockPosition.class);
// updateNeighbours.setAccessible(true);
// // IBlockData = block state after being powered
//
// updateNeighbours.invoke(mblock,
// ((org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData) block.getBlockData()).getState(),
// mworld,
// mpos);
// } else if(mblock instanceof net.minecraft.server.v1_15_R1.BlockButtonAbstract) {
// Method updateNeighbours = net.minecraft.server.v1_15_R1.BlockButtonAbstract.class.getDeclaredMethod("f", net.minecraft.server.v1_15_R1.IBlockData.class, net.minecraft.server.v1_15_R1.World.class, net.minecraft.server.v1_15_R1.BlockPosition.class);
// updateNeighbours.setAccessible(true);
// // IBlockData = block state after being powered
//
// updateNeighbours.invoke(mblock,
// ((org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData) block.getBlockData()).getState(),
// mworld,
// mpos);
// } else if(mblock instanceof net.minecraft.server.v1_15_R1.BlockPressurePlateAbstract) {
// Method updateNeighbours = net.minecraft.server.v1_15_R1.BlockPressurePlateAbstract.class.getDeclaredMethod("a", net.minecraft.server.v1_15_R1.World.class, net.minecraft.server.v1_15_R1.BlockPosition.class);
// updateNeighbours.setAccessible(true);
// // IBlockData = block state after being powered
//
// updateNeighbours.invoke(mblock,
// mworld,
// mpos);
// }
} catch (Throwable ex) {
Logger.getLogger(BlockUtilsModern.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected static void _toggleDoorStatesModern(boolean allowDoorToOpen, Block... doors) {
for (Block door : doors) {
BlockData blockData;
if (door == null || !((blockData = door.getBlockData()) instanceof Door)) {
continue;
}
Door data = (Door) blockData;
if (!allowDoorToOpen && !data.isOpen()) {
continue;
}
// The lower half of the door contains the open/close state
if (data.getHalf() == Bisected.Half.TOP) {
Block lowerHalf = door.getRelative(BlockFace.DOWN);
if (lowerHalf.getBlockData() instanceof Door) {
Door lowerData = (Door) lowerHalf.getBlockData();
lowerData.setOpen(!data.isOpen());
lowerHalf.setBlockData(lowerData);
}
} else {
data.setOpen(!data.isOpen());
door.setBlockData(data);
}
// Play the door open/close sound
door.getWorld().playEffect(door.getLocation(), Effect.DOOR_TOGGLE, 0);
}
}
protected static Block _getDoubleDoorModern(Block block) {
BlockData bd = block.getBlockData();
Block door = null;
if (bd instanceof Door) {
final Door d = (Door) bd;
final BlockFace face = d.getFacing();
if (face.getModX() == 0) {
if (d.getHinge() == Door.Hinge.RIGHT) {
door = block.getRelative(face.getModZ(), 0, 0);
} else {
door = block.getRelative(-face.getModZ(), 0, 0);
}
} else {
if (d.getHinge() == Door.Hinge.RIGHT) {
door = block.getRelative(0, 0, -face.getModX());
} else {
door = block.getRelative(0, 0, face.getModX());
}
}
}
return door != null && door.getBlockData() instanceof Door
&& ((Door) door.getBlockData()).getHinge() != ((Door) bd).getHinge() ? door : null;
}
protected static BlockFace _getDoorClosedDirectionModern(Block door) {
if (BlockUtils.DOORS.contains(door.getType())) {
BlockData bd = door.getBlockData();
if (bd instanceof Door) {
Door d = (Door) bd;
// The lower half of the door contains the open/close state
if (d.getHalf() == Bisected.Half.TOP) {
door = door.getRelative(BlockFace.DOWN);
if (door.getBlockData() instanceof Door) {
d = (Door) door.getBlockData();
} else {
return null;
}
}
final BlockFace face = d.getFacing();
// now we /could/ also correct for the hinge (top block), it's not needed information
if (face.getModX() == 0) {
return d.isOpen() ? BlockFace.EAST : BlockFace.SOUTH;
} else {
return d.isOpen() ? BlockFace.SOUTH : BlockFace.EAST;
}
}
} else if (BlockUtils.FENCE_GATES.contains(door.getType())) {
BlockData bd = door.getBlockData();
if (bd instanceof Gate) {
Gate g = (Gate) bd;
final BlockFace face = g.getFacing();
if (face.getModX() == 0) {
return g.isOpen() ? BlockFace.EAST : BlockFace.SOUTH;
} else {
return g.isOpen() ? BlockFace.SOUTH : BlockFace.EAST;
}
}
} else if (BlockUtils.TRAP_DOORS.contains(door.getType())) {
BlockData bd = door.getBlockData();
if (bd instanceof TrapDoor) {
TrapDoor t = (TrapDoor) bd;
if (!t.isOpen()) {
return BlockFace.UP;
} else {
return t.getFacing();
}
}
}
return null;
}
protected static boolean _isCropFullyGrown(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
return ((Ageable) data).getAge() == ((Ageable) data).getMaximumAge();
}
return false;
}
protected static int _getMaxGrowthStage(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
return ((Ageable) data).getMaximumAge();
}
return -1;
}
protected static int _getMaxGrowthStage(Material material) {
BlockData data = material.createBlockData();
if (data instanceof Ageable) {
return ((Ageable) data).getMaximumAge();
}
return -1;
}
public static void _setGrowthStage(Block block, int stage) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
((Ageable) data).setAge(Math.max(0, Math.min(stage, ((Ageable) data).getMaximumAge())));
block.setBlockData(data);
}
}
public static void _incrementGrowthStage(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
final int max = ((Ageable) data).getMaximumAge();
final int age = ((Ageable) data).getAge();
if (age < max) {
((Ageable) data).setAge(age + 1);
block.setBlockData(data);
}
}
}
public static void _resetGrowthStage(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
((Ageable) data).setAge(0);
block.setBlockData(data);
}
}
}
package com.songoda.core.utils;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.ServerVersion;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.AnaloguePowerable;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Powerable;
import org.bukkit.block.data.type.Door;
import org.bukkit.block.data.type.Gate;
import org.bukkit.block.data.type.Switch;
import org.bukkit.block.data.type.TrapDoor;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
public class BlockUtilsModern {
protected static void _updatePressurePlateModern(Block plate, int power) {
BlockData blockData = plate.getBlockData();
boolean update = false;
if (blockData instanceof AnaloguePowerable) {
AnaloguePowerable a = (AnaloguePowerable) blockData;
int toPower = Math.min(a.getMaximumPower(), power);
if ((update = toPower != a.getPower())) {
a.setPower(toPower);
plate.setBlockData(a);
}
} else if (blockData instanceof Powerable) {
Powerable p = (Powerable) blockData;
if ((update = p.isPowered() != (power != 0))) {
p.setPowered(power != 0);
plate.setBlockData(p);
}
}
if (update) {
_updateRedstoneNeighbours(plate);
}
}
protected static void _toggleLeverModern(Block lever) {
BlockData blockData = lever.getBlockData();
if (blockData instanceof Switch) {
Switch s = (Switch) blockData;
s.setPowered(!s.isPowered());
lever.setBlockData(s);
_updateRedstoneNeighbours(lever);
}
}
protected static void _pressButtonModern(Block button) {
BlockData blockData = button.getBlockData();
if (blockData instanceof Switch) {
Switch s = (Switch) blockData;
s.setPowered(true);
button.setBlockData(s);
_updateRedstoneNeighbours(button);
}
}
static void _releaseButtonModern(Block button) {
BlockData blockData = button.getBlockData();
if (blockData instanceof Switch) {
Switch s = (Switch) blockData;
s.setPowered(false);
button.setBlockData(s);
_updateRedstoneNeighbours(button);
}
}
private static Class<?> clazzCraftWorld;
private static Class<?> clazzCraftBlock;
private static Class<?> clazzLeverBlock;
private static Class<?> clazzButtonBlock;
private static Class<?> clazzPressurePlateBlock;
private static Method craftWorld_getHandle, craftBlock_getNMS, craftBlock_getPostition, craftBlockData_getState,
nmsLever_updateNeighbours, nmsButton_updateNeighbours, nmsPlate_updateNeighbours, nmsBlockData_getBlock;
static {
try {
// Cache reflection.
clazzCraftWorld = ClassMapping.CRAFT_WORLD.getClazz();
clazzCraftBlock = ClassMapping.CRAFT_BLOCK.getClazz();
craftWorld_getHandle = clazzCraftWorld.getMethod("getHandle");
craftBlock_getPostition = clazzCraftBlock.getDeclaredMethod("getPosition");
craftBlock_getNMS = clazzCraftBlock.getDeclaredMethod("getNMS");
Class<?> clazzBlockData = ClassMapping.BLOCK_BASE.getClazz("BlockData");
nmsBlockData_getBlock = clazzBlockData.getDeclaredMethod("getBlock");
Class<?> clazzCraftBlockData = ClassMapping.CRAFT_BLOCK_DATA.getClazz();
craftBlockData_getState = clazzCraftBlockData.getDeclaredMethod("getState");
Class<?> clazzWorld = ClassMapping.WORLD.getClazz();
Class<?> clazzBlockState = ClassMapping.I_BLOCK_DATA.getClazz();
Class<?> clazzBlockPos = ClassMapping.BLOCK_POSITION.getClazz();
clazzLeverBlock = ClassMapping.BLOCK_LEVER.getClazz();
clazzButtonBlock = ClassMapping.BLOCK_BUTTON_ABSTRACT.getClazz();
clazzPressurePlateBlock = ClassMapping.BLOCK_PRESSURE_PLATE_ABSTRACT.getClazz();
// nmsLever_updateNeighbours, nmsButton_updateNeighbours, nmsPlate_updateNeighbours
nmsLever_updateNeighbours = clazzLeverBlock.getDeclaredMethod(ServerVersion.isServerVersionAbove(ServerVersion.V1_13)
? "e" : "b", clazzBlockState, clazzWorld, clazzBlockPos);
nmsLever_updateNeighbours.setAccessible(true);
nmsButton_updateNeighbours = clazzButtonBlock.getDeclaredMethod(ServerVersion.isServerVersionAbove(ServerVersion.V1_13)
? "f" : "c", clazzBlockState, clazzWorld, clazzBlockPos);
nmsButton_updateNeighbours.setAccessible(true);
nmsPlate_updateNeighbours = clazzPressurePlateBlock.getDeclaredMethod("a", clazzWorld, clazzBlockPos);
nmsPlate_updateNeighbours.setAccessible(true);
} catch (Throwable ex) {
Logger.getLogger(BlockUtilsModern.class.getName()).log(Level.SEVERE, null, ex);
}
}
static void _updateRedstoneNeighbours(Block block) {
try {
// spigot made some changes to how data updates work in 1.13+
// updating the data value of a redstone power source
// does NOT update attatched block power,
// even if you update the block state. (Still broken last I checked in 1.15.2)
// so now we're going to manually call the updateNeighbours block method
// invoke and cast objects.
Object cworld = clazzCraftWorld.cast(block.getWorld());
Object mworld = craftWorld_getHandle.invoke(cworld);
Object cblock = clazzCraftBlock.cast(block);
Object mblock = nmsBlockData_getBlock.invoke(craftBlock_getNMS.invoke(cblock));
Object mpos = craftBlock_getPostition.invoke(cblock);
//System.out.println(mblock.getClass());
// now for testing stuff
if (clazzLeverBlock.isAssignableFrom(mblock.getClass())) {
final Object mstate = craftBlockData_getState.invoke(block.getBlockData());
nmsLever_updateNeighbours.invoke(mblock, mstate, mworld, mpos);
} else if (clazzButtonBlock.isAssignableFrom(mblock.getClass())) {
final Object mstate = craftBlockData_getState.invoke(block.getBlockData());
nmsButton_updateNeighbours.invoke(mblock, mstate, mworld, mpos);
} else if (clazzPressurePlateBlock.isAssignableFrom(mblock.getClass())) {
nmsPlate_updateNeighbours.invoke(mblock, mworld, mpos);
} else {
System.out.println("Unknown redstone: " + mblock.getClass().getName());
}
//
// if(mblock instanceof net.minecraft.server.v1_15_R1.BlockLever) {
// Method updateNeighbours = net.minecraft.server.v1_15_R1.BlockLever.class.getDeclaredMethod("e", net.minecraft.server.v1_15_R1.IBlockData.class, net.minecraft.server.v1_15_R1.World.class, net.minecraft.server.v1_15_R1.BlockPosition.class);
// updateNeighbours.setAccessible(true);
// // IBlockData = block state after being powered
//
// updateNeighbours.invoke(mblock,
// ((org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData) block.getBlockData()).getState(),
// mworld,
// mpos);
// } else if(mblock instanceof net.minecraft.server.v1_15_R1.BlockButtonAbstract) {
// Method updateNeighbours = net.minecraft.server.v1_15_R1.BlockButtonAbstract.class.getDeclaredMethod("f", net.minecraft.server.v1_15_R1.IBlockData.class, net.minecraft.server.v1_15_R1.World.class, net.minecraft.server.v1_15_R1.BlockPosition.class);
// updateNeighbours.setAccessible(true);
// // IBlockData = block state after being powered
//
// updateNeighbours.invoke(mblock,
// ((org.bukkit.craftbukkit.v1_15_R1.block.data.CraftBlockData) block.getBlockData()).getState(),
// mworld,
// mpos);
// } else if(mblock instanceof net.minecraft.server.v1_15_R1.BlockPressurePlateAbstract) {
// Method updateNeighbours = net.minecraft.server.v1_15_R1.BlockPressurePlateAbstract.class.getDeclaredMethod("a", net.minecraft.server.v1_15_R1.World.class, net.minecraft.server.v1_15_R1.BlockPosition.class);
// updateNeighbours.setAccessible(true);
// // IBlockData = block state after being powered
//
// updateNeighbours.invoke(mblock,
// mworld,
// mpos);
// }
} catch (Throwable ex) {
Logger.getLogger(BlockUtilsModern.class.getName()).log(Level.SEVERE, null, ex);
}
}
protected static void _toggleDoorStatesModern(boolean allowDoorToOpen, Block... doors) {
for (Block door : doors) {
BlockData blockData;
if (door == null || !((blockData = door.getBlockData()) instanceof Door)) {
continue;
}
Door data = (Door) blockData;
if (!allowDoorToOpen && !data.isOpen()) {
continue;
}
// The lower half of the door contains the open/close state
if (data.getHalf() == Bisected.Half.TOP) {
Block lowerHalf = door.getRelative(BlockFace.DOWN);
if (lowerHalf.getBlockData() instanceof Door) {
Door lowerData = (Door) lowerHalf.getBlockData();
lowerData.setOpen(!data.isOpen());
lowerHalf.setBlockData(lowerData);
}
} else {
data.setOpen(!data.isOpen());
door.setBlockData(data);
}
// Play the door open/close sound
door.getWorld().playEffect(door.getLocation(), Effect.DOOR_TOGGLE, 0);
}
}
protected static Block _getDoubleDoorModern(Block block) {
BlockData bd = block.getBlockData();
Block door = null;
if (bd instanceof Door) {
final Door d = (Door) bd;
final BlockFace face = d.getFacing();
if (face.getModX() == 0) {
if (d.getHinge() == Door.Hinge.RIGHT) {
door = block.getRelative(face.getModZ(), 0, 0);
} else {
door = block.getRelative(-face.getModZ(), 0, 0);
}
} else {
if (d.getHinge() == Door.Hinge.RIGHT) {
door = block.getRelative(0, 0, -face.getModX());
} else {
door = block.getRelative(0, 0, face.getModX());
}
}
}
return door != null && door.getBlockData() instanceof Door
&& ((Door) door.getBlockData()).getHinge() != ((Door) bd).getHinge() ? door : null;
}
protected static BlockFace _getDoorClosedDirectionModern(Block door) {
if (BlockUtils.DOORS.contains(door.getType())) {
BlockData bd = door.getBlockData();
if (bd instanceof Door) {
Door d = (Door) bd;
// The lower half of the door contains the open/close state
if (d.getHalf() == Bisected.Half.TOP) {
door = door.getRelative(BlockFace.DOWN);
if (door.getBlockData() instanceof Door) {
d = (Door) door.getBlockData();
} else {
return null;
}
}
final BlockFace face = d.getFacing();
// now we /could/ also correct for the hinge (top block), it's not needed information
if (face.getModX() == 0) {
return d.isOpen() ? BlockFace.EAST : BlockFace.SOUTH;
} else {
return d.isOpen() ? BlockFace.SOUTH : BlockFace.EAST;
}
}
} else if (BlockUtils.FENCE_GATES.contains(door.getType())) {
BlockData bd = door.getBlockData();
if (bd instanceof Gate) {
Gate g = (Gate) bd;
final BlockFace face = g.getFacing();
if (face.getModX() == 0) {
return g.isOpen() ? BlockFace.EAST : BlockFace.SOUTH;
} else {
return g.isOpen() ? BlockFace.SOUTH : BlockFace.EAST;
}
}
} else if (BlockUtils.TRAP_DOORS.contains(door.getType())) {
BlockData bd = door.getBlockData();
if (bd instanceof TrapDoor) {
TrapDoor t = (TrapDoor) bd;
if (!t.isOpen()) {
return BlockFace.UP;
} else {
return t.getFacing();
}
}
}
return null;
}
protected static boolean _isCropFullyGrown(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
return ((Ageable) data).getAge() == ((Ageable) data).getMaximumAge();
}
return false;
}
protected static int _getMaxGrowthStage(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
return ((Ageable) data).getMaximumAge();
}
return -1;
}
protected static int _getMaxGrowthStage(Material material) {
BlockData data = material.createBlockData();
if (data instanceof Ageable) {
return ((Ageable) data).getMaximumAge();
}
return -1;
}
public static void _setGrowthStage(Block block, int stage) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
((Ageable) data).setAge(Math.max(0, Math.min(stage, ((Ageable) data).getMaximumAge())));
block.setBlockData(data);
}
}
public static void _incrementGrowthStage(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
final int max = ((Ageable) data).getMaximumAge();
final int age = ((Ageable) data).getAge();
if (age < max) {
((Ageable) data).setAge(age + 1);
block.setBlockData(data);
}
}
}
public static void _resetGrowthStage(Block block) {
BlockData data = block.getBlockData();
if (data instanceof Ageable) {
((Ageable) data).setAge(0);
block.setBlockData(data);
}
}
}

View File

@ -51,7 +51,6 @@ public class ColorUtils {
public B getBlue() {
return blue;
}
}
public static ColorCode fromRGB(int r, int g, int b) {
@ -64,5 +63,4 @@ public class ColorUtils {
});
return closest.firstEntry().getValue();
}
}
}

View File

@ -1,7 +1,7 @@
package com.songoda.core.utils;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.CompatibleMaterial;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;

View File

@ -20,6 +20,7 @@ public class ItemSerializer {
* A method to serialize an {@link ItemStack} list to Base64 String.
*
* @param items to turn into a Base64 String.
*
* @return Base64 string of the items.
*/
public static String toBase64(List<ItemStack> items) {
@ -48,6 +49,7 @@ public class ItemSerializer {
* Gets a list of ItemStacks from Base64 string.
*
* @param data Base64 string to convert to ItemStack list.
*
* @return ItemStack array created from the Base64 string.
*/
public static List<ItemStack> fromBase64(String data) {
@ -72,7 +74,9 @@ public class ItemSerializer {
/**
* Deserialize a byte array into an ItemStack.
*
* @param data Data to deserialize.
*
* @return Deserialized ItemStack.
*/
public static ItemStack deserializeItem(byte[] data) {
@ -88,7 +92,9 @@ public class ItemSerializer {
/**
* Serialize an ItemStack into a byte array.
*
* @param item Item to serialize.
*
* @return Serialized data.
*/
public static byte[] serializeItem(ItemStack item) {

File diff suppressed because it is too large Load Diff

View File

@ -21,5 +21,4 @@ public class LocationUtils {
l.getY() >= y1 && l.getY() <= y2 &&
l.getZ() >= z1 && l.getZ() <= z2;
}
}

View File

@ -45,8 +45,8 @@ public class Metrics {
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
final String defaultPackage = new String(
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
final String examplePackage = new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
@ -316,6 +316,7 @@ public class Metrics {
*
* @param plugin Any plugin. It's just used to get a logger instance.
* @param data The data to send.
*
* @throws Exception If the request failed.
*/
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
@ -367,7 +368,9 @@ public class Metrics {
* Gzips the given String.
*
* @param str The string to gzip.
*
* @return The gzipped String.
*
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
@ -421,7 +424,6 @@ public class Metrics {
}
protected abstract JSONObject getChartData() throws Exception;
}
/**
@ -577,7 +579,6 @@ public class Metrics {
data.put("value", value);
return data;
}
}
/**
@ -622,7 +623,6 @@ public class Metrics {
data.put("values", values);
return data;
}
}
/**
@ -660,7 +660,6 @@ public class Metrics {
data.put("values", values);
return data;
}
}
/**
@ -710,5 +709,4 @@ public class Metrics {
return data;
}
}
}
}

View File

@ -24,7 +24,7 @@ public class NumberUtils {
if (count < 1000) return String.valueOf(count);
int exp = (int) (Math.log(count) / Math.log(1000));
return String.format("%.1f%c", count / Math.pow(1000, exp),
"kMGTPE".charAt(exp-1)).replace(".0", "");
"kMGTPE".charAt(exp - 1)).replace(".0", "");
}
public static boolean isInt(String number) {
@ -43,5 +43,4 @@ public class NumberUtils {
return false;
return s.matches("[-+]?\\d*\\.?\\d+");
}
}

View File

@ -1,230 +1,236 @@
package com.songoda.core.utils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
public class PlayerUtils {
static Random random = new Random();
public static void sendMessages(Player player, String... messages) {
for (String message : messages)
player.sendMessage(message);
}
public static void sendMessages(Player player, List<String> messages) {
for (String message : messages)
player.sendMessage(message);
}
/**
* Get a list of all of the players that this player can "see"
*
* @param sender user to check against, or null for all players
* @param startingWith optional query to test: only players whose game names
* start with this
* @return list of player names that are "visible" to the player
*/
public static List<String> getVisiblePlayerNames(CommandSender sender, String startingWith) {
Player player = sender instanceof Player ? (Player) sender : null;
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> p != player)
.filter(p -> startsWith == null || p.getName().toLowerCase().startsWith(startsWith))
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
.map(Player::getName)
.collect(Collectors.toList());
}
/**
* Get a list of all of the players that this player can "see"
*
* @param sender user to check against, or null for all players
* @param startingWith optional query to test: only players whose game names
* start with this
* @return list of player names that are "visible" to the player
*/
public static List<String> getVisiblePlayerDisplayNames(CommandSender sender, String startingWith) {
Player player = sender instanceof Player ? (Player) sender : null;
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.replaceAll("[^a-zA-Z]", "").toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> p != player)
.filter(p -> startsWith == null || p.getDisplayName().replaceAll("[^a-zA-Z]", "").toLowerCase().startsWith(startsWith))
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
.map(Player::getDisplayName)
.collect(Collectors.toList());
}
/**
* Get a list of all of the players that this player can "see"
*
* @param sender user to check against, or null for all players
* @param startingWith optional query to test: only players whose game names
* start with this
* @return list of players that are "visible" to the player
*/
public static List<Player> getVisiblePlayers(CommandSender sender, String startingWith) {
Player player = sender instanceof Player ? (Player) sender : null;
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> p != player)
.filter(p -> startsWith == null || p.getName().toLowerCase().startsWith(startsWith))
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
.map(p -> (Player) p)
.collect(Collectors.toList());
}
/**
* Get a list of all online player names that start with a string.
*
* @param us Ourselves / who is requesting the list. Will not return this player.
* @param startsWith All names returned must start with this input string
* @return List of matching player IGN
*/
public static List<String> getAllPlayers(CommandSender us, String startsWith) {
final String arg = startsWith.toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> us != p && p.getName().startsWith(arg))
.map(Player::getName)
.collect(Collectors.toList());
}
/**
* Get a list of all online player names that start with a string.
*
* @param us Ourselves / who is requesting the list. Will not return this player.
* @param startsWith All names returned must start with this input string
* @return List of matching player display names
*/
public static List<String> getAllPlayersDisplay(CommandSender us, String startsWith) {
final String arg = startsWith.replaceAll("[^a-zA-Z]", "").toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> us != p && p.getDisplayName().replaceAll("[^a-zA-Z]", "").startsWith(arg))
.map(Player::getDisplayName)
.collect(Collectors.toList());
}
/**
* Search for and grab the closest match for a provided player name. <br />
* Also checks player display names if there is not an exact match.
*
* @param player player to search for
* @return Player that closest matches the input name, or null if none found
*/
public static Player findPlayer(String player) {
Player found = Bukkit.getServer().getPlayer(player);
if (found == null) {
final String searchName = player.toLowerCase();
final String searchDisplayName = player.replaceAll("[^a-zA-Z]", "").toLowerCase();
int d = 999;
for (Player p2 : Bukkit.getOnlinePlayers()) {
final String test;
if (p2.getName().toLowerCase().startsWith(searchName)) {
int d2 = p2.getName().length() - searchName.length();
if (d2 < d) {
found = p2;
d = d2;
} else if (d2 == d) {
found = null;
}
} else if ((test = p2.getDisplayName().replaceAll("[^a-zA-Z]", "")).toLowerCase().startsWith(searchDisplayName)) {
int d2 = test.length() - searchDisplayName.length();
if (d2 < d) {
found = p2;
d = d2;
} else if (d2 == d) {
found = null;
}
}
}
}
return found;
}
public static Player getRandomPlayer() {
final Collection<? extends Player> all = Bukkit.getOnlinePlayers();
final Iterator<? extends Player> alli = all.iterator();
int pick = random.nextInt(all.size());
for (; pick > 0; --pick) {
alli.next();
}
return alli.hasNext() ? alli.next() : null;
}
public static void giveItem(Player player, ItemStack item) {
if (player == null || !player.isOnline() || item == null) {
return;
}
Map<Integer, ItemStack> leftover = player.getInventory().addItem(item);
if (!leftover.isEmpty()) {
leftover.values().stream().forEach(it -> player.getWorld().dropItemNaturally(player.getLocation(), it));
}
}
public static void giveItem(Player player, ItemStack... items) {
if (player == null || !player.isOnline() || items == null || items.length == 0) {
return;
}
Map<Integer, ItemStack> leftover = player.getInventory().addItem(items);
if (!leftover.isEmpty()) {
final World world = player.getWorld();
final Location location = player.getLocation();
leftover.values().stream().forEach(it -> world.dropItemNaturally(location, it));
}
}
public static void giveItem(Player player, Collection<ItemStack> items) {
if (player == null || !player.isOnline() || items == null || items.isEmpty()) {
return;
}
Map<Integer, ItemStack> leftover = player.getInventory().addItem(items.toArray(new ItemStack[items.size()]));
if (!leftover.isEmpty()) {
final World world = player.getWorld();
final Location location = player.getLocation();
leftover.values().stream().forEach(it -> world.dropItemNaturally(location, it));
}
}
public static int getNumberFromPermission(Player player, String permission, int def) {
final Set<PermissionAttachmentInfo> permissions = player.getEffectivePermissions();
boolean set = false;
int highest = 0;
for (PermissionAttachmentInfo info : permissions) {
final String perm = info.getPermission();
if (!perm.startsWith(permission)) continue;
final int index = perm.lastIndexOf('.');
if (index == -1 || index == perm.length()) continue;
String numStr = perm.substring(perm.lastIndexOf('.') + 1);
if (numStr.equals("*")) return def;
final int number = Integer.parseInt(numStr);
if (number >= highest) {
highest = number;
set = true;
}
}
return set ? highest : def;
}
}
package com.songoda.core.utils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
public class PlayerUtils {
static Random random = new Random();
public static void sendMessages(Player player, String... messages) {
for (String message : messages)
player.sendMessage(message);
}
public static void sendMessages(Player player, List<String> messages) {
for (String message : messages)
player.sendMessage(message);
}
/**
* Get a list of all of the players that this player can "see"
*
* @param sender user to check against, or null for all players
* @param startingWith optional query to test: only players whose game names
* start with this
*
* @return list of player names that are "visible" to the player
*/
public static List<String> getVisiblePlayerNames(CommandSender sender, String startingWith) {
Player player = sender instanceof Player ? (Player) sender : null;
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> p != player)
.filter(p -> startsWith == null || p.getName().toLowerCase().startsWith(startsWith))
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
.map(Player::getName)
.collect(Collectors.toList());
}
/**
* Get a list of all of the players that this player can "see"
*
* @param sender user to check against, or null for all players
* @param startingWith optional query to test: only players whose game names
* start with this
*
* @return list of player names that are "visible" to the player
*/
public static List<String> getVisiblePlayerDisplayNames(CommandSender sender, String startingWith) {
Player player = sender instanceof Player ? (Player) sender : null;
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.replaceAll("[^a-zA-Z]", "").toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> p != player)
.filter(p -> startsWith == null || p.getDisplayName().replaceAll("[^a-zA-Z]", "").toLowerCase().startsWith(startsWith))
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
.map(Player::getDisplayName)
.collect(Collectors.toList());
}
/**
* Get a list of all of the players that this player can "see"
*
* @param sender user to check against, or null for all players
* @param startingWith optional query to test: only players whose game names
* start with this
*
* @return list of players that are "visible" to the player
*/
public static List<Player> getVisiblePlayers(CommandSender sender, String startingWith) {
Player player = sender instanceof Player ? (Player) sender : null;
final String startsWith = startingWith == null || startingWith.isEmpty() ? null : startingWith.toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> p != player)
.filter(p -> startsWith == null || p.getName().toLowerCase().startsWith(startsWith))
.filter(p -> player == null || (player.canSee(p) && p.getMetadata("vanished").isEmpty()))
.map(p -> (Player) p)
.collect(Collectors.toList());
}
/**
* Get a list of all online player names that start with a string.
*
* @param us Ourselves / who is requesting the list. Will not return this player.
* @param startsWith All names returned must start with this input string
*
* @return List of matching player IGN
*/
public static List<String> getAllPlayers(CommandSender us, String startsWith) {
final String arg = startsWith.toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> us != p && p.getName().startsWith(arg))
.map(Player::getName)
.collect(Collectors.toList());
}
/**
* Get a list of all online player names that start with a string.
*
* @param us Ourselves / who is requesting the list. Will not return this player.
* @param startsWith All names returned must start with this input string
*
* @return List of matching player display names
*/
public static List<String> getAllPlayersDisplay(CommandSender us, String startsWith) {
final String arg = startsWith.replaceAll("[^a-zA-Z]", "").toLowerCase();
return Bukkit.getOnlinePlayers().stream()
.filter(p -> us != p && p.getDisplayName().replaceAll("[^a-zA-Z]", "").startsWith(arg))
.map(Player::getDisplayName)
.collect(Collectors.toList());
}
/**
* Search for and grab the closest match for a provided player name. <br />
* Also checks player display names if there is not an exact match.
*
* @param player player to search for
*
* @return Player that closest matches the input name, or null if none found
*/
public static Player findPlayer(String player) {
Player found = Bukkit.getServer().getPlayer(player);
if (found == null) {
final String searchName = player.toLowerCase();
final String searchDisplayName = player.replaceAll("[^a-zA-Z]", "").toLowerCase();
int d = 999;
for (Player p2 : Bukkit.getOnlinePlayers()) {
final String test;
if (p2.getName().toLowerCase().startsWith(searchName)) {
int d2 = p2.getName().length() - searchName.length();
if (d2 < d) {
found = p2;
d = d2;
} else if (d2 == d) {
found = null;
}
} else if ((test = p2.getDisplayName().replaceAll("[^a-zA-Z]", "")).toLowerCase().startsWith(searchDisplayName)) {
int d2 = test.length() - searchDisplayName.length();
if (d2 < d) {
found = p2;
d = d2;
} else if (d2 == d) {
found = null;
}
}
}
}
return found;
}
public static Player getRandomPlayer() {
final Collection<? extends Player> all = Bukkit.getOnlinePlayers();
final Iterator<? extends Player> alli = all.iterator();
int pick = random.nextInt(all.size());
for (; pick > 0; --pick) {
alli.next();
}
return alli.hasNext() ? alli.next() : null;
}
public static void giveItem(Player player, ItemStack item) {
if (player == null || !player.isOnline() || item == null) {
return;
}
Map<Integer, ItemStack> leftover = player.getInventory().addItem(item);
if (!leftover.isEmpty()) {
leftover.values().stream().forEach(it -> player.getWorld().dropItemNaturally(player.getLocation(), it));
}
}
public static void giveItem(Player player, ItemStack... items) {
if (player == null || !player.isOnline() || items == null || items.length == 0) {
return;
}
Map<Integer, ItemStack> leftover = player.getInventory().addItem(items);
if (!leftover.isEmpty()) {
final World world = player.getWorld();
final Location location = player.getLocation();
leftover.values().stream().forEach(it -> world.dropItemNaturally(location, it));
}
}
public static void giveItem(Player player, Collection<ItemStack> items) {
if (player == null || !player.isOnline() || items == null || items.isEmpty()) {
return;
}
Map<Integer, ItemStack> leftover = player.getInventory().addItem(items.toArray(new ItemStack[items.size()]));
if (!leftover.isEmpty()) {
final World world = player.getWorld();
final Location location = player.getLocation();
leftover.values().stream().forEach(it -> world.dropItemNaturally(location, it));
}
}
public static int getNumberFromPermission(Player player, String permission, int def) {
final Set<PermissionAttachmentInfo> permissions = player.getEffectivePermissions();
boolean set = false;
int highest = 0;
for (PermissionAttachmentInfo info : permissions) {
final String perm = info.getPermission();
if (!perm.startsWith(permission)) continue;
final int index = perm.lastIndexOf('.');
if (index == -1 || index == perm.length()) continue;
String numStr = perm.substring(perm.lastIndexOf('.') + 1);
if (numStr.equals("*")) return def;
final int number = Integer.parseInt(numStr);
if (number >= highest) {
highest = number;
set = true;
}
}
return set ? highest : def;
}
}

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