mirror of
https://github.com/songoda/SongodaCore.git
synced 2024-11-27 04:25:19 +01:00
Merge branch 'development'
This commit is contained in:
commit
cfdebcba56
736
.editorconfig
736
.editorconfig
@ -1,3 +1,7 @@
|
||||
# This EditorConfig aims to achieve compact code while allowing a file's content to be understood easily
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
@ -15,8 +19,127 @@ ij_smart_tabs = false
|
||||
ij_visual_guides = none
|
||||
ij_wrap_on_typing = false
|
||||
|
||||
|
||||
##
|
||||
# Common file formats
|
||||
##
|
||||
[*.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
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
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
|
||||
|
||||
[{*.json,*.graphqlconfig,*.har,*.jsb2,*.jsb3,*.webmanifest,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
|
||||
indent_size = 2
|
||||
ij_json_keep_blank_lines_in_code = 0
|
||||
ij_json_keep_indents_on_empty_lines = false
|
||||
ij_json_keep_line_breaks = true
|
||||
ij_json_space_after_colon = true
|
||||
ij_json_space_after_comma = true
|
||||
ij_json_space_before_colon = true
|
||||
ij_json_space_before_comma = false
|
||||
ij_json_spaces_within_braces = false
|
||||
ij_json_spaces_within_brackets = false
|
||||
ij_json_wrap_long_lines = false
|
||||
|
||||
[{*.xml,*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.mpd,*.pom,*.rng,*.tld,*.wsdl,*.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
|
||||
# TODO: Not happy with this yet
|
||||
##
|
||||
[{*.markdown,*.md}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_continuation_indent_size = 4
|
||||
|
||||
|
||||
##
|
||||
# HTML + CSS
|
||||
##
|
||||
[{*.html,*.htm,*.ng,*.sht,*.shtm,*.shtml}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_continuation_indent_size = 4
|
||||
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
|
||||
ij_html_align_attributes = true
|
||||
ij_html_align_text = false
|
||||
ij_html_attribute_wrap = normal
|
||||
ij_html_block_comment_at_first_column = true
|
||||
ij_html_do_not_align_children_of_min_lines = 0
|
||||
ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p, li
|
||||
ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
|
||||
ij_html_enforce_quotes = true
|
||||
ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
|
||||
ij_html_keep_blank_lines = 2
|
||||
ij_html_keep_indents_on_empty_lines = false
|
||||
ij_html_keep_line_breaks = true
|
||||
ij_html_keep_line_breaks_in_text = true
|
||||
ij_html_keep_whitespaces = false
|
||||
ij_html_keep_whitespaces_inside = span, pre, textarea
|
||||
ij_html_line_comment_at_first_column = true
|
||||
ij_html_new_line_after_last_attribute = never
|
||||
ij_html_new_line_before_first_attribute = never
|
||||
ij_html_quote_style = double
|
||||
ij_html_remove_new_line_before_tags = br
|
||||
ij_html_space_after_tag_name = false
|
||||
ij_html_space_around_equality_in_attribute = false
|
||||
ij_html_space_inside_empty_tag = false
|
||||
ij_html_text_wrap = normal
|
||||
|
||||
[*.css]
|
||||
ij_css_align_closing_brace_with_properties = false
|
||||
ij_css_blank_lines_around_nested_selector = 1
|
||||
ij_css_blank_lines_between_blocks = 1
|
||||
ij_css_brace_placement = end_of_line
|
||||
ij_css_enforce_quotes_on_format = true
|
||||
ij_css_hex_color_long_format = false
|
||||
ij_css_hex_color_lower_case = true
|
||||
ij_css_hex_color_short_format = true
|
||||
ij_css_hex_color_upper_case = false
|
||||
ij_css_keep_blank_lines_in_code = 2
|
||||
ij_css_keep_indents_on_empty_lines = false
|
||||
ij_css_keep_single_line_blocks = false
|
||||
ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
|
||||
ij_css_space_after_colon = true
|
||||
ij_css_space_before_opening_brace = true
|
||||
ij_css_use_double_quotes = true
|
||||
ij_css_value_alignment = on_value
|
||||
|
||||
##
|
||||
# Java + Gradle
|
||||
##
|
||||
[*.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
|
||||
@ -71,7 +194,7 @@ 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_count_to_use_import_on_demand = 999
|
||||
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
|
||||
@ -79,10 +202,10 @@ 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_add_p_tag_on_empty_lines = false
|
||||
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_do_not_wrap_if_one_line = false
|
||||
ij_java_doc_enable_formatting = true
|
||||
ij_java_doc_enable_leading_asterisks = true
|
||||
ij_java_doc_indent_on_continuation = true
|
||||
@ -111,10 +234,10 @@ 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_blank_lines_before_right_brace = 2
|
||||
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||
ij_java_keep_blank_lines_in_code = 2
|
||||
ij_java_keep_blank_lines_in_declarations = 2
|
||||
ij_java_keep_builder_methods_indents = false
|
||||
ij_java_keep_control_statement_in_one_line = true
|
||||
ij_java_keep_first_column_comment = true
|
||||
@ -122,9 +245,9 @@ 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_keep_simple_classes_in_one_line = false
|
||||
ij_java_keep_simple_lambdas_in_one_line = false
|
||||
ij_java_keep_simple_methods_in_one_line = false
|
||||
ij_java_label_indent_absolute = false
|
||||
ij_java_label_indent_size = 0
|
||||
ij_java_lambda_brace_style = end_of_line
|
||||
@ -138,9 +261,9 @@ 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_names_count_to_use_import_on_demand = 999
|
||||
ij_java_new_line_after_lparen_in_record_header = false
|
||||
ij_java_packages_to_use_import_on_demand = _java.awt.*, _javax.swing.*
|
||||
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
|
||||
@ -199,7 +322,7 @@ 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_array_initializer_braces = false
|
||||
ij_java_space_within_empty_method_call_parentheses = false
|
||||
ij_java_space_within_empty_method_parentheses = false
|
||||
ij_java_spaces_around_additive_operators = true
|
||||
@ -217,7 +340,7 @@ 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_braces = false
|
||||
ij_java_spaces_within_brackets = false
|
||||
ij_java_spaces_within_cast_parentheses = false
|
||||
ij_java_spaces_within_catch_parentheses = false
|
||||
@ -250,12 +373,539 @@ 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
|
||||
[{*.gradle,*.gant,*.groovy,*.gy}]
|
||||
ij_groovy_align_group_field_declarations = false
|
||||
ij_groovy_align_multiline_array_initializer_expression = false
|
||||
ij_groovy_align_multiline_assignment = false
|
||||
ij_groovy_align_multiline_binary_operation = false
|
||||
ij_groovy_align_multiline_chained_methods = false
|
||||
ij_groovy_align_multiline_extends_list = false
|
||||
ij_groovy_align_multiline_for = true
|
||||
ij_groovy_align_multiline_list_or_map = true
|
||||
ij_groovy_align_multiline_method_parentheses = false
|
||||
ij_groovy_align_multiline_parameters = true
|
||||
ij_groovy_align_multiline_parameters_in_calls = false
|
||||
ij_groovy_align_multiline_resources = true
|
||||
ij_groovy_align_multiline_ternary_operation = false
|
||||
ij_groovy_align_multiline_throws_list = false
|
||||
ij_groovy_align_named_args_in_map = true
|
||||
ij_groovy_align_throws_keyword = false
|
||||
ij_groovy_array_initializer_new_line_after_left_brace = false
|
||||
ij_groovy_array_initializer_right_brace_on_new_line = false
|
||||
ij_groovy_array_initializer_wrap = off
|
||||
ij_groovy_assert_statement_wrap = off
|
||||
ij_groovy_assignment_wrap = off
|
||||
ij_groovy_binary_operation_wrap = off
|
||||
ij_groovy_blank_lines_after_class_header = 0
|
||||
ij_groovy_blank_lines_after_imports = 1
|
||||
ij_groovy_blank_lines_after_package = 1
|
||||
ij_groovy_blank_lines_around_class = 1
|
||||
ij_groovy_blank_lines_around_field = 0
|
||||
ij_groovy_blank_lines_around_field_in_interface = 0
|
||||
ij_groovy_blank_lines_around_method = 1
|
||||
ij_groovy_blank_lines_around_method_in_interface = 1
|
||||
ij_groovy_blank_lines_before_imports = 1
|
||||
ij_groovy_blank_lines_before_method_body = 0
|
||||
ij_groovy_blank_lines_before_package = 0
|
||||
ij_groovy_block_brace_style = end_of_line
|
||||
ij_groovy_block_comment_at_first_column = true
|
||||
ij_groovy_call_parameters_new_line_after_left_paren = false
|
||||
ij_groovy_call_parameters_right_paren_on_new_line = false
|
||||
ij_groovy_call_parameters_wrap = off
|
||||
ij_groovy_catch_on_new_line = false
|
||||
ij_groovy_class_annotation_wrap = split_into_lines
|
||||
ij_groovy_class_brace_style = end_of_line
|
||||
ij_groovy_class_count_to_use_import_on_demand = 5
|
||||
ij_groovy_do_while_brace_force = never
|
||||
ij_groovy_else_on_new_line = false
|
||||
ij_groovy_enum_constants_wrap = off
|
||||
ij_groovy_extends_keyword_wrap = off
|
||||
ij_groovy_extends_list_wrap = off
|
||||
ij_groovy_field_annotation_wrap = split_into_lines
|
||||
ij_groovy_finally_on_new_line = false
|
||||
ij_groovy_for_brace_force = never
|
||||
ij_groovy_for_statement_new_line_after_left_paren = false
|
||||
ij_groovy_for_statement_right_paren_on_new_line = false
|
||||
ij_groovy_for_statement_wrap = off
|
||||
ij_groovy_if_brace_force = never
|
||||
ij_groovy_import_annotation_wrap = 2
|
||||
ij_groovy_imports_layout = *, |, javax.**, java.**, |, $*
|
||||
ij_groovy_indent_case_from_switch = true
|
||||
ij_groovy_indent_label_blocks = true
|
||||
ij_groovy_insert_inner_class_imports = false
|
||||
ij_groovy_keep_blank_lines_before_right_brace = 2
|
||||
ij_groovy_keep_blank_lines_in_code = 2
|
||||
ij_groovy_keep_blank_lines_in_declarations = 2
|
||||
ij_groovy_keep_control_statement_in_one_line = true
|
||||
ij_groovy_keep_first_column_comment = true
|
||||
ij_groovy_keep_indents_on_empty_lines = false
|
||||
ij_groovy_keep_line_breaks = true
|
||||
ij_groovy_keep_multiple_expressions_in_one_line = false
|
||||
ij_groovy_keep_simple_blocks_in_one_line = false
|
||||
ij_groovy_keep_simple_classes_in_one_line = true
|
||||
ij_groovy_keep_simple_lambdas_in_one_line = true
|
||||
ij_groovy_keep_simple_methods_in_one_line = true
|
||||
ij_groovy_label_indent_absolute = false
|
||||
ij_groovy_label_indent_size = 0
|
||||
ij_groovy_lambda_brace_style = end_of_line
|
||||
ij_groovy_layout_static_imports_separately = true
|
||||
ij_groovy_line_comment_add_space = false
|
||||
ij_groovy_line_comment_at_first_column = true
|
||||
ij_groovy_method_annotation_wrap = split_into_lines
|
||||
ij_groovy_method_brace_style = end_of_line
|
||||
ij_groovy_method_call_chain_wrap = off
|
||||
ij_groovy_method_parameters_new_line_after_left_paren = false
|
||||
ij_groovy_method_parameters_right_paren_on_new_line = false
|
||||
ij_groovy_method_parameters_wrap = off
|
||||
ij_groovy_modifier_list_wrap = false
|
||||
ij_groovy_names_count_to_use_import_on_demand = 3
|
||||
ij_groovy_parameter_annotation_wrap = off
|
||||
ij_groovy_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_groovy_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_groovy_prefer_parameters_wrap = false
|
||||
ij_groovy_resource_list_new_line_after_left_paren = false
|
||||
ij_groovy_resource_list_right_paren_on_new_line = false
|
||||
ij_groovy_resource_list_wrap = off
|
||||
ij_groovy_space_after_assert_separator = true
|
||||
ij_groovy_space_after_colon = true
|
||||
ij_groovy_space_after_comma = true
|
||||
ij_groovy_space_after_comma_in_type_arguments = true
|
||||
ij_groovy_space_after_for_semicolon = true
|
||||
ij_groovy_space_after_quest = true
|
||||
ij_groovy_space_after_type_cast = true
|
||||
ij_groovy_space_before_annotation_parameter_list = false
|
||||
ij_groovy_space_before_array_initializer_left_brace = false
|
||||
ij_groovy_space_before_assert_separator = false
|
||||
ij_groovy_space_before_catch_keyword = true
|
||||
ij_groovy_space_before_catch_left_brace = true
|
||||
ij_groovy_space_before_catch_parentheses = true
|
||||
ij_groovy_space_before_class_left_brace = true
|
||||
ij_groovy_space_before_closure_left_brace = true
|
||||
ij_groovy_space_before_colon = true
|
||||
ij_groovy_space_before_comma = false
|
||||
ij_groovy_space_before_do_left_brace = true
|
||||
ij_groovy_space_before_else_keyword = true
|
||||
ij_groovy_space_before_else_left_brace = true
|
||||
ij_groovy_space_before_finally_keyword = true
|
||||
ij_groovy_space_before_finally_left_brace = true
|
||||
ij_groovy_space_before_for_left_brace = true
|
||||
ij_groovy_space_before_for_parentheses = true
|
||||
ij_groovy_space_before_for_semicolon = false
|
||||
ij_groovy_space_before_if_left_brace = true
|
||||
ij_groovy_space_before_if_parentheses = true
|
||||
ij_groovy_space_before_method_call_parentheses = false
|
||||
ij_groovy_space_before_method_left_brace = true
|
||||
ij_groovy_space_before_method_parentheses = false
|
||||
ij_groovy_space_before_quest = true
|
||||
ij_groovy_space_before_switch_left_brace = true
|
||||
ij_groovy_space_before_switch_parentheses = true
|
||||
ij_groovy_space_before_synchronized_left_brace = true
|
||||
ij_groovy_space_before_synchronized_parentheses = true
|
||||
ij_groovy_space_before_try_left_brace = true
|
||||
ij_groovy_space_before_try_parentheses = true
|
||||
ij_groovy_space_before_while_keyword = true
|
||||
ij_groovy_space_before_while_left_brace = true
|
||||
ij_groovy_space_before_while_parentheses = true
|
||||
ij_groovy_space_in_named_argument = true
|
||||
ij_groovy_space_in_named_argument_before_colon = false
|
||||
ij_groovy_space_within_empty_array_initializer_braces = false
|
||||
ij_groovy_space_within_empty_method_call_parentheses = false
|
||||
ij_groovy_spaces_around_additive_operators = true
|
||||
ij_groovy_spaces_around_assignment_operators = true
|
||||
ij_groovy_spaces_around_bitwise_operators = true
|
||||
ij_groovy_spaces_around_equality_operators = true
|
||||
ij_groovy_spaces_around_lambda_arrow = true
|
||||
ij_groovy_spaces_around_logical_operators = true
|
||||
ij_groovy_spaces_around_multiplicative_operators = true
|
||||
ij_groovy_spaces_around_regex_operators = true
|
||||
ij_groovy_spaces_around_relational_operators = true
|
||||
ij_groovy_spaces_around_shift_operators = true
|
||||
ij_groovy_spaces_within_annotation_parentheses = false
|
||||
ij_groovy_spaces_within_array_initializer_braces = false
|
||||
ij_groovy_spaces_within_braces = true
|
||||
ij_groovy_spaces_within_brackets = false
|
||||
ij_groovy_spaces_within_cast_parentheses = false
|
||||
ij_groovy_spaces_within_catch_parentheses = false
|
||||
ij_groovy_spaces_within_for_parentheses = false
|
||||
ij_groovy_spaces_within_gstring_injection_braces = false
|
||||
ij_groovy_spaces_within_if_parentheses = false
|
||||
ij_groovy_spaces_within_list_or_map = false
|
||||
ij_groovy_spaces_within_method_call_parentheses = false
|
||||
ij_groovy_spaces_within_method_parentheses = false
|
||||
ij_groovy_spaces_within_parentheses = false
|
||||
ij_groovy_spaces_within_switch_parentheses = false
|
||||
ij_groovy_spaces_within_synchronized_parentheses = false
|
||||
ij_groovy_spaces_within_try_parentheses = false
|
||||
ij_groovy_spaces_within_tuple_expression = false
|
||||
ij_groovy_spaces_within_while_parentheses = false
|
||||
ij_groovy_special_else_if_treatment = true
|
||||
ij_groovy_ternary_operation_wrap = off
|
||||
ij_groovy_throws_keyword_wrap = off
|
||||
ij_groovy_throws_list_wrap = off
|
||||
ij_groovy_use_flying_geese_braces = false
|
||||
ij_groovy_use_fq_class_names = false
|
||||
ij_groovy_use_fq_class_names_in_javadoc = true
|
||||
ij_groovy_use_relative_indents = false
|
||||
ij_groovy_use_single_class_imports = true
|
||||
ij_groovy_variable_annotation_wrap = off
|
||||
ij_groovy_while_brace_force = never
|
||||
ij_groovy_while_on_new_line = false
|
||||
ij_groovy_wrap_chain_calls_after_dot = false
|
||||
ij_groovy_wrap_long_lines = false
|
||||
|
||||
|
||||
##
|
||||
# TypeScript / JavaScript
|
||||
##
|
||||
[{*.ts,*.ats}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_continuation_indent_size = 4
|
||||
ij_typescript_align_imports = false
|
||||
ij_typescript_align_multiline_array_initializer_expression = false
|
||||
ij_typescript_align_multiline_binary_operation = false
|
||||
ij_typescript_align_multiline_chained_methods = false
|
||||
ij_typescript_align_multiline_extends_list = false
|
||||
ij_typescript_align_multiline_for = true
|
||||
ij_typescript_align_multiline_parameters = true
|
||||
ij_typescript_align_multiline_parameters_in_calls = false
|
||||
ij_typescript_align_multiline_ternary_operation = false
|
||||
ij_typescript_align_object_properties = 0
|
||||
ij_typescript_align_union_types = false
|
||||
ij_typescript_align_var_statements = 0
|
||||
ij_typescript_array_initializer_new_line_after_left_brace = false
|
||||
ij_typescript_array_initializer_right_brace_on_new_line = false
|
||||
ij_typescript_array_initializer_wrap = off
|
||||
ij_typescript_assignment_wrap = off
|
||||
ij_typescript_binary_operation_sign_on_next_line = false
|
||||
ij_typescript_binary_operation_wrap = off
|
||||
ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
|
||||
ij_typescript_blank_lines_after_imports = 1
|
||||
ij_typescript_blank_lines_around_class = 1
|
||||
ij_typescript_blank_lines_around_field = 0
|
||||
ij_typescript_blank_lines_around_field_in_interface = 0
|
||||
ij_typescript_blank_lines_around_function = 1
|
||||
ij_typescript_blank_lines_around_method = 1
|
||||
ij_typescript_blank_lines_around_method_in_interface = 1
|
||||
ij_typescript_block_brace_style = end_of_line
|
||||
ij_typescript_call_parameters_new_line_after_left_paren = false
|
||||
ij_typescript_call_parameters_right_paren_on_new_line = false
|
||||
ij_typescript_call_parameters_wrap = off
|
||||
ij_typescript_catch_on_new_line = false
|
||||
ij_typescript_chained_call_dot_on_new_line = true
|
||||
ij_typescript_class_brace_style = end_of_line
|
||||
ij_typescript_comma_on_new_line = false
|
||||
ij_typescript_do_while_brace_force = never
|
||||
ij_typescript_else_on_new_line = false
|
||||
ij_typescript_enforce_trailing_comma = remove
|
||||
ij_typescript_extends_keyword_wrap = off
|
||||
ij_typescript_extends_list_wrap = off
|
||||
ij_typescript_field_prefix = _
|
||||
ij_typescript_file_name_style = relaxed
|
||||
ij_typescript_finally_on_new_line = false
|
||||
ij_typescript_for_brace_force = never
|
||||
ij_typescript_for_statement_new_line_after_left_paren = false
|
||||
ij_typescript_for_statement_right_paren_on_new_line = false
|
||||
ij_typescript_for_statement_wrap = off
|
||||
ij_typescript_force_quote_style = true
|
||||
ij_typescript_force_semicolon_style = true
|
||||
ij_typescript_function_expression_brace_style = end_of_line
|
||||
ij_typescript_if_brace_force = never
|
||||
ij_typescript_import_merge_members = global
|
||||
ij_typescript_import_prefer_absolute_path = global
|
||||
ij_typescript_import_sort_members = true
|
||||
ij_typescript_import_sort_module_name = true
|
||||
ij_typescript_import_use_node_resolution = true
|
||||
ij_typescript_imports_wrap = on_every_item
|
||||
ij_typescript_indent_case_from_switch = true
|
||||
ij_typescript_indent_chained_calls = true
|
||||
ij_typescript_indent_package_children = 0
|
||||
ij_typescript_jsdoc_include_types = false
|
||||
ij_typescript_jsx_attribute_value = braces
|
||||
ij_typescript_keep_blank_lines_in_code = 2
|
||||
ij_typescript_keep_first_column_comment = true
|
||||
ij_typescript_keep_indents_on_empty_lines = false
|
||||
ij_typescript_keep_line_breaks = true
|
||||
ij_typescript_keep_simple_blocks_in_one_line = false
|
||||
ij_typescript_keep_simple_methods_in_one_line = false
|
||||
ij_typescript_line_comment_add_space = true
|
||||
ij_typescript_line_comment_at_first_column = false
|
||||
ij_typescript_method_brace_style = end_of_line
|
||||
ij_typescript_method_call_chain_wrap = off
|
||||
ij_typescript_method_parameters_new_line_after_left_paren = false
|
||||
ij_typescript_method_parameters_right_paren_on_new_line = false
|
||||
ij_typescript_method_parameters_wrap = off
|
||||
ij_typescript_object_literal_wrap = on_every_item
|
||||
ij_typescript_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_typescript_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_typescript_place_assignment_sign_on_next_line = false
|
||||
ij_typescript_prefer_as_type_cast = false
|
||||
ij_typescript_prefer_explicit_types_function_expression_returns = false
|
||||
ij_typescript_prefer_explicit_types_function_returns = false
|
||||
ij_typescript_prefer_explicit_types_vars_fields = false
|
||||
ij_typescript_prefer_parameters_wrap = false
|
||||
ij_typescript_reformat_c_style_comments = false
|
||||
ij_typescript_space_after_colon = true
|
||||
ij_typescript_space_after_comma = true
|
||||
ij_typescript_space_after_dots_in_rest_parameter = false
|
||||
ij_typescript_space_after_generator_mult = true
|
||||
ij_typescript_space_after_property_colon = true
|
||||
ij_typescript_space_after_quest = true
|
||||
ij_typescript_space_after_type_colon = true
|
||||
ij_typescript_space_after_unary_not = false
|
||||
ij_typescript_space_before_async_arrow_lparen = true
|
||||
ij_typescript_space_before_catch_keyword = true
|
||||
ij_typescript_space_before_catch_left_brace = true
|
||||
ij_typescript_space_before_catch_parentheses = true
|
||||
ij_typescript_space_before_class_lbrace = true
|
||||
ij_typescript_space_before_class_left_brace = true
|
||||
ij_typescript_space_before_colon = true
|
||||
ij_typescript_space_before_comma = false
|
||||
ij_typescript_space_before_do_left_brace = true
|
||||
ij_typescript_space_before_else_keyword = true
|
||||
ij_typescript_space_before_else_left_brace = true
|
||||
ij_typescript_space_before_finally_keyword = true
|
||||
ij_typescript_space_before_finally_left_brace = true
|
||||
ij_typescript_space_before_for_left_brace = true
|
||||
ij_typescript_space_before_for_parentheses = true
|
||||
ij_typescript_space_before_for_semicolon = false
|
||||
ij_typescript_space_before_function_left_parenth = true
|
||||
ij_typescript_space_before_generator_mult = false
|
||||
ij_typescript_space_before_if_left_brace = true
|
||||
ij_typescript_space_before_if_parentheses = true
|
||||
ij_typescript_space_before_method_call_parentheses = false
|
||||
ij_typescript_space_before_method_left_brace = true
|
||||
ij_typescript_space_before_method_parentheses = false
|
||||
ij_typescript_space_before_property_colon = false
|
||||
ij_typescript_space_before_quest = true
|
||||
ij_typescript_space_before_switch_left_brace = true
|
||||
ij_typescript_space_before_switch_parentheses = true
|
||||
ij_typescript_space_before_try_left_brace = true
|
||||
ij_typescript_space_before_type_colon = false
|
||||
ij_typescript_space_before_unary_not = false
|
||||
ij_typescript_space_before_while_keyword = true
|
||||
ij_typescript_space_before_while_left_brace = true
|
||||
ij_typescript_space_before_while_parentheses = true
|
||||
ij_typescript_spaces_around_additive_operators = true
|
||||
ij_typescript_spaces_around_arrow_function_operator = true
|
||||
ij_typescript_spaces_around_assignment_operators = true
|
||||
ij_typescript_spaces_around_bitwise_operators = true
|
||||
ij_typescript_spaces_around_equality_operators = true
|
||||
ij_typescript_spaces_around_logical_operators = true
|
||||
ij_typescript_spaces_around_multiplicative_operators = true
|
||||
ij_typescript_spaces_around_relational_operators = true
|
||||
ij_typescript_spaces_around_shift_operators = true
|
||||
ij_typescript_spaces_around_unary_operator = false
|
||||
ij_typescript_spaces_within_array_initializer_brackets = false
|
||||
ij_typescript_spaces_within_brackets = false
|
||||
ij_typescript_spaces_within_catch_parentheses = false
|
||||
ij_typescript_spaces_within_for_parentheses = false
|
||||
ij_typescript_spaces_within_if_parentheses = false
|
||||
ij_typescript_spaces_within_imports = true
|
||||
ij_typescript_spaces_within_interpolation_expressions = false
|
||||
ij_typescript_spaces_within_method_call_parentheses = false
|
||||
ij_typescript_spaces_within_method_parentheses = false
|
||||
ij_typescript_spaces_within_object_literal_braces = false
|
||||
ij_typescript_spaces_within_object_type_braces = true
|
||||
ij_typescript_spaces_within_parentheses = false
|
||||
ij_typescript_spaces_within_switch_parentheses = false
|
||||
ij_typescript_spaces_within_type_assertion = false
|
||||
ij_typescript_spaces_within_union_types = true
|
||||
ij_typescript_spaces_within_while_parentheses = false
|
||||
ij_typescript_special_else_if_treatment = true
|
||||
ij_typescript_ternary_operation_signs_on_next_line = false
|
||||
ij_typescript_ternary_operation_wrap = off
|
||||
ij_typescript_union_types_wrap = on_every_item
|
||||
ij_typescript_use_chained_calls_group_indents = false
|
||||
ij_typescript_use_double_quotes = false
|
||||
ij_typescript_use_explicit_js_extension = global
|
||||
ij_typescript_use_path_mapping = always
|
||||
ij_typescript_use_public_modifier = false
|
||||
ij_typescript_use_semicolon_after_statement = true
|
||||
ij_typescript_var_declaration_wrap = normal
|
||||
ij_typescript_while_brace_force = never
|
||||
ij_typescript_while_on_new_line = false
|
||||
ij_typescript_wrap_comments = false
|
||||
|
||||
[{*.js,*.cjs}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_continuation_indent_size = 4
|
||||
ij_javascript_align_imports = false
|
||||
ij_javascript_align_multiline_array_initializer_expression = false
|
||||
ij_javascript_align_multiline_binary_operation = false
|
||||
ij_javascript_align_multiline_chained_methods = false
|
||||
ij_javascript_align_multiline_extends_list = false
|
||||
ij_javascript_align_multiline_for = true
|
||||
ij_javascript_align_multiline_parameters = true
|
||||
ij_javascript_align_multiline_parameters_in_calls = false
|
||||
ij_javascript_align_multiline_ternary_operation = false
|
||||
ij_javascript_align_object_properties = 0
|
||||
ij_javascript_align_union_types = false
|
||||
ij_javascript_align_var_statements = 0
|
||||
ij_javascript_array_initializer_new_line_after_left_brace = false
|
||||
ij_javascript_array_initializer_right_brace_on_new_line = false
|
||||
ij_javascript_array_initializer_wrap = off
|
||||
ij_javascript_assignment_wrap = off
|
||||
ij_javascript_binary_operation_sign_on_next_line = false
|
||||
ij_javascript_binary_operation_wrap = off
|
||||
ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
|
||||
ij_javascript_blank_lines_after_imports = 1
|
||||
ij_javascript_blank_lines_around_class = 1
|
||||
ij_javascript_blank_lines_around_field = 0
|
||||
ij_javascript_blank_lines_around_function = 1
|
||||
ij_javascript_blank_lines_around_method = 1
|
||||
ij_javascript_block_brace_style = end_of_line
|
||||
ij_javascript_call_parameters_new_line_after_left_paren = false
|
||||
ij_javascript_call_parameters_right_paren_on_new_line = false
|
||||
ij_javascript_call_parameters_wrap = off
|
||||
ij_javascript_catch_on_new_line = false
|
||||
ij_javascript_chained_call_dot_on_new_line = true
|
||||
ij_javascript_class_brace_style = end_of_line
|
||||
ij_javascript_comma_on_new_line = false
|
||||
ij_javascript_do_while_brace_force = never
|
||||
ij_javascript_else_on_new_line = false
|
||||
ij_javascript_enforce_trailing_comma = remove
|
||||
ij_javascript_extends_keyword_wrap = off
|
||||
ij_javascript_extends_list_wrap = off
|
||||
ij_javascript_field_prefix = _
|
||||
ij_javascript_file_name_style = relaxed
|
||||
ij_javascript_finally_on_new_line = false
|
||||
ij_javascript_for_brace_force = never
|
||||
ij_javascript_for_statement_new_line_after_left_paren = false
|
||||
ij_javascript_for_statement_right_paren_on_new_line = false
|
||||
ij_javascript_for_statement_wrap = off
|
||||
ij_javascript_force_quote_style = true
|
||||
ij_javascript_force_semicolon_style = true
|
||||
ij_javascript_function_expression_brace_style = end_of_line
|
||||
ij_javascript_if_brace_force = never
|
||||
ij_javascript_import_merge_members = global
|
||||
ij_javascript_import_prefer_absolute_path = global
|
||||
ij_javascript_import_sort_members = true
|
||||
ij_javascript_import_sort_module_name = false
|
||||
ij_javascript_import_use_node_resolution = true
|
||||
ij_javascript_imports_wrap = on_every_item
|
||||
ij_javascript_indent_case_from_switch = true
|
||||
ij_javascript_indent_chained_calls = true
|
||||
ij_javascript_indent_package_children = 0
|
||||
ij_javascript_jsx_attribute_value = braces
|
||||
ij_javascript_keep_blank_lines_in_code = 2
|
||||
ij_javascript_keep_first_column_comment = true
|
||||
ij_javascript_keep_indents_on_empty_lines = false
|
||||
ij_javascript_keep_line_breaks = true
|
||||
ij_javascript_keep_simple_blocks_in_one_line = false
|
||||
ij_javascript_keep_simple_methods_in_one_line = false
|
||||
ij_javascript_line_comment_add_space = true
|
||||
ij_javascript_line_comment_at_first_column = false
|
||||
ij_javascript_method_brace_style = end_of_line
|
||||
ij_javascript_method_call_chain_wrap = off
|
||||
ij_javascript_method_parameters_new_line_after_left_paren = false
|
||||
ij_javascript_method_parameters_right_paren_on_new_line = false
|
||||
ij_javascript_method_parameters_wrap = off
|
||||
ij_javascript_object_literal_wrap = on_every_item
|
||||
ij_javascript_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_javascript_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_javascript_place_assignment_sign_on_next_line = false
|
||||
ij_javascript_prefer_as_type_cast = false
|
||||
ij_javascript_prefer_explicit_types_function_expression_returns = false
|
||||
ij_javascript_prefer_explicit_types_function_returns = false
|
||||
ij_javascript_prefer_explicit_types_vars_fields = false
|
||||
ij_javascript_prefer_parameters_wrap = false
|
||||
ij_javascript_reformat_c_style_comments = false
|
||||
ij_javascript_space_after_colon = true
|
||||
ij_javascript_space_after_comma = true
|
||||
ij_javascript_space_after_dots_in_rest_parameter = false
|
||||
ij_javascript_space_after_generator_mult = true
|
||||
ij_javascript_space_after_property_colon = true
|
||||
ij_javascript_space_after_quest = true
|
||||
ij_javascript_space_after_type_colon = true
|
||||
ij_javascript_space_after_unary_not = false
|
||||
ij_javascript_space_before_async_arrow_lparen = true
|
||||
ij_javascript_space_before_catch_keyword = true
|
||||
ij_javascript_space_before_catch_left_brace = true
|
||||
ij_javascript_space_before_catch_parentheses = true
|
||||
ij_javascript_space_before_class_lbrace = true
|
||||
ij_javascript_space_before_class_left_brace = true
|
||||
ij_javascript_space_before_colon = true
|
||||
ij_javascript_space_before_comma = false
|
||||
ij_javascript_space_before_do_left_brace = true
|
||||
ij_javascript_space_before_else_keyword = true
|
||||
ij_javascript_space_before_else_left_brace = true
|
||||
ij_javascript_space_before_finally_keyword = true
|
||||
ij_javascript_space_before_finally_left_brace = true
|
||||
ij_javascript_space_before_for_left_brace = true
|
||||
ij_javascript_space_before_for_parentheses = true
|
||||
ij_javascript_space_before_for_semicolon = false
|
||||
ij_javascript_space_before_function_left_parenth = true
|
||||
ij_javascript_space_before_generator_mult = false
|
||||
ij_javascript_space_before_if_left_brace = true
|
||||
ij_javascript_space_before_if_parentheses = true
|
||||
ij_javascript_space_before_method_call_parentheses = false
|
||||
ij_javascript_space_before_method_left_brace = true
|
||||
ij_javascript_space_before_method_parentheses = false
|
||||
ij_javascript_space_before_property_colon = false
|
||||
ij_javascript_space_before_quest = true
|
||||
ij_javascript_space_before_switch_left_brace = true
|
||||
ij_javascript_space_before_switch_parentheses = true
|
||||
ij_javascript_space_before_try_left_brace = true
|
||||
ij_javascript_space_before_type_colon = false
|
||||
ij_javascript_space_before_unary_not = false
|
||||
ij_javascript_space_before_while_keyword = true
|
||||
ij_javascript_space_before_while_left_brace = true
|
||||
ij_javascript_space_before_while_parentheses = true
|
||||
ij_javascript_spaces_around_additive_operators = true
|
||||
ij_javascript_spaces_around_arrow_function_operator = true
|
||||
ij_javascript_spaces_around_assignment_operators = true
|
||||
ij_javascript_spaces_around_bitwise_operators = true
|
||||
ij_javascript_spaces_around_equality_operators = true
|
||||
ij_javascript_spaces_around_logical_operators = true
|
||||
ij_javascript_spaces_around_multiplicative_operators = true
|
||||
ij_javascript_spaces_around_relational_operators = true
|
||||
ij_javascript_spaces_around_shift_operators = true
|
||||
ij_javascript_spaces_around_unary_operator = false
|
||||
ij_javascript_spaces_within_array_initializer_brackets = false
|
||||
ij_javascript_spaces_within_brackets = false
|
||||
ij_javascript_spaces_within_catch_parentheses = false
|
||||
ij_javascript_spaces_within_for_parentheses = false
|
||||
ij_javascript_spaces_within_if_parentheses = false
|
||||
ij_javascript_spaces_within_imports = true
|
||||
ij_javascript_spaces_within_interpolation_expressions = false
|
||||
ij_javascript_spaces_within_method_call_parentheses = false
|
||||
ij_javascript_spaces_within_method_parentheses = false
|
||||
ij_javascript_spaces_within_object_literal_braces = false
|
||||
ij_javascript_spaces_within_object_type_braces = true
|
||||
ij_javascript_spaces_within_parentheses = false
|
||||
ij_javascript_spaces_within_switch_parentheses = false
|
||||
ij_javascript_spaces_within_type_assertion = false
|
||||
ij_javascript_spaces_within_union_types = true
|
||||
ij_javascript_spaces_within_while_parentheses = false
|
||||
ij_javascript_special_else_if_treatment = true
|
||||
ij_javascript_ternary_operation_signs_on_next_line = false
|
||||
ij_javascript_ternary_operation_wrap = off
|
||||
ij_javascript_union_types_wrap = on_every_item
|
||||
ij_javascript_use_chained_calls_group_indents = false
|
||||
ij_javascript_use_double_quotes = false
|
||||
ij_javascript_use_explicit_js_extension = global
|
||||
ij_javascript_use_path_mapping = always
|
||||
ij_javascript_use_public_modifier = false
|
||||
ij_javascript_use_semicolon_after_statement = true
|
||||
ij_javascript_var_declaration_wrap = normal
|
||||
ij_javascript_while_brace_force = never
|
||||
ij_javascript_while_on_new_line = false
|
||||
ij_javascript_wrap_comments = false
|
||||
|
||||
|
||||
##
|
||||
# Shell scripts
|
||||
##
|
||||
[{*.bash,*.sh,*.zsh}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
|
||||
|
||||
##
|
||||
# EditorConfig
|
||||
##
|
||||
[.editorconfig]
|
||||
ij_editorconfig_align_group_field_declarations = false
|
||||
ij_editorconfig_space_after_colon = false
|
||||
@ -263,49 +913,3 @@ ij_editorconfig_space_after_comma = true
|
||||
ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.ant, *.fxml, *.jhm, *.jnlp, *.jrxml, *.pom, *.rng, *.tld, *.wsdl, *.xml, *.xsd, *.xsl, *.xslt, *.xul}]
|
||||
ij_xml_align_attributes = true
|
||||
ij_xml_align_text = false
|
||||
ij_xml_attribute_wrap = normal
|
||||
ij_xml_block_comment_at_first_column = true
|
||||
ij_xml_keep_blank_lines = 2
|
||||
ij_xml_keep_indents_on_empty_lines = false
|
||||
ij_xml_keep_line_breaks = true
|
||||
ij_xml_keep_line_breaks_in_text = true
|
||||
ij_xml_keep_whitespaces = false
|
||||
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||
ij_xml_keep_whitespaces_inside_cdata = false
|
||||
ij_xml_line_comment_at_first_column = true
|
||||
ij_xml_space_after_tag_name = false
|
||||
ij_xml_space_around_equals_in_attribute = false
|
||||
ij_xml_space_inside_empty_tag = false
|
||||
ij_xml_text_wrap = normal
|
||||
|
||||
[{*.markdown, *.md}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_markdown_force_one_space_after_blockquote_symbol = true
|
||||
ij_markdown_force_one_space_after_header_symbol = true
|
||||
ij_markdown_force_one_space_after_list_bullet = true
|
||||
ij_markdown_force_one_space_between_words = true
|
||||
ij_markdown_keep_indents_on_empty_lines = false
|
||||
ij_markdown_max_lines_around_block_elements = 1
|
||||
ij_markdown_max_lines_around_header = 1
|
||||
ij_markdown_max_lines_between_paragraphs = 1
|
||||
ij_markdown_min_lines_around_block_elements = 1
|
||||
ij_markdown_min_lines_around_header = 1
|
||||
ij_markdown_min_lines_between_paragraphs = 1
|
||||
|
||||
[{*.yaml, *.yml, *.lang}]
|
||||
indent_size = 2
|
||||
ij_yaml_align_values_properties = do_not_align
|
||||
ij_yaml_autoinsert_sequence_marker = true
|
||||
ij_yaml_block_mapping_on_new_line = false
|
||||
ij_yaml_indent_sequence_value = true
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
ij_yaml_sequence_on_new_line = false
|
||||
ij_yaml_space_before_colon = false
|
||||
ij_yaml_spaces_within_braces = true
|
||||
ij_yaml_spaces_within_brackets = true
|
||||
|
4
.github/workflows/maven.yml
vendored
4
.github/workflows/maven.yml
vendored
@ -50,13 +50,13 @@ jobs:
|
||||
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
|
||||
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
|
||||
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 }}
|
||||
|
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 ]
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Setup Java
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: 16
|
||||
distribution: adopt
|
||||
|
||||
# Checkout project files
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
# Caches
|
||||
- name: 'Cache: Maven'
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
- name: 'Cache: SonarCloud'
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
|
||||
- name: Analyze project
|
||||
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=songoda_SongodaCore
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@
|
||||
/NMS/*/target/
|
||||
|
||||
dependency-reduced-pom.xml
|
||||
/**/logs/*.log
|
||||
|
||||
##
|
||||
# Misc.
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.5.13</version>
|
||||
<version>2.5.14</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
public enum ClassMapping {
|
||||
|
||||
BIOME_BASE("world.level.biome", "BiomeBase"),
|
||||
BIOME_STORAGE("world.level.chunk", "BiomeStorage"),
|
||||
BLOCK("world.level.block", "Block"),
|
||||
@ -43,6 +42,7 @@ public enum ClassMapping {
|
||||
CRAFT_CHUNK("CraftChunk"),
|
||||
CRAFT_ENTITY("entity", "CraftEntity"),
|
||||
CRAFT_ITEM_STACK("inventory", "CraftItemStack"),
|
||||
CRAFT_MAGIC_NUMBERS("util", "CraftMagicNumbers"),
|
||||
CRAFT_PLAYER("entity", "CraftPlayer"),
|
||||
CRAFT_WORLD("CraftWorld");
|
||||
|
||||
@ -63,17 +63,21 @@ public enum ClassMapping {
|
||||
}
|
||||
|
||||
public Class<?> getClazz(String sub) {
|
||||
String name = sub == null ? className : className + "$" + sub;
|
||||
|
||||
try {
|
||||
String name = sub == null ? className : className + "$" + sub;
|
||||
if (className.startsWith("Craft"))
|
||||
if (className.startsWith("Craft")) {
|
||||
return Class.forName("org.bukkit.craftbukkit." + ServerVersion.getServerVersionString()
|
||||
+ (packageName == null ? "" : "." + packageName) + "." + name);
|
||||
}
|
||||
|
||||
return Class.forName("net.minecraft." + (
|
||||
ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) && packageName != null
|
||||
? packageName : "server." + ServerVersion.getServerVersionString()) + "." + name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ public class ClientVersion {
|
||||
}
|
||||
|
||||
private static ServerVersion protocolToVersion(int version) {
|
||||
// https://github.com/ViaVersion/ViaVersion/blob/master/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
|
||||
// https://github.com/ProtocolSupport/ProtocolSupport/blob/master/src/protocolsupport/api/ProtocolVersion.java
|
||||
// https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite
|
||||
// https://github.com/ViaVersion/ViaVersion/blob/master/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java
|
||||
switch (version) {
|
||||
case 4:
|
||||
case 5:
|
||||
@ -101,9 +101,12 @@ public class ClientVersion {
|
||||
case 754:
|
||||
return ServerVersion.V1_16;
|
||||
case 755:
|
||||
case 756:
|
||||
return ServerVersion.V1_17;
|
||||
|
||||
default:
|
||||
return version > 756 ? ServerVersion.getServerVersion() : ServerVersion.UNKNOWN;
|
||||
}
|
||||
return version > 498 ? ServerVersion.getServerVersion() : ServerVersion.UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,12 +19,8 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Biomes that are compatible with server versions 1.7+
|
||||
*
|
||||
* @author Brianna
|
||||
* @since 2020-03-27
|
||||
*/
|
||||
public enum CompatibleBiome {
|
||||
|
||||
/* 1.17 */
|
||||
DRIPSTONE_CAVES(ServerVersion.V1_17),
|
||||
LUSH_CAVES(ServerVersion.V1_17),
|
||||
@ -114,20 +110,24 @@ public enum CompatibleBiome {
|
||||
private static final boolean isAbove1_16_R1 = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)
|
||||
&& !ServerVersion.getServerVersionString().equals("v1_16_R1");
|
||||
|
||||
private static final Map<String, CompatibleBiome> lookupMap = new HashMap();
|
||||
private static final Map<String, CompatibleBiome> lookupMap = new HashMap<>();
|
||||
private static final Set<CompatibleBiome> compatibleBiomes = new HashSet<>();
|
||||
private final Deque<Version> versions = new ArrayDeque<>();
|
||||
private static Method methodGetHandle, methodMarkDirty, methodBiomeToBiomeBase, methodGetBiomeIndex, methodSetBiome;
|
||||
private static Field fieldStorageRegistry;
|
||||
|
||||
static {
|
||||
for (CompatibleBiome biome : values())
|
||||
for (Version version : biome.getVersions())
|
||||
for (CompatibleBiome biome : values()) {
|
||||
for (Version version : biome.getVersions()) {
|
||||
lookupMap.put(version.biome, biome);
|
||||
}
|
||||
}
|
||||
|
||||
for (CompatibleBiome biome : CompatibleBiome.values())
|
||||
if (biome.isCompatible())
|
||||
for (CompatibleBiome biome : CompatibleBiome.values()) {
|
||||
if (biome.isCompatible()) {
|
||||
compatibleBiomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
try {
|
||||
@ -148,13 +148,14 @@ public enum CompatibleBiome {
|
||||
try {
|
||||
// If 1.16.5
|
||||
fieldStorageRegistry = classBiomeStorage.getDeclaredField("registry");
|
||||
} catch (NoSuchFieldException e) {
|
||||
} catch (NoSuchFieldException ex) {
|
||||
// If less than 1.16.5
|
||||
fieldStorageRegistry = classBiomeStorage.getDeclaredField("g");
|
||||
}
|
||||
|
||||
fieldStorageRegistry.setAccessible(true);
|
||||
} catch (NoSuchMethodException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException | NoSuchFieldException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,6 +172,7 @@ public enum CompatibleBiome {
|
||||
public boolean isCompatible() {
|
||||
Version version = versions.getLast();
|
||||
ServerVersion.isServerVersionAtLeast(version.version);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -179,9 +181,12 @@ public enum CompatibleBiome {
|
||||
}
|
||||
|
||||
public Biome getBiome() {
|
||||
for (Version version : versions)
|
||||
if (ServerVersion.isServerVersionAtLeast(version.version))
|
||||
for (Version version : versions) {
|
||||
if (ServerVersion.isServerVersionAtLeast(version.version)) {
|
||||
return Biome.valueOf(version.biome);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -201,14 +206,17 @@ public enum CompatibleBiome {
|
||||
Object nmsChunk = null;
|
||||
Object biomeStorage = null;
|
||||
Object biomeBase = null;
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
nmsChunk = methodGetHandle.invoke(chunk);
|
||||
biomeStorage = methodGetBiomeIndex.invoke(nmsChunk);
|
||||
|
||||
if (isAbove1_16_R1) {
|
||||
Object registry = fieldStorageRegistry.get(biomeStorage);
|
||||
biomeBase = methodBiomeToBiomeBase.invoke(null, registry, getBiome());
|
||||
} else
|
||||
} else {
|
||||
biomeBase = methodBiomeToBiomeBase.invoke(null, getBiome());
|
||||
}
|
||||
}
|
||||
|
||||
World world = chunk.getWorld();
|
||||
@ -216,22 +224,31 @@ public enum CompatibleBiome {
|
||||
int chunkZ = chunk.getZ();
|
||||
for (int x = chunkX << 4; x < (chunkX << 4) + 16; x++) {
|
||||
for (int z = chunkZ << 4; z < (chunkZ << 4) + 16; z++) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15))
|
||||
for (int y = 0; y < world.getMaxHeight(); ++y)
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
for (int y = 0; y < world.getMaxHeight(); ++y) {
|
||||
methodSetBiome.invoke(biomeStorage, x >> 2, y >> 2, z >> 2, biomeBase);
|
||||
else
|
||||
chunk.getWorld().setBiome(x, z, getBiome());
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
chunk.getWorld().setBiome(x, z, getBiome());
|
||||
}
|
||||
}
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15))
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
methodMarkDirty.invoke(nmsChunk);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBiome(World world, int x, int y, int z) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15))
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
world.setBiome(x, y, z, getBiome());
|
||||
else
|
||||
world.setBiome(x, z, getBiome());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
world.setBiome(x, z, getBiome());
|
||||
}
|
||||
|
||||
private static Version v(ServerVersion version, String biome) {
|
||||
@ -243,7 +260,6 @@ public enum CompatibleBiome {
|
||||
}
|
||||
|
||||
private static class Version {
|
||||
|
||||
final ServerVersion version;
|
||||
final String biome;
|
||||
|
||||
|
@ -11,20 +11,17 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Get which hand is being used.
|
||||
*
|
||||
* @author Brianna
|
||||
* @since 2020-03-24
|
||||
*/
|
||||
public enum CompatibleHand {
|
||||
|
||||
MAIN_HAND, OFF_HAND;
|
||||
|
||||
private static Map<String, Method> methodCache = new HashMap<>();
|
||||
private static final Map<String, Method> methodCache = new HashMap<>();
|
||||
|
||||
public static CompatibleHand getHand(Object event) {
|
||||
try {
|
||||
Class<?> clazz = event.getClass();
|
||||
String className = clazz.getName();
|
||||
|
||||
Method method;
|
||||
if (methodCache.containsKey(className)) {
|
||||
method = methodCache.get(className);
|
||||
@ -32,10 +29,15 @@ public enum CompatibleHand {
|
||||
method = clazz.getDeclaredMethod("getHand");
|
||||
methodCache.put(className, method);
|
||||
}
|
||||
|
||||
EquipmentSlot slot = (EquipmentSlot) method.invoke(event);
|
||||
if (slot == EquipmentSlot.OFF_HAND) return OFF_HAND;
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
|
||||
if (slot == EquipmentSlot.OFF_HAND) {
|
||||
return OFF_HAND;
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignore) {
|
||||
}
|
||||
|
||||
return MAIN_HAND;
|
||||
}
|
||||
|
||||
@ -65,10 +67,12 @@ public enum CompatibleHand {
|
||||
int result = item.getAmount() - amount;
|
||||
item.setAmount(result);
|
||||
|
||||
if (this == CompatibleHand.MAIN_HAND)
|
||||
if (this == CompatibleHand.MAIN_HAND) {
|
||||
player.setItemInHand(result > 0 ? item : null);
|
||||
else
|
||||
player.getInventory().setItemInOffHand(result > 0 ? item : null);
|
||||
return;
|
||||
}
|
||||
|
||||
player.getInventory().setItemInOffHand(result > 0 ? item : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,10 +83,11 @@ public enum CompatibleHand {
|
||||
* @return the item
|
||||
*/
|
||||
public ItemStack getItem(Player player) {
|
||||
if (this == MAIN_HAND)
|
||||
if (this == MAIN_HAND) {
|
||||
return player.getItemInHand();
|
||||
else
|
||||
return player.getInventory().getItemInOffHand();
|
||||
}
|
||||
|
||||
return player.getInventory().getItemInOffHand();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,9 +97,11 @@ public enum CompatibleHand {
|
||||
* @param item the item to set
|
||||
*/
|
||||
public void setItem(Player player, ItemStack item) {
|
||||
if (this == MAIN_HAND)
|
||||
if (this == MAIN_HAND) {
|
||||
player.setItemInHand(item);
|
||||
else
|
||||
player.getInventory().setItemInOffHand(item);
|
||||
return;
|
||||
}
|
||||
|
||||
player.getInventory().setItemInOffHand(item);
|
||||
}
|
||||
}
|
||||
|
@ -16,12 +16,9 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Items that are compatible with server versions 1.7+
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-23
|
||||
*/
|
||||
public enum CompatibleMaterial {
|
||||
/*
|
||||
/*
|
||||
TODO: add another handler for getBlockItem() for materials and fallback materials
|
||||
|
||||
Legacy has some values not used in modern, eg:
|
||||
@ -33,7 +30,7 @@ public enum CompatibleMaterial {
|
||||
JUNGLE_DOOR_ITEM(429),
|
||||
ACACIA_DOOR_ITEM(430),
|
||||
DARK_OAK_DOOR_ITEM(431),
|
||||
*/
|
||||
*/
|
||||
|
||||
/* 1.17 */
|
||||
AMETHYST_BLOCK(),
|
||||
@ -1296,7 +1293,7 @@ public enum CompatibleMaterial {
|
||||
// quick test to see if our version is < 1.13
|
||||
protected static final boolean useLegacy = ServerVersion.isServerVersionBelow(ServerVersion.V1_13);
|
||||
// map to speed up name->material lookups
|
||||
private static final Map<String, CompatibleMaterial> lookupMap = new HashMap();
|
||||
private static final Map<String, CompatibleMaterial> lookupMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (CompatibleMaterial m : values()) {
|
||||
@ -1304,22 +1301,27 @@ public enum CompatibleMaterial {
|
||||
lookupMap.put(m.legacy, m);
|
||||
continue;
|
||||
}
|
||||
|
||||
lookupMap.put(m.name(), m);
|
||||
if (!m.usesCompatibility()) {
|
||||
lookupMap.put(m.material + ":" + (m.data == null ? "" : m.data), m);
|
||||
}
|
||||
}
|
||||
|
||||
for (CompatibleMaterial m : values()) {
|
||||
if (!m.usesCompatibility()) {
|
||||
if (m.legacy != null && !lookupMap.containsKey(m.legacy)) {
|
||||
lookupMap.put(m.legacy, m);
|
||||
}
|
||||
|
||||
if (m.modern2 != null && !lookupMap.containsKey(m.modern2)) {
|
||||
lookupMap.put(m.modern2, m);
|
||||
}
|
||||
|
||||
if (m.legacyBlockMaterial != null && !lookupMap.containsKey(m.legacyBlockMaterial.blockMaterialName)) {
|
||||
lookupMap.put(m.legacyBlockMaterial.blockMaterialName, m);
|
||||
}
|
||||
|
||||
if (m.legacyBlockMaterial != null && !lookupMap.containsKey(m.legacyBlockMaterial.alternateBlockMaterialName)) {
|
||||
lookupMap.put(m.legacyBlockMaterial.alternateBlockMaterialName, m);
|
||||
}
|
||||
@ -1422,8 +1424,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Does this material need to use a legacy fallback?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean usesLegacy() {
|
||||
return legacy != null && ServerVersion.isServerVersionBelow(minVersion);
|
||||
@ -1431,8 +1431,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Does this material need to use a fallback item on this server?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean usesCompatibility() {
|
||||
return compatibleMaterial != null && material == compatibleMaterial.material;
|
||||
@ -1441,18 +1439,13 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Is this item reused in later versions of Minecraft?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isRecycled() {
|
||||
return usesLegacy() && this == CompatibleMaterial.GRASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the legacy data value for this material if there is one, or -1 if
|
||||
* none
|
||||
*
|
||||
* @return
|
||||
* Get the legacy data value for this material if there is one, or -1 if none
|
||||
*/
|
||||
public byte getData() {
|
||||
return data != null ? data : -1;
|
||||
@ -1523,6 +1516,7 @@ public enum CompatibleMaterial {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String key = item.getType() + ":";
|
||||
CompatibleMaterial m = lookupMap.get(key);
|
||||
return m != null ? m : lookupMap.get(key + item.getDurability());
|
||||
@ -1561,8 +1555,8 @@ public enum CompatibleMaterial {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
try {
|
||||
methodGetBlockData = FallingBlock.class.getDeclaredMethod("getBlockData");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1575,16 +1569,20 @@ public enum CompatibleMaterial {
|
||||
* @return LegacyMaterial or null if none found
|
||||
*/
|
||||
public static CompatibleMaterial getMaterial(FallingBlock block) {
|
||||
if (block == null) return null;
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
return getMaterial(block.getBlockData().getMaterial());
|
||||
} else {
|
||||
try {
|
||||
return getMaterial(block.getMaterial(), (byte) methodGetBlockData.invoke(block));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return getMaterial(block.getMaterial(), (byte) methodGetBlockData.invoke(block));
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1599,21 +1597,21 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getMaterial(Material mat, byte data) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) { // Flattening
|
||||
return CompatibleMaterial.getMaterial(mat);
|
||||
} else { // Pre-Flattening
|
||||
if (mat != null) {
|
||||
if (data != 0) {
|
||||
for (CompatibleMaterial cm : CompatibleMaterial.values()) {
|
||||
if (cm.getMaterial() != null
|
||||
&& cm.getMaterial().equals(mat)) {
|
||||
if (cm.getData() == data) {
|
||||
return cm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-Flattening
|
||||
if (mat != null) {
|
||||
if (data != 0) {
|
||||
for (CompatibleMaterial cm : CompatibleMaterial.values()) {
|
||||
if (cm.getMaterial() != null && cm.getMaterial().equals(mat) && cm.getData() == data) {
|
||||
return cm;
|
||||
}
|
||||
}
|
||||
return CompatibleMaterial.getMaterial(mat);
|
||||
}
|
||||
|
||||
return CompatibleMaterial.getMaterial(mat);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1621,15 +1619,19 @@ public enum CompatibleMaterial {
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Material mat = block.getType();
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(mat.name(), block.getData());
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
|
||||
CompatibleMaterial withData = lookupMap.get(mat.name() + ":" + block.getData());
|
||||
return withData == null ? lookupMap.get(mat.name()) : withData;
|
||||
}
|
||||
|
||||
return lookupMap.get(mat.name());
|
||||
}
|
||||
|
||||
@ -1645,12 +1647,16 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getBlockMaterial(String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
} else if (useLegacy) {
|
||||
}
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(name.toUpperCase());
|
||||
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
}
|
||||
|
||||
return lookupMap.get(name.toUpperCase());
|
||||
}
|
||||
|
||||
@ -1667,12 +1673,16 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getBlockMaterial(String name, CompatibleMaterial def) {
|
||||
if (name == null) {
|
||||
return def;
|
||||
} else if (useLegacy) {
|
||||
}
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(name.toUpperCase());
|
||||
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
}
|
||||
|
||||
return lookupMap.getOrDefault(name.toUpperCase(), def);
|
||||
}
|
||||
|
||||
@ -1686,12 +1696,16 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getBlockMaterial(Material mat) {
|
||||
if (mat == null) {
|
||||
return null;
|
||||
} else if (useLegacy) {
|
||||
}
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(mat.name());
|
||||
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
}
|
||||
|
||||
return lookupMap.get(mat.name());
|
||||
}
|
||||
|
||||
@ -1699,13 +1713,15 @@ public enum CompatibleMaterial {
|
||||
|
||||
public static Set<CompatibleMaterial> getAllValidItemMaterials() {
|
||||
if (all == null) {
|
||||
all = new LinkedHashSet();
|
||||
all = new LinkedHashSet<>();
|
||||
|
||||
for (CompatibleMaterial mat : values()) {
|
||||
if (mat.isValidItem() && !mat.usesCompatibility()) {
|
||||
all.add(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(all);
|
||||
}
|
||||
|
||||
@ -1723,10 +1739,12 @@ public enum CompatibleMaterial {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CompatibleMaterial m = lookupMap.get(name.toUpperCase());
|
||||
if (m != null) {
|
||||
return m.getItem();
|
||||
}
|
||||
|
||||
Material mat = Material.getMaterial(name);
|
||||
return mat != null ? new ItemStack(mat) : null;
|
||||
}
|
||||
@ -1737,8 +1755,8 @@ public enum CompatibleMaterial {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
try {
|
||||
methodSetData = Block.class.getDeclaredMethod("setData", byte.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1750,12 +1768,14 @@ public enum CompatibleMaterial {
|
||||
*/
|
||||
public void applyToBlock(Block block) {
|
||||
if (block == null) return;
|
||||
|
||||
block.setType(material);
|
||||
|
||||
if (data != null && data != -1 && ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
try {
|
||||
methodSetData.invoke(block, data);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1768,14 +1788,15 @@ public enum CompatibleMaterial {
|
||||
* @return true if material of the ItemStack matches this item, corrected for legacy data
|
||||
*/
|
||||
public boolean matches(ItemStack item) {
|
||||
return item != null && !usesCompatibility() && item.getType() == material && (data == null || item.getDurability() == data); // eons ago, ItemStack.getData() would return a byte. 1.7 doesn't, though.
|
||||
return item != null &&
|
||||
!usesCompatibility() && item.getType() == material &&
|
||||
// eons ago, ItemStack.getData() would return a byte. 1.7 doesn't, though.
|
||||
(data == null || item.getDurability() == data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some blocks change to other materials when placed down. This checks to
|
||||
* see if this one is one of those.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasDifferentBlockItem() {
|
||||
switch (this) {
|
||||
@ -1832,14 +1853,13 @@ public enum CompatibleMaterial {
|
||||
case CAKE:
|
||||
case COMPARATOR:
|
||||
return usesLegacy();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this is a material that can exist as a block
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBlock() {
|
||||
return material != null && material.isBlock();
|
||||
@ -1847,8 +1867,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check to see if this is an item that can be consumed to restore hunger
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEdible() {
|
||||
return material != null && material.isEdible();
|
||||
@ -1856,8 +1874,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and can be built on
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSolid() {
|
||||
return material != null && material.isSolid();
|
||||
@ -1865,8 +1881,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and does not block any light
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isTransparent() {
|
||||
return material != null && material.isTransparent();
|
||||
@ -1874,8 +1888,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and can catch fire
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFlammable() {
|
||||
return material != null && material.isFlammable();
|
||||
@ -1883,8 +1895,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and can be destroyed by burning
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBurnable() {
|
||||
return material != null && material.isBurnable();
|
||||
@ -1892,11 +1902,9 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Checks if this Material can be used as fuel in a Furnace
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFuel() {
|
||||
// this function is not implemented in some older versions, so we need this here..
|
||||
// this function is not implemented in some older versions, so we need this here...
|
||||
switch (this) {
|
||||
case ACACIA_BOAT:
|
||||
case ACACIA_BUTTON:
|
||||
@ -2253,8 +2261,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is air
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAir() {
|
||||
switch (this) {
|
||||
@ -2269,8 +2275,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is water
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isWater() {
|
||||
return this == CompatibleMaterial.WATER;
|
||||
@ -2278,26 +2282,26 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Get the EntityType of the monster spawn egg.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public EntityType getEggType() {
|
||||
String entityName = this.name().replace("_SPAWN_EGG", "");
|
||||
if (entityName.equals("MOOSHROOM"))
|
||||
|
||||
if (entityName.equals("MOOSHROOM")) {
|
||||
entityName = "MUSHROOM_COW";
|
||||
else if (entityName.equals("ZOMBIE_PIGMAN"))
|
||||
} else if (entityName.equals("ZOMBIE_PIGMAN")) {
|
||||
entityName = "PIG_ZOMBIE";
|
||||
}
|
||||
|
||||
try {
|
||||
return EntityType.valueOf(entityName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the material is a block and completely blocks vision
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOccluding() {
|
||||
return material != null && material.isOccluding();
|
||||
@ -2312,11 +2316,9 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Checks if this Material is an obtainable item.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isItem() {
|
||||
// this function is not implemented in some older versions, so we need this here..
|
||||
// this function is not implemented in some older versions, so we need this here...
|
||||
switch (this) {
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
@ -2410,19 +2412,18 @@ public enum CompatibleMaterial {
|
||||
case YELLOW_WALL_BANNER:
|
||||
case ZOMBIE_WALL_HEAD:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this Material can be interacted with. <br />
|
||||
* This method will return true if there is at least one state in which
|
||||
* additional interact handling is performed for the material.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isInteractable() {
|
||||
// this function is not implemented in some older versions, so we need this here..
|
||||
// this function is not implemented in some older versions, so we need this here...
|
||||
switch (this) {
|
||||
case ACACIA_BUTTON:
|
||||
case ACACIA_DOOR:
|
||||
@ -2634,11 +2635,11 @@ public enum CompatibleMaterial {
|
||||
case WHITE_BED:
|
||||
case WHITE_SHULKER_BOX:
|
||||
case YELLOW_BED:
|
||||
case YELLOW_SHULKER_BOX: {
|
||||
case YELLOW_SHULKER_BOX:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2738,7 +2739,10 @@ public enum CompatibleMaterial {
|
||||
case WHITE_WALL_BANNER:
|
||||
case WITHER_SKELETON_WALL_SKULL:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
switch (this) {
|
||||
case ACACIA_WOOD:
|
||||
@ -2754,8 +2758,11 @@ public enum CompatibleMaterial {
|
||||
case STRIPPED_OAK_WOOD:
|
||||
case STRIPPED_SPRUCE_WOOD:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2786,8 +2793,9 @@ public enum CompatibleMaterial {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this material is a food that can be cooked and is in its cooked state
|
||||
* @return true if this material is food that can be cooked and is in its cooked state
|
||||
*/
|
||||
public boolean isCooked() {
|
||||
switch (this) {
|
||||
@ -2801,12 +2809,13 @@ public enum CompatibleMaterial {
|
||||
case COOKED_SALMON:
|
||||
case DRIED_KELP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this material is a food that can be cooked and is in its raw state
|
||||
* @return true if this material is food that can be cooked and is in its raw state
|
||||
*/
|
||||
public boolean isRaw() {
|
||||
switch (this) {
|
||||
@ -2820,8 +2829,9 @@ public enum CompatibleMaterial {
|
||||
case RABBIT:
|
||||
case SALMON:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2836,8 +2846,9 @@ public enum CompatibleMaterial {
|
||||
case PEONY:
|
||||
case TALL_GRASS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2935,8 +2946,7 @@ public enum CompatibleMaterial {
|
||||
return MOOSHROOM_SPAWN_EGG;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_16)
|
||||
&& type == EntityType.valueOf("PIG_ZOMBIE")) {
|
||||
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_16) && type == EntityType.valueOf("PIG_ZOMBIE")) {
|
||||
return ZOMBIE_PIGMAN_SPAWN_EGG;
|
||||
}
|
||||
|
||||
@ -2977,8 +2987,9 @@ public enum CompatibleMaterial {
|
||||
return RED_STAINED_GLASS_PANE;
|
||||
case 15:
|
||||
return BLACK_STAINED_GLASS_PANE;
|
||||
default:
|
||||
return WHITE_STAINED_GLASS;
|
||||
}
|
||||
return WHITE_STAINED_GLASS_PANE;
|
||||
}
|
||||
|
||||
public static CompatibleMaterial getGlassColor(int color) {
|
||||
@ -3015,8 +3026,9 @@ public enum CompatibleMaterial {
|
||||
return RED_STAINED_GLASS;
|
||||
case 15:
|
||||
return BLACK_STAINED_GLASS;
|
||||
default:
|
||||
return WHITE_STAINED_GLASS;
|
||||
}
|
||||
return WHITE_STAINED_GLASS;
|
||||
}
|
||||
|
||||
public static CompatibleMaterial getWoolColor(int color) {
|
||||
@ -3053,8 +3065,9 @@ public enum CompatibleMaterial {
|
||||
return RED_WOOL;
|
||||
case 15:
|
||||
return BLACK_WOOL;
|
||||
default:
|
||||
return WHITE_WOOL;
|
||||
}
|
||||
return WHITE_WOOL;
|
||||
}
|
||||
|
||||
public static CompatibleMaterial getDyeColor(int color) {
|
||||
@ -3091,7 +3104,8 @@ public enum CompatibleMaterial {
|
||||
return ORANGE_DYE;
|
||||
case 15:
|
||||
return WHITE_DYE;
|
||||
default:
|
||||
return WHITE_DYE;
|
||||
}
|
||||
return WHITE_DYE;
|
||||
}
|
||||
}
|
||||
|
@ -1,326 +1,325 @@
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CompatibleParticleHandler {
|
||||
|
||||
public static enum ParticleType {
|
||||
EXPLOSION_NORMAL,
|
||||
EXPLOSION_LARGE,
|
||||
EXPLOSION_HUGE,
|
||||
FIREWORKS_SPARK,
|
||||
WATER_BUBBLE,
|
||||
WATER_SPLASH,
|
||||
WATER_WAKE,
|
||||
SUSPENDED,
|
||||
SUSPENDED_DEPTH,
|
||||
CRIT,
|
||||
CRIT_MAGIC,
|
||||
SMOKE_NORMAL,
|
||||
SMOKE_LARGE,
|
||||
SPELL,
|
||||
SPELL_INSTANT,
|
||||
SPELL_MOB,
|
||||
SPELL_MOB_AMBIENT,
|
||||
SPELL_WITCH,
|
||||
DRIP_WATER,
|
||||
DRIP_LAVA,
|
||||
VILLAGER_ANGRY,
|
||||
VILLAGER_HAPPY,
|
||||
TOWN_AURA,
|
||||
NOTE,
|
||||
PORTAL,
|
||||
ENCHANTMENT_TABLE,
|
||||
FLAME,
|
||||
LAVA,
|
||||
CLOUD,
|
||||
REDSTONE(), //DustOptions
|
||||
SNOWBALL,
|
||||
SNOW_SHOVEL,
|
||||
SLIME,
|
||||
HEART,
|
||||
BARRIER,
|
||||
ITEM_CRACK(), // ItemStack
|
||||
BLOCK_CRACK(), // BlockData
|
||||
BLOCK_DUST(), // BlockData
|
||||
WATER_DROP,
|
||||
// 1.8-1.12 included ITEM_TAKE
|
||||
MOB_APPEARANCE,
|
||||
/// End 1.8 particles ///
|
||||
DRAGON_BREATH(ServerVersion.V1_9, "SPELL_MOB_AMBIENT"),
|
||||
END_ROD(ServerVersion.V1_9, "ENCHANTMENT_TABLE"),
|
||||
DAMAGE_INDICATOR(ServerVersion.V1_9, "VILLAGER_ANGRY"),
|
||||
SWEEP_ATTACK(ServerVersion.V1_9, "CRIT"),
|
||||
/// End 1.9 particles ///
|
||||
FALLING_DUST(ServerVersion.V1_10, "BLOCK_DUST"), // BlockData
|
||||
/// End 1.10 ///
|
||||
TOTEM(ServerVersion.V1_11, "VILLAGER_HAPPY"),
|
||||
SPIT(ServerVersion.V1_11, "REDSTONE"),
|
||||
/// End 1.11-1.12 ///
|
||||
SQUID_INK(ServerVersion.V1_13, "CRIT"),
|
||||
BUBBLE_POP(ServerVersion.V1_13, "CRIT"),
|
||||
CURRENT_DOWN(ServerVersion.V1_13, "CRIT"),
|
||||
BUBBLE_COLUMN_UP(ServerVersion.V1_13, "CRIT"),
|
||||
NAUTILUS(ServerVersion.V1_13, "ENCHANTMENT_TABLE"),
|
||||
DOLPHIN(ServerVersion.V1_13, "TOWN_AURA"),
|
||||
/// End 1.13 ///
|
||||
SNEEZE(ServerVersion.V1_14, "REDSTONE"),
|
||||
CAMPFIRE_COSY_SMOKE(ServerVersion.V1_14, "SMOKE_NORMAL"),
|
||||
CAMPFIRE_SIGNAL_SMOKE(ServerVersion.V1_14, "SMOKE_LARGE"),
|
||||
COMPOSTER(ServerVersion.V1_14, "CRIT"),
|
||||
FLASH(ServerVersion.V1_14, "EXPLOSION_NORMAL"), // idk
|
||||
FALLING_LAVA(ServerVersion.V1_14, "DRIP_LAVA"),
|
||||
LANDING_LAVA(ServerVersion.V1_14, "LAVA"),
|
||||
FALLING_WATER(ServerVersion.V1_14, "DRIP_WATER"),
|
||||
/// End 1.14 ///
|
||||
DRIPPING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
FALLING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
FALLING_NECTAR(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
LANDING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
/// End 1.15 ///
|
||||
// ToDo: Someone needs to make better compatible fall backs.
|
||||
SOUL_FIRE_FLAME(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
ASH(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
CRIMSON_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
WARPED_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
SOUL(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
DRIPPING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
FALLING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
LANDING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
REVERSE_PORTAL(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
WHITE_ASH(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
/// End 1.16 ///
|
||||
// ToDo: Someone needs to make better compatible fall backs.
|
||||
LIGHT(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
DUST_COLOR_TRANSITION(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
VIBRATION(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
FALLING_SPORE_BLOSSOM(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SPORE_BLOSSOM_AIR(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SMALL_FLAME(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SNOWFLAKE(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
DRIPPING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
FALLING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
DRIPPING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
FALLING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
GLOW_SQUID_INK(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
GLOW(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
WAX_ON(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
WAX_OFF(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
ELECTRIC_SPARK(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SCRAPE(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
/// End 1.17 ///
|
||||
;
|
||||
|
||||
final boolean compatibilityMode;
|
||||
final LegacyParticleEffects.Type compatibleEffect;
|
||||
final Object particle;
|
||||
final static Map<String, ParticleType> map = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (ParticleType t : values()) {
|
||||
map.put(t.name(), t);
|
||||
}
|
||||
}
|
||||
|
||||
private ParticleType() {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
this.compatibilityMode = true;
|
||||
this.particle = null;
|
||||
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(name());
|
||||
} else {
|
||||
this.compatibleEffect = null;
|
||||
// does this particle exist in our version?
|
||||
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
|
||||
if (check != null) {
|
||||
this.particle = check;
|
||||
this.compatibilityMode = false;
|
||||
} else {
|
||||
// this shouldn't happen, really
|
||||
this.particle = Particle.END_ROD;
|
||||
this.compatibilityMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ParticleType(ServerVersion minVersion, String compatible) {
|
||||
// Particle class doesn't exist in 1.8
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
this.compatibilityMode = true;
|
||||
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(compatible);
|
||||
this.particle = null;
|
||||
} else if (ServerVersion.isServerVersionBelow(minVersion)) {
|
||||
this.compatibilityMode = true;
|
||||
this.compatibleEffect = null;
|
||||
this.particle = Particle.valueOf(compatible);
|
||||
} else {
|
||||
this.compatibleEffect = null;
|
||||
// does this particle exist in our version?
|
||||
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
|
||||
if (check != null) {
|
||||
this.particle = check;
|
||||
this.compatibilityMode = false;
|
||||
} else {
|
||||
// this shouldn't happen, really
|
||||
this.particle = Particle.END_ROD;
|
||||
this.compatibilityMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ParticleType getParticle(String name) {
|
||||
return map.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(String type, Location location) {
|
||||
spawnParticles(type, location, 0);
|
||||
}
|
||||
|
||||
public static void spawnParticles(String type, Location location, int count) {
|
||||
ParticleType pt;
|
||||
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
|
||||
spawnParticles(pt, location, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(String type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
|
||||
ParticleType pt;
|
||||
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
|
||||
spawnParticles(pt, location, count, offsetX, offsetY, offsetZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
LegacyParticleEffects.createParticle(location, type.compatibleEffect);
|
||||
} else {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (1 * (Math.random() - Math.random()));
|
||||
float yy = (float) (1 * (Math.random() - Math.random()));
|
||||
float zz = (float) (1 * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
|
||||
}
|
||||
} else {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (offsetX * (Math.random() - Math.random()));
|
||||
float yy = (float) (offsetY * (Math.random() - Math.random()));
|
||||
float zz = (float) (offsetZ * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
|
||||
}
|
||||
} else {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra) {
|
||||
spawnParticles(type, location, count, offsetX, offsetY, offsetZ, extra, null);
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, Player receiver) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (offsetX * (Math.random() - Math.random()));
|
||||
float yy = (float) (offsetY * (Math.random() - Math.random()));
|
||||
float zz = (float) (offsetZ * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, type.compatibleEffect, 0F, 0F, 0F, (float) extra, 0, receiver != null ? Collections.singletonList(receiver) : null);
|
||||
}
|
||||
} else {
|
||||
if (receiver == null) {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
|
||||
} else {
|
||||
receiver.spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void redstoneParticles(Location location, int red, int green, int blue) {
|
||||
redstoneParticles(location, red, green, blue, 1F, 1, 0, null);
|
||||
}
|
||||
|
||||
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius) {
|
||||
redstoneParticles(location, red, green, blue, size, count, radius, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn colored redstone particles
|
||||
*
|
||||
* @param location area to spawn the particle in
|
||||
* @param red red value 0-255
|
||||
* @param green green value 0-255
|
||||
* @param blue blue value 0-255
|
||||
* @param size (1.13+) size of the particles
|
||||
* @param count how many particles to spawn
|
||||
* @param radius how far to spread out the particles from location
|
||||
*/
|
||||
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius, Player player) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
float xx = (float) (radius * (Math.random() - Math.random()));
|
||||
float yy = (float) (radius * (Math.random() - Math.random()));
|
||||
float zz = (float) (radius * (Math.random() - Math.random()));
|
||||
if (player == null)
|
||||
location.getWorld().spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
|
||||
else
|
||||
player.spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
|
||||
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (radius * (Math.random() - Math.random()));
|
||||
float yy = (float) (radius * (Math.random() - Math.random()));
|
||||
float zz = (float) (radius * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
if (player == null)
|
||||
location.getWorld().spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
|
||||
else
|
||||
player.spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
|
||||
}
|
||||
} else {
|
||||
// WE NEED MAGIC!
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (radius * (Math.random() - Math.random()));
|
||||
float yy = (float) (radius * (Math.random() - Math.random()));
|
||||
float zz = (float) (radius * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, LegacyParticleEffects.Type.REDSTONE,
|
||||
red / 255F, green / 255F, blue / 255F, 1F,
|
||||
0, player == null ? null : Collections.singletonList(player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void bonemealSmoke(Location l) {
|
||||
final org.bukkit.World w = l.getWorld();
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_EAST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_WEST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.EAST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SELF);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.WEST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_EAST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_WEST);
|
||||
}
|
||||
}
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CompatibleParticleHandler {
|
||||
public enum ParticleType {
|
||||
EXPLOSION_NORMAL,
|
||||
EXPLOSION_LARGE,
|
||||
EXPLOSION_HUGE,
|
||||
FIREWORKS_SPARK,
|
||||
WATER_BUBBLE,
|
||||
WATER_SPLASH,
|
||||
WATER_WAKE,
|
||||
SUSPENDED,
|
||||
SUSPENDED_DEPTH,
|
||||
CRIT,
|
||||
CRIT_MAGIC,
|
||||
SMOKE_NORMAL,
|
||||
SMOKE_LARGE,
|
||||
SPELL,
|
||||
SPELL_INSTANT,
|
||||
SPELL_MOB,
|
||||
SPELL_MOB_AMBIENT,
|
||||
SPELL_WITCH,
|
||||
DRIP_WATER,
|
||||
DRIP_LAVA,
|
||||
VILLAGER_ANGRY,
|
||||
VILLAGER_HAPPY,
|
||||
TOWN_AURA,
|
||||
NOTE,
|
||||
PORTAL,
|
||||
ENCHANTMENT_TABLE,
|
||||
FLAME,
|
||||
LAVA,
|
||||
CLOUD,
|
||||
REDSTONE(), //DustOptions
|
||||
SNOWBALL,
|
||||
SNOW_SHOVEL,
|
||||
SLIME,
|
||||
HEART,
|
||||
BARRIER,
|
||||
ITEM_CRACK(), // ItemStack
|
||||
BLOCK_CRACK(), // BlockData
|
||||
BLOCK_DUST(), // BlockData
|
||||
WATER_DROP,
|
||||
// 1.8-1.12 included ITEM_TAKE
|
||||
MOB_APPEARANCE,
|
||||
/// End 1.8 particles ///
|
||||
DRAGON_BREATH(ServerVersion.V1_9, "SPELL_MOB_AMBIENT"),
|
||||
END_ROD(ServerVersion.V1_9, "ENCHANTMENT_TABLE"),
|
||||
DAMAGE_INDICATOR(ServerVersion.V1_9, "VILLAGER_ANGRY"),
|
||||
SWEEP_ATTACK(ServerVersion.V1_9, "CRIT"),
|
||||
/// End 1.9 particles ///
|
||||
FALLING_DUST(ServerVersion.V1_10, "BLOCK_DUST"), // BlockData
|
||||
/// End 1.10 ///
|
||||
TOTEM(ServerVersion.V1_11, "VILLAGER_HAPPY"),
|
||||
SPIT(ServerVersion.V1_11, "REDSTONE"),
|
||||
/// End 1.11-1.12 ///
|
||||
SQUID_INK(ServerVersion.V1_13, "CRIT"),
|
||||
BUBBLE_POP(ServerVersion.V1_13, "CRIT"),
|
||||
CURRENT_DOWN(ServerVersion.V1_13, "CRIT"),
|
||||
BUBBLE_COLUMN_UP(ServerVersion.V1_13, "CRIT"),
|
||||
NAUTILUS(ServerVersion.V1_13, "ENCHANTMENT_TABLE"),
|
||||
DOLPHIN(ServerVersion.V1_13, "TOWN_AURA"),
|
||||
/// End 1.13 ///
|
||||
SNEEZE(ServerVersion.V1_14, "REDSTONE"),
|
||||
CAMPFIRE_COSY_SMOKE(ServerVersion.V1_14, "SMOKE_NORMAL"),
|
||||
CAMPFIRE_SIGNAL_SMOKE(ServerVersion.V1_14, "SMOKE_LARGE"),
|
||||
COMPOSTER(ServerVersion.V1_14, "CRIT"),
|
||||
FLASH(ServerVersion.V1_14, "EXPLOSION_NORMAL"), // idk
|
||||
FALLING_LAVA(ServerVersion.V1_14, "DRIP_LAVA"),
|
||||
LANDING_LAVA(ServerVersion.V1_14, "LAVA"),
|
||||
FALLING_WATER(ServerVersion.V1_14, "DRIP_WATER"),
|
||||
/// End 1.14 ///
|
||||
DRIPPING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
FALLING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
FALLING_NECTAR(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
LANDING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
|
||||
/// End 1.15 ///
|
||||
// ToDo: Someone needs to make better compatible fall backs.
|
||||
SOUL_FIRE_FLAME(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
ASH(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
CRIMSON_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
WARPED_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
SOUL(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
DRIPPING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
FALLING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
LANDING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
REVERSE_PORTAL(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
WHITE_ASH(ServerVersion.V1_16, "DRIP_WATER"),
|
||||
/// End 1.16 ///
|
||||
// ToDo: Someone needs to make better compatible fall backs.
|
||||
LIGHT(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
DUST_COLOR_TRANSITION(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
VIBRATION(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
FALLING_SPORE_BLOSSOM(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SPORE_BLOSSOM_AIR(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SMALL_FLAME(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SNOWFLAKE(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
DRIPPING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
FALLING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
DRIPPING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
FALLING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
GLOW_SQUID_INK(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
GLOW(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
WAX_ON(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
WAX_OFF(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
ELECTRIC_SPARK(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
SCRAPE(ServerVersion.V1_17, "DRIP_WATER"),
|
||||
/// End 1.17 ///
|
||||
;
|
||||
|
||||
final boolean compatibilityMode;
|
||||
final LegacyParticleEffects.Type compatibleEffect;
|
||||
final Object particle;
|
||||
final static Map<String, ParticleType> map = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (ParticleType t : values()) {
|
||||
map.put(t.name(), t);
|
||||
}
|
||||
}
|
||||
|
||||
ParticleType() {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
this.compatibilityMode = true;
|
||||
this.particle = null;
|
||||
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(name());
|
||||
} else {
|
||||
this.compatibleEffect = null;
|
||||
// does this particle exist in our version?
|
||||
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
|
||||
if (check != null) {
|
||||
this.particle = check;
|
||||
this.compatibilityMode = false;
|
||||
} else {
|
||||
// this shouldn't happen, really
|
||||
this.particle = Particle.END_ROD;
|
||||
this.compatibilityMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleType(ServerVersion minVersion, String compatible) {
|
||||
// Particle class doesn't exist in 1.8
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
this.compatibilityMode = true;
|
||||
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(compatible);
|
||||
this.particle = null;
|
||||
} else if (ServerVersion.isServerVersionBelow(minVersion)) {
|
||||
this.compatibilityMode = true;
|
||||
this.compatibleEffect = null;
|
||||
this.particle = Particle.valueOf(compatible);
|
||||
} else {
|
||||
this.compatibleEffect = null;
|
||||
// does this particle exist in our version?
|
||||
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
|
||||
if (check != null) {
|
||||
this.particle = check;
|
||||
this.compatibilityMode = false;
|
||||
} else {
|
||||
// this shouldn't happen, really
|
||||
this.particle = Particle.END_ROD;
|
||||
this.compatibilityMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ParticleType getParticle(String name) {
|
||||
return map.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(String type, Location location) {
|
||||
spawnParticles(type, location, 0);
|
||||
}
|
||||
|
||||
public static void spawnParticles(String type, Location location, int count) {
|
||||
ParticleType pt;
|
||||
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
|
||||
spawnParticles(pt, location, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(String type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
|
||||
ParticleType pt;
|
||||
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
|
||||
spawnParticles(pt, location, count, offsetX, offsetY, offsetZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
LegacyParticleEffects.createParticle(location, type.compatibleEffect);
|
||||
} else {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (1 * (Math.random() - Math.random()));
|
||||
float yy = (float) (1 * (Math.random() - Math.random()));
|
||||
float zz = (float) (1 * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
|
||||
}
|
||||
} else {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (offsetX * (Math.random() - Math.random()));
|
||||
float yy = (float) (offsetY * (Math.random() - Math.random()));
|
||||
float zz = (float) (offsetZ * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
|
||||
}
|
||||
} else {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra) {
|
||||
spawnParticles(type, location, count, offsetX, offsetY, offsetZ, extra, null);
|
||||
}
|
||||
|
||||
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, Player receiver) {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (offsetX * (Math.random() - Math.random()));
|
||||
float yy = (float) (offsetY * (Math.random() - Math.random()));
|
||||
float zz = (float) (offsetZ * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, type.compatibleEffect, 0F, 0F, 0F, (float) extra, 0, receiver != null ? Collections.singletonList(receiver) : null);
|
||||
}
|
||||
} else {
|
||||
if (receiver == null) {
|
||||
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
|
||||
} else {
|
||||
receiver.spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void redstoneParticles(Location location, int red, int green, int blue) {
|
||||
redstoneParticles(location, red, green, blue, 1F, 1, 0, null);
|
||||
}
|
||||
|
||||
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius) {
|
||||
redstoneParticles(location, red, green, blue, size, count, radius, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn colored redstone particles
|
||||
*
|
||||
* @param location area to spawn the particle in
|
||||
* @param red red value 0-255
|
||||
* @param green green value 0-255
|
||||
* @param blue blue value 0-255
|
||||
* @param size (1.13+) size of the particles
|
||||
* @param count how many particles to spawn
|
||||
* @param radius how far to spread out the particles from location
|
||||
*/
|
||||
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius, Player player) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
float xx = (float) (radius * (Math.random() - Math.random()));
|
||||
float yy = (float) (radius * (Math.random() - Math.random()));
|
||||
float zz = (float) (radius * (Math.random() - Math.random()));
|
||||
if (player == null)
|
||||
location.getWorld().spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
|
||||
else
|
||||
player.spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
|
||||
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (radius * (Math.random() - Math.random()));
|
||||
float yy = (float) (radius * (Math.random() - Math.random()));
|
||||
float zz = (float) (radius * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
if (player == null)
|
||||
location.getWorld().spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
|
||||
else
|
||||
player.spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
|
||||
}
|
||||
} else {
|
||||
// WE NEED MAGIC!
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xx = (float) (radius * (Math.random() - Math.random()));
|
||||
float yy = (float) (radius * (Math.random() - Math.random()));
|
||||
float zz = (float) (radius * (Math.random() - Math.random()));
|
||||
Location at = location.clone().add(xx, yy, zz);
|
||||
LegacyParticleEffects.createParticle(at, LegacyParticleEffects.Type.REDSTONE,
|
||||
red / 255F, green / 255F, blue / 255F, 1F,
|
||||
0, player == null ? null : Collections.singletonList(player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void bonemealSmoke(Location l) {
|
||||
final org.bukkit.World w = l.getWorld();
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_EAST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_WEST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.EAST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.SELF);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.WEST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_EAST);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH);
|
||||
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_WEST);
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,9 @@ import org.bukkit.entity.Player;
|
||||
* sounds were renamed. New sounds have been added by different versions, as
|
||||
* well. The intent of this class is to provide either the correct sound or a
|
||||
* near equivalent for the current server.
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public enum CompatibleSound {
|
||||
|
||||
// some of these values are missing an API value..
|
||||
// some of these values are missing an API value...
|
||||
// would using the raw strings be better?
|
||||
// 1.8 list:
|
||||
// https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/mapping-and-modding-tutorials/2213619-1-8-all-playsound-sound-arguments
|
||||
@ -473,8 +469,8 @@ public enum CompatibleSound {
|
||||
BLOCK_CHEST_CLOSE(ServerVersion.V1_9, v("CHEST_CLOSE")),
|
||||
BLOCK_CHEST_LOCKED(ServerVersion.V1_9, v("CHEST_CLOSE", true)),
|
||||
BLOCK_CHEST_OPEN(ServerVersion.V1_9, v("CHEST_OPEN")),
|
||||
BLOCK_CHORUS_FLOWER_DEATH(ServerVersion.V1_9, v(null, true)), // I have no idea..
|
||||
BLOCK_CHORUS_FLOWER_GROW(ServerVersion.V1_9, v(null, true)), // I have no idea..
|
||||
BLOCK_CHORUS_FLOWER_DEATH(ServerVersion.V1_9, v(null, true)), // I have no idea...
|
||||
BLOCK_CHORUS_FLOWER_GROW(ServerVersion.V1_9, v(null, true)), // I have no idea...
|
||||
BLOCK_COMPARATOR_CLICK(ServerVersion.V1_9, v("WOOD_CLICK", true)),
|
||||
BLOCK_COMPOSTER_EMPTY,
|
||||
BLOCK_COMPOSTER_FILL,
|
||||
@ -638,7 +634,7 @@ public enum CompatibleSound {
|
||||
ENTITY_ARMOR_STAND_FALL,
|
||||
ENTITY_ARMOR_STAND_HIT,
|
||||
ENTITY_ARMOR_STAND_PLACE,
|
||||
ENTITY_ARROW_HIT("SUCCESSFUL_HIT"), // these may be reversed..
|
||||
ENTITY_ARROW_HIT("SUCCESSFUL_HIT"), // these may be reversed...
|
||||
ENTITY_ARROW_HIT_PLAYER("ARROW_HIT"),
|
||||
ENTITY_ARROW_SHOOT("SHOOT_ARROW"),
|
||||
ENTITY_BAT_AMBIENT("BAT_IDLE"),
|
||||
@ -1226,7 +1222,7 @@ public enum CompatibleSound {
|
||||
protected /*final*/ boolean compatibilityMode;
|
||||
protected static final boolean DEBUG = false;
|
||||
|
||||
private CompatibleSound() {
|
||||
CompatibleSound() {
|
||||
// This could get risky, since we haven't finished this
|
||||
//sound = Sound.valueOf(name());
|
||||
Sound find = null;
|
||||
@ -1244,21 +1240,22 @@ public enum CompatibleSound {
|
||||
}
|
||||
|
||||
// if the sound ony ever changed from 1.8 -> 1.9
|
||||
private CompatibleSound(String compatibility_18) {
|
||||
CompatibleSound(String compatibility_18) {
|
||||
try {
|
||||
compatibilityMode = false;
|
||||
|
||||
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_9)) {
|
||||
sound = Sound.valueOf(compatibility_18);
|
||||
} else {
|
||||
sound = Sound.valueOf(name());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ERROR loading " + name());
|
||||
e.printStackTrace();
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private CompatibleSound(Version... versions) {
|
||||
CompatibleSound(Version... versions) {
|
||||
try {
|
||||
for (Version v : versions) {
|
||||
if (v.sound != null && ServerVersion.isServerVersionAtLeast(v.version)) {
|
||||
@ -1267,12 +1264,13 @@ public enum CompatibleSound {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ERROR loading " + name());
|
||||
for (Version v : versions) {
|
||||
System.err.println(v.version + " - " + v.sound);
|
||||
}
|
||||
e.printStackTrace();
|
||||
|
||||
ex.printStackTrace();
|
||||
}
|
||||
Sound find = null;
|
||||
for (Sound s : Sound.values()) {
|
||||
@ -1285,7 +1283,7 @@ public enum CompatibleSound {
|
||||
compatibilityMode = find == null;
|
||||
}
|
||||
|
||||
private CompatibleSound(ServerVersion minVersion, Version... versions) {
|
||||
CompatibleSound(ServerVersion minVersion, Version... versions) {
|
||||
try {
|
||||
if (ServerVersion.isServerVersionAtLeast(minVersion)) {
|
||||
// should be good to use this sound
|
||||
@ -1302,12 +1300,13 @@ public enum CompatibleSound {
|
||||
sound = null;
|
||||
compatibilityMode = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ERROR loading " + name() + " (" + minVersion);
|
||||
for (Version v : versions) {
|
||||
System.err.println(v.version + " - " + v.sound);
|
||||
}
|
||||
e.printStackTrace();
|
||||
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,85 +1,88 @@
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EntityNamespace {
|
||||
|
||||
static final HashMap<String, EntityType> validTypes = new HashMap();
|
||||
static final HashMap<String, String> legacyToModernTypes = new HashMap() {
|
||||
{
|
||||
put("xporb", "experience_orb");
|
||||
put("xp_orb", "experience_orb");
|
||||
put("leashknot", "leash_knot");
|
||||
put("smallfireball", "small_fireball");
|
||||
put("thrownenderpearl", "ender_pearl");
|
||||
put("eyeofendersignal", "eye_of_ender");
|
||||
put("eye_of_ender_signal", "eye_of_ender");
|
||||
put("thrownexpbottle", "experience_bottle");
|
||||
put("xp_bottle", "experience_bottle");
|
||||
put("itemframe", "item_frame");
|
||||
put("witherskull", "wither_skull");
|
||||
put("primedtnt", "tnt");
|
||||
put("fallingsand", "falling_block");
|
||||
put("fireworksrocketentity", "firework_rocket");
|
||||
put("fireworks_rocket", "firework_rocket");
|
||||
put("spectralarrow", "spectral_arrow");
|
||||
put("tippedarrow", "arrow");
|
||||
put("shulkerbullet", "shulker_bullet");
|
||||
put("dragonfireball", "dragon_fireball");
|
||||
put("armorstand", "armor_stand");
|
||||
put("minecartcommandblock", "command_block_minecart");
|
||||
put("commandblock_minecart", "command_block_minecart");
|
||||
put("minecartrideable", "minecart");
|
||||
put("minecartchest", "chest_minecart");
|
||||
put("minecartfurnace", "furnace_minecart");
|
||||
put("minecarttnt", "tnt_minecart");
|
||||
put("minecarthopper", "hopper_minecart");
|
||||
put("minecartmobspawner", "spawner_minecart");
|
||||
put("pigzombie", "zombie_pigman");
|
||||
put("cavespider", "cave_spider");
|
||||
put("lavaslime", "magma_cube");
|
||||
put("enderdragon", "ender_dragon");
|
||||
put("witherboss", "wither");
|
||||
put("mushroomcow", "mooshroom");
|
||||
put("snowman", "snow_golem");
|
||||
put("ozelot", "ocelot");
|
||||
put("villagergolem", "iron_golem");
|
||||
put("villager_golem", "iron_golem");
|
||||
put("entityhorse", "horse");
|
||||
put("endercrystal", "end_crystal");
|
||||
put("ender_crystal", "end_crystal");
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
for (EntityType t : EntityType.values()) {
|
||||
if (t.getName() != null) {
|
||||
validTypes.put(t.getName().toLowerCase(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType minecraftToBukkit(String entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
// first try to translate natively
|
||||
EntityType type = EntityType.fromName(entity);
|
||||
if (type == null) {
|
||||
// try legacy values
|
||||
type = EntityType.fromName(legacyToModernTypes.get(entity));
|
||||
// try converting modern to legacy
|
||||
if (type == null && legacyToModernTypes.containsValue(entity)) {
|
||||
for (Map.Entry<String, String> e : legacyToModernTypes.entrySet()) {
|
||||
if (e.getValue().equals(entity) && (type = EntityType.fromName(legacyToModernTypes.get(e.getKey()))) != null) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EntityNamespace {
|
||||
static final HashMap<String, EntityType> validTypes = new HashMap<>();
|
||||
static final HashMap<String, String> legacyToModernTypes = new HashMap<String, String>() {
|
||||
{
|
||||
put("xporb", "experience_orb");
|
||||
put("xp_orb", "experience_orb");
|
||||
put("leashknot", "leash_knot");
|
||||
put("smallfireball", "small_fireball");
|
||||
put("thrownenderpearl", "ender_pearl");
|
||||
put("eyeofendersignal", "eye_of_ender");
|
||||
put("eye_of_ender_signal", "eye_of_ender");
|
||||
put("thrownexpbottle", "experience_bottle");
|
||||
put("xp_bottle", "experience_bottle");
|
||||
put("itemframe", "item_frame");
|
||||
put("witherskull", "wither_skull");
|
||||
put("primedtnt", "tnt");
|
||||
put("fallingsand", "falling_block");
|
||||
put("fireworksrocketentity", "firework_rocket");
|
||||
put("fireworks_rocket", "firework_rocket");
|
||||
put("spectralarrow", "spectral_arrow");
|
||||
put("tippedarrow", "arrow");
|
||||
put("shulkerbullet", "shulker_bullet");
|
||||
put("dragonfireball", "dragon_fireball");
|
||||
put("armorstand", "armor_stand");
|
||||
put("minecartcommandblock", "command_block_minecart");
|
||||
put("commandblock_minecart", "command_block_minecart");
|
||||
put("minecartrideable", "minecart");
|
||||
put("minecartchest", "chest_minecart");
|
||||
put("minecartfurnace", "furnace_minecart");
|
||||
put("minecarttnt", "tnt_minecart");
|
||||
put("minecarthopper", "hopper_minecart");
|
||||
put("minecartmobspawner", "spawner_minecart");
|
||||
put("pigzombie", "zombie_pigman");
|
||||
put("cavespider", "cave_spider");
|
||||
put("lavaslime", "magma_cube");
|
||||
put("enderdragon", "ender_dragon");
|
||||
put("witherboss", "wither");
|
||||
put("mushroomcow", "mooshroom");
|
||||
put("snowman", "snow_golem");
|
||||
put("ozelot", "ocelot");
|
||||
put("villagergolem", "iron_golem");
|
||||
put("villager_golem", "iron_golem");
|
||||
put("entityhorse", "horse");
|
||||
put("endercrystal", "end_crystal");
|
||||
put("ender_crystal", "end_crystal");
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
for (EntityType t : EntityType.values()) {
|
||||
if (t.getName() != null) {
|
||||
validTypes.put(t.getName().toLowerCase(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType minecraftToBukkit(String entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// first try to translate natively
|
||||
EntityType type = EntityType.fromName(entity);
|
||||
|
||||
if (type == null) {
|
||||
// try legacy values
|
||||
type = EntityType.fromName(legacyToModernTypes.get(entity));
|
||||
|
||||
// try converting modern to legacy
|
||||
if (type == null && legacyToModernTypes.containsValue(entity)) {
|
||||
for (Map.Entry<String, String> e : legacyToModernTypes.entrySet()) {
|
||||
if (e.getValue().equals(entity) && (type = EntityType.fromName(legacyToModernTypes.get(e.getKey()))) != null) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,12 +8,8 @@ import java.util.Map;
|
||||
/**
|
||||
* Starting in Minecraft 1.13, separate materials for blocks and items were
|
||||
* phased out. This provides a translation for those values.
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-09-12
|
||||
*/
|
||||
public enum LegacyMaterialBlockType {
|
||||
|
||||
OAK_LEAVES("LEAVES", (byte) 8, true),
|
||||
SPRUCE_LEAVES("LEAVES", (byte) 9, true),
|
||||
BIRCH_LEAVES("LEAVES", (byte) 10, true),
|
||||
@ -56,8 +52,8 @@ public enum LegacyMaterialBlockType {
|
||||
final String alternateBlockMaterialName;
|
||||
final Material blockMaterial, alternateBlockMaterial;
|
||||
final boolean requiresData; // some blocks require data to render properly (double blocks)
|
||||
final static Map<String, LegacyMaterialBlockType> lookupTable = new HashMap();
|
||||
final static Map<String, LegacyMaterialBlockType> reverseLookupTable = new HashMap();
|
||||
final static Map<String, LegacyMaterialBlockType> lookupTable = new HashMap<>();
|
||||
final static Map<String, LegacyMaterialBlockType> reverseLookupTable = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (LegacyMaterialBlockType t : values()) {
|
||||
@ -69,23 +65,23 @@ public enum LegacyMaterialBlockType {
|
||||
}
|
||||
}
|
||||
|
||||
private LegacyMaterialBlockType(String blockMaterial) {
|
||||
LegacyMaterialBlockType(String blockMaterial) {
|
||||
this(blockMaterial, (byte) -1, null, false);
|
||||
}
|
||||
|
||||
private LegacyMaterialBlockType(String blockMaterial, boolean requiresData) {
|
||||
LegacyMaterialBlockType(String blockMaterial, boolean requiresData) {
|
||||
this(blockMaterial, (byte) -1, null, requiresData);
|
||||
}
|
||||
|
||||
private LegacyMaterialBlockType(String blockMaterial, byte data, boolean requiresData) {
|
||||
LegacyMaterialBlockType(String blockMaterial, byte data, boolean requiresData) {
|
||||
this(blockMaterial, data, null, requiresData);
|
||||
}
|
||||
|
||||
private LegacyMaterialBlockType(String blockMaterial, String alternateMaterial) {
|
||||
LegacyMaterialBlockType(String blockMaterial, String alternateMaterial) {
|
||||
this(blockMaterial, (byte) -1, alternateMaterial, false);
|
||||
}
|
||||
|
||||
private LegacyMaterialBlockType(String blockMaterial, byte data, String alternateMaterial, boolean requiresData) {
|
||||
LegacyMaterialBlockType(String blockMaterial, byte data, String alternateMaterial, boolean requiresData) {
|
||||
this.blockMaterialName = blockMaterial;
|
||||
this.alternateBlockMaterialName = alternateMaterial;
|
||||
this.requiresData = requiresData;
|
||||
|
@ -1,255 +1,253 @@
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Particle effects for servers 1.8 and below
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-23
|
||||
*/
|
||||
public class LegacyParticleEffects {
|
||||
|
||||
public static enum Type {
|
||||
|
||||
EXPLOSION_NORMAL("explode"),
|
||||
EXPLOSION_LARGE("largeexplode"),
|
||||
EXPLOSION_HUGE("hugeexplosion"),
|
||||
FIREWORKS_SPARK("fireworksSpark"),
|
||||
WATER_BUBBLE("bubble"),
|
||||
WATER_SPLASH("splash"),
|
||||
WATER_WAKE("wake", ServerVersion.V1_8),
|
||||
SUSPENDED("suspended"),
|
||||
SUSPENDED_DEPTH("depthsuspend"),
|
||||
CRIT("crit"),
|
||||
CRIT_MAGIC("magicCrit"),
|
||||
SMOKE_NORMAL("smoke"),
|
||||
SMOKE_LARGE("largesmoke"),
|
||||
SPELL("spell"),
|
||||
SPELL_INSTANT("instantSpell"),
|
||||
SPELL_MOB("mobSpell"),
|
||||
SPELL_MOB_AMBIENT("mobSpellAmbient"),
|
||||
SPELL_WITCH("witchMagic"),
|
||||
DRIP_WATER("dripWater"),
|
||||
DRIP_LAVA("dripLava"),
|
||||
VILLAGER_ANGRY("angryVillager"),
|
||||
VILLAGER_HAPPY("happyVillager"),
|
||||
TOWN_AURA("townaura"),
|
||||
NOTE("note"),
|
||||
PORTAL("portal"),
|
||||
ENCHANTMENT_TABLE("enchantmenttable"),
|
||||
FLAME("flame"),
|
||||
LAVA("lava"),
|
||||
FOOTSTEP("footstep"),
|
||||
CLOUD("cloud"),
|
||||
REDSTONE("reddust"),
|
||||
SNOWBALL("snowballpoof"),
|
||||
SNOW_SHOVEL("snowshovel"),
|
||||
SLIME("slime"),
|
||||
HEART("heart"),
|
||||
BARRIER("barrier", ServerVersion.V1_8),
|
||||
/**
|
||||
* Used when a block is broken
|
||||
*/
|
||||
ITEM_CRACK("iconcrack_"),
|
||||
BLOCK_CRACK("blockcrack_", ServerVersion.V1_8),
|
||||
BLOCK_DUST("blockdust_", ServerVersion.V1_8),
|
||||
WATER_DROP("droplet", ServerVersion.V1_8),
|
||||
ITEM_TAKE("take", ServerVersion.V1_8),
|
||||
MOB_APPEARANCE("mobappearance", ServerVersion.V1_8),
|
||||
TOOL_BREAK("tilecrack_", ServerVersion.UNKNOWN, ServerVersion.V1_7);
|
||||
|
||||
public final String name;
|
||||
public final ServerVersion minVersion;
|
||||
public final ServerVersion maxVersion;
|
||||
|
||||
private Type(String name) {
|
||||
this.name = name;
|
||||
this.minVersion = ServerVersion.UNKNOWN;
|
||||
this.maxVersion = null;
|
||||
}
|
||||
|
||||
private Type(String name, ServerVersion minVersion) {
|
||||
this.name = name;
|
||||
this.minVersion = minVersion;
|
||||
this.maxVersion = null;
|
||||
}
|
||||
|
||||
private Type(String name, ServerVersion minVersion, ServerVersion maxVersion) {
|
||||
this.name = name;
|
||||
this.minVersion = minVersion;
|
||||
this.maxVersion = maxVersion;
|
||||
}
|
||||
|
||||
public static Type getById(String id) {
|
||||
for (Type t : Type.values()) {
|
||||
if (t.name.equalsIgnoreCase(id) || t.name().equalsIgnoreCase(id)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String version = getNMSVersion();
|
||||
private static boolean enabled = true;
|
||||
private static Class mc_packetPlayOutWorldParticlesClazz;
|
||||
private static Class cb_craftPlayerClazz;
|
||||
private static Method cb_craftPlayer_getHandle;
|
||||
private static Class mc_entityPlayerClazz;
|
||||
private static Class mc_playerConnectionClazz;
|
||||
private static Field mc_entityPlayer_playerConnection;
|
||||
private static Class mc_PacketInterface;
|
||||
private static Method mc_playerConnection_sendPacket;
|
||||
private static Class mc_EnumParticle;
|
||||
private static Method mc_EnumParticle_valueOf;
|
||||
|
||||
static {
|
||||
try {
|
||||
// lower versions use "Packet63WorldParticles"
|
||||
if (!version.startsWith("v1_7") && !version.startsWith("v1_8")) {
|
||||
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".Packet63WorldParticles");
|
||||
} else {
|
||||
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".PacketPlayOutWorldParticles");
|
||||
}
|
||||
cb_craftPlayerClazz = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftPlayer");
|
||||
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
|
||||
mc_entityPlayerClazz = Class.forName("net.minecraft.server." + version + ".EntityPlayer");
|
||||
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField("playerConnection");
|
||||
mc_playerConnectionClazz = Class.forName("net.minecraft.server." + version + ".PlayerConnection");
|
||||
mc_PacketInterface = Class.forName("net.minecraft.server." + version + ".Packet");
|
||||
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
|
||||
if (version.startsWith("v1_8")) {
|
||||
// Aren't worrying about anything after 1.8 in this class here
|
||||
mc_EnumParticle = Class.forName("net.minecraft.server." + version + ".EnumParticle");
|
||||
mc_EnumParticle_valueOf = mc_EnumParticle.getDeclaredMethod("valueOf", String.class);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing particle packets (disabling further packets)", ex);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getNMSVersion() {
|
||||
String ver = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return ver.substring(ver.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public static void createParticle(Location l, Type e) {
|
||||
createParticle(l, e, 0F, 0F, 0F, 1, 0, null);
|
||||
}
|
||||
|
||||
public static void createParticle(Location l, Type e, List<Player> localOnly) {
|
||||
createParticle(l, e, 0F, 0F, 0F, 1, 0, localOnly);
|
||||
}
|
||||
|
||||
public static void createParticle(Location l, Type e, float effectSpeed, int amountOfParticles) {
|
||||
createParticle(l, e, 0F, 0F, 0F, effectSpeed, amountOfParticles, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param l exact location to spawn the particle
|
||||
* @param e particle effect type
|
||||
* @param xx for notes, this is a value 0-1 for the color ([0-24]/24), for
|
||||
* redstone this is the red value 0-1 ([0-255]/255).
|
||||
* Otherwise this is the distance for particles to fly on the x-axis.
|
||||
* @param yy for redstone this is the green value 0-1 ([0-255]/255)
|
||||
* Otherwise this is the distance for particles to fly on the y-axis.
|
||||
* @param zz for redstone this is the blue value 0-1 ([0-255]/255)
|
||||
* Otherwise this is the distance for particles to fly on the z-axis.
|
||||
* @param effectSpeed particle effect speed
|
||||
* @param amountOfParticles extra particles to spawn (client-side)
|
||||
* @param localOnly list of players to send the packets to, or null for all players
|
||||
*/
|
||||
public static void createParticle(Location l, Type e, float xx, float yy, float zz, float effectSpeed, int amountOfParticles, List<Player> localOnly) {
|
||||
if (!enabled || e == null || effectSpeed < 0 || amountOfParticles < 0
|
||||
|| !ServerVersion.isServerVersionAtLeast(e.minVersion)
|
||||
|| (e.maxVersion != null && !ServerVersion.isServerVersionBelow(e.maxVersion))) {
|
||||
return;
|
||||
}
|
||||
final int rangeSquared = 256; // apparently there is no way to override this (unless to make smaller, of course)
|
||||
// collect a list of players to send this packet to
|
||||
List<Player> sendTo = new ArrayList();
|
||||
if (localOnly == null) {
|
||||
for (Player p : l.getWorld().getPlayers()) {
|
||||
if (p.getLocation().distanceSquared(l) <= rangeSquared) {
|
||||
sendTo.add(p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final World w = l.getWorld();
|
||||
for (Player p : localOnly) {
|
||||
if (p.getWorld() == w && p.getLocation().distanceSquared(l) <= rangeSquared) {
|
||||
sendTo.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sendTo.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Make an instance of the packet!
|
||||
Object sPacket = mc_packetPlayOutWorldParticlesClazz.newInstance();
|
||||
for (Field field : sPacket.getClass().getDeclaredFields()) {
|
||||
// Set those fields we need to be accessible!
|
||||
field.setAccessible(true);
|
||||
final String fieldName = field.getName();
|
||||
// Set them to what we want!
|
||||
if (fieldName.equals("a")) {
|
||||
// we're just going to assume it's either 1.7 or 1.8
|
||||
if (version.startsWith("v1_8")) {
|
||||
// 1.8 uses an Enum
|
||||
field.set(sPacket, mc_EnumParticle_valueOf.invoke(null, e.name()));
|
||||
} else {
|
||||
field.set(sPacket, e.name);
|
||||
}
|
||||
} else if (fieldName.equals("b")) {
|
||||
field.setFloat(sPacket, (float) l.getX()); // x
|
||||
} else if (fieldName.equals("c")) {
|
||||
field.setFloat(sPacket, (float) l.getY()); // y
|
||||
} else if (fieldName.equals("d")) {
|
||||
field.setFloat(sPacket, (float) l.getZ()); // z
|
||||
} else if (fieldName.equals("e")) {
|
||||
field.setFloat(sPacket, xx); // xOffset
|
||||
} else if (fieldName.equals("f")) {
|
||||
field.setFloat(sPacket, yy); // yOffset
|
||||
} else if (fieldName.equals("g")) {
|
||||
field.setFloat(sPacket, zz); // zOffset
|
||||
} else if (fieldName.equals("h")) {
|
||||
field.setFloat(sPacket, effectSpeed);
|
||||
} else if (fieldName.equals("i")) {
|
||||
field.setInt(sPacket, amountOfParticles);
|
||||
}
|
||||
/*
|
||||
1.8 also includes other data:
|
||||
j = boolean, set if view distance is increased from 256 to 65536
|
||||
k = int[] for packet data (like block type for ITEM_CRACK)
|
||||
*/
|
||||
}
|
||||
// send it on its way!
|
||||
for (Player p : sendTo) {
|
||||
sendPacket(sPacket, p);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing a particle packet (disabling further packets)", ex);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendPacket(Object packet, Player to) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
Object cbPlayer = cb_craftPlayer_getHandle.invoke(to);
|
||||
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
|
||||
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
|
||||
}
|
||||
}
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Particle effects for servers 1.8 and below
|
||||
*/
|
||||
public class LegacyParticleEffects {
|
||||
public enum Type {
|
||||
EXPLOSION_NORMAL("explode"),
|
||||
EXPLOSION_LARGE("largeexplode"),
|
||||
EXPLOSION_HUGE("hugeexplosion"),
|
||||
FIREWORKS_SPARK("fireworksSpark"),
|
||||
WATER_BUBBLE("bubble"),
|
||||
WATER_SPLASH("splash"),
|
||||
WATER_WAKE("wake", ServerVersion.V1_8),
|
||||
SUSPENDED("suspended"),
|
||||
SUSPENDED_DEPTH("depthsuspend"),
|
||||
CRIT("crit"),
|
||||
CRIT_MAGIC("magicCrit"),
|
||||
SMOKE_NORMAL("smoke"),
|
||||
SMOKE_LARGE("largesmoke"),
|
||||
SPELL("spell"),
|
||||
SPELL_INSTANT("instantSpell"),
|
||||
SPELL_MOB("mobSpell"),
|
||||
SPELL_MOB_AMBIENT("mobSpellAmbient"),
|
||||
SPELL_WITCH("witchMagic"),
|
||||
DRIP_WATER("dripWater"),
|
||||
DRIP_LAVA("dripLava"),
|
||||
VILLAGER_ANGRY("angryVillager"),
|
||||
VILLAGER_HAPPY("happyVillager"),
|
||||
TOWN_AURA("townaura"),
|
||||
NOTE("note"),
|
||||
PORTAL("portal"),
|
||||
ENCHANTMENT_TABLE("enchantmenttable"),
|
||||
FLAME("flame"),
|
||||
LAVA("lava"),
|
||||
FOOTSTEP("footstep"),
|
||||
CLOUD("cloud"),
|
||||
REDSTONE("reddust"),
|
||||
SNOWBALL("snowballpoof"),
|
||||
SNOW_SHOVEL("snowshovel"),
|
||||
SLIME("slime"),
|
||||
HEART("heart"),
|
||||
BARRIER("barrier", ServerVersion.V1_8),
|
||||
/**
|
||||
* Used when a block is broken
|
||||
*/
|
||||
ITEM_CRACK("iconcrack_"),
|
||||
BLOCK_CRACK("blockcrack_", ServerVersion.V1_8),
|
||||
BLOCK_DUST("blockdust_", ServerVersion.V1_8),
|
||||
WATER_DROP("droplet", ServerVersion.V1_8),
|
||||
ITEM_TAKE("take", ServerVersion.V1_8),
|
||||
MOB_APPEARANCE("mobappearance", ServerVersion.V1_8),
|
||||
TOOL_BREAK("tilecrack_", ServerVersion.UNKNOWN, ServerVersion.V1_7);
|
||||
|
||||
public final String name;
|
||||
public final ServerVersion minVersion;
|
||||
public final ServerVersion maxVersion;
|
||||
|
||||
Type(String name) {
|
||||
this.name = name;
|
||||
this.minVersion = ServerVersion.UNKNOWN;
|
||||
this.maxVersion = null;
|
||||
}
|
||||
|
||||
Type(String name, ServerVersion minVersion) {
|
||||
this.name = name;
|
||||
this.minVersion = minVersion;
|
||||
this.maxVersion = null;
|
||||
}
|
||||
|
||||
Type(String name, ServerVersion minVersion, ServerVersion maxVersion) {
|
||||
this.name = name;
|
||||
this.minVersion = minVersion;
|
||||
this.maxVersion = maxVersion;
|
||||
}
|
||||
|
||||
public static Type getById(String id) {
|
||||
for (Type t : Type.values()) {
|
||||
if (t.name.equalsIgnoreCase(id) || t.name().equalsIgnoreCase(id)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String version = getNMSVersion();
|
||||
private static boolean enabled = true;
|
||||
private static Class<?> mc_packetPlayOutWorldParticlesClazz;
|
||||
private static Class<?> cb_craftPlayerClazz;
|
||||
private static Method cb_craftPlayer_getHandle;
|
||||
private static Class<?> mc_entityPlayerClazz;
|
||||
private static Class<?> mc_playerConnectionClazz;
|
||||
private static Field mc_entityPlayer_playerConnection;
|
||||
private static Class<?> mc_PacketInterface;
|
||||
private static Method mc_playerConnection_sendPacket;
|
||||
private static Class<?> mc_EnumParticle;
|
||||
private static Method mc_EnumParticle_valueOf;
|
||||
|
||||
static {
|
||||
try {
|
||||
// lower versions use "Packet63WorldParticles"
|
||||
if (!version.startsWith("v1_7") && !version.startsWith("v1_8")) {
|
||||
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".Packet63WorldParticles");
|
||||
} else {
|
||||
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".PacketPlayOutWorldParticles");
|
||||
}
|
||||
cb_craftPlayerClazz = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftPlayer");
|
||||
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
|
||||
mc_entityPlayerClazz = Class.forName("net.minecraft.server." + version + ".EntityPlayer");
|
||||
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField("playerConnection");
|
||||
mc_playerConnectionClazz = Class.forName("net.minecraft.server." + version + ".PlayerConnection");
|
||||
mc_PacketInterface = Class.forName("net.minecraft.server." + version + ".Packet");
|
||||
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
|
||||
if (version.startsWith("v1_8")) {
|
||||
// Aren't worrying about anything after 1.8 in this class here
|
||||
mc_EnumParticle = Class.forName("net.minecraft.server." + version + ".EnumParticle");
|
||||
mc_EnumParticle_valueOf = mc_EnumParticle.getDeclaredMethod("valueOf", String.class);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing particle packets (disabling further packets)", ex);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getNMSVersion() {
|
||||
String ver = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return ver.substring(ver.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public static void createParticle(Location l, Type e) {
|
||||
createParticle(l, e, 0F, 0F, 0F, 1, 0, null);
|
||||
}
|
||||
|
||||
public static void createParticle(Location l, Type e, List<Player> localOnly) {
|
||||
createParticle(l, e, 0F, 0F, 0F, 1, 0, localOnly);
|
||||
}
|
||||
|
||||
public static void createParticle(Location l, Type e, float effectSpeed, int amountOfParticles) {
|
||||
createParticle(l, e, 0F, 0F, 0F, effectSpeed, amountOfParticles, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param l exact location to spawn the particle
|
||||
* @param e particle effect type
|
||||
* @param xx for notes, this is a value 0-1 for the color ([0-24]/24), for
|
||||
* redstone this is the red value 0-1 ([0-255]/255).
|
||||
* Otherwise, this is the distance for particles to fly on the x-axis.
|
||||
* @param yy for redstone this is the green value 0-1 ([0-255]/255)
|
||||
* Otherwise this is the distance for particles to fly on the y-axis.
|
||||
* @param zz for redstone this is the blue value 0-1 ([0-255]/255)
|
||||
* Otherwise this is the distance for particles to fly on the z-axis.
|
||||
* @param effectSpeed particle effect speed
|
||||
* @param amountOfParticles extra particles to spawn (client-side)
|
||||
* @param localOnly list of players to send the packets to, or null for all players
|
||||
*/
|
||||
public static void createParticle(Location l, Type e, float xx, float yy, float zz, float effectSpeed, int amountOfParticles, List<Player> localOnly) {
|
||||
if (!enabled || e == null || effectSpeed < 0 || amountOfParticles < 0
|
||||
|| !ServerVersion.isServerVersionAtLeast(e.minVersion)
|
||||
|| (e.maxVersion != null && !ServerVersion.isServerVersionBelow(e.maxVersion))) {
|
||||
return;
|
||||
}
|
||||
final int rangeSquared = 256; // apparently there is no way to override this (unless to make smaller, of course)
|
||||
// collect a list of players to send this packet to
|
||||
List<Player> sendTo = new ArrayList();
|
||||
if (localOnly == null) {
|
||||
for (Player p : l.getWorld().getPlayers()) {
|
||||
if (p.getLocation().distanceSquared(l) <= rangeSquared) {
|
||||
sendTo.add(p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final World w = l.getWorld();
|
||||
for (Player p : localOnly) {
|
||||
if (p.getWorld() == w && p.getLocation().distanceSquared(l) <= rangeSquared) {
|
||||
sendTo.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sendTo.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Make an instance of the packet!
|
||||
Object sPacket = mc_packetPlayOutWorldParticlesClazz.newInstance();
|
||||
for (Field field : sPacket.getClass().getDeclaredFields()) {
|
||||
// Set those fields we need to be accessible!
|
||||
field.setAccessible(true);
|
||||
final String fieldName = field.getName();
|
||||
|
||||
// Set them to what we want!
|
||||
if (fieldName.equals("a")) {
|
||||
// we're just going to assume it's either 1.7 or 1.8
|
||||
if (version.startsWith("v1_8")) {
|
||||
// 1.8 uses an Enum
|
||||
field.set(sPacket, mc_EnumParticle_valueOf.invoke(null, e.name()));
|
||||
} else {
|
||||
field.set(sPacket, e.name);
|
||||
}
|
||||
} else if (fieldName.equals("b")) {
|
||||
field.setFloat(sPacket, (float) l.getX()); // x
|
||||
} else if (fieldName.equals("c")) {
|
||||
field.setFloat(sPacket, (float) l.getY()); // y
|
||||
} else if (fieldName.equals("d")) {
|
||||
field.setFloat(sPacket, (float) l.getZ()); // z
|
||||
} else if (fieldName.equals("e")) {
|
||||
field.setFloat(sPacket, xx); // xOffset
|
||||
} else if (fieldName.equals("f")) {
|
||||
field.setFloat(sPacket, yy); // yOffset
|
||||
} else if (fieldName.equals("g")) {
|
||||
field.setFloat(sPacket, zz); // zOffset
|
||||
} else if (fieldName.equals("h")) {
|
||||
field.setFloat(sPacket, effectSpeed);
|
||||
} else if (fieldName.equals("i")) {
|
||||
field.setInt(sPacket, amountOfParticles);
|
||||
}
|
||||
/*
|
||||
1.8 also includes other data:
|
||||
j = boolean, set if view distance is increased from 256 to 65536
|
||||
k = int[] for packet data (like block type for ITEM_CRACK)
|
||||
*/
|
||||
}
|
||||
|
||||
// send it on its way!
|
||||
for (Player p : sendTo) {
|
||||
sendPacket(sPacket, p);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing a particle packet (disabling further packets)", ex);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendPacket(Object packet, Player to) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
Object cbPlayer = cb_craftPlayer_getHandle.invoke(to);
|
||||
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
|
||||
|
||||
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,49 @@
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
public class LegacyPotionEffects {
|
||||
|
||||
private LegacyPotionEffects() {
|
||||
}
|
||||
|
||||
protected final static Random rand = new Random();
|
||||
|
||||
private final static HashMap<Integer, String> potionEffectNames = new HashMap() {
|
||||
{
|
||||
put(PotionEffectType.SPEED.getId(), "Speed");
|
||||
put(PotionEffectType.SLOW.getId(), "Slowness");
|
||||
put(PotionEffectType.FAST_DIGGING.getId(), "Haste");
|
||||
put(PotionEffectType.SLOW_DIGGING.getId(), "Mining Fatigue");
|
||||
put(PotionEffectType.INCREASE_DAMAGE.getId(), "Strength");
|
||||
put(PotionEffectType.WEAKNESS.getId(), "Weakness");
|
||||
put(PotionEffectType.HEAL.getId(), "Instant Health");
|
||||
put(PotionEffectType.HARM.getId(), "Instant Damage");
|
||||
put(PotionEffectType.JUMP.getId(), "Jump Boost");
|
||||
put(PotionEffectType.CONFUSION.getId(), "Nausea");
|
||||
put(PotionEffectType.REGENERATION.getId(), "Regeneration");
|
||||
put(PotionEffectType.DAMAGE_RESISTANCE.getId(), "Resistance");
|
||||
put(PotionEffectType.FIRE_RESISTANCE.getId(), "Fire Resistance");
|
||||
put(PotionEffectType.WATER_BREATHING.getId(), "Water Breathing");
|
||||
put(PotionEffectType.INVISIBILITY.getId(), "Invisibility");
|
||||
put(PotionEffectType.BLINDNESS.getId(), "Blindness");
|
||||
put(PotionEffectType.NIGHT_VISION.getId(), "Night Vision");
|
||||
put(PotionEffectType.HUNGER.getId(), "Hunger");
|
||||
put(PotionEffectType.POISON.getId(), "Poison");
|
||||
put(PotionEffectType.WITHER.getId(), "Wither");
|
||||
put(PotionEffectType.HEALTH_BOOST.getId(), "Health Boost");
|
||||
put(PotionEffectType.ABSORPTION.getId(), "Absorption");
|
||||
put(PotionEffectType.SATURATION.getId(), "Saturation");
|
||||
}
|
||||
};
|
||||
|
||||
public static String getEffectName(PotionEffectType e) {
|
||||
if (e == null) {
|
||||
return "null";
|
||||
}
|
||||
final String n = potionEffectNames.get(e.getId());
|
||||
return n == null ? e.getName() : n;
|
||||
}
|
||||
}
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
public class LegacyPotionEffects {
|
||||
private LegacyPotionEffects() {
|
||||
}
|
||||
|
||||
protected final static Random rand = new Random();
|
||||
|
||||
private final static HashMap<Integer, String> potionEffectNames = new HashMap<Integer, String>() {
|
||||
{
|
||||
put(PotionEffectType.SPEED.getId(), "Speed");
|
||||
put(PotionEffectType.SLOW.getId(), "Slowness");
|
||||
put(PotionEffectType.FAST_DIGGING.getId(), "Haste");
|
||||
put(PotionEffectType.SLOW_DIGGING.getId(), "Mining Fatigue");
|
||||
put(PotionEffectType.INCREASE_DAMAGE.getId(), "Strength");
|
||||
put(PotionEffectType.WEAKNESS.getId(), "Weakness");
|
||||
put(PotionEffectType.HEAL.getId(), "Instant Health");
|
||||
put(PotionEffectType.HARM.getId(), "Instant Damage");
|
||||
put(PotionEffectType.JUMP.getId(), "Jump Boost");
|
||||
put(PotionEffectType.CONFUSION.getId(), "Nausea");
|
||||
put(PotionEffectType.REGENERATION.getId(), "Regeneration");
|
||||
put(PotionEffectType.DAMAGE_RESISTANCE.getId(), "Resistance");
|
||||
put(PotionEffectType.FIRE_RESISTANCE.getId(), "Fire Resistance");
|
||||
put(PotionEffectType.WATER_BREATHING.getId(), "Water Breathing");
|
||||
put(PotionEffectType.INVISIBILITY.getId(), "Invisibility");
|
||||
put(PotionEffectType.BLINDNESS.getId(), "Blindness");
|
||||
put(PotionEffectType.NIGHT_VISION.getId(), "Night Vision");
|
||||
put(PotionEffectType.HUNGER.getId(), "Hunger");
|
||||
put(PotionEffectType.POISON.getId(), "Poison");
|
||||
put(PotionEffectType.WITHER.getId(), "Wither");
|
||||
put(PotionEffectType.HEALTH_BOOST.getId(), "Health Boost");
|
||||
put(PotionEffectType.ABSORPTION.getId(), "Absorption");
|
||||
put(PotionEffectType.SATURATION.getId(), "Saturation");
|
||||
}
|
||||
};
|
||||
|
||||
public static String getEffectName(PotionEffectType e) {
|
||||
if (e == null) {
|
||||
return "null";
|
||||
}
|
||||
final String n = potionEffectNames.get(e.getId());
|
||||
return n == null ? e.getName() : n;
|
||||
}
|
||||
}
|
||||
|
@ -4,38 +4,43 @@ import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public enum ServerProject {
|
||||
|
||||
UNKNOWN, CRAFTBUKKIT, SPIGOT, PAPER, TACO, GLOWSTONE;
|
||||
private final static ServerProject serverProject = checkProject();
|
||||
|
||||
private static ServerProject checkProject() {
|
||||
String serverPath = Bukkit.getServer().getClass().getName();
|
||||
|
||||
if (serverPath.contains("glowstone")) {
|
||||
return GLOWSTONE;
|
||||
}
|
||||
|
||||
// taco is pretty easy to check. it uses paper stuff, though, so should be checked first
|
||||
try {
|
||||
Class.forName("net.techcable.tacospigot.TacoSpigotConfig");
|
||||
return TACO;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// paper used to be called "paperclip"
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paperclip.Paperclip");
|
||||
return PAPER;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
return PAPER;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// spigot is the fork that pretty much all builds are based on anymore
|
||||
try {
|
||||
Class.forName("org.spigotmc.SpigotConfig");
|
||||
return SPIGOT;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
return serverPath.contains("craftbukkit") ? CRAFTBUKKIT : UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore-Modules</artifactId>
|
||||
<version>2.5.13</version>
|
||||
<version>2.5.14</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -51,9 +51,9 @@ public class SongodaCore {
|
||||
private final static int coreRevision = 9;
|
||||
|
||||
/**
|
||||
* This has been added as of Rev 6
|
||||
* @since coreRevision 6
|
||||
*/
|
||||
private final static String coreVersion = "2.5.13";
|
||||
private final static String coreVersion = "2.5.14";
|
||||
|
||||
/**
|
||||
* This is specific to the website api
|
||||
@ -87,13 +87,14 @@ public class SongodaCore {
|
||||
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
|
||||
if (clazz.getSimpleName().equals("SongodaCore")) {
|
||||
try {
|
||||
// test to see if we're up to date
|
||||
// test to see if we're up-to-date
|
||||
int otherVersion;
|
||||
try {
|
||||
otherVersion = (int) clazz.getMethod("getCoreVersion").invoke(null);
|
||||
} catch (Exception ignore) {
|
||||
otherVersion = -1;
|
||||
}
|
||||
|
||||
if (otherVersion >= getCoreVersion()) {
|
||||
// use the active service
|
||||
// assuming that the other is greater than R6 if we get here ;)
|
||||
@ -104,49 +105,57 @@ public class SongodaCore {
|
||||
INSTANCE.shadingListener = new ShadedEventListener();
|
||||
Bukkit.getPluginManager().registerEvents(INSTANCE.shadingListener, plugin);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
// we are newer than the registered service: steal all of its registrations
|
||||
// grab the old core's registrations
|
||||
List otherPlugins = (List) clazz.getMethod("getPlugins").invoke(null);
|
||||
// destroy the old core
|
||||
Object oldCore = clazz.getMethod("getInstance").invoke(null);
|
||||
Method destruct = clazz.getDeclaredMethod("destroy");
|
||||
destruct.setAccessible(true);
|
||||
destruct.invoke(oldCore);
|
||||
// register ourselves as the SongodaCore service!
|
||||
INSTANCE = new SongodaCore(plugin);
|
||||
INSTANCE.init();
|
||||
INSTANCE.register(plugin, pluginID, icon, coreVersion);
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
|
||||
// we need (JavaPlugin plugin, int pluginID, String icon) for our object
|
||||
if (!otherPlugins.isEmpty()) {
|
||||
Object testSubject = otherPlugins.get(0);
|
||||
Class otherPluginInfo = testSubject.getClass();
|
||||
Method otherPluginInfo_getJavaPlugin = otherPluginInfo.getMethod("getJavaPlugin");
|
||||
Method otherPluginInfo_getSongodaId = otherPluginInfo.getMethod("getSongodaId");
|
||||
Method otherPluginInfo_getCoreIcon = otherPluginInfo.getMethod("getCoreIcon");
|
||||
Method otherPluginInfo_getCoreLibraryVersion = otherVersion >= 6 ? otherPluginInfo.getMethod("getCoreLibraryVersion") : null;
|
||||
for (Object other : otherPlugins) {
|
||||
INSTANCE.register(
|
||||
(JavaPlugin) otherPluginInfo_getJavaPlugin.invoke(other),
|
||||
(int) otherPluginInfo_getSongodaId.invoke(other),
|
||||
(String) otherPluginInfo_getCoreIcon.invoke(other),
|
||||
otherPluginInfo_getCoreLibraryVersion != null ? (String) otherPluginInfo_getCoreLibraryVersion.invoke(other) : "?");
|
||||
}
|
||||
}
|
||||
|
||||
// we are newer than the registered service: steal all of its registrations
|
||||
// grab the old core's registrations
|
||||
List<?> otherPlugins = (List<?>) clazz.getMethod("getPlugins").invoke(null);
|
||||
|
||||
// destroy the old core
|
||||
Object oldCore = clazz.getMethod("getInstance").invoke(null);
|
||||
Method destruct = clazz.getDeclaredMethod("destroy");
|
||||
destruct.setAccessible(true);
|
||||
destruct.invoke(oldCore);
|
||||
|
||||
// register ourselves as the SongodaCore service!
|
||||
INSTANCE = new SongodaCore(plugin);
|
||||
INSTANCE.init();
|
||||
INSTANCE.register(plugin, pluginID, icon, coreVersion);
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
|
||||
|
||||
// we need (JavaPlugin plugin, int pluginID, String icon) for our object
|
||||
if (!otherPlugins.isEmpty()) {
|
||||
Object testSubject = otherPlugins.get(0);
|
||||
Class otherPluginInfo = testSubject.getClass();
|
||||
Method otherPluginInfo_getJavaPlugin = otherPluginInfo.getMethod("getJavaPlugin");
|
||||
Method otherPluginInfo_getSongodaId = otherPluginInfo.getMethod("getSongodaId");
|
||||
Method otherPluginInfo_getCoreIcon = otherPluginInfo.getMethod("getCoreIcon");
|
||||
Method otherPluginInfo_getCoreLibraryVersion = otherVersion >= 6 ? otherPluginInfo.getMethod("getCoreLibraryVersion") : null;
|
||||
|
||||
for (Object other : otherPlugins) {
|
||||
INSTANCE.register(
|
||||
(JavaPlugin) otherPluginInfo_getJavaPlugin.invoke(other),
|
||||
(int) otherPluginInfo_getSongodaId.invoke(other),
|
||||
(String) otherPluginInfo_getCoreIcon.invoke(other),
|
||||
otherPluginInfo_getCoreLibraryVersion != null ? (String) otherPluginInfo_getCoreLibraryVersion.invoke(other) : "?");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
|
||||
plugin.getLogger().log(Level.WARNING, "Error registering core service", ignored);
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
|
||||
plugin.getLogger().log(Level.WARNING, "Error registering core service", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// register ourselves as the SongodaCore service!
|
||||
INSTANCE = new SongodaCore(plugin);
|
||||
INSTANCE.init();
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
|
||||
}
|
||||
|
||||
INSTANCE.register(plugin, pluginID, icon, coreVersion);
|
||||
}
|
||||
|
||||
@ -166,16 +175,17 @@ public class SongodaCore {
|
||||
.addSubCommand(new SongodaCoreDiagCommand());
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
|
||||
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
|
||||
|
||||
// we aggressively want to own this command
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () -> {
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
|
||||
}, 10 * 60 * 1));
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () -> {
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
|
||||
}, 20 * 60 * 1));
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () -> {
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
|
||||
}, 20 * 60 * 2));
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () ->
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager),
|
||||
10 * 60));
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () ->
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager),
|
||||
20 * 60));
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () ->
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager),
|
||||
20 * 60 * 2));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,22 +193,26 @@ public class SongodaCore {
|
||||
*/
|
||||
private void destroy() {
|
||||
Bukkit.getServicesManager().unregister(SongodaCore.class, INSTANCE);
|
||||
|
||||
tasks.stream().filter(Objects::nonNull)
|
||||
.forEach(task -> Bukkit.getScheduler().cancelTask(task.getTaskId()));
|
||||
|
||||
HandlerList.unregisterAll(loginListener);
|
||||
if (!hasShading()) {
|
||||
HandlerList.unregisterAll(shadingListener);
|
||||
}
|
||||
|
||||
registeredPlugins.clear();
|
||||
commandManager = null;
|
||||
loginListener = null;
|
||||
}
|
||||
|
||||
private ArrayList<BukkitTask> tasks = new ArrayList();
|
||||
private ArrayList<BukkitTask> tasks = new ArrayList<>();
|
||||
|
||||
private void register(JavaPlugin plugin, int pluginID, String icon, String libraryVersion) {
|
||||
logger.info(getPrefix() + "Hooked " + plugin.getName() + ".");
|
||||
PluginInfo info = new PluginInfo(plugin, pluginID, icon, libraryVersion);
|
||||
|
||||
// don't forget to check for language pack updates ;)
|
||||
info.addModule(new LocaleModule());
|
||||
registeredPlugins.add(info);
|
||||
@ -238,10 +252,10 @@ public class SongodaCore {
|
||||
for (PluginInfoModule module : plugin.getModules()) {
|
||||
module.run(plugin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
final String er = e.getMessage();
|
||||
} catch (IOException ex) {
|
||||
final String er = ex.getMessage();
|
||||
logger.log(Level.FINE, "Connection with Songoda servers failed: " + (er.contains("URL") ? er.substring(0, er.indexOf("URL") + 3) : er));
|
||||
} catch (ParseException e) {
|
||||
} catch (ParseException ex) {
|
||||
logger.log(Level.FINE, "Failed to parse json for " + plugin.getJavaPlugin().getName() + " update check");
|
||||
}
|
||||
}
|
||||
@ -283,13 +297,19 @@ public class SongodaCore {
|
||||
}
|
||||
|
||||
private static class ShadedEventListener implements Listener {
|
||||
boolean via = false;
|
||||
boolean via;
|
||||
boolean proto = false;
|
||||
|
||||
ShadedEventListener() {
|
||||
if ((via = Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))) {
|
||||
via = Bukkit.getPluginManager().isPluginEnabled("ViaVersion");
|
||||
|
||||
if (via) {
|
||||
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginVia(p, getHijackedPlugin()));
|
||||
} else if ((proto = Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
proto = Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
|
||||
if (proto) {
|
||||
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginProtocol(p, getHijackedPlugin()));
|
||||
}
|
||||
}
|
||||
@ -298,7 +318,10 @@ public class SongodaCore {
|
||||
void onLogin(PlayerLoginEvent event) {
|
||||
if (via) {
|
||||
ClientVersion.onLoginVia(event.getPlayer(), getHijackedPlugin());
|
||||
} else if (proto) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (proto) {
|
||||
ClientVersion.onLoginProtocol(event.getPlayer(), getHijackedPlugin());
|
||||
}
|
||||
}
|
||||
@ -322,18 +345,25 @@ public class SongodaCore {
|
||||
}
|
||||
|
||||
private class EventListener implements Listener {
|
||||
final HashMap<UUID, Long> lastCheck = new HashMap();
|
||||
final HashMap<UUID, Long> lastCheck = new HashMap<>();
|
||||
|
||||
@EventHandler
|
||||
void onLogin(PlayerLoginEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
// don't spam players with update checks
|
||||
long now = System.currentTimeMillis();
|
||||
Long last = lastCheck.get(player.getUniqueId());
|
||||
if (last != null && now - 10000 < last) return;
|
||||
|
||||
if (last != null && now - 10000 < last) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastCheck.put(player.getUniqueId(), now);
|
||||
|
||||
// is this player good to revieve update notices?
|
||||
if (!event.getPlayer().isOp() && !player.hasPermission("songoda.updatecheck")) return;
|
||||
|
||||
// check for updates! ;)
|
||||
for (PluginInfo plugin : getPlugins()) {
|
||||
if (plugin.getNotification() != null && plugin.getJavaPlugin().isEnabled())
|
||||
@ -346,16 +376,20 @@ public class SongodaCore {
|
||||
void onDisable(PluginDisableEvent event) {
|
||||
// don't track disabled plugins
|
||||
PluginInfo pi = registeredPlugins.stream().filter(p -> event.getPlugin() == p.getJavaPlugin()).findFirst().orElse(null);
|
||||
|
||||
if (pi != null) {
|
||||
registeredPlugins.remove(pi);
|
||||
}
|
||||
|
||||
if (event.getPlugin() == piggybackedPlugin) {
|
||||
// uh-oh! Abandon ship!!
|
||||
Bukkit.getServicesManager().unregisterAll(piggybackedPlugin);
|
||||
|
||||
// can we move somewhere else?
|
||||
if ((pi = registeredPlugins.stream().findFirst().orElse(null)) != null) {
|
||||
// move ourselves to this plugin
|
||||
piggybackedPlugin = pi.getJavaPlugin();
|
||||
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, piggybackedPlugin, ServicePriority.Normal);
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
|
||||
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
|
||||
|
@ -17,8 +17,6 @@ import java.util.logging.Level;
|
||||
/**
|
||||
* REMINDER: When converting plugins to use this, REMOVE METRICS <br>
|
||||
* Must not have two instances of Metrics enabled!
|
||||
*
|
||||
* @author jascotty2
|
||||
*/
|
||||
public abstract class SongodaPlugin extends JavaPlugin {
|
||||
protected Locale locale;
|
||||
@ -72,13 +70,8 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
public final void onLoad() {
|
||||
try {
|
||||
onPluginLoad();
|
||||
} catch (Throwable t) {
|
||||
Bukkit.getLogger().log(Level.SEVERE,
|
||||
"Unexpected error while loading " + getDescription().getName()
|
||||
+ " v" + getDescription().getVersion()
|
||||
+ " c" + SongodaCore.getCoreLibraryVersion()
|
||||
+ ": Disabling plugin!", t);
|
||||
emergencyStop = true;
|
||||
} catch (Throwable th) {
|
||||
criticalErrorOnPluginStartup(th);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,38 +79,40 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
public final void onEnable() {
|
||||
if (emergencyStop) {
|
||||
setEnabled(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
console.sendMessage(" "); // blank line to separate chatter
|
||||
console.sendMessage(ChatColor.GREEN + "=============================");
|
||||
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
|
||||
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
|
||||
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
|
||||
ChatColor.GREEN.toString(), "Enabling", ChatColor.GRAY.toString()));
|
||||
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY,
|
||||
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE));
|
||||
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY,
|
||||
ChatColor.GREEN, "Enabling", ChatColor.GRAY));
|
||||
|
||||
try {
|
||||
locale = Locale.loadDefaultLocale(this, "en_US");
|
||||
|
||||
// plugin setup
|
||||
onPluginEnable();
|
||||
|
||||
// Load Data.
|
||||
Bukkit.getScheduler().runTaskLater(this, this::onDataLoad, dataLoadDelay);
|
||||
|
||||
if (emergencyStop) {
|
||||
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
console.sendMessage(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start Metrics
|
||||
Metrics.start(this);
|
||||
} catch (Throwable t) {
|
||||
Bukkit.getLogger().log(Level.SEVERE,
|
||||
"Unexpected error while loading " + getDescription().getName()
|
||||
+ " v" + getDescription().getVersion()
|
||||
+ " c" + SongodaCore.getCoreLibraryVersion()
|
||||
+ ": Disabling plugin!", t);
|
||||
emergencyStop();
|
||||
} catch (Throwable th) {
|
||||
criticalErrorOnPluginStartup(th);
|
||||
|
||||
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
console.sendMessage(" ");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -125,25 +120,23 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
console.sendMessage(" "); // blank line to separate chatter
|
||||
}
|
||||
|
||||
protected void emergencyStop() {
|
||||
emergencyStop = true;
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onDisable() {
|
||||
if (emergencyStop) {
|
||||
return;
|
||||
}
|
||||
console.sendMessage(" "); // blank line to speparate chatter
|
||||
|
||||
console.sendMessage(" "); // blank line to separate chatter
|
||||
console.sendMessage(ChatColor.GREEN + "=============================");
|
||||
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
|
||||
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
|
||||
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
|
||||
ChatColor.RED.toString(), "Disabling", ChatColor.GRAY.toString()));
|
||||
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY,
|
||||
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE));
|
||||
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY,
|
||||
ChatColor.RED, "Disabling", ChatColor.GRAY));
|
||||
|
||||
onPluginDisable();
|
||||
|
||||
console.sendMessage(ChatColor.GREEN + "=============================");
|
||||
console.sendMessage(" "); // blank line to speparate chatter
|
||||
console.sendMessage(" "); // blank line to separate chatter
|
||||
}
|
||||
|
||||
public ConsoleCommandSender getConsole() {
|
||||
@ -166,15 +159,15 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
public boolean setLocale(String localeName, boolean reload) {
|
||||
if (locale != null && locale.getName().equals(localeName)) {
|
||||
return !reload || locale.reloadMessages();
|
||||
} else {
|
||||
Locale l = Locale.loadLocale(this, localeName);
|
||||
if (l != null) {
|
||||
locale = l;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Locale l = Locale.loadLocale(this, localeName);
|
||||
if (l != null) {
|
||||
locale = l;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void shutdownDataManager(DataManagerAbstract dataManager) {
|
||||
@ -213,4 +206,27 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void emergencyStop() {
|
||||
emergencyStop = true;
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs one or multiple errors that occurred during plugin startup and calls {@link #emergencyStop()} afterwards
|
||||
*
|
||||
* @param th The error(s) that occurred
|
||||
*/
|
||||
protected void criticalErrorOnPluginStartup(Throwable... th) {
|
||||
Bukkit.getLogger().log(Level.SEVERE,
|
||||
String.format(
|
||||
"Unexpected error while loading %s v%s c%s: Disabling plugin!",
|
||||
getDescription().getName(),
|
||||
getDescription().getVersion(),
|
||||
SongodaCore.getCoreLibraryVersion()
|
||||
), th);
|
||||
|
||||
emergencyStop();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ChatMessage {
|
||||
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
private final List<JsonObject> textList = new ArrayList<>();
|
||||
|
||||
@ -36,7 +35,8 @@ public class ChatMessage {
|
||||
}
|
||||
|
||||
public ChatMessage fromText(String text, boolean noHex) {
|
||||
Pattern pattern = Pattern.compile("(.*?)(?!&([omnlk]))(?=(&([123456789abcdefr#])|$)|#([a-f]|[A-F]|[0-9]){6})",
|
||||
Pattern pattern = Pattern.compile(
|
||||
"(.*?)(?!&([omnlk]))(?=(&([123456789abcdefr#])|$)|#([a-f]|[A-F]|[0-9]){6})",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(text);
|
||||
|
||||
@ -44,12 +44,15 @@ public class ChatMessage {
|
||||
ColorContainer color = null;
|
||||
String match1 = matcher.group(1);
|
||||
|
||||
if (matcher.groupCount() == 0 || match1.length() == 0) continue;
|
||||
if (matcher.groupCount() == 0 || match1.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char colorChar = '-';
|
||||
|
||||
if (matcher.start() != 0)
|
||||
if (matcher.start() != 0) {
|
||||
colorChar = text.substring(matcher.start() - 1, matcher.start()).charAt(0);
|
||||
}
|
||||
|
||||
if (colorChar != '-') {
|
||||
if (colorChar == '#') {
|
||||
@ -70,15 +73,17 @@ public class ChatMessage {
|
||||
|
||||
ColorCode code = ColorCode.getByChar(Character.toLowerCase(match2.charAt(0)));
|
||||
|
||||
if (code != null && code != ColorCode.RESET)
|
||||
if (code != null && code != ColorCode.RESET) {
|
||||
stackedCodes.add(code);
|
||||
}
|
||||
|
||||
if (color != null)
|
||||
if (color != null) {
|
||||
match2 = match2.substring(1);
|
||||
}
|
||||
|
||||
if (match2.length() == 0) continue;
|
||||
|
||||
addMessage(match2, color, stackedCodes);
|
||||
if (match2.length() != 0) {
|
||||
addMessage(match2, color, stackedCodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,31 +96,40 @@ public class ChatMessage {
|
||||
|
||||
public String toText(boolean noHex) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
|
||||
for (JsonObject object : textList) {
|
||||
if (object.has("color")) {
|
||||
String color = object.get("color").getAsString();
|
||||
text.append("&");
|
||||
|
||||
if (color.length() == 7) {
|
||||
text.append(new ColorContainer(color, noHex).getColor().getCode());
|
||||
} else {
|
||||
text.append(ColorCode.valueOf(color.toUpperCase()).getCode());
|
||||
}
|
||||
}
|
||||
|
||||
for (ColorCode code : ColorCode.values()) {
|
||||
if (code.isColor()) continue;
|
||||
|
||||
String c = code.name().toLowerCase();
|
||||
if (object.has(c) && object.get(c).getAsBoolean())
|
||||
if (object.has(c) && object.get(c).getAsBoolean()) {
|
||||
text.append("&").append(code.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
text.append(object.get("text").getAsString());
|
||||
}
|
||||
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
public ChatMessage addMessage(String s) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", s);
|
||||
|
||||
textList.add(txt);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -127,11 +141,14 @@ public class ChatMessage {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
if (color != null)
|
||||
if (color != null) {
|
||||
txt.addProperty("color", color.getHexCode() != null ? "#" + color.getHexCode() : color.getColorCode().name().toLowerCase());
|
||||
}
|
||||
|
||||
for (ColorCode code : ColorCode.values()) {
|
||||
if (!code.isColor())
|
||||
if (!code.isColor()) {
|
||||
txt.addProperty(code.name().toLowerCase(), colorCodes.contains(code));
|
||||
}
|
||||
}
|
||||
|
||||
textList.add(txt);
|
||||
@ -141,14 +158,17 @@ public class ChatMessage {
|
||||
public ChatMessage addRunCommand(String text, String hoverText, String cmd) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
JsonObject hover = new JsonObject();
|
||||
hover.addProperty("action", "show_text");
|
||||
hover.addProperty("value", hoverText);
|
||||
txt.add("hoverEvent", hover);
|
||||
|
||||
JsonObject click = new JsonObject();
|
||||
click.addProperty("action", "run_command");
|
||||
click.addProperty("value", cmd);
|
||||
txt.add("clickEvent", click);
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
}
|
||||
@ -156,14 +176,17 @@ public class ChatMessage {
|
||||
public ChatMessage addPromptCommand(String text, String hoverText, String cmd) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
JsonObject hover = new JsonObject();
|
||||
hover.addProperty("action", "show_text");
|
||||
hover.addProperty("value", hoverText);
|
||||
txt.add("hoverEvent", hover);
|
||||
|
||||
JsonObject click = new JsonObject();
|
||||
click.addProperty("action", "suggest_command");
|
||||
click.addProperty("value", cmd);
|
||||
txt.add("clickEvent", click);
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
}
|
||||
@ -171,14 +194,17 @@ public class ChatMessage {
|
||||
public ChatMessage addURL(String text, String hoverText, String url) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
JsonObject hover = new JsonObject();
|
||||
hover.addProperty("action", "show_text");
|
||||
hover.addProperty("value", hoverText);
|
||||
txt.add("hoverEvent", hover);
|
||||
|
||||
JsonObject click = new JsonObject();
|
||||
click.addProperty("action", "open_url");
|
||||
click.addProperty("value", url);
|
||||
txt.add("clickEvent", hover);
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
}
|
||||
@ -200,10 +226,14 @@ public class ChatMessage {
|
||||
|
||||
Object packet;
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)) {
|
||||
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)), mc_chatMessageType_Chat.get(null), ((Player) sender).getUniqueId());
|
||||
packet = mc_PacketPlayOutChat_new.newInstance(
|
||||
mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)),
|
||||
mc_chatMessageType_Chat.get(null),
|
||||
((Player) sender).getUniqueId());
|
||||
} else {
|
||||
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)));
|
||||
}
|
||||
|
||||
Object cbPlayer = cb_craftPlayer_getHandle.invoke(sender);
|
||||
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
|
||||
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
|
||||
@ -211,9 +241,11 @@ public class ChatMessage {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
|
||||
enabled = false;
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(TextUtils.formatText((prefix == null ? "" : prefix.toText(true) + " ") + toText(true)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(TextUtils.formatText((prefix == null ? "" : prefix.toText(true) + " ") + toText(true)));
|
||||
}
|
||||
|
||||
private static boolean enabled = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_8);
|
||||
@ -230,7 +262,6 @@ public class ChatMessage {
|
||||
static void init() {
|
||||
if (enabled) {
|
||||
try {
|
||||
|
||||
final String version = ServerVersion.getServerVersionString();
|
||||
Class<?> cb_craftPlayerClazz, mc_entityPlayerClazz, mc_playerConnectionClazz, mc_PacketInterface,
|
||||
mc_IChatBaseComponent, mc_IChatBaseComponent_ChatSerializer, mc_PacketPlayOutChat;
|
||||
@ -263,11 +294,12 @@ public class ChatMessage {
|
||||
|
||||
public ChatMessage replaceAll(String toReplace, String replaceWith) {
|
||||
for (JsonObject object : textList) {
|
||||
String text = object.get("text").getAsString()
|
||||
.replaceAll(toReplace, replaceWith);
|
||||
String text = object.get("text").getAsString().replaceAll(toReplace, replaceWith);
|
||||
|
||||
object.remove("text");
|
||||
object.addProperty("text", text);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum ColorCode {
|
||||
|
||||
BLACK('0', ChatColor.BLACK, true),
|
||||
DARK_BLUE('1', ChatColor.DARK_BLUE, true),
|
||||
DARK_GREEN('2', ChatColor.DARK_GREEN, true),
|
||||
@ -43,11 +42,7 @@ public enum ColorCode {
|
||||
}
|
||||
|
||||
static {
|
||||
ColorCode[] var0 = values();
|
||||
int l = var0.length;
|
||||
|
||||
for (int i = 0; i < l; ++i) {
|
||||
ColorCode color = var0[i];
|
||||
for (ColorCode color : values()) {
|
||||
BY_CHAR.put(color.code, color);
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ package com.songoda.core.chat;
|
||||
import com.songoda.core.compatibility.ServerVersion;
|
||||
import com.songoda.core.utils.ColorUtils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.*;
|
||||
|
||||
public class ColorContainer {
|
||||
|
||||
private ColorCode colorCode;
|
||||
private String hexCode;
|
||||
|
||||
@ -17,6 +16,7 @@ public class ColorContainer {
|
||||
|
||||
public ColorContainer(String hexCode, boolean noHex) {
|
||||
this.hexCode = hexCode;
|
||||
|
||||
if (noHex || ServerVersion.isServerVersionBelow(ServerVersion.V1_16)) {
|
||||
this.colorCode = getColor();
|
||||
this.hexCode = null;
|
||||
@ -32,12 +32,19 @@ public class ColorContainer {
|
||||
}
|
||||
|
||||
public ColorCode getColor() {
|
||||
if (colorCode != null) return colorCode;
|
||||
if (hexCode == null) return null;
|
||||
if (colorCode != null) {
|
||||
return colorCode;
|
||||
}
|
||||
|
||||
if (hexCode == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
java.awt.Color jColor = new Color(
|
||||
Integer.valueOf(hexCode.substring(0, 2), 16),
|
||||
Integer.valueOf(hexCode.substring(2, 4), 16),
|
||||
Integer.valueOf(hexCode.substring(4, 6), 16));
|
||||
|
||||
return ColorUtils.fromRGB(jColor.getRed(), jColor.getGreen(), jColor.getBlue());
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractCommand {
|
||||
|
||||
private final CommandType _cmdType;
|
||||
private final boolean _hasArgs;
|
||||
private final List<String> _handledCommands = new ArrayList<>();
|
||||
@ -65,8 +64,8 @@ public abstract class AbstractCommand {
|
||||
return _cmdType == CommandType.PLAYER_ONLY;
|
||||
}
|
||||
|
||||
public static enum ReturnType {SUCCESS, NEEDS_PLAYER, FAILURE, SYNTAX_ERROR}
|
||||
public enum ReturnType {SUCCESS, NEEDS_PLAYER, FAILURE, SYNTAX_ERROR}
|
||||
|
||||
public static enum CommandType {PLAYER_ONLY, CONSOLE_OK}
|
||||
public enum CommandType {PLAYER_ONLY, CONSOLE_OK}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
private final HashMap<String, SimpleNestedCommand> commands = new HashMap<>();
|
||||
@ -68,19 +67,27 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
public List<String> getSubCommands(String command) {
|
||||
SimpleNestedCommand nested = command == null ? null : commands.get(command.toLowerCase());
|
||||
return nested == null ? Collections.emptyList() : new ArrayList<>(nested.children.keySet());
|
||||
|
||||
if (nested == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return new ArrayList<>(nested.children.keySet());
|
||||
}
|
||||
|
||||
public Set<AbstractCommand> getAllCommands() {
|
||||
HashSet<AbstractCommand> all = new HashSet<>();
|
||||
|
||||
commands.values().stream()
|
||||
.filter(c -> c.parent != null && !all.contains(c.parent))
|
||||
.forEach(c -> {
|
||||
all.add(c.parent);
|
||||
|
||||
c.children.values().stream()
|
||||
.filter(s -> !all.contains(s))
|
||||
.forEach(s -> all.add(s));
|
||||
.forEach(all::add);
|
||||
});
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
@ -91,10 +98,12 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
public SimpleNestedCommand registerCommandDynamically(AbstractCommand abstractCommand) {
|
||||
SimpleNestedCommand nested = new SimpleNestedCommand(abstractCommand);
|
||||
|
||||
abstractCommand.getCommands().forEach(cmd -> {
|
||||
CommandManager.registerCommandDynamically(plugin, cmd, this, this);
|
||||
commands.put(cmd.toLowerCase(), nested);
|
||||
PluginCommand pcmd = plugin.getCommand(cmd);
|
||||
|
||||
if (pcmd != null) {
|
||||
pcmd.setExecutor(this);
|
||||
pcmd.setTabCompleter(this);
|
||||
@ -102,21 +111,26 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
plugin.getLogger().warning("Failed to register command: /" + cmd);
|
||||
}
|
||||
});
|
||||
|
||||
return nested;
|
||||
}
|
||||
|
||||
public SimpleNestedCommand addCommand(AbstractCommand abstractCommand) {
|
||||
SimpleNestedCommand nested = new SimpleNestedCommand(abstractCommand);
|
||||
|
||||
abstractCommand.getCommands().forEach(cmd -> {
|
||||
commands.put(cmd.toLowerCase(), nested);
|
||||
PluginCommand pcmd = plugin.getCommand(cmd);
|
||||
if (pcmd != null) {
|
||||
pcmd.setExecutor(this);
|
||||
pcmd.setTabCompleter(this);
|
||||
} else {
|
||||
|
||||
if (pcmd == null) {
|
||||
plugin.getLogger().warning("Failed to register command: /" + cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
pcmd.setExecutor(this);
|
||||
pcmd.setTabCompleter(this);
|
||||
});
|
||||
|
||||
return nested;
|
||||
}
|
||||
|
||||
@ -137,9 +151,11 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
public MainCommand getMainCommand(String command) {
|
||||
SimpleNestedCommand nested = command == null ? null : commands.get(command.toLowerCase());
|
||||
|
||||
if (nested != null && nested.parent instanceof MainCommand) {
|
||||
return (MainCommand) nested.parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -147,16 +163,19 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
for (AbstractCommand abstractCommand : abstractCommands) {
|
||||
addCommand(abstractCommand);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandManager setExecutor(String command) {
|
||||
PluginCommand pcmd = command == null ? null : plugin.getCommand(command);
|
||||
|
||||
if (pcmd != null) {
|
||||
pcmd.setExecutor(this);
|
||||
} else {
|
||||
plugin.getLogger().warning("Failed to register command: /" + command);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -169,28 +188,34 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) {
|
||||
// grab the specific command that's being called
|
||||
SimpleNestedCommand nested = commands.get(command.getName().toLowerCase());
|
||||
|
||||
if (nested != null) {
|
||||
// check to see if we're trying to call a sub-command
|
||||
if (args.length != 0 && !nested.children.isEmpty()) {
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
|
||||
if (subCmd != null) {
|
||||
// we have a subcommand to use!
|
||||
AbstractCommand sub = nested.children.get(subCmd);
|
||||
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
|
||||
// now process the command
|
||||
processRequirements(sub, commandSender, newArgs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if we've gotten this far, then just use the command we have
|
||||
if (nested.parent != null) {
|
||||
processRequirements(nested.parent, commandSender, args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
commandSender.sendMessage(msg_noCommand);
|
||||
return true;
|
||||
}
|
||||
@ -227,6 +252,7 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
@ -235,17 +261,24 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
sender.sendMessage(msg_noConsole);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
|
||||
AbstractCommand.ReturnType returnType = command.runCommand(sender, args);
|
||||
|
||||
if (returnType == AbstractCommand.ReturnType.NEEDS_PLAYER) {
|
||||
sender.sendMessage(msg_noConsole);
|
||||
} else if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
|
||||
for (String s : msg_syntaxError) {
|
||||
sender.sendMessage(s.replace("%syntax%", command.getSyntax()));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(msg_noPerms);
|
||||
}
|
||||
|
||||
@ -253,10 +286,12 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
// grab the specific command that's being called
|
||||
SimpleNestedCommand nested = commands.get(command.getName().toLowerCase());
|
||||
|
||||
if (nested != null) {
|
||||
if (args.length == 0 || nested.children.isEmpty()) {
|
||||
return nested.parent != null ? nested.parent.onTab(sender, args) : null;
|
||||
}
|
||||
|
||||
// check for each sub-command that they have access to
|
||||
final boolean op = sender.isOp();
|
||||
final boolean console = !(sender instanceof Player);
|
||||
@ -267,44 +302,49 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
.filter(e -> !console || !e.getValue().isNoConsole())
|
||||
.filter(e -> e.getKey().startsWith(arg))
|
||||
.filter(e -> op || e.getValue().getPermissionNode() == null || sender.hasPermission(e.getValue().getPermissionNode()))
|
||||
.map(e -> e.getKey())
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
// more than one arg, let's check to see if we have a command here
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
AbstractCommand sub;
|
||||
if (subCmd != null && (sub = nested.children.get(subCmd)) != null
|
||||
&& (!console || !sub.isNoConsole())
|
||||
&& (op || sub.getPermissionNode() == null || sender.hasPermission(sub.getPermissionNode()))) {
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
// we're good to go!
|
||||
return fetchList(sub, newArgs, sender);
|
||||
}
|
||||
}
|
||||
|
||||
// more than one arg, let's check to see if we have a command here
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
AbstractCommand sub;
|
||||
if (subCmd != null &&
|
||||
(sub = nested.children.get(subCmd)) != null &&
|
||||
(!console || !sub.isNoConsole()) &&
|
||||
(op || sub.getPermissionNode() == null || sender.hasPermission(sub.getPermissionNode()))) {
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
|
||||
// we're good to go!
|
||||
return fetchList(sub, newArgs, sender);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private List<String> fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) {
|
||||
List<String> list = abstractCommand.onTab(sender, args);
|
||||
|
||||
if (args.length != 0) {
|
||||
String str = args[args.length - 1];
|
||||
|
||||
if (list != null && str != null && str.length() >= 1) {
|
||||
try {
|
||||
list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase()));
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
} catch (UnsupportedOperationException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void registerCommandDynamically(Plugin plugin, String command, CommandExecutor executor, TabCompleter tabManager) {
|
||||
try {
|
||||
|
||||
// Retrieve the SimpleCommandMap from the server
|
||||
Class<?> clazzCraftServer = Bukkit.getServer().getClass();
|
||||
Object craftServer = clazzCraftServer.cast(Bukkit.getServer());
|
||||
@ -337,8 +377,8 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
fieldKnownCommands.setAccessible(true);
|
||||
Map<String, Command> knownCommands = (Map<String, Command>) fieldKnownCommands.get(commandMap);
|
||||
knownCommands.put(command, commandObject);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MainCommand extends AbstractCommand {
|
||||
|
||||
String header = null;
|
||||
String description;
|
||||
boolean sortHelp = false;
|
||||
@ -22,6 +21,7 @@ public class MainCommand extends AbstractCommand {
|
||||
|
||||
public MainCommand(Plugin plugin, String command) {
|
||||
super(CommandType.CONSOLE_OK, command);
|
||||
|
||||
this.command = command;
|
||||
this.plugin = plugin;
|
||||
this.description = "Shows the command help page for /" + command;
|
||||
@ -56,6 +56,7 @@ public class MainCommand extends AbstractCommand {
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
sender.sendMessage("");
|
||||
|
||||
if (header != null) {
|
||||
sender.sendMessage(header);
|
||||
} else {
|
||||
@ -63,17 +64,21 @@ public class MainCommand extends AbstractCommand {
|
||||
plugin.getDescription().getName(), plugin.getDescription().getVersion()), sender instanceof ConsoleCommandSender)
|
||||
.sendTo(sender);
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + "/songoda" + ChatColor.GRAY + " - Opens the Songoda plugin GUI");
|
||||
sender.sendMessage("");
|
||||
|
||||
if (nestedCommands != null) {
|
||||
List<String> commands = nestedCommands.children.values().stream().distinct().map(c -> c.getCommands().get(0)).collect(Collectors.toList());
|
||||
|
||||
if (sortHelp) {
|
||||
Collections.sort(commands);
|
||||
}
|
||||
|
||||
boolean isPlayer = sender instanceof Player;
|
||||
// todo? pagation if commands.size is too large? (player-only)
|
||||
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + getSyntax() + ChatColor.GRAY + " - " + getDescription());
|
||||
|
||||
for (String cmdStr : commands) {
|
||||
final AbstractCommand cmd = nestedCommands.children.get(cmdStr);
|
||||
if (cmd == null) continue;
|
||||
@ -85,7 +90,7 @@ public class MainCommand extends AbstractCommand {
|
||||
chatMessage.addMessage(ChatColor.DARK_GRAY + "- ")
|
||||
.addPromptCommand(ChatColor.YELLOW + c + cmd.getSyntax(), ChatColor.YELLOW + c + cmdStr, c + cmdStr)
|
||||
.addMessage(ChatColor.GRAY + " - " + cmd.getDescription());
|
||||
chatMessage.sendTo((Player) sender);
|
||||
chatMessage.sendTo(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SelectorArguments {
|
||||
|
||||
static Pattern selectorPattern = Pattern.compile("^(@[apers])(\\[(.*?)\\])?$");
|
||||
static Pattern selectorPattern = Pattern.compile("^(@[apers])(\\[(.*?)])?$");
|
||||
static Pattern selectorRangePattern = Pattern.compile("^([0-9]{1,9}(\\.[0-9]{1,9})?)?(\\.\\.)?([0-9]{1,9}(\\.[0-9]{1,9})?)?$");
|
||||
|
||||
/**
|
||||
@ -38,14 +37,17 @@ public class SelectorArguments {
|
||||
if (!(sender instanceof BlockCommandSender || sender instanceof Player)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Matcher m = selectorPattern.matcher(argument);
|
||||
if (!m.find()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SelectorType type = SelectorType.getType(m.group(1));
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SelectorArguments selector = new SelectorArguments(sender, type);
|
||||
|
||||
if (m.group(3) != null) {
|
||||
@ -67,9 +69,11 @@ public class SelectorArguments {
|
||||
|
||||
private void parseArguments(String selectorArgs) {
|
||||
String[] args = selectorArgs.split(",");
|
||||
|
||||
for (String s : args) {
|
||||
if (s.contains("=")) {
|
||||
String[] v = s.split("=");
|
||||
|
||||
if (v[0].equals("distance")) {
|
||||
// 10 = d == 10
|
||||
// 10..12 = d > 10 && d <= 12
|
||||
@ -80,6 +84,7 @@ public class SelectorArguments {
|
||||
if (distGroup.group(1) != null) {
|
||||
rangeMin = Double.parseDouble(distGroup.group(1));
|
||||
}
|
||||
|
||||
if (distGroup.group(3) == null) {
|
||||
rangeMax = rangeMin;
|
||||
} else if (distGroup.group(4) != null) {
|
||||
@ -89,9 +94,11 @@ public class SelectorArguments {
|
||||
} else if (v[0].equals("type")) {
|
||||
entityType = EntityNamespace.minecraftToBukkit(v[1]);
|
||||
}
|
||||
|
||||
// more arguments can be parsed here (TODO)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
advancements Advancement earned by entity.
|
||||
distance Distance to entity.
|
||||
@ -121,16 +128,21 @@ public class SelectorArguments {
|
||||
public Collection<Entity> getSelection() {
|
||||
final Location location = sender instanceof Player ? ((Player) sender).getLocation() : ((BlockCommandSender) sender).getBlock().getLocation();
|
||||
Collection<Entity> list = preSelect(location);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return list;
|
||||
}
|
||||
|
||||
List<Entity> list2 = filter(location, list);
|
||||
|
||||
if (list2.isEmpty()) {
|
||||
return list2;
|
||||
}
|
||||
|
||||
switch (selector) {
|
||||
case PLAYER:
|
||||
Collections.sort(list2, (o1, o2) -> (int) (o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location)));
|
||||
list2.sort((o1, o2) -> (int) (o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location)));
|
||||
|
||||
return Arrays.asList(list2.get(0));
|
||||
case RANDOM_PLAYER:
|
||||
Collections.shuffle(list2);
|
||||
@ -140,6 +152,7 @@ public class SelectorArguments {
|
||||
case SELF:
|
||||
return list2;
|
||||
}
|
||||
|
||||
return list2;
|
||||
}
|
||||
|
||||
@ -151,28 +164,32 @@ public class SelectorArguments {
|
||||
return rangeMax == Double.POSITIVE_INFINITY
|
||||
? location.getWorld().getEntitiesByClasses(Player.class)
|
||||
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2).stream()
|
||||
.filter(e -> e instanceof Player).collect(Collectors.toSet());
|
||||
.filter(Player.class::isInstance).collect(Collectors.toSet());
|
||||
|
||||
case ALL_ENTITIES:
|
||||
return rangeMax == Double.POSITIVE_INFINITY
|
||||
? location.getWorld().getEntities()
|
||||
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2);
|
||||
|
||||
case SELF:
|
||||
return sender instanceof Entity ? Arrays.asList((Entity) sender) : Collections.EMPTY_LIST;
|
||||
return sender instanceof Entity ? Arrays.asList((Entity) sender) : Collections.emptyList();
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected List<Entity> filter(Location location, Collection<Entity> list) {
|
||||
Stream<Entity> stream = list.stream()
|
||||
.filter(p -> rangeMin == 0 || p.getLocation().distance(location) > rangeMin)
|
||||
.filter(e -> entityType == null || e.getType() == entityType);
|
||||
|
||||
return stream.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static enum SelectorType {
|
||||
|
||||
public enum SelectorType {
|
||||
PLAYER, RANDOM_PLAYER, ALL_PLAYER, ALL_ENTITIES, SELF;
|
||||
|
||||
// TODO: Store selector string in enum
|
||||
public static SelectorType getType(String str) {
|
||||
if (str != null) {
|
||||
switch (str.toLowerCase()) {
|
||||
@ -186,8 +203,11 @@ public class SelectorArguments {
|
||||
return ALL_ENTITIES;
|
||||
case "@s":
|
||||
return SELF;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SimpleNestedCommand {
|
||||
|
||||
final AbstractCommand parent;
|
||||
final LinkedHashMap<String, AbstractCommand> children = new LinkedHashMap<>();
|
||||
|
||||
|
@ -1,108 +1,114 @@
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import com.songoda.core.configuration.ConfigFormattingRules.CommentStyle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A comment for a configuration key
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-28
|
||||
*/
|
||||
public class Comment {
|
||||
|
||||
final List<String> lines = new ArrayList();
|
||||
CommentStyle commentStyle = null;
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Comment(String... lines) {
|
||||
this(null, Arrays.asList(lines));
|
||||
}
|
||||
|
||||
public Comment(List<String> lines) {
|
||||
this(null, lines);
|
||||
}
|
||||
|
||||
public Comment(CommentStyle commentStyle, String... lines) {
|
||||
this(commentStyle, Arrays.asList(lines));
|
||||
}
|
||||
|
||||
public Comment(CommentStyle commentStyle, List<String> lines) {
|
||||
this.commentStyle = commentStyle;
|
||||
if (lines != null) {
|
||||
lines.forEach(s -> this.lines.addAll(Arrays.asList(s.split("\n"))));
|
||||
}
|
||||
}
|
||||
|
||||
public CommentStyle getCommentStyle() {
|
||||
return commentStyle;
|
||||
}
|
||||
|
||||
public void setCommentStyle(CommentStyle commentStyle) {
|
||||
this.commentStyle = commentStyle;
|
||||
}
|
||||
|
||||
public List<String> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return lines.isEmpty() ? "" : lines.stream().collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
public static Comment loadComment(List<String> lines) {
|
||||
CommentStyle style = ConfigFormattingRules.parseStyle(lines);
|
||||
int linePad = (style.drawBorder ? 1 : 0) + (style.drawSpace ? 1 : 0);
|
||||
int prefix = style.commentPrefix.length();
|
||||
int suffix = style.commentSuffix.length();
|
||||
return new Comment(style, lines.subList(linePad, lines.size() - linePad).stream().map(s -> s.substring(prefix, s.length() - suffix).trim()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public void writeComment(Writer output, int offset, CommentStyle defaultStyle) throws IOException {
|
||||
CommentStyle style = commentStyle != null ? commentStyle : defaultStyle;
|
||||
int minSpacing = 0, borderSpacing = 0;
|
||||
// first draw the top of the comment
|
||||
if (style.drawBorder) {
|
||||
// grab the longest line in the list of lines
|
||||
minSpacing = lines.stream().max((s1, s2) -> s1.length() - s2.length()).get().length();
|
||||
borderSpacing = minSpacing + style.commentPrefix.length() + style.commentSuffix.length();
|
||||
// draw the first line
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + (new String(new char[borderSpacing + 2])).replace('\0', '#') + "\n");
|
||||
if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ')
|
||||
+ "#" + style.spacePrefixTop
|
||||
+ (new String(new char[borderSpacing - style.spacePrefixTop.length() - style.spaceSuffixTop.length()])).replace('\0', style.spaceCharTop)
|
||||
+ style.spaceSuffixTop + "#\n");
|
||||
}
|
||||
} else if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#\n");
|
||||
}
|
||||
// then the actual comment lines
|
||||
for (String line : lines) {
|
||||
// todo? should we auto-wrap comment lines that are longer than 80 characters?
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#" + style.commentPrefix
|
||||
+ (minSpacing == 0 ? line : line + (new String(new char[minSpacing - line.length()])).replace('\0', ' ')) + style.commentSuffix + (style.drawBorder ? "#\n" : "\n"));
|
||||
}
|
||||
// now draw the bottom of the comment border
|
||||
if (style.drawBorder) {
|
||||
if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ')
|
||||
+ "#" + style.spacePrefixBottom
|
||||
+ (new String(new char[borderSpacing - style.spacePrefixBottom.length() - style.spaceSuffixBottom.length()])).replace('\0', style.spaceCharBottom)
|
||||
+ style.spaceSuffixBottom + "#\n");
|
||||
}
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + (new String(new char[borderSpacing + 2])).replace('\0', '#') + "\n");
|
||||
} else if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import com.songoda.core.configuration.ConfigFormattingRules.CommentStyle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A comment for a configuration key
|
||||
*/
|
||||
public class Comment {
|
||||
final List<String> lines = new ArrayList<>();
|
||||
CommentStyle commentStyle = null;
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Comment(String... lines) {
|
||||
this(null, Arrays.asList(lines));
|
||||
}
|
||||
|
||||
public Comment(List<String> lines) {
|
||||
this(null, lines);
|
||||
}
|
||||
|
||||
public Comment(CommentStyle commentStyle, String... lines) {
|
||||
this(commentStyle, Arrays.asList(lines));
|
||||
}
|
||||
|
||||
public Comment(CommentStyle commentStyle, List<String> lines) {
|
||||
this.commentStyle = commentStyle;
|
||||
|
||||
if (lines != null) {
|
||||
lines.forEach(s -> this.lines.addAll(Arrays.asList(s.split("\n"))));
|
||||
}
|
||||
}
|
||||
|
||||
public CommentStyle getCommentStyle() {
|
||||
return commentStyle;
|
||||
}
|
||||
|
||||
public void setCommentStyle(CommentStyle commentStyle) {
|
||||
this.commentStyle = commentStyle;
|
||||
}
|
||||
|
||||
public List<String> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return lines.isEmpty() ? "" : String.join("\n", lines);
|
||||
}
|
||||
|
||||
public static Comment loadComment(List<String> lines) {
|
||||
CommentStyle style = ConfigFormattingRules.parseStyle(lines);
|
||||
|
||||
int linePad = (style.drawBorder ? 1 : 0) + (style.drawSpace ? 1 : 0);
|
||||
int prefix = style.commentPrefix.length();
|
||||
int suffix = style.commentSuffix.length();
|
||||
|
||||
return new Comment(style, lines.subList(linePad, lines.size() - linePad).stream().map(s -> s.substring(prefix, s.length() - suffix).trim()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public void writeComment(Writer output, int offset, CommentStyle defaultStyle) throws IOException {
|
||||
CommentStyle style = commentStyle != null ? commentStyle : defaultStyle;
|
||||
int minSpacing = 0, borderSpacing = 0;
|
||||
|
||||
// first draw the top of the comment
|
||||
if (style.drawBorder) {
|
||||
// grab the longest line in the list of lines
|
||||
minSpacing = lines.stream().max(Comparator.comparingInt(String::length)).orElse("").length();
|
||||
borderSpacing = minSpacing + style.commentPrefix.length() + style.commentSuffix.length();
|
||||
|
||||
// draw the first line
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + (new String(new char[borderSpacing + 2])).replace('\0', '#') + "\n");
|
||||
|
||||
if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ')
|
||||
+ "#" + style.spacePrefixTop
|
||||
+ (new String(new char[borderSpacing - style.spacePrefixTop.length() - style.spaceSuffixTop.length()])).replace('\0', style.spaceCharTop)
|
||||
+ style.spaceSuffixTop + "#\n");
|
||||
}
|
||||
} else if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#\n");
|
||||
}
|
||||
|
||||
// then the actual comment lines
|
||||
for (String line : lines) {
|
||||
// todo? should we auto-wrap comment lines that are longer than 80 characters?
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#" + style.commentPrefix
|
||||
+ (minSpacing == 0 ? line : line + (new String(new char[minSpacing - line.length()])).replace('\0', ' ')) + style.commentSuffix + (style.drawBorder ? "#\n" : "\n"));
|
||||
}
|
||||
|
||||
// now draw the bottom of the comment border
|
||||
if (style.drawBorder) {
|
||||
if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ')
|
||||
+ "#" + style.spacePrefixBottom
|
||||
+ (new String(new char[borderSpacing - style.spacePrefixBottom.length() - style.spaceSuffixBottom.length()])).replace('\0', style.spaceCharBottom)
|
||||
+ style.spaceSuffixBottom + "#\n");
|
||||
}
|
||||
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + (new String(new char[borderSpacing + 2])).replace('\0', '#') + "\n");
|
||||
} else if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
@ -45,12 +44,8 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Configuration settings for a plugin
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-28
|
||||
*/
|
||||
public class Config extends ConfigSection {
|
||||
|
||||
/*
|
||||
Serialization notes:
|
||||
// implements ConfigurationSerializable:
|
||||
@ -75,35 +70,43 @@ public class Config extends ConfigSection {
|
||||
Charset defaultCharset = StandardCharsets.UTF_8;
|
||||
SaveTask saveTask;
|
||||
Timer autosaveTimer;
|
||||
|
||||
////////////// Config settings ////////////////
|
||||
/**
|
||||
* save file whenever a change is made
|
||||
*/
|
||||
boolean autosave = false;
|
||||
|
||||
/**
|
||||
* time in seconds to start a save after a change is made
|
||||
*/
|
||||
int autosaveInterval = 60;
|
||||
|
||||
/**
|
||||
* remove nodes not defined in defaults
|
||||
*/
|
||||
boolean autoremove = false;
|
||||
|
||||
/**
|
||||
* load comments when loading the file
|
||||
*/
|
||||
boolean loadComments = true;
|
||||
|
||||
/**
|
||||
* Default comment applied to config nodes
|
||||
*/
|
||||
ConfigFormattingRules.CommentStyle defaultNodeCommentFormat = ConfigFormattingRules.CommentStyle.SIMPLE;
|
||||
|
||||
/**
|
||||
* Default comment applied to section nodes
|
||||
*/
|
||||
ConfigFormattingRules.CommentStyle defaultSectionCommentFormat = ConfigFormattingRules.CommentStyle.SPACED;
|
||||
|
||||
/**
|
||||
* Extra lines to put between root nodes
|
||||
*/
|
||||
int rootNodeSpacing = 1;
|
||||
|
||||
/**
|
||||
* Extra lines to put in front of comments. <br>
|
||||
* This is separate from rootNodeSpacing, if applicable.
|
||||
@ -113,6 +116,7 @@ public class Config extends ConfigSection {
|
||||
public Config() {
|
||||
this.plugin = null;
|
||||
this.file = null;
|
||||
|
||||
dirName = null;
|
||||
fileName = null;
|
||||
}
|
||||
@ -120,24 +124,28 @@ public class Config extends ConfigSection {
|
||||
public Config(@NotNull File file) {
|
||||
this.plugin = null;
|
||||
this.file = file.getAbsoluteFile();
|
||||
|
||||
dirName = null;
|
||||
fileName = null;
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
dirName = null;
|
||||
fileName = null;
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin, @NotNull String file) {
|
||||
this.plugin = plugin;
|
||||
|
||||
dirName = null;
|
||||
fileName = file;
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin, @Nullable String directory, @NotNull String file) {
|
||||
this.plugin = plugin;
|
||||
|
||||
dirName = directory;
|
||||
fileName = file;
|
||||
}
|
||||
@ -156,6 +164,7 @@ public class Config extends ConfigSection {
|
||||
this.file = new File(plugin.getDataFolder(), fileName != null ? fileName : "config.yml");
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -337,6 +346,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -347,6 +357,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(commentStyle, description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -357,6 +368,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -367,6 +379,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(commentStyle, description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -374,24 +387,27 @@ public class Config extends ConfigSection {
|
||||
public List<String> getHeader() {
|
||||
if (headerComment != null) {
|
||||
return headerComment.getLines();
|
||||
} else {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public Config clearConfig(boolean clearDefaults) {
|
||||
root.values.clear();
|
||||
root.configComments.clear();
|
||||
|
||||
if (clearDefaults) {
|
||||
root.defaultComments.clear();
|
||||
root.defaults.clear();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Config clearDefaults() {
|
||||
root.defaultComments.clear();
|
||||
root.defaults.clear();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -404,17 +420,22 @@ public class Config extends ConfigSection {
|
||||
if (file.exists()) {
|
||||
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file))) {
|
||||
Charset charset = TextUtils.detectCharset(stream, StandardCharsets.UTF_8);
|
||||
|
||||
// upgrade charset if file was saved in a more complex format
|
||||
if (charset == StandardCharsets.UTF_16BE || charset == StandardCharsets.UTF_16LE) {
|
||||
defaultCharset = StandardCharsets.UTF_16;
|
||||
}
|
||||
|
||||
this.load(new InputStreamReader(stream, charset));
|
||||
|
||||
return true;
|
||||
} catch (IOException | InvalidConfigurationException ex) {
|
||||
(plugin != null ? plugin.getLogger() : Bukkit.getLogger()).log(Level.SEVERE, "Failed to load config file: " + file.getName(), ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -432,22 +453,26 @@ public class Config extends ConfigSection {
|
||||
builder.append(line).append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
this.loadFromString(builder.toString());
|
||||
}
|
||||
|
||||
public void loadFromString(@NotNull String contents) throws InvalidConfigurationException {
|
||||
Map input;
|
||||
Map<?, ?> input;
|
||||
|
||||
try {
|
||||
input = (Map) this.yaml.load(contents);
|
||||
input = this.yaml.load(contents);
|
||||
} catch (YAMLException e2) {
|
||||
throw new InvalidConfigurationException(e2);
|
||||
} catch (ClassCastException e3) {
|
||||
throw new InvalidConfigurationException("Top level is not a Map.");
|
||||
}
|
||||
|
||||
if (input != null) {
|
||||
if (loadComments) {
|
||||
this.parseComments(contents, input);
|
||||
}
|
||||
|
||||
this.convertMapsToSections(input, this);
|
||||
}
|
||||
}
|
||||
@ -457,10 +482,12 @@ public class Config extends ConfigSection {
|
||||
for (Map.Entry<?, ?> entry : input.entrySet()) {
|
||||
String key = entry.getKey().toString();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (value instanceof Map) {
|
||||
this.convertMapsToSections((Map) value, section.createSection(key));
|
||||
this.convertMapsToSections((Map<?, ?>) value, section.createSection(key));
|
||||
continue;
|
||||
}
|
||||
|
||||
section.set(key, value);
|
||||
}
|
||||
}
|
||||
@ -475,8 +502,9 @@ public class Config extends ConfigSection {
|
||||
boolean insideScalar = false;
|
||||
boolean firstNode = true;
|
||||
int index = 0;
|
||||
LinkedList<String> currentPath = new LinkedList();
|
||||
ArrayList<String> commentBlock = new ArrayList();
|
||||
LinkedList<String> currentPath = new LinkedList<>();
|
||||
ArrayList<String> commentBlock = new ArrayList<>();
|
||||
|
||||
try {
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.isEmpty()) {
|
||||
@ -523,17 +551,20 @@ public class Config extends ConfigSection {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!commentBlock.isEmpty()) {
|
||||
footerComment = Comment.loadComment(commentBlock);
|
||||
commentBlock.clear();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Config.class.getName()).log(Level.SEVERE, "Error parsing config comment", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteNonDefaultSettings() {
|
||||
// Delete old config values (thread-safe)
|
||||
List<String> defaultKeys = Arrays.asList(defaults.keySet().toArray(new String[0]));
|
||||
|
||||
for (String key : values.keySet().toArray(new String[0])) {
|
||||
if (!defaultKeys.contains(key)) {
|
||||
values.remove(key);
|
||||
@ -558,9 +589,11 @@ public class Config extends ConfigSection {
|
||||
|
||||
public boolean saveChanges() {
|
||||
boolean saved = true;
|
||||
|
||||
if (changed || hasNewDefaults()) {
|
||||
saved = save();
|
||||
}
|
||||
|
||||
if (saveTask != null) {
|
||||
//Close Threads
|
||||
saveTask.cancel();
|
||||
@ -568,14 +601,19 @@ public class Config extends ConfigSection {
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
boolean hasNewDefaults() {
|
||||
if (file != null && !file.exists()) return true;
|
||||
|
||||
for (String def : defaults.keySet()) {
|
||||
if (!values.containsKey(def)) return true;
|
||||
if (!values.containsKey(def)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -587,6 +625,7 @@ public class Config extends ConfigSection {
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
|
||||
return save(getFile());
|
||||
}
|
||||
|
||||
@ -597,15 +636,18 @@ public class Config extends ConfigSection {
|
||||
|
||||
public boolean save(@NotNull File file) {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
|
||||
if (file.getParentFile() != null && !file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
String data = this.saveToString();
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter((OutputStream) new FileOutputStream(file), defaultCharset);) {
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), defaultCharset)) {
|
||||
writer.write(data);
|
||||
} catch (IOException e) {
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -615,41 +657,50 @@ public class Config extends ConfigSection {
|
||||
if (autoremove) {
|
||||
deleteNonDefaultSettings();
|
||||
}
|
||||
|
||||
yamlOptions.setIndent(indentation);
|
||||
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
yamlOptions.setSplitLines(false);
|
||||
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
|
||||
StringWriter str = new StringWriter();
|
||||
|
||||
if (headerComment != null) {
|
||||
headerComment.writeComment(str, 0, ConfigFormattingRules.CommentStyle.BLOCKED);
|
||||
str.write("\n"); // add one space after the header
|
||||
}
|
||||
|
||||
String dump = yaml.dump(this.getValues(false));
|
||||
if (!dump.equals(BLANK_CONFIG)) {
|
||||
writeComments(dump, str);
|
||||
}
|
||||
|
||||
if (footerComment != null) {
|
||||
str.write("\n");
|
||||
footerComment.writeComment(str, 0, ConfigFormattingRules.CommentStyle.BLOCKED);
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(Config.class.getName()).log(Level.SEVERE, "Error saving config", ex);
|
||||
delaySave();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
protected final Pattern yamlNode = Pattern.compile("^( *)([^:\\{\\}\\[\\],&\\*#\\?\\|\\-<>=!%@`]+):(.*)$");
|
||||
protected final Pattern yamlNode = Pattern.compile("^( *)([^:{}\\[\\],&*#?|\\-<>=!%@`]+):(.*)$");
|
||||
|
||||
protected void writeComments(String data, Writer out) throws IOException {
|
||||
// line-by-line apply line spacing formatting and comments per-node
|
||||
BufferedReader in = new BufferedReader(new StringReader(data));
|
||||
|
||||
String line;
|
||||
boolean insideScalar = false;
|
||||
boolean firstNode = true;
|
||||
int index = 0;
|
||||
LinkedList<String> currentPath = new LinkedList();
|
||||
|
||||
LinkedList<String> currentPath = new LinkedList<>();
|
||||
while ((line = in.readLine()) != null) {
|
||||
// ignore comments and empty lines (there shouldn't be any, but just in case)
|
||||
if (line.trim().startsWith("#") || line.isEmpty()) {
|
||||
@ -667,6 +718,7 @@ public class Config extends ConfigSection {
|
||||
while (depth < currentPath.size()) {
|
||||
currentPath.removeLast();
|
||||
}
|
||||
|
||||
currentPath.add(m.group(2));
|
||||
String path = currentPath.stream().collect(Collectors.joining(String.valueOf(pathChar)));
|
||||
|
||||
@ -708,6 +760,7 @@ public class Config extends ConfigSection {
|
||||
// write it down!
|
||||
comment.writeComment(out, lineOffset, style);
|
||||
}
|
||||
|
||||
// ignore scalars
|
||||
index = lineOffset;
|
||||
if (m.group(3).trim().equals("|") || m.group(3).trim().equals(">")) {
|
||||
@ -727,11 +780,11 @@ public class Config extends ConfigSection {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
class SaveTask extends TimerTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
saveChanges();
|
||||
|
@ -1,273 +1,272 @@
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConfigFileConfigurationAdapter extends FileConfiguration {
|
||||
|
||||
final Config config;
|
||||
|
||||
public ConfigFileConfigurationAdapter(Config config) {
|
||||
super(config);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public Config getCoreConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveToString() {
|
||||
return config.saveToString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromString(String string) throws InvalidConfigurationException {
|
||||
config.loadFromString(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String buildHeader() {
|
||||
return "#" + config.getHeader().stream().collect(Collectors.joining("\n#"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigOptionsAdapter options() {
|
||||
return new ConfigOptionsAdapter(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys(boolean deep) {
|
||||
return config.getKeys(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getValues(boolean deep) {
|
||||
return config.getValues(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String path) {
|
||||
return config.contains(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSet(String path) {
|
||||
return config.isSet(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentPath() {
|
||||
return config.getCurrentPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return config.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration getRoot() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefault(String path, Object value) {
|
||||
config.addDefault(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getDefaultSection() {
|
||||
return config.getDefaultSection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String path, Object value) {
|
||||
config.set(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String path) {
|
||||
return config.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String path, Object def) {
|
||||
return config.get(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection createSection(String path) {
|
||||
return config.createSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection createSection(String path, Map<?, ?> map) {
|
||||
return config.createSection(path, map);
|
||||
}
|
||||
|
||||
// Other non-FileConfiguration methods
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createDefaultSection(@NotNull String path) {
|
||||
return config.createDefaultSection(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createDefaultSection(@NotNull String path, String... comment) {
|
||||
return config.createDefaultSection(path, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createDefaultSection(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.createDefaultSection(path, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
|
||||
return config.setComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
|
||||
return config.setComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, String... lines) {
|
||||
return config.setDefaultComment(path, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, @Nullable List<String> lines) {
|
||||
return config.setDefaultComment(path, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
|
||||
return config.setDefaultComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
|
||||
return config.setDefaultComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Comment getComment(@NotNull String path) {
|
||||
return config.getComment(path);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCommentString(@NotNull String path) {
|
||||
return config.getCommentString(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ConfigSection> getSections(String path) {
|
||||
return config.getSections(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, String... comment) {
|
||||
return config.set(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, List<String> comment) {
|
||||
return config.set(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.set(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
|
||||
return config.set(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value) {
|
||||
return config.setDefault(path, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, String... comment) {
|
||||
return config.setDefault(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, List<String> comment) {
|
||||
return config.setDefault(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.setDefault(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
|
||||
return config.setDefault(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, String... comment) {
|
||||
return config.createSection(path, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable List<String> comment) {
|
||||
return config.createSection(path, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.createSection(path, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> comment) {
|
||||
return config.createSection(path, commentStyle, comment);
|
||||
}
|
||||
|
||||
public char getChar(@NotNull String path) {
|
||||
return config.getChar(path);
|
||||
}
|
||||
|
||||
public char getChar(@NotNull String path, char def) {
|
||||
return config.getChar(path, def);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompatibleMaterial getMaterial(@NotNull String path) {
|
||||
return config.getMaterial(path);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompatibleMaterial getMaterial(@NotNull String path, @Nullable CompatibleMaterial def) {
|
||||
return config.getMaterial(path, def);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection getOrCreateConfigurationSection(@NotNull String path) {
|
||||
return config.getOrCreateConfigurationSection(path);
|
||||
}
|
||||
}
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConfigFileConfigurationAdapter extends FileConfiguration {
|
||||
final Config config;
|
||||
|
||||
public ConfigFileConfigurationAdapter(Config config) {
|
||||
super(config);
|
||||
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public Config getCoreConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveToString() {
|
||||
return config.saveToString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromString(String string) throws InvalidConfigurationException {
|
||||
config.loadFromString(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String buildHeader() {
|
||||
return "#" + String.join("\n#", config.getHeader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigOptionsAdapter options() {
|
||||
return new ConfigOptionsAdapter(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys(boolean deep) {
|
||||
return config.getKeys(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getValues(boolean deep) {
|
||||
return config.getValues(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String path) {
|
||||
return config.contains(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSet(String path) {
|
||||
return config.isSet(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentPath() {
|
||||
return config.getCurrentPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return config.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration getRoot() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefault(String path, Object value) {
|
||||
config.addDefault(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection getDefaultSection() {
|
||||
return config.getDefaultSection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String path, Object value) {
|
||||
config.set(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String path) {
|
||||
return config.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String path, Object def) {
|
||||
return config.get(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection createSection(String path) {
|
||||
return config.createSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSection createSection(String path, Map<?, ?> map) {
|
||||
return config.createSection(path, map);
|
||||
}
|
||||
|
||||
// Other non-FileConfiguration methods
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createDefaultSection(@NotNull String path) {
|
||||
return config.createDefaultSection(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createDefaultSection(@NotNull String path, String... comment) {
|
||||
return config.createDefaultSection(path, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createDefaultSection(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.createDefaultSection(path, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
|
||||
return config.setComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
|
||||
return config.setComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, String... lines) {
|
||||
return config.setDefaultComment(path, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, @Nullable List<String> lines) {
|
||||
return config.setDefaultComment(path, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
|
||||
return config.setDefaultComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
|
||||
return config.setDefaultComment(path, commentStyle, lines);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Comment getComment(@NotNull String path) {
|
||||
return config.getComment(path);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCommentString(@NotNull String path) {
|
||||
return config.getCommentString(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ConfigSection> getSections(String path) {
|
||||
return config.getSections(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, String... comment) {
|
||||
return config.set(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, List<String> comment) {
|
||||
return config.set(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.set(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
|
||||
return config.set(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value) {
|
||||
return config.setDefault(path, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, String... comment) {
|
||||
return config.setDefault(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, List<String> comment) {
|
||||
return config.setDefault(path, value, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.setDefault(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
|
||||
return config.setDefault(path, value, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, String... comment) {
|
||||
return config.createSection(path, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable List<String> comment) {
|
||||
return config.createSection(path, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
return config.createSection(path, commentStyle, comment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> comment) {
|
||||
return config.createSection(path, commentStyle, comment);
|
||||
}
|
||||
|
||||
public char getChar(@NotNull String path) {
|
||||
return config.getChar(path);
|
||||
}
|
||||
|
||||
public char getChar(@NotNull String path, char def) {
|
||||
return config.getChar(path, def);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompatibleMaterial getMaterial(@NotNull String path) {
|
||||
return config.getMaterial(path);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompatibleMaterial getMaterial(@NotNull String path, @Nullable CompatibleMaterial def) {
|
||||
return config.getMaterial(path, def);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection getOrCreateConfigurationSection(@NotNull String path) {
|
||||
return config.getOrCreateConfigurationSection(path);
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,12 @@ package com.songoda.core.configuration;
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigFormattingRules {
|
||||
|
||||
int spacesBetweenMainCategories;
|
||||
int spacesBetweenValues;
|
||||
CommentStyle rootCommentStyle = CommentStyle.BLOCKSPACED;
|
||||
CommentStyle mainCategoryCommentStyle = CommentStyle.SPACED;
|
||||
|
||||
public static enum CommentStyle {
|
||||
|
||||
public enum CommentStyle {
|
||||
/**
|
||||
* # Comment
|
||||
*/
|
||||
@ -41,10 +39,10 @@ public class ConfigFormattingRules {
|
||||
final String commentSuffix, spaceSuffixTop, spaceSuffixBottom;
|
||||
final char spaceCharTop, spaceCharBottom;
|
||||
|
||||
private CommentStyle(boolean drawBorder, boolean drawSpace,
|
||||
String spacePrefixTop, char spaceCharTop, String spaceSuffixTop,
|
||||
String commentPrefix, String commentSuffix,
|
||||
String spacePrefixBottom, char spaceCharBottom, String spaceSuffixBottom) {
|
||||
CommentStyle(boolean drawBorder, boolean drawSpace,
|
||||
String spacePrefixTop, char spaceCharTop, String spaceSuffixTop,
|
||||
String commentPrefix, String commentSuffix,
|
||||
String spacePrefixBottom, char spaceCharBottom, String spaceSuffixBottom) {
|
||||
this.drawBorder = drawBorder;
|
||||
this.drawSpace = drawSpace;
|
||||
this.commentPrefix = commentPrefix;
|
||||
@ -57,7 +55,7 @@ public class ConfigFormattingRules {
|
||||
this.spaceCharBottom = spaceCharBottom;
|
||||
}
|
||||
|
||||
private CommentStyle(boolean drawBorder, boolean drawSpace, String commentPrefix, String commentSuffix) {
|
||||
CommentStyle(boolean drawBorder, boolean drawSpace, String commentPrefix, String commentSuffix) {
|
||||
this.drawBorder = drawBorder;
|
||||
this.drawSpace = drawSpace;
|
||||
this.commentPrefix = commentPrefix;
|
||||
@ -71,14 +69,18 @@ public class ConfigFormattingRules {
|
||||
public static CommentStyle parseStyle(List<String> lines) {
|
||||
if (lines == null || lines.size() <= 2) {
|
||||
return CommentStyle.SIMPLE;
|
||||
} else if (lines.size() > 2 && lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
|
||||
}
|
||||
|
||||
if (lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
|
||||
return CommentStyle.SPACED;
|
||||
}
|
||||
boolean hasBorders = lines.size() > 2 && lines.get(0).trim().matches("^##+$") && lines.get(lines.size() - 1).trim().matches("^##+$");
|
||||
|
||||
boolean hasBorders = lines.get(0).trim().matches("^##+$") && lines.get(lines.size() - 1).trim().matches("^##+$");
|
||||
if (!hasBorders) {
|
||||
// default return
|
||||
return CommentStyle.SIMPLE;
|
||||
}
|
||||
|
||||
// now need to figure out if this is blocked or not
|
||||
if (lines.size() > 4 && lines.get(1).trim().matches(("^#"
|
||||
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
|
||||
@ -88,6 +90,7 @@ public class ConfigFormattingRules {
|
||||
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))) {
|
||||
return CommentStyle.BLOCKSPACED;
|
||||
}
|
||||
|
||||
return CommentStyle.BLOCKED;
|
||||
}
|
||||
}
|
||||
|
@ -1,71 +1,72 @@
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfigurationOptions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigOptionsAdapter extends FileConfigurationOptions {
|
||||
|
||||
final ConfigSection config;
|
||||
|
||||
public ConfigOptionsAdapter(ConfigSection config) {
|
||||
super(config);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public Config getConfig() {
|
||||
return (Config) config.root;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigFileConfigurationAdapter configuration() {
|
||||
return new ConfigFileConfigurationAdapter((Config) config.root);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter copyDefaults(boolean value) {
|
||||
// we always copy new values
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter pathSeparator(char value) {
|
||||
((Config) config.root).setPathSeparator(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter header(@Nullable String value) {
|
||||
if (value == null) {
|
||||
((Config) config.root).setHeader((List) null);
|
||||
} else {
|
||||
((Config) config.root).setHeader(value.split("\n"));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter copyHeader(boolean value) {
|
||||
if (!value) {
|
||||
((Config) config.root).setHeader((List) null);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public int indent() {
|
||||
return ((Config) config.root).getIndent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigOptionsAdapter indent(int value) {
|
||||
((Config) config.root).setIndent(value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfigurationOptions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigOptionsAdapter extends FileConfigurationOptions {
|
||||
final ConfigSection config;
|
||||
|
||||
public ConfigOptionsAdapter(ConfigSection config) {
|
||||
super(config);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public Config getConfig() {
|
||||
return (Config) config.root;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigFileConfigurationAdapter configuration() {
|
||||
return new ConfigFileConfigurationAdapter((Config) config.root);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter copyDefaults(boolean value) {
|
||||
// we always copy new values
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter pathSeparator(char value) {
|
||||
(config.root).setPathSeparator(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter header(@Nullable String value) {
|
||||
if (value == null) {
|
||||
((Config) config.root).setHeader((List) null);
|
||||
} else {
|
||||
((Config) config.root).setHeader(value.split("\n"));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConfigOptionsAdapter copyHeader(boolean value) {
|
||||
if (!value) {
|
||||
((Config) config.root).setHeader((List) null);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int indent() {
|
||||
return config.root.getIndent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigOptionsAdapter indent(int value) {
|
||||
config.root.setIndent(value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ConfigSetting {
|
||||
|
||||
final Config config;
|
||||
final String key;
|
||||
|
||||
@ -21,12 +20,14 @@ public class ConfigSetting {
|
||||
public ConfigSetting(@NotNull Config config, @NotNull String key, @NotNull Object defaultValue, String... comment) {
|
||||
this.config = config;
|
||||
this.key = key;
|
||||
|
||||
config.setDefault(key, defaultValue, comment);
|
||||
}
|
||||
|
||||
public ConfigSetting(@NotNull Config config, @NotNull String key, @NotNull Object defaultValue, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
this.config = config;
|
||||
this.key = key;
|
||||
|
||||
config.setDefault(key, defaultValue, commentStyle, comment);
|
||||
}
|
||||
|
||||
|
@ -1,35 +1,30 @@
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
public interface DataStoreObject<T> {
|
||||
|
||||
/**
|
||||
* @return a unique hashable instance of T to store this value under
|
||||
*/
|
||||
public abstract T getKey();
|
||||
|
||||
/**
|
||||
* @return a unique identifier for saving this value with
|
||||
*/
|
||||
public abstract String getConfigKey();
|
||||
|
||||
/**
|
||||
* Save this data to a ConfigurationSection
|
||||
*
|
||||
* @param sec
|
||||
*/
|
||||
public abstract void saveToSection(ConfigurationSection sec);
|
||||
|
||||
/**
|
||||
* @return true if this data has changed from the state saved to file
|
||||
*/
|
||||
public boolean hasChanged();
|
||||
|
||||
/**
|
||||
* Mark this data as needing a save or not
|
||||
*
|
||||
* @param isChanged
|
||||
*/
|
||||
public void setChanged(boolean isChanged);
|
||||
}
|
||||
package com.songoda.core.configuration;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
public interface DataStoreObject<T> {
|
||||
/**
|
||||
* @return a unique hashable instance of T to store this value under
|
||||
*/
|
||||
T getKey();
|
||||
|
||||
/**
|
||||
* @return a unique identifier for saving this value with
|
||||
*/
|
||||
String getConfigKey();
|
||||
|
||||
/**
|
||||
* Save this data to a ConfigurationSection
|
||||
*/
|
||||
void saveToSection(ConfigurationSection sec);
|
||||
|
||||
/**
|
||||
* @return true if this data has changed from the state saved to file
|
||||
*/
|
||||
boolean hasChanged();
|
||||
|
||||
/**
|
||||
* Mark this data as needing a save or not
|
||||
*/
|
||||
void setChanged(boolean isChanged);
|
||||
}
|
||||
|
@ -21,16 +21,12 @@ import java.util.logging.Level;
|
||||
* Used to easily store a set of one data value
|
||||
*
|
||||
* @param <T> DataObject class that is used to store the data
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-09-06
|
||||
*/
|
||||
public class SimpleDataStore<T extends DataStoreObject> {
|
||||
|
||||
protected final Plugin plugin;
|
||||
protected final String filename, dirName;
|
||||
private final Function<ConfigurationSection, T> getFromSection;
|
||||
protected final HashMap<Object, T> data = new HashMap();
|
||||
protected final HashMap<Object, T> data = new HashMap<>();
|
||||
private File file;
|
||||
private final Object lock = new Object();
|
||||
SaveTask saveTask;
|
||||
@ -63,6 +59,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
this.file = new File(plugin.getDataFolder(), filename != null ? filename : "data.yml");
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -99,10 +96,13 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
@Nullable
|
||||
public T remove(@NotNull Object key) {
|
||||
T temp;
|
||||
|
||||
synchronized (lock) {
|
||||
temp = data.remove(key);
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -119,11 +119,15 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T temp;
|
||||
|
||||
synchronized (lock) {
|
||||
temp = data.remove(value.getKey());
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -141,11 +145,15 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T temp;
|
||||
|
||||
synchronized (lock) {
|
||||
temp = data.put(value.getKey(), value);
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -155,18 +163,19 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
*
|
||||
* @param value values to be added
|
||||
*/
|
||||
@Nullable
|
||||
public void addAll(@NotNull T[] value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
for (int i = 0; i < value.length; ++i) {
|
||||
if (value[i] != null) {
|
||||
data.put(value[i].getKey(), value[i]);
|
||||
for (T t : value) {
|
||||
if (t != null) {
|
||||
data.put(t.getKey(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
@ -181,6 +190,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
for (T v : value) {
|
||||
if (v != null) {
|
||||
@ -188,6 +198,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
@ -198,6 +209,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (!getFile().exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
YamlConfiguration f = new YamlConfiguration();
|
||||
f.options().pathSeparator('\0');
|
||||
@ -205,9 +217,9 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
|
||||
synchronized (lock) {
|
||||
data.clear();
|
||||
f.getValues(false).entrySet().stream()
|
||||
.filter(d -> d.getValue() instanceof ConfigurationSection)
|
||||
.map(Map.Entry::getValue)
|
||||
|
||||
f.getValues(false).values().stream()
|
||||
.filter(ConfigurationSection.class::isInstance)
|
||||
.map(v -> getFromSection.apply((ConfigurationSection) v))
|
||||
.forEach(v -> data.put(v.getKey(), v));
|
||||
}
|
||||
@ -221,7 +233,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
* made
|
||||
*/
|
||||
public void saveChanges() {
|
||||
if (saveTask != null || data.values().stream().anyMatch(v -> v.hasChanged())) {
|
||||
if (saveTask != null || data.values().stream().anyMatch(DataStoreObject::hasChanged)) {
|
||||
flushSave();
|
||||
}
|
||||
}
|
||||
@ -248,20 +260,22 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
|
||||
YamlConfiguration f = new YamlConfiguration();
|
||||
|
||||
synchronized (lock) {
|
||||
data.values().stream().forEach(e -> e.saveToSection(f.createSection(e.getConfigKey())));
|
||||
data.values().forEach(e -> e.saveToSection(f.createSection(e.getConfigKey())));
|
||||
}
|
||||
|
||||
try {
|
||||
f.save(getFile());
|
||||
data.values().stream().forEach(e -> e.setChanged(false));
|
||||
data.values().forEach(e -> e.setChanged(false));
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to save data to " + file.getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
class SaveTask extends TimerTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
flushSave();
|
||||
|
@ -27,12 +27,8 @@ import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Edit a configuration file for a specific plugin
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
final JavaPlugin plugin;
|
||||
final String file;
|
||||
final MemoryConfiguration config;
|
||||
@ -40,8 +36,8 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
final Player player;
|
||||
Method configSection_getCommentString = null;
|
||||
boolean edits = false;
|
||||
List<String> sections = new ArrayList();
|
||||
List<String> settings = new ArrayList();
|
||||
List<String> sections = new ArrayList<>();
|
||||
List<String> settings = new ArrayList<>();
|
||||
|
||||
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config) {
|
||||
this(player, plugin, parent, file, config, config);
|
||||
@ -49,6 +45,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config, ConfigurationSection node) {
|
||||
super(parent);
|
||||
|
||||
this.player = player;
|
||||
this.plugin = plugin;
|
||||
this.file = file;
|
||||
@ -65,7 +62,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
// if we have a ConfigSection, we can also grab comments
|
||||
try {
|
||||
configSection_getCommentString = node.getClass().getDeclaredMethod("getCommentString", String.class);
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
// decorate header
|
||||
@ -80,9 +77,10 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
for (String key : node.getKeys(false)) {
|
||||
if (node.isConfigurationSection(key)) {
|
||||
sections.add(key);
|
||||
} else {
|
||||
settings.add(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
settings.add(key);
|
||||
}
|
||||
|
||||
// next we need to display the config settings
|
||||
@ -95,17 +93,21 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
// now display individual settings
|
||||
for (final String settingKey : settings) {
|
||||
final Object val = node.get(settingKey);
|
||||
if (val == null) continue;
|
||||
else if (val instanceof Boolean) {
|
||||
if (val == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val instanceof Boolean) {
|
||||
// toggle switch
|
||||
setButton(index, configItem(CompatibleMaterial.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Boolean) val), "Click to toggle this setting"),
|
||||
setButton(index, configItem(CompatibleMaterial.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf(val), "Click to toggle this setting"),
|
||||
(event) -> this.toggle(event.slot, settingKey));
|
||||
|
||||
if ((Boolean) val) {
|
||||
highlightItem(index);
|
||||
}
|
||||
} else if (isNumber(val)) {
|
||||
// number dial
|
||||
this.setButton(index, configItem(CompatibleMaterial.CLOCK, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Number) val), "Click to edit this setting"),
|
||||
this.setButton(index, configItem(CompatibleMaterial.CLOCK, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf(val), "Click to edit this setting"),
|
||||
(event) -> {
|
||||
event.gui.exit();
|
||||
ChatPrompt.showPrompt(plugin, event.player, "Enter a new number value for " + settingKey + ":", response -> {
|
||||
@ -151,17 +153,16 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
});
|
||||
});
|
||||
} else if (val instanceof List) {
|
||||
setButton(index, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List) val).size()), "Click to edit this setting"),
|
||||
(event) -> {
|
||||
event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> {
|
||||
if (((ConfigEditorListEditorGui) gui.gui).saveChanges) {
|
||||
setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).values);
|
||||
}
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
setButton(index, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List<?>) val).size()), "Click to edit this setting"),
|
||||
(event) ->
|
||||
event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> {
|
||||
if (((ConfigEditorListEditorGui) gui.gui).saveChanges) {
|
||||
setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).values);
|
||||
}
|
||||
})));
|
||||
} /* else {
|
||||
// idk. should we display uneditable values?
|
||||
}
|
||||
} */
|
||||
|
||||
++index;
|
||||
}
|
||||
@ -173,16 +174,22 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
protected void updateValue(int clickCell, String path) {
|
||||
ItemStack item = inventory.getItem(clickCell);
|
||||
if (item == null || item == AIR) return;
|
||||
|
||||
if (item == null || item == AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
Object val = node.get(path);
|
||||
|
||||
if (meta != null && val != null) {
|
||||
String valStr;
|
||||
if (val instanceof List) {
|
||||
valStr = String.format("(%d values)", ((List) val).size());
|
||||
valStr = String.format("(%d values)", ((List<?>) val).size());
|
||||
} else {
|
||||
valStr = val.toString();
|
||||
}
|
||||
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null || lore.isEmpty()) {
|
||||
meta.setLore(Arrays.asList(valStr));
|
||||
@ -190,20 +197,24 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
lore.set(0, valStr);
|
||||
meta.setLore(lore);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
setItem(clickCell, item);
|
||||
}
|
||||
|
||||
edits = true;
|
||||
}
|
||||
|
||||
void toggle(int clickCell, String path) {
|
||||
boolean val = !node.getBoolean(path);
|
||||
node.set(path, val);
|
||||
|
||||
if (val) {
|
||||
setItem(clickCell, ItemUtils.addGlow(inventory.getItem(clickCell)));
|
||||
} else {
|
||||
setItem(clickCell, ItemUtils.removeGlow(inventory.getItem(clickCell)));
|
||||
}
|
||||
|
||||
updateValue(clickCell, path);
|
||||
}
|
||||
|
||||
@ -216,20 +227,24 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
} else if (node.isLong(path)) {
|
||||
node.set(path, Long.parseLong(input));
|
||||
}
|
||||
|
||||
updateValue(clickCell, path);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (NumberFormatException ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setMaterial(int clickCell, String path, ItemStack item) {
|
||||
CompatibleMaterial mat = CompatibleMaterial.getMaterial(item);
|
||||
|
||||
if (mat == null) {
|
||||
node.set(path, CompatibleMaterial.STONE.name());
|
||||
} else {
|
||||
node.set(path, mat.name());
|
||||
}
|
||||
|
||||
updateValue(clickCell, path);
|
||||
}
|
||||
|
||||
@ -242,6 +257,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
if (!edits) {
|
||||
return;
|
||||
}
|
||||
|
||||
// could also check and call saveChanges()
|
||||
if (config instanceof FileConfiguration) {
|
||||
try {
|
||||
@ -257,50 +273,59 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
plugin.getLogger().log(Level.WARNING, "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.reloadConfig();
|
||||
player.sendMessage(ChatColor.GREEN + "Config " + file + " saved!");
|
||||
}
|
||||
|
||||
private boolean isNumber(Object value) {
|
||||
return value != null && (
|
||||
value instanceof Long
|
||||
|| value instanceof Integer
|
||||
|| value instanceof Float
|
||||
|| value instanceof Double);
|
||||
return (value instanceof Long
|
||||
|| value instanceof Integer
|
||||
|| value instanceof Float
|
||||
|| value instanceof Double);
|
||||
}
|
||||
|
||||
private boolean isMaterial(Object value) {
|
||||
CompatibleMaterial m;
|
||||
|
||||
return value instanceof String && value.toString().equals(value.toString().toUpperCase())
|
||||
&& (m = CompatibleMaterial.getMaterial(value.toString())) != null && m.isValidItem();
|
||||
}
|
||||
|
||||
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String def) {
|
||||
String[] info = null;
|
||||
|
||||
if (configSection_getCommentString != null) {
|
||||
try {
|
||||
Object comment = configSection_getCommentString.invoke(node, path);
|
||||
|
||||
if (comment != null) {
|
||||
info = comment.toString().split("\n");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? def.split("\n") : null));
|
||||
}
|
||||
|
||||
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String value, String def) {
|
||||
if (value == null) value = "";
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
|
||||
String[] info = null;
|
||||
|
||||
if (configSection_getCommentString != null) {
|
||||
try {
|
||||
Object comment = configSection_getCommentString.invoke(node, path);
|
||||
if (comment != null) {
|
||||
info = (value + "\n" + comment.toString()).split("\n");
|
||||
info = (value + "\n" + comment).split("\n");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? (value + "\n" + def).split("\n") : null));
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,8 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Edit a string list
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
|
||||
final ConfigEditorGui current;
|
||||
|
||||
public boolean saveChanges = false;
|
||||
@ -25,6 +21,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
|
||||
public ConfigEditorListEditorGui(ConfigEditorGui current, String key, List<String> val) {
|
||||
super(current);
|
||||
|
||||
this.current = current;
|
||||
this.blankItem = current.getDefaultItem();
|
||||
headerBackItem = footerBackItem = current.getHeaderBackItem();
|
||||
@ -32,7 +29,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
this.setUseHeader(true);
|
||||
this.setItem(4, current.configItem(CompatibleMaterial.FILLED_MAP, key, current.getCurrentNode(), key, null));
|
||||
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
|
||||
this.values = new ArrayList(val);
|
||||
this.values = new ArrayList<>(val);
|
||||
|
||||
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.LAVA_BUCKET, ChatColor.RED + "Discard Changes"), (event) -> event.player.closeInventory());
|
||||
this.setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.REDSTONE, ChatColor.GREEN + "Save"), (event) -> {
|
||||
@ -45,9 +42,8 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
ChatPrompt.showPrompt(event.manager.getPlugin(), event.player, "Enter a new value to add:", response -> {
|
||||
values.add(response.getMessage().trim());
|
||||
redraw();
|
||||
}).setOnClose(() -> {
|
||||
event.manager.showGUI(event.player, this);
|
||||
})
|
||||
.setOnClose(() -> event.manager.showGUI(event.player, this))
|
||||
.setOnCancel(() -> {
|
||||
event.player.sendMessage(ChatColor.RED + "Edit canceled");
|
||||
event.manager.showGUI(event.player, this);
|
||||
@ -59,6 +55,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
|
||||
void redraw() {
|
||||
page = 1;
|
||||
|
||||
// clear old display
|
||||
if (inventory != null) {
|
||||
for (Integer i : cellItems.keySet().toArray(new Integer[0])) {
|
||||
@ -78,6 +75,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
redraw();
|
||||
});
|
||||
}
|
||||
|
||||
// update display
|
||||
update();
|
||||
}
|
||||
|
@ -19,14 +19,10 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Edit all configuration files for a specific plugin
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class PluginConfigGui extends SimplePagedGui {
|
||||
|
||||
final JavaPlugin plugin;
|
||||
LinkedHashMap<String, MemoryConfiguration> configs = new LinkedHashMap();
|
||||
LinkedHashMap<String, MemoryConfiguration> configs = new LinkedHashMap<>();
|
||||
|
||||
public PluginConfigGui(SongodaPlugin plugin) {
|
||||
this(plugin, null);
|
||||
@ -34,6 +30,7 @@ public class PluginConfigGui extends SimplePagedGui {
|
||||
|
||||
public PluginConfigGui(SongodaPlugin plugin, Gui parent) {
|
||||
super(parent);
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
// collect list of plugins
|
||||
@ -44,6 +41,7 @@ public class PluginConfigGui extends SimplePagedGui {
|
||||
configs.put(cfg.getFile().getName(), cfg);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@ -61,21 +59,22 @@ public class PluginConfigGui extends SimplePagedGui {
|
||||
try {
|
||||
// can we also grab extra config from this mysterious plugin?
|
||||
Object more = plugin.getClass().getDeclaredMethod("getExtraConfig").invoke(plugin);
|
||||
if (more != null && more instanceof List && !((List) more).isEmpty()) {
|
||||
if (more instanceof List && !((List<?>) more).isEmpty()) {
|
||||
try {
|
||||
// if we have the getExtraConfig function, we should also be able to get the file
|
||||
Method method_Config_getFile = ((List) more).get(0).getClass().getDeclaredMethod("getFile");
|
||||
for (Object cfg : ((List) more)) {
|
||||
Method method_Config_getFile = ((List<?>) more).get(0).getClass().getDeclaredMethod("getFile");
|
||||
for (Object cfg : ((List<?>) more)) {
|
||||
configs.put(((File) method_Config_getFile.invoke(cfg)).getName(), (MemoryConfiguration) cfg);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// include a failsafe, I guess
|
||||
((List) more).forEach(cfg -> configs.put("(File " + configs.size() + ")", (MemoryConfiguration) cfg));
|
||||
((List<?>) more).forEach(cfg -> configs.put("(File " + configs.size() + ")", (MemoryConfiguration) cfg));
|
||||
}
|
||||
}
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
|
||||
// I guess not!
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -6,19 +6,21 @@ import org.json.simple.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class LocaleModule implements PluginInfoModule {
|
||||
|
||||
@Override
|
||||
public void run(PluginInfo plugin) {
|
||||
if (plugin.getJavaPlugin() == null || plugin.getSongodaId() <= 0) return;
|
||||
JSONObject json = plugin.getJson();
|
||||
if (plugin.getJavaPlugin() == null || plugin.getSongodaId() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject json = plugin.getJson();
|
||||
JSONArray files = (JSONArray) json.get("neededFiles");
|
||||
|
||||
for (Object o : files) {
|
||||
JSONObject file = (JSONObject) o;
|
||||
|
||||
@ -26,13 +28,14 @@ public class LocaleModule implements PluginInfoModule {
|
||||
downloadLocale(plugin, (String) file.get("link"), (String) file.get("name"));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(LocaleModule.class.getName()).log(Level.INFO, "Failed to check for locale files: " + e.getMessage());
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(LocaleModule.class.getName()).log(Level.INFO, "Failed to check for locale files: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void downloadLocale(PluginInfo plugin, String link, String fileName) throws MalformedURLException, IOException {
|
||||
void downloadLocale(PluginInfo plugin, String link, String fileName) throws IOException {
|
||||
URL url = new URL(link);
|
||||
|
||||
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
|
||||
urlConnection.setRequestProperty("Accept", "*/*");
|
||||
|
@ -9,7 +9,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class PluginInfo {
|
||||
|
||||
protected final JavaPlugin javaPlugin;
|
||||
protected final int songodaId;
|
||||
protected final String coreIcon;
|
||||
@ -37,6 +36,7 @@ public final class PluginInfo {
|
||||
|
||||
public void setLatestVersion(String latestVersion) {
|
||||
this.latestVersion = latestVersion;
|
||||
|
||||
hasUpdate = latestVersion != null && !latestVersion.isEmpty() && !javaPlugin.getDescription().getVersion().equalsIgnoreCase(latestVersion);
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ public final class PluginInfo {
|
||||
|
||||
public PluginInfoModule addModule(PluginInfoModule module) {
|
||||
modules.add(module);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.songoda.core.core;
|
||||
|
||||
public interface PluginInfoModule {
|
||||
|
||||
void run(PluginInfo plugin);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import org.bukkit.entity.Player;
|
||||
import java.util.List;
|
||||
|
||||
public class SongodaCoreCommand extends AbstractCommand {
|
||||
|
||||
protected GuiManager guiManager;
|
||||
|
||||
public SongodaCoreCommand() {
|
||||
@ -22,10 +21,12 @@ public class SongodaCoreCommand extends AbstractCommand {
|
||||
if (guiManager == null || guiManager.isClosed()) {
|
||||
guiManager = new GuiManager(SongodaCore.getHijackedPlugin());
|
||||
}
|
||||
|
||||
guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI());
|
||||
} else {
|
||||
sender.sendMessage("/songoda diag");
|
||||
}
|
||||
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class SongodaCoreDiagCommand extends AbstractCommand {
|
||||
|
||||
private final DecimalFormat format = new DecimalFormat("##.##");
|
||||
|
||||
private Object serverInstance;
|
||||
@ -27,36 +26,38 @@ public class SongodaCoreDiagCommand extends AbstractCommand {
|
||||
serverInstance = ClassMapping.MINECRAFT_SERVER.getClazz().getMethod("getServer").invoke(null);
|
||||
tpsField = serverInstance.getClass().getField("recentTps");
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
| InvocationTargetException | NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Songoda Diagnostics Information");
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Plugins:");
|
||||
|
||||
for (PluginInfo plugin : SongodaCore.getPlugins()) {
|
||||
sender.sendMessage(plugin.getJavaPlugin().getName()
|
||||
+ " (" + plugin.getJavaPlugin().getDescription().getVersion() + " Core " + plugin.getCoreLibraryVersion() + ")");
|
||||
}
|
||||
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Server Version: " + Bukkit.getVersion());
|
||||
sender.sendMessage("NMS: " + ServerProject.getServerVersion() + " " + ServerVersion.getServerVersionString());
|
||||
sender.sendMessage("Operating System: " + System.getProperty("os.name"));
|
||||
sender.sendMessage("Allocated Memory: " + format.format(Runtime.getRuntime().maxMemory() / (1024 * 1024)) + "Mb");
|
||||
sender.sendMessage("Online Players: " + Bukkit.getOnlinePlayers().size());
|
||||
|
||||
if (tpsField != null) {
|
||||
try {
|
||||
double[] tps = ((double[]) tpsField.get(serverInstance));
|
||||
|
||||
sender.sendMessage("TPS from last 1m, 5m, 15m: " + format.format(tps[0]) + ", "
|
||||
+ format.format(tps[1]) + ", " + format.format(tps[2]));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import java.util.List;
|
||||
|
||||
final class SongodaCoreOverviewGUI extends Gui {
|
||||
|
||||
protected SongodaCoreOverviewGUI() {
|
||||
List<PluginInfo> plugins = SongodaCore.getPlugins();
|
||||
// could do pages, too, but don't think we'll have that many at a time for a while
|
||||
@ -23,6 +22,7 @@ final class SongodaCoreOverviewGUI extends Gui {
|
||||
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
final PluginInfo plugin = plugins.get(i);
|
||||
|
||||
if (plugin.hasUpdate()) {
|
||||
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
|
||||
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
|
||||
@ -38,17 +38,19 @@ final class SongodaCoreOverviewGUI extends Gui {
|
||||
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
|
||||
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
|
||||
highlightItem(i);
|
||||
} else {
|
||||
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
|
||||
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
|
||||
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
|
||||
"",
|
||||
ChatColor.GOLD + "Click for the marketplace page link.",
|
||||
ChatColor.GOLD + "Right Click to edit plugin settings."
|
||||
),
|
||||
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
|
||||
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
|
||||
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
|
||||
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
|
||||
"",
|
||||
ChatColor.GOLD + "Click for the marketplace page link.",
|
||||
ChatColor.GOLD + "Right Click to edit plugin settings."
|
||||
),
|
||||
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
|
||||
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,10 @@ public class DataManagerAbstract {
|
||||
ResultSet result = statement.executeQuery(query);
|
||||
result.next();
|
||||
id = result.getInt(1);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -143,24 +144,31 @@ public class DataManagerAbstract {
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue tasks to be ran asynchronously.
|
||||
* Queue tasks to be run asynchronously.
|
||||
*
|
||||
* @param runnable task to put into queue.
|
||||
* @param queueKey the queue key to add the runnable to.
|
||||
*/
|
||||
@Deprecated
|
||||
public void queueAsync(Runnable runnable, String queueKey) {
|
||||
if (queueKey == null) return;
|
||||
if (queueKey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Runnable> queue = queues.computeIfAbsent(queueKey, t -> new LinkedList<>());
|
||||
queue.add(runnable);
|
||||
if (queue.size() == 1) runQueue(queueKey);
|
||||
|
||||
if (queue.size() == 1) {
|
||||
runQueue(queueKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void runQueue(String queueKey) {
|
||||
doQueue(queueKey, (s) -> {
|
||||
if (!queues.get(queueKey).isEmpty())
|
||||
if (!queues.get(queueKey).isEmpty()) {
|
||||
runQueue(queueKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public abstract class DataMigration {
|
||||
|
||||
private final int revision;
|
||||
|
||||
public DataMigration(int revision) {
|
||||
|
@ -8,7 +8,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DataMigrationManager {
|
||||
|
||||
private final List<DataMigration> migrations;
|
||||
private final DatabaseConnector databaseConnector;
|
||||
private final DataManagerAbstract dataManagerAbstract;
|
||||
@ -65,23 +64,23 @@ public class DataMigrationManager {
|
||||
|
||||
// Grab required migrations
|
||||
int finalCurrentMigration = currentMigration;
|
||||
List<DataMigration> requiredMigrations = this.migrations
|
||||
.stream()
|
||||
List<DataMigration> requiredMigrations = this.migrations.stream()
|
||||
.filter(x -> x.getRevision() > finalCurrentMigration)
|
||||
.sorted(Comparator.comparingInt(DataMigration::getRevision))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Nothing to migrate, abort
|
||||
if (requiredMigrations.isEmpty())
|
||||
if (requiredMigrations.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Migrate the data
|
||||
for (DataMigration dataMigration : requiredMigrations)
|
||||
for (DataMigration dataMigration : requiredMigrations) {
|
||||
dataMigration.migrate(connection, this.dataManagerAbstract.getTablePrefix());
|
||||
}
|
||||
|
||||
// Set the new current migration to be the highest migrated to
|
||||
currentMigration = requiredMigrations
|
||||
.stream()
|
||||
currentMigration = requiredMigrations.stream()
|
||||
.map(DataMigration::getRevision)
|
||||
.max(Integer::compareTo)
|
||||
.orElse(-1);
|
||||
|
@ -4,7 +4,6 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface DatabaseConnector {
|
||||
|
||||
/**
|
||||
* Checks if the connection to the database has been created
|
||||
*
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.songoda.core.database;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -9,7 +8,6 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MySQLConnector implements DatabaseConnector {
|
||||
|
||||
private final Plugin plugin;
|
||||
private HikariDataSource hikari;
|
||||
private boolean initializedSuccessfully;
|
||||
|
@ -8,7 +8,6 @@ import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SQLiteConnector implements DatabaseConnector {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final String connectionString;
|
||||
private Connection connection;
|
||||
@ -19,8 +18,8 @@ public class SQLiteConnector implements DatabaseConnector {
|
||||
|
||||
try {
|
||||
Class.forName("org.sqlite.JDBC"); // This is required to put here for Spigot 1.10 and below to force class load
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,128 +1,140 @@
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.gui.methods.Clickable;
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.anvil.AnvilCore;
|
||||
import com.songoda.core.nms.anvil.CustomAnvil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Anvil GUI for text prompts
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-09-15
|
||||
*/
|
||||
public class AnvilGui extends Gui {
|
||||
|
||||
final Player player;
|
||||
CustomAnvil anvil;
|
||||
List<String> endPrompt = null;
|
||||
|
||||
public AnvilGui(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public AnvilGui(Player player, Gui parent) {
|
||||
super(parent);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnvilGui setAction(@Nullable Clickable action) {
|
||||
return (AnvilGui) setAction(2, action);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnvilGui setAction(@Nullable ClickType type, @Nullable Clickable action) {
|
||||
return (AnvilGui) setAction(2, type, action);
|
||||
}
|
||||
|
||||
protected void open() {
|
||||
anvil.open();
|
||||
}
|
||||
|
||||
public AnvilGui setInput(ItemStack item) {
|
||||
return (AnvilGui) this.setItem(0, item);
|
||||
}
|
||||
|
||||
public ItemStack getInput() {
|
||||
return this.getItem(0);
|
||||
}
|
||||
|
||||
public AnvilGui setOutput(ItemStack item) {
|
||||
return (AnvilGui) this.setItem(2, item);
|
||||
}
|
||||
|
||||
public AnvilGui setOutputPrompt(String str) {
|
||||
endPrompt = Arrays.asList(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnvilGui setOutputPrompt(String... str) {
|
||||
endPrompt = Arrays.asList(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnvilGui setOutputPrompt(List<String> str) {
|
||||
endPrompt = str;
|
||||
return this;
|
||||
}
|
||||
|
||||
void updateOutputPrompt() {
|
||||
final ItemStack in;
|
||||
if (endPrompt != null && (in = cellItems.get(0)) != null) {
|
||||
setItem(2, GuiUtils.createButtonItem(in, endPrompt));
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack getOutput() {
|
||||
return this.getItem(2);
|
||||
}
|
||||
|
||||
public String getInputText() {
|
||||
return anvil != null ? anvil.getRenameText() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Inventory generateInventory(@NotNull GuiManager manager) {
|
||||
this.guiManager = manager;
|
||||
|
||||
createInventory();
|
||||
ItemStack item;
|
||||
if ((item = cellItems.get(0)) != null) {
|
||||
inventory.setItem(0, item);
|
||||
} else if ((item = cellItems.get(1)) != null) {
|
||||
inventory.setItem(1, item);
|
||||
} else if (!acceptsItems) {
|
||||
cellItems.put(0, item = GuiUtils.createButtonItem(CompatibleMaterial.PAPER, " ", " "));
|
||||
inventory.setItem(0, item);
|
||||
}
|
||||
if ((item = cellItems.get(2)) != null) {
|
||||
inventory.setItem(2, item);
|
||||
}
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createInventory() {
|
||||
AnvilCore nms = NmsManager.getAnvil();
|
||||
if (nms != null) {
|
||||
anvil = nms.createAnvil(player, new GuiHolder(guiManager, this));
|
||||
anvil.setCustomTitle(title);
|
||||
anvil.setLevelCost(0);
|
||||
inventory = anvil.getInventory();
|
||||
anvil.setOnChange(this::updateOutputPrompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.gui.methods.Clickable;
|
||||
import com.songoda.core.nms.NmsManager;
|
||||
import com.songoda.core.nms.anvil.AnvilCore;
|
||||
import com.songoda.core.nms.anvil.CustomAnvil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Anvil GUI for text prompts
|
||||
*/
|
||||
public class AnvilGui extends Gui {
|
||||
final Player player;
|
||||
CustomAnvil anvil;
|
||||
List<String> endPrompt = null;
|
||||
|
||||
public AnvilGui(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public AnvilGui(Player player, Gui parent) {
|
||||
super(parent);
|
||||
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnvilGui setAction(@Nullable Clickable action) {
|
||||
return (AnvilGui) setAction(2, action);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnvilGui setAction(@Nullable ClickType type, @Nullable Clickable action) {
|
||||
return (AnvilGui) setAction(2, type, action);
|
||||
}
|
||||
|
||||
protected void open() {
|
||||
anvil.open();
|
||||
}
|
||||
|
||||
public AnvilGui setInput(ItemStack item) {
|
||||
return (AnvilGui) this.setItem(0, item);
|
||||
}
|
||||
|
||||
public ItemStack getInput() {
|
||||
return this.getItem(0);
|
||||
}
|
||||
|
||||
public AnvilGui setOutput(ItemStack item) {
|
||||
return (AnvilGui) this.setItem(2, item);
|
||||
}
|
||||
|
||||
public AnvilGui setOutputPrompt(String str) {
|
||||
endPrompt = Arrays.asList(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnvilGui setOutputPrompt(String... str) {
|
||||
endPrompt = Arrays.asList(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AnvilGui setOutputPrompt(List<String> str) {
|
||||
endPrompt = str;
|
||||
return this;
|
||||
}
|
||||
|
||||
void updateOutputPrompt() {
|
||||
if (endPrompt != null) {
|
||||
ItemStack in = cellItems.get(0);
|
||||
|
||||
if (in != null) {
|
||||
setItem(2, GuiUtils.createButtonItem(in, endPrompt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack getOutput() {
|
||||
return this.getItem(2);
|
||||
}
|
||||
|
||||
public String getInputText() {
|
||||
return anvil != null ? anvil.getRenameText() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Inventory generateInventory(@NotNull GuiManager manager) {
|
||||
this.guiManager = manager;
|
||||
|
||||
createInventory();
|
||||
ItemStack item;
|
||||
if (cellItems.containsKey(0)) {
|
||||
item = cellItems.get(0);
|
||||
|
||||
inventory.setItem(0, item);
|
||||
} else if (cellItems.containsKey(1)) {
|
||||
item = cellItems.get(1);
|
||||
|
||||
inventory.setItem(1, item);
|
||||
} else if (!acceptsItems) {
|
||||
item = GuiUtils.createButtonItem(CompatibleMaterial.PAPER, " ", " ");
|
||||
|
||||
cellItems.put(0, item);
|
||||
inventory.setItem(0, item);
|
||||
}
|
||||
|
||||
if (cellItems.containsKey(2)) {
|
||||
item = cellItems.get(2);
|
||||
|
||||
inventory.setItem(2, item);
|
||||
}
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createInventory() {
|
||||
AnvilCore nms = NmsManager.getAnvil();
|
||||
|
||||
if (nms != null) {
|
||||
anvil = nms.createAnvil(player, new GuiHolder(guiManager, this));
|
||||
anvil.setCustomTitle(title);
|
||||
anvil.setLevelCost(0);
|
||||
|
||||
inventory = anvil.getInventory();
|
||||
|
||||
anvil.setOnChange(this::updateOutputPrompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ public enum BackgroundType {
|
||||
ADVENTURE, END, HUSBANDRY, NETHER, STONE;
|
||||
final String key;
|
||||
|
||||
private BackgroundType() {
|
||||
BackgroundType() {
|
||||
this.key = "minecraft:textures/gui/advancements/backgrounds/" + name().toLowerCase() + ".png";
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -33,12 +33,8 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* TODO: animated buttons
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class Gui {
|
||||
|
||||
protected Inventory inventory;
|
||||
protected String title;
|
||||
protected GuiType inventoryType = GuiType.STANDARD;
|
||||
@ -72,6 +68,7 @@ public class Gui {
|
||||
|
||||
public Gui(@NotNull GuiType type) {
|
||||
this.inventoryType = type;
|
||||
|
||||
switch (type) {
|
||||
case HOPPER:
|
||||
case DISPENSER:
|
||||
@ -79,6 +76,7 @@ public class Gui {
|
||||
break;
|
||||
default:
|
||||
this.rows = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,10 +95,13 @@ public class Gui {
|
||||
|
||||
@NotNull
|
||||
public List<Player> getPlayers() {
|
||||
return inventory == null ? Collections.EMPTY_LIST
|
||||
: inventory.getViewers().stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> (Player) e)
|
||||
if (inventory == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return inventory.getViewers().stream()
|
||||
.filter(Player.class::isInstance)
|
||||
.map(Player.class::cast)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -109,6 +110,7 @@ public class Gui {
|
||||
if (inventory != null && inventory.getViewers().isEmpty()) {
|
||||
open = false;
|
||||
}
|
||||
|
||||
return open;
|
||||
}
|
||||
|
||||
@ -154,9 +156,10 @@ public class Gui {
|
||||
public void exit() {
|
||||
allowClose = true;
|
||||
open = false;
|
||||
|
||||
inventory.getViewers().stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> (Player) e)
|
||||
.filter(Player.class::isInstance)
|
||||
.map(Player.class::cast)
|
||||
.collect(Collectors.toList())
|
||||
.forEach(Player::closeInventory);
|
||||
}
|
||||
@ -166,9 +169,10 @@ public class Gui {
|
||||
*/
|
||||
public void close() {
|
||||
allowClose = true;
|
||||
|
||||
inventory.getViewers().stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> (Player) e)
|
||||
.filter(Player.class::isInstance)
|
||||
.map(Player.class::cast)
|
||||
.collect(Collectors.toList())
|
||||
.forEach(Player::closeInventory);
|
||||
}
|
||||
@ -188,6 +192,7 @@ public class Gui {
|
||||
public Gui setUnlocked(int row, int col) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
unlockedCells.put(cell, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -196,6 +201,7 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
unlockedCells.put(cell, true);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -204,24 +210,29 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
unlockedCells.put(cell, open);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, true);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, boolean open) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, open);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -235,26 +246,35 @@ public class Gui {
|
||||
public Gui setUnlocked(int row, int col, boolean open) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
unlockedCells.put(cell, open);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setTitle(String title) {
|
||||
if (title == null) title = "";
|
||||
if (title == null) {
|
||||
title = "";
|
||||
}
|
||||
|
||||
if (!title.equals(this.title)) {
|
||||
this.title = title;
|
||||
|
||||
if (inventory != null) {
|
||||
// update active inventory
|
||||
List<Player> toUpdate = getPlayers();
|
||||
boolean isAllowClose = allowClose;
|
||||
exit();
|
||||
|
||||
Inventory oldInv = inventory;
|
||||
createInventory();
|
||||
inventory.setContents(oldInv.getContents());
|
||||
|
||||
toUpdate.forEach(player -> player.openInventory(inventory));
|
||||
|
||||
allowClose = isAllowClose;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -270,7 +290,9 @@ public class Gui {
|
||||
break;
|
||||
default:
|
||||
this.rows = Math.max(1, Math.min(6, rows));
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -302,24 +324,29 @@ public class Gui {
|
||||
if (inventory != null && unlockedCells.getOrDefault(cell, false)) {
|
||||
return inventory.getItem(cell);
|
||||
}
|
||||
|
||||
return cellItems.get(cell);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getItem(int row, int col) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
if (inventory != null && unlockedCells.getOrDefault(cell, false)) {
|
||||
return inventory.getItem(cell);
|
||||
}
|
||||
|
||||
return cellItems.get(cell);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setItem(int cell, @Nullable ItemStack item) {
|
||||
cellItems.put(cell, item);
|
||||
|
||||
if (inventory != null && cell >= 0 && cell < inventory.getSize()) {
|
||||
inventory.setItem(cell, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -332,36 +359,48 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui mirrorFill(int row, int col, boolean mirrorRow, boolean mirrorCol, ItemStack item) {
|
||||
setItem(row, col, item);
|
||||
if (mirrorRow)
|
||||
|
||||
if (mirrorRow) {
|
||||
setItem(rows - row - 1, col, item);
|
||||
if (mirrorCol)
|
||||
}
|
||||
|
||||
if (mirrorCol) {
|
||||
setItem(row, 8 - col, item);
|
||||
if (mirrorRow && mirrorCol)
|
||||
}
|
||||
|
||||
if (mirrorRow && mirrorCol) {
|
||||
setItem(rows - row - 1, 8 - col, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui highlightItem(int cell) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, ItemUtils.addGlow(item));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui highlightItem(int row, int col) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
return highlightItem(cell);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui removeHighlight(int cell) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, ItemUtils.removeGlow(item));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -379,9 +418,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItemLore(int cell, @NotNull String... lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItemLore(item, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -393,9 +434,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItemLore(int cell, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItemLore(item, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -407,9 +450,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItemName(int cell, @Nullable String name) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItemName(item, name));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -431,9 +476,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull String name, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, name, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -445,9 +492,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull ItemStack itemTo, @Nullable String title, @NotNull String... lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -459,9 +508,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable String... lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -473,9 +524,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull ItemStack itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -487,9 +540,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -522,15 +577,18 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
setConditional(cell, null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setActionForRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, @Nullable Clickable action) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
setConditional(cell, null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -539,15 +597,18 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
setConditional(cell, type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setActionForRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
setConditional(cell, type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -566,14 +627,17 @@ public class Gui {
|
||||
public Gui setButton(int cell, ItemStack item, @Nullable Clickable action) {
|
||||
setItem(cell, item);
|
||||
setConditional(cell, null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(int row, int col, @Nullable ItemStack item, @Nullable Clickable action) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
setItem(cell, item);
|
||||
setConditional(cell, null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -581,19 +645,22 @@ public class Gui {
|
||||
public Gui setButton(int cell, @Nullable ItemStack item, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
setItem(cell, item);
|
||||
setConditional(cell, type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(int row, int col, @Nullable ItemStack item, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
setItem(cell, item);
|
||||
setConditional(cell, type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void setConditional(int cell, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
Map<ClickType, Clickable> conditionals = conditionalButtons.computeIfAbsent(cell, k -> new HashMap());
|
||||
Map<ClickType, Clickable> conditionals = conditionalButtons.computeIfAbsent(cell, k -> new HashMap<>());
|
||||
conditionals.put(type, action);
|
||||
}
|
||||
|
||||
@ -632,8 +699,9 @@ public class Gui {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
if (inventory != null)
|
||||
if (inventory != null) {
|
||||
inventory.clear();
|
||||
}
|
||||
|
||||
setActionForRange(0, 53, null);
|
||||
cellItems.clear();
|
||||
@ -645,9 +713,11 @@ public class Gui {
|
||||
nextPageItem = cellItems.get(cell);
|
||||
nextPageIndex = cell;
|
||||
nextPage = item;
|
||||
|
||||
if (page < pages) {
|
||||
setButton(nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -661,9 +731,11 @@ public class Gui {
|
||||
prevPageItem = cellItems.get(cell);
|
||||
prevPageIndex = cell;
|
||||
prevPage = item;
|
||||
|
||||
if (page > 1) {
|
||||
setButton(prevPageIndex, prevPage, ClickType.LEFT, (event) -> this.prevPage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -674,6 +746,7 @@ public class Gui {
|
||||
|
||||
public void setPages(int pages) {
|
||||
this.pages = Math.max(1, pages);
|
||||
|
||||
if (page > pages) {
|
||||
setPage(pages);
|
||||
}
|
||||
@ -682,8 +755,10 @@ public class Gui {
|
||||
public void setPage(int page) {
|
||||
int lastPage = this.page;
|
||||
this.page = Math.max(1, Math.min(pages, page));
|
||||
|
||||
if (pager != null && this.page != lastPage) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
@ -692,8 +767,10 @@ public class Gui {
|
||||
public void changePage(int direction) {
|
||||
int lastPage = page;
|
||||
this.page = Math.max(1, Math.min(pages, page + direction));
|
||||
|
||||
if (pager != null && this.page != lastPage) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
@ -703,6 +780,7 @@ public class Gui {
|
||||
if (page < pages) {
|
||||
int lastPage = page;
|
||||
++page;
|
||||
|
||||
// page switch events
|
||||
if (pager != null) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
@ -721,6 +799,7 @@ public class Gui {
|
||||
if (page > 1) {
|
||||
int lastPage = page;
|
||||
--page;
|
||||
|
||||
if (pager != null) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
|
||||
@ -743,6 +822,7 @@ public class Gui {
|
||||
this.clearActions(prevPageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextPage != null) {
|
||||
if (pages > 1 && page != pages) {
|
||||
this.setButton(nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
@ -764,6 +844,7 @@ public class Gui {
|
||||
final int cells = rows * inventoryType.columns;
|
||||
|
||||
createInventory();
|
||||
|
||||
for (int i = 0; i < cells; ++i) {
|
||||
final ItemStack item = cellItems.get(i);
|
||||
inventory.setItem(i, item != null ? item : (unlockedCells.getOrDefault(i, false) ? AIR : blankItem));
|
||||
@ -784,6 +865,7 @@ public class Gui {
|
||||
default:
|
||||
inventory = new GuiHolder(guiManager, this).newInventory(rows * 9,
|
||||
title == null ? "" : trimTitle(title));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -793,8 +875,9 @@ public class Gui {
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (inventory == null)
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int cells = rows * inventoryType.columns;
|
||||
for (int i = 0; i < cells; ++i) {
|
||||
@ -806,9 +889,12 @@ public class Gui {
|
||||
protected static String trimTitle(String title) {
|
||||
if (title == null) {
|
||||
return "";
|
||||
} else if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8) && title.length() > 32) {
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8) && title.length() > 32) {
|
||||
return title.charAt(30) == '\u00A7' ? title.substring(0, 30) : title.substring(0, 31);
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
@ -819,6 +905,7 @@ public class Gui {
|
||||
protected boolean onClick(@NotNull GuiManager manager, @NotNull Player player, @NotNull Inventory inventory, @NotNull InventoryClickEvent event) {
|
||||
final int cell = event.getSlot();
|
||||
Map<ClickType, Clickable> conditionals = conditionalButtons.get(cell);
|
||||
|
||||
Clickable button;
|
||||
if (conditionals != null
|
||||
&& ((button = conditionals.get(event.getClick())) != null || (button = conditionals.get(null)) != null)) {
|
||||
@ -829,12 +916,15 @@ public class Gui {
|
||||
// this is a default action, not a triggered action
|
||||
defaultClicker.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
}
|
||||
|
||||
if (privateDefaultClicker != null) {
|
||||
// this is a private default action, not a triggered action
|
||||
privateDefaultClicker.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -846,6 +936,7 @@ public class Gui {
|
||||
public void onOpen(@NotNull GuiManager manager, @NotNull Player player) {
|
||||
open = true;
|
||||
guiManager = manager;
|
||||
|
||||
if (opener != null) {
|
||||
opener.onOpen(new GuiOpenEvent(manager, this, player));
|
||||
}
|
||||
@ -856,10 +947,13 @@ public class Gui {
|
||||
manager.showGUI(player, this);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean showParent = open && parent != null;
|
||||
|
||||
if (closer != null) {
|
||||
closer.onClose(new GuiCloseEvent(manager, this, player));
|
||||
}
|
||||
|
||||
if (showParent) {
|
||||
manager.showGUI(player, parent);
|
||||
}
|
||||
|
@ -1,40 +1,36 @@
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Internal class for marking an inventory as a GUI inventory
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
class GuiHolder implements InventoryHolder {
|
||||
|
||||
final Gui gui;
|
||||
final GuiManager manager;
|
||||
|
||||
public GuiHolder(GuiManager manager, Gui gui) {
|
||||
this.gui = gui;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return gui.inventory;
|
||||
}
|
||||
|
||||
public Gui getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public Inventory newInventory(int size, String title) {
|
||||
return Bukkit.createInventory(this, size, title);
|
||||
}
|
||||
|
||||
public Inventory newInventory(InventoryType type, String title) {
|
||||
return Bukkit.createInventory(this, type, title);
|
||||
}
|
||||
}
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
/**
|
||||
* Internal class for marking an inventory as a GUI inventory
|
||||
*/
|
||||
class GuiHolder implements InventoryHolder {
|
||||
final Gui gui;
|
||||
final GuiManager manager;
|
||||
|
||||
public GuiHolder(GuiManager manager, Gui gui) {
|
||||
this.gui = gui;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return gui.inventory;
|
||||
}
|
||||
|
||||
public Gui getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public Inventory newInventory(int size, String title) {
|
||||
return Bukkit.createInventory(this, size, title);
|
||||
}
|
||||
|
||||
public Inventory newInventory(InventoryType type, String title) {
|
||||
return Bukkit.createInventory(this, type, title);
|
||||
}
|
||||
}
|
||||
|
@ -1,275 +1,300 @@
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.compatibility.ClientVersion;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.ServerVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Manages events for GUI screens
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class GuiManager {
|
||||
|
||||
final Plugin plugin;
|
||||
final UUID uuid = UUID.randomUUID(); // manager tracking to fix weird bugs from lazy programming
|
||||
final GuiListener listener = new GuiListener(this);
|
||||
final Map<Player, Gui> openInventories = new HashMap();
|
||||
private final Object lock = new Object();
|
||||
private boolean initialized = false;
|
||||
private boolean shutdown = false;
|
||||
|
||||
public GuiManager(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the GUI handlers
|
||||
*/
|
||||
public void init() {
|
||||
Bukkit.getPluginManager().registerEvents(listener, plugin);
|
||||
initialized = true;
|
||||
shutdown = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this manager cannot open any more GUI screens
|
||||
*
|
||||
* @return true if the owning plugin has shutdown
|
||||
*/
|
||||
public boolean isClosed() {
|
||||
return shutdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and display a GUI interface for a player
|
||||
*
|
||||
* @param player player to open the interface for
|
||||
* @param gui GUI to use
|
||||
*/
|
||||
public void showGUI(Player player, Gui gui) {
|
||||
if (shutdown) {
|
||||
if (plugin.isEnabled()) {
|
||||
// recover if reloaded without calling init manually
|
||||
init();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (!initialized) {
|
||||
init();
|
||||
}
|
||||
if (gui instanceof AnvilGui) {
|
||||
// bukkit throws a fit now if you try to set anvil stuff asynchronously
|
||||
Gui openInv = openInventories.get(player);
|
||||
if (openInv != null) {
|
||||
openInv.open = false;
|
||||
}
|
||||
gui.getOrCreateInventory(this);
|
||||
((AnvilGui) gui).open();
|
||||
gui.onOpen(this, player);
|
||||
synchronized (lock) {
|
||||
openInventories.put(player, gui);
|
||||
}
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
Gui openInv = openInventories.get(player);
|
||||
if (openInv != null) {
|
||||
openInv.open = false;
|
||||
}
|
||||
Inventory inv = gui.getOrCreateInventory(this);
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
player.openInventory(inv);
|
||||
gui.onOpen(this, player);
|
||||
synchronized (lock) {
|
||||
openInventories.put(player, gui);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message) {
|
||||
showPopup(player, message, CompatibleMaterial.NETHER_STAR, BackgroundType.ADVENTURE);
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message, CompatibleMaterial icon) {
|
||||
showPopup(player, message, icon, BackgroundType.ADVENTURE);
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message, CompatibleMaterial icon, BackgroundType background) {
|
||||
if (ClientVersion.getClientVersion(player).isAtLeast(ServerVersion.V1_12)) {
|
||||
PopupMessage popup = new PopupMessage(plugin, icon, message, background);
|
||||
popup.add();
|
||||
popup.grant(player);
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
|
||||
popup.revoke(player);
|
||||
popup.remove();
|
||||
}, 70);
|
||||
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
|
||||
player.sendTitle("", message, 10, 70, 10);
|
||||
} else {
|
||||
player.sendTitle("", message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all active GUIs
|
||||
*/
|
||||
public void closeAll() {
|
||||
synchronized (lock) {
|
||||
openInventories.entrySet().stream()
|
||||
.filter(e -> e.getKey().getOpenInventory().getTopInventory().getHolder() instanceof GuiHolder)
|
||||
.collect(Collectors.toList()) // to prevent concurrency exceptions
|
||||
.forEach(e -> e.getKey().closeInventory());
|
||||
openInventories.clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class GuiListener implements Listener {
|
||||
|
||||
final GuiManager manager;
|
||||
|
||||
public GuiListener(GuiManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onDragGUI(InventoryDragEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory openInv = event.getInventory();
|
||||
Gui gui;
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (event.getRawSlots().stream().filter(slot -> gui.inventory.getSize() > slot).anyMatch(slot -> !gui.unlockedCells.getOrDefault(slot, false))) {
|
||||
event.setCancelled(true);
|
||||
event.setResult(Result.DENY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onClickGUI(InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory openInv = event.getInventory();
|
||||
final Player player = (Player) event.getWhoClicked();
|
||||
|
||||
Gui gui;
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (event.getClick() == ClickType.DOUBLE_CLICK) {
|
||||
// always cancel this event if there are matching gui elements, since it tends to do bad things
|
||||
ItemStack clicked = event.getCursor();
|
||||
if (clicked != null && clicked.getType() != Material.AIR) {
|
||||
int cell = 0;
|
||||
for (ItemStack it : gui.inventory.getContents()) {
|
||||
if (!gui.unlockedCells.getOrDefault(cell++, false) && clicked.isSimilar(it)) {
|
||||
event.setCancelled(true);
|
||||
if (gui instanceof AnvilGui) {
|
||||
((AnvilGui) gui).anvil.update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getSlotType() == SlotType.OUTSIDE) {
|
||||
if (!gui.onClickOutside(manager, player, event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} // did we click the gui or in the user's inventory?
|
||||
else if (event.getRawSlot() < gui.inventory.getSize()) {// or could use event.getClickedInventory() == gui.inventory
|
||||
// allow event if this is not a GUI element
|
||||
event.setCancelled(gui.unlockedCells.entrySet().stream().noneMatch(e -> event.getSlot() == e.getKey() && e.getValue()));
|
||||
// process button press
|
||||
if (gui.onClick(manager, player, openInv, event)) {
|
||||
player.playSound(player.getLocation(), gui.getDefaultSound().getSound(), 1F, 1F);
|
||||
}
|
||||
} else {
|
||||
// Player clicked in the bottom inventory while GUI is open
|
||||
if (gui.onClickPlayerInventory(manager, player, openInv, event)) {
|
||||
player.playSound(player.getLocation(), gui.getDefaultSound().getSound(), 1F, 1F);
|
||||
} else if (!gui.acceptsItems || event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
|
||||
event.setCancelled(true);
|
||||
if (gui instanceof AnvilGui) {
|
||||
((AnvilGui) gui).anvil.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onCloseGUI(InventoryCloseEvent event) {
|
||||
Inventory openInv = event.getInventory();
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
Gui gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
if (gui instanceof AnvilGui) {
|
||||
gui.inventory.clear();
|
||||
gui.inventory = null;
|
||||
}
|
||||
if (!gui.open) {
|
||||
return;
|
||||
}
|
||||
final Player player = (Player) event.getPlayer();
|
||||
if (!gui.allowDropItems) {
|
||||
player.setItemOnCursor(null);
|
||||
}
|
||||
if (manager.shutdown) {
|
||||
gui.onClose(manager, player);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskLater(manager.plugin, () -> gui.onClose(manager, player), 1);
|
||||
}
|
||||
manager.openInventories.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
void onDisable(PluginDisableEvent event) {
|
||||
if (event.getPlugin() == manager.plugin) {
|
||||
// uh-oh! Abandon ship!!
|
||||
manager.shutdown = true;
|
||||
manager.closeAll();
|
||||
manager.initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.compatibility.ClientVersion;
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.compatibility.ServerVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Manages events for GUI screens
|
||||
*/
|
||||
public class GuiManager {
|
||||
final Plugin plugin;
|
||||
final UUID uuid = UUID.randomUUID(); // manager tracking to fix weird bugs from lazy programming
|
||||
final GuiListener listener = new GuiListener(this);
|
||||
final Map<Player, Gui> openInventories = new HashMap<>();
|
||||
private final Object lock = new Object();
|
||||
private boolean initialized = false;
|
||||
private boolean shutdown = false;
|
||||
|
||||
public GuiManager(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the GUI handlers
|
||||
*/
|
||||
public void init() {
|
||||
Bukkit.getPluginManager().registerEvents(listener, plugin);
|
||||
|
||||
initialized = true;
|
||||
shutdown = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this manager cannot open any more GUI screens
|
||||
*
|
||||
* @return true if the owning plugin has shutdown
|
||||
*/
|
||||
public boolean isClosed() {
|
||||
return shutdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and display a GUI interface for a player
|
||||
*
|
||||
* @param player player to open the interface for
|
||||
* @param gui GUI to use
|
||||
*/
|
||||
public void showGUI(Player player, Gui gui) {
|
||||
if (shutdown) {
|
||||
if (!plugin.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// recover if reloaded without calling init manually
|
||||
init();
|
||||
} else if (!initialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
// bukkit throws a fit now if you try to set anvil stuff asynchronously
|
||||
Gui openInv = openInventories.get(player);
|
||||
|
||||
if (openInv != null) {
|
||||
openInv.open = false;
|
||||
}
|
||||
|
||||
gui.getOrCreateInventory(this);
|
||||
((AnvilGui) gui).open();
|
||||
gui.onOpen(this, player);
|
||||
|
||||
synchronized (lock) {
|
||||
openInventories.put(player, gui);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
Gui openInv = openInventories.get(player);
|
||||
|
||||
if (openInv != null) {
|
||||
openInv.open = false;
|
||||
}
|
||||
|
||||
Inventory inv = gui.getOrCreateInventory(this);
|
||||
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
player.openInventory(inv);
|
||||
gui.onOpen(this, player);
|
||||
|
||||
synchronized (lock) {
|
||||
openInventories.put(player, gui);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message) {
|
||||
showPopup(player, message, CompatibleMaterial.NETHER_STAR, BackgroundType.ADVENTURE);
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message, CompatibleMaterial icon) {
|
||||
showPopup(player, message, icon, BackgroundType.ADVENTURE);
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message, CompatibleMaterial icon, BackgroundType background) {
|
||||
if (ClientVersion.getClientVersion(player).isAtLeast(ServerVersion.V1_12)) {
|
||||
PopupMessage popup = new PopupMessage(plugin, icon, message, background);
|
||||
popup.add();
|
||||
popup.grant(player);
|
||||
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
|
||||
popup.revoke(player);
|
||||
popup.remove();
|
||||
}, 70);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
|
||||
player.sendTitle("", message, 10, 70, 10);
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendTitle("", message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all active GUIs
|
||||
*/
|
||||
public void closeAll() {
|
||||
synchronized (lock) {
|
||||
openInventories.entrySet().stream()
|
||||
.filter(e -> e.getKey().getOpenInventory().getTopInventory().getHolder() instanceof GuiHolder)
|
||||
.collect(Collectors.toList()) // to prevent concurrency exceptions
|
||||
.forEach(e -> e.getKey().closeInventory());
|
||||
|
||||
openInventories.clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class GuiListener implements Listener {
|
||||
final GuiManager manager;
|
||||
|
||||
public GuiListener(GuiManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onDragGUI(InventoryDragEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory openInv = event.getInventory();
|
||||
Gui gui;
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (event.getRawSlots().stream()
|
||||
.filter(slot -> gui.inventory.getSize() > slot)
|
||||
.anyMatch(slot -> !gui.unlockedCells.getOrDefault(slot, false))) {
|
||||
event.setCancelled(true);
|
||||
event.setResult(Result.DENY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onClickGUI(InventoryClickEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory openInv = event.getInventory();
|
||||
final Player player = (Player) event.getWhoClicked();
|
||||
|
||||
Gui gui;
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder &&
|
||||
((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (event.getClick() == ClickType.DOUBLE_CLICK) {
|
||||
// always cancel this event if there are matching gui elements, since it tends to do bad things
|
||||
ItemStack clicked = event.getCursor();
|
||||
if (clicked != null && clicked.getType() != Material.AIR) {
|
||||
int cell = 0;
|
||||
for (ItemStack it : gui.inventory.getContents()) {
|
||||
if (!gui.unlockedCells.getOrDefault(cell++, false) && clicked.isSimilar(it)) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
((AnvilGui) gui).anvil.update();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getSlotType() == SlotType.OUTSIDE) {
|
||||
if (!gui.onClickOutside(manager, player, event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} // did we click the gui or in the user's inventory?
|
||||
else if (event.getRawSlot() < gui.inventory.getSize()) { // or could use event.getClickedInventory() == gui.inventory
|
||||
// allow event if this is not a GUI element
|
||||
event.setCancelled(gui.unlockedCells.entrySet().stream().noneMatch(e -> event.getSlot() == e.getKey() && e.getValue()));
|
||||
|
||||
// process button press
|
||||
if (gui.onClick(manager, player, openInv, event)) {
|
||||
player.playSound(player.getLocation(), gui.getDefaultSound().getSound(), 1F, 1F);
|
||||
}
|
||||
} else {
|
||||
// Player clicked in the bottom inventory while GUI is open
|
||||
if (gui.onClickPlayerInventory(manager, player, openInv, event)) {
|
||||
player.playSound(player.getLocation(), gui.getDefaultSound().getSound(), 1F, 1F);
|
||||
} else if (!gui.acceptsItems || event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
((AnvilGui) gui).anvil.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onCloseGUI(InventoryCloseEvent event) {
|
||||
Inventory openInv = event.getInventory();
|
||||
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder &&
|
||||
((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
Gui gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
gui.inventory.clear();
|
||||
gui.inventory = null;
|
||||
}
|
||||
|
||||
if (!gui.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = (Player) event.getPlayer();
|
||||
if (!gui.allowDropItems) {
|
||||
player.setItemOnCursor(null);
|
||||
}
|
||||
|
||||
if (manager.shutdown) {
|
||||
gui.onClose(manager, player);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskLater(manager.plugin, () -> gui.onClose(manager, player), 1);
|
||||
}
|
||||
|
||||
manager.openInventories.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
void onDisable(PluginDisableEvent event) {
|
||||
if (event.getPlugin() == manager.plugin) {
|
||||
// uh-oh! Abandon ship!!
|
||||
manager.shutdown = true;
|
||||
manager.closeAll();
|
||||
manager.initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package com.songoda.core.gui;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
|
||||
public enum GuiType {
|
||||
|
||||
STANDARD(InventoryType.CHEST, 6, 9),
|
||||
DISPENSER(InventoryType.DISPENSER, 9, 3),
|
||||
HOPPER(InventoryType.HOPPER, 5, 1);
|
||||
@ -12,7 +11,7 @@ public enum GuiType {
|
||||
protected final int rows;
|
||||
protected final int columns;
|
||||
|
||||
private GuiType(InventoryType type, int rows, int columns) {
|
||||
GuiType(InventoryType type, int rows, int columns) {
|
||||
this.type = type;
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
|
@ -10,32 +10,33 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jascotty2
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class GuiUtils {
|
||||
|
||||
public static ItemStack getBorderGlassItem() {
|
||||
ItemStack glass = CompatibleMaterial.LIGHT_BLUE_STAINED_GLASS_PANE.getItem();
|
||||
ItemMeta glassmeta = glass.getItemMeta();
|
||||
|
||||
glassmeta.setDisplayName(ChatColor.BLACK.toString());
|
||||
glass.setItemMeta(glassmeta);
|
||||
|
||||
return glass;
|
||||
}
|
||||
|
||||
public static ItemStack getBorderItem(ItemStack item) {
|
||||
ItemMeta glassmeta = item.getItemMeta();
|
||||
|
||||
glassmeta.setDisplayName(ChatColor.BLACK.toString());
|
||||
item.setItemMeta(glassmeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack getBorderItem(CompatibleMaterial mat) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta glassmeta = item.getItemMeta();
|
||||
|
||||
glassmeta.setDisplayName(ChatColor.BLACK.toString());
|
||||
item.setItemMeta(glassmeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -52,198 +53,248 @@ public class GuiUtils {
|
||||
*/
|
||||
public static List<String> getSafeLore(List<String> lines) {
|
||||
// fix newlines
|
||||
ArrayList<String> newLore = new ArrayList();
|
||||
ArrayList<String> newLore = new ArrayList<>();
|
||||
|
||||
for (String l : lines) {
|
||||
for (String l2 : l.split("\n")) {
|
||||
if (l2.length() < 54) {
|
||||
newLore.add(l2);
|
||||
} else {
|
||||
// try to shorten the string
|
||||
String shorterString = l2;
|
||||
ChatColor lastColor = null; // todo? probably should also track formatting codes..
|
||||
int line = 0;
|
||||
while (shorterString.length() > 50) {
|
||||
int breakingSpace = -1;
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
if (shorterString.charAt(i) == ChatColor.COLOR_CHAR) {
|
||||
lastColor = ChatColor.getByChar(shorterString.charAt(++i));
|
||||
} else if (shorterString.charAt(i) == ' ' || shorterString.charAt(i) == '-') {
|
||||
breakingSpace = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// try to shorten the string
|
||||
String shorterString = l2;
|
||||
ChatColor lastColor = null; // todo? probably should also track formatting codes..
|
||||
int line = 0;
|
||||
while (shorterString.length() > 50) {
|
||||
int breakingSpace = -1;
|
||||
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
if (shorterString.charAt(i) == ChatColor.COLOR_CHAR) {
|
||||
lastColor = ChatColor.getByChar(shorterString.charAt(++i));
|
||||
} else if (shorterString.charAt(i) == ' ' || shorterString.charAt(i) == '-') {
|
||||
breakingSpace = i;
|
||||
}
|
||||
if (breakingSpace == -1) {
|
||||
breakingSpace = Math.max(50, shorterString.length());
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
|
||||
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
|
||||
} else {
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace));
|
||||
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
|
||||
}
|
||||
++line;
|
||||
}
|
||||
if (!shorterString.isEmpty()) {
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + " " + shorterString);
|
||||
|
||||
if (breakingSpace == -1) {
|
||||
breakingSpace = Math.max(50, shorterString.length());
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
|
||||
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
|
||||
} else {
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace));
|
||||
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
|
||||
}
|
||||
|
||||
++line;
|
||||
}
|
||||
|
||||
if (!shorterString.isEmpty()) {
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + " " + shorterString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newLore;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, String... lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, String... lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, String title, String... lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, List<String> lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, List<String> lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, String title, List<String> lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, String[] lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String[] lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, String[] lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, List<String> lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -251,81 +302,101 @@ public class GuiUtils {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, List<String> lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItem(ItemStack item, String title, String... lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItemName(ItemStack item, String title) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItemLore(ItemStack item, String... lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItemLore(ItemStack item, List<String> lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -333,16 +404,21 @@ public class GuiUtils {
|
||||
if (!matTo.matches(item)) {
|
||||
item = matTo.getItem();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -350,30 +426,39 @@ public class GuiUtils {
|
||||
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
|
||||
item = to.clone();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItem(ItemStack item, String title, List<String> lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -381,16 +466,21 @@ public class GuiUtils {
|
||||
if (!matTo.matches(item)) {
|
||||
item = matTo.getItem();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -398,16 +488,21 @@ public class GuiUtils {
|
||||
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
|
||||
item = to.clone();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
meta.setLore(Collections.emptyList());
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,8 @@ import java.util.UUID;
|
||||
* Calling this class on anything below 1.12 will cause ClassLoader Exceptions!
|
||||
*/
|
||||
class PopupMessage {
|
||||
|
||||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final HashSet<UUID> registeredMessages = new HashSet();
|
||||
private static final HashSet<UUID> registeredMessages = new HashSet<>();
|
||||
|
||||
final UUID id = UUID.randomUUID();
|
||||
private final NamespacedKey key;
|
||||
@ -52,14 +51,18 @@ class PopupMessage {
|
||||
private String getJSON() {
|
||||
JsonObject json = new JsonObject();
|
||||
JsonObject advDisplay = new JsonObject();
|
||||
|
||||
if (this.icon != null) {
|
||||
JsonObject displayIcon = new JsonObject();
|
||||
displayIcon.addProperty("item", "minecraft:" + this.icon.getMaterial().name().toLowerCase());
|
||||
|
||||
if (this.icon.usesData()) {
|
||||
displayIcon.addProperty("data", this.icon.getData());
|
||||
}
|
||||
|
||||
advDisplay.add("icon", displayIcon);
|
||||
}
|
||||
|
||||
advDisplay.add("title", gson.fromJson(ComponentSerializer.toString(this.title), JsonElement.class));
|
||||
advDisplay.addProperty("background", background.key);
|
||||
advDisplay.addProperty("description", "");
|
||||
@ -88,24 +91,31 @@ class PopupMessage {
|
||||
final Advancement adv = getAdvancement();
|
||||
final AdvancementProgress progress = pl.getAdvancementProgress(adv);
|
||||
|
||||
if (!progress.isDone())
|
||||
progress.getRemainingCriteria().forEach((crit) -> progress.awardCriteria(crit));
|
||||
if (!progress.isDone()) {
|
||||
for (String s : progress.getRemainingCriteria()) {
|
||||
progress.awardCriteria(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void revoke(final Player pl) {
|
||||
final Advancement adv = getAdvancement();
|
||||
final AdvancementProgress prog = pl.getAdvancementProgress(adv);
|
||||
|
||||
if (prog.isDone())
|
||||
prog.getAwardedCriteria().forEach((crit) -> prog.revokeCriteria(crit));
|
||||
if (prog.isDone()) {
|
||||
for (String s : prog.getAwardedCriteria()) {
|
||||
prog.revokeCriteria(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void add() {
|
||||
if (!registeredMessages.contains(id)) {
|
||||
registeredMessages.add(id);
|
||||
|
||||
try {
|
||||
Bukkit.getUnsafe().loadAdvancement(key, getJSON());
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Bukkit.getLogger().warning("Failed to create popup advancement!");
|
||||
}
|
||||
}
|
||||
@ -122,18 +132,19 @@ class PopupMessage {
|
||||
return Bukkit.getAdvancement(key);
|
||||
}
|
||||
|
||||
public static enum FrameType {
|
||||
public enum FrameType {
|
||||
TASK,
|
||||
CHALLENGE,
|
||||
GOAL;
|
||||
|
||||
final String id;
|
||||
|
||||
private FrameType() {
|
||||
FrameType() {
|
||||
id = name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public static enum TriggerType {
|
||||
public enum TriggerType {
|
||||
ARBITRARY_PLAYER_TICK(ServerVersion.V1_13, "TICK"),
|
||||
BRED_ANIMALS,
|
||||
BREWED_POTION,
|
||||
@ -163,17 +174,18 @@ class PopupMessage {
|
||||
USED_ENDER_EYE,
|
||||
USED_TOTEM,
|
||||
VILLAGER_TRADE;
|
||||
|
||||
final ServerVersion minVersion;
|
||||
final String compatible;
|
||||
final String key;
|
||||
|
||||
private TriggerType() {
|
||||
TriggerType() {
|
||||
this.minVersion = ServerVersion.UNKNOWN;
|
||||
this.compatible = "";
|
||||
this.key = "minecraft:" + name().toLowerCase();
|
||||
}
|
||||
|
||||
private TriggerType(ServerVersion minVersion, String compatible) {
|
||||
TriggerType(ServerVersion minVersion, String compatible) {
|
||||
this.minVersion = minVersion;
|
||||
this.compatible = compatible;
|
||||
this.key = "minecraft:" + (ServerVersion.isServerVersionAtLeast(minVersion) ? name() : compatible).toLowerCase();
|
||||
|
@ -1,225 +1,235 @@
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.gui.events.GuiClickEvent;
|
||||
import com.songoda.core.gui.methods.Clickable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Paged GUI for when you aren't going to be making too many pages
|
||||
*
|
||||
* @author jascotty2
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class SimplePagedGui extends Gui {
|
||||
|
||||
protected boolean useHeader;
|
||||
private int rowsPerPage, maxCellSlot;
|
||||
protected ItemStack headerBackItem;
|
||||
protected ItemStack footerBackItem;
|
||||
final int nextPageIndex = 4, prevPageIndex = 6;
|
||||
|
||||
public SimplePagedGui() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public SimplePagedGui(Gui parent) {
|
||||
super(parent);
|
||||
|
||||
nextPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Next Page");
|
||||
prevPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Previous Page");
|
||||
}
|
||||
|
||||
public SimplePagedGui setUseHeader(boolean useHeader) {
|
||||
this.useHeader = useHeader;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack getHeaderBackItem() {
|
||||
return headerBackItem;
|
||||
}
|
||||
|
||||
public SimplePagedGui setHeaderBackItem(ItemStack headerBackItem) {
|
||||
this.headerBackItem = headerBackItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack getFooterBackItem() {
|
||||
return footerBackItem;
|
||||
}
|
||||
|
||||
public SimplePagedGui setFooterBackItem(ItemStack footerBackItem) {
|
||||
this.footerBackItem = footerBackItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimplePagedGui setItem(int row, int col, ItemStack item) {
|
||||
return setItem(col + row * 9, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimplePagedGui setItem(int cell, ItemStack item) {
|
||||
// set the cell relative to the current page
|
||||
int cellIndex = cell < 0 ? cell : (page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9)));
|
||||
|
||||
cellItems.put(cellIndex, item);
|
||||
if (open && cell >= 0 && cell < inventory.getSize()) {
|
||||
inventory.setItem(cell, item);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextPage() {
|
||||
if (page < pages) {
|
||||
++page;
|
||||
showPage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prevPage() {
|
||||
if (page > 1) {
|
||||
--page;
|
||||
showPage();
|
||||
}
|
||||
}
|
||||
|
||||
public void showPage() {
|
||||
int startCell = useHeader ? 9 : 0;
|
||||
int cellIndex = startCell + (page - 1) * (rowsPerPage * 9);
|
||||
|
||||
for (int i = startCell; i < (rows - 1) * 9; ++i) {
|
||||
final ItemStack item = cellItems.get(cellIndex++);
|
||||
inventory.setItem(i, item != null ? item : blankItem);
|
||||
}
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updatePageNavigation() {
|
||||
if (page > 1) {
|
||||
inventory.setItem(inventory.getSize() - prevPageIndex, prevPage);
|
||||
this.setButton(-prevPageIndex, prevPage, ClickType.LEFT, (event) -> this.prevPage());
|
||||
} else {
|
||||
inventory.setItem(inventory.getSize() - prevPageIndex, footerBackItem != null ? footerBackItem : blankItem);
|
||||
this.setItem(-prevPageIndex, null);
|
||||
this.clearActions(-prevPageIndex);
|
||||
}
|
||||
if (pages > 1 && page != pages) {
|
||||
inventory.setItem(inventory.getSize() - nextPageIndex, nextPage);
|
||||
this.setButton(-nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
} else {
|
||||
inventory.setItem(inventory.getSize() - nextPageIndex, footerBackItem != null ? footerBackItem : blankItem);
|
||||
this.setItem(-nextPageIndex, null);
|
||||
this.clearActions(-nextPageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Inventory generateInventory(GuiManager manager) {
|
||||
this.guiManager = manager;
|
||||
// calculate pages here
|
||||
rowsPerPage = useHeader ? 4 : 5;
|
||||
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
|
||||
int maxRows = (int) Math.ceil(maxCellSlot / 9.);
|
||||
pages = (int) Math.max(1, Math.ceil(maxRows / (double) rowsPerPage));
|
||||
this.setRows(maxRows + (useHeader ? 1 : 0));
|
||||
|
||||
// create inventory view
|
||||
createInventory();
|
||||
|
||||
// populate and return the display inventory
|
||||
setPage(Math.min(page, pages));
|
||||
update();
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createInventory() {
|
||||
final int cells = rows * 9;
|
||||
inventory = Bukkit.getServer().createInventory(new GuiHolder(guiManager, this), cells,
|
||||
title == null ? "" : trimTitle(title));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate pages here
|
||||
rowsPerPage = useHeader ? 4 : 5;
|
||||
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
|
||||
int maxRows = Math.max((useHeader ? 1 : 0), (int) Math.ceil(maxCellSlot / 9.));
|
||||
pages = (int) Math.ceil(maxRows / rowsPerPage);
|
||||
|
||||
// create a new inventory if needed
|
||||
List<Player> toUpdate = null;
|
||||
if (Math.min(54, (maxRows + (useHeader ? 1 : 0)) * 9) != inventory.getSize()) {
|
||||
toUpdate = getPlayers();
|
||||
this.setRows(maxRows + (useHeader ? 1 : 0));
|
||||
createInventory();
|
||||
}
|
||||
|
||||
// populate header
|
||||
if (useHeader) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
final ItemStack item = cellItems.get(i);
|
||||
inventory.setItem(i, item != null ? item : (headerBackItem != null ? headerBackItem : blankItem));
|
||||
}
|
||||
}
|
||||
|
||||
// last row is dedicated to pagation
|
||||
final int cells = rows * 9;
|
||||
for (int i = cells - 9; i < cells; ++i) {
|
||||
inventory.setItem(i, footerBackItem != null ? footerBackItem : blankItem);
|
||||
}
|
||||
|
||||
// fill out the rest of the page
|
||||
showPage();
|
||||
|
||||
// did we need to change the display window size?
|
||||
if (toUpdate != null) {
|
||||
// whoopsie!
|
||||
exit();
|
||||
toUpdate.forEach(player -> guiManager.showGUI(player, this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onClick(GuiManager manager, Player player, Inventory inventory, InventoryClickEvent event) {
|
||||
int cell = event.getSlot();
|
||||
Map<ClickType, Clickable> conditionals;
|
||||
|
||||
if (useHeader && cell < 9) {
|
||||
conditionals = conditionalButtons.get(cell);
|
||||
} else if (cell >= (rows - 1) * 9) {
|
||||
// footer row
|
||||
conditionals = conditionalButtons.get(cell - (rows * 9));
|
||||
} else {
|
||||
int cellIndex = page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9));
|
||||
conditionals = conditionalButtons.get(cellIndex);
|
||||
}
|
||||
|
||||
Clickable button;
|
||||
if (conditionals != null
|
||||
&& ((button = conditionals.get(event.getClick())) != null || (button = conditionals.get(null)) != null)) {
|
||||
button.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
} else {
|
||||
// no event for this button
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package com.songoda.core.gui;
|
||||
|
||||
import com.songoda.core.compatibility.CompatibleMaterial;
|
||||
import com.songoda.core.gui.events.GuiClickEvent;
|
||||
import com.songoda.core.gui.methods.Clickable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Paged GUI for when you aren't going to be making too many pages
|
||||
*/
|
||||
public class SimplePagedGui extends Gui {
|
||||
protected boolean useHeader;
|
||||
private int rowsPerPage, maxCellSlot;
|
||||
protected ItemStack headerBackItem;
|
||||
protected ItemStack footerBackItem;
|
||||
final int nextPageIndex = 4, prevPageIndex = 6;
|
||||
|
||||
public SimplePagedGui() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public SimplePagedGui(Gui parent) {
|
||||
super(parent);
|
||||
|
||||
nextPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Next Page");
|
||||
prevPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Previous Page");
|
||||
}
|
||||
|
||||
public SimplePagedGui setUseHeader(boolean useHeader) {
|
||||
this.useHeader = useHeader;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack getHeaderBackItem() {
|
||||
return headerBackItem;
|
||||
}
|
||||
|
||||
public SimplePagedGui setHeaderBackItem(ItemStack headerBackItem) {
|
||||
this.headerBackItem = headerBackItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack getFooterBackItem() {
|
||||
return footerBackItem;
|
||||
}
|
||||
|
||||
public SimplePagedGui setFooterBackItem(ItemStack footerBackItem) {
|
||||
this.footerBackItem = footerBackItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimplePagedGui setItem(int row, int col, ItemStack item) {
|
||||
return setItem(col + row * 9, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimplePagedGui setItem(int cell, ItemStack item) {
|
||||
// set the cell relative to the current page
|
||||
int cellIndex = cell < 0 ? cell : (page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9)));
|
||||
|
||||
cellItems.put(cellIndex, item);
|
||||
if (open && cell >= 0 && cell < inventory.getSize()) {
|
||||
inventory.setItem(cell, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextPage() {
|
||||
if (page < pages) {
|
||||
++page;
|
||||
showPage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prevPage() {
|
||||
if (page > 1) {
|
||||
--page;
|
||||
showPage();
|
||||
}
|
||||
}
|
||||
|
||||
public void showPage() {
|
||||
int startCell = useHeader ? 9 : 0;
|
||||
int cellIndex = startCell + (page - 1) * (rowsPerPage * 9);
|
||||
|
||||
for (int i = startCell; i < (rows - 1) * 9; ++i) {
|
||||
final ItemStack item = cellItems.get(cellIndex++);
|
||||
inventory.setItem(i, item != null ? item : blankItem);
|
||||
}
|
||||
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updatePageNavigation() {
|
||||
if (page > 1) {
|
||||
inventory.setItem(inventory.getSize() - prevPageIndex, prevPage);
|
||||
|
||||
this.setButton(-prevPageIndex, prevPage, ClickType.LEFT, (event) -> this.prevPage());
|
||||
} else {
|
||||
inventory.setItem(inventory.getSize() - prevPageIndex, footerBackItem != null ? footerBackItem : blankItem);
|
||||
|
||||
this.setItem(-prevPageIndex, null);
|
||||
this.clearActions(-prevPageIndex);
|
||||
}
|
||||
|
||||
if (pages > 1 && page != pages) {
|
||||
inventory.setItem(inventory.getSize() - nextPageIndex, nextPage);
|
||||
|
||||
this.setButton(-nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
} else {
|
||||
inventory.setItem(inventory.getSize() - nextPageIndex, footerBackItem != null ? footerBackItem : blankItem);
|
||||
|
||||
this.setItem(-nextPageIndex, null);
|
||||
this.clearActions(-nextPageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Inventory generateInventory(GuiManager manager) {
|
||||
this.guiManager = manager;
|
||||
|
||||
// calculate pages here
|
||||
rowsPerPage = useHeader ? 4 : 5;
|
||||
maxCellSlot = this.cellItems.keySet().stream().max(Integer::compare).orElse(0) + 1;
|
||||
int maxRows = (int) Math.ceil(maxCellSlot / 9.);
|
||||
pages = (int) Math.max(1, Math.ceil(maxRows / (double) rowsPerPage));
|
||||
this.setRows(maxRows + (useHeader ? 1 : 0));
|
||||
|
||||
// create inventory view
|
||||
createInventory();
|
||||
|
||||
// populate and return the display inventory
|
||||
setPage(Math.min(page, pages));
|
||||
update();
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createInventory() {
|
||||
final int cells = rows * 9;
|
||||
|
||||
inventory = Bukkit.getServer().createInventory(new GuiHolder(guiManager, this), cells,
|
||||
title == null ? "" : trimTitle(title));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate pages here
|
||||
rowsPerPage = useHeader ? 4 : 5;
|
||||
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
|
||||
int maxRows = Math.max((useHeader ? 1 : 0), (int) Math.ceil(maxCellSlot / 9.));
|
||||
pages = (int) Math.ceil(maxRows / rowsPerPage);
|
||||
|
||||
// create a new inventory if needed
|
||||
List<Player> toUpdate = null;
|
||||
if (Math.min(54, (maxRows + (useHeader ? 1 : 0)) * 9) != inventory.getSize()) {
|
||||
toUpdate = getPlayers();
|
||||
|
||||
this.setRows(maxRows + (useHeader ? 1 : 0));
|
||||
|
||||
createInventory();
|
||||
}
|
||||
|
||||
// populate header
|
||||
if (useHeader) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
final ItemStack item = cellItems.get(i);
|
||||
|
||||
inventory.setItem(i, item != null ? item : (headerBackItem != null ? headerBackItem : blankItem));
|
||||
}
|
||||
}
|
||||
|
||||
// last row is dedicated to pagation
|
||||
final int cells = rows * 9;
|
||||
for (int i = cells - 9; i < cells; ++i) {
|
||||
inventory.setItem(i, footerBackItem != null ? footerBackItem : blankItem);
|
||||
}
|
||||
|
||||
// fill out the rest of the page
|
||||
showPage();
|
||||
|
||||
// did we need to change the display window size?
|
||||
if (toUpdate != null) {
|
||||
// whoopsie!
|
||||
exit();
|
||||
toUpdate.forEach(player -> guiManager.showGUI(player, this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onClick(GuiManager manager, Player player, Inventory inventory, InventoryClickEvent event) {
|
||||
int cell = event.getSlot();
|
||||
Map<ClickType, Clickable> conditionals;
|
||||
|
||||
if (useHeader && cell < 9) {
|
||||
conditionals = conditionalButtons.get(cell);
|
||||
} else if (cell >= (rows - 1) * 9) {
|
||||
// footer row
|
||||
conditionals = conditionalButtons.get(cell - (rows * 9));
|
||||
} else {
|
||||
int cellIndex = page == 1 ? cell : cell + (page - 1) * rowsPerPage * 9;
|
||||
conditionals = conditionalButtons.get(cellIndex);
|
||||
}
|
||||
|
||||
Clickable button;
|
||||
if (conditionals != null
|
||||
&& ((button = conditionals.get(event.getClick())) != null || (button = conditionals.get(null)) != null)) {
|
||||
button.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
} else {
|
||||
// no event for this button
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,13 @@ public class GuiClickEvent extends GuiEvent {
|
||||
|
||||
public GuiClickEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event, int slot, boolean guiClicked) {
|
||||
super(manager, gui, player);
|
||||
|
||||
this.slot = slot;
|
||||
this.guiClicked = guiClicked;
|
||||
this.cursor = event.getCursor();
|
||||
|
||||
Inventory clicked = event.getClickedInventory();
|
||||
|
||||
this.clickedItem = clicked == null ? null : clicked.getItem(event.getSlot());
|
||||
this.clickType = event.getClick();
|
||||
this.event = event;
|
||||
|
@ -5,7 +5,6 @@ import com.songoda.core.gui.GuiManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class GuiCloseEvent extends GuiEvent {
|
||||
|
||||
public GuiCloseEvent(GuiManager manager, Gui gui, Player player) {
|
||||
super(manager, gui, player);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ public class GuiDropItemEvent extends GuiEvent {
|
||||
|
||||
public GuiDropItemEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event) {
|
||||
super(manager, gui, player);
|
||||
|
||||
this.cursor = event.getCursor();
|
||||
this.clickType = event.getClick();
|
||||
this.event = event;
|
||||
|
@ -5,7 +5,6 @@ import com.songoda.core.gui.GuiManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class GuiEvent {
|
||||
|
||||
public final GuiManager manager;
|
||||
public final Gui gui;
|
||||
public final Player player;
|
||||
|
@ -5,7 +5,6 @@ import com.songoda.core.gui.GuiManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class GuiOpenEvent extends GuiEvent {
|
||||
|
||||
public GuiOpenEvent(GuiManager manager, Gui gui, Player player) {
|
||||
super(manager, gui, player);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.songoda.core.gui.Gui;
|
||||
import com.songoda.core.gui.GuiManager;
|
||||
|
||||
public class GuiPageEvent {
|
||||
|
||||
final Gui gui;
|
||||
final GuiManager manager;
|
||||
final int lastPage;
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiClickEvent;
|
||||
|
||||
public interface Clickable {
|
||||
|
||||
void onClick(GuiClickEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiCloseEvent;
|
||||
|
||||
public interface Closable {
|
||||
|
||||
void onClose(GuiCloseEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiDropItemEvent;
|
||||
|
||||
public interface Droppable {
|
||||
|
||||
boolean onDrop(GuiDropItemEvent event);
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
package com.songoda.core.gui.methods;
|
||||
|
||||
import com.songoda.core.gui.events.GuiOpenEvent;
|
||||
|
||||
public interface Openable {
|
||||
|
||||
void onOpen(GuiOpenEvent event);
|
||||
}
|
||||
package com.songoda.core.gui.methods;
|
||||
|
||||
import com.songoda.core.gui.events.GuiOpenEvent;
|
||||
|
||||
public interface Openable {
|
||||
void onOpen(GuiOpenEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiPageEvent;
|
||||
|
||||
public interface Pagable {
|
||||
|
||||
void onPageChange(GuiPageEvent event);
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.OfflinePlayer;
|
||||
* A convenience class for static access to an Economy HookManager
|
||||
*/
|
||||
public class EconomyManager {
|
||||
|
||||
private static char currencySymbol = '$';
|
||||
|
||||
private static final HookManager<Economy> manager = new HookManager(Economy.class);
|
||||
@ -48,8 +47,6 @@ public class EconomyManager {
|
||||
/**
|
||||
* Get the name of the economy plugin being used. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getName() {
|
||||
return manager.getName();
|
||||
@ -119,7 +116,7 @@ public class EconomyManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the curency symbl used in the #formatEconomy method.
|
||||
* Change the curency symbol used in the #formatEconomy method.
|
||||
*
|
||||
* @param currencySymbol the new symbol
|
||||
*/
|
||||
@ -128,7 +125,7 @@ public class EconomyManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the curency symbl used in the #formatEconomy method.
|
||||
* Change the curency symbol used in the #formatEconomy method.
|
||||
*
|
||||
* @param currencySymbol the new symbol
|
||||
*/
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.entity.LivingEntity;
|
||||
* A convenience class for static access to a Stacker HookManager
|
||||
*/
|
||||
public class EntityStackerManager {
|
||||
|
||||
private static final HookManager<Stacker> manager = new HookManager(Stacker.class);
|
||||
|
||||
/**
|
||||
@ -56,8 +55,9 @@ public class EntityStackerManager {
|
||||
}
|
||||
|
||||
public static void remove(LivingEntity entity, int amount) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().remove(entity, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOne(LivingEntity entity) {
|
||||
@ -65,8 +65,9 @@ public class EntityStackerManager {
|
||||
}
|
||||
|
||||
public static void add(LivingEntity entity, int amount) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().add(entity, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMinStackSize(EntityType type) {
|
||||
|
@ -11,7 +11,6 @@ import java.util.Map;
|
||||
* A convenience class for static access to a Holograms HookManager
|
||||
*/
|
||||
public class HologramManager {
|
||||
|
||||
private static final HookManager<Holograms> manager = new HookManager(Holograms.class);
|
||||
|
||||
/**
|
||||
@ -49,37 +48,44 @@ public class HologramManager {
|
||||
}
|
||||
|
||||
public static void createHologram(Location location, String line) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().createHologram(location, line);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createHologram(Location location, List<String> lines) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().createHologram(location, lines);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeHologram(Location location) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().removeHologram(location);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeAllHolograms() {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().removeAllHolograms();
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateHologram(Location location, String line) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().updateHologram(location, line);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateHologram(Location location, List<String> lines) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().updateHologram(location, lines);
|
||||
}
|
||||
}
|
||||
|
||||
public static void bulkUpdateHolograms(Map<Location, List<String>> holograms) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().bulkUpdateHolograms(holograms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
package com.songoda.core.hooks;
|
||||
|
||||
public interface Hook {
|
||||
|
||||
/**
|
||||
* Get the name of the plugin being used
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
abstract String getName();
|
||||
|
||||
/**
|
||||
* Check to see if the economy plugin being used is active
|
||||
*
|
||||
* @return true if the plugin is loaded and active
|
||||
*/
|
||||
abstract boolean isEnabled();
|
||||
}
|
||||
package com.songoda.core.hooks;
|
||||
|
||||
public interface Hook {
|
||||
/**
|
||||
* Get the name of the plugin being used
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Check to see if the economy plugin being used is active
|
||||
*
|
||||
* @return true if the plugin is loaded and active
|
||||
*/
|
||||
boolean isEnabled();
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HookManager<T extends Hook> {
|
||||
|
||||
private final Class typeClass;
|
||||
private T defaultHook = null;
|
||||
private boolean loaded = false;
|
||||
@ -36,9 +35,11 @@ public class HookManager<T extends Hook> {
|
||||
if (!loaded) {
|
||||
registeredHooks.putAll(PluginHook.loadHooks(typeClass, hookingPlugin).entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> (T) e.getValue())));
|
||||
|
||||
if (!registeredHooks.isEmpty()) {
|
||||
defaultHook = (T) registeredHooks.values().iterator().next();
|
||||
defaultHook = registeredHooks.values().iterator().next();
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@ -66,8 +67,10 @@ public class HookManager<T extends Hook> {
|
||||
T hook = getHook(name);
|
||||
if (hook != null) {
|
||||
defaultHook = hook;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -84,8 +87,10 @@ public class HookManager<T extends Hook> {
|
||||
T hook = getHook(plugin);
|
||||
if (hook != null) {
|
||||
defaultHook = hook;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -97,10 +102,12 @@ public class HookManager<T extends Hook> {
|
||||
* @return returns null if plugin is not enabled
|
||||
*/
|
||||
public T getHook(String name) {
|
||||
if (name == null)
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String plugin = name.trim();
|
||||
return (T) registeredHooks.get(registeredHooks.keySet().stream()
|
||||
return registeredHooks.get(registeredHooks.keySet().stream()
|
||||
.filter(type -> type.plugin.equalsIgnoreCase(plugin))
|
||||
.findFirst().orElse(null));
|
||||
}
|
||||
|
@ -1,233 +1,267 @@
|
||||
package com.songoda.core.hooks;
|
||||
|
||||
import com.songoda.core.hooks.jobs.JobsHandler;
|
||||
import com.songoda.core.hooks.jobs.JobsPlayerHandler;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class JobsHook {
|
||||
|
||||
static boolean canHook;
|
||||
|
||||
static {
|
||||
try {
|
||||
// if this class exists, we're good to use Jobs classes
|
||||
Class.forName("com.gamingmesh.jobs.Jobs");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
public static JobsPlayerHandler getPlayer(Player player) {
|
||||
if (canHook) {
|
||||
return JobsPlayerHandler.loadPlayer(player);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return canHook;
|
||||
}
|
||||
|
||||
public static List<String> getAllJobs() {
|
||||
if (canHook) {
|
||||
return JobsHandler.getJobs();
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
public static double getBoostExp(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostExp(job);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getBoostMoney(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostMoney(job);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getBoostPoints(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostPoints(job);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void promoteJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.promoteJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static void promoteJob(Player player, String job, int levels) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.promoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public static void demoteJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.demoteJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static void demoteJob(Player player, String job, int levels) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.demoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public static void joinJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.joinJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static void leaveAllJobs(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.leaveAllJobs();
|
||||
}
|
||||
}
|
||||
|
||||
public static void leaveJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.leaveJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTotalLevels(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getTotalLevels();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getMaxBrewingStandsAllowed(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getMaxBrewingStandsAllowed();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getMaxFurnacesAllowed(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getMaxFurnacesAllowed();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static List<String> getJobs(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getJobs();
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
public static void eatItem(Player player, ItemStack item) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.eatItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void breakBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breakBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tntBreakBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.tntBreakBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void placeBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.placeBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void placeEntity(Player player, Entity block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.placeEntity(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void breakEntity(Player player, Entity block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breakEntity(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void breedEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breedEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void killEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.killEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tameEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.tameEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void catchFish(Player player, ItemStack items) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.catchFish(items);
|
||||
}
|
||||
}
|
||||
|
||||
public static void killEntity(Player player, LivingEntity entity, Entity damageSource) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.killEntity(entity, damageSource);
|
||||
}
|
||||
}
|
||||
|
||||
public static void itemEnchanted(Player player, ItemStack resultStack) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
if (jPlayer != null) {
|
||||
jPlayer.itemEnchanted(resultStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.songoda.core.hooks;
|
||||
|
||||
import com.songoda.core.hooks.jobs.JobsHandler;
|
||||
import com.songoda.core.hooks.jobs.JobsPlayerHandler;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class JobsHook {
|
||||
static boolean canHook;
|
||||
|
||||
static {
|
||||
try {
|
||||
// if this class exists, we're good to use Jobs classes
|
||||
Class.forName("com.gamingmesh.jobs.Jobs");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public static JobsPlayerHandler getPlayer(Player player) {
|
||||
if (canHook) {
|
||||
return JobsPlayerHandler.loadPlayer(player);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return canHook;
|
||||
}
|
||||
|
||||
public static List<String> getAllJobs() {
|
||||
if (canHook) {
|
||||
return JobsHandler.getJobs();
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static double getBoostExp(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostExp(job);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getBoostMoney(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostMoney(job);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getBoostPoints(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostPoints(job);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void promoteJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.promoteJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static void promoteJob(Player player, String job, int levels) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.promoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public static void demoteJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.demoteJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static void demoteJob(Player player, String job, int levels) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.demoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public static void joinJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.joinJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static void leaveAllJobs(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.leaveAllJobs();
|
||||
}
|
||||
}
|
||||
|
||||
public static void leaveJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.leaveJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTotalLevels(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getTotalLevels();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getMaxBrewingStandsAllowed(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getMaxBrewingStandsAllowed();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getMaxFurnacesAllowed(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getMaxFurnacesAllowed();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static List<String> getJobs(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getJobs();
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static void eatItem(Player player, ItemStack item) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.eatItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void breakBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breakBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tntBreakBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.tntBreakBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void placeBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.placeBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void placeEntity(Player player, Entity block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.placeEntity(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void breakEntity(Player player, Entity block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breakEntity(block);
|
||||
}
|
||||
}
|
||||
|
||||
public static void breedEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breedEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void killEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.killEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tameEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.tameEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void catchFish(Player player, ItemStack items) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.catchFish(items);
|
||||
}
|
||||
}
|
||||
|
||||
public static void killEntity(Player player, LivingEntity entity, Entity damageSource) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.killEntity(entity, damageSource);
|
||||
}
|
||||
}
|
||||
|
||||
public static void itemEnchanted(Player player, ItemStack resultStack) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.itemEnchanted(resultStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import org.bukkit.block.Block;
|
||||
* A convenience class for static access to a Log HookManager
|
||||
*/
|
||||
public class LogManager {
|
||||
|
||||
private static final HookManager<Log> manager = new HookManager(Log.class);
|
||||
|
||||
/**
|
||||
@ -47,8 +46,6 @@ public class LogManager {
|
||||
/**
|
||||
* Get the name of the log plugin being used. <br />
|
||||
* NOTE: using a default log assumes that this library is shaded
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getName() {
|
||||
return manager.getName();
|
||||
@ -62,8 +59,9 @@ public class LogManager {
|
||||
* @param block the block that is placed
|
||||
*/
|
||||
public static void logPlacement(OfflinePlayer player, Block block) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().logPlacement(player, block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,8 +71,9 @@ public class LogManager {
|
||||
* @param player player to commit actionremvedplaced
|
||||
*/
|
||||
public static void logRemoval(OfflinePlayer player, Block block) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().logRemoval(player, block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,7 +84,8 @@ public class LogManager {
|
||||
* @param location the location that is interacted with
|
||||
*/
|
||||
public static void logInteraction(OfflinePlayer player, Location location) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().logInteraction(player, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
|
||||
import java.util.Collection;
|
||||
|
||||
public class McMMOHook {
|
||||
|
||||
static boolean canHook = false;
|
||||
|
||||
static {
|
||||
@ -16,7 +15,7 @@ public class McMMOHook {
|
||||
// if this class exists, we're good to use McMMO
|
||||
Class.forName("com.gmail.nossr50.api.AbilityAPI");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,46 +184,46 @@ public class McMMOHook {
|
||||
}
|
||||
|
||||
public static boolean hasHerbalismDoubleDrops(Player player) {
|
||||
return canHook ? McMMOHandler.hasHerbalismDoubleDrops(player) : false;
|
||||
return canHook && McMMOHandler.hasHerbalismDoubleDrops(player);
|
||||
}
|
||||
|
||||
public static boolean hasMiningDoubleDrops(Player player) {
|
||||
return canHook ? McMMOHandler.hasMiningDoubleDrops(player) : false;
|
||||
return canHook && McMMOHandler.hasMiningDoubleDrops(player);
|
||||
}
|
||||
|
||||
public static boolean hasWoodcuttingDoubleDrops(Player player) {
|
||||
return canHook ? McMMOHandler.hasWoodcuttingDoubleDrops(player) : false;
|
||||
return canHook && McMMOHandler.hasWoodcuttingDoubleDrops(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingBerserk(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingBerserk(player) : false;
|
||||
return canHook && McMMOHandler.isUsingBerserk(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingGigaDrill(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingGigaDrill(player) : false;
|
||||
return canHook && McMMOHandler.isUsingGigaDrill(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingGreenTerra(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingGreenTerra(player) : false;
|
||||
return canHook && McMMOHandler.isUsingGreenTerra(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingSerratedStrikes(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingSerratedStrikes(player) : false;
|
||||
return canHook && McMMOHandler.isUsingSerratedStrikes(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingSkullSplitter(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingSkullSplitter(player) : false;
|
||||
return canHook && McMMOHandler.isUsingSkullSplitter(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingSuperBreaker(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingSuperBreaker(player) : false;
|
||||
return canHook && McMMOHandler.isUsingSuperBreaker(player);
|
||||
}
|
||||
|
||||
public static boolean isUsingTreeFeller(Player player) {
|
||||
return canHook ? McMMOHandler.isUsingTreeFeller(player) : false;
|
||||
return canHook && McMMOHandler.isUsingTreeFeller(player);
|
||||
}
|
||||
|
||||
public static boolean isBleeding(LivingEntity victim) {
|
||||
return canHook ? McMMOHandler.isBleeding(victim) : false;
|
||||
return canHook && McMMOHandler.isBleeding(victim);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class PluginHook<T extends Class> {
|
||||
|
||||
public static final PluginHook ECO_VAULT = new PluginHook(Economy.class, "Vault", VaultEconomy.class);
|
||||
public static final PluginHook ECO_PLAYER_POINTS = new PluginHook(Economy.class, "PlayerPoints", PlayerPointsEconomy.class);
|
||||
public static final PluginHook ECO_RESERVE = new PluginHook(Economy.class, "Reserve", ReserveEconomy.class);
|
||||
@ -65,13 +64,17 @@ public final class PluginHook<T extends Class> {
|
||||
if (!Hook.class.isAssignableFrom(handler)) {
|
||||
throw new RuntimeException("Tried to register a non-Hook plugin hook! " + pluginName + " -> " + handler.getName());
|
||||
}
|
||||
|
||||
this.hookGeneric = type;
|
||||
this.plugin = pluginName;
|
||||
this.managerClass = handler;
|
||||
|
||||
if (hooks == null) {
|
||||
hooks = new LinkedHashMap();
|
||||
hooks = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
hooks.put(handler, this);
|
||||
|
||||
// Does this class have a plugin constructor?
|
||||
try {
|
||||
pluginConstructor = handler.getDeclaredConstructor(Plugin.class);
|
||||
@ -89,7 +92,6 @@ public final class PluginHook<T extends Class> {
|
||||
* Permissible constructors are empty () or (org.bukkit.plugin.Plugin) <br>
|
||||
* Each plugin defined must use a different handler class.
|
||||
*
|
||||
* @param <T>
|
||||
* @param type Generic hook type for this plugin
|
||||
* @param pluginName Plugin name
|
||||
* @param handler Specific class that will handle this plugin, if enabled.
|
||||
@ -107,6 +109,7 @@ public final class PluginHook<T extends Class> {
|
||||
for (PluginHook hook : getHooks(type)) {
|
||||
if (pluginManager.isPluginEnabled(hook.plugin)) {
|
||||
Hook handler = (Hook) (plugin != null ? hook.load(plugin) : hook.load());
|
||||
|
||||
if (handler != null && handler.isEnabled()) {
|
||||
loaded.put(hook, handler);
|
||||
}
|
||||
@ -136,6 +139,7 @@ public final class PluginHook<T extends Class> {
|
||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -148,6 +152,7 @@ public final class PluginHook<T extends Class> {
|
||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -156,6 +161,7 @@ public final class PluginHook<T extends Class> {
|
||||
int hash = 3;
|
||||
hash = 37 * hash + Objects.hashCode(this.plugin);
|
||||
hash = 37 * hash + Objects.hashCode(this.managerClass);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -164,8 +170,8 @@ public final class PluginHook<T extends Class> {
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PluginHook<?> other = (PluginHook<?>) obj;
|
||||
return Objects.equals(this.plugin, other.plugin)
|
||||
&& Objects.equals(this.managerClass, other.managerClass);
|
||||
return Objects.equals(this.plugin, other.plugin) && Objects.equals(this.managerClass, other.managerClass);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class ProtectionManager {
|
||||
|
||||
private static final HookManager<Protection> manager = new HookManager(Protection.class);
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
static boolean canHook = false;
|
||||
|
||||
static {
|
||||
@ -21,7 +20,7 @@ public class WorldGuardHook {
|
||||
// if this class exists, we're good to use WG classes
|
||||
Class.forName("com.sk89q.worldguard.protection.flags.Flag");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +146,7 @@ public class WorldGuardHook {
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> getRegionNames(@NotNull Location loc) {
|
||||
return canHook ? WorldGuardRegionHandler.getRegionNames(loc) : Collections.EMPTY_LIST;
|
||||
return canHook ? WorldGuardRegionHandler.getRegionNames(loc) : Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,6 +156,6 @@ public class WorldGuardHook {
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> getRegionNames(@NotNull Chunk c) {
|
||||
return canHook ? WorldGuardRegionHandler.getRegionNames(c) : Collections.EMPTY_LIST;
|
||||
return canHook ? WorldGuardRegionHandler.getRegionNames(c) : Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.songoda.core.hooks.Hook;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public abstract class Economy implements Hook {
|
||||
|
||||
/**
|
||||
* Get the players available balance
|
||||
*
|
||||
|
@ -5,7 +5,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class PlayerPointsEconomy extends Economy {
|
||||
|
||||
private final PlayerPoints playerPoints;
|
||||
|
||||
public PlayerPointsEconomy() {
|
||||
@ -34,18 +33,21 @@ public class PlayerPointsEconomy extends Economy {
|
||||
@Override
|
||||
public boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
int amount = convertAmount(cost);
|
||||
|
||||
return playerPoints.getAPI().look(player.getUniqueId()) >= amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
int amount = convertAmount(cost);
|
||||
|
||||
return playerPoints.getAPI().take(player.getUniqueId(), amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(OfflinePlayer player, double amount) {
|
||||
int amt = convertAmount(amount);
|
||||
|
||||
return playerPoints.getAPI().give(player.getUniqueId(), amt);
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,12 @@ import org.bukkit.OfflinePlayer;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ReserveEconomy extends Economy {
|
||||
|
||||
EconomyAPI economyAPI;
|
||||
|
||||
public ReserveEconomy() {
|
||||
if (Reserve.instance().economyProvided())
|
||||
if (Reserve.instance().economyProvided()) {
|
||||
economyAPI = Reserve.instance().economy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -32,16 +32,16 @@ public class ReserveEconomy extends Economy {
|
||||
|
||||
@Override
|
||||
public boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
return economyAPI.hasHoldings(player.getUniqueId(), new BigDecimal(cost));
|
||||
return economyAPI.hasHoldings(player.getUniqueId(), BigDecimal.valueOf(cost));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
return economyAPI.removeHoldings(player.getUniqueId(), new BigDecimal(cost));
|
||||
return economyAPI.removeHoldings(player.getUniqueId(), BigDecimal.valueOf(cost));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(OfflinePlayer player, double amount) {
|
||||
return economyAPI.addHoldings(player.getUniqueId(), new BigDecimal(amount));
|
||||
return economyAPI.addHoldings(player.getUniqueId(), BigDecimal.valueOf(amount));
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
public class VaultEconomy extends Economy {
|
||||
|
||||
private final net.milkbowl.vault.economy.Economy vault;
|
||||
|
||||
public VaultEconomy() {
|
||||
// this returns null if we have Vault with no compatible eco plugin
|
||||
RegisteredServiceProvider<net.milkbowl.vault.economy.Economy> v = Bukkit.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||
|
||||
if (v != null) {
|
||||
this.vault = v.getProvider();
|
||||
} else {
|
||||
@ -31,8 +31,10 @@ public class VaultEconomy extends Economy {
|
||||
|
||||
@Override
|
||||
public double getBalance(OfflinePlayer player) {
|
||||
if (vault == null)
|
||||
if (vault == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vault.getBalance(player);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class CMIHolograms extends Holograms {
|
||||
|
||||
private static CMI cmi;
|
||||
private static HologramManager cmiHologramManager;
|
||||
private static HashSet<String> ourHolograms = new HashSet<>();
|
||||
@ -28,14 +27,16 @@ public class CMIHolograms extends Holograms {
|
||||
try {
|
||||
useOldMethod = CMIHologram.class.getDeclaredField("lines").getDeclaringClass() == String[].class;
|
||||
cmi_CMIHologram_getLines = CMIHologram.class.getMethod("getLines");
|
||||
} catch (NoSuchFieldException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchFieldException | NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public CMIHolograms(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
cmi = (CMI) Bukkit.getPluginManager().getPlugin("CMI");
|
||||
|
||||
if (cmi != null) {
|
||||
cmiHologramManager = cmi.getHologramManager();
|
||||
}
|
||||
@ -64,11 +65,14 @@ public class CMIHolograms extends Holograms {
|
||||
@Override
|
||||
public void removeHologram(Location location) {
|
||||
location = fixLocation(location);
|
||||
|
||||
final String id = locStr(location);
|
||||
CMIHologram holo = cmiHologramManager.getByName(id);
|
||||
|
||||
if (holo != null) {
|
||||
cmiHologramManager.removeHolo(holo);
|
||||
}
|
||||
|
||||
ourHolograms.remove(id);
|
||||
}
|
||||
|
||||
@ -76,10 +80,12 @@ public class CMIHolograms extends Holograms {
|
||||
public void removeAllHolograms() {
|
||||
for (String id : ourHolograms) {
|
||||
CMIHologram holo = cmiHologramManager.getByName(id);
|
||||
|
||||
if (holo != null) {
|
||||
cmiHologramManager.removeHolo(holo);
|
||||
}
|
||||
}
|
||||
|
||||
ourHolograms.clear();
|
||||
}
|
||||
|
||||
@ -87,6 +93,7 @@ public class CMIHolograms extends Holograms {
|
||||
public void updateHologram(Location location, List<String> lines) {
|
||||
location = fixLocation(location);
|
||||
CMIHologram holo = cmiHologramManager.getByName(locStr(location));
|
||||
|
||||
if (holo != null) {
|
||||
// only update if there is a change to the text
|
||||
List<String> holoLines;
|
||||
@ -100,6 +107,7 @@ public class CMIHolograms extends Holograms {
|
||||
Logger.getLogger(CMIHolograms.class.getName()).log(Level.SEVERE, "CMI Hologram error!", ex);
|
||||
holoLines = Collections.emptyList();
|
||||
}
|
||||
|
||||
boolean isChanged = lines.size() != holoLines.size();
|
||||
if (!isChanged) {
|
||||
// double-check the lines
|
||||
@ -107,12 +115,15 @@ public class CMIHolograms extends Holograms {
|
||||
isChanged = !holo.getLine(i).equals(lines.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (isChanged) {
|
||||
holo.setLines(lines);
|
||||
holo.update();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
createAt(location, lines);
|
||||
}
|
||||
|
||||
@ -129,6 +140,7 @@ public class CMIHolograms extends Holograms {
|
||||
|
||||
private void createAt(Location location, List<String> lines) {
|
||||
final String id = locStr(location);
|
||||
|
||||
CMIHologram holo = new CMIHologram(id, location);
|
||||
holo.setLines(lines);
|
||||
|
||||
|
@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Holograms implements Hook {
|
||||
|
||||
protected double xOffset = 0.5;
|
||||
protected double yOffset = 0.5;
|
||||
protected double zOffset = 0.5;
|
||||
@ -24,6 +23,7 @@ public abstract class Holograms implements Hook {
|
||||
this.xOffset = x;
|
||||
this.yOffset = y;
|
||||
this.zOffset = z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ public abstract class Holograms implements Hook {
|
||||
double x = location.getX();
|
||||
double y = location.getY();
|
||||
double z = location.getZ();
|
||||
|
||||
return location.clone().add((x - (int) x) + xOffset, (y - (int) y) + yOffset + defaultHeightOffset(), (z - (int) z) + zOffset);
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HologramsHolograms extends Holograms {
|
||||
|
||||
HologramPlugin hologramPlugin;
|
||||
HashSet<String> ourHolograms = new HashSet<>();
|
||||
|
||||
public HologramsHolograms(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
hologramPlugin = (HologramPlugin) Bukkit.getPluginManager().getPlugin("Holograms");
|
||||
}
|
||||
|
||||
@ -45,12 +45,15 @@ public class HologramsHolograms extends Holograms {
|
||||
@Override
|
||||
public void removeHologram(Location location) {
|
||||
location = fixLocation(location);
|
||||
|
||||
final String id = locStr(location);
|
||||
Hologram hologram = hologramPlugin.getHologramManager().getHologram(id);
|
||||
|
||||
if (hologram != null) {
|
||||
hologram.despawn();
|
||||
hologramPlugin.getHologramManager().removeActiveHologram(hologram);
|
||||
}
|
||||
|
||||
ourHolograms.remove(id);
|
||||
}
|
||||
|
||||
@ -58,11 +61,13 @@ public class HologramsHolograms extends Holograms {
|
||||
public void removeAllHolograms() {
|
||||
for (String id : ourHolograms) {
|
||||
Hologram hologram = hologramPlugin.getHologramManager().getHologram(id);
|
||||
|
||||
if (hologram != null) {
|
||||
hologram.despawn();
|
||||
hologramPlugin.getHologramManager().removeActiveHologram(hologram);
|
||||
}
|
||||
}
|
||||
|
||||
ourHolograms.clear();
|
||||
}
|
||||
|
||||
@ -112,14 +117,15 @@ public class HologramsHolograms extends Holograms {
|
||||
|
||||
private void createAt(Location location, List<String> lines) {
|
||||
final String id = locStr(location);
|
||||
|
||||
Hologram hologram = new Hologram(id, location);
|
||||
|
||||
for (String line : lines) {
|
||||
hologram.addLine(new TextLine(hologram, line));
|
||||
}
|
||||
|
||||
hologramPlugin.getHologramManager().addActiveHologram(hologram);
|
||||
|
||||
if (!ourHolograms.contains(id))
|
||||
ourHolograms.add(id);
|
||||
ourHolograms.add(id);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HolographicDisplaysHolograms extends Holograms {
|
||||
|
||||
public HolographicDisplaysHolograms(Plugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
@ -39,10 +38,14 @@ public class HolographicDisplaysHolograms extends Holograms {
|
||||
@Override
|
||||
public void removeHologram(Location location) {
|
||||
location = fixLocation(location);
|
||||
|
||||
for (Hologram hologram : HologramsAPI.getHolograms(plugin)) {
|
||||
if (hologram.getX() != location.getX()
|
||||
|| hologram.getY() != location.getY()
|
||||
|| hologram.getZ() != location.getZ()) continue;
|
||||
|| hologram.getZ() != location.getZ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hologram.delete();
|
||||
}
|
||||
}
|
||||
@ -63,7 +66,9 @@ public class HolographicDisplaysHolograms extends Holograms {
|
||||
for (Hologram hologram : holograms) {
|
||||
if (hologram.getX() != location.getX()
|
||||
|| hologram.getY() != location.getY()
|
||||
|| hologram.getZ() != location.getZ()) continue;
|
||||
|| hologram.getZ() != location.getZ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// only update if there is a change to the text
|
||||
boolean isChanged = lines.size() != hologram.size();
|
||||
@ -92,6 +97,7 @@ public class HolographicDisplaysHolograms extends Holograms {
|
||||
|
||||
private void createAt(Location location, List<String> lines) {
|
||||
Hologram hologram = HologramsAPI.createHologram(plugin, location);
|
||||
|
||||
for (String line : lines) {
|
||||
hologram.appendTextLine(line);
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package com.songoda.core.hooks.jobs;
|
||||
|
||||
import com.gamingmesh.jobs.Jobs;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JobsHandler {
|
||||
|
||||
public static List<String> getJobs() {
|
||||
return Jobs.getJobs().stream().map(j -> j.getName()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
package com.songoda.core.hooks.jobs;
|
||||
|
||||
import com.gamingmesh.jobs.Jobs;
|
||||
import com.gamingmesh.jobs.container.Job;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JobsHandler {
|
||||
public static List<String> getJobs() {
|
||||
return Jobs.getJobs().stream().map(Job::getName).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -1,183 +1,195 @@
|
||||
package com.songoda.core.hooks.jobs;
|
||||
|
||||
import com.gamingmesh.jobs.CMILib.CMIEnchantment;
|
||||
import com.gamingmesh.jobs.Jobs;
|
||||
import com.gamingmesh.jobs.actions.BlockActionInfo;
|
||||
import com.gamingmesh.jobs.actions.CustomKillInfo;
|
||||
import com.gamingmesh.jobs.actions.EnchantActionInfo;
|
||||
import com.gamingmesh.jobs.actions.EntityActionInfo;
|
||||
import com.gamingmesh.jobs.actions.ItemActionInfo;
|
||||
import com.gamingmesh.jobs.container.ActionType;
|
||||
import com.gamingmesh.jobs.container.CurrencyType;
|
||||
import com.gamingmesh.jobs.container.Job;
|
||||
import com.gamingmesh.jobs.container.JobProgression;
|
||||
import com.gamingmesh.jobs.container.JobsPlayer;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JobsPlayerHandler {
|
||||
|
||||
protected final JobsPlayer jPlayer;
|
||||
|
||||
protected JobsPlayerHandler(JobsPlayer jPlayer) {
|
||||
this.jPlayer = jPlayer;
|
||||
}
|
||||
|
||||
public static JobsPlayerHandler loadPlayer(Player player) {
|
||||
JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player);
|
||||
return jPlayer != null ? new JobsPlayerHandler(jPlayer) : null;
|
||||
}
|
||||
|
||||
public double getBoostExp(String job) {
|
||||
return jPlayer.getBoost(job, CurrencyType.EXP);
|
||||
}
|
||||
|
||||
public double getBoostMoney(String job) {
|
||||
return jPlayer.getBoost(job, CurrencyType.MONEY);
|
||||
}
|
||||
|
||||
public double getBoostPoints(String job) {
|
||||
return jPlayer.getBoost(job, CurrencyType.POINTS);
|
||||
}
|
||||
|
||||
public void promoteJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
if (job != null) {
|
||||
jPlayer.promoteJob(job, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void promoteJob(String jobName, int levels) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
if (job != null) {
|
||||
jPlayer.promoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public void demoteJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
if (job != null) {
|
||||
jPlayer.demoteJob(job, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void demoteJob(String jobName, int levels) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
if (job != null) {
|
||||
jPlayer.demoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public void joinJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
if (job != null) {
|
||||
jPlayer.joinJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public void leaveAllJobs() {
|
||||
jPlayer.leaveAllJobs();
|
||||
}
|
||||
|
||||
public void leaveJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
if (job != null) {
|
||||
jPlayer.leaveJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalLevels() {
|
||||
return jPlayer.getTotalLevels();
|
||||
}
|
||||
|
||||
public int getMaxBrewingStandsAllowed() {
|
||||
return jPlayer.getMaxBrewingStandsAllowed();
|
||||
}
|
||||
|
||||
public int getMaxFurnacesAllowed() {
|
||||
return jPlayer.getMaxFurnacesAllowed();
|
||||
}
|
||||
|
||||
public List<String> getJobs() {
|
||||
return jPlayer.getJobProgression().stream().map(p -> p.getJob().getName()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void eatItem(ItemStack item) {
|
||||
Jobs.action(jPlayer, new ItemActionInfo(item, ActionType.EAT));
|
||||
}
|
||||
|
||||
public void breakBlock(Block block) {
|
||||
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.BREAK), block);
|
||||
}
|
||||
|
||||
public void tntBreakBlock(Block block) {
|
||||
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.TNTBREAK), block);
|
||||
}
|
||||
|
||||
public void placeBlock(Block block) {
|
||||
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.PLACE), block);
|
||||
}
|
||||
|
||||
public void placeEntity(Entity block) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.PLACE));
|
||||
}
|
||||
|
||||
public void breakEntity(Entity block) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.BREAK));
|
||||
}
|
||||
|
||||
public void breedEntity(LivingEntity entity) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.BREED));
|
||||
}
|
||||
|
||||
public void killEntity(LivingEntity entity) {
|
||||
killEntity(entity, jPlayer.getPlayer());
|
||||
}
|
||||
|
||||
public void tameEntity(LivingEntity entity) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo((Entity) entity, ActionType.TAME));
|
||||
}
|
||||
|
||||
public void catchFish(ItemStack items) {
|
||||
Jobs.action(jPlayer, new ItemActionInfo(items, ActionType.FISH));
|
||||
}
|
||||
|
||||
public void killEntity(LivingEntity entity, Entity damageSource) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.KILL), damageSource, entity);
|
||||
if (entity instanceof Player && !entity.hasMetadata("NPC")) {
|
||||
JobsPlayer jVictim = Jobs.getPlayerManager().getJobsPlayer((Player) entity);
|
||||
if (jVictim == null) {
|
||||
return;
|
||||
}
|
||||
List<JobProgression> jobs = jVictim.getJobProgression();
|
||||
if (jobs == null) {
|
||||
return;
|
||||
}
|
||||
for (JobProgression job : jobs) {
|
||||
Jobs.action(jPlayer, new CustomKillInfo(job.getJob().getName(), ActionType.CUSTOMKILL), damageSource, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void itemEnchanted(ItemStack resultStack) {
|
||||
Map<Enchantment, Integer> enchants = resultStack.getEnchantments();
|
||||
for (Map.Entry<Enchantment, Integer> oneEnchant : enchants.entrySet()) {
|
||||
CMIEnchantment e;
|
||||
String enchantName;
|
||||
Integer level2;
|
||||
Enchantment enchant = oneEnchant.getKey();
|
||||
if (enchant == null || (enchantName = (e = CMIEnchantment.get(enchant)) == null ? null : e.toString()) == null || (level2 = oneEnchant.getValue()) == null) {
|
||||
continue;
|
||||
}
|
||||
Jobs.action(jPlayer, new EnchantActionInfo(enchantName, level2, ActionType.ENCHANT));
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.songoda.core.hooks.jobs;
|
||||
|
||||
import com.gamingmesh.jobs.CMILib.CMIEnchantment;
|
||||
import com.gamingmesh.jobs.Jobs;
|
||||
import com.gamingmesh.jobs.actions.BlockActionInfo;
|
||||
import com.gamingmesh.jobs.actions.CustomKillInfo;
|
||||
import com.gamingmesh.jobs.actions.EnchantActionInfo;
|
||||
import com.gamingmesh.jobs.actions.EntityActionInfo;
|
||||
import com.gamingmesh.jobs.actions.ItemActionInfo;
|
||||
import com.gamingmesh.jobs.container.ActionType;
|
||||
import com.gamingmesh.jobs.container.CurrencyType;
|
||||
import com.gamingmesh.jobs.container.Job;
|
||||
import com.gamingmesh.jobs.container.JobProgression;
|
||||
import com.gamingmesh.jobs.container.JobsPlayer;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JobsPlayerHandler {
|
||||
protected final JobsPlayer jPlayer;
|
||||
|
||||
protected JobsPlayerHandler(JobsPlayer jPlayer) {
|
||||
this.jPlayer = jPlayer;
|
||||
}
|
||||
|
||||
public static JobsPlayerHandler loadPlayer(Player player) {
|
||||
JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player);
|
||||
|
||||
return jPlayer != null ? new JobsPlayerHandler(jPlayer) : null;
|
||||
}
|
||||
|
||||
public double getBoostExp(String job) {
|
||||
return jPlayer.getBoost(job, CurrencyType.EXP);
|
||||
}
|
||||
|
||||
public double getBoostMoney(String job) {
|
||||
return jPlayer.getBoost(job, CurrencyType.MONEY);
|
||||
}
|
||||
|
||||
public double getBoostPoints(String job) {
|
||||
return jPlayer.getBoost(job, CurrencyType.POINTS);
|
||||
}
|
||||
|
||||
public void promoteJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.promoteJob(job, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void promoteJob(String jobName, int levels) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.promoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public void demoteJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.demoteJob(job, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void demoteJob(String jobName, int levels) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.demoteJob(job, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public void joinJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.joinJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public void leaveAllJobs() {
|
||||
jPlayer.leaveAllJobs();
|
||||
}
|
||||
|
||||
public void leaveJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.leaveJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalLevels() {
|
||||
return jPlayer.getTotalLevels();
|
||||
}
|
||||
|
||||
public int getMaxBrewingStandsAllowed() {
|
||||
return jPlayer.getMaxBrewingStandsAllowed();
|
||||
}
|
||||
|
||||
public int getMaxFurnacesAllowed() {
|
||||
return jPlayer.getMaxFurnacesAllowed();
|
||||
}
|
||||
|
||||
public List<String> getJobs() {
|
||||
return jPlayer.getJobProgression().stream().map(p -> p.getJob().getName()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void eatItem(ItemStack item) {
|
||||
Jobs.action(jPlayer, new ItemActionInfo(item, ActionType.EAT));
|
||||
}
|
||||
|
||||
public void breakBlock(Block block) {
|
||||
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.BREAK), block);
|
||||
}
|
||||
|
||||
public void tntBreakBlock(Block block) {
|
||||
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.TNTBREAK), block);
|
||||
}
|
||||
|
||||
public void placeBlock(Block block) {
|
||||
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.PLACE), block);
|
||||
}
|
||||
|
||||
public void placeEntity(Entity block) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.PLACE));
|
||||
}
|
||||
|
||||
public void breakEntity(Entity block) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.BREAK));
|
||||
}
|
||||
|
||||
public void breedEntity(LivingEntity entity) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.BREED));
|
||||
}
|
||||
|
||||
public void killEntity(LivingEntity entity) {
|
||||
killEntity(entity, jPlayer.getPlayer());
|
||||
}
|
||||
|
||||
public void tameEntity(LivingEntity entity) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.TAME));
|
||||
}
|
||||
|
||||
public void catchFish(ItemStack items) {
|
||||
Jobs.action(jPlayer, new ItemActionInfo(items, ActionType.FISH));
|
||||
}
|
||||
|
||||
public void killEntity(LivingEntity entity, Entity damageSource) {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.KILL), damageSource, entity);
|
||||
if (entity instanceof Player && !entity.hasMetadata("NPC")) {
|
||||
JobsPlayer jVictim = Jobs.getPlayerManager().getJobsPlayer((Player) entity);
|
||||
|
||||
if (jVictim == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<JobProgression> jobs = jVictim.getJobProgression();
|
||||
if (jobs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (JobProgression job : jobs) {
|
||||
Jobs.action(jPlayer, new CustomKillInfo(job.getJob().getName(), ActionType.CUSTOMKILL), damageSource, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void itemEnchanted(ItemStack resultStack) {
|
||||
Map<Enchantment, Integer> enchants = resultStack.getEnchantments();
|
||||
|
||||
for (Map.Entry<Enchantment, Integer> oneEnchant : enchants.entrySet()) {
|
||||
CMIEnchantment e;
|
||||
String enchantName;
|
||||
Integer level2;
|
||||
Enchantment enchant = oneEnchant.getKey();
|
||||
|
||||
if (enchant == null || (enchantName = (e = CMIEnchantment.get(enchant)) == null ? null : e.toString()) == null || (level2 = oneEnchant.getValue()) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Jobs.action(jPlayer, new EnchantActionInfo(enchantName, level2, ActionType.ENCHANT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class CoreProtectLog extends Log {
|
||||
|
||||
private CoreProtectAPI api;
|
||||
private boolean useDeprecatedMethod = ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12);
|
||||
|
||||
@ -30,18 +29,20 @@ public class CoreProtectLog extends Log {
|
||||
public void logPlacement(OfflinePlayer player, Block block) {
|
||||
if (this.useDeprecatedMethod) {
|
||||
this.api.logPlacement(player.getName(), block.getLocation(), block.getType(), block.getData());
|
||||
} else {
|
||||
this.api.logPlacement(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
return;
|
||||
}
|
||||
|
||||
this.api.logPlacement(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logRemoval(OfflinePlayer player, Block block) {
|
||||
if (this.useDeprecatedMethod) {
|
||||
this.api.logRemoval(player.getName(), block.getLocation(), block.getType(), block.getData());
|
||||
} else {
|
||||
this.api.logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
return;
|
||||
}
|
||||
|
||||
this.api.logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public abstract class Log implements Hook {
|
||||
|
||||
public abstract void logPlacement(OfflinePlayer player, Block block);
|
||||
|
||||
public abstract void logRemoval(OfflinePlayer player, Block block);
|
||||
|
@ -26,7 +26,6 @@ import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class McMMOHandler {
|
||||
|
||||
static boolean mcmmo_v2 = false;
|
||||
static boolean legacy_v13 = false;
|
||||
static boolean legacy_v12 = false;
|
||||
@ -62,6 +61,7 @@ public class McMMOHandler {
|
||||
mcmmo_SecondaryAbility_valueOf = mcmmo_SecondaryAbility.getDeclaredMethod("valueOf", String.class);
|
||||
mcmmo_Permissions_secondaryAbilityEnabled = com.gmail.nossr50.util.Permissions.class.getDeclaredMethod("secondaryAbilityEnabled", Player.class, mcmmo_SecondaryAbility);
|
||||
mcmmo_SkillUtils_activationSuccessful = com.gmail.nossr50.util.skills.SkillUtils.class.getDeclaredMethod("activationSuccessful", mcmmo_SecondaryAbility, Player.class, int.class, int.class);
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.block.data.BlockData.class);
|
||||
legacy_v13 = true;
|
||||
@ -72,8 +72,8 @@ public class McMMOHandler {
|
||||
mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.Material.class);
|
||||
legacy_v8 = true;
|
||||
}
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to register McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex2) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to register McMMO Legacy Hook", ex2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,296 +81,392 @@ public class McMMOHandler {
|
||||
public static void addMining(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "mining");
|
||||
return;
|
||||
}
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(Block::getState).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.MINING);
|
||||
}
|
||||
|
||||
public static void addExcavation(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "excavation");
|
||||
return;
|
||||
}
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(Block::getState).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.EXCAVATION);
|
||||
}
|
||||
|
||||
public static void addHerbalism(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "herbalism");
|
||||
return;
|
||||
}
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(Block::getState).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.HERBALISM);
|
||||
}
|
||||
|
||||
public static void addWoodcutting(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "woodcutting");
|
||||
return;
|
||||
}
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(Block::getState).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.WOODCUTTING);
|
||||
}
|
||||
|
||||
public static int getAcrobaticsSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "acrobatics");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ACROBATICS);
|
||||
}
|
||||
|
||||
public static int getAlchemySkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "alchemy");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ALCHEMY);
|
||||
}
|
||||
|
||||
public static int getArcherySkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "archery");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ARCHERY);
|
||||
}
|
||||
|
||||
public static int getAxesSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "axes");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.AXES);
|
||||
}
|
||||
|
||||
public static int getExcavationSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "excavation");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.EXCAVATION);
|
||||
}
|
||||
|
||||
public static int getFishingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "fishing");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.FISHING);
|
||||
}
|
||||
|
||||
public static int getHerbalismSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "herbalism");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.HERBALISM);
|
||||
}
|
||||
|
||||
public static int getMiningSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "mining");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.MINING);
|
||||
}
|
||||
|
||||
public static int getRepairSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "repair");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.REPAIR);
|
||||
}
|
||||
|
||||
public static int getSmeltingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "smelting");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.SMELTING);
|
||||
}
|
||||
|
||||
public static int getSwordsSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "swords");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.SWORDS);
|
||||
}
|
||||
|
||||
public static int getTamingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "taming");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.TAMING);
|
||||
}
|
||||
|
||||
public static int getUnarmedSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "unarmed");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.UNARMED);
|
||||
}
|
||||
|
||||
public static int getWoodcuttingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "woodcutting");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.WOODCUTTING);
|
||||
}
|
||||
|
||||
public static void addAcrobatics(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "acrobatics", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ACROBATICS, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addAlchemy(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "alchemy", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ALCHEMY, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addArchery(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "archery", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ARCHERY, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addAxes(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "axes", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.AXES, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addExcavation(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "excavation", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.EXCAVATION, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addFishing(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "fishing", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.FISHING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addHerbalism(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "herbalism", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.HERBALISM, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addMining(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "mining", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.MINING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addRepair(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "repair", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.REPAIR, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addSmelting(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "smelting", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.SMELTING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addSwords(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "swords", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.SWORDS, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addTaming(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "taming", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.TAMING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addUnarmed(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "unarmed", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.UNARMED, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addWoodcutting(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "woodcutting", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.WOODCUTTING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
@ -455,22 +551,25 @@ public class McMMOHandler {
|
||||
if (player.hasMetadata("mcMMO: Player Data")) {
|
||||
try {
|
||||
Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase());
|
||||
|
||||
if ((boolean) mcmmo_SkillType_getDoubleDropsDisabled.invoke(skillType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int skillLevel = (int) mcmmo_McMMOPlayer_getSkillLevel.invoke(UserManager.getPlayer(player), skillType);
|
||||
int activationChance = (int) mcmmo_PerksUtils_handleLuckyPerks.invoke(null, player, skillType);
|
||||
|
||||
Object secondaryDouble = mcmmo_SecondaryAbility_valueOf.invoke(null, skill.toUpperCase() + "_DOUBLE_DROPS");
|
||||
|
||||
if (!((boolean) mcmmo_Permissions_secondaryAbilityEnabled.invoke(null, player, secondaryDouble))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (boolean) mcmmo_SkillUtils_activationSuccessful.invoke(null, secondaryDouble, player, skillLevel, activationChance);
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -484,30 +583,34 @@ public class McMMOHandler {
|
||||
}
|
||||
|
||||
ExperienceAPI.addXP(player, skill, xp);
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Object legacy_getBlock(Block block) {
|
||||
if (legacy_v13) {
|
||||
return block.getBlockData();
|
||||
} else if (legacy_v12) {
|
||||
return block.getState().getData();
|
||||
} else {
|
||||
return block.getType();
|
||||
}
|
||||
|
||||
if (legacy_v12) {
|
||||
return block.getState().getData();
|
||||
}
|
||||
|
||||
return block.getType();
|
||||
}
|
||||
|
||||
protected static int getSkillLegacy(Player player, String skill) {
|
||||
if (player.hasMetadata("mcMMO: Player Data")) {
|
||||
try {
|
||||
Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase());
|
||||
|
||||
return (int) mcmmo_McMMOPlayer_getSkillLevel.invoke(UserManager.getPlayer(player), skillType);
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ import world.bentobox.bentobox.managers.IslandsManager;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BentoBoxProtection extends Protection {
|
||||
|
||||
private final IslandsManager islandsManager;
|
||||
|
||||
public BentoBoxProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
this.islandsManager = BentoBox.getInstance().getIslands();
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user