Repository: Simplix-Softworks/Cirrus
Branch: master
Commit: e9d150254681
Files: 128
Total size: 346.5 KB
Directory structure:
gitextract_6gkla1sj/
├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── cirrus-bungeecord/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── dev/
│ └── simplix/
│ └── cirrus/
│ └── bungeecord/
│ ├── BungeeCordPlayerWrapper.java
│ ├── CirrusBungeeCord.java
│ ├── converters/
│ │ ├── ItemModelConverter.java
│ │ ├── ItemStackConverter.java
│ │ ├── PlayerConverter.java
│ │ └── PlayerUniqueIdConverter.java
│ ├── listeners/
│ │ └── QuitListener.java
│ └── protocolize/
│ └── ProtocolizeMenuBuilder.java
├── cirrus-bungeecord-example/
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── dev/
│ │ └── simplix/
│ │ └── cirrus/
│ │ └── bungeecord/
│ │ └── example/
│ │ ├── CirrusExamplePlugin.java
│ │ ├── commands/
│ │ │ └── TestCommand.java
│ │ └── menus/
│ │ ├── ExampleMenu.java
│ │ └── ExampleMultiPageMenu.java
│ └── resources/
│ └── plugin.yml
├── cirrus-common/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── dev/
│ │ │ └── simplix/
│ │ │ └── cirrus/
│ │ │ └── common/
│ │ │ ├── Cirrus.java
│ │ │ ├── Utils.java
│ │ │ ├── business/
│ │ │ │ ├── ConfigurationFactory.java
│ │ │ │ ├── DataInventoryMenuItemWrapper.java
│ │ │ │ ├── InventoryMenuItemWrapper.java
│ │ │ │ ├── MenuItemWrapper.java
│ │ │ │ └── PlayerWrapper.java
│ │ │ ├── config/
│ │ │ │ └── JsonConfigurationFactory.java
│ │ │ ├── configuration/
│ │ │ │ ├── MenuConfiguration.java
│ │ │ │ ├── MultiPageMenuConfiguration.java
│ │ │ │ └── impl/
│ │ │ │ ├── SimpleMenuConfiguration.java
│ │ │ │ └── SimpleMultiPageMenuConfiguration.java
│ │ │ ├── container/
│ │ │ │ ├── Container.java
│ │ │ │ └── impl/
│ │ │ │ └── ItemContainer.java
│ │ │ ├── converter/
│ │ │ │ ├── Converter.java
│ │ │ │ └── Converters.java
│ │ │ ├── effect/
│ │ │ │ ├── AbstractChangingItemAnimation.java
│ │ │ │ ├── AbstractMenuAnimation.java
│ │ │ │ ├── Animated.java
│ │ │ │ ├── Animations.java
│ │ │ │ ├── MenuAnimation.java
│ │ │ │ └── MenuAnimator.java
│ │ │ ├── effects/
│ │ │ │ ├── GradualColorChangeAnimation.java
│ │ │ │ ├── RGBColorChangeAnimation.java
│ │ │ │ └── SimpleChangingItemAnimation.java
│ │ │ ├── handler/
│ │ │ │ ├── ActionHandler.java
│ │ │ │ └── AutoCancellingActionHandler.java
│ │ │ ├── i18n/
│ │ │ │ ├── LocalizedItemStackModel.java
│ │ │ │ ├── LocalizedString.java
│ │ │ │ ├── LocalizedStringDeserializer.java
│ │ │ │ ├── LocalizedStringList.java
│ │ │ │ ├── LocalizedStringListDeserializer.java
│ │ │ │ ├── LocalizedStringListSerializer.java
│ │ │ │ ├── LocalizedStringSerializer.java
│ │ │ │ ├── Localizer.java
│ │ │ │ └── Replacer.java
│ │ │ ├── item/
│ │ │ │ ├── CirrusItem.java
│ │ │ │ ├── Items.java
│ │ │ │ └── ProtocolizeMenuItemWrapper.java
│ │ │ ├── menu/
│ │ │ │ ├── AbstractConfigurableMenu.java
│ │ │ │ ├── AbstractMenu.java
│ │ │ │ ├── ErrorProne.java
│ │ │ │ ├── Menu.java
│ │ │ │ └── MenuBuilder.java
│ │ │ ├── menus/
│ │ │ │ ├── AbstractBrowserMenu.java
│ │ │ │ ├── MultiPageMenu.java
│ │ │ │ └── SimpleMenu.java
│ │ │ ├── model/
│ │ │ │ ├── CallResult.java
│ │ │ │ └── Click.java
│ │ │ ├── mojangson/
│ │ │ │ ├── MojangsonScope.java
│ │ │ │ ├── MojangsonWriter.java
│ │ │ │ ├── TagDeserializer.java
│ │ │ │ └── TagSerializer.java
│ │ │ └── util/
│ │ │ ├── ColorUtils.java
│ │ │ ├── Colors.java
│ │ │ ├── InventoryContentMap.java
│ │ │ └── SafeRunnable.java
│ │ └── resources/
│ │ └── cirrus/
│ │ ├── MenuConfiguration.json
│ │ └── MultiPageMenuConfiguration.json
│ └── test/
│ └── java/
│ └── dev/
│ └── simplix/
│ └── cirrus/
│ └── common/
│ └── tests/
│ ├── SnbtGsonTest.java
│ └── SnbtTest.java
├── cirrus-spigot/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── dev/
│ └── simplix/
│ └── cirrus/
│ └── spigot/
│ ├── CirrusSpigot.java
│ ├── SpigotPlayerWrapper.java
│ ├── converters/
│ │ ├── BukkitItemStackConverter.java
│ │ ├── ItemModelConverter.java
│ │ ├── ItemTypeMaterialDataConverter.java
│ │ ├── MaterialDataItemTypeConverter.java
│ │ ├── NmsNbtQuerzNbtConverter.java
│ │ ├── PlayerConverter.java
│ │ ├── ProtocolizeItemStackConverter.java
│ │ ├── QuerzNbtNmsNbtConverter.java
│ │ ├── SpigotClickTypeConverter.java
│ │ └── SpigotInventoryTypeConverter.java
│ ├── listener/
│ │ └── InventoryListener.java
│ ├── menubuilder/
│ │ └── SpigotMenuBuilder.java
│ ├── menus/
│ │ └── SpigotMenu.java
│ └── util/
│ ├── BungeeCordComponentConverterProvider.java
│ ├── OtherModuleProvider.java
│ ├── ProtocolVersionUtil.java
│ ├── ProtocolVersions.java
│ ├── ReflectionClasses.java
│ ├── ReflectionUtil.java
│ └── SpigotItemsUtils.java
├── cirrus-spigot-example/
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── dev/
│ │ └── simplix/
│ │ └── cirrus/
│ │ └── spigot/
│ │ └── example/
│ │ ├── CirrusExamplePlugin.java
│ │ ├── commands/
│ │ │ └── TestCommandExecutor.java
│ │ └── menus/
│ │ ├── ExampleMenu.java
│ │ └── ExampleMultiPageMenu.java
│ └── resources/
│ └── plugin.yml
├── cirrus-spigot-modern/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── dev/
│ └── simplix/
│ └── cirrus/
│ └── spigot/
│ └── modern/
│ └── ModernInventoryView.java
├── cirrus-velocity/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── dev/
│ └── simplix/
│ └── cirrus/
│ └── velocity/
│ ├── CirrusVelocity.java
│ ├── VelocityPlayerWrapper.java
│ ├── converters/
│ │ ├── ItemModelConverter.java
│ │ ├── ItemStackConverter.java
│ │ ├── PlayerConverter.java
│ │ └── PlayerUniqueIdConverter.java
│ ├── listener/
│ │ └── QuitListener.java
│ └── protocolize/
│ └── ProtocolizeMenuBuilder.java
├── cirrus-velocity-example/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── dev/
│ └── simplix/
│ └── cirrus/
│ └── velocity/
│ └── example/
│ ├── CirrusExamplePlugin.java
│ ├── commands/
│ │ └── TestCommand.java
│ └── menus/
│ ├── ExampleMenu.java
│ └── ExampleMultiPageMenu.java
└── pom.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = false
max_line_length = 100
tab_width = 2
ij_continuation_indent_size = 4
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false
ij_smart_tabs = false
ij_visual_guides = 100
ij_wrap_on_typing = true
[]
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
[*.bib]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_bibtex_keep_first_column_comment = true
ij_bibtex_keep_indents_on_empty_lines = false
ij_bibtex_wrap_long_lines = false
[*.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 = false
ij_css_hex_color_long_format = false
ij_css_hex_color_lower_case = false
ij_css_hex_color_short_format = false
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 = do_not_align
[*.csv]
max_line_length = 2147483647
ij_wrap_on_typing = false
ij_csv_wrap_long_lines = false
[*.feature]
tab_width = 4
ij_continuation_indent_size = 8
ij_gherkin_keep_indents_on_empty_lines = false
[*.gsp]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_gsp_keep_indents_on_empty_lines = false
[*.haml]
tab_width = 4
ij_continuation_indent_size = 8
ij_haml_keep_indents_on_empty_lines = false
[*.java]
ij_wrap_on_typing = false
ij_java_align_consecutive_assignments = false
ij_java_align_consecutive_variable_declarations = false
ij_java_align_group_field_declarations = false
ij_java_align_multiline_annotation_parameters = false
ij_java_align_multiline_array_initializer_expression = false
ij_java_align_multiline_assignment = false
ij_java_align_multiline_binary_operation = true
ij_java_align_multiline_chained_methods = false
ij_java_align_multiline_extends_list = false
ij_java_align_multiline_for = false
ij_java_align_multiline_method_parentheses = false
ij_java_align_multiline_parameters = false
ij_java_align_multiline_parameters_in_calls = false
ij_java_align_multiline_parenthesized_expression = false
ij_java_align_multiline_records = false
ij_java_align_multiline_resources = false
ij_java_align_multiline_ternary_operation = false
ij_java_align_multiline_text_blocks = false
ij_java_align_multiline_throws_list = false
ij_java_align_subsequent_simple_methods = false
ij_java_align_throws_keyword = false
ij_java_annotation_parameter_wrap = off
ij_java_array_initializer_new_line_after_left_brace = true
ij_java_array_initializer_right_brace_on_new_line = false
ij_java_array_initializer_wrap = on_every_item
ij_java_assert_statement_colon_on_next_line = false
ij_java_assert_statement_wrap = off
ij_java_assignment_wrap = off
ij_java_binary_operation_sign_on_next_line = true
ij_java_binary_operation_wrap = on_every_item
ij_java_blank_lines_after_anonymous_class_header = 0
ij_java_blank_lines_after_class_header = 1
ij_java_blank_lines_after_imports = 1
ij_java_blank_lines_after_package = 1
ij_java_blank_lines_around_class = 1
ij_java_blank_lines_around_field = 0
ij_java_blank_lines_around_field_in_interface = 0
ij_java_blank_lines_around_initializer = 1
ij_java_blank_lines_around_method = 1
ij_java_blank_lines_around_method_in_interface = 1
ij_java_blank_lines_before_class_end = 0
ij_java_blank_lines_before_imports = 1
ij_java_blank_lines_before_method_body = 0
ij_java_blank_lines_before_package = 0
ij_java_block_brace_style = end_of_line
ij_java_block_comment_at_first_column = true
ij_java_call_parameters_new_line_after_left_paren = true
ij_java_call_parameters_right_paren_on_new_line = false
ij_java_call_parameters_wrap = on_every_item
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 = 5
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 = true
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 = false
ij_java_doc_add_blank_line_after_return = false
ij_java_doc_add_p_tag_on_empty_lines = true
ij_java_doc_align_exception_comments = true
ij_java_doc_align_param_comments = true
ij_java_doc_do_not_wrap_if_one_line = false
ij_java_doc_enable_formatting = true
ij_java_doc_enable_leading_asterisks = true
ij_java_doc_indent_on_continuation = false
ij_java_doc_keep_empty_lines = true
ij_java_doc_keep_empty_parameter_tag = true
ij_java_doc_keep_empty_return_tag = true
ij_java_doc_keep_empty_throws_tag = true
ij_java_doc_keep_invalid_tags = true
ij_java_doc_param_description_on_new_line = false
ij_java_doc_preserve_line_breaks = false
ij_java_doc_use_throws_not_exception_tag = true
ij_java_else_on_new_line = false
ij_java_entity_dd_suffix = EJB
ij_java_entity_eb_suffix = Bean
ij_java_entity_hi_suffix = Home
ij_java_entity_lhi_prefix = Local
ij_java_entity_lhi_suffix = Home
ij_java_entity_li_prefix = Local
ij_java_entity_pk_class = java.lang.String
ij_java_entity_vo_suffix = VO
ij_java_enum_constants_wrap = off
ij_java_extends_keyword_wrap = off
ij_java_extends_list_wrap = on_every_item
ij_java_field_annotation_wrap = on_every_item
ij_java_finally_on_new_line = false
ij_java_for_brace_force = never
ij_java_for_statement_new_line_after_left_paren = true
ij_java_for_statement_right_paren_on_new_line = false
ij_java_for_statement_wrap = on_every_item
ij_java_generate_final_locals = false
ij_java_generate_final_parameters = false
ij_java_if_brace_force = never
ij_java_imports_layout = $*, |, *
ij_java_indent_case_from_switch = true
ij_java_insert_inner_class_imports = true
ij_java_insert_override_annotation = true
ij_java_keep_blank_lines_before_right_brace = 1
ij_java_keep_blank_lines_between_package_declaration_and_header = 1
ij_java_keep_blank_lines_in_code = 1
ij_java_keep_blank_lines_in_declarations = 1
ij_java_keep_control_statement_in_one_line = false
ij_java_keep_first_column_comment = true
ij_java_keep_indents_on_empty_lines = false
ij_java_keep_line_breaks = true
ij_java_keep_multiple_expressions_in_one_line = false
ij_java_keep_simple_blocks_in_one_line = false
ij_java_keep_simple_classes_in_one_line = 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
ij_java_layout_static_imports_separately = true
ij_java_line_comment_add_space = false
ij_java_line_comment_at_first_column = true
ij_java_message_dd_suffix = EJB
ij_java_message_eb_suffix = Bean
ij_java_method_annotation_wrap = split_into_lines
ij_java_method_brace_style = end_of_line
ij_java_method_call_chain_wrap = on_every_item
ij_java_method_parameters_new_line_after_left_paren = true
ij_java_method_parameters_right_paren_on_new_line = false
ij_java_method_parameters_wrap = on_every_item
ij_java_modifier_list_wrap = false
ij_java_names_count_to_use_import_on_demand = 5
ij_java_new_line_after_lparen_in_record_header = true
ij_java_parameter_annotation_wrap = off
ij_java_parentheses_expression_new_line_after_left_paren = true
ij_java_parentheses_expression_right_paren_on_new_line = false
ij_java_place_assignment_sign_on_next_line = false
ij_java_prefer_longer_names = true
ij_java_prefer_parameters_wrap = false
ij_java_record_components_wrap = on_every_item
ij_java_repeat_synchronized = true
ij_java_replace_instanceof_and_cast = false
ij_java_replace_null_check = true
ij_java_replace_sum_lambda_with_method_ref = true
ij_java_resource_list_new_line_after_left_paren = true
ij_java_resource_list_right_paren_on_new_line = false
ij_java_resource_list_wrap = off
ij_java_rparen_on_new_line_in_record_header = false
ij_java_session_dd_suffix = EJB
ij_java_session_eb_suffix = Bean
ij_java_session_hi_suffix = Home
ij_java_session_lhi_prefix = Local
ij_java_session_lhi_suffix = Home
ij_java_session_li_prefix = Local
ij_java_session_si_suffix = Service
ij_java_space_after_closing_angle_bracket_in_type_argument = false
ij_java_space_after_colon = true
ij_java_space_after_comma = true
ij_java_space_after_comma_in_type_arguments = true
ij_java_space_after_for_semicolon = true
ij_java_space_after_quest = true
ij_java_space_after_type_cast = true
ij_java_space_before_annotation_array_initializer_left_brace = false
ij_java_space_before_annotation_parameter_list = false
ij_java_space_before_array_initializer_left_brace = false
ij_java_space_before_catch_keyword = true
ij_java_space_before_catch_left_brace = true
ij_java_space_before_catch_parentheses = true
ij_java_space_before_class_left_brace = true
ij_java_space_before_colon = true
ij_java_space_before_colon_in_foreach = true
ij_java_space_before_comma = false
ij_java_space_before_do_left_brace = true
ij_java_space_before_else_keyword = true
ij_java_space_before_else_left_brace = true
ij_java_space_before_finally_keyword = true
ij_java_space_before_finally_left_brace = true
ij_java_space_before_for_left_brace = true
ij_java_space_before_for_parentheses = true
ij_java_space_before_for_semicolon = false
ij_java_space_before_if_left_brace = true
ij_java_space_before_if_parentheses = true
ij_java_space_before_method_call_parentheses = false
ij_java_space_before_method_left_brace = true
ij_java_space_before_method_parentheses = false
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
ij_java_space_before_quest = true
ij_java_space_before_switch_left_brace = true
ij_java_space_before_switch_parentheses = true
ij_java_space_before_synchronized_left_brace = true
ij_java_space_before_synchronized_parentheses = true
ij_java_space_before_try_left_brace = true
ij_java_space_before_try_parentheses = true
ij_java_space_before_type_parameter_list = false
ij_java_space_before_while_keyword = true
ij_java_space_before_while_left_brace = true
ij_java_space_before_while_parentheses = true
ij_java_space_inside_one_line_enum_braces = false
ij_java_space_within_empty_array_initializer_braces = 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
ij_java_spaces_around_assignment_operators = true
ij_java_spaces_around_bitwise_operators = true
ij_java_spaces_around_equality_operators = true
ij_java_spaces_around_lambda_arrow = true
ij_java_spaces_around_logical_operators = true
ij_java_spaces_around_method_ref_dbl_colon = false
ij_java_spaces_around_multiplicative_operators = true
ij_java_spaces_around_relational_operators = true
ij_java_spaces_around_shift_operators = true
ij_java_spaces_around_type_bounds_in_type_parameters = true
ij_java_spaces_around_unary_operator = false
ij_java_spaces_within_angle_brackets = false
ij_java_spaces_within_annotation_parentheses = false
ij_java_spaces_within_array_initializer_braces = false
ij_java_spaces_within_braces = false
ij_java_spaces_within_brackets = false
ij_java_spaces_within_cast_parentheses = false
ij_java_spaces_within_catch_parentheses = false
ij_java_spaces_within_for_parentheses = false
ij_java_spaces_within_if_parentheses = false
ij_java_spaces_within_method_call_parentheses = false
ij_java_spaces_within_method_parentheses = false
ij_java_spaces_within_parentheses = false
ij_java_spaces_within_switch_parentheses = false
ij_java_spaces_within_synchronized_parentheses = false
ij_java_spaces_within_try_parentheses = false
ij_java_spaces_within_while_parentheses = false
ij_java_special_else_if_treatment = true
ij_java_subclass_name_suffix = Impl
ij_java_ternary_operation_signs_on_next_line = true
ij_java_ternary_operation_wrap = on_every_item
ij_java_test_name_suffix = Test
ij_java_throws_keyword_wrap = normal
ij_java_throws_list_wrap = off
ij_java_use_external_annotations = false
ij_java_use_fq_class_names = false
ij_java_use_relative_indents = false
ij_java_use_single_class_imports = true
ij_java_variable_annotation_wrap = off
ij_java_visibility = public
ij_java_while_brace_force = never
ij_java_while_on_new_line = false
ij_java_wrap_comments = true
ij_java_wrap_first_method_in_call_chain = true
ij_java_wrap_long_lines = false
[*.less]
tab_width = 4
ij_continuation_indent_size = 8
ij_less_align_closing_brace_with_properties = false
ij_less_blank_lines_around_nested_selector = 1
ij_less_blank_lines_between_blocks = 1
ij_less_brace_placement = 0
ij_less_enforce_quotes_on_format = false
ij_less_hex_color_long_format = false
ij_less_hex_color_lower_case = false
ij_less_hex_color_short_format = false
ij_less_hex_color_upper_case = false
ij_less_keep_blank_lines_in_code = 2
ij_less_keep_indents_on_empty_lines = false
ij_less_keep_single_line_blocks = false
ij_less_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_less_space_after_colon = true
ij_less_space_before_opening_brace = true
ij_less_use_double_quotes = true
ij_less_value_alignment = 0
[*.nbtt]
indent_size = 4
max_line_length = 150
tab_width = 4
ij_nbtt_keep_indents_on_empty_lines = false
ij_nbtt_space_after_colon = true
ij_nbtt_space_after_comma = true
ij_nbtt_space_before_colon = true
ij_nbtt_space_before_comma = false
ij_nbtt_spaces_within_brackets = false
ij_nbtt_spaces_within_parentheses = false
[*.sass]
ij_sass_align_closing_brace_with_properties = false
ij_sass_blank_lines_around_nested_selector = 1
ij_sass_blank_lines_between_blocks = 1
ij_sass_brace_placement = 0
ij_sass_enforce_quotes_on_format = false
ij_sass_hex_color_long_format = false
ij_sass_hex_color_lower_case = false
ij_sass_hex_color_short_format = false
ij_sass_hex_color_upper_case = false
ij_sass_keep_blank_lines_in_code = 2
ij_sass_keep_indents_on_empty_lines = false
ij_sass_keep_single_line_blocks = false
ij_sass_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_sass_space_after_colon = true
ij_sass_space_before_opening_brace = true
ij_sass_use_double_quotes = true
ij_sass_value_alignment = 0
[*.scss]
ij_scss_align_closing_brace_with_properties = false
ij_scss_blank_lines_around_nested_selector = 1
ij_scss_blank_lines_between_blocks = 1
ij_scss_brace_placement = 0
ij_scss_enforce_quotes_on_format = false
ij_scss_hex_color_long_format = false
ij_scss_hex_color_lower_case = false
ij_scss_hex_color_short_format = false
ij_scss_hex_color_upper_case = false
ij_scss_keep_blank_lines_in_code = 2
ij_scss_keep_indents_on_empty_lines = false
ij_scss_keep_single_line_blocks = false
ij_scss_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_scss_space_after_colon = true
ij_scss_space_before_opening_brace = true
ij_scss_use_double_quotes = true
ij_scss_value_alignment = 0
[*.styl]
tab_width = 4
ij_continuation_indent_size = 8
ij_stylus_align_closing_brace_with_properties = false
ij_stylus_blank_lines_around_nested_selector = 1
ij_stylus_blank_lines_between_blocks = 1
ij_stylus_brace_placement = 0
ij_stylus_enforce_quotes_on_format = false
ij_stylus_hex_color_long_format = false
ij_stylus_hex_color_lower_case = false
ij_stylus_hex_color_short_format = false
ij_stylus_hex_color_upper_case = false
ij_stylus_keep_blank_lines_in_code = 2
ij_stylus_keep_indents_on_empty_lines = false
ij_stylus_keep_single_line_blocks = false
ij_stylus_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_stylus_space_after_colon = true
ij_stylus_space_before_opening_brace = true
ij_stylus_use_double_quotes = true
ij_stylus_value_alignment = 0
[*.tikz]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_latex_keep_first_column_comment = true
ij_latex_keep_indents_on_empty_lines = false
ij_latex_line_comment_add_space = false
ij_latex_line_comment_at_first_column = true
ij_latex_wrap_long_lines = false
[.editorconfig]
ij_editorconfig_align_group_field_declarations = false
ij_editorconfig_space_after_colon = false
ij_editorconfig_space_after_comma = true
ij_editorconfig_space_before_colon = false
ij_editorconfig_space_before_comma = false
ij_editorconfig_spaces_around_assignment_operators = true
[{*.ant, *.bpmn, *.fxml, *.jhm, *.jnlp, *.jrxml, *.plan, *.pom, *.rng, *.tld, *.wadl, *.wsdd, *.wsdl, *.xjb, *.xml, *.xsd, *.xsl, *.xslt, *.xul}]
ij_continuation_indent_size = 2
ij_xml_align_attributes = false
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
ij_xml_use_custom_settings = true
[{*.as, *.es, *.js2}]
indent_size = 4
ij_continuation_indent_size = 8
ij_actionscript_align_imports = false
ij_actionscript_align_multiline_array_initializer_expression = false
ij_actionscript_align_multiline_binary_operation = false
ij_actionscript_align_multiline_chained_methods = false
ij_actionscript_align_multiline_extends_list = false
ij_actionscript_align_multiline_for = false
ij_actionscript_align_multiline_parameters = false
ij_actionscript_align_multiline_parameters_in_calls = false
ij_actionscript_align_multiline_ternary_operation = false
ij_actionscript_align_object_properties = 0
ij_actionscript_align_union_types = false
ij_actionscript_align_var_statements = 0
ij_actionscript_array_initializer_new_line_after_left_brace = false
ij_actionscript_array_initializer_right_brace_on_new_line = false
ij_actionscript_array_initializer_wrap = normal
ij_actionscript_assignment_wrap = off
ij_actionscript_binary_operation_sign_on_next_line = true
ij_actionscript_binary_operation_wrap = normal
ij_actionscript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_actionscript_blank_lines_after_imports = 1
ij_actionscript_blank_lines_after_package = 0
ij_actionscript_blank_lines_around_function = 1
ij_actionscript_blank_lines_around_method = 1
ij_actionscript_blank_lines_before_imports = 1
ij_actionscript_blank_lines_before_package = 0
ij_actionscript_block_brace_style = end_of_line
ij_actionscript_call_parameters_new_line_after_left_paren = false
ij_actionscript_call_parameters_right_paren_on_new_line = false
ij_actionscript_call_parameters_wrap = normal
ij_actionscript_catch_on_new_line = false
ij_actionscript_chained_call_dot_on_new_line = true
ij_actionscript_class_brace_style = end_of_line
ij_actionscript_comma_on_new_line = false
ij_actionscript_do_while_brace_force = always
ij_actionscript_else_on_new_line = false
ij_actionscript_enforce_trailing_comma = keep
ij_actionscript_extends_keyword_wrap = off
ij_actionscript_extends_list_wrap = normal
ij_actionscript_field_prefix = _
ij_actionscript_file_name_style = relaxed
ij_actionscript_finally_on_new_line = false
ij_actionscript_for_brace_force = always
ij_actionscript_for_statement_new_line_after_left_paren = false
ij_actionscript_for_statement_right_paren_on_new_line = false
ij_actionscript_for_statement_wrap = normal
ij_actionscript_force_quote_style = false
ij_actionscript_force_semicolon_style = false
ij_actionscript_function_expression_brace_style = end_of_line
ij_actionscript_if_brace_force = always
ij_actionscript_import_merge_members = global
ij_actionscript_import_prefer_absolute_path = global
ij_actionscript_import_sort_members = true
ij_actionscript_import_sort_module_name = false
ij_actionscript_import_use_node_resolution = true
ij_actionscript_imports_wrap = on_every_item
ij_actionscript_indent_case_from_switch = true
ij_actionscript_indent_chained_calls = true
ij_actionscript_indent_package_children = 0
ij_actionscript_jsx_attribute_value = braces
ij_actionscript_keep_blank_lines_in_code = 1
ij_actionscript_keep_first_column_comment = true
ij_actionscript_keep_indents_on_empty_lines = false
ij_actionscript_keep_line_breaks = true
ij_actionscript_keep_simple_blocks_in_one_line = false
ij_actionscript_keep_simple_methods_in_one_line = false
ij_actionscript_line_comment_at_first_column = true
ij_actionscript_method_brace_style = end_of_line
ij_actionscript_method_call_chain_wrap = off
ij_actionscript_method_parameters_new_line_after_left_paren = false
ij_actionscript_method_parameters_right_paren_on_new_line = false
ij_actionscript_method_parameters_wrap = normal
ij_actionscript_object_literal_wrap = on_every_item
ij_actionscript_parentheses_expression_new_line_after_left_paren = false
ij_actionscript_parentheses_expression_right_paren_on_new_line = false
ij_actionscript_place_assignment_sign_on_next_line = false
ij_actionscript_prefer_as_type_cast = false
ij_actionscript_prefer_explicit_types_function_expression_returns = false
ij_actionscript_prefer_explicit_types_function_returns = false
ij_actionscript_prefer_explicit_types_vars_fields = false
ij_actionscript_prefer_parameters_wrap = false
ij_actionscript_reformat_c_style_comments = false
ij_actionscript_space_after_colon = true
ij_actionscript_space_after_comma = true
ij_actionscript_space_after_dots_in_rest_parameter = false
ij_actionscript_space_after_generator_mult = true
ij_actionscript_space_after_property_colon = true
ij_actionscript_space_after_quest = true
ij_actionscript_space_after_type_colon = false
ij_actionscript_space_after_unary_not = false
ij_actionscript_space_before_async_arrow_lparen = true
ij_actionscript_space_before_catch_keyword = true
ij_actionscript_space_before_catch_left_brace = true
ij_actionscript_space_before_catch_parentheses = true
ij_actionscript_space_before_class_lbrace = true
ij_actionscript_space_before_colon = true
ij_actionscript_space_before_comma = false
ij_actionscript_space_before_do_left_brace = true
ij_actionscript_space_before_else_keyword = true
ij_actionscript_space_before_else_left_brace = true
ij_actionscript_space_before_finally_keyword = true
ij_actionscript_space_before_finally_left_brace = true
ij_actionscript_space_before_for_left_brace = true
ij_actionscript_space_before_for_parentheses = true
ij_actionscript_space_before_for_semicolon = false
ij_actionscript_space_before_function_left_parenth = true
ij_actionscript_space_before_generator_mult = false
ij_actionscript_space_before_if_left_brace = true
ij_actionscript_space_before_if_parentheses = true
ij_actionscript_space_before_method_call_parentheses = false
ij_actionscript_space_before_method_left_brace = true
ij_actionscript_space_before_method_parentheses = false
ij_actionscript_space_before_property_colon = false
ij_actionscript_space_before_quest = true
ij_actionscript_space_before_switch_left_brace = true
ij_actionscript_space_before_switch_parentheses = true
ij_actionscript_space_before_try_left_brace = true
ij_actionscript_space_before_type_colon = false
ij_actionscript_space_before_unary_not = false
ij_actionscript_space_before_while_keyword = true
ij_actionscript_space_before_while_left_brace = true
ij_actionscript_space_before_while_parentheses = true
ij_actionscript_spaces_around_additive_operators = true
ij_actionscript_spaces_around_arrow_function_operator = true
ij_actionscript_spaces_around_assignment_operators = true
ij_actionscript_spaces_around_bitwise_operators = true
ij_actionscript_spaces_around_equality_operators = true
ij_actionscript_spaces_around_logical_operators = true
ij_actionscript_spaces_around_multiplicative_operators = true
ij_actionscript_spaces_around_relational_operators = true
ij_actionscript_spaces_around_shift_operators = true
ij_actionscript_spaces_around_unary_operator = false
ij_actionscript_spaces_within_array_initializer_brackets = false
ij_actionscript_spaces_within_brackets = false
ij_actionscript_spaces_within_catch_parentheses = false
ij_actionscript_spaces_within_for_parentheses = false
ij_actionscript_spaces_within_if_parentheses = false
ij_actionscript_spaces_within_imports = false
ij_actionscript_spaces_within_interpolation_expressions = false
ij_actionscript_spaces_within_method_call_parentheses = false
ij_actionscript_spaces_within_method_parentheses = false
ij_actionscript_spaces_within_object_literal_braces = false
ij_actionscript_spaces_within_object_type_braces = true
ij_actionscript_spaces_within_parentheses = false
ij_actionscript_spaces_within_switch_parentheses = false
ij_actionscript_spaces_within_type_assertion = false
ij_actionscript_spaces_within_union_types = true
ij_actionscript_spaces_within_while_parentheses = false
ij_actionscript_special_else_if_treatment = true
ij_actionscript_ternary_operation_signs_on_next_line = true
ij_actionscript_ternary_operation_wrap = normal
ij_actionscript_union_types_wrap = on_every_item
ij_actionscript_use_chained_calls_group_indents = false
ij_actionscript_use_double_quotes = true
ij_actionscript_use_explicit_js_extension = global
ij_actionscript_use_path_mapping = always
ij_actionscript_use_public_modifier = false
ij_actionscript_use_semicolon_after_statement = true
ij_actionscript_var_declaration_wrap = normal
ij_actionscript_while_brace_force = always
ij_actionscript_while_on_new_line = false
ij_actionscript_wrap_comments = false
[{*.ats, *.ts}]
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 = keep
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 = false
ij_typescript_force_semicolon_style = false
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 = false
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 = false
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 = false
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 = true
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
[{*.cfc, *.cfm, *.cfml}]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_cfml_align_multiline_binary_operation = false
ij_cfml_align_multiline_for = true
ij_cfml_align_multiline_parameters = true
ij_cfml_align_multiline_parameters_in_calls = false
ij_cfml_align_multiline_ternary_operation = false
ij_cfml_assignment_wrap = off
ij_cfml_binary_operation_sign_on_next_line = false
ij_cfml_binary_operation_wrap = off
ij_cfml_block_brace_style = end_of_line
ij_cfml_call_parameters_new_line_after_left_paren = false
ij_cfml_call_parameters_right_paren_on_new_line = false
ij_cfml_call_parameters_wrap = off
ij_cfml_catch_on_new_line = false
ij_cfml_else_on_new_line = false
ij_cfml_for_statement_new_line_after_left_paren = false
ij_cfml_for_statement_right_paren_on_new_line = false
ij_cfml_for_statement_wrap = off
ij_cfml_keep_blank_lines_in_code = 2
ij_cfml_keep_first_column_comment = true
ij_cfml_keep_indents_on_empty_lines = false
ij_cfml_keep_line_breaks = true
ij_cfml_method_brace_style = next_line
ij_cfml_method_parameters_new_line_after_left_paren = false
ij_cfml_method_parameters_right_paren_on_new_line = false
ij_cfml_method_parameters_wrap = off
ij_cfml_parentheses_expression_new_line_after_left_paren = false
ij_cfml_parentheses_expression_right_paren_on_new_line = false
ij_cfml_place_assignment_sign_on_next_line = false
ij_cfml_space_after_colon = true
ij_cfml_space_after_comma = true
ij_cfml_space_after_for_semicolon = true
ij_cfml_space_after_quest = true
ij_cfml_space_before_catch_keyword = true
ij_cfml_space_before_catch_left_brace = true
ij_cfml_space_before_catch_parentheses = true
ij_cfml_space_before_colon = true
ij_cfml_space_before_comma = false
ij_cfml_space_before_else_keyword = true
ij_cfml_space_before_else_left_brace = true
ij_cfml_space_before_for_left_brace = true
ij_cfml_space_before_for_parentheses = true
ij_cfml_space_before_for_semicolon = false
ij_cfml_space_before_if_left_brace = true
ij_cfml_space_before_if_parentheses = true
ij_cfml_space_before_method_call_parentheses = false
ij_cfml_space_before_method_left_brace = true
ij_cfml_space_before_method_parentheses = false
ij_cfml_space_before_quest = true
ij_cfml_space_before_switch_left_brace = true
ij_cfml_space_before_switch_parentheses = true
ij_cfml_space_before_try_left_brace = true
ij_cfml_space_before_while_keyword = true
ij_cfml_space_before_while_left_brace = true
ij_cfml_space_before_while_parentheses = true
ij_cfml_spaces_around_additive_operators = true
ij_cfml_spaces_around_assignment_operators = true
ij_cfml_spaces_around_equality_operators = true
ij_cfml_spaces_around_logical_operators = true
ij_cfml_spaces_around_multiplicative_operators = true
ij_cfml_spaces_around_relational_operators = true
ij_cfml_spaces_around_unary_operator = false
ij_cfml_spaces_within_catch_parentheses = false
ij_cfml_spaces_within_for_parentheses = false
ij_cfml_spaces_within_if_parentheses = false
ij_cfml_spaces_within_method_call_parentheses = false
ij_cfml_spaces_within_method_parentheses = false
ij_cfml_spaces_within_switch_parentheses = false
ij_cfml_spaces_within_while_parentheses = false
ij_cfml_special_else_if_treatment = false
ij_cfml_ternary_operation_signs_on_next_line = false
ij_cfml_ternary_operation_wrap = off
ij_cfml_while_on_new_line = false
[{*.cjs, *.js}]
max_line_length = 80
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 = false
ij_javascript_align_multiline_parameters = false
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 = normal
ij_javascript_assignment_wrap = off
ij_javascript_binary_operation_sign_on_next_line = true
ij_javascript_binary_operation_wrap = normal
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 = normal
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 = always
ij_javascript_else_on_new_line = false
ij_javascript_enforce_trailing_comma = keep
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 = always
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 = normal
ij_javascript_force_quote_style = false
ij_javascript_force_semicolon_style = false
ij_javascript_function_expression_brace_style = end_of_line
ij_javascript_if_brace_force = always
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 = false
ij_javascript_indent_package_children = 0
ij_javascript_jsx_attribute_value = braces
ij_javascript_keep_blank_lines_in_code = 1
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 = normal
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 = false
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 = true
ij_javascript_ternary_operation_wrap = normal
ij_javascript_union_types_wrap = on_every_item
ij_javascript_use_chained_calls_group_indents = false
ij_javascript_use_double_quotes = true
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 = always
ij_javascript_while_on_new_line = false
ij_javascript_wrap_comments = false
[{*.cjsx, *.coffee}]
ij_continuation_indent_size = 2
ij_coffeescript_align_function_body = false
ij_coffeescript_align_imports = false
ij_coffeescript_align_multiline_array_initializer_expression = true
ij_coffeescript_align_multiline_parameters = true
ij_coffeescript_align_multiline_parameters_in_calls = false
ij_coffeescript_align_object_properties = 0
ij_coffeescript_align_union_types = false
ij_coffeescript_align_var_statements = 0
ij_coffeescript_array_initializer_new_line_after_left_brace = false
ij_coffeescript_array_initializer_right_brace_on_new_line = false
ij_coffeescript_array_initializer_wrap = normal
ij_coffeescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_coffeescript_blank_lines_around_function = 1
ij_coffeescript_call_parameters_new_line_after_left_paren = false
ij_coffeescript_call_parameters_right_paren_on_new_line = false
ij_coffeescript_call_parameters_wrap = normal
ij_coffeescript_chained_call_dot_on_new_line = true
ij_coffeescript_comma_on_new_line = false
ij_coffeescript_enforce_trailing_comma = keep
ij_coffeescript_field_prefix = _
ij_coffeescript_file_name_style = relaxed
ij_coffeescript_force_quote_style = false
ij_coffeescript_force_semicolon_style = false
ij_coffeescript_function_expression_brace_style = end_of_line
ij_coffeescript_import_merge_members = global
ij_coffeescript_import_prefer_absolute_path = global
ij_coffeescript_import_sort_members = true
ij_coffeescript_import_sort_module_name = false
ij_coffeescript_import_use_node_resolution = true
ij_coffeescript_imports_wrap = on_every_item
ij_coffeescript_indent_chained_calls = true
ij_coffeescript_indent_package_children = 0
ij_coffeescript_jsx_attribute_value = braces
ij_coffeescript_keep_blank_lines_in_code = 2
ij_coffeescript_keep_first_column_comment = true
ij_coffeescript_keep_indents_on_empty_lines = false
ij_coffeescript_keep_line_breaks = true
ij_coffeescript_keep_simple_methods_in_one_line = false
ij_coffeescript_method_parameters_new_line_after_left_paren = false
ij_coffeescript_method_parameters_right_paren_on_new_line = false
ij_coffeescript_method_parameters_wrap = off
ij_coffeescript_object_literal_wrap = on_every_item
ij_coffeescript_prefer_as_type_cast = false
ij_coffeescript_prefer_explicit_types_function_expression_returns = false
ij_coffeescript_prefer_explicit_types_function_returns = false
ij_coffeescript_prefer_explicit_types_vars_fields = false
ij_coffeescript_reformat_c_style_comments = false
ij_coffeescript_space_after_comma = true
ij_coffeescript_space_after_dots_in_rest_parameter = false
ij_coffeescript_space_after_generator_mult = true
ij_coffeescript_space_after_property_colon = true
ij_coffeescript_space_after_type_colon = true
ij_coffeescript_space_after_unary_not = false
ij_coffeescript_space_before_async_arrow_lparen = true
ij_coffeescript_space_before_class_lbrace = true
ij_coffeescript_space_before_comma = false
ij_coffeescript_space_before_function_left_parenth = true
ij_coffeescript_space_before_generator_mult = false
ij_coffeescript_space_before_property_colon = false
ij_coffeescript_space_before_type_colon = false
ij_coffeescript_space_before_unary_not = false
ij_coffeescript_spaces_around_additive_operators = true
ij_coffeescript_spaces_around_arrow_function_operator = true
ij_coffeescript_spaces_around_assignment_operators = true
ij_coffeescript_spaces_around_bitwise_operators = true
ij_coffeescript_spaces_around_equality_operators = true
ij_coffeescript_spaces_around_logical_operators = true
ij_coffeescript_spaces_around_multiplicative_operators = true
ij_coffeescript_spaces_around_relational_operators = true
ij_coffeescript_spaces_around_shift_operators = true
ij_coffeescript_spaces_around_unary_operator = false
ij_coffeescript_spaces_within_array_initializer_braces = false
ij_coffeescript_spaces_within_array_initializer_brackets = false
ij_coffeescript_spaces_within_imports = false
ij_coffeescript_spaces_within_index_brackets = false
ij_coffeescript_spaces_within_interpolation_expressions = false
ij_coffeescript_spaces_within_method_call_parentheses = false
ij_coffeescript_spaces_within_method_parentheses = false
ij_coffeescript_spaces_within_object_braces = false
ij_coffeescript_spaces_within_object_literal_braces = false
ij_coffeescript_spaces_within_object_type_braces = true
ij_coffeescript_spaces_within_range_brackets = false
ij_coffeescript_spaces_within_type_assertion = false
ij_coffeescript_spaces_within_union_types = true
ij_coffeescript_union_types_wrap = on_every_item
ij_coffeescript_use_chained_calls_group_indents = false
ij_coffeescript_use_double_quotes = true
ij_coffeescript_use_explicit_js_extension = global
ij_coffeescript_use_path_mapping = always
ij_coffeescript_use_public_modifier = false
ij_coffeescript_use_semicolon_after_statement = false
ij_coffeescript_var_declaration_wrap = normal
[{*.ft, *.vm, *.vsl}]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_vtl_keep_indents_on_empty_lines = false
[{*.gant, *.gradle, *.groovy, *.gson, *.gy}]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
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_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_long_lines = false
[{*.gradle.kts, *.kt, *.kts, *.main.kts}]
ij_kotlin_align_in_columns_case_branch = false
ij_kotlin_align_multiline_binary_operation = false
ij_kotlin_align_multiline_extends_list = false
ij_kotlin_align_multiline_method_parentheses = false
ij_kotlin_align_multiline_parameters = true
ij_kotlin_align_multiline_parameters_in_calls = false
ij_kotlin_assignment_wrap = on_every_item
ij_kotlin_blank_lines_after_class_header = 0
ij_kotlin_blank_lines_around_block_when_branches = 0
ij_kotlin_block_comment_at_first_column = true
ij_kotlin_call_parameters_new_line_after_left_paren = true
ij_kotlin_call_parameters_right_paren_on_new_line = false
ij_kotlin_call_parameters_wrap = on_every_item
ij_kotlin_catch_on_new_line = false
ij_kotlin_class_annotation_wrap = split_into_lines
ij_kotlin_continuation_indent_for_chained_calls = true
ij_kotlin_continuation_indent_for_expression_bodies = true
ij_kotlin_continuation_indent_in_argument_lists = true
ij_kotlin_continuation_indent_in_elvis = true
ij_kotlin_continuation_indent_in_if_conditions = true
ij_kotlin_continuation_indent_in_parameter_lists = true
ij_kotlin_continuation_indent_in_supertype_lists = true
ij_kotlin_else_on_new_line = false
ij_kotlin_enum_constants_wrap = off
ij_kotlin_extends_list_wrap = on_every_item
ij_kotlin_field_annotation_wrap = split_into_lines
ij_kotlin_finally_on_new_line = false
ij_kotlin_if_rparen_on_new_line = false
ij_kotlin_import_nested_classes = false
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
ij_kotlin_keep_blank_lines_before_right_brace = 1
ij_kotlin_keep_blank_lines_in_code = 1
ij_kotlin_keep_blank_lines_in_declarations = 1
ij_kotlin_keep_first_column_comment = true
ij_kotlin_keep_indents_on_empty_lines = false
ij_kotlin_keep_line_breaks = true
ij_kotlin_lbrace_on_next_line = false
ij_kotlin_line_comment_add_space = false
ij_kotlin_line_comment_at_first_column = true
ij_kotlin_method_annotation_wrap = split_into_lines
ij_kotlin_method_call_chain_wrap = on_every_item
ij_kotlin_method_parameters_new_line_after_left_paren = true
ij_kotlin_method_parameters_right_paren_on_new_line = false
ij_kotlin_method_parameters_wrap = on_every_item
ij_kotlin_name_count_to_use_star_import = 5
ij_kotlin_name_count_to_use_star_import_for_members = 3
ij_kotlin_parameter_annotation_wrap = on_every_item
ij_kotlin_space_after_comma = true
ij_kotlin_space_after_extend_colon = true
ij_kotlin_space_after_type_colon = true
ij_kotlin_space_before_catch_parentheses = true
ij_kotlin_space_before_comma = false
ij_kotlin_space_before_extend_colon = true
ij_kotlin_space_before_for_parentheses = true
ij_kotlin_space_before_if_parentheses = true
ij_kotlin_space_before_lambda_arrow = true
ij_kotlin_space_before_type_colon = false
ij_kotlin_space_before_when_parentheses = true
ij_kotlin_space_before_while_parentheses = true
ij_kotlin_spaces_around_additive_operators = true
ij_kotlin_spaces_around_assignment_operators = true
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_spaces_around_function_type_arrow = true
ij_kotlin_spaces_around_logical_operators = true
ij_kotlin_spaces_around_multiplicative_operators = true
ij_kotlin_spaces_around_range = false
ij_kotlin_spaces_around_relational_operators = true
ij_kotlin_spaces_around_unary_operator = false
ij_kotlin_spaces_around_when_arrow = true
ij_kotlin_variable_annotation_wrap = off
ij_kotlin_while_on_new_line = false
ij_kotlin_wrap_elvis_expressions = 1
ij_kotlin_wrap_expression_body_functions = 0
ij_kotlin_wrap_first_method_in_call_chain = false
[{*.htm, *.html, *.ng, *.sht, *.shtm, *.shtml}]
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
ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
ij_html_enforce_quotes = false
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
[{*.jsf, *.jsp, *.jspf, *.tag, *.tagf, *.xjsp}]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_jsp_jsp_prefer_comma_separated_import_list = false
ij_jsp_keep_indents_on_empty_lines = false
[{*.jspx, *.tagx}]
indent_size = 4
tab_width = 4
ij_continuation_indent_size = 8
ij_jspx_keep_indents_on_empty_lines = false
[{*.properties, spring.handlers, spring.schemas}]
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}]
ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true
================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
### Linux template
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### Windows template
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/**
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
*.iml
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### macOS template
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Java template
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Simplix Softworks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Cirrus
[](http://ci.exceptionflug.de/job/Cirrus/) [](https://plugins.jetbrains.com/plugin/15194-cirrus-tooling) [](https://discord.simplixsoft.com/) 
Menu Framework.
Cirrus enables you to develop platform-independent versatile graphical menus for Spigot, BungeeCord, and Velocity! The
goal of Cirrus is to aim for maximum compatibility. Cirrus had been tested on several well-known BungeeCord-Forks as
well on all Spigot versions beginning from 1.16.5 till the latest release. The first-ever way of creating menus for Velocity.
# WIP
Cirrus is currently WIP. The documentation is invalid in parts. We will publish a stable version soon.
Spigot & BungeeCord implementations will work, Velocity implementations are currently very experimental.
We aim to publish documentation & production ready versions in the coming month.
## Version
Current version is:
- Stable: 2.0.0
- Development: 2.1.0-SNAPHOT
## PR
If you have any improvements regarding Cirrus feel free to create a PR. We are happy to review & merge it.
Keep in mind that to use our codestyle as defined in .editorconfig.
## Platforms
On Spigot Cirrus is fully independent of third party plugins. Protocolize is needed only only if Cirrus is used on
proxies like BungeeCord or Velocity.
- Spigot
- BungeeCord
- Velocity (WIP)
## Supported Bukkit Versions
Due to the changes in the API we only officially support 1.16.5-LATEST (which is 1.19 by the time this is written)
Since Cirrus is designed to be mostly version independent, older versions will likely function as well but they are deprecated (so we won't attempt to resolve issues with these versions).
## Tooling
Cirrus offers an IntelliJ plugin to enhance the usability of Cirrus. It provides a realtime preview while editing menu
configuration files.
[](https://plugins.jetbrains.com/plugin/15194-cirrus-tooling)

## Requirements
### Protocolize
Cirrus is powered by [Protocolize](https://github.com/Exceptionflug/protocolize). A protocol manipulation library by one
of the Simplix Softworks founders, Exceptionflug. Protocolize enables you to do so much more on BungeeCord/Velocity!
## Installation
Just shade and relocate the platform module into your own plugin. Don't forget to call the `CirrusSpigot`
, `CirrusBungeeCord` or `CirrusVelocity` init method.
### More developer documentation
Check out the [wiki](https://github.com/Simplix-Softworks/Cirrus/wiki) for further information on how to use Cirrus in
your application.
================================================
FILE: cirrus-bungeecord/pom.xml
================================================
cirrus-bungeecord
4.0.0
cirrus
dev.simplix.cirrus
2.0.0
${cirrus.version}
cirrus-common
dev.simplix.cirrus
compile
${cirrus.version}
net.md-5
bungeecord-api
1.21-R0.1-SNAPSHOT
provided
${project.name}-${project.version}
src/main/resources
true
org.apache.maven.plugins
maven-shade-plugin
3.0.0
package
shade
false
org.apache.maven.plugins
maven-compiler-plugin
8
8
org.apache.maven.plugins
maven-source-plugin
3.0.1
attach-sources
deploy
jar-no-fork
org.apache.maven.plugins
maven-javadoc-plugin
3.0.1
attach-javadocs
jar
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/BungeeCordPlayerWrapper.java
================================================
package dev.simplix.cirrus.bungeecord;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.player.ProtocolizePlayer;
import lombok.NonNull;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
public class BungeeCordPlayerWrapper implements PlayerWrapper {
private final ProtocolizePlayer protocolizePlayer;
private final ProxiedPlayer handle;
public BungeeCordPlayerWrapper(@NonNull ProxiedPlayer handle) {
this.handle = handle;
this.protocolizePlayer = Protocolize.playerProvider().player(handle.getUniqueId());
}
@Override
public UUID uniqueId() {
return this.handle.getUniqueId();
}
@Override
public String name() {
return this.handle.getName();
}
@Override
public int protocolVersion() {
return this.protocolizePlayer.protocolVersion();
}
@Override
public void sendMessage(@NonNull String msg) {
this.handle.sendMessage(msg);
}
@Override
public void closeInventory() {
this.protocolizePlayer.closeInventory();
}
@Override
public boolean hasPermission(@NonNull String permission) {
return this.handle.hasPermission(permission);
}
@Override
public T handle() {
return (T) this.handle;
}
public ProtocolizePlayer protocolizePlayer() {
return this.protocolizePlayer;
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/CirrusBungeeCord.java
================================================
package dev.simplix.cirrus.bungeecord;
import dev.simplix.cirrus.bungeecord.converters.ItemModelConverter;
import dev.simplix.cirrus.bungeecord.converters.ItemStackConverter;
import dev.simplix.cirrus.bungeecord.converters.PlayerConverter;
import dev.simplix.cirrus.bungeecord.converters.PlayerUniqueIdConverter;
import dev.simplix.cirrus.bungeecord.listeners.QuitListener;
import dev.simplix.cirrus.bungeecord.protocolize.ProtocolizeMenuBuilder;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.effect.MenuAnimator;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.protocolize.api.item.ItemStack;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Plugin;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class CirrusBungeeCord {
private static Plugin plugin;
static {
// Players
Converters.register(ProxiedPlayer.class, PlayerWrapper.class, new PlayerConverter());
Converters.register(UUID.class, PlayerWrapper.class, new PlayerUniqueIdConverter());
// Items
Converters.register(ItemStack.class, MenuItemWrapper.class, new ItemStackConverter());
Converters.register(CirrusItem.class, InventoryMenuItemWrapper.class, new ItemModelConverter());
}
public static void init(Plugin plugin) {
if (CirrusBungeeCord.plugin != null) {
return;
}
CirrusBungeeCord.plugin = plugin;
Cirrus.registerService(MenuBuilder.class, new ProtocolizeMenuBuilder());
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new QuitListener());
ProxyServer.getInstance().getScheduler().schedule(plugin, () -> {
if (ProxyServer.getInstance().getOnlineCount() > 0 && !MenuAnimator.isEmpty()) {
MenuAnimator.updateAll();
}
}, 50 * 2, TimeUnit.MILLISECONDS);
}
public static Plugin plugin() {
if (plugin == null) {
throw new IllegalStateException("Cirrus is not initialized. Please call CirrusBungeeCord#init during onEnable.");
} // ➤
return plugin;
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/ItemModelConverter.java
================================================
package dev.simplix.cirrus.bungeecord.converters;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.protocolize.api.chat.ChatElement;
import dev.simplix.protocolize.api.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Collectors;
public class ItemModelConverter implements Converter {
@Override
public InventoryMenuItemWrapper convert(@NotNull CirrusItem model) {
ItemStack itemStack = new ItemStack(model.itemType(), model.amount(), model.durability());
itemStack.nbtData(model.nbt());
itemStack.displayName(ChatElement.ofLegacyText(model.displayName()));
itemStack.lore(model.lore().stream().map(ChatElement::ofLegacyText).collect(Collectors.toList()));
return InventoryMenuItemWrapper.builder()
.handle(Converters.convert(itemStack, MenuItemWrapper.class))
.actionArguments(model.actionArguments())
.actionHandler(model.actionHandler())
.build();
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/ItemStackConverter.java
================================================
package dev.simplix.cirrus.bungeecord.converters;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;
import dev.simplix.protocolize.api.item.ItemStack;
import lombok.NonNull;
public class ItemStackConverter implements Converter {
@Override
public MenuItemWrapper convert(@NonNull ItemStack itemStack) {
return new ProtocolizeMenuItemWrapper(itemStack);
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/PlayerConverter.java
================================================
package dev.simplix.cirrus.bungeecord.converters;
import dev.simplix.cirrus.bungeecord.BungeeCordPlayerWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import lombok.NonNull;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import org.jetbrains.annotations.NotNull;
public final class PlayerConverter implements Converter {
@Override
public PlayerWrapper convert(@NonNull @NotNull ProxiedPlayer proxiedPlayer) {
return new BungeeCordPlayerWrapper(proxiedPlayer);
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/PlayerUniqueIdConverter.java
================================================
package dev.simplix.cirrus.bungeecord.converters;
import dev.simplix.cirrus.bungeecord.BungeeCordPlayerWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import lombok.NonNull;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
public class PlayerUniqueIdConverter implements Converter {
@Override
public PlayerWrapper convert(@NonNull UUID uuid) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
if (player == null) {
throw new IllegalArgumentException("Player " + uuid + " is offline");
}
return new BungeeCordPlayerWrapper(player);
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/listeners/QuitListener.java
================================================
package dev.simplix.cirrus.bungeecord.listeners;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import lombok.NonNull;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
public class QuitListener implements Listener {
@EventHandler
public void onQuit(@NonNull PlayerDisconnectEvent event) {
Cirrus.getService(MenuBuilder.class).destroyMenusOfPlayer(event.getPlayer().getUniqueId());
}
}
================================================
FILE: cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/protocolize/ProtocolizeMenuBuilder.java
================================================
package dev.simplix.cirrus.bungeecord.protocolize;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import dev.simplix.cirrus.bungeecord.BungeeCordPlayerWrapper;
import dev.simplix.cirrus.common.Utils;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.i18n.Replacer;
import dev.simplix.cirrus.common.menu.AbstractMenu;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.cirrus.common.model.Click;
import dev.simplix.protocolize.api.ClickType;
import dev.simplix.protocolize.api.chat.ChatElement;
import dev.simplix.protocolize.api.inventory.Inventory;
import dev.simplix.protocolize.api.item.BaseItemStack;
import dev.simplix.protocolize.api.item.ItemStack;
import dev.simplix.protocolize.api.player.ProtocolizePlayer;
import dev.simplix.protocolize.data.packets.OpenWindow;
import dev.simplix.protocolize.data.packets.WindowItems;
import lombok.NonNull;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.chat.ComponentSerializer;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public class ProtocolizeMenuBuilder implements MenuBuilder {
private final Map> buildMap = new LinkedHashMap<>();
private final Set menus = Sets.newConcurrentHashSet();
@Override
public T build(@Nullable T prebuild, @NonNull Menu menu) {
final Entry menuLongEntry = this.buildMap.get(menu.player().uniqueId());
if (menuLongEntry != null && !menuLongEntry.getKey().equals(menu)) {
menuLongEntry.getKey().handleClose(true);
}
if (!(menu instanceof AbstractMenu)) {
throw new IllegalArgumentException("This implementation can only build cirrus menus!");
}
final boolean register = prebuild == null;
if (prebuild instanceof Inventory) {
String title = Replacer.of(menu.title()).replaceAll((Object[]) menu.replacements().get())
.replacedMessageJoined();
final Inventory inventory = (Inventory) prebuild;
final BaseComponent[] component = TextComponent.fromLegacyText(title);
for (BaseComponent baseComponent : component) {
baseComponent.setItalic(false); // Wir kommen nicht aus Italien
}
if (!ComponentSerializer.toString((BaseComponent[]) inventory.title().asComponent())
.equals(ComponentSerializer.toString(component)) ||
inventory.type().getTypicalSize(menu.player().protocolVersion()) != menu
.topContainer()
.capacity()
|| inventory.type() != menu.inventoryType()) {
prebuild = (T) makeInv(menu);
}
} else {
prebuild = (T) makeInv(menu);
}
final Inventory inventory = (Inventory) prebuild;
buildContainer(inventory, menu.topContainer());
buildContainer(inventory, menu.bottomContainer());
this.buildMap.put(
menu.player().uniqueId(),
new AbstractMap.SimpleEntry<>(menu, System.currentTimeMillis()));
if (register) {
this.menus.add(menu);
}
open(menu.player(), inventory);
return prebuild;
}
private void buildContainer(@NonNull Inventory inventory, @NonNull Container container) {
for (int i = container.baseSlot(); i < container.baseSlot() + container.capacity(); i++) {
InventoryMenuItemWrapper item = container.itemMap().get(i);
BaseItemStack currentStack = inventory.item(i);
if (item == null) {
if (currentStack != null) {
inventory.item(i, ItemStack.NO_DATA);
}
}
if (item != null) {
for (BaseComponent[] loreComponent : item.loreComponents()) {
for (BaseComponent baseComponent : loreComponent) {
// if (!baseComponent.isItalic()) {
// baseComponent.setItalic(false);
// }
}
}
if (currentStack == null) {
if (item.handle() == null) {
ProxyServer.getInstance().getLogger()
.severe("InventoryItem's ItemStackWrapper is null @ slot " + i);
continue;
}
inventory.item(i, item.handle());
} else {
if (!currentStack.equals(item.handle())) {
inventory.item(i, item.handle());
}
}
}
}
}
private Inventory makeInv(@NonNull Menu menu) {
Inventory inventory = new Inventory(menu.inventoryType());
BaseComponent[] textComponent = TextComponent.fromLegacyText(Replacer.of(menu.title())
.replaceAll((Object[]) menu.replacements().get()).replacedMessageJoined());
for (BaseComponent component : textComponent) {
if (!component.isItalic()) {
component.setItalic(false); // Resolve client side behavior
}
}
inventory.title(ChatElement.of(textComponent));
inventory.onClose(inventoryClose -> {
Map.Entry lastBuild = lastBuildOfPlayer(inventoryClose.player().uniqueId());
if (((AbstractMenu) lastBuild.getKey()).internalId() == ((AbstractMenu) menu).internalId()
&& (System.currentTimeMillis() - lastBuild.getValue()) <= 55) {
return;
}
menu.handleClose((System.currentTimeMillis() - lastBuild.getValue()) <= 55);
invalidate(menu);
});
inventory.onClick(inventoryClick -> {
if (inventoryClick.clickType() == null) {
return;
}
if (inventoryClick.player() == null) {
return;
}
Inventory i = inventoryClick.inventory();
if (i == null) {
return;
}
// ProxyServer.getInstance().broadcast("Clicked inventory");
// ProxyServer.getInstance().broadcast("Clicked menu: " + menu.getClass().getSimpleName() + " @ slot " + inventoryClick.slot());
Container container;
if (inventoryClick.slot() > menu.topContainer().capacity() - 1) {
container = menu.bottomContainer();
// ProxyServer.getInstance().broadcast("Clicked bottom container");
} else {
container = menu.topContainer();
// ProxyServer.getInstance().broadcast("Clicked top container");
}
InventoryMenuItemWrapper item = container.get(inventoryClick.slot());
ClickType type = inventoryClick.clickType();
if (item == null) {
// ProxyServer.getInstance().broadcast("Clicked nothing");
if (menu.customActionHandler() != null) {
try {
CallResult callResult = menu
.customActionHandler()
.handle(new Click(type, menu, null, inventoryClick.slot()));
inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);
} catch (Exception ex) {
inventoryClick.cancelled(true);
menu.handleException(null, ex);
}
}
return;
}
// ProxyServer.getInstance().broadcast("Clicked " + item.displayName());
ActionHandler actionHandler = menu.actionHandler(item.actionHandler());
if (actionHandler == null) {
inventoryClick.cancelled(true);
return;
}
try {
final CallResult callResult = actionHandler.handle(new Click(
type,
menu,
item,
inventoryClick.slot()));
inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);
} catch (final Exception ex) {
inventoryClick.cancelled(true);
menu.handleException(actionHandler, ex);
}
});
return inventory;
}
@Override
public void open(
PlayerWrapper playerWrapper, T inventoryImpl) {
if (playerWrapper instanceof BungeeCordPlayerWrapper) {
final ProtocolizePlayer protocolizePlayer = ((BungeeCordPlayerWrapper) playerWrapper).protocolizePlayer();
final Inventory inventory = (Inventory) inventoryImpl;
boolean alreadyOpen = false;
int windowId = -1;
for (Integer id : protocolizePlayer.registeredInventories().keySet()) {
Inventory val = protocolizePlayer.registeredInventories().get(id);
if (val.type() == inventory.type() && val.title().equals(inventory.title())) {
alreadyOpen = true;
break;
}
}
// Close all inventories if not opened
if (!alreadyOpen) {
protocolizePlayer.closeInventory();
}
if (protocolizePlayer.registeredInventories().containsValue(inventory)) {
for (Integer id : protocolizePlayer.registeredInventories().keySet()) {
Inventory val = protocolizePlayer.registeredInventories().get(id);
if (val == inventory) {
windowId = id;
break;
}
}
if (windowId == -1) {
windowId = protocolizePlayer.generateWindowId();
protocolizePlayer.registerInventory(windowId, inventory);
}
} else {
windowId = protocolizePlayer.generateWindowId();
protocolizePlayer.registerInventory(windowId, inventory);
}
if (!alreadyOpen) {
protocolizePlayer.sendPacket(new OpenWindow(windowId, inventory.type(), inventory.title()));
}
int protocolVersion;
try {
protocolVersion = protocolizePlayer.protocolVersion();
} catch (Throwable t) {
protocolVersion = 47;
}
List items = Lists.newArrayList(inventory.itemsIndexed(protocolVersion));
protocolizePlayer.sendPacket(new WindowItems((short) windowId, items, 0));
}
}
private void removeItalic(BaseComponent[] components) {
for (BaseComponent component : components) {
component.setItalic(false);
}
}
@Override
@Nullable
public Menu menuByHandle(Object handle) {
if (handle == null) {
return null;
}
for (final Menu menu : this.menus) {
if (menu.equals(handle)) {
return menu;
}
}
return null;
}
@Override
public void destroyMenusOfPlayer(@NonNull UUID uniqueId) {
this.menus.removeIf(
wrapper -> ((ProxiedPlayer) wrapper.player().handle()).getUniqueId().equals(uniqueId));
this.buildMap.remove(uniqueId);
}
@Override
public Entry lastBuildOfPlayer(@NonNull UUID uniqueId) {
return this.buildMap.get(uniqueId);
}
@Override
public void invalidate(@NonNull Menu menu) {
this.menus.remove(menu);
}
}
================================================
FILE: cirrus-bungeecord-example/pom.xml
================================================
4.0.0
dev.simplix.cirrus
cirrus
2.0.0
dev.simplix.cirrus
cirrus-bungeecord-example
${cirrus.version}
cirrus-common
dev.simplix.cirrus
compile
${cirrus.version}
cirrus-bungeecord
dev.simplix.cirrus
compile
${cirrus.version}
net.md-5
bungeecord-api
1.21-R0.1-SNAPSHOT
provided
${project.name}-${project.version}
src/main/resources
true
org.apache.maven.plugins
maven-shade-plugin
3.0.0
package
shade
org.apache.maven.plugins
maven-compiler-plugin
8
8
================================================
FILE: cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/CirrusExamplePlugin.java
================================================
package dev.simplix.cirrus.bungeecord.example;
import dev.simplix.cirrus.bungeecord.CirrusBungeeCord;
import dev.simplix.cirrus.bungeecord.example.commands.TestCommand;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
public class CirrusExamplePlugin extends Plugin {
@Override
public void onEnable() {
CirrusBungeeCord.init(this);
ProxyServer.getInstance().getPluginManager().registerCommand(this, new TestCommand());
}
}
================================================
FILE: cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/commands/TestCommand.java
================================================
package dev.simplix.cirrus.bungeecord.example.commands;
import dev.simplix.cirrus.bungeecord.example.menus.ExampleMenu;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
public class TestCommand extends Command {
public TestCommand() {
super("test");
}
@Override
public void execute(CommandSender sender, String[] args) {
if (sender instanceof ProxiedPlayer) {
ProxiedPlayer proxy = (ProxiedPlayer) sender;
new ExampleMenu(Converters.convert(proxy, PlayerWrapper.class),
Cirrus.configurationFactory().loadFile("plugins/Cirrus/example.json")).open();
}
}
}
================================================
FILE: cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/menus/ExampleMenu.java
================================================
package dev.simplix.cirrus.bungeecord.example.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import java.util.Locale;
public class ExampleMenu extends AbstractConfigurableMenu {
public ExampleMenu(PlayerWrapper player, MenuConfiguration configuration) {
super(player, configuration, Locale.ENGLISH);
registerActionHandler("tnt", click -> {
topContainer().itemMap().remove(click.slot());
title("Hello, {viewer}");
build();
player().sendMessage("It simply works :)");
return CallResult.DENY_GRABBING;
});
}
}
================================================
FILE: cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/menus/ExampleMultiPageMenu.java
================================================
package dev.simplix.cirrus.bungeecord.example.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.menus.MultiPageMenu;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.item.ItemStack;
import dev.simplix.protocolize.api.providers.MappingProvider;
import dev.simplix.protocolize.data.ItemType;
import java.util.Collections;
import java.util.Locale;
public class ExampleMultiPageMenu extends MultiPageMenu {
private final MappingProvider mappingProvider = Protocolize.mappingProvider();
public ExampleMultiPageMenu(
PlayerWrapper player,
MultiPageMenuConfiguration configuration) {
super(player, configuration, Locale.ENGLISH);
registerMyActionHandlers();
addItems();
}
private void registerMyActionHandlers() {
registerActionHandler("test", click -> {
player().sendMessage("This is " + click.clickedItem().type().name());
return CallResult.DENY_GRABBING;
});
}
private void addItems() {
for (ItemType type : ItemType.values()) {
if (this.mappingProvider.mapping(type, player().protocolVersion()) != null) {
add(wrapItemStack(new ItemStack(type)), "test", Collections.emptyList());
}
}
}
}
================================================
FILE: cirrus-bungeecord-example/src/main/resources/plugin.yml
================================================
name: CirrusExample
author: Exceptionflug
version: 1.0
main: dev.simplix.cirrus.bungeecord.example.CirrusExamplePlugin
softdepend:
- simplixcore
commands:
test:
description: hi
================================================
FILE: cirrus-common/pom.xml
================================================
cirrus-common
maven-compiler-plugin
8
8
org.apache.maven.plugins
org.apache.maven.plugins
maven-source-plugin
3.0.1
attach-sources
deploy
jar-no-fork
org.apache.maven.plugins
maven-javadoc-plugin
3.0.1
attach-javadocs
jar
none
org.slf4j
slf4j-api
1.8.0-alpha2
provided
4.0.0
cirrus
dev.simplix.cirrus
2.0.0
${cirrus.version}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/Cirrus.java
================================================
package dev.simplix.cirrus.common;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.simplix.cirrus.common.business.ConfigurationFactory;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.config.JsonConfigurationFactory;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.i18n.*;
import dev.simplix.cirrus.common.mojangson.TagDeserializer;
import dev.simplix.cirrus.common.mojangson.TagSerializer;
import net.querz.nbt.tag.CompoundTag;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Cirrus {
private static final Map, Object> SERVICES = new ConcurrentHashMap<>();
public static Gson gson() {
return GSON;
}
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(CompoundTag.class, new TagSerializer())
.registerTypeAdapter(CompoundTag.class, new TagDeserializer())
.registerTypeAdapter(LocalizedString.class, new LocalizedStringSerializer())
.registerTypeAdapter(LocalizedString.class, new LocalizedStringDeserializer())
.registerTypeAdapter(LocalizedStringList.class, new LocalizedStringListSerializer())
.registerTypeAdapter(LocalizedStringList.class, new LocalizedStringListDeserializer())
.setPrettyPrinting()
.create();
static {
Converters.register(
InventoryMenuItemWrapper.class, MenuItemWrapper.class,
(Converter) InventoryMenuItemWrapper::wrapper);
registerService(ConfigurationFactory.class, new JsonConfigurationFactory(GSON));
}
/**
* This returns an instance of a registered service.
*
* @param type The registration type of the desired service
* @param The type of the service
* @return The instance of T or null if there is no service with this registration type
* @see Cirrus#registerService(Class, Object)
*/
public static T getService(Class type) {
return (T) SERVICES.get(type);
}
/**
* This will map a given service instance to a given registration type.
*
* @param type The registration type of the desired service
* @param instance An instance of the registration type
* @param The registration type
*/
public static void registerService(Class type, T instance) {
SERVICES.put(type, instance);
}
public static ConfigurationFactory configurationFactory() {
return getService(ConfigurationFactory.class);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/Utils.java
================================================
package dev.simplix.cirrus.common;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.chat.BaseComponent;
import net.querz.nbt.tag.*;
@UtilityClass
public class Utils {
private static final String STEVE_TEXTURE = "ewogICJ0aW1lc3RhbXAiIDogMTU5MTU3NDcyMzc4MywKICAicHJvZmlsZUlkIiA6ICI4NjY3YmE3MWI4NWE0MDA0YWY1NDQ1N2E5NzM0ZWVkNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJTdGV2ZSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82ZDNiMDZjMzg1MDRmZmMwMjI5Yjk0OTIxNDdjNjlmY2Y1OWZkMmVkNzg4NWY3ODUwMjE1MmY3N2I0ZDUwZGUxIgogICAgfSwKICAgICJDQVBFIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS85NTNjYWM4Yjc3OWZlNDEzODNlNjc1ZWUyYjg2MDcxYTcxNjU4ZjIxODBmNTZmYmNlOGFhMzE1ZWE3MGUyZWQ2IgogICAgfQogIH0KfQ==";
public void removeItalic(BaseComponent[] components) {
for (BaseComponent component : components) {
component.setItalic(false);
}
}
public static void hideNbtFlags(CompoundTag tag) {
tag.put("HideFlags", new IntTag(127));
}
public static void glow(CompoundTag tag) {
hideNbtFlags(tag);
final ListTag enchantments = new ListTag<>(CompoundTag.class);
final ListTag enchs = new ListTag<>(CompoundTag.class);
final CompoundTag exampleEnchantment = new CompoundTag();
exampleEnchantment.put("id", new StringTag("minecraft:efficiency"));
exampleEnchantment.put("lvl", new ShortTag((short) 1));
final CompoundTag exampleEnch = new CompoundTag();
exampleEnch.put("id", new ShortTag((short) 1));
exampleEnch.put("lvl", new ShortTag((short) 1));
enchantments.add(exampleEnchantment);
enchs.add(exampleEnch);
tag.put("ench", enchs);
tag.put("Enchantments", enchantments);
}
public static void texture(CompoundTag tag, String textureHash) {
if (!(tag.get("SkullOwner") instanceof CompoundTag)) {
tag.put("SkullOwner", new CompoundTag());
}
CompoundTag skullOwner = tag.getCompoundTag("SkullOwner");
if (skullOwner == null) {
skullOwner = new CompoundTag();
}
skullOwner.put("Name", new StringTag(textureHash));
CompoundTag properties = skullOwner.getCompoundTag("Properties");
if (properties == null) {
properties = new CompoundTag();
}
CompoundTag texture = new CompoundTag();
texture.put(
"Value",
new StringTag(textureHash.isEmpty() ? STEVE_TEXTURE : textureHash));
ListTag textures = new ListTag<>(CompoundTag.class);
textures.add(texture);
properties.put("textures", textures);
skullOwner.put("Properties", properties);
tag.put("SkullOwner", skullOwner);
}
public static int calculateSizeForContent(final int items) {
return (
items <= 9 ?
9 * 1 : items <= 9 * 2 ? 9 * 2 : items <= 9 * 3 ? 9 * 3
: items <= 9 * 4 ? 9 * 4 : 9 * 5) + 9;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/business/ConfigurationFactory.java
================================================
package dev.simplix.cirrus.common.business;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.configuration.impl.SimpleMenuConfiguration;
import dev.simplix.cirrus.common.configuration.impl.SimpleMultiPageMenuConfiguration;
import lombok.NonNull;
public interface ConfigurationFactory {
default MenuConfiguration loadFile(@NonNull String file) {
return loadFile(file, SimpleMenuConfiguration.class);
}
default MenuConfiguration loadResource(@NonNull String resourcePath, @NonNull Class> caller) {
return loadResource(resourcePath, caller, SimpleMenuConfiguration.class);
}
default MultiPageMenuConfiguration loadFileForMultiPageMenu(@NonNull String file) {
return loadFile(file, SimpleMultiPageMenuConfiguration.class);
}
default MultiPageMenuConfiguration loadResourcesForMultiPageMenu(
@NonNull String resourcePath,
@NonNull Class> caller) {
return loadResource(resourcePath, caller, SimpleMultiPageMenuConfiguration.class);
}
T loadFile(@NonNull String file, @NonNull Class type);
T loadResource(
@NonNull String resourcePath,
@NonNull Class> caller,
@NonNull Class type);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/business/DataInventoryMenuItemWrapper.java
================================================
package dev.simplix.cirrus.common.business;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.List;
@Accessors(fluent = true)
@Getter
@ToString(callSuper = true)
public class DataInventoryMenuItemWrapper extends InventoryMenuItemWrapper {
private final T data;
public DataInventoryMenuItemWrapper(
@NonNull MenuItemWrapper handle,
@NonNull String actionHandler,
@NonNull List actionArguments, T data) {
super(handle, actionHandler, actionArguments);
this.data = data;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/business/InventoryMenuItemWrapper.java
================================================
package dev.simplix.cirrus.common.business;
import dev.simplix.protocolize.data.ItemType;
import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.md_5.bungee.api.chat.BaseComponent;
import net.querz.nbt.tag.CompoundTag;
import java.util.List;
@Accessors(fluent = true)
@Builder
public class InventoryMenuItemWrapper implements MenuItemWrapper {
private final MenuItemWrapper handle;
@Getter
@Setter
private String actionHandler;
@Getter
@Setter
private List actionArguments;
@Override
public String displayName() {
return this.handle.displayName();
}
@Override
public BaseComponent[] displayNameComponents() {
return this.handle.displayNameComponents();
}
@Override
public List lore() {
return this.handle.lore();
}
@Override
public List loreComponents() {
return this.handle.loreComponents();
}
@Override
public ItemType type() {
return this.handle.type();
}
@Override
public CompoundTag nbt() {
return this.handle.nbt();
}
@Override
public int amount() {
return this.handle.amount();
}
@Override
public short durability() {
return this.handle.durability();
}
@Override
public void type(@NonNull ItemType type) {
this.handle.type(type);
}
@Override
public void displayName(@NonNull String displayName) {
this.handle.displayName(displayName);
}
@Override
public void displayNameComponents(@NonNull BaseComponent... baseComponents) {
this.handle.displayNameComponents(baseComponents);
}
@Override
public void lore(@NonNull List lore) {
this.handle.lore(lore);
}
@Override
public void loreComponents(@NonNull List lore) {
this.handle.loreComponents(lore);
}
@Override
public void nbt(@NonNull CompoundTag tag) {
this.handle.nbt(tag);
}
@Override
public void amount(int amount) {
this.handle.amount(amount);
}
@Override
public void durability(short durability) {
this.handle.durability(durability);
}
@Override
public T handle() {
return this.handle.handle();
}
public MenuItemWrapper wrapper() {
return this.handle;
}
@Override
public String toString() {
return "InventoryItemWrapper{" +
"handle=" + this.handle +
", actionHandler='" + this.actionHandler + '\'' +
", actionArguments=" + this.actionArguments +
'}';
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/business/MenuItemWrapper.java
================================================
package dev.simplix.cirrus.common.business;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import net.md_5.bungee.api.chat.BaseComponent;
import net.querz.nbt.tag.CompoundTag;
import java.util.List;
/**
* An {@link MenuItemWrapper} provides uniform data access for items across different platforms.
* Please be aware, that most of the given properties are immutable, so you have to set them using
* their setter after you have done some changes.
*/
public interface MenuItemWrapper {
/**
* Returns the display name of an item as a string.
*
* @return display name
*/
String displayName();
/**
* Returns the display name of an item as component array.
*
* @return display name
*/
BaseComponent[] displayNameComponents();
/**
* The lore of the item as strings.
*
* @return lore
*/
List lore();
/**
* The lore of the item as component arrays.
*
* @return lore
*/
List loreComponents();
/**
* The {@link ItemType} of the item.
*
* @return item type
*/
ItemType type();
/**
* This returns a querz-nbt {@link CompoundTag} with the nbt information about this item. Please
* be aware, that the nbt data of spigot ItemStacks are immutable. So you have to call setNBT()
* after you changed the data to set them.
*
* @return nbt data
*/
CompoundTag nbt();
/**
* Returns the amount of the stack
*
* @return amount
*/
int amount();
/**
* Returns the durability of the item.
*
* @return
*/
short durability();
/**
* Sets the mcc item type.
*
* @param type type to set
*/
void type(@NonNull ItemType type);
/**
* Sets the display name of the item
*
* @param displayName name
*/
void displayName(@NonNull String displayName);
/**
* Sets the display name of the item
*
* @param baseComponents name
*/
void displayNameComponents(@NonNull BaseComponent... baseComponents);
/**
* Sets the lore of the item
*
* @param lore
*/
void lore(List lore);
/**
* Sets the lore of the item
*
* @param lore
*/
void loreComponents(@NonNull List lore);
/**
* Sets the nbt data.
*
* @param tag nbt data
*/
void nbt(@NonNull CompoundTag tag);
/**
* Sets the stack amount.
*
* @param amount amount
*/
void amount(int amount);
/**
* Sets the durability.
* #DUDELAVERITY
*
* @param durability durability
*/
void durability(short durability);
/**
* Returns the handle of the wrapper
*
* @param dyncast handle type
* @return the handle
*/
T handle();
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/business/PlayerWrapper.java
================================================
package dev.simplix.cirrus.common.business;
import lombok.NonNull;
import java.util.UUID;
public interface PlayerWrapper {
void sendMessage(@NonNull String msg);
void closeInventory();
boolean hasPermission(@NonNull String permission);
UUID uniqueId();
String name();
int protocolVersion();
T handle();
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/config/JsonConfigurationFactory.java
================================================
package dev.simplix.cirrus.common.config;
import com.google.common.io.ByteStreams;
import com.google.gson.Gson;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.ConfigurationFactory;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import lombok.NonNull;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.util.Objects;
public class JsonConfigurationFactory implements ConfigurationFactory {
private final Gson gson;
public JsonConfigurationFactory(Gson gson) {
this.gson = gson;
}
@Override
public T loadFile(
@NonNull String filename,
@NonNull Class type) {
File file = new File(filename);
if (!file.exists()) {
if (file.getParentFile() != null) {
file.getParentFile().mkdirs();
}
copyResourceToFile("/cirrus/" + type.getSimpleName() + ".json", file);
}
try (
InputStreamReader reader = new InputStreamReader(
Files.newInputStream(file.toPath()),
StandardCharsets.UTF_8)) {
return this.gson.fromJson(reader, type);
} catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
@Override
public T loadResource(
@NonNull String resourcePath,
@NonNull Class> caller,
@NonNull Class type) {
try (InputStream stream = caller.getResourceAsStream(resourcePath)) {
if (stream == null) {
throw new NoSuchFileException("Unable to find resource " + resourcePath);
}
String contents = new String(ByteStreams.toByteArray(stream), StandardCharsets.UTF_8);
return this.gson.fromJson(contents, type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void copyResourceToFile(@NonNull String resource, @NonNull File file) {
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
fileOutputStream.write(ByteStreams.toByteArray(
Objects.requireNonNull(Cirrus.class.getResourceAsStream(resource), "Inputstream is null")));
fileOutputStream.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/MenuConfiguration.java
================================================
package dev.simplix.cirrus.common.configuration;
import com.google.common.base.Preconditions;
import dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;
import dev.simplix.cirrus.common.i18n.LocalizedString;
public interface MenuConfiguration {
default LocalizedItemStackModel forceBusinessItem(String keyword) {
return Preconditions.checkNotNull(
businessItems().get(keyword),
"No business-item named '" + keyword + "' found"
);
}
LocalizedString title();
dev.simplix.protocolize.data.inventory.InventoryType type();
LocalizedItemStackModel placeholderItem();
int[] reservedSlots();
LocalizedItemStackModel[] items();
java.util.Map businessItems();
MenuConfiguration title(LocalizedString title);
MenuConfiguration type(dev.simplix.protocolize.data.inventory.InventoryType type);
MenuConfiguration placeholderItem(LocalizedItemStackModel placeholderItem);
MenuConfiguration reservedSlots(int[] reservedSlots);
MenuConfiguration items(LocalizedItemStackModel[] items);
MenuConfiguration businessItems(java.util.Map businessItems);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/MultiPageMenuConfiguration.java
================================================
package dev.simplix.cirrus.common.configuration;
import dev.simplix.cirrus.common.i18n.LocalizedString;
import dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;
public interface MultiPageMenuConfiguration extends MenuConfiguration {
LocalizedItemStackModel nextPageItem();
LocalizedItemStackModel previousPageItem();
MultiPageMenuConfiguration title(LocalizedString title);
MultiPageMenuConfiguration type(dev.simplix.protocolize.data.inventory.InventoryType type);
MultiPageMenuConfiguration placeholderItem(LocalizedItemStackModel placeholderItem);
MultiPageMenuConfiguration reservedSlots(int[] reservedSlots);
MultiPageMenuConfiguration items(LocalizedItemStackModel[] items);
MultiPageMenuConfiguration businessItems(java.util.Map businessItems);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/impl/SimpleMenuConfiguration.java
================================================
package dev.simplix.cirrus.common.configuration.impl;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.i18n.LocalizedString;
import dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;
import dev.simplix.protocolize.data.inventory.InventoryType;
import java.util.HashMap;
import java.util.Map;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Accessors(fluent = true)
@NoArgsConstructor
public class SimpleMenuConfiguration implements MenuConfiguration {
private LocalizedString title;
private InventoryType type;
private LocalizedItemStackModel placeholderItem;
private int[] reservedSlots = new int[0];
private LocalizedItemStackModel[] items = new LocalizedItemStackModel[0];
private Map businessItems = new HashMap<>();
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/impl/SimpleMultiPageMenuConfiguration.java
================================================
package dev.simplix.cirrus.common.configuration.impl;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.i18n.LocalizedString;
import dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;
import dev.simplix.protocolize.data.inventory.InventoryType;
import java.util.HashMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Builder
@Accessors(fluent = true)
@AllArgsConstructor
@NoArgsConstructor
public class SimpleMultiPageMenuConfiguration implements MultiPageMenuConfiguration {
private LocalizedItemStackModel nextPageItem;
private LocalizedItemStackModel previousPageItem;
private LocalizedString title;
private InventoryType type;
private LocalizedItemStackModel placeholderItem;
private int[] reservedSlots = new int[0];
private LocalizedItemStackModel[] items = new LocalizedItemStackModel[0];
private Map businessItems = new HashMap<>();
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/container/Container.java
================================================
package dev.simplix.cirrus.common.container;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.item.CirrusItem;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A container stores {@link InventoryMenuItemWrapper}s at a given slot position.
*/
public interface Container {
/**
* Returns a map collecting all items.
*
* @return The map
*/
Map itemMap();
/**
* Returns a set with slots that are marked as reserved
*
* @return The set
*/
Set reservedSlots();
/**
* Returns the maximum capacity of this container
*
* @return the maximum amount of items this container can hold
*/
int capacity();
/**
* Returns the initial slot id of this container
*
* @return Initial slot id
*/
int baseSlot();
/**
* @return the slot index of the next available empty slot or -1 if no slot is empty
*/
int nextFreeSlot();
/**
* @return the slot index of the next available empty slot or -1 after the specified index
*/
int nextFreeSlot(int i);
/**
* Sets an item into the next free slot. Free slots are slots where no item has been set and the
* slot is not marked as reserved.
*
* @param inventoryItemWrapper The item to set
*/
default void add(InventoryMenuItemWrapper inventoryItemWrapper) {
set(nextFreeSlot(), inventoryItemWrapper);
}
/**
* Sets an item into the next free slot. Free slots are slots where no item has been set and the
* slot is not marked as reserved.
*
* @param menuItemWrapper The item stack to set
* @param actionHandler The action handler which should be called on click
* @param actionArgs the arguments for that click
*/
default void add(
MenuItemWrapper menuItemWrapper,
String actionHandler,
List actionArgs) {
set(nextFreeSlot(), InventoryMenuItemWrapper.builder()
.handle(menuItemWrapper)
.actionHandler(actionHandler)
.actionArguments(actionArgs)
.build());
}
/**
* Sets an item into the next free slot. Free slots are slots where no item has been set and the
* slot is not marked as reserved.
*
* @param model The item stack model
*/
default void add(CirrusItem model) {
set(nextFreeSlot(), InventoryMenuItemWrapper.builder()
.handle(Converters.convert(model, InventoryMenuItemWrapper.class))
.actionHandler(model.actionHandler())
.actionArguments(model.actionArguments())
.build());
}
/**
* Sets an item into a given position in the container
*
* @param slot The slot the item will be located at
* @param inventoryItemWrapper The item stack wrapper
*/
default void set(int slot, InventoryMenuItemWrapper inventoryItemWrapper) {
itemMap().put(slot, inventoryItemWrapper);
}
/**
* Sets an item into a given position in the container
*
* @param slot The slot the item will be located at
* @param menuItemWrapper The item stack wrapper
* @param actionHandler The handler that handles the click
* @param actionArgs Arguments for the action handler
*/
default void set(
int slot,
MenuItemWrapper menuItemWrapper,
String actionHandler,
List actionArgs) {
set(slot, InventoryMenuItemWrapper.builder()
.handle(menuItemWrapper)
.actionHandler(actionHandler)
.actionArguments(actionArgs)
.build());
}
/**
* Sets an item into a given position in the container
*
* @param slot The slot the item will be located at
* @param model The item stack model
*/
default void set(int slot, CirrusItem model) {
set(slot, InventoryMenuItemWrapper.builder()
.handle(Converters.convert(model, InventoryMenuItemWrapper.class))
.actionHandler(model.actionHandler())
.actionArguments(model.actionArguments())
.build());
}
/**
* Returns the item stack from the given position
*
* @param slot slot
* @return item
*/
default InventoryMenuItemWrapper get(int slot) {
return itemMap().get(slot);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/container/impl/ItemContainer.java
================================================
package dev.simplix.cirrus.common.container.impl;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.util.InventoryContentMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import lombok.NonNull;
public class ItemContainer implements Container {
private final InventoryContentMap inventoryContentMap = new InventoryContentMap();
private final Set reservedSlots = new HashSet<>();
private final int baseSlotIndex;
private final int capacity;
public ItemContainer(int baseSlotIndex, int capacity) {
this.baseSlotIndex = baseSlotIndex;
this.capacity = capacity;
}
@Override
public void set(int slot, @NonNull InventoryMenuItemWrapper inventoryItemWrapper) {
itemMap().put(slot + this.baseSlotIndex, inventoryItemWrapper);
}
@Override
public Map itemMap() {
return this.inventoryContentMap;
}
@Override
public Set reservedSlots() {
return this.reservedSlots;
}
@Override
public int capacity() {
return this.capacity;
}
@Override
public int baseSlot() {
return this.baseSlotIndex;
}
@Override
public int nextFreeSlot() {
for (int i = this.baseSlotIndex; i < this.capacity + this.baseSlotIndex; i++) {
if (!itemMap().containsKey(i) && !reservedSlots().contains(i)) {
return i;
}
}
return -1;
}
@Override
public int nextFreeSlot(int base) {
for (int i = base; i < this.capacity + this.baseSlotIndex; i++) {
if (!itemMap().containsKey(i) && !reservedSlots().contains(i)) {
return i;
}
}
return -1;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/converter/Converter.java
================================================
package dev.simplix.cirrus.common.converter;
import lombok.NonNull;
/**
* A converter is used to convert one object to another.
*
* @param The source type of the object
* @param The target type ot the object
*/
public interface Converter {
/**
* Converts a given source object to the target type.
*
* @param src The source object
* @return The target object
*/
Target convert(@NonNull Source src);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/converter/Converters.java
================================================
package dev.simplix.cirrus.common.converter;
import lombok.NonNull;
import org.jetbrains.annotations.Nullable;
import java.util.AbstractMap.SimpleEntry;
import java.util.*;
import java.util.Map.Entry;
/**
* Central registration class for {@link Converter}s.
*/
@SuppressWarnings("rawtypes")
public final class Converters {
private static final Map, Converter> CONVERTER_MAP = new HashMap<>();
private Converters() {
}
/**
* Converts a source object to a given type.
*
* @param source The source object to convert
* @param to The target type class
* @param The target type
* @return An object instance of the target type
*/
public static T convert(@NonNull final Object source, @NonNull final Class to) {
Converter converter = getConverter(source.getClass(), to);
if (converter == null) {
converter = getMultiConverter(source.getClass(), to);
}
if (converter == null) {
throw new NullPointerException("No converter available to convert " + source
.getClass()
.getName() + " to " + to.getName());
}
return (T) converter.convert(source);
}
private static Converter getMultiConverter(
@NonNull final Class source,
@NonNull final Class to) {
final List converters = new ArrayList<>();
findConversionRoute(converters, source, to);
if (converters.size() <= 1) {
return null;
}
return src -> {
Object out = src;
for (final Converter converter : converters) {
out = converter.convert(out);
}
return (T) out;
};
}
private static boolean findConversionRoute(
@NonNull final List converters,
@NonNull final Class> source,
@NonNull final Class> to) {
for (final Entry entry : CONVERTER_MAP.keySet()) {
if (entry.getKey().equals(source)) {
final List list = new ArrayList<>();
if (buildRoute(list, entry, to)) {
list.add(CONVERTER_MAP.get(entry));
Collections.reverse(list);
converters.addAll(list);
return true;
}
}
}
return false;
}
private static boolean buildRoute(
@NonNull final List converters,
@NonNull final Map.Entry entry,
@NonNull final Class> to) {
if (entry.getValue().equals(to)) {
return true;
}
for (final Entry entry1 : CONVERTER_MAP.keySet()) {
if (entry1.getKey().equals(entry.getValue())) {
if (buildRoute(converters, entry1, to)) {
converters.add(CONVERTER_MAP.get(entry1));
return true;
}
}
}
return false;
}
/**
* Registers a {@link Converter} for a given type conversion.
*
* @param sourceType The source type
* @param targetType The target type
* @param converter The convert instance
*/
public static void register(
@NonNull final Class> sourceType,
@NonNull final Class targetType,
@NonNull final Converter converter) {
CONVERTER_MAP.put(new SimpleEntry<>(sourceType, targetType), converter);
}
/**
* Returns a registered converter
*
* @param sourceType The source type class
* @param targetType The target type class
* @param The source type
* @param The target type
* @return The converter instance or null if no such converter exists
*/
@Nullable
public static Converter getConverter(
final Class sourceType,
final Class targetType) {
Converter converter = CONVERTER_MAP.get(new SimpleEntry<>(sourceType, targetType));
if (converter == null) {
for (Entry entry : CONVERTER_MAP.keySet()) {
if (entry.getKey().isAssignableFrom(sourceType)) {
if (entry.getValue().equals(targetType)) {
return CONVERTER_MAP.get(entry);
}
}
}
}
return converter;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/AbstractChangingItemAnimation.java
================================================
package dev.simplix.cirrus.common.effect;
import dev.simplix.cirrus.common.item.CirrusItem;
public abstract class AbstractChangingItemAnimation extends AbstractMenuAnimation {
protected AbstractChangingItemAnimation(CirrusItem input, int effectLength) {
super(input, effectLength);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/AbstractMenuAnimation.java
================================================
package dev.simplix.cirrus.common.effect;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;
import java.util.Iterator;
public abstract class AbstractMenuAnimation implements MenuAnimation {
protected final T input;
protected final int effectLength;
private Iterator iterator;
protected AbstractMenuAnimation(
T input,
int effectLength) {
this.input = Preconditions.checkNotNull(input, "input must not be null");
Preconditions.checkState(effectLength > 0, "effectLength is not larger than 0");
this.effectLength = effectLength;
}
@Override
public int effectLength() {
return this.effectLength;
}
@Override
public final T input() {
return this.input;
}
@Override
public final T next() {
if (this.iterator == null) {
this.iterator = Iterators.cycle(calculate());
}
return this.iterator.next();
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/Animated.java
================================================
package dev.simplix.cirrus.common.effect;
import dev.simplix.cirrus.common.menu.Menu;
public interface Animated extends Menu {
void update();
@Override
default void handleClose(boolean inventorySwitch) {
MenuAnimator.remove(this);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/Animations.java
================================================
package dev.simplix.cirrus.common.effect;
import lombok.experimental.UtilityClass;
@UtilityClass
public class Animations {
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/MenuAnimation.java
================================================
package dev.simplix.cirrus.common.effect;
import java.util.List;
public interface MenuAnimation {
/**
* Duration of the effect in the menu in ticks
*/
int effectLength();
/**
* Initial input of the effect
*/
T input();
/**
* All calculated values for the effect
*/
List calculate();
/**
* Next effect frame. Usually calculated with an
* infinite iterable calculated with {@link MenuAnimation#calculate()}
* and created with {@link com.google.common.collect.Iterables#cycle(Object[])}
*/
T next();
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/MenuAnimator.java
================================================
package dev.simplix.cirrus.common.effect;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import java.util.LinkedList;
import java.util.List;
@UtilityClass
public class MenuAnimator {
private final List menus = new LinkedList<>();
public boolean isEmpty() {
return menus.isEmpty();
}
public void register(@NonNull Animated menu) {
menus.add(menu);
}
public void remove(@NonNull Animated menu) {
menus.remove(menu);
}
public void updateAll() {
for (Animated menu : menus) {
menu.update();
menu.build();
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effects/GradualColorChangeAnimation.java
================================================
package dev.simplix.cirrus.common.effects;
import com.google.common.base.Preconditions;
import dev.simplix.cirrus.common.effect.AbstractMenuAnimation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Will generate: ...
*/
public class GradualColorChangeAnimation extends AbstractMenuAnimation {
protected final String primaryColor;
protected final String secondaryColor;
protected boolean reverse = false;
protected int transitionCount = 0;
public GradualColorChangeAnimation(
String primaryColor,
String input) {
this(primaryColor, "§f§l", input, 2);
}
public GradualColorChangeAnimation(
String primaryColor,
String secondaryColor,
String input,
int effectLength) {
super(input, effectLength);
this.primaryColor = Preconditions.checkNotNull(primaryColor, "primaryColor must not be null");
this.secondaryColor = Preconditions.checkNotNull(secondaryColor, "secondaryColor must not be null");
}
public GradualColorChangeAnimation reversed() {
this.reverse = true;
return this;
}
public GradualColorChangeAnimation reverse(boolean reverse) {
this.reverse = reverse;
return this;
}
public GradualColorChangeAnimation transitionCount(int transitionCount) {
this.transitionCount = transitionCount;
return this;
}
public GradualColorChangeAnimation length(int length) {
return new GradualColorChangeAnimation(this.primaryColor, this.secondaryColor, this.input, length).reverse(this.reverse).transitionCount(this.transitionCount);
}
@Override
public List calculate() {
final List out = new ArrayList<>();
out.addAll(insertEffect(this.primaryColor, this.secondaryColor));
out.addAll(insertEffect(this.secondaryColor, this.primaryColor));
return out;
}
private List insertEffect(String effectColor, String primaryColor) {
final List out = new ArrayList<>();
if (this.reverse) {
for (int i = this.input.length() - 1; i >= 0; i--) {
out.addAll(Collections.nCopies(this.effectLength, addAtIndex(primaryColor + this.input, effectColor, i + primaryColor.length())));
}
if (this.transitionCount != 0) {
out.addAll(Collections.nCopies(this.transitionCount, effectColor + this.input));
}
} else {
for (int i = 0; i <= this.input.length(); i++) {
out.addAll(Collections.nCopies(this.effectLength, addAtIndex(primaryColor + this.input, effectColor, i + primaryColor.length())));
}
if (this.transitionCount != 0) {
out.addAll(Collections.nCopies(this.transitionCount, primaryColor + this.input));
}
}
return out;
}
private String addAtIndex(String str, String toAdd, int position) {
StringBuilder sb = new StringBuilder(str);
sb.insert(position, toAdd);
return sb.toString();
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effects/RGBColorChangeAnimation.java
================================================
package dev.simplix.cirrus.common.effects;
import com.google.common.base.Preconditions;
import dev.simplix.cirrus.common.effect.AbstractMenuAnimation;
import dev.simplix.cirrus.common.util.ColorUtils;
import net.md_5.bungee.api.ChatColor;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RGBColorChangeAnimation extends AbstractMenuAnimation {
private final List colors;
private String colorSuffix;
private double step;
private RGBColorChangeAnimation(
String input,
int effectLength,
double step,
String colorSuffix,
List colors
) {
super(Preconditions.checkNotNull(input, "input must not be null"), effectLength);
this.step = step;
this.colors = Preconditions.checkNotNull(colors, "colors must not be null");
this.colorSuffix = Preconditions.checkNotNull(colorSuffix, "colorAddon must not be null");
Preconditions.checkState(colors.size() >= 2, "At least 2 colors must be provided¥");
}
public static RGBColorChangeAnimation fat(String input, Color... colors) {
return of(input, "§l", 2, 40, colors);
}
public static RGBColorChangeAnimation of(String input, String colorSuffix, int effectLength, double step, Color... colors) {
return new RGBColorChangeAnimation(input, effectLength, step, colorSuffix, Arrays.asList(colors));
}
public RGBColorChangeAnimation step(int step) {
this.step = step;
return this;
}
public RGBColorChangeAnimation colorSuffix(String colorSuffix) {
this.colorSuffix = colorSuffix;
return this;
}
@Override
public List calculate() {
final List out = new ArrayList<>();
for (int i = 0; i < this.colors.size(); i++) {
final Color color = this.colors.get(i);
final int index = (this.colors.size() == i + 1) ? 0 : (i + 1);
final Color color2 = this.colors.get(index);
out.addAll(Collections.nCopies(
this.effectLength,
ChatColor.of(color) + this.colorSuffix + this.input
));
for (Color between : ColorUtils.colorsInBetween(color, color2, this.step)) {
out.addAll(
Collections.nCopies(
this.effectLength,
ChatColor.of(between) + this.colorSuffix + this.input
)
);
}
}
return out;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/effects/SimpleChangingItemAnimation.java
================================================
package dev.simplix.cirrus.common.effects;
import dev.simplix.cirrus.common.effect.AbstractChangingItemAnimation;
import dev.simplix.cirrus.common.item.CirrusItem;
import java.util.List;
public class SimpleChangingItemAnimation extends AbstractChangingItemAnimation {
private final List values;
protected SimpleChangingItemAnimation(CirrusItem basis, List values, int effectLength) {
super(basis, effectLength);
this.values = values;
}
@Override
public List calculate() {
return this.values;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/handler/ActionHandler.java
================================================
package dev.simplix.cirrus.common.handler;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.cirrus.common.model.Click;
/**
* {@link ActionHandler}s are functions that get called when a click on an {@link
* InventoryMenuItemWrapper} occurs.
*/
@FunctionalInterface
public interface ActionHandler {
CallResult handle(Click click);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/handler/AutoCancellingActionHandler.java
================================================
package dev.simplix.cirrus.common.handler;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.cirrus.common.model.Click;
@FunctionalInterface
public interface AutoCancellingActionHandler extends ActionHandler {
@Override
default CallResult handle(Click click) {
onHandle(click);
return CallResult.DENY_GRABBING;
}
void onHandle(Click click);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedItemStackModel.java
================================================
package dev.simplix.cirrus.common.i18n;
import dev.simplix.cirrus.common.Utils;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.protocolize.data.ItemType;
import lombok.*;
import lombok.experimental.Accessors;
import net.querz.nbt.tag.CompoundTag;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@Data
@Builder
@Accessors(fluent = true)
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class LocalizedItemStackModel {
@Builder.Default
private LocalizedString displayName = new LocalizedString(new HashMap<>());
@Builder.Default
private LocalizedStringList lore = new LocalizedStringList(new HashMap<>());
@Builder.Default
private ItemType itemType = ItemType.STONE;
@Builder.Default
private byte amount = 1;
@Builder.Default
private short durability = -1;
@Builder.Default
private String actionHandler = "noAction";
@Builder.Default
private List actionArguments = Collections.emptyList();
@Builder.Default
private int[] slots = new int[0];
@Builder.Default
@NonNull
private CompoundTag nbt = new CompoundTag();
public LocalizedItemStackModel glow() {
Utils.glow(this.nbt);
return this;
}
public LocalizedItemStackModel texture(@NonNull String texture) {
Utils.texture(this.nbt, texture);
return this;
}
public CirrusItem localize(Locale locale, String... replacements) {
return Localizer.localize(
this,
locale,
replacements
);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedString.java
================================================
package dev.simplix.cirrus.common.i18n;
import lombok.NonNull;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class LocalizedString {
private final Map translations = new HashMap<>();
public LocalizedString(@NonNull Map stringMap) {
this.translations.putAll(stringMap);
}
/**
* @return The map with all translations
*/
public Map translations() {
return this.translations;
}
/**
* Returns the localized string for the given {@link Locale}. If the given locale is not
* available, it will return the first available translation. If there aren't any translations, it
* will return "missigno."
*
* @param locale The desired locale
* @return the localized string or "missigno."
*/
public String translated(Locale locale) {
return this.translations.getOrDefault(
locale.getLanguage(),
this.translations.getOrDefault(
this.translations.keySet().stream().findFirst().orElse(""),
"missgno."));
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringDeserializer.java
================================================
package dev.simplix.cirrus.common.i18n;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import lombok.NonNull;
import java.lang.reflect.Type;
import java.util.Map;
public class LocalizedStringDeserializer implements JsonDeserializer {
@Override
public LocalizedString deserialize(
@NonNull JsonElement jsonElement,
@NonNull Type type,
@NonNull JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
Map stringMap = jsonDeserializationContext.deserialize(
jsonElement,
new TypeToken>() {
}.getType());
return new LocalizedString(stringMap);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringList.java
================================================
package dev.simplix.cirrus.common.i18n;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import java.util.*;
@NoArgsConstructor
public class LocalizedStringList {
private final Map> translations = new HashMap<>();
public LocalizedStringList(@NonNull Map> stringListMap) {
this.translations.putAll(stringListMap);
}
/**
* @return The map with all translations
*/
public Map> translations() {
return this.translations;
}
private final List forceAdded = new ArrayList<>();
/**
* Returns the localized string list for the given {@link Locale}. If the given locale is not
* available, it will return the first available translation. If there aren't any translations, it
* will return an empty list.
*
* @param locale The desired locale
* @return the localized string list
*/
public List translated(@NonNull Locale locale) {
if (this.translations.isEmpty()) {
return Collections.emptyList();
}
String fallback = this.translations.keySet().iterator().next();
final List out = new ArrayList<>(this.translations.getOrDefault(
locale.getLanguage(),
this.translations.getOrDefault(
fallback,
Collections.emptyList()))
);
out.addAll(this.forceAdded);
return out;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringListDeserializer.java
================================================
package dev.simplix.cirrus.common.i18n;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import lombok.NonNull;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class LocalizedStringListDeserializer implements JsonDeserializer {
@Override
public LocalizedStringList deserialize(
@NonNull JsonElement jsonElement,
@NonNull Type type,
@NonNull JsonDeserializationContext jsonDeserializationContext)
throws JsonParseException {
Map> stringListMap = jsonDeserializationContext.deserialize(
jsonElement,
new TypeToken>>() {
}.getType());
return new LocalizedStringList(stringListMap);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringListSerializer.java
================================================
package dev.simplix.cirrus.common.i18n;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import lombok.NonNull;
import java.lang.reflect.Type;
public class LocalizedStringListSerializer implements JsonSerializer {
@Override
public JsonElement serialize(
@NonNull LocalizedStringList localizedStringList,
@NonNull Type type,
@NonNull JsonSerializationContext jsonSerializationContext) {
return jsonSerializationContext.serialize(localizedStringList.translations());
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringSerializer.java
================================================
package dev.simplix.cirrus.common.i18n;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import lombok.NonNull;
import java.lang.reflect.Type;
public class LocalizedStringSerializer implements JsonSerializer {
@Override
public JsonElement serialize(
@NonNull LocalizedString localizedString,
@NonNull Type type,
@NonNull JsonSerializationContext jsonSerializationContext) {
return jsonSerializationContext.serialize(localizedString.translations());
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/Localizer.java
================================================
package dev.simplix.cirrus.common.i18n;
import dev.simplix.cirrus.common.item.CirrusItem;
import lombok.NonNull;
import net.querz.nbt.io.SNBTUtil;
import net.querz.nbt.tag.CompoundTag;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public final class Localizer {
public static List localize(
LocalizedStringList localizedStringList,
@NonNull Locale locale,
String... replacements) {
if (localizedStringList == null) {
return Collections.emptyList();
}
return Arrays.asList(Replacer.of(localizedStringList.translated(locale))
.replaceAll((Object[]) replacements).replacedMessage());
}
public static String localize(
LocalizedString localizedString,
@NonNull Locale locale,
String... replacements) {
if (localizedString == null) {
return "";
}
return Replacer
.of(localizedString.translated(locale))
.replaceAll((Object[]) replacements)
.replacedMessageJoined();
}
public static CirrusItem localize(
@NonNull LocalizedItemStackModel model,
@NonNull Locale locale,
@NonNull String... replacements) {
return CirrusItem.of(localize(model.displayName(), locale, replacements))
.actionArguments(Arrays.asList(Replacer
.of(model.actionArguments() == null ? Collections.emptyList() : model.actionArguments())
.replaceAll((Object[]) replacements)
.replacedMessage()))
.actionHandler(model.actionHandler())
.amount(model.amount())
.durability(model.durability())
.itemType(model.itemType())
.lore(localize(model.lore(), locale, replacements))
.nbt(formatNbt(model.nbt(), replacements))
.slots(model.slots());
}
private static CompoundTag formatNbt(
@Nullable CompoundTag compoundTag,
@NonNull String... replacements) {
if (compoundTag == null) {
return null;
}
try {
String mojangson = SNBTUtil.toSNBT(compoundTag);
return (CompoundTag) SNBTUtil.fromSNBT(Replacer.of(mojangson)
.replaceAll((Object[]) replacements).replacedMessageJoined());
} catch (IOException ioException) {
// Ignored
}
return compoundTag;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/Replacer.java
================================================
package dev.simplix.cirrus.common.i18n;
import com.google.common.base.Preconditions;
import lombok.Getter;
import lombok.NonNull;
import lombok.experimental.Accessors;
import lombok.val;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* This is a utility class for handy message replacements. Placeholders begin with { and are ending
* with }
*
* Example:
* {viewer}
*/
@Getter
@Accessors(fluent = true)
public final class Replacer {
public static final String DELIMITER = "\n";
private final List messages;
//Messages to replace
private final List variables = new ArrayList<>();
private final List replacements = new ArrayList<>();
private Replacer(List messages) {
// Cloning our messages
this.messages = new ArrayList<>(messages);
}
// ----------------------------------------------------------------------------------------------------
// Static Factory methods
// ----------------------------------------------------------------------------------------------------
public static Replacer of(@NonNull final String... messages) {
return new Replacer(Arrays.asList(messages));
}
public static Replacer of(@NonNull final List messages) {
return new Replacer(messages);
}
public static Replacer ofMultilineString(@NonNull final String multilineString) {
return new Replacer(Arrays.asList(multilineString.split(DELIMITER)));
}
public final Replacer find(@NonNull final String... variables) {
this.variables.clear();
this.variables.addAll(Arrays.asList(variables));
return this;
}
public final Replacer replace(@NonNull final Object... replacements) {
this.replacements.clear();
this.replacements.addAll(Arrays.asList(replacements));
return this;
}
public Replacer set(final int index, @NonNull final String message) {
this.messages.set(index, message);
return this;
}
/**
* Replaces all variables with replacements.
*
* @param associativeArray Variable, Replacement, Variable, Replacement
*/
public final Replacer replaceAll(@NonNull final Object... associativeArray) {
this.variables.clear();
this.replacements.clear();
//Even: Value
for (int i = 0; i < associativeArray.length; i++) {
if (i % 2 == 0) {
//Odd: Key
val raw = associativeArray[i];
Preconditions.checkState(
raw instanceof String,
"Expected String at " + raw + ", got " + raw.getClass()
.getSimpleName());
this.variables.add((String) raw);
} else {
this.replacements.add(associativeArray[i]);
}
}
return this;
}
/**
* Method to replace the registered Replacers.
*/
public String[] replacedMessage() {
Preconditions.checkState(
this.replacements.size() == this.variables.size(),
"Variables " + this.variables.size()
+ " != replacements " + this.replacements.size(),
"Variables: " + this.variables.toString(),
"Replacments: " + this.replacements
);
// Join and replace as 1 message for maximum performance
String message = String.join(DELIMITER, this.messages);
for (int i = 0; i < this.variables.size(); i++) {
String found = this.variables.get(i);
{ // Auto insert brackets
if (!found.startsWith("{")) {
found = "{" + found;
}
if (!found.endsWith("}")) {
found = found + "}";
}
}
final Object rep = i <= this.replacements.size() ? this.replacements.get(i) : null;
message = message.replace(found, rep == null ? "" : rep.toString());
}
return message.split(DELIMITER);
}
/**
* Same as {@link #replacedMessage()} but joined using {@link String#join(CharSequence,
* CharSequence...)} and the {@link #DELIMITER}
*/
public String replacedMessageJoined() {
return String.join(DELIMITER, replacedMessage());
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/item/CirrusItem.java
================================================
package dev.simplix.cirrus.common.item;
import dev.simplix.cirrus.common.Utils;
import dev.simplix.cirrus.common.effect.AbstractMenuAnimation;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import lombok.experimental.Accessors;
import net.querz.nbt.tag.CompoundTag;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
@Accessors(fluent = true)
public class CirrusItem {
@NonNull
private String displayName = "Example-DisplayName";
@Nullable
private AbstractMenuAnimation titleEffect = null;
private List lore = Collections.emptyList();
@Nullable
private Supplier> loreSupplier = null;
private ItemType itemType = ItemType.STONE;
private byte amount = 1;
private short durability = -1;
private String actionHandler = "noAction";
private List actionArguments = Collections.emptyList();
private int[] slots = new int[0];
@NonNull
private CompoundTag nbt;
private CirrusItem(@NonNull String displayName, @Nullable AbstractMenuAnimation titleEffect, List lore, @Nullable Supplier> loreSupplier, ItemType itemType, byte amount, short durability, String actionHandler, List actionArguments, int[] slots, @NonNull CompoundTag nbt) {
this.displayName = displayName;
this.titleEffect = titleEffect;
this.lore = lore;
this.loreSupplier = loreSupplier;
this.itemType = itemType;
this.amount = amount;
this.durability = durability;
this.actionHandler = actionHandler;
this.actionArguments = actionArguments;
this.slots = slots;
this.nbt = nbt;
}
private CirrusItem() {
}
// ----------------------------------------------------------------------------------------------------
// Instancing
// ----------------------------------------------------------------------------------------------------
public static CirrusItem of(String name, ItemType type) {
return new CirrusItem().displayName(name).itemType(type);
}
public static CirrusItem of(String name) {
return of(name, ItemType.STONE);
}
public static CirrusItem animated(AbstractMenuAnimation effect, ItemType type) {
return new CirrusItem().itemType(type).titleEffect(effect);
}
public static CirrusItem animated(AbstractMenuAnimation effect) {
return animated(effect, ItemType.STONE);
}
// ----------------------------------------------------------------------------------------------------
// Chained setters
// ----------------------------------------------------------------------------------------------------
public CirrusItem lore(String... lines) {
this.lore = Arrays.asList(lines);
return this;
}
public CirrusItem slot(int... slots) {
this.slots = slots;
return this;
}
public String displayNam() {
if (this.titleEffect != null) {
return this.titleEffect.next();
}
return this.displayName;
}
public CirrusItem glow() {
Utils.glow(this.nbt);
return this;
}
public CirrusItem texture(@NonNull String texture) {
Utils.texture(this.nbt, texture);
return this;
}
public CirrusItem copy() {
return new CirrusItem(
this.displayName,
this.titleEffect,
this.lore,
this.loreSupplier,
this.itemType,
this.amount,
this.durability,
this.actionHandler,
this.actionArguments,
this.slots,
this.nbt
);
}
public @NonNull String displayName() {
return this.displayName;
}
public @Nullable AbstractMenuAnimation titleEffect() {
return this.titleEffect;
}
public List lore() {
if (this.loreSupplier != null) {
return this.loreSupplier.get();
}
return this.lore;
}
public @Nullable Supplier> loreSupplier() {
return this.loreSupplier;
}
public ItemType itemType() {
return this.itemType;
}
public byte amount() {
return this.amount;
}
public short durability() {
return this.durability;
}
public String actionHandler() {
return this.actionHandler;
}
public List actionArguments() {
return this.actionArguments;
}
public int[] slots() {
return this.slots;
}
public @NonNull CompoundTag nbt() {
return this.nbt;
}
public CirrusItem displayName(@NonNull String displayName) {
this.displayName = displayName;
return this;
}
public CirrusItem titleEffect(@Nullable AbstractMenuAnimation titleEffect) {
this.titleEffect = titleEffect;
return this;
}
public CirrusItem lore(List lore) {
this.lore = lore;
return this;
}
public CirrusItem loreSupplier(@Nullable Supplier> loreSupplier) {
this.loreSupplier = loreSupplier;
return this;
}
public CirrusItem itemType(ItemType itemType) {
this.itemType = itemType;
return this;
}
public CirrusItem amount(byte amount) {
this.amount = amount;
return this;
}
public CirrusItem durability(short durability) {
this.durability = durability;
return this;
}
public CirrusItem actionHandler(String actionHandler) {
this.actionHandler = actionHandler;
return this;
}
public CirrusItem actionArguments(List actionArguments) {
this.actionArguments = actionArguments;
return this;
}
public CirrusItem slots(int[] slots) {
this.slots = slots;
return this;
}
public CirrusItem nbt(@NonNull CompoundTag nbt) {
this.nbt = nbt;
return this;
}
@Override
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof CirrusItem)) {
return false;
}
final CirrusItem other = (CirrusItem) o;
if (!other.canEqual((Object) this)) {
return false;
}
final Object this$displayName = this.displayName();
final Object other$displayName = other.displayName();
if (this$displayName == null ? other$displayName != null : !this$displayName.equals(other$displayName)) {
return false;
}
final Object this$titleEffect = this.titleEffect();
final Object other$titleEffect = other.titleEffect();
if (this$titleEffect == null ? other$titleEffect != null : !this$titleEffect.equals(other$titleEffect)) {
return false;
}
final Object this$lore = this.lore();
final Object other$lore = other.lore();
if (this$lore == null ? other$lore != null : !this$lore.equals(other$lore)) {
return false;
}
final Object this$loreSupplier = this.loreSupplier();
final Object other$loreSupplier = other.loreSupplier();
if (this$loreSupplier == null ? other$loreSupplier != null : !this$loreSupplier.equals(other$loreSupplier)) {
return false;
}
final Object this$itemType = this.itemType();
final Object other$itemType = other.itemType();
if (this$itemType == null ? other$itemType != null : !this$itemType.equals(other$itemType)) {
return false;
}
if (this.amount() != other.amount()) {
return false;
}
if (this.durability() != other.durability()) {
return false;
}
final Object this$actionHandler = this.actionHandler();
final Object other$actionHandler = other.actionHandler();
if (this$actionHandler == null ? other$actionHandler != null : !this$actionHandler.equals(other$actionHandler)) {
return false;
}
final Object this$actionArguments = this.actionArguments();
final Object other$actionArguments = other.actionArguments();
if (this$actionArguments == null ? other$actionArguments != null : !this$actionArguments.equals(other$actionArguments)) {
return false;
}
if (!Arrays.equals(this.slots(), other.slots())) {
return false;
}
final Object this$nbt = this.nbt();
final Object other$nbt = other.nbt();
if (this$nbt == null ? other$nbt != null : !this$nbt.equals(other$nbt)) {
return false;
}
return true;
}
protected boolean canEqual(final Object other) {
return other instanceof CirrusItem;
}
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $displayName = this.displayName();
result = result * PRIME + ($displayName == null ? 43 : $displayName.hashCode());
final Object $titleEffect = this.titleEffect();
result = result * PRIME + ($titleEffect == null ? 43 : $titleEffect.hashCode());
final Object $lore = this.lore();
result = result * PRIME + ($lore == null ? 43 : $lore.hashCode());
final Object $loreSupplier = this.loreSupplier();
result = result * PRIME + ($loreSupplier == null ? 43 : $loreSupplier.hashCode());
final Object $itemType = this.itemType();
result = result * PRIME + ($itemType == null ? 43 : $itemType.hashCode());
result = result * PRIME + this.amount();
result = result * PRIME + this.durability();
final Object $actionHandler = this.actionHandler();
result = result * PRIME + ($actionHandler == null ? 43 : $actionHandler.hashCode());
final Object $actionArguments = this.actionArguments();
result = result * PRIME + ($actionArguments == null ? 43 : $actionArguments.hashCode());
result = result * PRIME + Arrays.hashCode(this.slots());
final Object $nbt = this.nbt();
result = result * PRIME + ($nbt == null ? 43 : $nbt.hashCode());
return result;
}
@Override
public String toString() {
return "CirrusItem(displayName=" + this.displayName() + ", titleEffect=" + this.titleEffect() + ", lore=" + this.lore() + ", loreSupplier=" + this.loreSupplier() + ", itemType=" + this.itemType() + ", amount=" + this.amount() + ", durability=" + this.durability() + ", actionHandler=" + this.actionHandler() + ", actionArguments=" + this.actionArguments() + ", slots=" + Arrays.toString(this.slots()) + ", nbt=" + this.nbt() + ")";
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/item/Items.java
================================================
package dev.simplix.cirrus.common.item;
import dev.simplix.cirrus.common.effects.RGBColorChangeAnimation;
import lombok.experimental.UtilityClass;
import java.awt.*;
@UtilityClass
public class Items {
public CirrusItem rgb(String displayName, Color... colors) {
return CirrusItem
.animated(RGBColorChangeAnimation.fat(displayName, colors));
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/item/ProtocolizeMenuItemWrapper.java
================================================
package dev.simplix.cirrus.common.item;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.protocolize.api.chat.ChatElement;
import dev.simplix.protocolize.api.item.ItemStack;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import net.md_5.bungee.api.chat.BaseComponent;
import net.querz.nbt.tag.CompoundTag;
import java.util.List;
import java.util.stream.Collectors;
public class ProtocolizeMenuItemWrapper implements MenuItemWrapper {
private final ItemStack itemStack;
public ProtocolizeMenuItemWrapper(ItemStack itemStack) {
this.itemStack = itemStack;
}
@Override
public String displayName() {
return this.itemStack.displayName().asLegacyText();
}
@Override
public BaseComponent[] displayNameComponents() {
return (BaseComponent[]) this.itemStack.displayName().asComponent();
}
@Override
public List lore() {
return this.itemStack.lore().stream().map(ChatElement::asLegacyText).collect(Collectors.toList());
}
@Override
public List loreComponents() {
return (List) this.itemStack.lore().stream().map(ChatElement::asComponent).collect(Collectors.toList());
}
@Override
public ItemType type() {
return this.itemStack.itemType();
}
@Override
public CompoundTag nbt() {
return this.itemStack.nbtData();
}
@Override
public int amount() {
return this.itemStack.amount();
}
@Override
public short durability() {
return this.itemStack.durability();
}
@Override
public void type(@NonNull ItemType type) {
this.itemStack.itemType(type);
}
@Override
public void displayName(@NonNull String displayName) {
this.itemStack.displayName(ChatElement.ofLegacyText(displayName));
}
@Override
public void displayNameComponents(BaseComponent... baseComponents) {
this.itemStack.displayName(ChatElement.of(baseComponents));
}
@Override
public void lore(@NonNull List lore) {
this.itemStack.lore(lore.stream().map(ChatElement::ofLegacyText).collect(Collectors.toList()));
}
@Override
public void loreComponents(@NonNull List lore) {
this.itemStack.lore(lore.stream().map(ChatElement::of).collect(Collectors.toList()));
}
@Override
public void nbt(@NonNull CompoundTag compoundTag) {
this.itemStack.nbtData(compoundTag);
}
@Override
public void amount(int amount) {
this.itemStack.amount((byte) amount);
}
@Override
public void durability(short durability) {
this.itemStack.durability(durability);
}
@Override
public T handle() {
return (T) this.itemStack;
}
@Override
public String toString() {
return handle().toString();
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/AbstractConfigurableMenu.java
================================================
package dev.simplix.cirrus.common.menu;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;
import lombok.Getter;
import lombok.NonNull;
import lombok.experimental.Accessors;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@Getter
@Accessors(fluent = true)
public abstract class AbstractConfigurableMenu extends AbstractMenu {
private final T configuration;
public AbstractConfigurableMenu(
@NonNull PlayerWrapper player,
@NonNull T configuration,
@NonNull Locale locale) {
this(player, configuration, locale, new HashMap<>());
}
public AbstractConfigurableMenu(
@NonNull PlayerWrapper player,
@NonNull T configuration,
@NonNull Locale locale,
@NonNull Map actionHandlerMap) {
super(player, configuration.type(), locale, actionHandlerMap);
title(configuration.title().translated(locale));
this.configuration = configuration;
applyItems();
}
@Override
protected void updateReplacements() {
super.updateReplacements();
topContainer().itemMap().clear();
bottomContainer().itemMap().clear();
topContainer().reservedSlots().clear();
bottomContainer().reservedSlots().clear();
applyItems();
}
private void applyItems() {
for (int slot : this.configuration.reservedSlots()) {
if (slot > topContainer().capacity() - 1) {
bottomContainer().reservedSlots().add(slot);
} else {
topContainer().reservedSlots().add(slot);
}
}
// Set placeholders
set(this.configuration.placeholderItem());
// Set other items
for (LocalizedItemStackModel model : this.configuration.items()) {
set(model);
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/AbstractMenu.java
================================================
package dev.simplix.cirrus.common.menu;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.container.impl.ItemContainer;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.handler.AutoCancellingActionHandler;
import dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;
import dev.simplix.cirrus.common.i18n.Localizer;
import dev.simplix.cirrus.common.i18n.Replacer;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.protocolize.data.inventory.InventoryType;
import lombok.Getter;
import lombok.NonNull;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
@Getter
@Accessors(fluent = true)
@Slf4j
public abstract class AbstractMenu implements Menu {
private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
private final Map actionHandlerMap;
private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);
private final Container topContainer;
private final Container bottomContainer;
private final InventoryType inventoryType;
private final Locale locale;
private final PlayerWrapper player;
private final int internalId = ID_GENERATOR.incrementAndGet();
private Supplier replacements;
private ActionHandler customActionHandler;
private Object nativeInventory;
private String title;
public AbstractMenu(
@NonNull PlayerWrapper player,
@NonNull InventoryType inventoryType,
@NonNull Locale locale) {
this(player, inventoryType, locale, new HashMap<>());
}
public AbstractMenu(
@NonNull PlayerWrapper player,
@NonNull InventoryType inventoryType,
@NonNull Locale locale,
@NonNull Map actionHandlerMap) {
this.inventoryType = inventoryType;
this.locale = locale;
this.player = player;
this.replacements = () -> new String[]{"viewer", player.name()};
this.topContainer = new ItemContainer(0, inventoryType.getTypicalSize(player.protocolVersion()));
this.bottomContainer = new ItemContainer(
inventoryType.getTypicalSize(player.protocolVersion()),
4 * 9);
this.actionHandlerMap = actionHandlerMap;
}
@Override
public void registerActionHandler(@NonNull String name, @NonNull AutoCancellingActionHandler actionHandler) {
this.actionHandlerMap.put(name, actionHandler);
}
@Override
public void registerActionHandler(@NonNull String name, @NonNull ActionHandler actionHandler) {
this.actionHandlerMap.put(name, actionHandler);
}
@Override
@Nullable
public ActionHandler actionHandler(@NonNull String name) {
return this.actionHandlerMap.get(name);
}
@Override
public void customActionHandler(@NonNull ActionHandler actionHandler) {
this.customActionHandler = actionHandler;
}
@Override
public void title(@NonNull String title) {
this.title = title;
}
@Override
public String title() {
return Replacer.of(this.title).replaceAll((Object[]) replacements().get()).replacedMessageJoined();
}
@Override
public void replacements(@NonNull Supplier replacements) {
this.replacements = replacements;
updateReplacements();
}
protected void updateReplacements() {
}
protected void nativeInventory(@NonNull Object nativeInventory) {
this.nativeInventory = nativeInventory;
}
@Override
public void build() {
if (menuBuilder() == null) {
return;
}
nativeInventory(menuBuilder().build(nativeInventory(), this));
}
@Override
public void open() {
build();
menuBuilder().open(this.player, nativeInventory());
}
protected int add(@NonNull LocalizedItemStackModel localizedItemStackModel) {
return add(localizedItemStackModel.localize(locale(), this.replacements.get()));
}
protected int add(@NonNull CirrusItem menuItem) {
int slot = topContainer().nextFreeSlot();
this.topContainer.set(slot, menuItem);
return slot;
}
protected int add(@NonNull InventoryMenuItemWrapper inventoryMenuItemWrapper) {
int slot = topContainer().nextFreeSlot();
this.topContainer.set(slot, inventoryMenuItemWrapper);
return slot;
}
protected void set(@NonNull LocalizedItemStackModel model) {
set(Localizer.localize(
model,
locale(),
replacements().get()));
}
protected void set(@NonNull CirrusItem model) {
for (int slot : model.slots()) {
if (slot > topContainer().capacity() - 1) {
bottomContainer().set(slot - bottomContainer().baseSlot(), model);
} else {
topContainer().set(slot, model);
}
}
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (o instanceof AbstractMenu) {
final AbstractMenu abstractMenu = (AbstractMenu) o;
return abstractMenu.internalId == this.internalId();
}
if (this == o) {
return true;
}
return o.equals(nativeInventory());
}
@Override
public int hashCode() {
return Objects.hash(
this.actionHandlerMap,
this.topContainer,
this.bottomContainer,
this.inventoryType,
this.locale,
this.player,
this.internalId,
this.replacements,
this.customActionHandler,
this.nativeInventory,
this.title);
}
@Override
public void handleException(
@Nullable ActionHandler actionHandler, Throwable throwable) {
if (actionHandler == null) {
this.player.sendMessage(
"§cThere was a problem while running your menu. Please take a look at the console.");
log.error(
"[Cirrus] Exception occurred while running menu " + getClass().getName(),
throwable);
} else {
this.player.sendMessage(
"§cThere was a problem while running your action handler. Please take a look at the console.");
log.error("[Cirrus] Exception occurred while running action handler for menu "
+ getClass().getName(), throwable);
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/ErrorProne.java
================================================
package dev.simplix.cirrus.common.menu;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.util.SafeRunnable;
import lombok.NonNull;
import org.jetbrains.annotations.Nullable;
public interface ErrorProne {
default void handleException(@Nullable ActionHandler actionHandler, Throwable throwable) {
}
/**
* Executes error prone code that may throw a exception. When an exception is thrown, it will be
* delegated to the exception handler.
*
* @param runnable The runnable to run
*/
default void errorProne(@NonNull SafeRunnable runnable) {
try {
runnable.run();
} catch (Throwable throwable) {
handleException(null, throwable);
}
}
/**
* Executes error prone code that may throw a exception. When an exception is thrown, it will be
* delegated to the exception handler.
*
* @param runnable The runnable to run
* @param finallyRunnable Code that may run finally
*/
default void errorProne(@NonNull SafeRunnable runnable, @NonNull Runnable finallyRunnable) {
try {
runnable.run();
} catch (Throwable throwable) {
handleException(null, throwable);
} finally {
finallyRunnable.run();
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/Menu.java
================================================
package dev.simplix.cirrus.common.menu;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.handler.AutoCancellingActionHandler;
import dev.simplix.protocolize.data.inventory.InventoryType;
import lombok.NonNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import java.util.function.Supplier;
public interface Menu extends ErrorProne {
/**
* @return The inventory type
*/
InventoryType inventoryType();
void registerActionHandler(@NonNull String name, @NonNull AutoCancellingActionHandler actionHandler);
/**
* Registers a new action handler
*
* @param name the name
* @param actionHandler the action handler
*/
void registerActionHandler(@NonNull String name, @NonNull ActionHandler actionHandler);
/**
* ActionHandler which handles clicks in empty space
*
* @param actionHandler the action handler
*/
void customActionHandler(@NonNull ActionHandler actionHandler);
/**
* This opens the menu for the specified player
*/
void open();
/**
* This builds the menu
*/
void build();
/**
* ActionHandler which handles clicks in empty space
*
* @return The custom action handler
*/
ActionHandler customActionHandler();
/**
* Returns an action handler by its name
*
* @param name the name of the desired action handler
* @return the action handler or null if not found
*/
@Nullable
ActionHandler actionHandler(@NonNull String name);
/**
* Returns the {@link Container} for the upper inventory.
*
* @return container
*/
Container topContainer();
/**
* Returns the {@link Container} for the lower inventory.
*
* @return container
*/
Container bottomContainer();
/**
* Returns the title of the menu
*
* @return title string
*/
String title();
/**
* Sets the title of the menu
*
* @param title title
*/
void title(@NonNull String title);
/**
* @return The locale the menu is in
*/
Locale locale();
/**
* Returns the owner of this menu. The current viewer.
*
* @return The player
*/
PlayerWrapper player();
/**
* Returns a {@link Supplier} which returns a string array used for placeholder replacement.
*
* @return Supplier for string array
*/
Supplier replacements();
/**
* Sets a {@link Supplier} which returns a string array used for placeholder replacement.
*
* @param supplier supplier
*/
void replacements(Supplier supplier);
/**
* Called when leaving the current menu.
*
* @param inventorySwitch true if a new menu was built within the last 55ms
*/
default void handleClose(boolean inventorySwitch) {
}
/**
* Converts an object into an ItemStackWrapper.
*
* @param object the object to convert
* @return the wrapper object
*/
default MenuItemWrapper wrapItemStack(@NonNull Object object) {
return Converters.convert(object, MenuItemWrapper.class);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/MenuBuilder.java
================================================
package dev.simplix.cirrus.common.menu;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import lombok.NonNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public interface MenuBuilder {
T build(@Nullable T prebuild, @NonNull Menu menu);
void open(@NonNull PlayerWrapper playerWrapper, @NonNull T inventoryImpl);
@Nullable
Menu menuByHandle(@Nullable Object handle);
default Optional findMenuByHandle(@Nullable Object handle) {
return Optional.ofNullable(menuByHandle(handle));
}
void destroyMenusOfPlayer(@NonNull UUID uniqueId);
Map.Entry lastBuildOfPlayer(@NonNull UUID uniqueId);
void invalidate(@NonNull Menu menu);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menus/AbstractBrowserMenu.java
================================================
package dev.simplix.cirrus.common.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.cirrus.common.model.Click;
import lombok.NonNull;
import java.util.*;
import java.util.Map.Entry;
public abstract class AbstractBrowserMenu extends MultiPageMenu {
protected Map slotValueMap = new HashMap<>();
protected Map out = new HashMap<>();
public AbstractBrowserMenu(
@NonNull PlayerWrapper player,
@NonNull MultiPageMenuConfiguration configuration,
@NonNull Locale locale) {
this(player, configuration, locale, new HashMap<>());
}
public AbstractBrowserMenu(
@NonNull PlayerWrapper player,
@NonNull MultiPageMenuConfiguration configuration,
@NonNull Locale locale, @NonNull Map actionHandlerMap) {
super(player, configuration, locale, actionHandlerMap);
registerActionHandler("click", click -> {
final T value = this.slotValueMap.get(click.slot());
if (value == null) {
return;
}
click(click, value);
});
}
protected abstract void click(Click click, T value);
protected abstract List values();
protected abstract CirrusItem map(T value);
protected Map mappedValues() {
if (this.out != null && !this.out.isEmpty()) {
return this.out;
}
this.out = new HashMap<>();
for (T value : values()) {
this.out.put(value, map(value));
}
return this.out;
}
protected void insert() {
for (Entry entry : mappedValues().entrySet()) {
final CirrusItem value = entry.getValue();
final Integer slot = add(value, "click", new ArrayList<>());
this.slotValueMap.put(slot, entry.getKey());
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menus/MultiPageMenu.java
================================================
package dev.simplix.cirrus.common.menus;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;
import dev.simplix.cirrus.common.menu.AbstractMenu;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.common.model.CallResult;
import lombok.Getter;
import lombok.NonNull;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.function.Supplier;
@Slf4j
@Accessors(fluent = true)
public class MultiPageMenu extends AbstractMenu {
private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);
@Getter
private final List pages = new LinkedList<>();
@Getter
private final MultiPageMenuConfiguration configuration;
private int currentPage = 1;
public MultiPageMenu(
@NonNull PlayerWrapper player,
@NonNull MultiPageMenuConfiguration configuration,
@NonNull Locale locale) {
this(player, configuration, locale, new HashMap<>());
}
public MultiPageMenu(
@NonNull PlayerWrapper player,
@NonNull MultiPageMenuConfiguration configuration,
@NonNull Locale locale,
@NonNull Map actionHandlerMap) {
super(player, configuration.type(), locale, actionHandlerMap);
this.configuration = configuration;
title(configuration.title().translated(locale));
this.pages.add(new PageMenu(player, configuration, locale));
registerActionHandlers();
configuration.nextPageItem().actionHandler("nextPage");
configuration.previousPageItem().actionHandler("previousPage");
Arrays
.stream(configuration.nextPageItem().slots())
.forEach(value -> topContainer().reservedSlots().add(value));
Arrays
.stream(configuration.previousPageItem().slots())
.forEach(value -> topContainer().reservedSlots().add(value));
replacements(() -> new String[]{
"viewer", player.name(),
"page", Integer.toString(this.currentPage),
"pageCount", Integer.toString(this.pages.size())});
}
private void registerActionHandlers() {
registerActionHandler("nextPage", click -> {
if (this.currentPage == this.pages.size()) {
return CallResult.DENY_GRABBING;
}
this.currentPage++;
build();
return CallResult.DENY_GRABBING;
});
registerActionHandler("previousPage", click -> {
if (this.currentPage == 1) {
return CallResult.DENY_GRABBING;
}
this.currentPage--;
build();
return CallResult.DENY_GRABBING;
});
}
@Override
public void build() {
currentPage().build();
}
@Override
public void open() {
currentPage(1);
currentPage().open();
}
@Override
public MenuBuilder menuBuilder() {
return this.menuBuilder;
}
@Override
public Container bottomContainer() {
return currentPage().bottomContainer();
}
@Override
public Container topContainer() {
return currentPage().topContainer();
}
public Menu currentPage() {
return this.pages.get(this.currentPage - 1);
}
public List pages() {
return this.pages;
}
public int currentPageNumber() {
return this.currentPage;
}
public void currentPage(int page) {
this.currentPage = page;
}
public void newPage() {
this.pages.add(new PageMenu(player(), configuration(), locale()));
this.currentPage++;
}
public int add(@NonNull CirrusItem model, String actionHandler, List arguments) {
return add(wrapItemStack(model), actionHandler, arguments);
}
@Override
public int add(@NonNull InventoryMenuItemWrapper inventoryItemWrapper) {
int slot = currentPage().topContainer().nextFreeSlot();
int oldPage = this.currentPage;
if (slot == -1) {
if (this.pages.size() > this.currentPage) {
this.currentPage = this.pages.size();
int out = this.add(inventoryItemWrapper);
currentPage(oldPage);
return out;
}
newPage();
if (currentPage().topContainer().nextFreeSlot() == -1) {
log.info("[Cirrus] Cannot add item to "
+ MultiPageMenu.this.getClass().getSimpleName()
+ ": No space in new page!");
currentPage(oldPage);
return -1;
}
this.add(inventoryItemWrapper);
} else {
currentPage().topContainer().set(slot, inventoryItemWrapper);
}
currentPage(oldPage);
return slot;
}
public int add(
@NonNull MenuItemWrapper menuItemWrapper,
@NonNull String actionHandler,
@NonNull List actionArgs) {
int slot = currentPage().topContainer().nextFreeSlot();
int oldPage = this.currentPage;
if (slot == -1) {
if (this.pages.size() > this.currentPage) {
this.currentPage = this.pages.size();
int out = this.add(menuItemWrapper, actionHandler, actionArgs);
currentPage(oldPage);
return out;
}
newPage();
if (currentPage().topContainer().nextFreeSlot() == -1) {
log.info("[Cirrus] Cannot add item to "
+ MultiPageMenu.this.getClass().getSimpleName()
+ ": No space in new page!");
currentPage(oldPage);
return -1;
}
this.add(menuItemWrapper, actionHandler, actionArgs);
} else {
currentPage().topContainer().add(menuItemWrapper, actionHandler, actionArgs);
}
currentPage(oldPage);
return slot;
}
class PageMenu extends AbstractConfigurableMenu {
public PageMenu(
@NonNull PlayerWrapper player,
@NonNull MenuConfiguration configuration,
@NonNull Locale locale) {
super(player, configuration, locale);
}
@Override
public Supplier replacements() {
return MultiPageMenu.this.replacements();
}
@Override
public String title() {
return MultiPageMenu.this.title();
}
@Override
public ActionHandler actionHandler(@NonNull String name) {
return MultiPageMenu.this.actionHandler(name);
}
@Override
protected void nativeInventory(@NonNull Object nativeInventory) {
MultiPageMenu.this.nativeInventory(nativeInventory);
}
@Override
public MenuBuilder menuBuilder() {
return MultiPageMenu.this.menuBuilder();
}
@Override
public void build() {
if (MultiPageMenu.this.currentPage > 1) {
set(MultiPageMenu.this.configuration().previousPageItem());
}
if (MultiPageMenu.this.pages.size() > MultiPageMenu.this.currentPage) {
set(MultiPageMenu.this.configuration().nextPageItem());
}
if (menuBuilder() == null) {
return;
}
nativeInventory(menuBuilder().build(nativeInventory(), MultiPageMenu.this));
}
@Override
public Object nativeInventory() {
return MultiPageMenu.this.nativeInventory();
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/menus/SimpleMenu.java
================================================
package dev.simplix.cirrus.common.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;
import lombok.NonNull;
import java.util.Locale;
import java.util.Map;
public class SimpleMenu extends AbstractConfigurableMenu {
public SimpleMenu(@NonNull PlayerWrapper player,
@NonNull MenuConfiguration configuration,
@NonNull Locale locale) {
super(player, configuration, locale);
}
public SimpleMenu(@NonNull PlayerWrapper player,
@NonNull MenuConfiguration configuration,
@NonNull Locale locale,
@NonNull Map actionHandlerMap) {
super(player, configuration, locale, actionHandlerMap);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/model/CallResult.java
================================================
package dev.simplix.cirrus.common.model;
public enum CallResult {
DENY_GRABBING, ALLOW_GRABBING
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/model/Click.java
================================================
package dev.simplix.cirrus.common.model;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.protocolize.api.ClickType;
import lombok.NonNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* A click contains information about a click performed on an {@link InventoryMenuItemWrapper}.
*/
public final class Click {
private final ClickType clickType;
private final Menu clickedMenu;
private final InventoryMenuItemWrapper clickedItem;
private final int slot;
public Click(
@NonNull ClickType clickType,
@NonNull Menu clickedMenu,
@Nullable InventoryMenuItemWrapper clickedItem,
int slot) {
this.clickType = clickType;
this.clickedMenu = clickedMenu;
this.clickedItem = clickedItem;
this.slot = slot;
}
public PlayerWrapper player() {
return this.clickedMenu.player();
}
public ClickType clickType() {
return this.clickType;
}
public Menu clickedMenu() {
return this.clickedMenu;
}
public List arguments() {
if (this.clickedItem != null) {
return this.clickedItem.actionArguments();
}
return new ArrayList<>();
}
public T clickedItem() {
return (T) this.clickedItem;
}
public int slot() {
return this.slot;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/MojangsonScope.java
================================================
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.simplix.cirrus.common.mojangson;
/**
* Lexical scoping elements within a JSON reader or writer.
*
* @author Jesse Wilson
* @since 1.6
*/
final class MojangsonScope {
/**
* An array with no elements requires no separators or newlines before it is closed.
*/
static final int EMPTY_ARRAY = 1;
/**
* A array with at least one value requires a comma and newline before the next element.
*/
static final int NONEMPTY_ARRAY = 2;
/**
* An object with no name/value pairs requires no separators or newlines before it is closed.
*/
static final int EMPTY_OBJECT = 3;
/**
* An object whose most recent element is a key. The next element must be a value.
*/
static final int DANGLING_NAME = 4;
/**
* An object with at least one name/value pair requires a comma and newline before the next
* element.
*/
static final int NONEMPTY_OBJECT = 5;
/**
* No object or array has been started.
*/
static final int EMPTY_DOCUMENT = 6;
/**
* A document with at an array or object.
*/
static final int NONEMPTY_DOCUMENT = 7;
/**
* A document that's been closed and cannot be accessed.
*/
static final int CLOSED = 8;
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/MojangsonWriter.java
================================================
package dev.simplix.cirrus.common.mojangson;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
/**
* A modified version of {@link JsonWriter} only using quotes when it is necessary. MojangsonWriter
* is lenient by default.
*/
public class MojangsonWriter extends JsonWriter {
/*
* From RFC 7159, "All Unicode characters may be placed within the
* quotation marks except for the characters that must be escaped:
* quotation mark, reverse solidus, and the control characters
* (U+0000 through U+001F)."
*
* We also escape '\u2028' and '\u2029', which JavaScript interprets as
* newline characters. This prevents eval() from failing with a syntax
* error. http://code.google.com/p/google-gson/issues/detail?id=341
*/
private static final String[] REPLACEMENT_CHARS;
private static final String[] HTML_SAFE_REPLACEMENT_CHARS;
static {
REPLACEMENT_CHARS = new String[128];
for (int i = 0; i <= 0x1f; i++) {
REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int) i);
}
REPLACEMENT_CHARS['"'] = "\\\"";
REPLACEMENT_CHARS['\\'] = "\\\\";
REPLACEMENT_CHARS['\t'] = "\\t";
REPLACEMENT_CHARS['\b'] = "\\b";
REPLACEMENT_CHARS['\n'] = "\\n";
REPLACEMENT_CHARS['\r'] = "\\r";
REPLACEMENT_CHARS['\f'] = "\\f";
HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
}
/**
* The output data, containing at most one top-level array or object.
*/
private final Writer out;
private int[] stack = new int[32];
private int stackSize = 0;
/**
* A string containing a full set of spaces for a single level of indentation, or null for no
* pretty printing.
*/
private String indent;
/**
* The name/value separator; either ":" or ": ".
*/
private String separator = ":";
private boolean lenient;
private boolean htmlSafe;
private String deferredName;
private boolean serializeNulls = true;
{
push(MojangsonScope.EMPTY_DOCUMENT);
}
/**
* Creates a new instance that writes a MOJANGSON-encoded stream to {@code out}. For best
* performance, ensure {@link Writer} is buffered; wrapping in {@link java.io.BufferedWriter
* BufferedWriter} if necessary.
*/
public MojangsonWriter(Writer out) {
super(out);
if (out == null) {
throw new NullPointerException("out == null");
}
this.out = out;
setLenient(true);
}
/**
* Begins encoding a new array. Each call to this method must be paired with a call to {@link
* #endArray}.
*
* @return this writer.
*/
public MojangsonWriter beginArray() throws IOException {
writeDeferredName();
return open(MojangsonScope.EMPTY_ARRAY, '[');
}
/**
* Ends encoding the current array.
*
* @return this writer.
*/
public MojangsonWriter endArray() throws IOException {
return close(MojangsonScope.EMPTY_ARRAY, MojangsonScope.NONEMPTY_ARRAY, ']');
}
/**
* Begins encoding a new object. Each call to this method must be paired with a call to {@link
* #endObject}.
*
* @return this writer.
*/
public MojangsonWriter beginObject() throws IOException {
writeDeferredName();
return open(MojangsonScope.EMPTY_OBJECT, '{');
}
/**
* Ends encoding the current object.
*
* @return this writer.
*/
public MojangsonWriter endObject() throws IOException {
return close(MojangsonScope.EMPTY_OBJECT, MojangsonScope.NONEMPTY_OBJECT, '}');
}
/**
* Enters a new scope by appending any necessary whitespace and the given bracket.
*/
private MojangsonWriter open(int empty, char openBracket) throws IOException {
beforeValue();
push(empty);
out.write(openBracket);
return this;
}
/**
* Closes the current scope by appending any necessary whitespace and the given bracket.
*/
private MojangsonWriter close(int empty, int nonempty, char closeBracket)
throws IOException {
int context = peek();
if (context != nonempty && context != empty) {
throw new IllegalStateException("Nesting problem.");
}
if (deferredName != null) {
throw new IllegalStateException("Dangling name: " + deferredName);
}
stackSize--;
if (context == nonempty) {
newline();
}
out.write(closeBracket);
return this;
}
private void push(int newTop) {
if (stackSize == stack.length) {
stack = Arrays.copyOf(stack, stackSize * 2);
}
stack[stackSize++] = newTop;
}
/**
* Returns the value on the top of the stack.
*/
private int peek() {
if (stackSize == 0) {
throw new IllegalStateException("MojangsonWriter is closed.");
}
return stack[stackSize - 1];
}
/**
* Replace the value on the top of the stack with the given value.
*/
private void replaceTop(int topOfStack) {
stack[stackSize - 1] = topOfStack;
}
/**
* Encodes the property name.
*
* @param name the name of the forthcoming value. May not be null.
* @return this writer.
*/
public MojangsonWriter name(String name) throws IOException {
if (name == null) {
throw new NullPointerException("name == null");
}
if (deferredName != null) {
throw new IllegalStateException();
}
if (stackSize == 0) {
throw new IllegalStateException("MojangsonWriter is closed.");
}
deferredName = name;
return this;
}
private void writeDeferredName() throws IOException {
if (deferredName != null) {
beforeName();
string(deferredName);
deferredName = null;
}
}
/**
* Encodes {@code value}.
*
* @param value the literal string value, or null to encode a null literal.
* @return this writer.
*/
public MojangsonWriter value(String value) throws IOException {
if (value == null) {
return nullValue();
}
writeDeferredName();
beforeValue();
string(value);
return this;
}
/**
* Writes {@code value} directly to the writer without quoting or escaping.
*
* @param value the literal string value, or null to encode a null literal.
* @return this writer.
*/
public MojangsonWriter jsonValue(String value) throws IOException {
if (value == null) {
return nullValue();
}
writeDeferredName();
beforeValue();
out.append(value);
return this;
}
/**
* Encodes {@code null}.
*
* @return this writer.
*/
public MojangsonWriter nullValue() throws IOException {
if (deferredName != null) {
if (serializeNulls) {
writeDeferredName();
} else {
deferredName = null;
return this; // skip the name and the value
}
}
beforeValue();
out.write("null");
return this;
}
/**
* Encodes {@code value}.
*
* @return this writer.
*/
public MojangsonWriter value(boolean value) throws IOException {
writeDeferredName();
beforeValue();
out.write(value ? "true" : "false");
return this;
}
/**
* Encodes {@code value}.
*
* @return this writer.
*/
public MojangsonWriter value(Boolean value) throws IOException {
if (value == null) {
return nullValue();
}
writeDeferredName();
beforeValue();
out.write(value ? "true" : "false");
return this;
}
/**
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link
* Double#isInfinite() infinities}.
* @return this writer.
*/
public MojangsonWriter value(double value) throws IOException {
writeDeferredName();
if (!lenient && (Double.isNaN(value) || Double.isInfinite(value))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
beforeValue();
out.append(Double.toString(value));
return this;
}
/**
* Encodes {@code value}.
*
* @return this writer.
*/
public MojangsonWriter value(long value) throws IOException {
writeDeferredName();
beforeValue();
out.write(Long.toString(value));
return this;
}
/**
* Encodes {@code value}.
*
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link
* Double#isInfinite() infinities}.
* @return this writer.
*/
public MojangsonWriter value(Number value) throws IOException {
if (value == null) {
return nullValue();
}
writeDeferredName();
String string = value.toString();
if (!lenient
&& (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
beforeValue();
out.append(string);
return this;
}
/**
* Ensures all buffered data is written to the underlying {@link Writer} and flushes that writer.
*/
public void flush() throws IOException {
if (stackSize == 0) {
throw new IllegalStateException("MojangsonWriter is closed.");
}
out.flush();
}
/**
* Flushes and closes this writer and the underlying {@link Writer}.
*
* @throws IOException if the JSON document is incomplete.
*/
public void close() throws IOException {
out.close();
int size = stackSize;
if (size > 1 || size == 1 && stack[size - 1] != MojangsonScope.NONEMPTY_DOCUMENT) {
throw new IOException("Incomplete document");
}
stackSize = 0;
}
private void newline() throws IOException {
if (indent == null) {
return;
}
out.write('\n');
for (int i = 1, size = stackSize; i < size; i++) {
out.write(indent);
}
}
/**
* Inserts any necessary separators and whitespace before a name. Also adjusts the stack to expect
* the name's value.
*/
private void beforeName() throws IOException {
int context = peek();
if (context == MojangsonScope.NONEMPTY_OBJECT) { // first in object
out.write(',');
} else if (context != MojangsonScope.EMPTY_OBJECT) { // not in an object!
throw new IllegalStateException("Nesting problem.");
}
newline();
replaceTop(MojangsonScope.DANGLING_NAME);
}
/**
* Inserts any necessary separators and whitespace before a literal value, inline array, or inline
* object. Also adjusts the stack to expect either a closing bracket or another element.
*/
@SuppressWarnings("fallthrough")
private void beforeValue() throws IOException {
switch (peek()) {
case MojangsonScope.NONEMPTY_DOCUMENT:
if (!lenient) {
throw new IllegalStateException(
"JSON must have only one top-level value.");
}
// fall-through
case MojangsonScope.EMPTY_DOCUMENT: // first in document
replaceTop(MojangsonScope.NONEMPTY_DOCUMENT);
break;
case MojangsonScope.EMPTY_ARRAY: // first in array
replaceTop(MojangsonScope.NONEMPTY_ARRAY);
newline();
break;
case MojangsonScope.NONEMPTY_ARRAY: // another in array
out.append(',');
newline();
break;
case MojangsonScope.DANGLING_NAME: // value for name
out.append(separator);
replaceTop(MojangsonScope.NONEMPTY_OBJECT);
break;
default:
throw new IllegalStateException("Nesting problem.");
}
}
private void string(String value) throws IOException {
boolean quotesNeeded = value.contains(" ")
|| value.isEmpty();
for (char c : value.toCharArray()) {
if (c > 0x7a || (c > 0x39 && c < 0x41) || c < 0x30 || (c > 0x5a && c < 0x61)) {
quotesNeeded = true;
break;
}
}
if (quotesNeeded) { // Mojangson uses lenient json
out.write('\"');
}
int last = 0;
int length = value.length();
if (last < length) {
out.write(value, last, length - last);
}
if (quotesNeeded) {
out.write('\"');
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/TagDeserializer.java
================================================
package dev.simplix.cirrus.common.mojangson;
import com.google.gson.*;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import net.querz.nbt.io.SNBTUtil;
import net.querz.nbt.tag.Tag;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Type;
@Slf4j
public final class TagDeserializer implements JsonDeserializer> {
private static final Gson GSON = new GsonBuilder().create();
@Override
public Tag> deserialize(
@NonNull JsonElement json,
@NonNull Type typeOfT,
@NonNull JsonDeserializationContext context)
throws JsonParseException {
if (!json.isJsonObject()) {
throw new IllegalArgumentException("Expected json object!");
}
StringWriter stringWriter = new StringWriter();
try {
GSON.toJson(json, new MojangsonWriter(stringWriter));
return SNBTUtil.fromSNBT(stringWriter.toString());
} catch (IOException e) {
log.error("Something went wrong while parsing SNBT string: " + stringWriter.toString());
throw new RuntimeException(e);
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/TagSerializer.java
================================================
package dev.simplix.cirrus.common.mojangson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import lombok.NonNull;
import net.querz.nbt.io.SNBTUtil;
import net.querz.nbt.tag.Tag;
import java.io.IOException;
import java.lang.reflect.Type;
public final class TagSerializer implements JsonSerializer> {
@Override
public JsonElement serialize(
@NonNull Tag> src,
@NonNull Type typeOfSrc,
@NonNull JsonSerializationContext context) {
try {
String json = SNBTUtil.toSNBT(src);
return JsonParser.parseString(json);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/util/ColorUtils.java
================================================
package dev.simplix.cirrus.common.util;
import lombok.experimental.UtilityClass;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@UtilityClass
public class ColorUtils {
public List colorsInBetween(final Color first, final Color second, final double step) {
final double diffBlue = (second.getBlue() - first.getBlue()) / step;
final double diffGreen = (second.getGreen() - first.getGreen()) / step;
final double diffRed = (second.getRed() - first.getRed()) / step;
final List list = new ArrayList<>();
for (int i = 1; i <= step; ++i) {
list.add(
new Color(
(int) Math.round(first.getRed() + diffRed * i),
(int) Math.round(first.getGreen() + diffGreen * i),
(int) Math.round(first.getBlue() + diffBlue * i)
)
);
}
return list;
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/util/Colors.java
================================================
package dev.simplix.cirrus.common.util;
import lombok.experimental.UtilityClass;
import java.awt.*;
@UtilityClass
public class Colors {
public final Color DARK_BLUE = new Color(0x0000AA);
public final Color DARK_GREEN = new Color(0x00AA00);
public final Color DARK_AQUA = new Color(0x00AAAA);
public final Color DARK_RED = new Color(0xAA0000);
public final Color DARK_PURPLE = new Color(0xAA00AA);
public final Color GOLD = new Color(0xFFAA00);
public final Color GRAY = new Color(0xAAAAAA);
public final Color DARK_GRAY = new Color(0x555555);
public final Color BLUE = new Color(0x5555FF);
public final Color GREEN = new Color(0x55FF55);
public final Color AQUA = new Color(0x55FFFF);
public final Color RED = new Color(0xFF5555);
public final Color LIGHT_PURPLE = new Color(0xFF55FF);
public final Color YELLOW = new Color(0xFFFF55);
public final Color WHITE = new Color(0xFFFFFF);
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/util/InventoryContentMap.java
================================================
package dev.simplix.cirrus.common.util;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import lombok.NonNull;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
public class InventoryContentMap implements ConcurrentMap {
private final Map value = new ConcurrentHashMap<>();
// Delegate methods
@Override
public int size() {
return this.value.size();
}
@Override
public boolean isEmpty() {
return this.value.isEmpty();
}
@Override
public boolean containsKey(@NonNull Object key) {
return this.value.containsKey(key);
}
@Override
public boolean containsValue(@NonNull Object value) {
return this.value.containsValue(value);
}
@Override
public InventoryMenuItemWrapper get(@NonNull Object key) {
return this.value.get(key);
}
@Nullable
@Override
public InventoryMenuItemWrapper put(@NonNull Integer key, @NonNull InventoryMenuItemWrapper value) {
return this.value.put(key, value);
}
@Override
public InventoryMenuItemWrapper remove(Object key) {
return this.value.remove(key);
}
@Override
public void putAll(@NotNull Map extends Integer, ? extends InventoryMenuItemWrapper> m) {
this.value.putAll(m);
}
@Override
public void clear() {
this.value.clear();
}
@NotNull
@Override
public Set keySet() {
return this.value.keySet();
}
@NotNull
@Override
public Collection values() {
return this.value.values();
}
@NotNull
@Override
public Set> entrySet() {
return this.value.entrySet();
}
@Override
public boolean equals(Object obj) {
return this.value.equals(obj);
}
@Override
public int hashCode() {
return this.value.hashCode();
}
@Override
public InventoryMenuItemWrapper getOrDefault(Object key, InventoryMenuItemWrapper defaultValue) {
return this.value.getOrDefault(key, defaultValue);
}
@Override
public void forEach(BiConsumer super Integer, ? super InventoryMenuItemWrapper> action) {
this.value.forEach(action);
}
@Override
public void replaceAll(BiFunction super Integer, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> function) {
this.value.replaceAll(function);
}
@Override
public InventoryMenuItemWrapper putIfAbsent(Integer key, InventoryMenuItemWrapper value) {
return this.value.putIfAbsent(key, value);
}
@Override
public boolean remove(Object key, Object value) {
return this.value.remove(key, value);
}
@Override
public boolean replace(
Integer key,
InventoryMenuItemWrapper oldValue,
InventoryMenuItemWrapper newValue) {
return this.value.replace(key, oldValue, newValue);
}
@Override
public InventoryMenuItemWrapper replace(Integer key, InventoryMenuItemWrapper value) {
return this.value.replace(key, value);
}
@Override
public InventoryMenuItemWrapper computeIfAbsent(
Integer key,
@NotNull Function super Integer, ? extends InventoryMenuItemWrapper> mappingFunction) {
return this.value.computeIfAbsent(key, mappingFunction);
}
@Override
public InventoryMenuItemWrapper computeIfPresent(
Integer key,
@NotNull BiFunction super Integer, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> remappingFunction) {
return this.value.computeIfPresent(key, remappingFunction);
}
@Override
public InventoryMenuItemWrapper compute(
Integer key,
@NotNull BiFunction super Integer, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> remappingFunction) {
return this.value.compute(key, remappingFunction);
}
@Override
public InventoryMenuItemWrapper merge(
Integer key,
@NotNull InventoryMenuItemWrapper value,
@NotNull BiFunction super InventoryMenuItemWrapper, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> remappingFunction) {
return this.value.merge(key, value, remappingFunction);
}
}
================================================
FILE: cirrus-common/src/main/java/dev/simplix/cirrus/common/util/SafeRunnable.java
================================================
package dev.simplix.cirrus.common.util;
public interface SafeRunnable {
void run() throws Throwable;
}
================================================
FILE: cirrus-common/src/main/resources/cirrus/MenuConfiguration.json
================================================
{
"title": {
"en": "§bCirrus Menu",
"de": "§bCirrus Menü"
},
"type": "GENERIC_9X4",
"placeholderItem": {
"itemType": "GRAY_STAINED_GLASS_PANE",
"displayName": {
"en": "§0",
"de": "§0"
},
"lore": {
"en": [],
"de": []
},
"amount": 1,
"slots": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
27,
28,
29,
30,
31,
32,
33,
34,
35
]
},
"reservedSlots": [],
"items": [
{
"itemType": "PLAYER_HEAD",
"displayName": {
"en": "§6Example Item",
"de": "§6Beispielitem"
},
"lore": {
"en": [
"§7Hello §6{viewer}§7,",
"§7this is an example item to show",
"§7how Cirrus menus and items are configured."
],
"de": [
"§7Hallo §6{viewer}§7,",
"§7das ist ein Beispiel, um zu zeigen",
"§7wie man Cirrus Menüs und Items konfiguriert."
]
},
"amount": 1,
"actionHandler": "noAction",
"actionArguments": [],
"slots": [
13
],
"nbt": {
"SkullOwner": "Exceptionflug"
}
}
]
}
================================================
FILE: cirrus-common/src/main/resources/cirrus/MultiPageMenuConfiguration.json
================================================
{
"title": {
"en": "§bCirrus Menu {page} / {pageCount}",
"de": "§bCirrus Menü {page} / {pageCount}"
},
"type": "GENERIC_9X6",
"placeholderItem": {
"itemType": "GRAY_STAINED_GLASS_PANE",
"displayName": {
"en": "§0",
"de": "§0"
},
"lore": {
"en": [],
"de": []
},
"amount": 1,
"slots": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
17,
18,
26,
27,
35,
36,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53
]
},
"reservedSlots": [],
"nextPageItem": {
"itemType": "LIME_STAINED_GLASS_PANE",
"displayName": {
"en": "§aNext page",
"de": "§aNächste Seite"
},
"lore": {
"en": [],
"de": []
},
"amount": 1,
"slots": [
17,
26,
35,
44
]
},
"previousPageItem": {
"itemType": "LIME_STAINED_GLASS_PANE",
"displayName": {
"en": "§cPrevious page",
"de": "§cVorherige Seite"
},
"lore": {
"en": [],
"de": []
},
"amount": 1,
"slots": [
9,
18,
27,
36
]
},
"items": []
}
================================================
FILE: cirrus-common/src/test/java/dev/simplix/cirrus/common/tests/SnbtGsonTest.java
================================================
package dev.simplix.cirrus.common.tests;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.simplix.cirrus.common.mojangson.TagDeserializer;
import dev.simplix.cirrus.common.mojangson.TagSerializer;
import net.querz.nbt.tag.CompoundTag;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public final class SnbtGsonTest {
private final Gson gson = new GsonBuilder()
.registerTypeAdapter(CompoundTag.class, new TagSerializer())
.registerTypeAdapter(CompoundTag.class, new TagDeserializer())
.create();
// @Test
public void test() {
CompoundTag display = new CompoundTag();
display.putInt("integer", 134);
display.putBoolean("boolean", true);
display.putFloat("float", 24934.3F);
display.putDouble("double", 9999.21348D);
display.putShort("short", (short) 12);
display.putByte("byte", (byte) 3);
display.putString("string", "This is a string");
CompoundTag compoundTag = new CompoundTag();
compoundTag.put("display", display);
String serialized = gson.toJson(compoundTag, CompoundTag.class);
CompoundTag deserialized = gson.fromJson(serialized, CompoundTag.class);
Assertions.assertEquals(compoundTag, deserialized);
System.out.println("Cirrus SNBT over Gson - OK");
}
}
================================================
FILE: cirrus-common/src/test/java/dev/simplix/cirrus/common/tests/SnbtTest.java
================================================
package dev.simplix.cirrus.common.tests;
import net.querz.nbt.io.SNBTUtil;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.Tag;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.IOException;
public final class SnbtTest {
@Test
public void test() throws IOException {
CompoundTag display = new CompoundTag();
display.putInt("integer", 134);
display.putBoolean("boolean", true);
display.putFloat("float", 24934.3F);
display.putDouble("double", 9999.21348D);
display.putShort("short", (short) 12);
display.putByte("byte", (byte) 3);
CompoundTag compoundTag = new CompoundTag();
compoundTag.put("display", display);
String mojangson = SNBTUtil.toSNBT(compoundTag);
Tag> after = SNBTUtil.fromSNBT(mojangson);
Assertions.assertEquals(compoundTag, after);
System.out.println("Querz SNBT - OK");
}
}
================================================
FILE: cirrus-spigot/pom.xml
================================================
4.0.0
dev.simplix.cirrus
cirrus
2.0.0
cirrus-spigot
${cirrus.version}
org.spigotmc
spigot-api
1.19-R0.1-SNAPSHOT
provided
org.spigotmc
spigot-api
1.8.8-R0.1-SNAPSHOT
provided
dev.simplix.cirrus
cirrus-common
${cirrus.version}
compile
dev.simplix.cirrus
cirrus-spigot-modern
${cirrus.version}
compile
dev.simplix
protocolize-api
2.1.0
compile
org.slf4j
slf4j-api
1.8.0-alpha2
provided
${project.name}-${project.version}
src/main/resources
true
org.apache.maven.plugins
maven-shade-plugin
3.0.0
package
shade
false
org.apache.maven.plugins
maven-compiler-plugin
8
8
org.apache.maven.plugins
maven-source-plugin
3.0.1
attach-sources
deploy
jar-no-fork
org.apache.maven.plugins
maven-javadoc-plugin
3.0.1
none
attach-javadocs
jar
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/CirrusSpigot.java
================================================
package dev.simplix.cirrus.spigot;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.effect.MenuAnimator;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.spigot.converters.*;
import dev.simplix.cirrus.spigot.listener.InventoryListener;
import dev.simplix.cirrus.spigot.menubuilder.SpigotMenuBuilder;
import dev.simplix.cirrus.spigot.util.BungeeCordComponentConverterProvider;
import dev.simplix.cirrus.spigot.util.OtherModuleProvider;
import dev.simplix.cirrus.spigot.util.ReflectionClasses;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.item.ItemStack;
import dev.simplix.protocolize.api.providers.ComponentConverterProvider;
import dev.simplix.protocolize.api.providers.ModuleProvider;
import dev.simplix.protocolize.data.ItemType;
import dev.simplix.protocolize.data.inventory.InventoryType;
import lombok.extern.slf4j.Slf4j;
import net.querz.nbt.tag.CompoundTag;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.material.MaterialData;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.UUID;
/**
* Date: 18.09.2021
*
* @author Exceptionflug
*/
@Slf4j
public class CirrusSpigot {
private static JavaPlugin plugin;
public static void init(JavaPlugin plugin) {
if (CirrusSpigot.plugin != null) {
return;
}
CirrusSpigot.plugin = plugin;
Cirrus.registerService(MenuBuilder.class, new SpigotMenuBuilder());
Bukkit.getPluginManager().registerEvents(new InventoryListener(), plugin);
Protocolize.registerService(ComponentConverterProvider.class, new BungeeCordComponentConverterProvider());
Protocolize.registerService(ModuleProvider.class, new OtherModuleProvider());
registerConverters();
}
private static void registerConverters() {
try {
// Players
Converters.register(
Player.class,
PlayerWrapper.class,
new PlayerConverter());
Converters.register(UUID.class, PlayerWrapper.class, o -> Bukkit.getPlayer((UUID) o));
// Items
Converters.register( // Protocolize ----> Bukkit
ItemStack.class,
org.bukkit.inventory.ItemStack.class,
new ProtocolizeItemStackConverter());
Converters.register( // Bukkit ----> Protocolize
org.bukkit.inventory.ItemStack.class,
ItemStack.class,
new BukkitItemStackConverter());
Converters.register(
ItemStack.class,
MenuItemWrapper.class,
o -> new ProtocolizeMenuItemWrapper(
(dev.simplix.protocolize.api.item.ItemStack) o));
Converters.register(ItemType.class, MaterialData.class, new ItemTypeMaterialDataConverter());
Converters.register(MaterialData.class, ItemType.class, new MaterialDataItemTypeConverter());
Converters.register(
CirrusItem.class,
InventoryMenuItemWrapper.class,
new ItemModelConverter());
Converters.register(
InventoryType.class,
org.bukkit.event.inventory.InventoryType.class,
new SpigotInventoryTypeConverter());
Converters.register(
ClickType.class,
dev.simplix.protocolize.api.ClickType.class,
new SpigotClickTypeConverter());
// NBT
Converters.register( // Querz ----> NMS
CompoundTag.class,
ReflectionClasses.nbtTagCompound(),
new QuerzNbtNmsNbtConverter());
Converters.register( // NMS ----> Querz
ReflectionClasses.nbtTagCompound(),
CompoundTag.class,
new NmsNbtQuerzNbtConverter());
} catch (Exception exception) {
log.error("Cannot register cirrus converters", exception);
}
Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, () -> {
if (!MenuAnimator.isEmpty()) {
MenuAnimator.updateAll();
}
}, 2, 2);
}
public static JavaPlugin plugin() {
if (plugin == null) {
throw new IllegalStateException("Cirrus is not initialized. Please call CirrusSpigot#init during onEnable.");
}
return plugin;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/SpigotPlayerWrapper.java
================================================
package dev.simplix.cirrus.spigot;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;
import dev.simplix.cirrus.spigot.util.ProtocolVersions;
import lombok.NonNull;
import org.bukkit.entity.Player;
import java.util.UUID;
public class SpigotPlayerWrapper implements PlayerWrapper {
private final Player handle;
public SpigotPlayerWrapper(@NonNull Player handle) {
this.handle = handle;
}
@Override
public void sendMessage(@NonNull String msg) {
this.handle.sendMessage(msg);
}
@Override
public void closeInventory() {
this.handle.closeInventory();
}
@Override
public boolean hasPermission(@NonNull String permission) {
return this.handle.hasPermission(permission);
}
@Override
public UUID uniqueId() {
return this.handle.getUniqueId();
}
@Override
public String name() {
return this.handle.getName();
}
@Override
public T handle() {
return (T) this.handle;
}
@Override
public int protocolVersion() {
return Math.min(ProtocolVersionUtil.serverProtocolVersion(), ProtocolVersions.MINECRAFT_1_17_1);
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/BukkitItemStackConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.spigot.util.ReflectionClasses;
import dev.simplix.cirrus.spigot.util.ReflectionUtil;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import net.querz.nbt.tag.CompoundTag;
import org.bukkit.inventory.ItemStack;
public class BukkitItemStackConverter implements Converter {
private static Class> craftItemStackClass;
private static Class> itemStackNMSClass;
static {
try {
craftItemStackClass = ReflectionUtil.getClass("{obc}.inventory.CraftItemStack");
itemStackNMSClass = ReflectionClasses.itemStackClass();
} catch (Exception exception) {
exception.printStackTrace();
}
}
@Override
public dev.simplix.protocolize.api.item.ItemStack convert(@NonNull ItemStack src) {
try {
dev.simplix.protocolize.api.item.ItemStack out = new dev.simplix.protocolize.api.item.ItemStack(
Converters.convert(src.getData(), ItemType.class),
src.getAmount(),
src.getDurability());
Object handle = ReflectionUtil.fieldValue(craftItemStackClass, src, "handle");
out.nbtData(Converters.convert(
itemStackNMSClass.getMethod("getTag").invoke(handle),
CompoundTag.class));
return out;
} catch (Throwable throwable) {
throwable.printStackTrace();
return null;
}
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/ItemModelConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.protocolize.api.item.ItemStack;
import lombok.NonNull;
public class ItemModelConverter implements Converter {
@Override
public InventoryMenuItemWrapper convert(@NonNull CirrusItem model) {
ItemStack itemStack = new ItemStack(model.itemType(), model.amount(), model.durability());
itemStack.nbtData(model.nbt());
itemStack.displayName(model.displayName());
itemStack.lore(model.lore(), true);
return InventoryMenuItemWrapper.builder()
.handle(Converters.convert(itemStack, MenuItemWrapper.class))
.actionArguments(model.actionArguments())
.actionHandler(model.actionHandler())
.build();
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/ItemTypeMaterialDataConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.mapping.ProtocolIdMapping;
import dev.simplix.protocolize.api.providers.MappingProvider;
import dev.simplix.protocolize.api.util.ProtocolVersions;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import org.bukkit.Material;
import org.bukkit.material.MaterialData;
public class ItemTypeMaterialDataConverter implements Converter {
private final MappingProvider mappingProvider = Protocolize.mappingProvider();
@Override
public MaterialData convert(@NonNull ItemType src) {
ProtocolIdMapping mapping = this.mappingProvider.mapping(src, ProtocolVersionUtil.serverProtocolVersion());
if (mapping==null) {
return null;
}
if (ProtocolVersionUtil.serverProtocolVersion() >= ProtocolVersions.MINECRAFT_1_13) {
return new MaterialData(Material.valueOf(src.name()));
}
return null;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/MaterialDataItemTypeConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import com.google.common.collect.Multimap;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.mapping.ProtocolIdMapping;
import dev.simplix.protocolize.api.providers.MappingProvider;
import dev.simplix.protocolize.api.util.ProtocolVersions;
import dev.simplix.protocolize.data.ItemType;
import dev.simplix.protocolize.data.mapping.LegacyItemProtocolIdMapping;
import lombok.NonNull;
import org.bukkit.material.MaterialData;
public class MaterialDataItemTypeConverter implements Converter {
private final MappingProvider mappingProvider = Protocolize.mappingProvider();
@Override
public ItemType convert(@NonNull MaterialData src) {
// Modern versioning
if (ProtocolVersionUtil.serverProtocolVersion() >= ProtocolVersions.MINECRAFT_1_14) {
return ItemType.valueOf(src.getItemType().name().replace("LEGACY_", ""));
}
// Deprecated Legacy versioning
Multimap mappings = this.mappingProvider.mappings(ItemType.class, ProtocolVersionUtil.serverProtocolVersion());
for (ItemType type : mappings.keySet()) {
for (ProtocolIdMapping mapping : mappings.get(type)) {
if (mapping instanceof LegacyItemProtocolIdMapping) {
if (mapping.id() == src.getItemTypeId() && ((LegacyItemProtocolIdMapping) mapping).data() == src.getData()) {
return type;
}
}
}
}
return null;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/NmsNbtQuerzNbtConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.spigot.util.ReflectionClasses;
import lombok.NonNull;
import net.querz.nbt.io.NBTInputStream;
import net.querz.nbt.tag.CompoundTag;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
public class NmsNbtQuerzNbtConverter implements Converter {
private static Method nbtCompressedStreamToolAMethod;
static {
try {
nbtCompressedStreamToolAMethod = ReflectionClasses.nbtCompressedStreamTools()
.getMethod("a", ReflectionClasses.nbtTagCompound(), OutputStream.class);
} catch (final Exception exception) {
exception.printStackTrace();
}
}
@Override
public CompoundTag convert(@NonNull Object src) {
byte[] data = null;
try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
nbtCompressedStreamToolAMethod.invoke(null, src, byteArrayOutputStream);
data = byteArrayOutputStream.toByteArray();
} catch (final Exception exception) {
exception.printStackTrace();
}
try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data)) {
return (CompoundTag) new NBTInputStream(byteArrayInputStream).readTag(99).getTag();
} catch (final IOException ioException) {
ioException.printStackTrace();
}
return null;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/PlayerConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.spigot.SpigotPlayerWrapper;
import lombok.NonNull;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class PlayerConverter implements Converter {
@Override
public PlayerWrapper convert(@NonNull @NotNull Player proxiedPlayer) {
return new SpigotPlayerWrapper(proxiedPlayer);
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/ProtocolizeItemStackConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import dev.simplix.cirrus.common.Utils;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;
import dev.simplix.cirrus.spigot.util.ReflectionClasses;
import dev.simplix.cirrus.spigot.util.ReflectionUtil;
import dev.simplix.protocolize.api.item.ItemStack;
import lombok.NonNull;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.querz.nbt.tag.*;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.material.MaterialData;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static dev.simplix.protocolize.api.util.ProtocolVersions.MINECRAFT_1_13;
import static dev.simplix.protocolize.api.util.ProtocolVersions.MINECRAFT_1_14;
public class ProtocolizeItemStackConverter implements Converter {
private static Class> craftItemStackClass;
private static Class> nbtTagCompoundClass;
private static Class> itemStackNMSClass;
private static Method nmsCopyMethod;
private static Method bukkitCopyMethod;
private static Method setTagMethod;
static {
try {
craftItemStackClass = ReflectionUtil.getClass("{obc}.inventory.CraftItemStack");
nbtTagCompoundClass = ReflectionClasses.nbtTagCompound();
itemStackNMSClass = ReflectionClasses.itemStackClass();
nmsCopyMethod = craftItemStackClass.getMethod(
"asNMSCopy",
org.bukkit.inventory.ItemStack.class);
bukkitCopyMethod = craftItemStackClass.getMethod("asBukkitCopy", itemStackNMSClass);
} catch (Exception exception) {
exception.printStackTrace();
}
}
@Override
public org.bukkit.inventory.ItemStack convert(@NonNull ItemStack src) {
if (src.itemType() == null) {
return null;
}
if (src.itemType() == null) {
return new org.bukkit.inventory.ItemStack(Material.AIR);
}
MaterialData data = Converters.convert(src.itemType(), MaterialData.class);
org.bukkit.inventory.ItemStack out;
if (ProtocolVersionUtil.serverProtocolVersion() < MINECRAFT_1_13) {
out = new org.bukkit.inventory.ItemStack(
data.getItemType(),
src.amount(),
src.durability(),
data.getData());
} else {
out = new org.bukkit.inventory.ItemStack(
data.getItemType(),
src.amount(),
src.durability());
}
if (src.nbtData() == null) {
src.nbtData(new CompoundTag());
}
String textureHashToInsert = null;
if (src.nbtData() != null) {
CompoundTag tag = src.nbtData();
if (tag.containsKey("SkullOwner") && tag.get("SkullOwner") instanceof CompoundTag) {
final CompoundTag skullOwnerTag = tag.getCompoundTag("SkullOwner");
final Tag> propertiesRaw = skullOwnerTag.get("Properties");
if (propertiesRaw instanceof CompoundTag) {
try {
final ListTag textures = (ListTag) ((CompoundTag) propertiesRaw)
.getListTag("textures");
textureHashToInsert = textures.get(0).getString("Value");
} catch (final Exception ignored) {
}
}
}
}
writeDataToNbt(src);
// Finalizing the itemstack by inserting nbt data & hiding attributes
try {
Object nmsItemStack = nmsCopyMethod.invoke(null, out);
if (src.nbtData() != null) {
try {
Method setTag = method();
;
final CompoundTag nbtTag = src.nbtData().clone();
if (textureHashToInsert != null) {
nbtTag.remove("SkullOwner");
}
setTag.invoke(nmsItemStack, Converters.convert(nbtTag, nbtTagCompoundClass));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
final org.bukkit.inventory.ItemStack itemStackCopy = (org.bukkit.inventory.ItemStack) bukkitCopyMethod
.invoke(null, nmsItemStack);
mutateMetaDataToHideAttributes(itemStackCopy);
if (textureHashToInsert == null) {
return itemStackCopy;
}
final SkullMeta meta = (SkullMeta) itemStackCopy.getItemMeta();
mutateItemMetaForTextureHash(meta, textureHashToInsert);
itemStackCopy.setItemMeta(meta);
return itemStackCopy;
} catch (final Exception exception) {
exception.printStackTrace(); // Setting nbt to nms item is also pain in the ass
}
return out;
}
private Method method() throws NoSuchMethodException {
if (setTagMethod != null) {
return setTagMethod;
}
Method setTag;
try {
setTag = itemStackNMSClass.getMethod("setTag", nbtTagCompoundClass);
} catch (NoSuchMethodException e) {
setTag = itemStackNMSClass.getDeclaredMethod("setTagClone", nbtTagCompoundClass);
setTag.setAccessible(true);
}
return setTagMethod = setTag;
}
private void mutateMetaDataToHideAttributes(org.bukkit.inventory.ItemStack out) {
try {
final ItemMeta itemMeta = out.getItemMeta();
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
itemMeta.addItemFlags(ItemFlag.HIDE_DESTROYS);
itemMeta.addItemFlags(ItemFlag.HIDE_PLACED_ON);
itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
out.setItemMeta(itemMeta);
} catch (Throwable ignored) {
}
}
private GameProfile makeProfile(@NonNull String textureHash) {
// random uuid based on the textureHash string
UUID id = new UUID(
textureHash.substring(textureHash.length() - 20).hashCode(),
textureHash.substring(textureHash.length() - 10).hashCode()
);
GameProfile profile = new GameProfile(id, "Player");
profile.getProperties().put("textures", new Property("textures", textureHash));
return profile;
}
private void mutateItemMetaForTextureHash(SkullMeta meta, String textureHash) {
try {
Method metaSetProfileMethod = meta
.getClass()
.getDeclaredMethod("setProfile", GameProfile.class);
metaSetProfileMethod.setAccessible(true);
metaSetProfileMethod.invoke(meta, makeProfile(textureHash));
} catch (NoSuchMethodException | IllegalAccessException |
InvocationTargetException reflectiveOperationException) {
// if in an older API where there is no setProfile method,
// we set the profile field directly.
try {
Field profileField = meta.getClass().getDeclaredField("profile");
profileField.setAccessible(true);
profileField.set(meta, makeProfile(textureHash));
} catch (NoSuchFieldException | IllegalAccessException exception) {
exception.printStackTrace();
}
}
}
private void writeDataToNbt(@NonNull ItemStack stack) {
if (stack.displayName() != null) {
if (ProtocolVersionUtil.serverProtocolVersion() >= MINECRAFT_1_13) {
stack.nbtData().put("Damage", new IntTag(stack.durability()));
final BaseComponent[] baseComponents = stack.displayName();
Utils.removeItalic(baseComponents);
setDisplayNameTag(stack.nbtData(), ComponentSerializer.toString(baseComponents));
} else {
setDisplayNameTag(stack.nbtData(),
TextComponent.toLegacyText(stack.displayName()));
}
}
if (stack.lore() != null) {
setLoreTag(stack.nbtData(),
stack.lore(),
ProtocolVersionUtil.serverProtocolVersion());
}
}
private void setDisplayNameTag(@NonNull CompoundTag nbtData, @NonNull String name) {
if (name == null) {
return;
}
CompoundTag display = (CompoundTag) nbtData.get("display");
if (display == null) {
display = new CompoundTag();
}
final StringTag tag = new StringTag(name);
display.put("Name", tag);
nbtData.put("display", display);
}
private void setLoreTag(
@NonNull CompoundTag nbtData,
@NonNull List lore,
int protocolVersion) {
if (lore == null) {
return;
}
CompoundTag display = (CompoundTag) nbtData.get("display");
if (display == null) {
display = new CompoundTag();
}
if (protocolVersion < MINECRAFT_1_14) {
final ListTag tag = new ListTag<>(StringTag.class);
tag.addAll(lore.stream().map(i -> new StringTag(TextComponent.toLegacyText(i))).collect(
Collectors.toList()));
display.put("Lore", tag);
nbtData.put("display", display);
} else {
final ListTag tag = new ListTag<>(StringTag.class);
tag.addAll(lore.stream().map(components -> {
for (BaseComponent component : components) {
if (!component.isItalic()) {
component.setItalic(false);
}
}
return new StringTag(ComponentSerializer.toString(components));
}).collect(Collectors.toList()));
display.put("Lore", tag);
nbtData.put("display", display);
}
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/QuerzNbtNmsNbtConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.spigot.util.ReflectionClasses;
import lombok.NonNull;
import net.querz.nbt.io.NBTOutputStream;
import net.querz.nbt.tag.CompoundTag;
import org.jetbrains.annotations.NotNull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.zip.GZIPOutputStream;
public class QuerzNbtNmsNbtConverter implements Converter {
private static Method nbtCompressedStreamToolAMethod;
static {
try {
nbtCompressedStreamToolAMethod = ReflectionClasses
.nbtCompressedStreamTools()
.getMethod("a", InputStream.class);
} catch (final Exception e) {
e.printStackTrace();
}
}
@Override
public Object convert(@NonNull @NotNull CompoundTag src) {
byte[] data = null;
try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
new NBTOutputStream(gzipOutputStream).writeTag(src, 99);
gzipOutputStream.close();
data = byteArrayOutputStream.toByteArray();
} catch (IOException ioException) {
ioException.printStackTrace();
}
try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data)) {
return nbtCompressedStreamToolAMethod.invoke(null, byteArrayInputStream);
} catch (Exception exception) {
exception.printStackTrace();
}
return null;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/SpigotClickTypeConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.converter.Converter;
import lombok.NonNull;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.NotNull;
public class SpigotClickTypeConverter implements Converter {
@Override
public dev.simplix.protocolize.api.ClickType convert(@NonNull @NotNull ClickType src) {
switch (src) {
case LEFT:
return dev.simplix.protocolize.api.ClickType.LEFT_CLICK;
case RIGHT:
return dev.simplix.protocolize.api.ClickType.RIGHT_CLICK;
case DROP:
return dev.simplix.protocolize.api.ClickType.DROP;
case MIDDLE:
return dev.simplix.protocolize.api.ClickType.CREATIVE_MIDDLE_CLICK;
case NUMBER_KEY:
return dev.simplix.protocolize.api.ClickType.NUMBER_BUTTON_1;
case SHIFT_LEFT:
return dev.simplix.protocolize.api.ClickType.SHIFT_LEFT_CLICK;
case SHIFT_RIGHT:
return dev.simplix.protocolize.api.ClickType.SHIFT_RIGHT_CLICK;
case CONTROL_DROP:
return dev.simplix.protocolize.api.ClickType.DROP_ALL;
case DOUBLE_CLICK:
return dev.simplix.protocolize.api.ClickType.DOUBLE_CLICK;
case WINDOW_BORDER_LEFT:
return dev.simplix.protocolize.api.ClickType.LEFT_CLICK_OUTSIDE_INVENTORY_HOLDING_NOTHING;
case WINDOW_BORDER_RIGHT:
return dev.simplix.protocolize.api.ClickType.RIGHT_CLICK_OUTSIDE_INVENTORY_HOLDING_NOTHING;
}
return null;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/SpigotInventoryTypeConverter.java
================================================
package dev.simplix.cirrus.spigot.converters;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.protocolize.data.inventory.InventoryType;
import lombok.NonNull;
public class SpigotInventoryTypeConverter implements Converter {
@Override
public org.bukkit.event.inventory.InventoryType convert(@NonNull InventoryType src) {
switch (src) {
case ANVIL:
return org.bukkit.event.inventory.InventoryType.ANVIL;
case BEACON:
return org.bukkit.event.inventory.InventoryType.BEACON;
case BREWING_STAND:
return org.bukkit.event.inventory.InventoryType.BREWING;
case CRAFTING:
return org.bukkit.event.inventory.InventoryType.WORKBENCH;
case GENERIC_3X3:
return org.bukkit.event.inventory.InventoryType.DISPENSER;
case ENCHANTMENT:
return org.bukkit.event.inventory.InventoryType.ENCHANTING;
case FURNACE:
return org.bukkit.event.inventory.InventoryType.FURNACE;
case HOPPER:
return org.bukkit.event.inventory.InventoryType.HOPPER;
case MERCHANT:
return org.bukkit.event.inventory.InventoryType.MERCHANT;
}
if (src.name().startsWith("GENERIC")) {
return org.bukkit.event.inventory.InventoryType.CHEST;
}
return null;
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/listener/InventoryListener.java
================================================
package dev.simplix.cirrus.spigot.listener;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.menu.AbstractMenu;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.cirrus.common.model.Click;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.InventoryView;
import java.util.Map;
@Slf4j
public class InventoryListener implements Listener {
private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);
@EventHandler
public void onDrag(InventoryDragEvent event) {
InventoryView inventoryView = event.getWhoClicked().getOpenInventory();
if (event.getInventory() == null) {
return;
}
Menu menu = this.menuBuilder.menuByHandle(inventoryView);
if (menu == null) {
return;
}
event.setCancelled(true);
}
@EventHandler
public void onClick(InventoryClickEvent event) {
InventoryView inventoryView = event.getWhoClicked().getOpenInventory();
if (event.getClickedInventory() == null) {
return;
}
// Bukkit.broadcastMessage("Clicked inventoryView");
Menu menu = this.menuBuilder.menuByHandle(inventoryView);
if (menu == null) {
return;
}
// Bukkit.broadcastMessage("Clicked menu: "
// + menu.getClass().getSimpleName()
// + " @ slot "
// + event.getSlot());
Container container;
if (event.getRawSlot() > menu.topContainer().capacity() - 1) {
container = menu.bottomContainer();
// Bukkit.broadcastMessage("Clicked bottom container");
} else {
container = menu.topContainer();
// Bukkit.broadcastMessage("Clicked top container");
}
InventoryMenuItemWrapper item = container.get(event.getRawSlot());
ClickType type = event.getClick();
if (item == null) {
// Bukkit.broadcastMessage("Clicked nothing");
if (menu.customActionHandler() != null) {
try {
CallResult callResult = menu
.customActionHandler()
.handle(new Click(Converters.convert(
type,
dev.simplix.protocolize.api.ClickType.class),
menu, null, event.getSlot()));
event.setCancelled(callResult == null || callResult == CallResult.DENY_GRABBING);
} catch (Exception ex) {
event.setCancelled(true);
menu.handleException(null, ex);
}
}
return;
}
// Bukkit.broadcastMessage("Clicked " + item.displayName());
ActionHandler actionHandler = menu.actionHandler(item.actionHandler());
if (actionHandler == null) {
event.setCancelled(true);
return;
}
try {
final CallResult callResult = actionHandler.handle(new Click(
Converters.convert(type, dev.simplix.protocolize.api.ClickType.class),
menu,
item,
event.getSlot()));
event.setCancelled(callResult == null || callResult == CallResult.DENY_GRABBING);
} catch (final Exception ex) {
event.setCancelled(true);
menu.handleException(actionHandler, ex);
}
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
this.menuBuilder.destroyMenusOfPlayer(event.getPlayer().getUniqueId());
}
@EventHandler
public void onClose(InventoryCloseEvent inventoryCloseEvent) {
InventoryView inventoryView = inventoryCloseEvent.getPlayer().getOpenInventory();
if (inventoryView == null) {
return;
}
Menu menu = this.menuBuilder.menuByHandle(inventoryView);
if (menu == null) {
return;
}
((Player) inventoryCloseEvent.getPlayer()).updateInventory();
Map.Entry lastBuild = this.menuBuilder.lastBuildOfPlayer(inventoryCloseEvent.getPlayer().getUniqueId());
if (lastBuild == null) {
log.warn("[Cirrus] Exiting from unbuilt menu? Class = "
+ menu.getClass().getName()
+ ", Player = "
+ inventoryCloseEvent.getPlayer().getName());
menu.handleClose(false);
this.menuBuilder.invalidate(menu);
return;
}
if (((AbstractMenu) lastBuild.getKey()).internalId() == ((AbstractMenu) menu).internalId()
&& (System.currentTimeMillis() - lastBuild.getValue()) <= 55) {
return;
}
menu.handleClose((System.currentTimeMillis() - lastBuild.getValue()) <= 55);
this.menuBuilder.invalidate(menu);
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/menubuilder/SpigotMenuBuilder.java
================================================
package dev.simplix.cirrus.spigot.menubuilder;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.common.menus.MultiPageMenu;
import dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;
import dev.simplix.cirrus.spigot.util.ReflectionUtil;
import dev.simplix.protocolize.api.util.ProtocolVersions;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Constructor;
import java.util.*;
import java.util.Map.Entry;
@Slf4j
public final class SpigotMenuBuilder implements MenuBuilder {
private static Constructor> modernInventoryViewConstructor;
static {
try {
if (ProtocolVersionUtil.serverProtocolVersion() > ProtocolVersions.MINECRAFT_1_13) {
Class> modernInventoryViewClass = SpigotMenuBuilder.class.getClassLoader()
.loadClass("dev.simplix.cirrus.spigot.modern.ModernInventoryView");
modernInventoryViewConstructor =
modernInventoryViewClass.getConstructor(Menu.class, Inventory.class, Inventory.class);
}
} catch (ReflectiveOperationException exception) {
log.error("SpigotMenuBuilder won't work", exception);
}
}
private final Map> buildMap = new LinkedHashMap<>();
private final List menus = new LinkedList<>();
@Override
public T build(@Nullable T prebuild, @NonNull Menu menu) {
boolean reopen = false;
boolean register = prebuild == null;
if (prebuild instanceof InventoryView) {
InventoryView inventoryView = (InventoryView) prebuild;
if (!inventoryView.getTitle().equals(menu.title())
|| inventoryView.getTopInventory().getSize() != menu.inventoryType()
.getTypicalSize(ProtocolVersionUtil.serverProtocolVersion())
|| inventoryView.getTopInventory().getType() != Converters
.convert(menu.inventoryType(), org.bukkit.event.inventory.InventoryType.class)) {
prebuild = (T) makeView(menu);
reopen = true;
}
} else {
prebuild = (T) makeView(menu);
}
InventoryView view = (InventoryView) prebuild;
buildContainer(view.getTopInventory(), menu.topContainer(), false);
// buildContainer(view.getBottomInventory(), menu.bottomContainer(), true);
this.buildMap.put(
menu.player().uniqueId(),
new AbstractMap.SimpleEntry<>(menu, System.currentTimeMillis()));
if (register) {
this.menus.add(menu);
}
if (reopen || menu instanceof MultiPageMenu) {
open(menu.player(), prebuild);
}
return prebuild;
}
private void buildContainer(Inventory inventory, Container container, boolean bottom) {
for (int i = 0; i < container.capacity(); i++) {
InventoryMenuItemWrapper item = container.itemMap().get(i + container.baseSlot());
ItemStack currentStack = inventory.getItem(i);
if (item == null) {
if (currentStack != null) {
if (bottom) {
inventory.setItem(
container.baseSlot() + container.capacity() - 1 - (
i
+ container.baseSlot()),
null);
} else {
inventory.setItem(i, null);
}
}
}
if (item != null) {
ItemStack bukkitItemStack = Converters.convert(item.handle(), ItemStack.class);
if (currentStack == null) {
if (item.handle() == null) {
Bukkit.getLogger()
.severe("InventoryItem's ItemStackWrapper is null @ slot " + i);
continue;
}
if (bottom) {
inventory.setItem(
container.baseSlot() + container.capacity() - 1 - (
i
+ container.baseSlot()),
bukkitItemStack);
} else {
inventory.setItem(i, bukkitItemStack);
}
} else {
if (!currentStack.equals(bukkitItemStack)) {
if (bottom) {
inventory.setItem(
container.baseSlot() + container.capacity() - 1 - (
i
+ container.baseSlot()),
bukkitItemStack);
} else {
inventory.setItem(i, bukkitItemStack);
}
}
}
}
}
}
private static boolean isChest(dev.simplix.protocolize.data.inventory.InventoryType type) {
if (type == dev.simplix.protocolize.data.inventory.InventoryType.GENERIC_3X3) {
return false;
} else {
return type.name().startsWith("GENERIC") || type.name().contains("CHEST");
}
}
private InventoryView makeView(Menu menu) {
Inventory top;
if (isChest(menu.inventoryType())) {
top = Bukkit.createInventory(
menu.player().handle(),
menu.inventoryType().getTypicalSize(ProtocolVersionUtil.serverProtocolVersion()),
menu.title());
} else {
top = Bukkit.createInventory(
menu.player().handle(),
Converters
.convert(menu.inventoryType(), org.bukkit.event.inventory.InventoryType.class),
menu.title());
}
Inventory bottom;
if (menu.bottomContainer().itemMap().isEmpty()) {
bottom = ((Player) menu.player().handle()).getInventory();
} else {
bottom = createPlayerInventory(menu.player().handle());
}
if (ProtocolVersionUtil.serverProtocolVersion() > ProtocolVersions.MINECRAFT_1_13) {
return modernView(menu, top, bottom);
} else {
return legacyView(menu, top, bottom);
}
}
private InventoryView modernView(Menu menu, Inventory top, Inventory bottom) {
// We need to construct this class using reflection since referencing this class in code
// would cause a VerifyError while loading the class on non-modern spigot versions.
try {
return (InventoryView) modernInventoryViewConstructor
.newInstance(menu, top, bottom);
} catch (Exception e) {
log.error("Unable to construct ModernInventoryView", e);
}
return null;
}
private InventoryView legacyView(Menu menu, Inventory top, Inventory bottom) {
return new InventoryView() {
private final Inventory topInventory = top;
private final Inventory bottomInventory = bottom;
@Override
public Inventory getTopInventory() {
return this.topInventory;
}
@Override
public Inventory getBottomInventory() {
return this.bottomInventory;
}
@Override
public HumanEntity getPlayer() {
return menu.player().handle();
}
@Override
public InventoryType getType() {
return Converters.convert(
menu.inventoryType(),
org.bukkit.event.inventory.InventoryType.class);
}
};
}
private Inventory createPlayerInventory(Player player) {
try {
Class> craftPlayerInventoryClass =
ReflectionUtil.getClass("{obc}.inventory.CraftInventoryPlayer");
Class> nmsPlayerInventoryClass =
ReflectionUtil.getClass("{nms}.PlayerInventory");
Class> nmsEntityHumanClass =
ReflectionUtil.getClass("{nms}.EntityHuman");
Constructor> nmsPlayerInventoryConstructor =
nmsPlayerInventoryClass.getConstructor(nmsEntityHumanClass);
Object nmsPlayerInventory = nmsPlayerInventoryConstructor.newInstance(
nmsEntityHumanClass.cast(ReflectionUtil.nmsPlayer(player)));
Constructor> craftPlayerInventoryConstructor =
craftPlayerInventoryClass.getConstructor(nmsPlayerInventoryClass);
return (Inventory) craftPlayerInventoryConstructor.newInstance(nmsPlayerInventory);
} catch (ReflectiveOperationException exception) {
log.error("Cannot create player inventory", exception);
}
return null;
}
@Override
public void open(@NonNull PlayerWrapper playerWrapper, @NonNull T inventoryImpl) {
((Player) playerWrapper.handle()).openInventory((InventoryView) inventoryImpl);
}
@Override
public Menu menuByHandle(Object handle) {
if (handle == null) {
return null;
}
for (final Menu menu : this.menus) {
if (menu.equals(handle)) {
return menu;
}
}
return null;
}
@Override
public void destroyMenusOfPlayer(@NonNull UUID uniqueId) {
this.menus.removeIf(
wrapper -> ((Player) wrapper.player().handle()).getUniqueId().equals(uniqueId));
this.buildMap.remove(uniqueId);
}
@Override
public Entry lastBuildOfPlayer(@NonNull UUID uniqueId) {
return this.buildMap.get(uniqueId);
}
@Override
public void invalidate(@NonNull Menu menu) {
this.menus.remove(menu);
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/menus/SpigotMenu.java
================================================
package dev.simplix.cirrus.spigot.menus;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.cirrus.spigot.util.SpigotItemsUtils;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
public interface SpigotMenu extends Menu {
default ItemType typeFromMaterial(@NonNull MaterialData material) {
return SpigotItemsUtils.typeFromMaterial(material);
}
default ItemType typeFromMaterial(@NonNull Material material) {
return SpigotItemsUtils.typeFromMaterial(material);
}
default MenuItemWrapper wrapBukkitItemStack(@NonNull ItemStack itemStack) {
return SpigotItemsUtils.wrapBukkitItemStack(itemStack);
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/BungeeCordComponentConverterProvider.java
================================================
package dev.simplix.cirrus.spigot.util;
import dev.simplix.protocolize.api.ComponentConverter;
import dev.simplix.protocolize.api.providers.ComponentConverterProvider;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
/**
* Date: 24.08.2021
*
* @author Exceptionflug
*/
public final class BungeeCordComponentConverterProvider implements ComponentConverterProvider {
@Override
public ComponentConverter> platformConverter() {
return BungeeCordComponentConverter.INSTANCE;
}
public static class BungeeCordComponentConverter implements ComponentConverter {
static BungeeCordComponentConverter INSTANCE = new BungeeCordComponentConverter();
private BungeeCordComponentConverter() {
}
@Override
public String toLegacyText(BaseComponent[] components) {
return new TextComponent(components).toLegacyText();
}
@Override
public String toJson(BaseComponent[] components) {
return ComponentSerializer.toString(components);
}
@Override
public BaseComponent[] fromLegacyText(String legacyText) {
return TextComponent.fromLegacyText("§r" + legacyText);
}
@Override
public BaseComponent[] fromJson(String json) {
return ComponentSerializer.parse(json);
}
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/OtherModuleProvider.java
================================================
package dev.simplix.cirrus.spigot.util;
import dev.simplix.protocolize.api.Platform;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.module.ProtocolizeModule;
import dev.simplix.protocolize.api.providers.ModuleProvider;
import lombok.Getter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Date: 23.08.2021
*
* @author Exceptionflug
*/
@Slf4j(topic = "Protocolize")
@Getter
@Accessors(fluent = true)
public final class OtherModuleProvider implements ModuleProvider {
private final List modules = new ArrayList<>();
@Override
public void registerModule(ProtocolizeModule module) {
if (!supportedPlatform(module.supportedPlatforms())) {
log.warn("Won't register module " + module.getClass().getName() + ": Only supports " + Arrays.toString(module.supportedPlatforms()));
return;
}
modules.add(module);
enableModule(module);
}
@Override
public boolean moduleInstalled(String s) {
return this.modules.stream().map(module -> module.getClass().getSimpleName()).collect(Collectors.toList()).contains(s);
}
@Override
public ProtocolizeModule module(String s) {
return this.modules.stream().filter(module -> module.getClass().getSimpleName().equalsIgnoreCase(s)).findFirst().orElse(null);
}
private boolean supportedPlatform(Platform[] supportedPlatforms) {
for (Platform platform : supportedPlatforms) {
if (Protocolize.platform() == platform) {
return true;
}
}
return false;
}
private void enableModule(ProtocolizeModule module) {
module.registerMappings(Protocolize.mappingProvider());
module.registerPackets(Protocolize.protocolRegistration());
log.info("Enabled module " + module.getClass().getName());
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ProtocolVersionUtil.java
================================================
package dev.simplix.cirrus.spigot.util;
import java.lang.reflect.Field;
import dev.simplix.protocolize.data.inventory.InventoryType;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public final class ProtocolVersionUtil {
private static int protocolVersion;
public static int serverProtocolVersion() {
if (protocolVersion == 0) {
protocolVersion = detectVersion();
}
return protocolVersion;
}
private static int detectVersion() {
String majorVersion = ReflectionUtil
.serverVersion()
.substring(1, ReflectionUtil.serverVersion().indexOf('_', 3));
try {
Field field = dev.simplix.cirrus.spigot.util.ProtocolVersions.class.getField("MINECRAFT_" + majorVersion);
return field.getInt(null);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Cirrus is not compatible with server version "
+ ReflectionUtil.serverVersion());
} catch (IllegalAccessException e) {
log.error("[Cirrus] Unable to detect protocol version", e);
return ProtocolVersions.MINECRAFT_1_8;
}
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ProtocolVersions.java
================================================
package dev.simplix.cirrus.spigot.util;
public class ProtocolVersions {
public final static int MINECRAFT_1_8 = 47;
public final static int MINECRAFT_1_9 = 107;
public final static int MINECRAFT_1_9_1 = 108;
public final static int MINECRAFT_1_9_2 = 109;
public final static int MINECRAFT_1_9_3 = 110;
public final static int MINECRAFT_1_9_4 = MINECRAFT_1_9_3;
public final static int MINECRAFT_1_10 = 210;
public final static int MINECRAFT_1_11 = 315;
public final static int MINECRAFT_1_11_1 = 316;
public final static int MINECRAFT_1_11_2 = MINECRAFT_1_11_1;
public final static int MINECRAFT_1_12 = 335;
public final static int MINECRAFT_1_12_1 = 338;
public final static int MINECRAFT_1_12_2 = 340;
public final static int MINECRAFT_1_13 = 393;
public final static int MINECRAFT_1_13_1 = 401;
public final static int MINECRAFT_1_13_2 = 404;
public final static int MINECRAFT_1_14 = 477;
public final static int MINECRAFT_1_14_1 = 480;
public final static int MINECRAFT_1_14_2 = 485;
public final static int MINECRAFT_1_14_3 = 490;
public final static int MINECRAFT_1_14_4 = 498;
public final static int MINECRAFT_1_15 = 573;
public final static int MINECRAFT_1_15_1 = 575;
public final static int MINECRAFT_1_15_2 = 578;
public final static int MINECRAFT_1_16 = 735;
public final static int MINECRAFT_1_16_1 = 736;
public final static int MINECRAFT_1_16_2 = 751;
public final static int MINECRAFT_1_16_3 = 753;
public final static int MINECRAFT_1_16_4 = 754;
public final static int MINECRAFT_1_16_5 = MINECRAFT_1_16_4;
public final static int MINECRAFT_1_17 = 755;
public final static int MINECRAFT_1_17_1 = 756;
public final static int MINECRAFT_1_18 = 757;
public final static int MINECRAFT_LATEST = MINECRAFT_1_18;
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ReflectionClasses.java
================================================
package dev.simplix.cirrus.spigot.util;
public class ReflectionClasses {
public static Class> itemStackClass() throws ClassNotFoundException {
if (ReflectionUtil.hasNewPackageStructure()) {
return ReflectionUtil
.getClass("{nm}.world.item.ItemStack");
} else {
return ReflectionUtil
.getClass("{nms}.ItemStack");
}
}
public static Class> nbtCompressedStreamTools() throws ClassNotFoundException {
if (ReflectionUtil.hasNewPackageStructure()) {
return ReflectionUtil
.getClass("{nm}.nbt.NBTCompressedStreamTools");
} else {
return ReflectionUtil
.getClass("{nms}.NBTCompressedStreamTools");
}
}
public static Class> nbtTagCompound() throws ClassNotFoundException {
if (ReflectionUtil.hasNewPackageStructure()) {
return ReflectionUtil
.getClass("{nm}.nbt.NBTTagCompound");
} else {
return ReflectionUtil
.getClass("{nms}.NBTTagCompound");
}
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ReflectionUtil.java
================================================
package dev.simplix.cirrus.spigot.util;
import com.mojang.authlib.GameProfile;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Scoreboard;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public final class ReflectionUtil {
private static final String EXCEPTION_OCCURRED = "Exception occurred";
private static final String GET_HANDLE = "getHandle";
private static final String PLAYER_CONNECTION = "playerConnection";
private static final String SEND_PACKET = "sendPacket";
private static final String NMS_PACKET = "{nms}.Packet";
private static final Map, String>, Field> CACHED_FIELDS = new HashMap<>();
private static final Map> CACHED_CLASSES = new HashMap<>();
public static boolean hasNewPackageStructure() {
return ProtocolVersionUtil.serverProtocolVersion() >= ProtocolVersions.MINECRAFT_1_17;
}
public static Class> getClass(String classname) throws ClassNotFoundException {
String path = classname
.replace(
"{nm}",
"net.minecraft" + (
hasNewPackageStructure()
? ""
: "." + serverVersion()))
.replace(
"{nms}",
"net.minecraft.server" + (
hasNewPackageStructure()
? ""
: "." + serverVersion()))
.replace("{obc}", "org.bukkit.craftbukkit." + serverVersion());
Class> out = CACHED_CLASSES.get(path);
if (out == null) {
out = Class.forName(path);
CACHED_CLASSES.put(path, out);
}
return out;
}
public static String serverVersion() {
try {
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
} catch (Exception exception) {
return "v1_17_1";
}
}
public static GameProfile gameProfile(@NonNull Player player)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object obcPlayer = obcPlayer(player);
Class> obcPlayerClass = obcPlayer.getClass();
return (GameProfile) obcPlayerClass.getMethod("getProfile").invoke(player);
}
public static Object nmsPlayer(@NonNull Player player)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method getHandle = player.getClass().getMethod(GET_HANDLE);
return getHandle.invoke(player);
}
public static Object obcPlayer(@NonNull Player player)
throws ClassNotFoundException {
return getClass("{obc}.entity.CraftPlayer").cast(player);
}
public static Object nmsWorld(@NonNull World world)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method getHandle = world.getClass().getMethod(GET_HANDLE);
return getHandle.invoke(world);
}
public static Object nmsScoreboard(@NonNull Scoreboard scoreboard)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method getHandle = scoreboard.getClass().getMethod(GET_HANDLE);
return getHandle.invoke(scoreboard);
}
public static Object fieldValue(@NonNull Object instance, @NonNull String fieldName)
throws IllegalAccessException {
final Map.Entry, String> key = new AbstractMap.SimpleEntry<>(
instance.getClass(),
fieldName);
final Field field = CACHED_FIELDS.computeIfAbsent(key, i -> {
try {
return instance.getClass().getDeclaredField(fieldName);
} catch (final NoSuchFieldException e) {
log.error(EXCEPTION_OCCURRED, e);
}
return null;
});
if (field == null) {
return null;
}
if (!field.isAccessible()) {
field.setAccessible(true);
}
return field.get(instance);
}
public static T fieldValue(@NonNull Field field, @NonNull Object obj) {
try {
return (T) field.get(obj);
} catch (Exception exception) {
log.error(EXCEPTION_OCCURRED, exception);
return null;
}
}
public static Field field(@NonNull Class> clazz, @NonNull String fieldName)
throws NoSuchFieldException {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}
public static void value(Object instance, String field, Object value) {
try {
Field f = instance.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(instance, value);
} catch (Exception exception) {
log.error(EXCEPTION_OCCURRED, exception);
}
}
public static void value(
@NonNull Class> clazz,
@NonNull Object instance,
@NonNull String field,
@NonNull Object value) {
try {
Field declaredField = clazz.getDeclaredField(field);
declaredField.setAccessible(true);
declaredField.set(instance, value);
} catch (Exception e) {
log.error(EXCEPTION_OCCURRED, e);
}
}
public static void valueSubclass(
@NonNull Class> clazz,
@NonNull Object instance,
@NonNull String field,
@NonNull Object value) {
try {
Field declaredField = clazz.getDeclaredField(field);
declaredField.setAccessible(true);
declaredField.set(instance, value);
} catch (Exception e) {
log.error(EXCEPTION_OCCURRED, e);
}
}
public static void sendAllPacket(@NonNull Object packet) throws ReflectiveOperationException {
for (Player p : Bukkit.getOnlinePlayers()) {
Object nmsPlayer = nmsPlayer(p);
Object connection = nmsPlayer.getClass().getField(PLAYER_CONNECTION).get(nmsPlayer);
connection
.getClass()
.getMethod(SEND_PACKET, ReflectionUtil.getClass(NMS_PACKET))
.invoke(connection, packet);
}
}
public static void sendListPacket(@NonNull List players, @NonNull Object packet) {
try {
for (String name : players) {
Object nmsPlayer = nmsPlayer(Bukkit.getPlayer(name));
Object connection = nmsPlayer.getClass().getField(PLAYER_CONNECTION).get(nmsPlayer);
connection
.getClass()
.getMethod(SEND_PACKET, ReflectionUtil.getClass(NMS_PACKET))
.invoke(connection, packet);
}
} catch (Exception exception) {
log.error(EXCEPTION_OCCURRED, exception);
}
}
public static void sendPlayerPacket(@NonNull Player player, @NonNull Object packet)
throws ReflectiveOperationException {
Object nmsPlayer = nmsPlayer(player);
Object connection = nmsPlayer.getClass().getField(PLAYER_CONNECTION).get(nmsPlayer);
connection
.getClass()
.getMethod(SEND_PACKET, ReflectionUtil.getClass(NMS_PACKET))
.invoke(connection, packet);
}
public static void listFields(@NonNull Object object) {
log.info(object.getClass().getName() + " contains " + object
.getClass()
.getDeclaredFields().length + " declared fields.");
log.info(object.getClass().getName() + " contains " + object
.getClass()
.getDeclaredClasses().length + " declared classes.");
Field[] declaredFields = object.getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
try {
log.info(field.getName() + " -> " + field.get(object));
} catch (IllegalArgumentException | IllegalAccessException exception) {
log.error(EXCEPTION_OCCURRED, exception);
}
}
}
public static Object fieldValue(
@NonNull Class> superclass,
@NonNull Object instance,
@NonNull String fieldName)
throws IllegalAccessException, NoSuchFieldException {
Field field = superclass.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(instance);
}
}
================================================
FILE: cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/SpigotItemsUtils.java
================================================
package dev.simplix.cirrus.spigot.util;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;
import dev.simplix.protocolize.data.ItemType;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
@UtilityClass
public class SpigotItemsUtils {
public ItemType typeFromMaterial(@NonNull MaterialData material) {
return Converters.convert(material, ItemType.class);
}
public ItemType typeFromMaterial(@NonNull Material material) {
return ItemType.valueOf(material.name());
}
public MenuItemWrapper wrapBukkitItemStack(@NonNull ItemStack itemStack) {
dev.simplix.protocolize.api.item.ItemStack protocolizeStack = Converters.convert(itemStack, dev.simplix.protocolize.api.item.ItemStack.class);
return new ProtocolizeMenuItemWrapper(protocolizeStack);
}
}
================================================
FILE: cirrus-spigot-example/pom.xml
================================================
4.0.0
dev.simplix.cirrus
cirrus
2.0.0
cirrus-spigot-example
${cirrus.version}
cirrus-common
dev.simplix.cirrus
compile
${cirrus.version}
cirrus-spigot
dev.simplix.cirrus
compile
${cirrus.version}
org.spigotmc
spigot-api
1.19-R0.1-SNAPSHOT
provided
${project.name}-${project.version}
src/main/resources
true
org.apache.maven.plugins
maven-compiler-plugin
8
8
maven-shade-plugin
3.2.4
package
shade
================================================
FILE: cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/CirrusExamplePlugin.java
================================================
package dev.simplix.cirrus.spigot.example;
import dev.simplix.cirrus.spigot.CirrusSpigot;
import dev.simplix.cirrus.spigot.example.commands.TestCommandExecutor;
import org.bukkit.plugin.java.JavaPlugin;
public class CirrusExamplePlugin extends JavaPlugin {
@Override
public void onEnable() {
CirrusSpigot.init(this);
getCommand("test").setExecutor(new TestCommandExecutor());
}
}
================================================
FILE: cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/commands/TestCommandExecutor.java
================================================
package dev.simplix.cirrus.spigot.example.commands;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.impl.SimpleMultiPageMenuConfiguration;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.spigot.example.menus.ExampleMultiPageMenu;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class TestCommandExecutor implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
if (sender instanceof Player) {
Player player = (Player) sender;
final PlayerWrapper wrapper = Converters.getConverter(Player.class, PlayerWrapper.class).convert(player);
new ExampleMultiPageMenu(
wrapper,
Cirrus.configurationFactory().loadFile(
"plugins/Cirrus/example2.json", SimpleMultiPageMenuConfiguration.class)).open();
}
return false;
}
}
================================================
FILE: cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/menus/ExampleMenu.java
================================================
package dev.simplix.cirrus.spigot.example.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.effects.RGBColorChangeAnimation;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;
import dev.simplix.cirrus.common.model.CallResult;
import java.awt.*;
import java.util.Locale;
public class ExampleMenu extends AbstractConfigurableMenu {
public ExampleMenu(PlayerWrapper player, MenuConfiguration configuration) {
super(player, configuration, Locale.ENGLISH);
registerActionHandler("tnt", click -> {
topContainer().itemMap().remove(click.slot());
title("Hello, {viewer}");
build();
player().sendMessage("It simply works :)");
return CallResult.DENY_GRABBING;
});
set(configuration.businessItems().get("test"));
set(CirrusItem.animated(RGBColorChangeAnimation.fat("test", Color.green, Color.red)));
set(CirrusItem
.animated(RGBColorChangeAnimation.fat("test", Color.green, Color.red))
.slot(1, 2, 3)
.glow()
);
}
}
================================================
FILE: cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/menus/ExampleMultiPageMenu.java
================================================
package dev.simplix.cirrus.spigot.example.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.menus.MultiPageMenu;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.item.ItemStack;
import dev.simplix.protocolize.api.providers.MappingProvider;
import dev.simplix.protocolize.data.ItemType;
import java.util.Collections;
import java.util.Locale;
public class ExampleMultiPageMenu extends MultiPageMenu {
private final MappingProvider mappingProvider = Protocolize.mappingProvider();
public ExampleMultiPageMenu(
PlayerWrapper player,
MultiPageMenuConfiguration configuration) {
super(player, configuration, Locale.ENGLISH);
registerMyActionHandlers();
addItems();
}
private void registerMyActionHandlers() {
registerActionHandler("test", click -> {
player().sendMessage("This is " + click.clickedItem().type().name());
return CallResult.DENY_GRABBING;
});
}
private void addItems() {
for (ItemType type : ItemType.values()) {
if (this.mappingProvider.mapping(type, player().protocolVersion()) != null) {
add(wrapItemStack(new ItemStack(type)), "test", Collections.emptyList());
}
}
}
}
================================================
FILE: cirrus-spigot-example/src/main/resources/plugin.yml
================================================
name: CirrusExample
author: Exceptionflug
version: 1.0
main: dev.simplix.cirrus.spigot.example.CirrusExamplePlugin
api-version: 1.17
commands:
test:
description: Opens the test gui
================================================
FILE: cirrus-spigot-modern/pom.xml
================================================
4.0.0
dev.simplix.cirrus
cirrus
2.0.0
cirrus-spigot-modern
${cirrus.version}
org.spigotmc
spigot-api
1.19-R0.1-SNAPSHOT
provided
dev.simplix.cirrus
cirrus-common
${cirrus.version}
provided
================================================
FILE: cirrus-spigot-modern/src/main/java/dev/simplix/cirrus/spigot/modern/ModernInventoryView.java
================================================
package dev.simplix.cirrus.spigot.modern;
import dev.simplix.cirrus.common.menu.Menu;
import lombok.NonNull;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
public final class ModernInventoryView extends InventoryView {
private final Menu menu;
private final Inventory top;
private final Inventory bottom;
public ModernInventoryView(
@NonNull Menu menu,
@NonNull Inventory top,
@NonNull Inventory bottom) {
this.menu = menu;
this.top = top;
this.bottom = bottom;
}
@Override
public Inventory getTopInventory() {
return top;
}
@Override
public Inventory getBottomInventory() {
return bottom;
}
@Override
public HumanEntity getPlayer() {
return menu.player().handle();
}
@Override
public InventoryType getType() {
return top.getType();
}
@Override
public String getTitle() {
return menu.title();
}
}
================================================
FILE: cirrus-velocity/pom.xml
================================================
4.0.0
org.apache.maven.plugins
maven-compiler-plugin
maven-shade-plugin
3.2.4
package
shade
dev.simplix.cirrus
cirrus
2.0.0
cirrus-velocity
${cirrus.version}
3.0.0
cirrus-common
dev.simplix.cirrus
compile
${cirrus.version}
com.velocitypowered
velocity-api
${velocity.version}
provided
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/CirrusVelocity.java
================================================
package dev.simplix.cirrus.velocity;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.effect.MenuAnimator;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.velocity.converters.ItemModelConverter;
import dev.simplix.cirrus.velocity.converters.ItemStackConverter;
import dev.simplix.cirrus.velocity.converters.PlayerConverter;
import dev.simplix.cirrus.velocity.converters.PlayerUniqueIdConverter;
import dev.simplix.cirrus.velocity.listener.QuitListener;
import dev.simplix.cirrus.velocity.protocolize.ProtocolizeMenuBuilder;
import dev.simplix.protocolize.api.item.ItemStack;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* Date: 18.09.2021
*
* @author Exceptionflug
*/
public class CirrusVelocity {
private static ProxyServer proxyServer;
public static void init(ProxyServer proxyServer, Object plugin) {
if (CirrusVelocity.proxyServer != null) {
return;
}
CirrusVelocity.proxyServer = proxyServer;
Cirrus.registerService(MenuBuilder.class, new ProtocolizeMenuBuilder());
proxyServer.getEventManager().register(plugin, new QuitListener());
// Players
Converters.register(Player.class, PlayerWrapper.class, new PlayerConverter());
Converters.register(UUID.class, PlayerWrapper.class, new PlayerUniqueIdConverter(proxyServer));
// Items
Converters.register(ItemStack.class, MenuItemWrapper.class, new ItemStackConverter());
Converters.register(CirrusItem.class, InventoryMenuItemWrapper.class, new ItemModelConverter());
proxyServer.getScheduler().buildTask(plugin, () -> {
if (proxyServer.getPlayerCount() > 0 && !MenuAnimator.isEmpty()) {
MenuAnimator.updateAll();
}
}).repeat(50 * 2, TimeUnit.MILLISECONDS).schedule();
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/VelocityPlayerWrapper.java
================================================
package dev.simplix.cirrus.velocity;
import com.velocitypowered.api.proxy.Player;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.player.ProtocolizePlayer;
import java.util.UUID;
import lombok.NonNull;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class VelocityPlayerWrapper implements PlayerWrapper {
private final LegacyComponentSerializer legacyComponentSerializer = LegacyComponentSerializer.legacySection();
private final ProtocolizePlayer protocolizePlayer;
private final Player handle;
public VelocityPlayerWrapper(@NonNull Player handle) {
this.handle = handle;
this.protocolizePlayer = Protocolize.playerProvider().player(handle.getUniqueId());
}
@Override
public UUID uniqueId() {
return this.handle.getUniqueId();
}
@Override
public String name() {
return this.handle.getUsername();
}
@Override
public int protocolVersion() {
return this.protocolizePlayer.protocolVersion();
}
@Override
public void sendMessage(@NonNull String msg) {
this.handle.sendMessage(this.legacyComponentSerializer.deserialize(msg));
}
@Override
public void closeInventory() {
this.protocolizePlayer.closeInventory();
}
@Override
public boolean hasPermission(@NonNull String permission) {
return this.handle.hasPermission(permission);
}
@Override
public T handle() {
return (T) this.handle;
}
public ProtocolizePlayer protocolizePlayer() {
return this.protocolizePlayer;
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/ItemModelConverter.java
================================================
package dev.simplix.cirrus.velocity.converters;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.common.item.CirrusItem;
import dev.simplix.protocolize.api.chat.ChatElement;
import dev.simplix.protocolize.api.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.stream.Collectors;
public class ItemModelConverter implements Converter {
@Override
public InventoryMenuItemWrapper convert(@NotNull CirrusItem model) {
ItemStack itemStack = new ItemStack(model.itemType(), model.amount(), model.durability());
itemStack.nbtData(model.nbt());
itemStack.displayName(ChatElement.ofLegacyText(model.displayName()));
itemStack.lore(model.lore().stream().map(ChatElement::ofLegacyText).collect(Collectors.toList()));
return InventoryMenuItemWrapper.builder()
.handle(Converters.convert(itemStack, MenuItemWrapper.class))
.actionArguments(model.actionArguments())
.actionHandler(model.actionHandler())
.build();
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/ItemStackConverter.java
================================================
package dev.simplix.cirrus.velocity.converters;
import dev.simplix.cirrus.common.business.MenuItemWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;
import dev.simplix.protocolize.api.item.ItemStack;
import lombok.NonNull;
public class ItemStackConverter implements Converter {
@Override
public MenuItemWrapper convert(@NonNull ItemStack itemStack) {
return new ProtocolizeMenuItemWrapper(itemStack);
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/PlayerConverter.java
================================================
package dev.simplix.cirrus.velocity.converters;
import com.velocitypowered.api.proxy.Player;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.velocity.VelocityPlayerWrapper;
import lombok.NonNull;
public final class PlayerConverter implements Converter {
@Override
public PlayerWrapper convert(@NonNull Player proxiedPlayer) {
return new VelocityPlayerWrapper(proxiedPlayer);
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/PlayerUniqueIdConverter.java
================================================
package dev.simplix.cirrus.velocity.converters;
import com.velocitypowered.api.proxy.ProxyServer;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converter;
import dev.simplix.cirrus.velocity.VelocityPlayerWrapper;
import java.util.UUID;
import lombok.NonNull;
public class PlayerUniqueIdConverter implements Converter {
private final ProxyServer proxyServer;
public PlayerUniqueIdConverter(ProxyServer proxyServer) {
this.proxyServer = proxyServer;
}
@Override
public PlayerWrapper convert(@NonNull UUID uuid) {
return new VelocityPlayerWrapper(this.proxyServer.getPlayer(uuid)
.orElseThrow(() -> new IllegalArgumentException("Player " + uuid + " is offline")));
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/listener/QuitListener.java
================================================
package dev.simplix.cirrus.velocity.listener;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.menu.MenuBuilder;
/**
* Date: 18.09.2021
*
* @author Exceptionflug
*/
public class QuitListener {
private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);
@Subscribe
public void onQuit(DisconnectEvent event) {
this.menuBuilder.destroyMenusOfPlayer(event.getPlayer().getUniqueId());
}
}
================================================
FILE: cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/protocolize/ProtocolizeMenuBuilder.java
================================================
package dev.simplix.cirrus.velocity.protocolize;
import com.google.common.collect.Sets;
import com.velocitypowered.api.proxy.Player;
import dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.container.Container;
import dev.simplix.cirrus.common.handler.ActionHandler;
import dev.simplix.cirrus.common.i18n.Replacer;
import dev.simplix.cirrus.common.menu.AbstractMenu;
import dev.simplix.cirrus.common.menu.Menu;
import dev.simplix.cirrus.common.menu.MenuBuilder;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.cirrus.common.model.Click;
import dev.simplix.cirrus.velocity.VelocityPlayerWrapper;
import dev.simplix.protocolize.api.ClickType;
import dev.simplix.protocolize.api.chat.ChatElement;
import dev.simplix.protocolize.api.inventory.Inventory;
import dev.simplix.protocolize.api.item.BaseItemStack;
import dev.simplix.protocolize.api.item.ItemStack;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Map.Entry;
@Slf4j
public class ProtocolizeMenuBuilder implements MenuBuilder {
private final Map> buildMap = new LinkedHashMap<>();
private final Set menus = Sets.newConcurrentHashSet();
@Override
public T build(@Nullable T prebuild, @NonNull Menu menu) {
if (!(menu instanceof AbstractMenu)) {
throw new IllegalArgumentException("This implementation can only build cirrus menus!");
}
final boolean register = prebuild == null;
if (prebuild instanceof Inventory) {
String title = Replacer.of(menu.title()).replaceAll((Object[]) menu.replacements().get())
.replacedMessageJoined();
final Inventory inventory = (Inventory) prebuild;
if (!GsonComponentSerializer.gson().serialize((Component) inventory.title().asComponent())
.equals(GsonComponentSerializer.gson().serialize(Component.text(title))) ||
inventory.type().getTypicalSize(menu.player().protocolVersion()) != menu
.topContainer()
.capacity()
|| inventory.type() != menu.inventoryType()) {
prebuild = (T) makeInv(menu);
}
} else {
prebuild = (T) makeInv(menu);
}
final Inventory inventory = (Inventory) prebuild;
buildContainer(inventory, menu.topContainer());
buildContainer(inventory, menu.bottomContainer());
this.buildMap.put(
menu.player().uniqueId(),
new AbstractMap.SimpleEntry<>(menu, System.currentTimeMillis()));
if (register) {
this.menus.add(menu);
}
open(menu.player(), inventory);
return prebuild;
}
private void buildContainer(@NonNull Inventory inventory, @NonNull Container container) {
for (int i = container.baseSlot(); i < container.baseSlot() + container.capacity(); i++) {
InventoryMenuItemWrapper item = container.itemMap().get(i);
BaseItemStack currentStack = inventory.item(i);
if (item == null) {
if (currentStack != null) {
inventory.item(i, ItemStack.NO_DATA);
}
}
if (item != null) {
if (currentStack == null) {
if (item.handle() == null) {
log.error("InventoryItem's ItemStackWrapper is null @ slot " + i);
continue;
}
inventory.item(i, item.handle());
} else {
if (!currentStack.equals(item.handle())) {
inventory.item(i, item.handle());
}
}
}
}
}
private Inventory makeInv(@NonNull Menu menu) {
Inventory inventory = new Inventory(menu.inventoryType());
inventory.title(ChatElement.ofLegacyText(menu.title()));
inventory.onClose(inventoryClose -> {
Entry lastBuild = lastBuildOfPlayer(inventoryClose.player().uniqueId());
if (((AbstractMenu) lastBuild.getKey()).internalId() == ((AbstractMenu) menu).internalId()
&& (System.currentTimeMillis() - lastBuild.getValue()) <= 55) {
return;
}
menu.handleClose((System.currentTimeMillis() - lastBuild.getValue()) <= 55);
invalidate(menu);
});
inventory.onClick(inventoryClick -> {
if (inventoryClick.clickType() == null) {
return;
}
if (inventoryClick.player() == null) {
return;
}
Inventory i = inventoryClick.inventory();
if (i == null) {
return;
}
// ProxyServer.getInstance().broadcast("Clicked inventory");
// ProxyServer.getInstance().broadcast("Clicked menu: " + menu.getClass().getSimpleName() + " @ slot " + event.getSlot());
Container container;
if (inventoryClick.slot() > menu.topContainer().capacity() - 1) {
container = menu.bottomContainer();
// ProxyServer.getInstance().broadcast("Clicked bottom container");
} else {
container = menu.topContainer();
// ProxyServer.getInstance().broadcast("Clicked top container");
}
InventoryMenuItemWrapper item = container.get(inventoryClick.slot());
ClickType type = inventoryClick.clickType();
if (item == null) {
// ProxyServer.getInstance().broadcast("Clicked nothing");
if (menu.customActionHandler() != null) {
try {
CallResult callResult = menu
.customActionHandler()
.handle(new Click(type, menu, null, inventoryClick.slot()));
inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);
} catch (Exception ex) {
inventoryClick.cancelled(true);
menu.handleException(null, ex);
}
}
return;
}
// ProxyServer.getInstance().broadcast("Clicked "+item.displayName());
ActionHandler actionHandler = menu.actionHandler(item.actionHandler());
if (actionHandler == null) {
inventoryClick.cancelled(true);
return;
}
try {
final CallResult callResult = actionHandler.handle(new Click(
type,
menu,
item,
inventoryClick.slot()));
inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);
} catch (final Exception ex) {
inventoryClick.cancelled(true);
menu.handleException(actionHandler, ex);
}
});
return inventory;
}
@Override
public void open(
PlayerWrapper playerWrapper, T inventoryImpl) {
if (playerWrapper instanceof VelocityPlayerWrapper) {
((VelocityPlayerWrapper) playerWrapper).protocolizePlayer().openInventory((Inventory) inventoryImpl);
}
}
@Override
@Nullable
public Menu menuByHandle(Object handle) {
if (handle == null) {
return null;
}
for (final Menu menu : this.menus) {
if (menu.equals(handle)) {
return menu;
}
}
return null;
}
@Override
public void destroyMenusOfPlayer(@NonNull UUID uniqueId) {
this.menus.removeIf(
wrapper -> ((Player) wrapper.player().handle()).getUniqueId().equals(uniqueId));
this.buildMap.remove(uniqueId);
}
@Override
public Entry lastBuildOfPlayer(@NonNull UUID uniqueId) {
return this.buildMap.get(uniqueId);
}
@Override
public void invalidate(@NonNull Menu menu) {
this.menus.remove(menu);
}
}
================================================
FILE: cirrus-velocity-example/.gitignore
================================================
# User-specific stuff
.idea/
*.iml
*.ipr
*.iws
# IntelliJ
out/
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml
# Common working directory
run/
================================================
FILE: cirrus-velocity-example/pom.xml
================================================
4.0.0
dev.simplix.cirrus
cirrus
2.0.0
cirrus-velocity-example
${cirrus.version}
cirrus-common
dev.simplix.cirrus
compile
${cirrus.version}
cirrus-velocity
dev.simplix.cirrus
compile
${cirrus.version}
com.velocitypowered
velocity-api
3.0.0
provided
${project.name}-${project.version}
src/main/resources
true
org.apache.maven.plugins
maven-shade-plugin
3.0.0
package
shade
org.apache.maven.plugins
maven-compiler-plugin
8
8
================================================
FILE: cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/CirrusExamplePlugin.java
================================================
package dev.simplix.cirrus.velocity.example;
import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandManager;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import dev.simplix.cirrus.velocity.CirrusVelocity;
import dev.simplix.cirrus.velocity.example.commands.TestCommand;
@Plugin(
id = "cirrusexample",
name = "CirrusExample",
version = "1.0",
authors = "Xefreh"
)
public class CirrusExamplePlugin {
private final ProxyServer proxyServer;
private final CommandManager commandManager;
@Inject
public CirrusExamplePlugin(ProxyServer proxyServer, CommandManager commandManager) {
this.proxyServer = proxyServer;
this.commandManager = commandManager;
}
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
CirrusVelocity.init(proxyServer, this);
commandManager.register("test", new TestCommand());
}
}
================================================
FILE: cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/commands/TestCommand.java
================================================
package dev.simplix.cirrus.velocity.example.commands;
import com.velocitypowered.api.command.SimpleCommand;
import com.velocitypowered.api.proxy.Player;
import dev.simplix.cirrus.common.Cirrus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.converter.Converters;
import dev.simplix.cirrus.velocity.example.menus.ExampleMenu;
public class TestCommand implements SimpleCommand {
@Override
public void execute(Invocation invocation) {
if (invocation.source() instanceof Player) {
Player player = (Player) invocation.source();
new ExampleMenu(Converters.convert(player, PlayerWrapper.class),
Cirrus.configurationFactory().loadFile("plugins/Cirrus/example.json")).open();
}
}
}
================================================
FILE: cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/menus/ExampleMenu.java
================================================
package dev.simplix.cirrus.velocity.example.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MenuConfiguration;
import dev.simplix.cirrus.common.menus.SimpleMenu;
import dev.simplix.cirrus.common.model.CallResult;
import java.util.Locale;
public class ExampleMenu extends SimpleMenu {
public ExampleMenu(PlayerWrapper player, MenuConfiguration configuration) {
super(player, configuration, Locale.ENGLISH);
registerActionHandler("tnt", click -> {
topContainer().itemMap().remove(click.slot());
title("Hello, {viewer}");
build();
player().sendMessage("It simply works :)");
return CallResult.DENY_GRABBING;
});
}
}
================================================
FILE: cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/menus/ExampleMultiPageMenu.java
================================================
package dev.simplix.cirrus.velocity.example.menus;
import dev.simplix.cirrus.common.business.PlayerWrapper;
import dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;
import dev.simplix.cirrus.common.menus.MultiPageMenu;
import dev.simplix.cirrus.common.model.CallResult;
import dev.simplix.protocolize.api.Protocolize;
import dev.simplix.protocolize.api.item.ItemStack;
import dev.simplix.protocolize.api.providers.MappingProvider;
import dev.simplix.protocolize.data.ItemType;
import java.util.Collections;
import java.util.Locale;
public class ExampleMultiPageMenu extends MultiPageMenu {
private final MappingProvider mappingProvider = Protocolize.mappingProvider();
public ExampleMultiPageMenu(
PlayerWrapper player,
MultiPageMenuConfiguration configuration) {
super(player, configuration, Locale.ENGLISH);
registerMyActionHandlers();
addItems();
}
private void registerMyActionHandlers() {
registerActionHandler("test", click -> {
player().sendMessage("This is " + click.clickedItem().type().name());
return CallResult.DENY_GRABBING;
});
}
private void addItems() {
for (ItemType type : ItemType.values()) {
if (this.mappingProvider.mapping(type, player().protocolVersion()) != null) {
add(wrapItemStack(new ItemStack(type)), "test", Collections.emptyList());
}
}
}
}
================================================
FILE: pom.xml
================================================
cirrus
dev.simplix.cirrus
4.0.0
pom
2.0.0
8
8
1.8
2.0.0
UTF-8
protocolize-api
dev.simplix
provided
2.4.1
org.jetbrains
annotations
23.0.0
provided
lombok
org.projectlombok
provided
1.18.22
gson
com.google.code.gson
provided
2.8.9
bungeecord-chat
net.md-5
provided
1.21-R0.1-SNAPSHOT
junit-jupiter
org.junit.jupiter
test
5.7.0-M1
com.mojang
authlib
1.5.21
provided
cirrus-common
cirrus-bungeecord
cirrus-velocity
cirrus-spigot
cirrus-spigot-modern
cirrus-bungeecord-example
cirrus-spigot-example
cirrus-velocity-example
jitpack.io
https://jitpack.io
simplixsoft-public
https://repo.simplix.dev/repository/simplixsoft-public/
exceptionflug
https://mvn.exceptionflug.de/repository/exceptionflug-public/
velocity
https://repo.velocitypowered.com/snapshots/
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots/
minecraft-repo
https://libraries.minecraft.net/
simplixsoft-public
https://repo.simplix.dev/repository/simplixsoft-public/
simplixsoft-public
https://repo.simplix.dev/repository/simplixsoft-public/