mirror of
https://github.com/songoda/EpicAnchors.git
synced 2024-11-26 03:55:33 +01:00
Merge branch 'development'
This commit is contained in:
commit
c9405d3809
301
.editorconfig
301
.editorconfig
@ -1,3 +1,6 @@
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
@ -10,302 +13,14 @@ 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
|
||||
ij_formatter_tags_enabled = true
|
||||
|
||||
[*.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}]
|
||||
[{*.yaml,*.yml,*.json,*.graphqlconfig,*.har,*.jsb2,*.jsb3,*.webmanifest,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
|
||||
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}]
|
||||
|
||||
[{*.markdown,*.md,*.html,*.htm,*.ng,*.sht,*.shtm,*.shtml,*.ts,*.ats,*.js,*.cjs,*.bash,*.sh,*.zsh}]
|
||||
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
|
||||
tab_width = 2
|
||||
|
13
.github/FUNDING.yml
vendored
13
.github/FUNDING.yml
vendored
@ -1,12 +1 @@
|
||||
# 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']
|
||||
custom: [ 'https://craftaro.to/+' ]
|
||||
|
20
.github/dependabot.yml
vendored
20
.github/dependabot.yml
vendored
@ -1,18 +1,16 @@
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "maven"
|
||||
directory: "/"
|
||||
target-branch: "development"
|
||||
- package-ecosystem: maven
|
||||
directory: /
|
||||
target-branch: development
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
ignore:
|
||||
- dependency-name: "com.songoda:SongodaCore"
|
||||
interval: monthly
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
target-branch: "development"
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
target-branch: development
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
interval: monthly
|
||||
|
95
.github/workflows/build.yml
vendored
Normal file
95
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, development ]
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
env:
|
||||
DEPLOYMENT_POM_PATH: ./EpicAnchors-API/pom.xml
|
||||
DEPLOYMENT_ARTIFACT_DIR: ./EpicAnchors-API/target
|
||||
DEPLOYMENT_ARTIFACT_SELECTOR: EpicAnchors-API-*.jar
|
||||
PLUGIN_ARTIFACT_DIR: ./EpicAnchors-Plugin/target
|
||||
PLUGIN_ARTIFACT_SELECTOR: EpicAnchors-*.jar
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
name: Build + Deploy
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prepare Workspace
|
||||
uses: craftaro/GH-Commons/.github/actions/setup_workspace@master
|
||||
with:
|
||||
maven_username: ${{ secrets.PLUGINS_MAVEN_REPO_USERNAME }}
|
||||
maven_password: ${{ secrets.PLUGINS_MAVEN_REPO_PASSWORD }}
|
||||
|
||||
- name: Set project version
|
||||
uses: craftaro/GH-Commons/.github/actions/maven_set_project_version@master
|
||||
with:
|
||||
append_snapshot: ${{ github.ref_type == 'tag' && 'false' || 'true' }}
|
||||
version: ${{ github.ref_type == 'tag' && github.ref_name || '' }}
|
||||
increment_version: ${{ github.ref_type != 'tag' && 'patch' || '' }}
|
||||
increment_version_only_if_not_snapshot_version: ${{ github.ref == 'refs/heads/development' && 'true' || 'false' }}
|
||||
|
||||
- name: Build with Maven
|
||||
run: mvn -B -Duser.name="GitHub Actions on $GITHUB_REPOSITORY (id=$GITHUB_RUN_ID)" clean package
|
||||
|
||||
- name: Sign jar archives
|
||||
uses: craftaro/GH-Commons/.github/actions/sign_jars@master
|
||||
with:
|
||||
jar_file_selector: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}/${{ env.DEPLOYMENT_ARTIFACT_SELECTOR }}
|
||||
keystore_gpg_encrypted: ${{ secrets.PLUGINS_JARSIGNER_KEYSTORE_GPG }}
|
||||
keystore_gpg_password: ${{ secrets.PLUGINS_JARSIGNER_KEYSTORE_GPG_PASSWORD }}
|
||||
keystore_password: ${{ secrets.PLUGINS_JARSIGNER_KEYSTORE_PASSWORD }}
|
||||
|
||||
- name: Upload Build Artifacts [API]
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ github.event.repository.name }}-API
|
||||
path: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}/${{ env.DEPLOYMENT_ARTIFACT_SELECTOR }}
|
||||
|
||||
- name: Upload Build Artifacts [Plugin]
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ github.event.repository.name }}
|
||||
path: ${{ env.PLUGIN_ARTIFACT_DIR }}/${{ env.PLUGIN_ARTIFACT_SELECTOR }}
|
||||
|
||||
- name: Deploy to Maven repo
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: craftaro/GH-Commons/.github/actions/maven_deploy@master
|
||||
with:
|
||||
repository_url: ${{ vars.PLUGINS_MAVEN_REPO_URL_RELEASE }}
|
||||
repository_url_snapshots: ${{ vars.PLUGINS_MAVEN_REPO_URL_SNAPSHOT }}
|
||||
maven_pom_path: ${{ env.DEPLOYMENT_POM_PATH }}
|
||||
maven_out_dir: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}
|
||||
|
||||
- name: Deploy parent pom.xml to Maven repo
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: craftaro/GH-Commons/.github/actions/maven_deploy@master
|
||||
with:
|
||||
repository_url: ${{ vars.PLUGINS_MAVEN_REPO_URL_RELEASE }}
|
||||
repository_url_snapshots: ${{ vars.PLUGINS_MAVEN_REPO_URL_SNAPSHOT }}
|
||||
only_deploy_pom: true
|
||||
maven_out_dir: ${{ env.DEPLOYMENT_ARTIFACT_DIR }}
|
||||
|
||||
discord_webhook:
|
||||
name: Send Discord Webhook
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: [ Build ]
|
||||
if: ${{ always() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development' || github.ref_type == 'tag') }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Notify Webhook
|
||||
uses: craftaro/GH-Commons/.github/actions/discord_send_job_results@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
webhook_url: ${{ secrets.DISCORD_BUILD_STATUS_WEBHOOK }}
|
96
.github/workflows/maven.yml
vendored
96
.github/workflows/maven.yml
vendored
@ -1,96 +0,0 @@
|
||||
name: 'Build & Test'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, development ]
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Setup Java
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 16
|
||||
distribution: adopt
|
||||
|
||||
# Checkout project files
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Caches
|
||||
- name: 'Cache: Maven'
|
||||
uses: actions/cache@v3
|
||||
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: EpicAnchors-*.jar'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: EpicAnchors-artifacts
|
||||
path: ./target/EpicAnchors-*.jar
|
||||
|
||||
##
|
||||
# Discord Webhook
|
||||
# TODO: Extract into external Action for better re-usability (and readability) [Copied SongodaCore]
|
||||
##
|
||||
- name: 'Discord Webhook (Success)'
|
||||
if: ${{ success() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development') }}
|
||||
continue-on-error: true
|
||||
run: |
|
||||
curl -X POST --data "{\"content\":null,\"embeds\":[{\"title\":\"Build succeeded!\",\"description\":\"The build with the ID #$GITHUB_RUN_NUMBER has succeeded!\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"color\":5490477,\"fields\":[{\"name\":\"Branch\",\"value\":\"$GITHUB_REF\",\"inline\":true}],\"author\":{\"name\":\"$GITHUB_REPOSITORY\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY\",\"icon_url\":\"$GITHUB_SERVER_URL/songoda.png\"},\"footer\":{\"text\":\"Initiated by $GITHUB_ACTOR\",\"icon_url\":\"$GITHUB_SERVER_URL/$GITHUB_ACTOR.png\"}}],\"username\":\"OctoAgent\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/Octocat.png\"}" --header 'Content-Type: application/json' $DISCORD_WEBHOOK
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_BUILD_STATUS_WEBHOOK }}
|
||||
- name: 'Discord Webhook (Failure)'
|
||||
if: ${{ failure() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development') }}
|
||||
continue-on-error: true
|
||||
run: |
|
||||
curl -X POST --data "{\"content\":null,\"embeds\":[{\"title\":\"Build failed!\",\"description\":\"The build with the ID #$GITHUB_RUN_NUMBER has failed!\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"color\":15611419,\"fields\":[{\"name\":\"Branch\",\"value\":\"$GITHUB_REF\",\"inline\":true}],\"author\":{\"name\":\"$GITHUB_REPOSITORY\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY\",\"icon_url\":\"$GITHUB_SERVER_URL/songoda.png\"},\"footer\":{\"text\":\"Initiated by $GITHUB_ACTOR\",\"icon_url\":\"$GITHUB_SERVER_URL/$GITHUB_ACTOR.png\"}}],\"username\":\"OctoAgent\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/Octocat.png\"}" --header "Content-Type:application/json" $DISCORD_WEBHOOK
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_BUILD_STATUS_WEBHOOK }}
|
||||
|
||||
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Setup Java
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: adopt
|
||||
|
||||
# Checkout project files
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
# Caches
|
||||
- name: 'Cache: Maven'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
- name: 'Cache: SonarCloud'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
restore-keys: ${{ runner.os }}-sonar
|
||||
|
||||
# SonarCloud static analysis
|
||||
- name: SonarCloud
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
|
42
.github/workflows/sonarcloud.yml
vendored
Normal file
42
.github/workflows/sonarcloud.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: SonarCloud
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, development ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: read-all
|
||||
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_ORGANIZATION: craftaro
|
||||
SONAR_PROJECT_KEY: craftaro_EpicAnchors
|
||||
|
||||
jobs:
|
||||
Analyze:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare Workspace
|
||||
uses: craftaro/GH-Commons/.github/actions/setup_workspace@master
|
||||
|
||||
- name: 'Cache: SonarCloud'
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
|
||||
- name: Analyze project
|
||||
run: >
|
||||
mvn -B \
|
||||
verify \
|
||||
org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
|
||||
-Dsonar.host.url=https://sonarcloud.io \
|
||||
"-Dsonar.organization=$SONAR_ORGANIZATION" \
|
||||
"-Dsonar.projectKey=$SONAR_PROJECT_KEY"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,5 +1,10 @@
|
||||
/target/
|
||||
|
||||
# JetBrains IDEs
|
||||
## JetBrains IDEs
|
||||
/.idea/
|
||||
*.iml
|
||||
|
||||
## Maven
|
||||
/**/target/
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
## Misc.
|
||||
.DS_Store
|
||||
|
69
EpicAnchors-API/pom.xml
Normal file
69
EpicAnchors-API/pom.xml
Normal file
@ -0,0 +1,69 @@
|
||||
<?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.craftaro</groupId>
|
||||
<artifactId>EpicAnchors-Parent</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>EpicAnchors-API</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.6.3</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
<configuration>
|
||||
<doclint>all,-missing</doclint>
|
||||
<links>
|
||||
<link>https://hub.spigotmc.org/javadocs/spigot/</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.craftaro</groupId>
|
||||
<artifactId>CraftaroCore</artifactId>
|
||||
<version>${craftaro.coreVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,29 @@
|
||||
package com.craftaro.epicanchors;
|
||||
|
||||
import com.craftaro.epicanchors.api.AnchorManager;
|
||||
|
||||
public final class EpicAnchorsApi {
|
||||
private static EpicAnchorsApi instance;
|
||||
|
||||
private final AnchorManager anchorManager;
|
||||
|
||||
private EpicAnchorsApi(AnchorManager anchorManager) {
|
||||
this.anchorManager = anchorManager;
|
||||
}
|
||||
|
||||
public AnchorManager getAnchorManager() {
|
||||
return this.anchorManager;
|
||||
}
|
||||
|
||||
public static EpicAnchorsApi getApi() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void initApi(AnchorManager anchorManager) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("EpicAnchorsApi already initialized");
|
||||
}
|
||||
|
||||
instance = new EpicAnchorsApi(anchorManager);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.craftaro.epicanchors.api;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Anchor {
|
||||
int getDbId();
|
||||
|
||||
UUID getOwner();
|
||||
|
||||
boolean isLegacy();
|
||||
|
||||
@NotNull Location getLocation();
|
||||
|
||||
@NotNull World getWorld();
|
||||
|
||||
@NotNull Chunk getChunk();
|
||||
|
||||
int getTicksLeft();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
void setTicksLeft(int ticksLeft);
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
int addTicksLeft(int ticks);
|
||||
|
||||
int removeTicksLeft(int ticks);
|
||||
|
||||
boolean isInfinite();
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package com.songoda.epicanchors.api;
|
||||
package com.craftaro.epicanchors.api;
|
||||
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
@ -0,0 +1,88 @@
|
||||
package com.craftaro.epicanchors.api;
|
||||
|
||||
import com.craftaro.epicanchors.utils.Callback;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface AnchorManager {
|
||||
String NBT_TICKS_KEY = "EpicAnchors_Ticks".toLowerCase();
|
||||
|
||||
boolean isReady(World world);
|
||||
|
||||
Anchor[] getAnchors(@NotNull World world);
|
||||
|
||||
@Nullable Anchor getAnchor(@NotNull Block block);
|
||||
|
||||
boolean isAnchor(@NotNull Block block);
|
||||
|
||||
boolean hasAnchor(@NotNull Chunk chunk);
|
||||
|
||||
List<Anchor> searchAnchors(Location center, double searchRadius);
|
||||
|
||||
List<Anchor> searchAnchors(Location center, double searchRadius, boolean ignoreHeight);
|
||||
|
||||
/**
|
||||
* Creates a new anchor at a given location
|
||||
*
|
||||
* @param loc The block location for the anchor
|
||||
* @param ticks The amount of ticks the anchor lives or -1 for infinite
|
||||
*/
|
||||
void createAnchor(@NotNull Location loc, @NotNull UUID owner, int ticks, @Nullable Callback<Anchor> callback);
|
||||
|
||||
void destroyAnchor(@NotNull Anchor anchor);
|
||||
|
||||
void destroyAnchor(@NotNull Anchor anchor, boolean forceSkipItemDrop);
|
||||
|
||||
void registerAccessCheck(AnchorAccessCheck accessCheck);
|
||||
|
||||
/**
|
||||
* @param accessCheck The {@link AnchorAccessCheck} to remove
|
||||
* @return true if the {@link AnchorAccessCheck} has been found and removed, false otherwise
|
||||
*/
|
||||
boolean unregisterAccessCheck(AnchorAccessCheck accessCheck);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #hasAccess(Anchor, UUID)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasAccess(@NotNull Anchor anchor, @NotNull OfflinePlayer p);
|
||||
|
||||
/**
|
||||
* Checks if a player has access to an Anchor. By default, only the owner has access to an Anchor.
|
||||
* <br>
|
||||
* Other plugins can grant access to other players (e.g. friends).
|
||||
* <br>
|
||||
* Legacy anchors without an owner automatically grant access to all players.
|
||||
*
|
||||
* @return true if the player may access the Anchor, false otherwise
|
||||
* @see #registerAccessCheck(AnchorAccessCheck)
|
||||
*/
|
||||
boolean hasAccess(@NotNull Anchor anchor, @NotNull UUID uuid);
|
||||
|
||||
|
||||
ItemStack createAnchorItem(int ticks);
|
||||
|
||||
ItemStack createAnchorItem(int ticks, Material material);
|
||||
|
||||
ItemStack createAnchorItem(int ticks, XMaterial material);
|
||||
|
||||
boolean toggleChunkVisualized(Player p);
|
||||
|
||||
void setChunksVisualized(Player p, boolean visualize);
|
||||
|
||||
boolean hasChunksVisualized(Player p);
|
||||
|
||||
void updateHolograms(List<Anchor> anchors);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.songoda.epicanchors.utils;
|
||||
package com.craftaro.epicanchors.utils;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
109
EpicAnchors-Plugin/pom.xml
Normal file
109
EpicAnchors-Plugin/pom.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<?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.craftaro</groupId>
|
||||
<artifactId>EpicAnchors-Parent</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>EpicAnchors-Plugin</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.2</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
|
||||
<configuration>
|
||||
<finalName>${project.parent.name}-${project.version}</finalName>
|
||||
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<useDependencyReducedPomInJar>true</useDependencyReducedPomInJar>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>com.craftaro.core</pattern>
|
||||
<shadedPattern>com.craftaro.epicanchors.core</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
|
||||
<excludes>
|
||||
<exclude>META-INF/**</exclude>
|
||||
<exclude>LICENSE</exclude>
|
||||
<exclude>LICENSE.**</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<artifact>com.craftaro:CraftaroCore</artifact>
|
||||
<excludeDefaults>false</excludeDefaults>
|
||||
<includes>
|
||||
<include>**/nms/v*/**</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/third_party/org/apache/**</exclude>
|
||||
<exclude>**/third_party/net/kyori/**</exclude>
|
||||
<exclude>**/third_party/com/zaxxer/**</exclude>
|
||||
<exclude>**/third_party/org/jooq/**</exclude>
|
||||
<exclude>**/third_party/org/mariadb/**</exclude>
|
||||
<exclude>**/third_party/com/h2database/**</exclude>
|
||||
<exclude>**/third_party/org/h2/**</exclude>
|
||||
<exclude>**/third_party/com/cryptomorin/**</exclude>
|
||||
<exclude>**/third_party/org/reactivestreams/**</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.craftaro</groupId>
|
||||
<artifactId>EpicAnchors-API</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.craftaro</groupId>
|
||||
<artifactId>CraftaroCore</artifactId>
|
||||
<version>${craftaro.coreVersion}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,6 +1,7 @@
|
||||
package com.songoda.epicanchors;
|
||||
package com.craftaro.epicanchors;
|
||||
|
||||
import com.songoda.epicanchors.utils.WorldUtils;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.utils.WorldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -12,7 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Anchor {
|
||||
public class AnchorImpl implements Anchor {
|
||||
private final int dbId;
|
||||
|
||||
private final UUID owner;
|
||||
@ -20,7 +21,7 @@ public class Anchor {
|
||||
private final Location location;
|
||||
private int ticksLeft;
|
||||
|
||||
public Anchor(int dbId, @Nullable UUID owner, @NotNull Location location, int ticksLeft) {
|
||||
public AnchorImpl(int dbId, @Nullable UUID owner, @NotNull Location location, int ticksLeft) {
|
||||
if (dbId <= 0) throw new IllegalArgumentException("Invalid value for dbId");
|
||||
if (ticksLeft <= 0 && ticksLeft != -1) throw new IllegalArgumentException("Invalid value for ticksLeft");
|
||||
|
||||
@ -66,34 +67,42 @@ public class Anchor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDbId() {
|
||||
return this.dbId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLegacy() {
|
||||
return this.owner == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Location getLocation() {
|
||||
return this.location.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull World getWorld() {
|
||||
return this.location.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Chunk getChunk() {
|
||||
return this.location.getChunk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTicksLeft() {
|
||||
return this.ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unused")
|
||||
public void setTicksLeft(int ticksLeft) {
|
||||
if (ticksLeft < 0) throw new IllegalArgumentException("Invalid value for ticksLeft");
|
||||
@ -101,6 +110,7 @@ public class Anchor {
|
||||
this.ticksLeft = ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public int addTicksLeft(int ticks) {
|
||||
if (!isInfinite()) {
|
||||
@ -110,6 +120,7 @@ public class Anchor {
|
||||
return this.ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeTicksLeft(int ticks) {
|
||||
if (!isInfinite()) {
|
||||
this.ticksLeft -= ticks;
|
||||
@ -122,6 +133,7 @@ public class Anchor {
|
||||
return this.ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfinite() {
|
||||
return this.ticksLeft == -1;
|
||||
}
|
@ -1,19 +1,22 @@
|
||||
package com.songoda.epicanchors;
|
||||
package com.craftaro.epicanchors;
|
||||
|
||||
import com.songoda.core.SongodaPlugin;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.core.compatibility.CompatibleSound;
|
||||
import com.songoda.core.hooks.HologramManager;
|
||||
import com.songoda.core.third_party.de.tr7zw.nbtapi.NBTItem;
|
||||
import com.songoda.core.utils.TextUtils;
|
||||
import com.songoda.core.utils.TimeUtils;
|
||||
import com.songoda.epicanchors.api.AnchorAccessCheck;
|
||||
import com.songoda.epicanchors.files.DataManager;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
import com.songoda.epicanchors.utils.UpdateCallback;
|
||||
import com.songoda.epicanchors.utils.Utils;
|
||||
import com.craftaro.core.SongodaPlugin;
|
||||
import com.craftaro.core.compatibility.CompatibleMaterial;
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.core.hooks.HologramManager;
|
||||
import com.craftaro.core.third_party.de.tr7zw.nbtapi.NBTItem;
|
||||
import com.craftaro.core.utils.TextUtils;
|
||||
import com.craftaro.core.utils.TimeUtils;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.api.AnchorAccessCheck;
|
||||
import com.craftaro.epicanchors.api.AnchorManager;
|
||||
import com.craftaro.epicanchors.files.AnchorsDataManager;
|
||||
import com.craftaro.epicanchors.files.Settings;
|
||||
import com.craftaro.epicanchors.utils.Callback;
|
||||
import com.craftaro.epicanchors.utils.UpdateCallback;
|
||||
import com.craftaro.epicanchors.utils.Utils;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XSound;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -39,12 +42,12 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AnchorManager {
|
||||
public class AnchorManagerImpl implements AnchorManager {
|
||||
private static final String ERR_WORLD_NOT_READY = "EpicAnchors has not finished initializing that world yet";
|
||||
private static final String NBT_TICKS_KEY = "EpicAnchors_Ticks".toLowerCase();
|
||||
private static final String HOLOGRAM_PREFIX = "Anchor_";
|
||||
|
||||
private final SongodaPlugin plugin;
|
||||
private final DataManager dataManager;
|
||||
private final AnchorsDataManager dataManager;
|
||||
|
||||
private final Map<World, Set<Anchor>> anchors = new HashMap<>(3);
|
||||
private final Set<Player> visualizedChunk = new HashSet<>();
|
||||
@ -52,19 +55,19 @@ public class AnchorManager {
|
||||
|
||||
private boolean ready;
|
||||
|
||||
public AnchorManager(SongodaPlugin plugin, DataManager dataManager) {
|
||||
public AnchorManagerImpl(SongodaPlugin plugin, AnchorsDataManager dataManager) {
|
||||
this.plugin = Objects.requireNonNull(plugin);
|
||||
this.dataManager = Objects.requireNonNull(dataManager);
|
||||
}
|
||||
|
||||
protected void saveAll() {
|
||||
for (Set<Anchor> anchorSet : anchors.values()) {
|
||||
for (Set<Anchor> anchorSet : this.anchors.values()) {
|
||||
this.dataManager.updateAnchors(anchorSet, null);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deInitAll() {
|
||||
for (World world : anchors.keySet().toArray(new World[0])) {
|
||||
for (World world : this.anchors.keySet().toArray(new World[0])) {
|
||||
deInitAnchors(world);
|
||||
}
|
||||
}
|
||||
@ -82,12 +85,12 @@ public class AnchorManager {
|
||||
|
||||
this.dataManager.getAnchors(world, (ex, result) -> {
|
||||
if (ex == null) {
|
||||
this.anchors.computeIfAbsent(world, k -> new HashSet<>());
|
||||
this.anchors.computeIfAbsent(world, key -> new HashSet<>());
|
||||
|
||||
for (Anchor anchor : result) {
|
||||
anchor.init(this.plugin);
|
||||
((AnchorImpl) anchor).init(this.plugin);
|
||||
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), k -> new HashSet<>())
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), key -> new HashSet<>())
|
||||
.add(anchor);
|
||||
}
|
||||
|
||||
@ -102,7 +105,7 @@ public class AnchorManager {
|
||||
if (callback != null) {
|
||||
callback.accept(ex);
|
||||
} else {
|
||||
Utils.logException(this.plugin, ex, "SQLite");
|
||||
Utils.logException(this.plugin, ex, "H2");
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -115,7 +118,7 @@ public class AnchorManager {
|
||||
this.dataManager.updateAnchors(tmpAnchors, null);
|
||||
|
||||
for (Anchor anchor : tmpAnchors) {
|
||||
anchor.deInit(this.plugin);
|
||||
((AnchorImpl) anchor).deInit(this.plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,18 +126,19 @@ public class AnchorManager {
|
||||
protected void setReady() {
|
||||
this.ready = true;
|
||||
|
||||
Bukkit.getScheduler().runTaskTimer(plugin, this::saveAll, 20L * 60 * 5, 20L * 60 * 5);
|
||||
Bukkit.getScheduler().runTaskTimer(this.plugin, this::saveAll, 20L * 60 * 5, 20L * 60 * 5);
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
@Override
|
||||
public boolean isReady(World world) {
|
||||
return this.ready && anchors.containsKey(world);
|
||||
return this.ready && this.anchors.containsKey(world);
|
||||
}
|
||||
|
||||
/* Getter */
|
||||
|
||||
@Override
|
||||
public Anchor[] getAnchors(@NotNull World world) {
|
||||
Set<Anchor> set = anchors.get(world);
|
||||
Set<Anchor> set = this.anchors.get(world);
|
||||
|
||||
if (set != null) {
|
||||
return set.toArray(new Anchor[0]);
|
||||
@ -143,13 +147,14 @@ public class AnchorManager {
|
||||
return new Anchor[0];
|
||||
}
|
||||
|
||||
public @Nullable Anchor getAnchor(@NotNull Block b) {
|
||||
if (!isReady(b.getWorld())) {
|
||||
@Override
|
||||
public @Nullable Anchor getAnchor(@NotNull Block block) {
|
||||
if (!isReady(block.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
}
|
||||
|
||||
Location bLoc = b.getLocation();
|
||||
Set<Anchor> set = anchors.get(b.getWorld());
|
||||
Location bLoc = block.getLocation();
|
||||
Set<Anchor> set = this.anchors.get(block.getWorld());
|
||||
|
||||
if (set != null) {
|
||||
for (Anchor anchor : set) {
|
||||
@ -162,16 +167,18 @@ public class AnchorManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isAnchor(@NotNull Block b) {
|
||||
return getAnchor(b) != null;
|
||||
@Override
|
||||
public boolean isAnchor(@NotNull Block block) {
|
||||
return getAnchor(block) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnchor(@NotNull Chunk chunk) {
|
||||
if (!isReady(chunk.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
}
|
||||
|
||||
Set<Anchor> set = anchors.get(chunk.getWorld());
|
||||
Set<Anchor> set = this.anchors.get(chunk.getWorld());
|
||||
|
||||
if (set != null) {
|
||||
for (Anchor anchor : set) {
|
||||
@ -184,11 +191,13 @@ public class AnchorManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unused")
|
||||
public List<Anchor> searchAnchors(Location center, double searchRadius) {
|
||||
return searchAnchors(center, searchRadius, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Anchor> searchAnchors(Location center, double searchRadius, boolean ignoreHeight) {
|
||||
List<Anchor> result = new ArrayList<>();
|
||||
|
||||
@ -214,12 +223,7 @@ public class AnchorManager {
|
||||
|
||||
/* Create 'n Destroy */
|
||||
|
||||
/**
|
||||
* Creates a new anchor at a given location
|
||||
*
|
||||
* @param loc The block location for the anchor
|
||||
* @param ticks The amount of ticks the anchor lives or -1 for infinite
|
||||
*/
|
||||
@Override
|
||||
public void createAnchor(@NotNull Location loc, @NotNull UUID owner, int ticks, @Nullable Callback<Anchor> callback) {
|
||||
if (!isReady(loc.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
@ -230,14 +234,14 @@ public class AnchorManager {
|
||||
if (callback != null) {
|
||||
callback.accept(ex, null);
|
||||
} else {
|
||||
Utils.logException(this.plugin, ex, "SQLite");
|
||||
Utils.logException(this.plugin, ex, "H2");
|
||||
}
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(this.plugin, () -> {
|
||||
Block b = loc.getBlock();
|
||||
b.setType(Settings.MATERIAL.getMaterial().getMaterial());
|
||||
Block block = loc.getBlock();
|
||||
block.setType(Settings.MATERIAL.getMaterial().parseMaterial());
|
||||
|
||||
anchors.computeIfAbsent(anchor.getWorld(), k -> new HashSet<>())
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), key -> new HashSet<>())
|
||||
.add(anchor);
|
||||
|
||||
updateHologram(anchor);
|
||||
@ -250,16 +254,18 @@ public class AnchorManager {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyAnchor(@NotNull Anchor anchor) {
|
||||
destroyAnchor(anchor, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyAnchor(@NotNull Anchor anchor, boolean forceSkipItemDrop) {
|
||||
if (!isReady(anchor.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
}
|
||||
|
||||
for (Set<Anchor> value : anchors.values()) {
|
||||
for (Set<Anchor> value : this.anchors.values()) {
|
||||
value.remove(anchor);
|
||||
}
|
||||
|
||||
@ -269,7 +275,7 @@ public class AnchorManager {
|
||||
Block anchorBlock = anchorLoc.getBlock();
|
||||
Material anchorMaterial = anchorBlock.getType();
|
||||
|
||||
if (anchorBlock.getType() == Settings.MATERIAL.getMaterial().getMaterial()) {
|
||||
if (anchorBlock.getType() == Settings.MATERIAL.getMaterial().parseMaterial()) {
|
||||
anchorBlock.setType(Material.AIR);
|
||||
}
|
||||
|
||||
@ -281,49 +287,35 @@ public class AnchorManager {
|
||||
}
|
||||
|
||||
// Particles & Sound
|
||||
anchor.getWorld().playSound(anchorLoc, CompatibleSound.ENTITY_GENERIC_EXPLODE.getSound(), 10, 10);
|
||||
XSound.ENTITY_GENERIC_EXPLODE.play(anchorLoc, 10, 10);
|
||||
CompatibleParticleHandler.spawnParticles(CompatibleParticleHandler.ParticleType.getParticle(Settings.PARTICLE_DESTROY.getString()),
|
||||
anchor.getLocation().add(.5, .5, .5), 100, .5, .5, .5);
|
||||
|
||||
anchor.deInit(this.plugin);
|
||||
((AnchorImpl) anchor).deInit(this.plugin);
|
||||
this.dataManager.deleteAnchorAsync(anchor);
|
||||
}
|
||||
|
||||
/* Anchor access */
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void registerAccessCheck(AnchorAccessCheck accessCheck) {
|
||||
if (!accessChecks.contains(accessCheck)) {
|
||||
if (!this.accessChecks.contains(accessCheck)) {
|
||||
// Adding at the start of the list makes sure the default check is
|
||||
accessChecks.add(accessCheck);
|
||||
this.accessChecks.add(accessCheck);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accessCheck The {@link AnchorAccessCheck} to remove
|
||||
*
|
||||
* @return true if the {@link AnchorAccessCheck} has been found and removed, false otherwise
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public boolean unregisterAccessCheck(AnchorAccessCheck accessCheck) {
|
||||
return accessChecks.remove(accessCheck);
|
||||
return this.accessChecks.remove(accessCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAccess(@NotNull Anchor anchor, @NotNull OfflinePlayer p) {
|
||||
return hasAccess(anchor, p.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has access to an Anchor. By default only the owner has access to an Anchor.
|
||||
* <br>
|
||||
* Other plugins can grant access to other players (e.g. friends).
|
||||
* <br>
|
||||
* Legacy anchors without an owner automatically grant access to all players.
|
||||
*
|
||||
* @return true if the player may access the Anchor, false otherwise
|
||||
*
|
||||
* @see #registerAccessCheck(AnchorAccessCheck)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasAccess(@NotNull Anchor anchor, @NotNull UUID uuid) {
|
||||
if (anchor.isLegacy() || anchor.getOwner().equals(uuid)) return true;
|
||||
|
||||
@ -338,18 +330,21 @@ public class AnchorManager {
|
||||
|
||||
/* Anchor item */
|
||||
|
||||
@Override
|
||||
public ItemStack createAnchorItem(int ticks) {
|
||||
return createAnchorItem(ticks, Settings.MATERIAL.getMaterial());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createAnchorItem(int ticks, Material material) {
|
||||
return createAnchorItem(ticks, CompatibleMaterial.getMaterial(material));
|
||||
return createAnchorItem(ticks, CompatibleMaterial.getMaterial(material).get());
|
||||
}
|
||||
|
||||
public ItemStack createAnchorItem(int ticks, CompatibleMaterial material) {
|
||||
@Override
|
||||
public ItemStack createAnchorItem(int ticks, XMaterial material) {
|
||||
if (ticks <= 0 && ticks != -1) throw new IllegalArgumentException();
|
||||
|
||||
ItemStack item = material.getItem();
|
||||
ItemStack item = material.parseItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
assert meta != null;
|
||||
@ -363,43 +358,9 @@ public class AnchorManager {
|
||||
return nbtItem.getItem();
|
||||
}
|
||||
|
||||
public static int getTicksFromItem(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NBTItem nbtItem = new NBTItem(item);
|
||||
|
||||
if (nbtItem.hasTag(NBT_TICKS_KEY)) {
|
||||
return nbtItem.getInteger(NBT_TICKS_KEY);
|
||||
}
|
||||
|
||||
// Legacy code (pre v2) to stay cross-version compatible
|
||||
if (Settings.MATERIAL.getMaterial().getMaterial() == item.getType()) {
|
||||
if (nbtItem.hasTag("ticks")) {
|
||||
int result = nbtItem.getInteger("ticks");
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
}
|
||||
|
||||
// Tries to get the ticks remaining from hidden text
|
||||
if (item.hasItemMeta() &&
|
||||
item.getItemMeta().hasDisplayName() &&
|
||||
item.getItemMeta().getDisplayName().contains(":")) {
|
||||
try {
|
||||
int result = Integer.parseInt(item.getItemMeta().getDisplayName().replace("§", "").split(":")[0]);
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Chunk visualization */
|
||||
|
||||
@Override
|
||||
public boolean toggleChunkVisualized(Player p) {
|
||||
boolean visualize = !hasChunksVisualized(p);
|
||||
|
||||
@ -408,6 +369,7 @@ public class AnchorManager {
|
||||
return visualize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunksVisualized(Player p, boolean visualize) {
|
||||
if (visualize) {
|
||||
this.visualizedChunk.add(p);
|
||||
@ -416,6 +378,7 @@ public class AnchorManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean hasChunksVisualized(Player p) {
|
||||
return this.visualizedChunk.contains(p);
|
||||
@ -423,6 +386,7 @@ public class AnchorManager {
|
||||
|
||||
/* Holograms */
|
||||
|
||||
@Override
|
||||
public void updateHolograms(List<Anchor> anchors) {
|
||||
// are holograms enabled?
|
||||
if (!Settings.HOLOGRAMS.getBoolean() || !HologramManager.getManager().isEnabled()) return;
|
||||
@ -432,12 +396,12 @@ public class AnchorManager {
|
||||
for (Anchor anchor : anchors) {
|
||||
List<String> lines = Collections.singletonList(formatAnchorText(anchor.getTicksLeft(), true));
|
||||
|
||||
if (!HologramManager.isHologramLoaded("Anchor#" + anchor.getDbId())) {
|
||||
HologramManager.createHologram("Anchor#" + anchor.getDbId(), anchor.getLocation(), lines);
|
||||
if (!HologramManager.isHologramLoaded(HOLOGRAM_PREFIX + anchor.getDbId())) {
|
||||
HologramManager.createHologram(HOLOGRAM_PREFIX + anchor.getDbId(), anchor.getLocation(), lines);
|
||||
continue;
|
||||
}
|
||||
|
||||
hologramData.put("Anchor#" + anchor.getDbId(), lines);
|
||||
hologramData.put(HOLOGRAM_PREFIX + anchor.getDbId(), lines);
|
||||
}
|
||||
|
||||
// Create the holograms
|
||||
@ -473,7 +437,42 @@ public class AnchorManager {
|
||||
return TextUtils.formatText(Settings.NAME_TAG.getString().replace("{REMAINING}", remaining));
|
||||
}
|
||||
|
||||
public static int getTicksFromItem(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NBTItem nbtItem = new NBTItem(item);
|
||||
|
||||
if (nbtItem.hasTag(NBT_TICKS_KEY)) {
|
||||
return nbtItem.getInteger(NBT_TICKS_KEY);
|
||||
}
|
||||
|
||||
// Legacy code (pre v2) to stay cross-version compatible
|
||||
if (Settings.MATERIAL.getMaterial().parseMaterial() == item.getType()) {
|
||||
if (nbtItem.hasTag("ticks")) {
|
||||
int result = nbtItem.getInteger("ticks");
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
}
|
||||
|
||||
// Tries to get the ticks remaining from hidden text
|
||||
if (item.hasItemMeta() &&
|
||||
item.getItemMeta().hasDisplayName() &&
|
||||
item.getItemMeta().getDisplayName().contains(":")) {
|
||||
try {
|
||||
int result = Integer.parseInt(item.getItemMeta().getDisplayName().replace("§", "").split(":")[0]);
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void removeHologram(Anchor anchor) {
|
||||
HologramManager.removeHologram("Anchor#" + anchor.getDbId());
|
||||
HologramManager.removeHologram(HOLOGRAM_PREFIX + anchor.getDbId());
|
||||
}
|
||||
}
|
@ -1,30 +1,30 @@
|
||||
package com.songoda.epicanchors;
|
||||
package com.craftaro.epicanchors;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.songoda.core.SongodaPlugin;
|
||||
import com.songoda.core.commands.CommandManager;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.configuration.Config;
|
||||
import com.songoda.core.database.DatabaseConnector;
|
||||
import com.songoda.core.database.SQLiteConnector;
|
||||
import com.songoda.core.gui.GuiManager;
|
||||
import com.songoda.core.hooks.EconomyManager;
|
||||
import com.songoda.core.hooks.HologramManager;
|
||||
import com.songoda.epicanchors.commands.EpicAnchorsCommand;
|
||||
import com.songoda.epicanchors.commands.sub.GiveCommand;
|
||||
import com.songoda.epicanchors.commands.sub.ReloadCommand;
|
||||
import com.songoda.epicanchors.commands.sub.SettingsCommand;
|
||||
import com.songoda.epicanchors.commands.sub.ShowCommand;
|
||||
import com.songoda.epicanchors.files.DataManager;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.files.migration.AnchorMigration;
|
||||
import com.songoda.epicanchors.files.migration._1_InitialMigration;
|
||||
import com.songoda.epicanchors.listener.AnchorListener;
|
||||
import com.songoda.epicanchors.listener.BlockListener;
|
||||
import com.songoda.epicanchors.listener.WorldListener;
|
||||
import com.songoda.epicanchors.tasks.AnchorTask;
|
||||
import com.songoda.epicanchors.tasks.VisualizeTask;
|
||||
import com.songoda.epicanchors.utils.ThreadSync;
|
||||
import com.craftaro.core.SongodaCore;
|
||||
import com.craftaro.core.SongodaPlugin;
|
||||
import com.craftaro.core.commands.CommandManager;
|
||||
import com.craftaro.core.configuration.Config;
|
||||
import com.craftaro.core.dependency.Dependency;
|
||||
import com.craftaro.core.gui.GuiManager;
|
||||
import com.craftaro.core.hooks.EconomyManager;
|
||||
import com.craftaro.core.hooks.HologramManager;
|
||||
import com.craftaro.epicanchors.api.AnchorManager;
|
||||
import com.craftaro.epicanchors.commands.EpicAnchorsCommand;
|
||||
import com.craftaro.epicanchors.commands.sub.GiveCommand;
|
||||
import com.craftaro.epicanchors.commands.sub.ReloadCommand;
|
||||
import com.craftaro.epicanchors.commands.sub.SettingsCommand;
|
||||
import com.craftaro.epicanchors.commands.sub.ShowCommand;
|
||||
import com.craftaro.epicanchors.files.AnchorsDataManager;
|
||||
import com.craftaro.epicanchors.files.Settings;
|
||||
import com.craftaro.epicanchors.files.migration.LegacyYamlAnchorsMigrator;
|
||||
import com.craftaro.epicanchors.files.migration._1_InitialMigration;
|
||||
import com.craftaro.epicanchors.listener.AnchorListener;
|
||||
import com.craftaro.epicanchors.listener.BlockListener;
|
||||
import com.craftaro.epicanchors.listener.WorldListener;
|
||||
import com.craftaro.epicanchors.tasks.AnchorTask;
|
||||
import com.craftaro.epicanchors.tasks.VisualizeTask;
|
||||
import com.craftaro.epicanchors.utils.ThreadSync;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
@ -35,9 +35,9 @@ import java.util.logging.Level;
|
||||
|
||||
public final class EpicAnchors extends SongodaPlugin {
|
||||
private GuiManager guiManager;
|
||||
private AnchorManager anchorManager;
|
||||
private AnchorManagerImpl anchorManager;
|
||||
|
||||
private DataManager dataManager;
|
||||
private AnchorsDataManager dataManager;
|
||||
|
||||
@Override
|
||||
public void onPluginLoad() {
|
||||
@ -45,19 +45,12 @@ public final class EpicAnchors extends SongodaPlugin {
|
||||
|
||||
@Override
|
||||
public void onPluginEnable() {
|
||||
// Songoda Updater
|
||||
SongodaCore.registerPlugin(this, 31, CompatibleMaterial.END_PORTAL_FRAME);
|
||||
SongodaCore.registerPlugin(this, 31, XMaterial.END_PORTAL_FRAME);
|
||||
|
||||
// Initialize database
|
||||
this.getLogger().info("Initializing SQLite...");
|
||||
DatabaseConnector dbCon = new SQLiteConnector(this);
|
||||
this.dataManager = new DataManager(dbCon, this);
|
||||
AnchorMigration anchorMigration = new AnchorMigration(dbCon, this.dataManager,
|
||||
new _1_InitialMigration());
|
||||
anchorMigration.runMigrations();
|
||||
initializeDataManager();
|
||||
|
||||
anchorMigration.migrateLegacyData(this);
|
||||
this.anchorManager = new AnchorManager(this, this.dataManager);
|
||||
this.anchorManager = new AnchorManagerImpl(this, this.dataManager);
|
||||
EpicAnchorsApi.initApi(this.anchorManager);
|
||||
|
||||
// Economy [1/2]
|
||||
EconomyManager.load();
|
||||
@ -74,7 +67,7 @@ public final class EpicAnchors extends SongodaPlugin {
|
||||
|
||||
// Event Listener
|
||||
this.guiManager = new GuiManager(this);
|
||||
guiManager.init();
|
||||
this.guiManager.init();
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
pluginManager.registerEvents(new WorldListener(
|
||||
world -> this.anchorManager.initAnchorsAsync(world, null),
|
||||
@ -150,4 +143,19 @@ public final class EpicAnchors extends SongodaPlugin {
|
||||
public AnchorManager getAnchorManager() {
|
||||
return this.anchorManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config getDatabaseConfig() {
|
||||
Config staticDatabaseConfig = new Config();
|
||||
staticDatabaseConfig.set("Connection Settings.Type", "H2");
|
||||
staticDatabaseConfig.set("Connection Settings.Pool Size", 1);
|
||||
return staticDatabaseConfig;
|
||||
}
|
||||
|
||||
private void initializeDataManager() {
|
||||
super.initDatabase(new _1_InitialMigration());
|
||||
|
||||
this.dataManager = new AnchorsDataManager(this);
|
||||
LegacyYamlAnchorsMigrator.migrateLegacyData(this, this.dataManager);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.songoda.epicanchors.commands;
|
||||
package com.craftaro.epicanchors.commands;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.core.commands.CommandManager;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.craftaro.core.commands.AbstractCommand;
|
||||
import com.craftaro.core.commands.CommandManager;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@ -24,7 +24,7 @@ public class EpicAnchorsCommand extends AbstractCommand {
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
sender.sendMessage("");
|
||||
this.plugin.getLocale().newMessage("&7Version " + this.plugin.getDescription().getVersion()
|
||||
+ " Created with <3 by &5&l&oSongoda").sendPrefixedMessage(sender);
|
||||
+ " Created with <3 by &5&l&oCraftaro").sendPrefixedMessage(sender);
|
||||
|
||||
for (AbstractCommand cmd : this.commandManager.getAllCommands()) {
|
||||
if (cmd.getPermissionNode() == null || sender.hasPermission(cmd.getPermissionNode())) {
|
||||
@ -38,7 +38,7 @@ public class EpicAnchorsCommand extends AbstractCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... strings) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.songoda.epicanchors.commands.sub;
|
||||
package com.craftaro.epicanchors.commands.sub;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.utils.Utils;
|
||||
import com.craftaro.core.commands.AbstractCommand;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.utils.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -32,7 +32,7 @@ public class GiveCommand extends AbstractCommand {
|
||||
if (target == null &&
|
||||
!args[0].trim().equalsIgnoreCase("all") &&
|
||||
!args[0].trim().equalsIgnoreCase("@a")) {
|
||||
plugin.getLocale().newMessage("&cThat is not a player...").sendPrefixedMessage(sender);
|
||||
this.plugin.getLocale().newMessage("&cThat is not a player...").sendPrefixedMessage(sender);
|
||||
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
@ -40,22 +40,22 @@ public class GiveCommand extends AbstractCommand {
|
||||
ItemStack itemStack;
|
||||
|
||||
if (Utils.isInt(args[1]) && Integer.parseInt(args[1]) > 0) {
|
||||
itemStack = plugin.getAnchorManager().createAnchorItem(Integer.parseInt(args[1]) * 20 * 60 * 60);
|
||||
itemStack = this.plugin.getAnchorManager().createAnchorItem(Integer.parseInt(args[1]) * 20 * 60 * 60);
|
||||
} else if (args[1].equalsIgnoreCase("infinite")) {
|
||||
itemStack = plugin.getAnchorManager().createAnchorItem(-1);
|
||||
itemStack = this.plugin.getAnchorManager().createAnchorItem(-1);
|
||||
} else {
|
||||
plugin.getLocale().newMessage("&cYou can only use positive whole numbers...").sendPrefixedMessage(sender);
|
||||
this.plugin.getLocale().newMessage("&cYou can only use positive whole numbers...").sendPrefixedMessage(sender);
|
||||
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
if (target != null) {
|
||||
target.getInventory().addItem(itemStack);
|
||||
plugin.getLocale().getMessage("command.give.success").sendPrefixedMessage(target);
|
||||
this.plugin.getLocale().getMessage("command.give.success").sendPrefixedMessage(target);
|
||||
} else {
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
online.getInventory().addItem(itemStack);
|
||||
plugin.getLocale().getMessage("command.give.success").sendPrefixedMessage(online);
|
||||
this.plugin.getLocale().getMessage("command.give.success").sendPrefixedMessage(online);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ public class GiveCommand extends AbstractCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... args) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
if (args.length == 1) {
|
||||
Set<String> players = new HashSet<>();
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.songoda.epicanchors.commands.sub;
|
||||
package com.craftaro.epicanchors.commands.sub;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.craftaro.core.commands.AbstractCommand;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -17,8 +17,8 @@ public class ReloadCommand extends AbstractCommand {
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
plugin.reloadConfig();
|
||||
plugin.getLocale().getMessage("&7Configuration and Language files reloaded.").sendPrefixedMessage(sender);
|
||||
this.plugin.reloadConfig();
|
||||
this.plugin.getLocale().getMessage("&7Configuration and Language files reloaded.").sendPrefixedMessage(sender);
|
||||
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package com.songoda.epicanchors.commands.sub;
|
||||
package com.craftaro.epicanchors.commands.sub;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.core.configuration.editor.PluginConfigGui;
|
||||
import com.songoda.core.gui.GuiManager;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.craftaro.core.commands.AbstractCommand;
|
||||
import com.craftaro.core.configuration.editor.PluginConfigGui;
|
||||
import com.craftaro.core.gui.GuiManager;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -23,13 +23,13 @@ public class SettingsCommand extends AbstractCommand {
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
guiManager.showGUI((Player) sender, new PluginConfigGui(instance));
|
||||
this.guiManager.showGUI((Player) sender, new PluginConfigGui(this.instance));
|
||||
|
||||
return AbstractCommand.ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... strings) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.songoda.epicanchors.commands.sub;
|
||||
package com.craftaro.epicanchors.commands.sub;
|
||||
|
||||
import com.songoda.core.commands.AbstractCommand;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.craftaro.core.commands.AbstractCommand;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -30,7 +30,7 @@ public class ShowCommand extends AbstractCommand {
|
||||
|
||||
boolean visualize = this.plugin.getAnchorManager().toggleChunkVisualized((Player) sender);
|
||||
|
||||
plugin.getLocale().getMessage("command.show." + (visualize ? "start" : "stop"))
|
||||
this.plugin.getLocale().getMessage("command.show." + (visualize ? "start" : "stop"))
|
||||
.sendPrefixedMessage(sender);
|
||||
|
||||
return ReturnType.SUCCESS;
|
@ -1,16 +1,16 @@
|
||||
package com.songoda.epicanchors.files;
|
||||
package com.craftaro.epicanchors.files;
|
||||
|
||||
import com.songoda.core.database.DataManagerAbstract;
|
||||
import com.songoda.core.database.DatabaseConnector;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.files.migration.AnchorMigration;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
import com.songoda.epicanchors.utils.UpdateCallback;
|
||||
import com.songoda.epicanchors.utils.Utils;
|
||||
import com.craftaro.core.SongodaPlugin;
|
||||
import com.craftaro.core.database.DatabaseConnector;
|
||||
import com.craftaro.epicanchors.AnchorImpl;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.files.migration.LegacyYamlAnchorsMigrator;
|
||||
import com.craftaro.epicanchors.utils.Callback;
|
||||
import com.craftaro.epicanchors.utils.UpdateCallback;
|
||||
import com.craftaro.epicanchors.utils.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -27,38 +27,35 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DataManager extends DataManagerAbstract {
|
||||
public class AnchorsDataManager {
|
||||
private final ExecutorService thread = Executors.newSingleThreadExecutor();
|
||||
private final SongodaPlugin plugin;
|
||||
|
||||
private final String anchorTable;
|
||||
|
||||
public DataManager(DatabaseConnector databaseConnector, Plugin plugin) {
|
||||
super(databaseConnector, plugin);
|
||||
|
||||
this.anchorTable = getTableName(super.getTablePrefix(), "anchors");
|
||||
public AnchorsDataManager(SongodaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (!this.thread.isShutdown()) {
|
||||
this.thread.shutdown();
|
||||
|
||||
try {
|
||||
if (!this.thread.awaitTermination(60, TimeUnit.SECONDS)) {
|
||||
// Try stopping the thread forcefully (there is basically no hope left for the data)
|
||||
this.thread.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Utils.logException(super.plugin, ex);
|
||||
}
|
||||
|
||||
this.databaseConnector.closeConnection();
|
||||
if (this.thread.isShutdown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.thread.shutdown();
|
||||
try {
|
||||
if (!this.thread.awaitTermination(60, TimeUnit.SECONDS)) {
|
||||
// Try stopping the thread forcefully (there is basically no hope left for the data)
|
||||
this.thread.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
Utils.logException(this.plugin, ex);
|
||||
}
|
||||
|
||||
this.plugin.getDataManager().shutdown();
|
||||
}
|
||||
|
||||
public void exists(@NotNull String worldName, int x, int y, int z, @NotNull Callback<Boolean> callback) {
|
||||
this.databaseConnector.connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT id FROM " + this.anchorTable +
|
||||
" WHERE world_name =? AND x =? AND y =? AND z=?;")) {
|
||||
getDatabaseConnector().connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT id FROM " + getAnchorTable() + " WHERE world_name =? AND x =? AND y =? AND z=?;")) {
|
||||
ps.setString(1, worldName);
|
||||
ps.setInt(2, x);
|
||||
ps.setInt(3, y);
|
||||
@ -76,9 +73,8 @@ public class DataManager extends DataManagerAbstract {
|
||||
public void getAnchors(@Nullable World world, @NotNull Callback<List<Anchor>> callback) {
|
||||
List<Anchor> result = new ArrayList<>();
|
||||
|
||||
this.databaseConnector.connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM " + this.anchorTable +
|
||||
(world != null ? " WHERE world_name =?" : "") + ";")) {
|
||||
getDatabaseConnector().connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM " + getAnchorTable() + (world != null ? " WHERE world_name =?" : "") + ";")) {
|
||||
if (world != null) {
|
||||
ps.setString(1, world.getName());
|
||||
}
|
||||
@ -101,11 +97,10 @@ public class DataManager extends DataManagerAbstract {
|
||||
}
|
||||
|
||||
public void insertAnchor(Location loc, UUID owner, int ticks, Callback<Anchor> callback) {
|
||||
this.databaseConnector.connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO " + this.anchorTable +
|
||||
"(owner, world_name,x,y,z, ticks_left) VALUES (?,?,?,?,?, ?);");// Future SQLite version might support 'RETURNING *'
|
||||
PreparedStatement psFetch = con.prepareStatement("SELECT * FROM " + this.anchorTable +
|
||||
" WHERE world_name =? AND x =? AND y =? AND z=?;")) {
|
||||
getDatabaseConnector().connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO " + getAnchorTable() + "(owner, world_name,x,y,z, ticks_left) VALUES (?,?,?,?,?, ?);"); // Future SQLite version might support 'RETURNING *'
|
||||
PreparedStatement psFetch = con.prepareStatement("SELECT * FROM " + getAnchorTable() + " WHERE world_name =? AND x =? AND y =? AND z=?;")
|
||||
) {
|
||||
ps.setString(1, owner != null ? owner.toString() : null);
|
||||
|
||||
ps.setString(2, Objects.requireNonNull(loc.getWorld()).getName());
|
||||
@ -136,15 +131,14 @@ public class DataManager extends DataManagerAbstract {
|
||||
});
|
||||
}
|
||||
|
||||
public void migrateAnchor(List<AnchorMigration.LegacyAnchorEntry> anchorEntries, UpdateCallback callback) {
|
||||
this.databaseConnector.connect((con) -> {
|
||||
public void migrateAnchor(List<LegacyYamlAnchorsMigrator.LegacyAnchorEntry> anchorEntries, UpdateCallback callback) {
|
||||
getDatabaseConnector().connect((con) -> {
|
||||
con.setAutoCommit(false);
|
||||
|
||||
SQLException err = null;
|
||||
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO " + this.anchorTable +
|
||||
"(world_name,x,y,z, ticks_left) VALUES (?,?,?,?, ?);")) {
|
||||
for (AnchorMigration.LegacyAnchorEntry entry : anchorEntries) {
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO " + getAnchorTable() + "(world_name,x,y,z, ticks_left) VALUES (?,?,?,?, ?);")) {
|
||||
for (LegacyYamlAnchorsMigrator.LegacyAnchorEntry entry : anchorEntries) {
|
||||
ps.setString(1, entry.worldName);
|
||||
ps.setInt(2, entry.x);
|
||||
ps.setInt(3, entry.y);
|
||||
@ -159,7 +153,7 @@ public class DataManager extends DataManagerAbstract {
|
||||
|
||||
for (int i : batchRes) {
|
||||
if (i < 0 && i != Statement.SUCCESS_NO_INFO) {
|
||||
throw new AssertionError("Batch-INSERT failed for at least one statement with code " + i + "");
|
||||
throw new AssertionError("Batch-INSERT failed for at least one statement with code " + i);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
@ -181,14 +175,13 @@ public class DataManager extends DataManagerAbstract {
|
||||
}
|
||||
|
||||
public void updateAnchors(Collection<Anchor> anchors, UpdateCallback callback) {
|
||||
this.databaseConnector.connect((con) -> {
|
||||
getDatabaseConnector().connect((con) -> {
|
||||
con.setAutoCommit(false);
|
||||
|
||||
SQLException err = null;
|
||||
|
||||
for (Anchor anchor : anchors) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE " + this.anchorTable +
|
||||
" SET ticks_left =? WHERE id =?;")) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE " + getAnchorTable() + " SET ticks_left =? WHERE id =?;")) {
|
||||
ps.setInt(1, anchor.getTicksLeft());
|
||||
ps.setInt(2, anchor.getDbId());
|
||||
|
||||
@ -219,9 +212,8 @@ public class DataManager extends DataManagerAbstract {
|
||||
|
||||
public void deleteAnchorAsync(Anchor anchor, UpdateCallback callback) {
|
||||
this.thread.execute(() ->
|
||||
this.databaseConnector.connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM " + this.anchorTable +
|
||||
" WHERE id =?;")) {
|
||||
getDatabaseConnector().connect((con) -> {
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM " + getAnchorTable() + " WHERE id =?;")) {
|
||||
ps.setInt(1, anchor.getDbId());
|
||||
|
||||
ps.executeUpdate();
|
||||
@ -234,20 +226,22 @@ public class DataManager extends DataManagerAbstract {
|
||||
);
|
||||
}
|
||||
|
||||
public static String getTableName(String prefix, String name) {
|
||||
String result = prefix + name;
|
||||
public String getAnchorTable() {
|
||||
return getAnchorTable(this.plugin.getDataManager().getTablePrefix());
|
||||
}
|
||||
|
||||
if (!result.matches("[a-z0-9_]+")) {
|
||||
throw new IllegalStateException("The generated table name '" + result + "' contains invalid characters");
|
||||
}
|
||||
public static String getAnchorTable(String prefix) {
|
||||
return prefix + "anchors";
|
||||
}
|
||||
|
||||
return result;
|
||||
private DatabaseConnector getDatabaseConnector() {
|
||||
return this.plugin.getDataManager().getDatabaseConnector();
|
||||
}
|
||||
|
||||
private Anchor extractAnchor(ResultSet rs) throws SQLException {
|
||||
String ownerStr = rs.getString("owner");
|
||||
|
||||
return new Anchor(rs.getInt("id"),
|
||||
return new AnchorImpl(rs.getInt("id"),
|
||||
ownerStr != null ? UUID.fromString(ownerStr) : null,
|
||||
new Location(Bukkit.getWorld(rs.getString("world_name")),
|
||||
rs.getInt("x"),
|
||||
@ -260,7 +254,7 @@ public class DataManager extends DataManagerAbstract {
|
||||
if (callback != null) {
|
||||
callback.accept(ex);
|
||||
} else if (ex != null) {
|
||||
Utils.logException(this.plugin, ex, "SQLite");
|
||||
Utils.logException(this.plugin, ex, "H2");
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +262,7 @@ public class DataManager extends DataManagerAbstract {
|
||||
if (callback != null) {
|
||||
callback.accept(ex, null);
|
||||
} else {
|
||||
Utils.logException(this.plugin, ex, "SQLite");
|
||||
Utils.logException(this.plugin, ex, "H2");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package com.songoda.epicanchors.files;
|
||||
package com.craftaro.epicanchors.files;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.core.configuration.Config;
|
||||
import com.songoda.core.configuration.ConfigSetting;
|
||||
import com.songoda.core.hooks.EconomyManager;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.craftaro.core.compatibility.CompatibleMaterial;
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.core.configuration.Config;
|
||||
import com.craftaro.core.configuration.ConfigSetting;
|
||||
import com.craftaro.core.hooks.EconomyManager;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Settings {
|
||||
@ -13,60 +14,60 @@ public class Settings {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static final Config config = JavaPlugin.getPlugin(EpicAnchors.class).getCoreConfig();
|
||||
public static final Config CONFIG = JavaPlugin.getPlugin(EpicAnchors.class).getCoreConfig();
|
||||
|
||||
public static final ConfigSetting NAME_TAG = new ConfigSetting(config, "Main.Name Tag",
|
||||
public static final ConfigSetting NAME_TAG = new ConfigSetting(CONFIG, "Main.Name Tag",
|
||||
"&6Anchor &8(&7{REMAINING}&8)",
|
||||
"The anchor name tag used on the item and in the hologram.");
|
||||
|
||||
public static final ConfigSetting LORE = new ConfigSetting(config, "Main.Anchor Lore",
|
||||
public static final ConfigSetting LORE = new ConfigSetting(CONFIG, "Main.Anchor Lore",
|
||||
"&7Place down to keep that chunk\n&7loaded until the time runs out.",
|
||||
"The lore on the anchor item.");
|
||||
|
||||
public static final ConfigSetting MATERIAL = new ConfigSetting(config, "Main.Anchor Block Material",
|
||||
CompatibleMaterial.END_PORTAL_FRAME.name(), "The material an anchor is represented with?");
|
||||
public static final ConfigSetting MATERIAL = new ConfigSetting(CONFIG, "Main.Anchor Block Material",
|
||||
XMaterial.END_PORTAL_FRAME.name(), "The material an anchor is represented with?");
|
||||
|
||||
public static final ConfigSetting ADD_TIME_WITH_XP = new ConfigSetting(config, "Main.Add Time With XP", true,
|
||||
public static final ConfigSetting ADD_TIME_WITH_XP = new ConfigSetting(CONFIG, "Main.Add Time With XP", true,
|
||||
"Should players be able to add time to their anchors by using experience?");
|
||||
|
||||
public static final ConfigSetting XP_COST = new ConfigSetting(config, "Main.XP Cost", 10,
|
||||
public static final ConfigSetting XP_COST = new ConfigSetting(CONFIG, "Main.XP Cost", 10,
|
||||
"The cost in experience levels to add 30 minutes to an anchor.");
|
||||
|
||||
public static final ConfigSetting ADD_TIME_WITH_ECONOMY = new ConfigSetting(config, "Main.Add Time With Economy", true,
|
||||
public static final ConfigSetting ADD_TIME_WITH_ECONOMY = new ConfigSetting(CONFIG, "Main.Add Time With Economy", true,
|
||||
"Should players be able to add time to their anchors by using economy?");
|
||||
|
||||
public static final ConfigSetting ECONOMY_COST = new ConfigSetting(config, "Main.Economy Cost", 5000.0,
|
||||
public static final ConfigSetting ECONOMY_COST = new ConfigSetting(CONFIG, "Main.Economy Cost", 5000.0,
|
||||
"The cost in economy to add 30 minutes to an anchor.");
|
||||
|
||||
public static final ConfigSetting ALLOW_ANCHOR_BREAKING = new ConfigSetting(config, "Main.Allow Anchor Breaking", false,
|
||||
public static final ConfigSetting ALLOW_ANCHOR_BREAKING = new ConfigSetting(CONFIG, "Main.Allow Anchor Breaking", false,
|
||||
"Should players be able to break anchors and get an item dropped?");
|
||||
|
||||
public static final ConfigSetting HOLOGRAMS = new ConfigSetting(config, "Main.Holograms", true,
|
||||
public static final ConfigSetting HOLOGRAMS = new ConfigSetting(CONFIG, "Main.Holograms", true,
|
||||
"Toggle holograms showing above anchors.");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final ConfigSetting ECONOMY_PLUGIN = new ConfigSetting(config, "Main.Economy", EconomyManager.getEconomy() == null ? "Vault" : EconomyManager.getEconomy().getName(),
|
||||
public static final ConfigSetting ECONOMY_PLUGIN = new ConfigSetting(CONFIG, "Main.Economy", EconomyManager.getEconomy() == null ? "Vault" : EconomyManager.getEconomy().getName(),
|
||||
"Which economy plugin should be used?",
|
||||
"Supported plugins you have installed: \"" + String.join(", ", EconomyManager.getManager().getRegisteredPlugins()) + "\".");
|
||||
|
||||
public static final ConfigSetting ECO_ICON = new ConfigSetting(config, "Interfaces.Economy Icon", CompatibleMaterial.SUNFLOWER.name(),
|
||||
public static final ConfigSetting ECO_ICON = new ConfigSetting(CONFIG, "Interfaces.Economy Icon", XMaterial.SUNFLOWER.name(),
|
||||
"Item to be displayed as the icon for economy upgrades.");
|
||||
|
||||
public static final ConfigSetting XP_ICON = new ConfigSetting(config, "Interfaces.XP Icon", CompatibleMaterial.EXPERIENCE_BOTTLE.name(),
|
||||
public static final ConfigSetting XP_ICON = new ConfigSetting(CONFIG, "Interfaces.XP Icon", XMaterial.EXPERIENCE_BOTTLE.name(),
|
||||
"Item to be displayed as the icon for XP upgrades.");
|
||||
|
||||
public static final ConfigSetting GLASS_TYPE_1 = new ConfigSetting(config, "Interfaces.Glass Type 1", CompatibleMaterial.GRAY_STAINED_GLASS_PANE.name());
|
||||
public static final ConfigSetting GLASS_TYPE_2 = new ConfigSetting(config, "Interfaces.Glass Type 2", CompatibleMaterial.BLUE_STAINED_GLASS_PANE.name());
|
||||
public static final ConfigSetting GLASS_TYPE_3 = new ConfigSetting(config, "Interfaces.Glass Type 3", CompatibleMaterial.LIGHT_BLUE_STAINED_GLASS_PANE.name());
|
||||
public static final ConfigSetting GLASS_TYPE_1 = new ConfigSetting(CONFIG, "Interfaces.Glass Type 1", XMaterial.GRAY_STAINED_GLASS_PANE.name());
|
||||
public static final ConfigSetting GLASS_TYPE_2 = new ConfigSetting(CONFIG, "Interfaces.Glass Type 2", XMaterial.BLUE_STAINED_GLASS_PANE.name());
|
||||
public static final ConfigSetting GLASS_TYPE_3 = new ConfigSetting(CONFIG, "Interfaces.Glass Type 3", XMaterial.LIGHT_BLUE_STAINED_GLASS_PANE.name());
|
||||
|
||||
public static final ConfigSetting PARTICLE_DESTROY = new ConfigSetting(config, "Particles.Destroy",
|
||||
public static final ConfigSetting PARTICLE_DESTROY = new ConfigSetting(CONFIG, "Particles.Destroy",
|
||||
CompatibleParticleHandler.ParticleType.LAVA.name());
|
||||
public static final ConfigSetting PARTICLE_UPGRADE = new ConfigSetting(config, "Particles.Upgrade",
|
||||
public static final ConfigSetting PARTICLE_UPGRADE = new ConfigSetting(CONFIG, "Particles.Upgrade",
|
||||
CompatibleParticleHandler.ParticleType.SPELL_WITCH.name());
|
||||
public static final ConfigSetting PARTICLE_VISUALIZER = new ConfigSetting(config, "Particles.Visualizer",
|
||||
public static final ConfigSetting PARTICLE_VISUALIZER = new ConfigSetting(CONFIG, "Particles.Visualizer",
|
||||
CompatibleParticleHandler.ParticleType.VILLAGER_HAPPY.name());
|
||||
|
||||
public static final ConfigSetting LANGUAGE = new ConfigSetting(config, "System.Language Mode", "en_US",
|
||||
public static final ConfigSetting LANGUAGE = new ConfigSetting(CONFIG, "System.Language Mode", "en_US",
|
||||
"The enabled language file.",
|
||||
"More language files (if available) can be found in the plugins data folder.");
|
||||
|
||||
@ -75,31 +76,31 @@ public class Settings {
|
||||
* called after EconomyManager load
|
||||
*/
|
||||
public static void setupConfig() {
|
||||
config.load();
|
||||
config.setAutoremove(true)
|
||||
CONFIG.load();
|
||||
CONFIG.setAutoremove(true)
|
||||
.setAutosave(true);
|
||||
|
||||
// convert glass pane settings
|
||||
int color;
|
||||
if ((color = GLASS_TYPE_1.getInt(-1)) != -1) {
|
||||
config.set(GLASS_TYPE_1.getKey(), CompatibleMaterial.getGlassPaneColor(color).name());
|
||||
CONFIG.set(GLASS_TYPE_1.getKey(), CompatibleMaterial.getGlassPaneForColor(color).name());
|
||||
}
|
||||
if ((color = GLASS_TYPE_2.getInt(-1)) != -1) {
|
||||
config.set(GLASS_TYPE_2.getKey(), CompatibleMaterial.getGlassPaneColor(color).name());
|
||||
CONFIG.set(GLASS_TYPE_2.getKey(), CompatibleMaterial.getGlassPaneForColor(color).name());
|
||||
}
|
||||
if ((color = GLASS_TYPE_3.getInt(-1)) != -1) {
|
||||
config.set(GLASS_TYPE_3.getKey(), CompatibleMaterial.getGlassPaneColor(color).name());
|
||||
CONFIG.set(GLASS_TYPE_3.getKey(), CompatibleMaterial.getGlassPaneForColor(color).name());
|
||||
}
|
||||
|
||||
// convert economy settings
|
||||
if (config.getBoolean("Economy.Use Vault Economy") && EconomyManager.getManager().isEnabled("Vault")) {
|
||||
config.set("Main.Economy", "Vault");
|
||||
} else if (config.getBoolean("Economy.Use Reserve Economy") && EconomyManager.getManager().isEnabled("Reserve")) {
|
||||
config.set("Main.Economy", "Reserve");
|
||||
} else if (config.getBoolean("Economy.Use Player Points Economy") && EconomyManager.getManager().isEnabled("PlayerPoints")) {
|
||||
config.set("Main.Economy", "PlayerPoints");
|
||||
if (CONFIG.getBoolean("Economy.Use Vault Economy") && EconomyManager.getManager().isEnabled("Vault")) {
|
||||
CONFIG.set("Main.Economy", "Vault");
|
||||
} else if (CONFIG.getBoolean("Economy.Use Reserve Economy") && EconomyManager.getManager().isEnabled("Reserve")) {
|
||||
CONFIG.set("Main.Economy", "Reserve");
|
||||
} else if (CONFIG.getBoolean("Economy.Use Player Points Economy") && EconomyManager.getManager().isEnabled("PlayerPoints")) {
|
||||
CONFIG.set("Main.Economy", "PlayerPoints");
|
||||
}
|
||||
|
||||
config.saveChanges();
|
||||
CONFIG.saveChanges();
|
||||
}
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
package com.songoda.epicanchors.files.migration;
|
||||
package com.craftaro.epicanchors.files.migration;
|
||||
|
||||
import com.songoda.core.configuration.Config;
|
||||
import com.songoda.core.configuration.ConfigSection;
|
||||
import com.songoda.core.database.DataMigration;
|
||||
import com.songoda.core.database.DataMigrationManager;
|
||||
import com.songoda.core.database.DatabaseConnector;
|
||||
import com.songoda.epicanchors.files.DataManager;
|
||||
import com.songoda.epicanchors.utils.ThreadSync;
|
||||
import com.craftaro.core.configuration.Config;
|
||||
import com.craftaro.core.configuration.ConfigSection;
|
||||
import com.craftaro.epicanchors.files.AnchorsDataManager;
|
||||
import com.craftaro.epicanchors.utils.ThreadSync;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
@ -18,16 +15,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class AnchorMigration extends DataMigrationManager {
|
||||
private final DataManager dataManager;
|
||||
|
||||
public AnchorMigration(DatabaseConnector databaseConnector, DataManager dataManager, DataMigration... migrations) {
|
||||
super(databaseConnector, dataManager, migrations);
|
||||
|
||||
this.dataManager = dataManager;
|
||||
}
|
||||
|
||||
public void migrateLegacyData(Plugin plugin) {
|
||||
public class LegacyYamlAnchorsMigrator {
|
||||
public static void migrateLegacyData(Plugin plugin, AnchorsDataManager dataManager) {
|
||||
long start = System.nanoTime();
|
||||
|
||||
AtomicBoolean abortMigration = new AtomicBoolean(false);
|
||||
@ -94,7 +83,7 @@ public class AnchorMigration extends DataMigrationManager {
|
||||
|
||||
if (!abortMigration.get()) {
|
||||
int finalMigratedAnchors = migratedAnchors;
|
||||
this.dataManager.migrateAnchor(anchorQueue, ex -> {
|
||||
dataManager.migrateAnchor(anchorQueue, ex -> {
|
||||
long end = System.nanoTime();
|
||||
|
||||
if (ex == null) {
|
||||
@ -114,7 +103,7 @@ public class AnchorMigration extends DataMigrationManager {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] deserializeLegacyLocation(String str) {
|
||||
private static String[] deserializeLegacyLocation(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return new String[0];
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.craftaro.epicanchors.files.migration;
|
||||
|
||||
import com.craftaro.core.database.DataMigration;
|
||||
import com.craftaro.epicanchors.files.AnchorsDataManager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class _1_InitialMigration extends DataMigration {
|
||||
public _1_InitialMigration() {
|
||||
super(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrate(Connection connection, String tablePrefix) throws SQLException {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(
|
||||
"CREATE TABLE " + AnchorsDataManager.getAnchorTable(tablePrefix) +
|
||||
"(" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY auto_increment," +
|
||||
"world_name TEXT NOT NULL," +
|
||||
"x INTEGER NOT NULL," +
|
||||
"y INTEGER NOT NULL," +
|
||||
"z INTEGER NOT NULL," +
|
||||
"ticks_left INTEGER NOT NULL," +
|
||||
"owner VARCHAR(36)" +
|
||||
");");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package com.songoda.epicanchors.guis;
|
||||
package com.craftaro.epicanchors.guis;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.core.compatibility.CompatibleSound;
|
||||
import com.songoda.core.gui.Gui;
|
||||
import com.songoda.core.gui.GuiUtils;
|
||||
import com.songoda.core.hooks.EconomyManager;
|
||||
import com.songoda.core.utils.TextUtils;
|
||||
import com.songoda.core.utils.TimeUtils;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.core.gui.Gui;
|
||||
import com.craftaro.core.gui.GuiUtils;
|
||||
import com.craftaro.core.hooks.EconomyManager;
|
||||
import com.craftaro.core.utils.TextUtils;
|
||||
import com.craftaro.core.utils.TimeUtils;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.files.Settings;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XSound;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
@ -36,26 +36,26 @@ public class AnchorGui extends Gui {
|
||||
prepareGui(this.plugin, this, this.anchor);
|
||||
|
||||
if (Settings.ADD_TIME_WITH_XP.getBoolean()) {
|
||||
String itemName = plugin.getLocale().getMessage("interface.button.addtimewithxp").getMessage();
|
||||
String itemLore = plugin.getLocale().getMessage("interface.button.addtimewithxplore")
|
||||
String itemName = this.plugin.getLocale().getMessage("interface.button.addtimewithxp").getMessage();
|
||||
String itemLore = this.plugin.getLocale().getMessage("interface.button.addtimewithxplore")
|
||||
.processPlaceholder("cost", Settings.XP_COST.getInt())
|
||||
.getMessage();
|
||||
|
||||
setButton(11,
|
||||
GuiUtils.createButtonItem(Settings.XP_ICON.getMaterial(CompatibleMaterial.EXPERIENCE_BOTTLE), itemName, itemLore),
|
||||
event -> buyTime(anchor, event.player, false));
|
||||
GuiUtils.createButtonItem(Settings.XP_ICON.getMaterial(XMaterial.EXPERIENCE_BOTTLE), itemName, itemLore),
|
||||
event -> buyTime(this.anchor, event.player, false));
|
||||
}
|
||||
|
||||
if (EconomyManager.isEnabled() && Settings.ADD_TIME_WITH_ECONOMY.getBoolean()) {
|
||||
String itemName = plugin.getLocale().getMessage("interface.button.addtimewitheconomy").getMessage();
|
||||
String itemLore = plugin.getLocale().getMessage("interface.button.addtimewitheconomylore")
|
||||
String itemName = this.plugin.getLocale().getMessage("interface.button.addtimewitheconomy").getMessage();
|
||||
String itemLore = this.plugin.getLocale().getMessage("interface.button.addtimewitheconomylore")
|
||||
// EconomyManager#formatEconomy adds its own prefix/suffix
|
||||
.processPlaceholder("cost", EconomyManager.formatEconomy(Settings.ECONOMY_COST.getDouble()))
|
||||
.getMessage();
|
||||
|
||||
setButton(15,
|
||||
GuiUtils.createButtonItem(Settings.ECO_ICON.getMaterial(CompatibleMaterial.SUNFLOWER), itemName, itemLore),
|
||||
event -> buyTime(anchor, event.player, true));
|
||||
GuiUtils.createButtonItem(Settings.ECO_ICON.getMaterial(XMaterial.SUNFLOWER), itemName, itemLore),
|
||||
event -> buyTime(this.anchor, event.player, true));
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ public class AnchorGui extends Gui {
|
||||
if (success) {
|
||||
anchor.addTicksLeft(20 * 60 * 30); // 30 minutes
|
||||
|
||||
p.playSound(p.getLocation(), CompatibleSound.ENTITY_PLAYER_LEVELUP.getSound(), 0.6F, 15);
|
||||
XSound.ENTITY_PLAYER_LEVELUP.play(p, .6f, 15);
|
||||
CompatibleParticleHandler.spawnParticles(CompatibleParticleHandler.ParticleType.getParticle(Settings.PARTICLE_UPGRADE.getString()),
|
||||
anchor.getLocation().add(.5, .5, .5), 100, .5, .5, .5);
|
||||
} else {
|
||||
@ -112,7 +112,7 @@ public class AnchorGui extends Gui {
|
||||
ChatColor.GRAY + TimeUtils.makeReadable((long) ((anchor.getTicksLeft() / 20.0) * 1000)) + " remaining.";
|
||||
|
||||
gui.setItem(13, GuiUtils.createButtonItem(plugin.getAnchorManager().createAnchorItem(
|
||||
anchor.getTicksLeft(), anchor.getLocation().getBlock().getType()),
|
||||
anchor.getTicksLeft(), anchor.getLocation().getBlock().getType()),
|
||||
itemName, itemLore));
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package com.craftaro.epicanchors.guis;
|
||||
|
||||
import com.craftaro.core.gui.Gui;
|
||||
import com.craftaro.core.gui.GuiUtils;
|
||||
import com.craftaro.core.gui.methods.Closable;
|
||||
import com.craftaro.core.utils.TextUtils;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.files.Settings;
|
||||
import com.craftaro.epicanchors.utils.Callback;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
|
||||
public class DestroyConfirmationGui extends Gui {
|
||||
private final EpicAnchors plugin;
|
||||
private final Anchor anchor;
|
||||
|
||||
private Callback<Boolean> handler;
|
||||
|
||||
public DestroyConfirmationGui(EpicAnchors plugin, Anchor anchor, Callback<Boolean> callback) {
|
||||
this.plugin = plugin;
|
||||
this.anchor = anchor;
|
||||
|
||||
this.handler = (ex, result) -> {
|
||||
this.handler = null;
|
||||
this.close();
|
||||
|
||||
callback.accept(ex, result);
|
||||
};
|
||||
|
||||
this.setRows(3);
|
||||
this.setTitle(TextUtils.formatText(plugin.getLocale().getMessage("interface.anchor.title").getMessage()));
|
||||
|
||||
constructGUI();
|
||||
AnchorGui.runPreparedGuiTask(this.plugin, this, this.anchor);
|
||||
|
||||
Closable currClosable = this.closer;
|
||||
this.closer = event -> {
|
||||
currClosable.onClose(event);
|
||||
|
||||
if (this.handler != null) {
|
||||
this.handler.accept(null, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void constructGUI() {
|
||||
AnchorGui.prepareGui(this.plugin, this, this.anchor);
|
||||
|
||||
String cancelLore = this.plugin.getLocale().getMessage("interface.button.cancelDestroyLore").getMessage();
|
||||
String confirmLore = this.plugin.getLocale().getMessage("interface.button." +
|
||||
(Settings.ALLOW_ANCHOR_BREAKING.getBoolean() ? "confirmDestroyLore" : "confirmDestroyLoreNoDrops"))
|
||||
.getMessage();
|
||||
|
||||
setButton(11, GuiUtils.createButtonItem(XMaterial.RED_TERRACOTTA,
|
||||
this.plugin.getLocale().getMessage("interface.button.cancelDestroy").getMessage(),
|
||||
cancelLore.isEmpty() ? new String[0] : new String[]{cancelLore}),
|
||||
event -> this.handler.accept(null, false));
|
||||
|
||||
setButton(15, GuiUtils.createButtonItem(XMaterial.GREEN_TERRACOTTA,
|
||||
this.plugin.getLocale().getMessage("interface.button.confirmDestroy").getMessage(),
|
||||
confirmLore.isEmpty() ? new String[0] : new String[]{confirmLore}),
|
||||
event -> this.handler.accept(null, true));
|
||||
}
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
package com.songoda.epicanchors.listener;
|
||||
package com.craftaro.epicanchors.listener;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleHand;
|
||||
import com.songoda.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.core.compatibility.CompatibleSound;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.AnchorManager;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.guis.AnchorGui;
|
||||
import com.songoda.epicanchors.guis.DestroyConfirmationGui;
|
||||
import com.songoda.epicanchors.utils.Utils;
|
||||
import com.craftaro.core.compatibility.CompatibleHand;
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.epicanchors.AnchorManagerImpl;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.files.Settings;
|
||||
import com.craftaro.epicanchors.guis.AnchorGui;
|
||||
import com.craftaro.epicanchors.guis.DestroyConfirmationGui;
|
||||
import com.craftaro.epicanchors.utils.Utils;
|
||||
import com.craftaro.third_party.com.cryptomorin.xseries.XSound;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
@ -36,30 +36,30 @@ public class AnchorListener implements Listener {
|
||||
|
||||
if (item.hasItemMeta() &&
|
||||
item.getItemMeta().hasDisplayName() &&
|
||||
Settings.MATERIAL.getMaterial().getMaterial() == e.getBlock().getType()) {
|
||||
if (!plugin.getAnchorManager().isReady(e.getBlock().getWorld())) {
|
||||
Settings.MATERIAL.getMaterial().parseMaterial() == e.getBlock().getType()) {
|
||||
if (!this.plugin.getAnchorManager().isReady(e.getBlock().getWorld())) {
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().sendMessage("Anchors are still being initialized - Please wait a moment"); // TODO
|
||||
} else {
|
||||
int ticksLeft = AnchorManager.getTicksFromItem(item);
|
||||
int ticksLeft = AnchorManagerImpl.getTicksFromItem(item);
|
||||
|
||||
if (ticksLeft != 0) {
|
||||
boolean dropOnErr = e.getPlayer().getGameMode() != GameMode.CREATIVE;
|
||||
|
||||
plugin.getAnchorManager().createAnchor(e.getBlock().getLocation(), e.getPlayer().getUniqueId(), ticksLeft,
|
||||
this.plugin.getAnchorManager().createAnchor(e.getBlock().getLocation(), e.getPlayer().getUniqueId(), ticksLeft,
|
||||
(ex, result) -> {
|
||||
if (ex != null) {
|
||||
Utils.logException(this.plugin, ex, "SQLite");
|
||||
Utils.logException(this.plugin, ex, "H2");
|
||||
e.getPlayer().sendMessage("Error creating anchor!"); // TODO
|
||||
|
||||
Bukkit.getScheduler().runTask(this.plugin, () -> {
|
||||
if (Settings.MATERIAL.getMaterial().getMaterial() == e.getBlock().getType()) {
|
||||
if (Settings.MATERIAL.getMaterial().parseMaterial() == e.getBlock().getType()) {
|
||||
e.getBlock().setType(Material.AIR);
|
||||
}
|
||||
|
||||
if (dropOnErr) {
|
||||
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(),
|
||||
plugin.getAnchorManager().createAnchorItem(ticksLeft, item.getType()));
|
||||
this.plugin.getAnchorManager().createAnchorItem(ticksLeft, item.getType()));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -72,16 +72,16 @@ public class AnchorListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockInteract(PlayerInteractEvent e) {
|
||||
if (e.getClickedBlock() == null ||
|
||||
!plugin.getAnchorManager().isReady(e.getClickedBlock().getWorld())) return;
|
||||
!this.plugin.getAnchorManager().isReady(e.getClickedBlock().getWorld())) return;
|
||||
|
||||
Player p = e.getPlayer();
|
||||
Anchor anchor = plugin.getAnchorManager().getAnchor(e.getClickedBlock());
|
||||
Anchor anchor = this.plugin.getAnchorManager().getAnchor(e.getClickedBlock());
|
||||
|
||||
if (anchor != null) {
|
||||
e.setCancelled(true);
|
||||
|
||||
if (p.hasPermission("EpicAnchors.admin") ||
|
||||
this.plugin.getAnchorManager().hasAccess(anchor, p)) {
|
||||
this.plugin.getAnchorManager().hasAccess(anchor, p.getUniqueId())) {
|
||||
if (e.getAction() == Action.LEFT_CLICK_BLOCK) { // Destroy anchor
|
||||
this.plugin.getGuiManager().showGUI(e.getPlayer(),
|
||||
new DestroyConfirmationGui(this.plugin, anchor, (ex, result) -> {
|
||||
@ -90,13 +90,13 @@ public class AnchorListener implements Listener {
|
||||
Bukkit.getPluginManager().callEvent(blockBreakEvent);
|
||||
|
||||
if (!blockBreakEvent.isCancelled()) {
|
||||
plugin.getAnchorManager().destroyAnchor(anchor);
|
||||
this.plugin.getAnchorManager().destroyAnchor(anchor);
|
||||
}
|
||||
}
|
||||
}));
|
||||
} else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { // Manage anchor
|
||||
ItemStack item = CompatibleHand.MAIN_HAND.getItem(e.getPlayer());
|
||||
int itemTicks = AnchorManager.getTicksFromItem(item);
|
||||
int itemTicks = AnchorManagerImpl.getTicksFromItem(item);
|
||||
|
||||
if (itemTicks != 0) {
|
||||
if (!anchor.isInfinite()) {
|
||||
@ -110,16 +110,16 @@ public class AnchorListener implements Listener {
|
||||
CompatibleHand.MAIN_HAND.takeItem(p, 1);
|
||||
}
|
||||
|
||||
p.playSound(p.getLocation(), CompatibleSound.ENTITY_PLAYER_LEVELUP.getSound(), .6F, 15);
|
||||
XSound.ENTITY_PLAYER_LEVELUP.play(p, .6f, 15);
|
||||
CompatibleParticleHandler.spawnParticles(CompatibleParticleHandler.ParticleType.getParticle(Settings.PARTICLE_UPGRADE.getString()),
|
||||
anchor.getLocation().add(.5, .5, .5), 100, .5, .5, .5);
|
||||
}
|
||||
} else {
|
||||
plugin.getGuiManager().showGUI(p, new AnchorGui(plugin, anchor));
|
||||
this.plugin.getGuiManager().showGUI(p, new AnchorGui(this.plugin, anchor));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plugin.getLocale().getMessage("event.general.nopermission").sendMessage(p);
|
||||
this.plugin.getLocale().getMessage("event.general.nopermission").sendMessage(p);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.songoda.epicanchors.listener;
|
||||
package com.craftaro.epicanchors.listener;
|
||||
|
||||
import com.songoda.epicanchors.AnchorManager;
|
||||
import com.craftaro.epicanchors.api.AnchorManager;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -22,7 +22,7 @@ public class BlockListener implements Listener {
|
||||
private void onBlockBurn(BlockBurnEvent e) {
|
||||
if (!this.manager.isReady(e.getBlock().getWorld())) return;
|
||||
|
||||
if (manager.isAnchor(e.getBlock())) {
|
||||
if (this.manager.isAnchor(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -31,7 +31,7 @@ public class BlockListener implements Listener {
|
||||
private void onBlockPiston(BlockPistonExtendEvent e) {
|
||||
if (!this.manager.isReady(e.getBlock().getWorld())) return;
|
||||
|
||||
if (manager.isAnchor(e.getBlock())) {
|
||||
if (this.manager.isAnchor(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -40,7 +40,7 @@ public class BlockListener implements Listener {
|
||||
private void onBlockPiston(BlockPistonRetractEvent e) {
|
||||
if (!this.manager.isReady(e.getBlock().getWorld())) return;
|
||||
|
||||
if (manager.isAnchor(e.getBlock())) {
|
||||
if (this.manager.isAnchor(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@ public class BlockListener implements Listener {
|
||||
private void onBlockPhysics(BlockPhysicsEvent e) {
|
||||
if (!this.manager.isReady(e.getBlock().getWorld())) return;
|
||||
|
||||
if (manager.isAnchor(e.getBlock())) {
|
||||
if (this.manager.isAnchor(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ public class BlockListener implements Listener {
|
||||
private void onBlockPiston(LeavesDecayEvent e) {
|
||||
if (!this.manager.isReady(e.getBlock().getWorld())) return;
|
||||
|
||||
if (manager.isAnchor(e.getBlock())) {
|
||||
if (this.manager.isAnchor(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -67,8 +67,8 @@ public class BlockListener implements Listener {
|
||||
public void onPortalCreation(PortalCreateEvent e) {
|
||||
if (!this.manager.isReady(e.getWorld())) return;
|
||||
|
||||
for (Block b : e.getBlocks()) {
|
||||
if (manager.isAnchor(b)) {
|
||||
for (Block block : e.getBlocks()) {
|
||||
if (this.manager.isAnchor(block)) {
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.songoda.epicanchors.listener;
|
||||
package com.craftaro.epicanchors.listener;
|
||||
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -83,22 +83,22 @@ public class DebugListener implements Listener {
|
||||
if (e.isSneaking()) {
|
||||
e.getPlayer().sendMessage("§e§lEntities");
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
count.compute(entity.getType().name(), (k, v) -> v == null ? 1 : v + 1);
|
||||
count.compute(entity.getType().name(), (key, value) -> value == null ? 1 : value + 1);
|
||||
}
|
||||
} else {
|
||||
e.getPlayer().sendMessage("§e§lTileEntities");
|
||||
for (BlockState blockState : chunk.getTileEntities()) {
|
||||
count.compute(blockState.getType().name(), (k, v) -> v == null ? 1 : v + 1);
|
||||
count.compute(blockState.getType().name(), (key, value) -> value == null ? 1 : value + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> m = count.entrySet().stream()
|
||||
Map<String, Integer> sortedEntitiyCount = count.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
||||
(e1, e2) -> e1, LinkedHashMap::new));
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
|
||||
for (Map.Entry<String, Integer> entry : m.entrySet()) {
|
||||
String entityName = WordUtils.capitalize(entry.getKey().toLowerCase(), new char[] {'_'}).replace("_", "");
|
||||
for (Map.Entry<String, Integer> entry : sortedEntitiyCount.entrySet()) {
|
||||
String entityName = WordUtils.capitalize(entry.getKey().toLowerCase(), new char[]{'_'}).replace("_", "");
|
||||
|
||||
e.getPlayer().sendMessage("§a" + entityName + "§7:§r " + entry.getValue());
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.songoda.epicanchors.listener;
|
||||
package com.craftaro.epicanchors.listener;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -20,11 +20,11 @@ public class WorldListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
private void onWorldLoad(WorldLoadEvent e) {
|
||||
initAnchorsInWorld.accept(e.getWorld());
|
||||
this.initAnchorsInWorld.accept(e.getWorld());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
private void onWorldUnload(WorldUnloadEvent e) {
|
||||
deInitAnchorsInWorld.accept(e.getWorld());
|
||||
this.deInitAnchorsInWorld.accept(e.getWorld());
|
||||
}
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
package com.craftaro.epicanchors.tasks;
|
||||
|
||||
import com.craftaro.core.nms.Nms;
|
||||
import com.craftaro.core.nms.UnsupportedServerVersionException;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.api.AnchorManager;
|
||||
import com.craftaro.epicanchors.utils.Utils;
|
||||
import com.craftaro.epicanchors.utils.WorldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* More information about what types of game ticks there are and what does what: https://minecraft.fandom.com/wiki/Tick
|
||||
*/
|
||||
public class AnchorTask extends BukkitRunnable {
|
||||
private static final int TASK_INTERVAL = 3;
|
||||
|
||||
private final EpicAnchors plugin;
|
||||
private final AnchorManager anchorManager;
|
||||
|
||||
private boolean randomTicksFailed;
|
||||
private boolean spawnerTicksFailed;
|
||||
|
||||
public AnchorTask(EpicAnchors plugin) {
|
||||
this.plugin = plugin;
|
||||
this.anchorManager = plugin.getAnchorManager();
|
||||
}
|
||||
|
||||
public void startTask() {
|
||||
runTaskTimer(this.plugin, TASK_INTERVAL, TASK_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
if (!this.anchorManager.isReady(world)) return;
|
||||
|
||||
int randomTicksToDo = WorldUtils.getRandomTickSpeed(world) * TASK_INTERVAL;
|
||||
|
||||
Set<Chunk> alreadyTicked = new HashSet<>();
|
||||
Anchor[] anchorsInWorld = this.anchorManager.getAnchors(world);
|
||||
List<Anchor> toUpdateHolo = new ArrayList<>(anchorsInWorld.length);
|
||||
|
||||
List<Chunk> chunksWithPlayers = getChunksWithPlayers(world);
|
||||
for (Anchor anchor : anchorsInWorld) {
|
||||
Chunk chunk = anchor.getChunk();
|
||||
|
||||
if (alreadyTicked.add(chunk)) {
|
||||
// Having a chunk loaded takes care of entities and weather (https://minecraft.fandom.com/wiki/Tick#Chunk_tick)
|
||||
loadChunk(chunk);
|
||||
|
||||
executeTicksForInactiveSpawners(chunk);
|
||||
|
||||
if (!chunksWithPlayers.contains(chunk)) {
|
||||
executeRandomTick(chunk, randomTicksToDo);
|
||||
}
|
||||
}
|
||||
|
||||
if (updateAnchorTimeLeftAndCheckIfHologramsNeedsUpdate(anchor)) {
|
||||
toUpdateHolo.add(anchor);
|
||||
}
|
||||
}
|
||||
|
||||
this.anchorManager.updateHolograms(toUpdateHolo);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Utils.logException(this.plugin, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Chunk> getChunksWithPlayers(World world) {
|
||||
List<Player> playersInWorld = world.getPlayers();
|
||||
|
||||
List<Chunk> chunksWithPlayers = new ArrayList<>(playersInWorld.size());
|
||||
for (Player p : playersInWorld) {
|
||||
chunksWithPlayers.add(p.getLocation().getChunk());
|
||||
}
|
||||
return chunksWithPlayers;
|
||||
}
|
||||
|
||||
private void loadChunk(Chunk chunk) {
|
||||
if (chunk.isLoaded()) {
|
||||
// Loading an already loaded chunk still fires the ChunkLoadEvent and might have a huge
|
||||
// impact on performance if other plugins do not expect that either...
|
||||
return;
|
||||
}
|
||||
|
||||
WorldUtils.loadAnchoredChunk(chunk, this.plugin);
|
||||
}
|
||||
|
||||
private void executeTicksForInactiveSpawners(Chunk chunk) {
|
||||
if (this.spawnerTicksFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Nms.getImplementations().getWorld().tickInactiveSpawners(chunk, TASK_INTERVAL);
|
||||
} catch (UnsupportedServerVersionException | ReflectiveOperationException | IncompatibleClassChangeError ex) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, ex,
|
||||
() -> "Failed to do spawner ticks on this server implementation(/version) - " +
|
||||
"Skipping further spawner ticks.");
|
||||
|
||||
this.spawnerTicksFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void executeRandomTick(Chunk chunk, int randomTicks) {
|
||||
if (this.randomTicksFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Nms.getImplementations().getWorld().randomTickChunk(chunk, randomTicks);
|
||||
} catch (UnsupportedServerVersionException | ReflectiveOperationException | IncompatibleClassChangeError ex) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, ex,
|
||||
() -> "Failed to do random ticks on this server implementation(/version) - " +
|
||||
"Skipping further random ticks.");
|
||||
|
||||
this.randomTicksFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateAnchorTimeLeftAndCheckIfHologramsNeedsUpdate(Anchor anchor) {
|
||||
// TODO: Only update hologram if a player is nearby
|
||||
// Simplify player location to chunks to potentially group players
|
||||
// Use the server view distance to calculate minimum distance to count as not-nearby
|
||||
|
||||
if (!anchor.isInfinite()) {
|
||||
int ticksLeft = anchor.removeTicksLeft(TASK_INTERVAL);
|
||||
|
||||
if (ticksLeft == 0) {
|
||||
this.anchorManager.destroyAnchor(anchor);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package com.songoda.epicanchors.tasks;
|
||||
package com.craftaro.epicanchors.tasks;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.epicanchors.EpicAnchors;
|
||||
import com.craftaro.epicanchors.api.Anchor;
|
||||
import com.craftaro.epicanchors.files.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -30,7 +30,7 @@ public class VisualizeTask extends BukkitRunnable {
|
||||
}
|
||||
|
||||
public void startTask() {
|
||||
runTaskTimer(plugin, TASK_INTERVAL, TASK_INTERVAL);
|
||||
runTaskTimer(this.plugin, TASK_INTERVAL, TASK_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,10 +55,10 @@ public class VisualizeTask extends BukkitRunnable {
|
||||
Location pLoc = p.getLocation();
|
||||
|
||||
// start and stop chunk coordinates
|
||||
int cxi = (pLoc.getBlockX() >> 4) - radius;
|
||||
int cxn = cxi + radius * 2;
|
||||
int czi = (pLoc.getBlockZ() >> 4) - radius;
|
||||
int czn = czi + radius * 2;
|
||||
int cxi = (pLoc.getBlockX() >> 4) - this.radius;
|
||||
int cxn = cxi + this.radius * 2;
|
||||
int czi = (pLoc.getBlockZ() >> 4) - this.radius;
|
||||
int czn = czi + this.radius * 2;
|
||||
|
||||
// loop through the chunks to find applicable ones
|
||||
for (int cx = cxi; cx < cxn; ++cx) {
|
||||
@ -66,7 +66,7 @@ public class VisualizeTask extends BukkitRunnable {
|
||||
Chunk chunk = world.getChunkAt(cx, cz);
|
||||
|
||||
if (loadedChunks.contains(chunk)) {
|
||||
chunksToVisualize.computeIfAbsent(chunk, k -> new HashSet<>())
|
||||
chunksToVisualize.computeIfAbsent(chunk, key -> new HashSet<>())
|
||||
.add(p);
|
||||
}
|
||||
}
|
||||
@ -91,17 +91,17 @@ public class VisualizeTask extends BukkitRunnable {
|
||||
startY = maxY - 1;
|
||||
}
|
||||
|
||||
Block b = entry.getKey().getBlock(x, startY, z);
|
||||
Block block = entry.getKey().getBlock(x, startY, z);
|
||||
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
if (b.getType().isSolid()) break;
|
||||
if (block.getType().isSolid()) break;
|
||||
|
||||
b = b.getRelative(BlockFace.DOWN);
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
if (!b.isEmpty() && !b.getRelative(BlockFace.UP).getType().isOccluding()) {
|
||||
if (!block.isEmpty() && !block.getRelative(BlockFace.UP).getType().isOccluding()) {
|
||||
CompatibleParticleHandler.spawnParticles(particleType,
|
||||
b.getLocation().add(.5, 1.5, .5),
|
||||
block.getLocation().add(.5, 1.5, .5),
|
||||
0, 0, 0, 0, 1, p);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.songoda.epicanchors.utils;
|
||||
package com.craftaro.epicanchors.utils;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@ -7,10 +7,10 @@ public class ThreadSync {
|
||||
private final AtomicReference<Boolean> waiting = new AtomicReference<>(true);
|
||||
|
||||
public void waitForRelease() {
|
||||
synchronized (syncObj) {
|
||||
while (waiting.get()) {
|
||||
synchronized (this.syncObj) {
|
||||
while (this.waiting.get()) {
|
||||
try {
|
||||
syncObj.wait();
|
||||
this.syncObj.wait();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
@ -18,13 +18,13 @@ public class ThreadSync {
|
||||
}
|
||||
|
||||
public void release() {
|
||||
synchronized (syncObj) {
|
||||
waiting.set(false);
|
||||
syncObj.notifyAll();
|
||||
synchronized (this.syncObj) {
|
||||
this.waiting.set(false);
|
||||
this.syncObj.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
waiting.set(true);
|
||||
this.waiting.set(true);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.songoda.epicanchors.utils;
|
||||
package com.craftaro.epicanchors.utils;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.songoda.epicanchors.utils;
|
||||
package com.craftaro.epicanchors.utils;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
@ -1,4 +1,4 @@
|
||||
package com.songoda.epicanchors.utils;
|
||||
package com.craftaro.epicanchors.utils;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
@ -1,17 +1,18 @@
|
||||
name: ${project.name}
|
||||
description: ${project.description}
|
||||
name: ${project.parent.name}
|
||||
description: ${project.parent.description}
|
||||
version: ${project.version}
|
||||
api-version: 1.13
|
||||
|
||||
main: com.songoda.epicanchors.EpicAnchors
|
||||
main: com.craftaro.epicanchors.EpicAnchors
|
||||
softdepend:
|
||||
- Holograms
|
||||
- HolographicDisplays
|
||||
- Vault
|
||||
- DecentHolograms
|
||||
|
||||
author: Songoda
|
||||
author: Craftaro
|
||||
authors: [ SpraxDev ]
|
||||
website: ${project.url}
|
||||
website: ${project.parent.url}
|
||||
|
||||
commands:
|
||||
EpicAnchors:
|
143
pom.xml
143
pom.xml
@ -4,154 +4,63 @@
|
||||
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>
|
||||
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>EpicAnchors</artifactId>
|
||||
<version>2.2.7</version>
|
||||
<groupId>com.craftaro</groupId>
|
||||
<artifactId>EpicAnchors-Parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.1.1</version>
|
||||
<!-- Run 'mvn versions:set -DgenerateBackupPoms=false -DnewVersion=X.Y.Z-DEV' to update version recursively -->
|
||||
|
||||
<modules>
|
||||
<module>EpicAnchors-API</module>
|
||||
<module>EpicAnchors-Plugin</module>
|
||||
</modules>
|
||||
|
||||
<name>EpicAnchors</name>
|
||||
<description>Allow your players to keep chunks loaded for a limited amount of time for a cost.</description>
|
||||
<url>https://songoda.com/marketplace/product/31</url>
|
||||
<url>https://craftaro.com/marketplace/product/31</url>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<java.release>8</java.release>
|
||||
<craftaro.coreVersion>3.0.1-SNAPSHOT</craftaro.coreVersion>
|
||||
|
||||
<maven.compiler.release>8</maven.compiler.release>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<sonar.projectKey>songoda_EpicAnchors</sonar.projectKey>
|
||||
<sonar.organization>songoda</sonar.organization>
|
||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
||||
<sonar.moduleKey>${project.groupId}:${project.artifactId}</sonar.moduleKey>
|
||||
</properties>
|
||||
|
||||
<issueManagement>
|
||||
<url>https://support.songoda.com/servicedesk/customer/portal/3</url>
|
||||
<system>Jira Service Desk</system>
|
||||
<url>https://discord.gg/craftaro</url>
|
||||
<system>Discord server</system>
|
||||
</issueManagement>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/songoda/EpicAnchors</url>
|
||||
<connection>scm:git:git:github.com/songoda/EpicAnchors.git</connection>
|
||||
<url>https://github.com/craftaro/EpicAnchors</url>
|
||||
<connection>scm:git:git://github.com/craftaro/EpicAnchors.git</connection>
|
||||
</scm>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
|
||||
<release>${java.release}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
|
||||
<configuration>
|
||||
<finalName>${project.name}-${project.version}</finalName>
|
||||
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>com.songoda.core</pattern>
|
||||
<shadedPattern>com.songoda.epicanchors.core</shadedPattern>
|
||||
</relocation>
|
||||
|
||||
<relocation>
|
||||
<pattern>epicanchors.nms</pattern>
|
||||
<shadedPattern>com.songoda.epicanchors.nms</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
|
||||
<excludes>
|
||||
<exclude>META-INF/**</exclude>
|
||||
<exclude>LICENSE</exclude>
|
||||
<exclude>LICENSE.**</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<artifact>org.jetbrains:annotations</artifact>
|
||||
<excludes>
|
||||
<exclude>**</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<artifact>com.songoda:epicanchors-v*</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigotmc-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
<id>craftaro-minecraft-plugins</id>
|
||||
<url>https://repo.craftaro.com/repository/minecraft-plugins/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>songoda-public</id>
|
||||
<url>https://repo.songoda.com/repository/public/</url>
|
||||
<id>SpigotMC</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore</artifactId>
|
||||
<version>2.6.20</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Dev dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.0.1</version>
|
||||
<scope>compile</scope>
|
||||
<version>24.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -1,30 +0,0 @@
|
||||
package com.songoda.epicanchors.files.migration;
|
||||
|
||||
import com.songoda.core.database.DataMigration;
|
||||
import com.songoda.epicanchors.files.DataManager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class _1_InitialMigration extends DataMigration {
|
||||
public _1_InitialMigration() {
|
||||
super(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void migrate(Connection connection, String tablePrefix) throws SQLException {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute("CREATE TABLE " + DataManager.getTableName(tablePrefix, "anchors") + "(" +
|
||||
"id INTEGER NOT NULL," +
|
||||
"world_name TEXT NOT NULL," +
|
||||
"x INTEGER NOT NULL," +
|
||||
"y INTEGER NOT NULL," +
|
||||
"z INTEGER NOT NULL," +
|
||||
"ticks_left INTEGER NOT NULL," +
|
||||
"owner VARCHAR(36)," +
|
||||
"PRIMARY KEY(id AUTOINCREMENT)" +
|
||||
");");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.songoda.epicanchors.guis;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.gui.Gui;
|
||||
import com.songoda.core.gui.GuiUtils;
|
||||
import com.songoda.core.gui.methods.Closable;
|
||||
import com.songoda.core.utils.TextUtils;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
|
||||
public class DestroyConfirmationGui extends Gui {
|
||||
private final EpicAnchors plugin;
|
||||
private final Anchor anchor;
|
||||
|
||||
private Callback<Boolean> handler;
|
||||
|
||||
public DestroyConfirmationGui(EpicAnchors plugin, Anchor anchor, Callback<Boolean> callback) {
|
||||
this.plugin = plugin;
|
||||
this.anchor = anchor;
|
||||
|
||||
this.handler = (ex, result) -> {
|
||||
this.handler = null;
|
||||
this.close();
|
||||
|
||||
callback.accept(ex, result);
|
||||
};
|
||||
|
||||
this.setRows(3);
|
||||
this.setTitle(TextUtils.formatText(plugin.getLocale().getMessage("interface.anchor.title").getMessage()));
|
||||
|
||||
constructGUI();
|
||||
AnchorGui.runPreparedGuiTask(this.plugin, this, this.anchor);
|
||||
|
||||
Closable currClosable = this.closer;
|
||||
this.closer = event -> {
|
||||
currClosable.onClose(event);
|
||||
|
||||
if (this.handler != null) {
|
||||
this.handler.accept(null, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void constructGUI() {
|
||||
AnchorGui.prepareGui(this.plugin, this, this.anchor);
|
||||
|
||||
String cancelLore = plugin.getLocale().getMessage("interface.button.cancelDestroyLore").getMessage();
|
||||
String confirmLore = plugin.getLocale().getMessage("interface.button." +
|
||||
(Settings.ALLOW_ANCHOR_BREAKING.getBoolean() ? "confirmDestroyLore" : "confirmDestroyLoreNoDrops"))
|
||||
.getMessage();
|
||||
|
||||
setButton(11, GuiUtils.createButtonItem(CompatibleMaterial.RED_TERRACOTTA,
|
||||
plugin.getLocale().getMessage("interface.button.cancelDestroy").getMessage(),
|
||||
cancelLore.isEmpty() ? new String[0] : new String[] {cancelLore}),
|
||||
event -> this.handler.accept(null, false));
|
||||
|
||||
setButton(15, GuiUtils.createButtonItem(CompatibleMaterial.GREEN_TERRACOTTA,
|
||||
plugin.getLocale().getMessage("interface.button.confirmDestroy").getMessage(),
|
||||
confirmLore.isEmpty() ? new String[0] : new String[] {confirmLore}),
|
||||
event -> this.handler.accept(null, true));
|
||||
}
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
package com.songoda.epicanchors.tasks;
|
||||
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.AnchorManager;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.utils.Utils;
|
||||
import com.songoda.epicanchors.utils.WorldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* More information about what types of game ticks there are and what does what: https://minecraft.fandom.com/wiki/Tick
|
||||
*/
|
||||
public class AnchorTask extends BukkitRunnable {
|
||||
private static final int TASK_INTERVAL = 3;
|
||||
|
||||
private final EpicAnchors plugin;
|
||||
private final AnchorManager anchorManager;
|
||||
|
||||
private boolean randomTicksFailed;
|
||||
private boolean spawnerTicksFailed;
|
||||
|
||||
public AnchorTask(EpicAnchors plugin) {
|
||||
this.plugin = plugin;
|
||||
this.anchorManager = plugin.getAnchorManager();
|
||||
}
|
||||
|
||||
public void startTask() {
|
||||
runTaskTimer(this.plugin, TASK_INTERVAL, TASK_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
if (!this.anchorManager.isReady(world)) return;
|
||||
|
||||
int randomTicks = WorldUtils.getRandomTickSpeed(world) * TASK_INTERVAL;
|
||||
|
||||
Set<Chunk> alreadyTicked = new HashSet<>();
|
||||
Anchor[] anchorsInWorld = this.anchorManager.getAnchors(world);
|
||||
List<Anchor> toUpdateHolo = new ArrayList<>(anchorsInWorld.length);
|
||||
|
||||
// Skip all chunks with players in them
|
||||
for (Player pInWorld : world.getPlayers()) {
|
||||
alreadyTicked.add(pInWorld.getLocation().getChunk());
|
||||
}
|
||||
|
||||
for (Anchor anchor : anchorsInWorld) {
|
||||
Chunk chunk = anchor.getChunk();
|
||||
|
||||
// Tick the anchor's chunk (but not multiple times)
|
||||
if (alreadyTicked.add(chunk)) {
|
||||
// Having a chunk loaded takes care of entities and weather (https://minecraft.fandom.com/wiki/Tick#Chunk_tick)
|
||||
if (!chunk.isLoaded()) {
|
||||
// Loading an already loaded chunk still fires the ChunkLoadEvent and might have a huge
|
||||
// impact on performance if other plugins do not expect that either...
|
||||
|
||||
WorldUtils.loadAnchoredChunk(chunk, this.plugin);
|
||||
}
|
||||
|
||||
if (!randomTicksFailed) {
|
||||
try {
|
||||
NmsManager.getWorld().randomTickChunk(chunk, randomTicks);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, ex,
|
||||
() -> "Failed to do random ticks on this server implementation(/version) - " +
|
||||
"Skipping further random ticks.");
|
||||
|
||||
randomTicksFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!spawnerTicksFailed) {
|
||||
try {
|
||||
NmsManager.getWorld().tickInactiveSpawners(chunk, TASK_INTERVAL);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, ex,
|
||||
() -> "Failed to do spawner ticks on this server implementation(/version) - " +
|
||||
"Skipping further spawner ticks.");
|
||||
|
||||
spawnerTicksFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Only update hologram if a player is nearby
|
||||
// Simplify player location to chunks to potentially group players
|
||||
// Use the server view distance to calculate minimum distance to count as not-nearby
|
||||
|
||||
// Destroy anchors and queue hologram update
|
||||
if (!anchor.isInfinite()) {
|
||||
int ticksLeft = anchor.removeTicksLeft(3);
|
||||
|
||||
if (ticksLeft == 0) {
|
||||
this.anchorManager.destroyAnchor(anchor);
|
||||
} else {
|
||||
toUpdateHolo.add(anchor);
|
||||
}
|
||||
} else {
|
||||
toUpdateHolo.add(anchor);
|
||||
}
|
||||
}
|
||||
|
||||
// Update holograms on queued anchors
|
||||
anchorManager.updateHolograms(toUpdateHolo);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Utils.logException(this.plugin, ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.songoda.epicanchors.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ReflectionUtils {
|
||||
private ReflectionUtils() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static Object getFieldValue(Object instance, String fieldName) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field f = getField(instance, fieldName);
|
||||
boolean accessible = f.isAccessible();
|
||||
|
||||
f.setAccessible(true);
|
||||
|
||||
Object result = f.get(instance);
|
||||
|
||||
f.setAccessible(accessible);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void setFieldValue(Object instance, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field f = getField(instance, fieldName);
|
||||
boolean accessible = f.isAccessible();
|
||||
|
||||
f.setAccessible(true);
|
||||
|
||||
f.set(instance, value);
|
||||
|
||||
f.setAccessible(accessible);
|
||||
}
|
||||
|
||||
private static Field getField(Object instance, String fieldName) throws NoSuchFieldException {
|
||||
Field f = null;
|
||||
|
||||
Class<?> currClass = instance.getClass();
|
||||
do {
|
||||
try {
|
||||
f = currClass.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException ex) {
|
||||
currClass = currClass.getSuperclass();
|
||||
|
||||
if (currClass == null) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
} while (f == null);
|
||||
|
||||
return f;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user